Version 1.19.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac4d76d..94a71cc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,152 @@
-## 1.18.0 - 2016-08-02
+## 1.19.0 - 2016-08-26
 
-Patch release, resolves two issues:
+### Language changes
+
+* The language now allows a trailing comma after the last argument of a call and
+ the last parameter of a function declaration. This can make long argument or
+ parameter lists easier to maintain, as commas can be left as-is when
+ reordering lines. For details, see SDK issue
+ [26644](https://github.com/dart-lang/sdk/issues/26644).
+
+### Tool Changes
+
+* `dartfmt` - upgraded to v0.2.9+1
+  * Support trailing commas in argument and parameter lists.
+  * Gracefully handle read-only files.
+  * About a dozen other bug fixes.
+
+* Pub
+  * Added a `--no-packages-dir` flag to `pub get`, `pub upgrade`, and `pub
+    downgrade`. When this flag is passed, pub will not generate a `packages/`
+    directory, and will remove that directory and any symlinks to it if they
+    exist. Note that this replaces the unsupported `--no-package-symlinks` flag.
+
+  * Added the ability for packages to declare a constraint on the [Flutter][]
+    SDK:
+
+    ```yaml
+    environment:
+      flutter: ^0.1.2
+      sdk: >=1.19.0 <2.0.0
+    ```
+
+    A Flutter constraint will only be satisfiable when pub is running in the
+    context of the `flutter` executable, and when the Flutter SDK version
+    matches the constraint.
+
+  * Added `sdk` as a new package source that fetches packages from a hard-coded
+    SDK. Currently only the `flutter` SDK is supported:
+
+    ```yaml
+    dependencies:
+      flutter_driver:
+        sdk: flutter
+        version: ^0.0.1
+    ```
+
+    A Flutter `sdk` dependency will only be satisfiable when pub is running in
+    the context of the `flutter` executable, and when the Flutter SDK contains a
+    package with the given name whose version matches the constraint.
+
+  * `tar` files on Linux are now created with `0` as the user and group IDs.
+    This fixes a crash when publishing packages while using Active Directory.
+
+  * Fixed a bug where packages from a hosted HTTP URL were considered the same
+    as packages from an otherwise-identical HTTPS URL.
+
+  * Fixed timer formatting for timers that lasted longer than a minute.
+
+  * Eliminate some false negatives when determining whether global executables
+    are on the user's executable path.
+
+* `dart2js`
+  * `dart2dart` (aka `dart2js --output-type=dart`) has been removed (this was deprecated in Dart 1.11).
+
+[Flutter]: https://flutter.io/
+
+### Dart VM
+
+*   The dependency on BoringSSL has been rolled forward. Going forward, builds
+    of the Dart VM including secure sockets will require a compiler with C++11
+    support. For details, see the
+    [Building wiki page](https://github.com/dart-lang/sdk/wiki/Building).
+
+### Strong Mode
+
+*   New feature - an option to disable implicit casts
+    (SDK issue [26583](https://github.com/dart-lang/sdk/issues/26583)),
+    see the [documentation](https://github.com/dart-lang/dev_compiler/blob/master/doc/STATIC_SAFETY.md#disable-implicit-casts)
+    for usage instructions and examples.
+
+*   New feature - an option to disable implicit dynamic
+    (SDK issue [25573](https://github.com/dart-lang/sdk/issues/25573)),
+    see the [documentation](https://github.com/dart-lang/dev_compiler/blob/master/doc/STATIC_SAFETY.md#disable-implicit-dynamic)
+    for usage instructions and examples.
+
+*   Breaking change - infer generic type arguments from the
+    constructor invocation arguments
+    (SDK issue [25220](https://github.com/dart-lang/sdk/issues/25220)).
+
+    ```dart
+    var map = new Map<String, String>();
+
+    // infer: Map<String, String>
+    var otherMap = new Map.from(map);
+    ```
+
+*   Breaking change - infer local function return type
+    (SDK issue [26414](https://github.com/dart-lang/sdk/issues/26414)).
+
+    ```dart
+    void main() {
+      // infer: return type is int
+      f() { return 40; }
+      int y = f() + 2; // type checks
+      print(y);
+    }
+    ```
+
+*   Breaking change - allow type promotion from a generic type parameter
+    (SDK issue [26414](https://github.com/dart-lang/sdk/issues/26965)).
+
+    ```dart
+    void fn/*<T>*/(/*=T*/ object) {
+      if (object is String) {
+        // Treat `object` as `String` inside this block.
+        // But it will require a cast to pass it to something that expects `T`.
+        print(object.substring(1));
+      }
+    }
+    ```
+
+* Breaking change - smarter inference for Future.then
+    (SDK issue [25944](https://github.com/dart-lang/sdk/issues/25944)).
+    Previous workarounds that use async/await or `.then/*<Future<SomeType>>*/`
+    should no longer be necessary.
+
+    ```dart
+    // This will now infer correctly.
+    Future<List<int>> t2 = f.then((_) => [3]);
+    // This infers too.
+    Future<int> t2 = f.then((_) => new Future.value(42));
+    ```
+
+* Breaking change - smarter inference for async functions
+    (SDK issue [25322](https://github.com/dart-lang/sdk/issues/25322)).
+
+    ```dart
+    void test() async {
+      List<int> x = await [4]; // was previously inferred
+      List<int> y = await new Future.value([4]); // now inferred too
+    }
+    ```
+
+* Breaking change - sideways casts are no longer allowed
+    (SDK issue [26120](https://github.com/dart-lang/sdk/issues/26120)).
+
+## 1.18.1 - 2016-08-02
+
+Patch release, resolves two issues and improves performance:
 
 * Debugger: Fixes a bug that crashes the VM
 (SDK issue [26941](https://github.com/dart-lang/sdk/issues/26941))
@@ -15,6 +161,9 @@
 
 ### Core library changes
 
+* `dart:core`
+  * Improved performance when parsing some common URIs.
+  * Fixed bug in `Uri.resolve` (SDK issue [26804](https://github.com/dart-lang/sdk/issues/26804)).
 * `dart:io`
   * Adds file locking modes `FileLock.BLOCKING_SHARED` and
     `FileLock.BLOCKING_EXCLUSIVE`.
diff --git a/DEPS b/DEPS
index cbcfa64..d019eee 100644
--- a/DEPS
+++ b/DEPS
@@ -35,28 +35,28 @@
   "buildtools_revision": "@565d04e8741429fb1b4f26d102f2c6c3b849edeb",
 
   # Revisions of /third_party/* dependencies.
-  "args_tag": "@0.13.4",
-  "async_tag": "@1.10.0",
+  "args_tag": "@0.13.5",
+  "async_tag": "@1.11.0",
   "barback-0.13.0_rev": "@34853",
   "barback-0.14.0_rev": "@36398",
   "barback-0.14.1_rev": "@38525",
   "barback_tag" : "@0.15.2+7",
   "bazel_worker_tag": "@v0.1.0",
   "boolean_selector_tag" : "@1.0.0",
-  "boringssl_rev" : "@daeafc22c66ad48f6b32fc8d3362eb9ba31b774e",
+  "boringssl_rev" : "@8d343b44bbab829d1a28fdef650ca95f7db4412e",
   "charcode_tag": "@1.1.0",
   "chrome_rev" : "@19997",
   "cli_util_tag" : "@0.0.1+2",
   "code_transformers_rev": "@bfe9799e88d9c231747435e1c1d2495ef5ecd966",
-  "collection_tag": "@1.8.0",
+  "collection_tag": "@1.9.0",
   "convert_tag": "@2.0.0",
   "crypto_tag" : "@2.0.1",
   "csslib_tag" : "@0.12.0",
   "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
-  "dart_style_tag": "@0.2.4",
+  "dart_style_tag": "@0.2.9+1",
   "dartdoc_tag" : "@v0.9.6+2",
-  "dev_compiler_rev": "@7e9708eb5e9f3fcdc68b9af039d78cf39ce502b7",
+  "dev_compiler_rev": "@fa084164b620ea75cd2008c9dc317655a045ad6d",
   "fixnum_tag": "@0.10.5",
   "func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
@@ -68,9 +68,10 @@
   "idl_parser_rev": "@7fbe68cab90c38147dee4f48c30ad0d496c17915",
   "initialize_rev": "@595d501a92c3716395ad2d81f9aabdb9f90879b6",
   "intl_tag": "@0.13.0",
+  "isolate_tag": "@0.2.2",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.0",
-  "linter_rev": "@7ca3aab6ca45b988440e425c187993a533fbe27e",
+  "linter_rev": "@da3ec6ae914b40332fa6b6e100c1d4aabe9e27ca",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
@@ -78,21 +79,22 @@
   "mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
   "mustache4dart_rev" : "@5724cfd85151e5b6b53ddcd3380daf188fe47f92",
   "oauth2_tag": "@1.0.0",
-  "observatory_pub_packages_rev": "@e5e1e543bea10d4bed95b22ad3e7aa2b20a23584",
+  "observatory_pub_packages_rev": "@a01235b5b71df27b602dae4676d0bf771cbe7fa2",
   "observe_rev": "@eee2b8ec34236fa46982575fbccff84f61202ac6",
-  "package_config_rev": "@0.1.5",
+  "package_config_rev": "@1.0.0",
+  "package_resolver_tag": "@1.0.1",
   "path_tag": "@1.3.6",
   "plugin_tag": "@0.2.0",
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "@1.2.1",
   "protobuf_tag": "@0.5.1+1",
   "pub_cache_tag": "@v0.1.0",
-  "pub_rev": "@488ab539770512a234f0a01b74882dcbb3f1a4da",
-  "pub_semver_tag": "@1.2.1",
+  "pub_rev": "@101aa44a4aebaefd0796ce44e6d155cd79fe2db4",
+  "pub_semver_tag": "@1.3.0",
   "quiver_tag": "@0.21.4",
   "resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
   "root_certificates_rev": "@aed07942ce98507d2be28cbd29e879525410c7fc",
-  "scheduled_test_tag": "@0.12.5+2",
+  "scheduled_test_tag": "@0.12.6",
   "shelf_static_tag": "@0.2.3+4",
   "shelf_tag": "@0.6.5+2",
   "shelf_web_socket_tag": "@0.2.0",
@@ -102,11 +104,11 @@
   "source_maps_tag": "@0.10.1",
   "source_span_tag": "@1.2.0",
   "stack_trace_tag": "@1.4.2",
-  "stream_channel_tag": "@1.3.1",
+  "stream_channel_tag": "@1.5.0",
   "string_scanner_tag": "@0.1.4",
   "sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
   "test_reflective_loader_tag": "@0.0.3",
-  "test_tag": "@0.12.13+5",
+  "test_tag": "@0.12.15+1",
   "typed_data_tag": "@1.1.2",
   "usage_rev": "@b5080dac0d26a5609b266f8fdb0d053bc4c1c638",
   "utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
@@ -222,6 +224,8 @@
       (Var("github_dartlang") % "initialize") + Var("initialize_rev"),
   Var("dart_root") + "/third_party/pkg/intl":
       (Var("github_mirror") % "intl") + Var("intl_tag"),
+  Var("dart_root") + "/third_party/pkg/isolate":
+      (Var("github_dartlang") % "isolate") + Var("isolate_tag"),
   Var("dart_root") + "/third_party/pkg/json_rpc_2":
       (Var("github_mirror") % "json_rpc_2") + Var("json_rpc_2_tag"),
   Var("dart_root") + "/third_party/pkg/linter":
@@ -250,6 +254,9 @@
   Var("dart_root") + "/third_party/pkg_tested/package_config":
       (Var("github_mirror") % "package_config") +
       Var("package_config_rev"),
+  Var("dart_root") + "/third_party/pkg_tested/package_resolver":
+      "https://github.com/dart-lang/package_resolver.git" +
+      Var("package_resolver_tag"),
   Var("dart_root") + "/third_party/pkg/path":
       (Var("github_mirror") % "path") + Var("path_tag"),
   Var("dart_root") + "/third_party/pkg/plugin":
diff --git a/README.fuchsia b/README.fuchsia
deleted file mode 100644
index f09ff26..0000000
--- a/README.fuchsia
+++ /dev/null
@@ -1,41 +0,0 @@
-This is a README file describing how to build Dart for Fuchsia. It assumes that
-you have built the magenta kernel under //magenta, its toolchains are
-under //toolchains, and that you have a Dart checkout under //dart. It is early
-days and this is crufty. The process will improve from here.
-
-1. First, set up some symlinks in your Dart checkout:
-
-  //dart/third_party/fuchsia_tools/toolchains
-      -> symlinked to //toolchains
-  //dart/third_party/fuchsia_tools/sysroot/x86_64/usr
-      -> symlinked to //magenta/build-magenta-qemu-x86-64/sysroot/
-
-  Also, copy the linker script:
-
-  //magenta$ cp kernel/arch/x86/64/user.ld build-magenta-qemu-x86-64/sysroot/
-
-  and similarly for arm64.
-
-2. Build:
-
-  //dart$ tools/build.py -m product -a x64 --os=fuchsia fuchsia_test
-
-  This will produce //dart/out/ProductFuchsiaX64/fuchsia_test
-
-3. Strip it:
-
-  //dart$ third_party/fuchsia_tools/toolchains/x86_64-elf-5.3.0-Linux-x86_64/bin/x86_64-elf-strip out/ProductFuchsiaX64/fuchsia_test -o out/ProductFuchsiaX64/fuchsia_test.stripped
-
-4. Make a file //magenta/fuchsia_test.manifest containing:
-
-  bin/fuchsia_test=//dart/out/ProductFuchsiaX64/fuchsia_test.stripped
-
-  Where //dart is the actual path to your Dart checkout.
-
-5. Make an extra bootfs:
-
-  //magenta$ build-magenta-qemu-x86-64/tools/mkbootfs -o fuchsia_test.bootfs fuchsia_test.manifest
-
-6. Run:
-
-  //magenta$ ./scripts/run-magenta-x86-64 -x fuchsia_test.bootfs
diff --git a/create_sdk.gyp b/create_sdk.gyp
index 83ddc47..b1b9361 100644
--- a/create_sdk.gyp
+++ b/create_sdk.gyp
@@ -26,7 +26,6 @@
             '<!@(["python", "tools/list_files.py",'
                 '"dart$",'
                 '"sdk/lib"])',
-            'sdk/lib/dart2dart.platform',
             'sdk/lib/dart_client.platform',
             'sdk/lib/dart_server.platform',
             'sdk/lib/dart_shared.platform',
diff --git a/dart.gyp b/dart.gyp
index f513625..f3e6e82 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -35,13 +35,6 @@
       ],
     },
     {
-      'target_name': 'fuchsia_test',
-      'type': 'none',
-      'dependencies': [
-        'runtime/dart-runtime.gyp:fuchsia_test',
-      ],
-    },
-    {
       # This is the target that is built on the VM build bots.  It
       # must depend on anything that is required by the VM test
       # suites.
@@ -121,20 +114,6 @@
       'dependencies': [
         'create_sdk',
         'packages',
-        'try',
-      ],
-    },
-    {
-      # This is the target that is built on the dart2js debug build bots.
-      # It must depend on anything that is required by the dart2js
-      # test suites.
-      # We have this additional target because the try target takes to long
-      # to build in debug mode and will make the build step time out.
-      'target_name': 'dart2js_bot_debug',
-      'type': 'none',
-      'dependencies': [
-        'create_sdk',
-        'packages',
       ],
     },
     {
@@ -157,12 +136,5 @@
         'pkg/pkg.gyp:pkg_packages',
       ],
     },
-    {
-      'target_name': 'try',
-      'type': 'none',
-      'dependencies': [
-        'site/try/build_try.gyp:try_site',
-      ],
-    },
   ],
 }
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 140a8df..e5a70a8 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -655,9 +655,11 @@
 It is a compile-time error if a formal parameter is declared as a constant variable (\ref{variables}).
 
 \begin{grammar}
-{\bf formalParameterList:}`(' `)';
- `(' normalFormalParameters ( `,'  optionalFormalParameters)? `)';
-  `(' optionalFormalParameters `)'
+{\bf formalParameterList:}
+     `(' `)';
+     `(' normalFormalParameters `,'? `)';
+     `(' normalFormalParameters `,'  optionalFormalParameters `)';
+     `(' optionalFormalParameters `)'
    .
 %\end{grammar}
 %}
@@ -673,18 +675,21 @@
       normalFormalParameter (`,' normalFormalParameter)*
     .
 
-{\bf optionalFormalParameters:}optionalPositionalFormalParameters;
+{\bf optionalFormalParameters:}
+      optionalPositionalFormalParameters;
       namedFormalParameters
     .
 
 {\bf optionalPositionalFormalParameters:}
-      `[' defaultFormalParameter (`,' defaultFormalParameter)* `]'
+      `[' defaultFormalParameter (`,' defaultFormalParameter)* `,'? `]'
     .
 {\bf namedFormalParameters:}
-      `\{' defaultNamedParameter (`,' defaultNamedParameter)* `\}'
+      `\{' defaultNamedParameter (`,' defaultNamedParameter)* `,'? `\}'
     .
 \end{grammar}
 
+Formal parameter lists allow an optional trailing comma after the last parameter ($`,'?$). A parameter list with such a trailing comma is equivalent in all ways to the same parameter list without the trailing comma. All parameter lists in this specification are shown without a trailing comma, but the rules and semantics apply equally to the corresponding parameter list with a trailing comma.
+
 %Formal parameters are always \FINAL{}.
 %\Q{We're awaiting some data on whether enforcing this would cause widespread pain.}
 %A formal parameter is always considered to be initialized.  \rationale{This is because it will always be initialized by the call - even if it is optional.}
@@ -3608,10 +3613,11 @@
 
 \begin{grammar}
 {\bf arguments:}
-      `(' argumentList? `)'
+      `(' (argumentList  `,'?)? `)'
     .
 
-{\bf argumentList:}namedArgument (`,' namedArgument)*;
+{\bf argumentList:}
+      namedArgument (`,' namedArgument)*;
   %    expressionList ',' spreadArgument;
       expressionList (`,' namedArgument)*
 %      spreadArgument
@@ -3622,6 +3628,8 @@
     .
  \end{grammar}
 
+Argument lists allow an optional trailing comma after the last argument ($`,'?$). An argument list with such a trailing comma is equivalent in all ways to the same parameter list without the trailing comma. All argument lists in this specification are shown without a trailing comma, but the rules and semantics apply equally to the corresponding argument list with a trailing comma.
+
 \LMHash{}
 Evaluation of an actual argument list of the form
 
@@ -6471,7 +6479,7 @@
 
 \begin{grammar}
 {\bf assertStatement:}
-   assert `(' conditionalExpression `)' `{\escapegrammar ;}'
+   assert `(' expression `)' `{\escapegrammar ;}'
       .
 \end{grammar}
 
@@ -6479,7 +6487,7 @@
 The assert statement has no effect in production mode. In checked mode, execution of an assert statement \code{\ASSERT{}($e$);} proceeds as follows:
 
 \LMHash{}
-The conditional expression $e$ is evaluated to an object $o$. If the class of $o$ is a subtype of \code{Function} then let $r$ be the result of invoking $o$ with no arguments. Otherwise, let $r$ be $o$.
+The expression $e$ is evaluated to an object $o$. If the class of $o$ is a subtype of \code{Function} then let $r$ be the result of invoking $o$ with no arguments. Otherwise, let $r$ be $o$.
 It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Function}, or if $r$ is not of type \code{bool}.  If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, an \code{AssertionError} is thrown.
 
 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} AssertionError();\}} (in checked mode only).
diff --git a/pkg/analysis_server/.analysis_options b/pkg/analysis_server/.analysis_options
index 7b230dd..49fda46 100644
--- a/pkg/analysis_server/.analysis_options
+++ b/pkg/analysis_server/.analysis_options
@@ -1,3 +1,5 @@
+analyzer:
+  strong-mode: true
 linter:
   rules:
     - unnecessary_brace_in_string_interp
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart b/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart
new file mode 100644
index 0000000..87ccc30
--- /dev/null
+++ b/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart
@@ -0,0 +1,217 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library server.performance.local;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+
+import 'benchmark_scenario.dart';
+import 'memory_tests.dart';
+
+main(List<String> args) async {
+  int length = args.length;
+  if (length < 1) {
+    print('Usage: dart benchmark_local.dart path_to_flutter_checkout'
+        ' [benchmark_id]');
+    return;
+  }
+  paths = new PathHolder(flutterPath: args[0]);
+  String id = args.length >= 2 ? args[1] : null;
+  if (id == null) {
+    for (String id in benchmarks.keys) {
+      BenchmarkFunction benchmark = benchmarks[id];
+      await benchmark(id);
+    }
+  } else {
+    BenchmarkFunction benchmark = benchmarks[id];
+    if (benchmark != null) {
+      benchmark(id);
+    }
+  }
+}
+
+const Map<String, BenchmarkFunction> benchmarks =
+    const <String, BenchmarkFunction>{
+  'flutter-initialAnalysis-1': run_flutter_initialAnalysis_1,
+  'flutter-initialAnalysis-2': run_flutter_initialAnalysis_2,
+  'flutter-change-1': run_flutter_change_1,
+  'flutter-change-2': run_flutter_change_2,
+  'flutter-completion-1': run_flutter_completion_1,
+  'flutter-completion-2': run_flutter_completion_2,
+  'flutter-refactoring-1': run_flutter_refactoring_1,
+  'flutter-memory-initialAnalysis-1': run_flutter_memory_initialAnalysis_1,
+  'flutter-memory-initialAnalysis-2': run_flutter_memory_initialAnalysis_2,
+};
+
+PathHolder paths;
+
+Future run_flutter_change_1(String id) async {
+  String description = r'''
+1. Open 'packages/flutter'.
+2. Change a method body in lib/src/painting/colors.dart
+3. Measure the time to finish analysis.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
+      roots: [paths.packageFlutter],
+      file: '${paths.packageFlutter}/lib/src/painting/colors.dart',
+      fileChange: new FileChange(
+          afterStr: 'final double h = hue % 360;', insertStr: 'print(12345);'),
+      numOfRepeats: 10);
+  printBenchmarkResults(id, description, times);
+}
+
+Future run_flutter_change_2(String id) async {
+  String description = r'''
+1. Open 'packages/flutter'.
+2. Change the name of a public method in lib/src/painting/colors.dart
+3. Measure the time to finish analysis.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
+      roots: [paths.packageFlutter],
+      file: '${paths.packageFlutter}/lib/src/painting/colors.dart',
+      fileChange: new FileChange(
+          afterStr: 'withValue(dou', afterStrBack: 4, insertStr: 'NewName'),
+      numOfRepeats: 5);
+  printBenchmarkResults(id, description, times);
+}
+
+Future run_flutter_completion_1(String id) async {
+  String description = r'''
+1. Open 'packages/flutter'.
+2. Change a method body in packages/flutter/lib/src/material/button.dart
+3. Request code completion in this method and measure time to get results.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+  String completionMarker = 'print(12345);';
+  List<int> times = await new BenchmarkScenario()
+      .waitAnalyze_change_getCompletion(
+          roots: [paths.packageFlutter],
+          file: '${paths.packageFlutter}/lib/src/material/button.dart',
+          fileChange: new FileChange(
+              afterStr: 'Widget build(BuildContext context) {',
+              insertStr: completionMarker),
+          completeAfterStr: completionMarker,
+          numOfRepeats: 10);
+  printBenchmarkResults(id, description, times);
+}
+
+Future run_flutter_completion_2(String id) async {
+  String description = r'''
+1. Open 'packages/flutter'.
+2. Change the name of a public method in lib/src/rendering/layer.dart
+3. Request code completion in this method and measure time to get results.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+  List<int> times = await new BenchmarkScenario()
+      .waitAnalyze_change_getCompletion(
+          roots: [paths.packageFlutter],
+          file: '${paths.packageFlutter}/lib/src/rendering/layer.dart',
+          fileChange: new FileChange(
+              replaceWhat: 'void removeAllChildren() {',
+              replaceWith: 'void removeAllChildren2() {print(12345);parent.'),
+          completeAfterStr: 'print(12345);parent.',
+          numOfRepeats: 5);
+  printBenchmarkResults(id, description, times);
+}
+
+Future run_flutter_initialAnalysis_1(String id) async {
+  String description = r'''
+1. Start server, set 'hello_world' analysis root.
+2. Measure the time to finish initial analysis.
+3. Shutdown the server.
+4. Go to (1).
+''';
+  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
+      roots: [paths.exampleHelloWorld], numOfRepeats: 5);
+  printBenchmarkResults(id, description, times);
+}
+
+Future run_flutter_initialAnalysis_2(String id) async {
+  String description = r'''
+1. Start server, set 'hello_world' and 'flutter_gallery' analysis roots.
+2. Measure the time to finish initial analysis.
+3. Shutdown the server.
+4. Go to (1).
+''';
+  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
+      roots: [paths.exampleHelloWorld, paths.exampleGallery], numOfRepeats: 5);
+  printBenchmarkResults(id, description, times);
+}
+
+Future run_flutter_memory_initialAnalysis_1(String id) async {
+  String description = r'''
+1. Start server, set 'packages/flutter' as the analysis root.
+2. Measure the memory usage after finishing initial analysis.
+3. Shutdown the server.
+4. Go to (1).
+''';
+  List<int> sizes = await AnalysisServerMemoryUsageTest
+      .start_waitInitialAnalysis_shutdown(
+          roots: <String>[paths.packageFlutter], numOfRepeats: 3);
+  printMemoryResults(id, description, sizes);
+}
+
+Future run_flutter_memory_initialAnalysis_2(String id) async {
+  String description = r'''
+1. Start server, set 'packages/flutter' and 'packages/flutter_markdown' analysis roots.
+2. Measure the memory usage after finishing initial analysis.
+3. Shutdown the server.
+4. Go to (1).
+''';
+  List<int> sizes = await AnalysisServerMemoryUsageTest
+      .start_waitInitialAnalysis_shutdown(
+          roots: <String>[paths.packageFlutter, paths.packageMarkdown],
+          numOfRepeats: 3);
+  printMemoryResults(id, description, sizes);
+}
+
+Future run_flutter_refactoring_1(String id) async {
+  String description = r'''
+1. Open 'packages/flutter'.
+2. Change the name of a public method in lib/src/rendering/layer.dart
+3. Request rename refactoring for `getSourcesWithFullName` and measure time to get results.
+4. Rollback changes to the file and wait for analysis.
+5. Go to (2).
+''';
+  List<int> times = await new BenchmarkScenario()
+      .waitAnalyze_change_getRefactoring(
+          roots: [paths.packageFlutter],
+          file: '${paths.packageFlutter}/lib/src/rendering/layer.dart',
+          fileChange: new FileChange(
+              replaceWhat: 'void removeAllChildren() {',
+              replaceWith: 'void removeAllChildren2() {'),
+          refactoringAtStr: 'addToScene(ui.SceneBuilder builder',
+          refactoringKind: RefactoringKind.RENAME,
+          refactoringOptions: new RenameOptions('addToScene2'),
+          numOfRepeats: 5);
+  printBenchmarkResults(id, description, times);
+}
+
+typedef BenchmarkFunction(String id);
+
+class PathHolder {
+  String exampleHelloWorld;
+  String exampleGallery;
+  String exampleStocks;
+  String packageFlutter;
+  String packageMarkdown;
+  String packageSprites;
+
+  PathHolder({String flutterPath}) {
+    exampleHelloWorld = '$flutterPath/examples/hello_world';
+    exampleGallery = '$flutterPath/examples/flutter_gallery';
+    exampleStocks = '$flutterPath/examples/stocks';
+    packageFlutter = '$flutterPath/packages/flutter';
+    packageMarkdown = '$flutterPath/packages/flutter_markdown';
+    packageSprites = '$flutterPath/packages/flutter_sprites';
+  }
+}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_local.dart b/pkg/analysis_server/benchmark/perf/benchmark_local.dart
deleted file mode 100644
index 8cbdb89..0000000
--- a/pkg/analysis_server/benchmark/perf/benchmark_local.dart
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library server.performance.local;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-
-import 'benchmark_scenario.dart';
-import 'memory_tests.dart';
-
-main(List<String> args) async {
-  int length = args.length;
-  if (length < 1) {
-    print(
-        'Usage: dart benchmark_local.dart path_to_sdk_checkout [path_to_flutter_checkout]');
-    return;
-  } else if (length == 1) {
-    paths = new PathHolder(sdkPath: args[0]);
-  } else {
-    paths = new PathHolder(sdkPath: args[0], flutterPath: args[1]);
-  }
-  String now = new DateTime.now().toUtc().toIso8601String();
-  print('Benchmark started: $now');
-  print('');
-  print('');
-  await run_local_initialAnalysis_1();
-  await run_local_initialAnalysis_2();
-  await run_local_initialAnalysis_3();
-  await run_local_change_1();
-  await run_local_change_2();
-  await run_local_completion_1();
-  await run_local_completion_2();
-  await run_local_completion_3();
-  await run_local_completion_4();
-  await run_local_refactoring_1();
-
-  await run_memory_initialAnalysis_1();
-  await run_memory_initialAnalysis_2();
-}
-
-PathHolder paths;
-
-Future run_local_change_1() async {
-  String id = 'local-change-1';
-  String description = r'''
-1. Open 'analyzer'.
-2. Change a method body in src/task/dart.dart.
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
-      roots: [paths.analyzer],
-      file: '${paths.analyzer}/lib/src/task/dart.dart',
-      fileChange: new FileChange(
-          afterStr: 'if (hasDirectiveChange) {', insertStr: 'print(12345);'),
-      numOfRepeats: 10);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_change_2() async {
-  String id = 'local-change-2';
-  String description = r'''
-1. Open 'analyzer'.
-2. Change the name of a public method in src/task/dart.dart.
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
-      roots: [paths.analyzer],
-      file: '${paths.analyzer}/lib/src/task/dart.dart',
-      fileChange: new FileChange(
-          afterStr: 'resolveDirective(An',
-          afterStrBack: 3,
-          insertStr: 'NewName'),
-      numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_completion_1() async {
-  String id = 'local-completion-1';
-  String description = r'''
-1. Open 'analyzer'.
-2. Change a method body in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getCompletion(
-          roots: [paths.analyzer],
-          file: '${paths.analyzer}/lib/src/task/dart.dart',
-          fileChange: new FileChange(
-              afterStr: 'if (hasDirectiveChange) {',
-              insertStr: 'print(12345);'),
-          completeAfterStr: 'print(12345);',
-          numOfRepeats: 10);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_completion_2() async {
-  String id = 'local-completion-2';
-  String description = r'''
-1. Open 'analyzer'.
-2. Change the name of a public method in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getCompletion(
-          roots: [paths.analyzer],
-          file: '${paths.analyzer}/lib/src/task/dart.dart',
-          fileChange: new FileChange(
-              afterStr: 'DeltaResult validate(In',
-              afterStrBack: 3,
-              insertStr: 'NewName'),
-          completeAfterStr: 'if (hasDirectiveChange) {',
-          numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_completion_3() async {
-  String id = 'local-completion-3';
-  String description = r'''
-1. Open 'analysis_server' and 'analyzer'.
-2. Change a method body in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getCompletion(
-          roots: [paths.analysisServer, paths.analyzer],
-          file: '${paths.analyzer}/lib/src/task/dart.dart',
-          fileChange: new FileChange(
-              afterStr: 'if (hasDirectiveChange) {',
-              insertStr: 'print(12345);'),
-          completeAfterStr: 'print(12345);',
-          numOfRepeats: 10);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_completion_4() async {
-  String id = 'local-completion-4';
-  String description = r'''
-1. Open 'analysis_server' and 'analyzer'.
-2. Change the name of a public method in src/task/dart.dart.
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getCompletion(
-          roots: [paths.analysisServer, paths.analyzer],
-          file: '${paths.analyzer}/lib/src/task/dart.dart',
-          fileChange: new FileChange(
-              afterStr: 'DeltaResult validate(In',
-              afterStrBack: 3,
-              insertStr: 'NewName'),
-          completeAfterStr: 'if (hasDirectiveChange) {',
-          numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_initialAnalysis_1() async {
-  String id = 'local-initialAnalysis-1';
-  String description = r'''
-1. Start server, set 'analyzer' analysis root.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
-      roots: [paths.analyzer], numOfRepeats: 3);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_initialAnalysis_2() async {
-  String id = 'local-initialAnalysis-2';
-  String description = r'''
-1. Start server, set 'analyzer' and 'analysis_server' analysis roots.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
-      roots: [paths.analyzer, paths.analysisServer], numOfRepeats: 3);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_initialAnalysis_3() async {
-  String id = 'local-initialAnalysis-3';
-  String description = r'''
-1. Start server, set 'hello_world' and 'stocks' analysis roots.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
-      roots: [paths.flutterHelloWorld, paths.flutterStocks], numOfRepeats: 3);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_local_refactoring_1() async {
-  String id = 'local-refactoring-1';
-  String description = r'''
-1. Open 'analyzer'.
-2. Change the name of a public method in src/context/cache.dart.
-3. Request rename refactoring for `getSourcesWithFullName` and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
-  List<int> times = await new BenchmarkScenario()
-      .waitAnalyze_change_getRefactoring(
-          roots: [paths.analyzer],
-          file: '${paths.analyzer}/lib/src/context/cache.dart',
-          fileChange: new FileChange(
-              afterStr: 'getState(An', afterStrBack: 3, insertStr: 'NewName'),
-          refactoringAtStr: 'getSourcesWithFullName(String path)',
-          refactoringKind: RefactoringKind.RENAME,
-          refactoringOptions: new RenameOptions('getSourcesWithFullName2'),
-          numOfRepeats: 5);
-  printBenchmarkResults(id, description, times);
-}
-
-Future run_memory_initialAnalysis_1() async {
-  String id = 'memory-initialAnalysis-1';
-  String description = r'''
-1. Start server, set 'analyzer' and 'analysis_server' analysis roots.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> sizes = await AnalysisServerMemoryUsageTest
-      .start_waitInitialAnalysis_shutdown(
-          roots: <String>[paths.analyzer], numOfRepeats: 3);
-  printMemoryResults(id, description, sizes);
-}
-
-Future run_memory_initialAnalysis_2() async {
-  String id = 'memory-initialAnalysis-2';
-  String description = r'''
-1. Start server, set 'analyzer' and 'analysis_server' analysis roots.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
-  List<int> sizes = await AnalysisServerMemoryUsageTest
-      .start_waitInitialAnalysis_shutdown(
-          roots: <String>[paths.analyzer, paths.analysisServer],
-          numOfRepeats: 3);
-  printMemoryResults(id, description, sizes);
-}
-
-class PathHolder {
-  String analysisServer;
-  String analyzer;
-  String flutterHelloWorld;
-  String flutterStocks;
-
-  PathHolder({String sdkPath, String flutterPath}) {
-    analysisServer = '$sdkPath/pkg/analysis_server';
-    analyzer = '$sdkPath/pkg/analyzer';
-    flutterHelloWorld = '$flutterPath/examples/hello_world';
-    flutterStocks = '$flutterPath/examples/stocks';
-  }
-}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart b/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
index aac844b..3ec4c4c 100644
--- a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
+++ b/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:io';
+import 'dart:math';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:unittest/unittest.dart';
@@ -13,9 +14,11 @@
 import 'performance_tests.dart';
 
 void printBenchmarkResults(String id, String description, List<int> times) {
+  int minTime = times.fold(1 << 20, min);
   String now = new DateTime.now().toUtc().toIso8601String();
   print('$now ========== $id');
   print('times: $times');
+  print('min_time: $minTime');
   print(description.trim());
   print('--------------------');
   print('');
@@ -185,11 +188,19 @@
    */
   Future<String> _applyFileChange(String file, FileChange desc) async {
     String originalContent = _getFileContent(file);
-    int offset = _indexOfEnd(file, originalContent, desc.afterStr);
-    offset -= desc.afterStrBack;
-    String updatedContent = originalContent.substring(0, offset) +
-        desc.insertStr +
-        originalContent.substring(offset);
+    String updatedContent;
+    if (desc.afterStr != null) {
+      int offset = _indexOfEnd(file, originalContent, desc.afterStr);
+      offset -= desc.afterStrBack;
+      updatedContent = originalContent.substring(0, offset) +
+          desc.insertStr +
+          originalContent.substring(offset);
+    } else if (desc.replaceWhat != null) {
+      int offset = _indexOf(file, originalContent, desc.replaceWhat);
+      updatedContent = originalContent.substring(0, offset) +
+          desc.replaceWith +
+          originalContent.substring(offset + desc.replaceWhat.length);
+    }
     await sendAnalysisUpdateContent(
         {file: new AddContentOverlay(updatedContent)});
     return updatedContent;
@@ -279,9 +290,14 @@
   final String afterStr;
   final int afterStrBack;
   final String insertStr;
+  final String replaceWhat;
+  final String replaceWith;
 
-  FileChange({this.afterStr, this.afterStrBack: 0, this.insertStr}) {
-    expect(afterStr, isNotNull, reason: 'afterStr');
-    expect(insertStr, isNotNull, reason: 'insertStr');
+  FileChange({this.afterStr, this.afterStrBack: 0, this.insertStr, this.replaceWhat, this.replaceWith}) {
+    if (afterStr != null) {
+      expect(insertStr, isNotNull, reason: 'insertStr');
+    } else if (replaceWhat != null) {
+      expect(replaceWith, isNotNull, reason: 'replaceWith');
+    }
   }
 }
diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart
index 8522430..a648344 100644
--- a/pkg/analysis_server/benchmark/perf/memory_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/memory_tests.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'dart:math';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:unittest/unittest.dart';
@@ -12,9 +13,13 @@
 import '../../test/integration/integration_tests.dart';
 
 void printMemoryResults(String id, String description, List<int> sizes) {
+  int minMemory = sizes.fold(sizes.first, min);
+  int maxMemory = sizes.fold(sizes.first, max);
   String now = new DateTime.now().toUtc().toIso8601String();
   print('$now ========== $id');
   print('memory: $sizes');
+  print('min_memory: $minMemory');
+  print('max_memory: $maxMemory');
   print(description.trim());
   print('--------------------');
   print('');
@@ -98,7 +103,7 @@
    *  1. Start Analysis Server.
    *  2. Set the analysis [roots].
    *  3. Wait for analysis to complete.
-   *  4. Record the time to finish analysis.
+   *  4. Record the heap size after analysis is finished.
    *  5. Shutdown.
    *  6. Go to (1).
    */
diff --git a/pkg/analysis_server/benchmark/perf/performance_tests.dart b/pkg/analysis_server/benchmark/perf/performance_tests.dart
index 6d301c9..d6be917 100644
--- a/pkg/analysis_server/benchmark/perf/performance_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/performance_tests.dart
@@ -46,7 +46,7 @@
       expect(serverConnected.isCompleted, isFalse);
       serverConnected.complete();
     });
-    return startServer().then((_) {
+    return startServer(checked: false).then((_) {
       server.listenToOutput(dispatchNotification);
       server.exitCode.then((_) {
         skipShutdown = true;
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 7e695a2..307ed65 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -29,9 +29,10 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -39,6 +40,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:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/pub_summary.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/util/glob.dart';
 import 'package:analyzer/task/dart.dart';
@@ -298,6 +301,11 @@
   ResolverProvider fileResolverProvider;
 
   /**
+   * The manager of pub package summaries.
+   */
+  PubSummaryManager pubSummaryManager;
+
+  /**
    * Initialize a newly created server to receive requests from and send
    * responses to the given [channel].
    *
@@ -362,6 +370,8 @@
       });
     });
     _setupIndexInvalidation();
+    pubSummaryManager =
+        new PubSummaryManager(resourceProvider, '${io.pid}.temp');
     Notification notification =
         new ServerConnectedParams(VERSION, io.pid).toNotification();
     channel.sendNotification(notification);
@@ -699,23 +709,6 @@
     return nodes;
   }
 
-// TODO(brianwilkerson) Add the following method after 'prioritySources' has
-// been added to InternalAnalysisContext.
-//  /**
-//   * Return a list containing the full names of all of the sources that are
-//   * priority sources.
-//   */
-//  List<String> getPriorityFiles() {
-//    List<String> priorityFiles = new List<String>();
-//    folderMap.values.forEach((ContextDirectory directory) {
-//      InternalAnalysisContext context = directory.context;
-//      context.prioritySources.forEach((Source source) {
-//        priorityFiles.add(source.fullName);
-//      });
-//    });
-//    return priorityFiles;
-//  }
-
   /**
    * Returns resolved [CompilationUnit]s of the Dart file with the given [path].
    *
@@ -745,6 +738,23 @@
     return units;
   }
 
+// TODO(brianwilkerson) Add the following method after 'prioritySources' has
+// been added to InternalAnalysisContext.
+//  /**
+//   * Return a list containing the full names of all of the sources that are
+//   * priority sources.
+//   */
+//  List<String> getPriorityFiles() {
+//    List<String> priorityFiles = new List<String>();
+//    folderMap.values.forEach((ContextDirectory directory) {
+//      InternalAnalysisContext context = directory.context;
+//      context.prioritySources.forEach((Source source) {
+//        priorityFiles.add(source.fullName);
+//      });
+//    });
+//    return priorityFiles;
+//  }
+
   /**
    * Handle a [request] that was read from the communication channel.
    */
@@ -929,6 +939,32 @@
   }
 
   /**
+   * Schedule cache consistency validation in [context].
+   * The most of the validation must be done asynchronously.
+   */
+  void scheduleCacheConsistencyValidation(AnalysisContext context) {
+    if (context is InternalAnalysisContext) {
+      CacheConsistencyValidator validator = context.cacheConsistencyValidator;
+      List<Source> sources = validator.getSourcesToComputeModificationTimes();
+      // Compute modification times and notify the validator asynchronously.
+      new Future(() async {
+        try {
+          List<int> modificationTimes =
+              await resourceProvider.getModificationTimes(sources);
+          bool cacheInconsistencyFixed = validator
+              .sourceModificationTimesComputed(sources, modificationTimes);
+          if (cacheInconsistencyFixed) {
+            scheduleOperation(new PerformAnalysisOperation(context, false));
+          }
+        } catch (exception, stackTrace) {
+          sendServerErrorNotification(
+              'Failed to check cache consistency', exception, stackTrace);
+        }
+      });
+    }
+  }
+
+  /**
    * Schedules execution of the given [ServerOperation].
    */
   void scheduleOperation(ServerOperation operation) {
@@ -1509,6 +1545,7 @@
 class AnalysisServerOptions {
   bool enableIncrementalResolutionApi = false;
   bool enableIncrementalResolutionValidation = false;
+  bool enablePubSummaryManager = false;
   bool finerGrainedInvalidation = false;
   bool noErrorNotification = false;
   bool noIndex = false;
@@ -1567,6 +1604,21 @@
     context.sourceFactory =
         _createSourceFactory(context, options, disposition, folder);
     context.analysisOptions = options;
+
+    if (analysisServer.options.enablePubSummaryManager) {
+      List<LinkedPubPackage> linkedBundles =
+          analysisServer.pubSummaryManager.getLinkedBundles(context);
+      if (linkedBundles.isNotEmpty) {
+        SummaryDataStore store = new SummaryDataStore([]);
+        for (LinkedPubPackage package in linkedBundles) {
+          store.addBundle(null, package.unlinked);
+          store.addBundle(null, package.linked);
+        }
+        context.resultProvider =
+            new InputPackagesResultProvider(context, store);
+      }
+    }
+
     analysisServer._onContextsChangedController
         .add(new ContextsChangedEvent(added: [context]));
     analysisServer.schedulePerformAnalysisOperation(context);
@@ -1635,7 +1687,7 @@
     EmbedderYamlLocator locator =
         disposition.getEmbedderLocator(resourceProvider);
     Map<Folder, YamlMap> embedderYamls = locator.embedderYamls;
-    EmbedderSdk embedderSdk = new EmbedderSdk(embedderYamls);
+    EmbedderSdk embedderSdk = new EmbedderSdk(resourceProvider, embedderYamls);
     if (embedderSdk.libraryMap.size() == 0) {
       // There was no embedder file, or the file was empty, so used the default
       // SDK.
diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
index ce6235d..c17b77b 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
@@ -51,10 +51,11 @@
   }
 
   @override
-  Future<Response> sendRequest(Request request) {
+  Future<Response> sendRequest(Request request) async {
     String id = request.id;
     output.write(JSON.encode(request.toJson()) + '\n');
-    return responseStream.firstWhere((Response response) => response.id == id);
+    return await responseStream
+        .firstWhere((Response response) => response.id == id);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/channel/web_socket_channel.dart b/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
index 0368eb6..282b1f9 100644
--- a/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
@@ -55,10 +55,11 @@
   }
 
   @override
-  Future<Response> sendRequest(Request request) {
+  Future<Response> sendRequest(Request request) async {
     String id = request.id;
     socket.add(JSON.encode(request.toJson()));
-    return responseStream.firstWhere((Response response) => response.id == id);
+    return await responseStream
+        .firstWhere((Response response) => response.id == id);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 585da46..86b13a1 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -16,14 +16,15 @@
 import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/config.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';
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context.dart' as context;
 import 'package:analyzer/src/context/source.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -391,6 +392,13 @@
   static const String PACKAGE_SPEC_NAME = '.packages';
 
   /**
+   * The name of the key in an embedder file whose value is the list of
+   * libraries in the SDK.
+   * TODO(brianwilkerson) This is also defined in sdk.dart.
+   */
+  static const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
+
+  /**
    * The [ResourceProvider] using which paths are converted into [Resource]s.
    */
   final ResourceProvider resourceProvider;
@@ -515,6 +523,7 @@
       contexts.add(info.context);
       info.children.forEach(addContextAndDescendants);
     }
+
     if (innermostContainingInfo != null) {
       if (analysisRoot == innermostContainingInfo.folder) {
         addContextAndDescendants(innermostContainingInfo);
@@ -529,6 +538,11 @@
     return contexts;
   }
 
+  /**
+   * Check if this map defines embedded libraries.
+   */
+  bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null;
+
   @override
   AnalysisContext getContextFor(String path) {
     return _getInnermostContextInfoFor(path)?.context;
@@ -625,7 +639,7 @@
     if (analyzer is Map) {
       // Set ignore patterns.
       YamlList exclude = analyzer[AnalyzerOptions.exclude];
-      List<String> excludeList = _toStringList(exclude);
+      List<String> excludeList = toStringList(exclude);
       if (excludeList != null) {
         setIgnorePatternsForContext(info, excludeList);
       }
@@ -913,7 +927,8 @@
                 .where((r) => r is! DartUriResolver)
                 .toList();
             // Add an embedded URI resolver in its place.
-            resolvers.add(new DartUriResolver(new EmbedderSdk(embedderYamls)));
+            resolvers.add(new DartUriResolver(
+                new EmbedderSdk(resourceProvider, embedderYamls)));
 
             // Set a new source factory.
             SourceFactoryImpl newFactory = sourceFactory.clone();
@@ -1158,7 +1173,7 @@
     EmbedderYamlLocator locator =
         disposition.getEmbedderLocator(resourceProvider);
     Map<Folder, YamlMap> embedderYamls = locator.embedderYamls;
-    EmbedderSdk embedderSdk = new EmbedderSdk(embedderYamls);
+    EmbedderSdk embedderSdk = new EmbedderSdk(resourceProvider, embedderYamls);
     if (embedderSdk.libraryMap.size() == 0) {
       // There was no embedder file, or the file was empty, so used the default
       // SDK.
@@ -1594,25 +1609,6 @@
   }
 
   /**
-   * If all of the elements of [list] are strings, return a list of strings
-   * containing the same elements. Otherwise, return `null`.
-   */
-  List<String> _toStringList(YamlList list) {
-    if (list == null) {
-      return null;
-    }
-    List<String> stringList = <String>[];
-    for (var element in list) {
-      if (element is String) {
-        stringList.add(element);
-      } else {
-        return null;
-      }
-    }
-    return stringList;
-  }
-
-  /**
    * If the given [object] is a map, and all of the keys in the map are strings,
    * return a map containing the same mappings. Otherwise, return `null`.
    */
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 76b27ae..b99cec3 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -372,12 +372,7 @@
     List<ChangeNotice> notices = result.changeNotices;
     // nothing to analyze
     if (notices == null) {
-      bool cacheInconsistencyFixed = context.validateCacheConsistency();
-      if (cacheInconsistencyFixed) {
-        server.addOperation(new PerformAnalysisOperation(context, true));
-        return;
-      }
-      // analysis is done
+      server.scheduleCacheConsistencyValidation(context);
       setCacheSize(context, IDLE_CACHE_SIZE);
       server.sendContextAnalysisDoneNotifications(
           context, AnalysisDoneReason.COMPLETE);
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 138c20f..864f04f 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -17,6 +17,7 @@
 import 'package:analyzer/src/dart/ast/utilities.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/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart' as engine;
 import 'package:analyzer/src/generated/utilities_dart.dart' as engine;
 
@@ -254,15 +255,15 @@
     engine.SourceRange range) {
   int startLine = 0;
   int startColumn = 0;
-  {
-    engine.LineInfo lineInfo = context.getLineInfo(source);
+  try {
+    engine.LineInfo lineInfo = context.computeLineInfo(source);
     if (lineInfo != null) {
       engine.LineInfo_Location offsetLocation =
           lineInfo.getLocation(range.offset);
       startLine = offsetLocation.lineNumber;
       startColumn = offsetLocation.columnNumber;
     }
-  }
+  } on AnalysisException {}
   return new Location(
       source.fullName, range.offset, range.length, startLine, startColumn);
 }
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 bbf9cb5..7e7ae5c 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
@@ -22,6 +22,13 @@
     if (args.isEmpty) {
       return 0;
     }
+    if (entity == argList.rightParenthesis) {
+      // Parser ignores trailing commas
+      if (argList.rightParenthesis.previous?.lexeme == ',') {
+        return args.length;
+      }
+      return args.length - 1;
+    }
   }
   return null;
 }
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 4a0e1b7..37c58a69 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -118,6 +118,15 @@
   Future findTopLevelDeclarations(protocol.Request request) async {
     var params =
         new protocol.SearchFindTopLevelDeclarationsParams.fromRequest(request);
+    try {
+      // validate the regex
+      new RegExp(params.pattern);
+    } on FormatException catch (exception) {
+      server.sendResponse(new protocol.Response.invalidParameter(
+          request, 'pattern', exception.message));
+      return;
+    }
+
     await server.onAnalysisComplete;
     // respond
     String searchId = (_nextSearchId++).toString();
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index 29af16e..fad37c4 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -76,42 +76,41 @@
   }
 
   Future _createSubclasses(
-      TypeHierarchyItem item, int itemId, InterfaceType type) {
-    var future = getDirectSubClasses(_searchEngine, type.element);
-    return future.then((Set<ClassElement> subElements) {
-      List<int> subItemIds = <int>[];
-      for (ClassElement subElement in subElements) {
-        // check for recursion
-        TypeHierarchyItem subItem = _elementItemMap[subElement];
-        if (subItem != null) {
-          int id = _items.indexOf(subItem);
-          item.subclasses.add(id);
-          continue;
-        }
-        // create a subclass item
-        ExecutableElement subMemberElement = _findMemberElement(subElement);
-        subItem = new TypeHierarchyItem(convertElement(subElement),
-            memberElement: subMemberElement != null
-                ? convertElement(subMemberElement)
-                : null,
-            superclass: itemId);
-        int subItemId = _items.length;
-        // remember
-        _elementItemMap[subElement] = subItem;
-        _items.add(subItem);
-        _itemClassElements.add(subElement);
-        // add to hierarchy
-        item.subclasses.add(subItemId);
-        subItemIds.add(subItemId);
+      TypeHierarchyItem item, int itemId, InterfaceType type) async {
+    Set<ClassElement> subElements =
+        await getDirectSubClasses(_searchEngine, type.element);
+    List<int> subItemIds = <int>[];
+    for (ClassElement subElement in subElements) {
+      // check for recursion
+      TypeHierarchyItem subItem = _elementItemMap[subElement];
+      if (subItem != null) {
+        int id = _items.indexOf(subItem);
+        item.subclasses.add(id);
+        continue;
       }
-      // compute subclasses of subclasses
-      return Future.forEach(subItemIds, (int subItemId) {
-        TypeHierarchyItem subItem = _items[subItemId];
-        ClassElement subItemElement = _itemClassElements[subItemId];
-        InterfaceType subType = subItemElement.type;
-        return _createSubclasses(subItem, subItemId, subType);
-      });
-    });
+      // create a subclass item
+      ExecutableElement subMemberElement = _findMemberElement(subElement);
+      subItem = new TypeHierarchyItem(convertElement(subElement),
+          memberElement: subMemberElement != null
+              ? convertElement(subMemberElement)
+              : null,
+          superclass: itemId);
+      int subItemId = _items.length;
+      // remember
+      _elementItemMap[subElement] = subItem;
+      _items.add(subItem);
+      _itemClassElements.add(subElement);
+      // add to hierarchy
+      item.subclasses.add(subItemId);
+      subItemIds.add(subItemId);
+    }
+    // compute subclasses of subclasses
+    for (int subItemId in subItemIds) {
+      TypeHierarchyItem subItem = _items[subItemId];
+      ClassElement subItemElement = _itemClassElements[subItemId];
+      InterfaceType subType = subItemElement.type;
+      await _createSubclasses(subItem, subItemId, subType);
+    }
   }
 
   int _createSuperItem(InterfaceType type) {
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index b6c878f..28deb09 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -20,11 +20,10 @@
 import 'package:analyzer/instrumentation/file_instrumentation.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/incremental_logger.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:args/args.dart';
 import 'package:linter/src/plugin/linter_plugin.dart';
 import 'package:plugin/manager.dart';
@@ -244,6 +243,11 @@
       "incremental-resolution-validation";
 
   /**
+   * The name of the option used to enable using pub summary manager.
+   */
+  static const String ENABLE_PUB_SUMMARY_MANAGER = 'enable-pub-summary-manager';
+
+  /**
    * The name of the option used to enable fined grained invalidation.
    */
   static const String FINER_GRAINED_INVALIDATION = 'finer-grained-invalidation';
@@ -379,6 +383,8 @@
         results[ENABLE_INCREMENTAL_RESOLUTION_API];
     analysisServerOptions.enableIncrementalResolutionValidation =
         results[INCREMENTAL_RESOLUTION_VALIDATION];
+    analysisServerOptions.enablePubSummaryManager =
+        results[ENABLE_PUB_SUMMARY_MANAGER];
     analysisServerOptions.finerGrainedInvalidation =
         results[FINER_GRAINED_INVALIDATION];
     analysisServerOptions.noErrorNotification = results[NO_ERROR_NOTIFICATION];
@@ -405,18 +411,22 @@
     ExtensionManager manager = new ExtensionManager();
     manager.processPlugins(plugins);
 
-    JavaFile defaultSdkDirectory;
+    String defaultSdkPath;
     if (results[SDK_OPTION] != null) {
-      defaultSdkDirectory = new JavaFile(results[SDK_OPTION]);
+      defaultSdkPath = results[SDK_OPTION];
     } else {
       // No path to the SDK was provided.
       // Use DirectoryBasedDartSdk.defaultSdkDirectory, which will make a guess.
-      defaultSdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
+      defaultSdkPath = FolderBasedDartSdk
+          .defaultSdkDirectory(PhysicalResourceProvider.INSTANCE)
+          .path;
     }
     bool useSummaries = analysisServerOptions.fileReadMode == 'as-is';
     SdkCreator defaultSdkCreator = (AnalysisOptions options) {
-      DirectoryBasedDartSdk sdk =
-          new DirectoryBasedDartSdk(defaultSdkDirectory);
+      PhysicalResourceProvider resourceProvider =
+          PhysicalResourceProvider.INSTANCE;
+      FolderBasedDartSdk sdk = new FolderBasedDartSdk(resourceProvider,
+          FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
       sdk.analysisOptions = options;
       sdk.useSummary = useSummaries;
       return sdk;
@@ -424,7 +434,7 @@
     // TODO(brianwilkerson) It would be nice to avoid creating an SDK that
     // cannot be re-used, but the SDK is needed to create a package map provider
     // in the case where we need to run `pub` in order to get the package map.
-    DirectoryBasedDartSdk defaultSdk = defaultSdkCreator(null);
+    DartSdk defaultSdk = defaultSdkCreator(null);
     //
     // Initialize the instrumentation service.
     //
@@ -448,8 +458,7 @@
     //
     socketServer = new SocketServer(
         analysisServerOptions,
-        new DartSdkManager(defaultSdkDirectory.getAbsolutePath(), useSummaries,
-            defaultSdkCreator),
+        new DartSdkManager(defaultSdkPath, useSummaries, defaultSdkCreator),
         defaultSdk,
         service,
         serverPlugin,
@@ -532,6 +541,10 @@
         help: "enable validation of incremental resolution results (slow)",
         defaultsTo: false,
         negatable: false);
+    parser.addFlag(ENABLE_PUB_SUMMARY_MANAGER,
+        help: "enable using summaries for pub cache packages",
+        defaultsTo: false,
+        negatable: false);
     parser.addFlag(FINER_GRAINED_INVALIDATION,
         help: "enable finer grained invalidation",
         defaultsTo: false,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index f29e7a6..3b26f60 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -19,6 +19,12 @@
 int _argCount(DartCompletionRequest request) {
   AstNode node = request.target.containingNode;
   if (node is ArgumentList) {
+    if (request.target.entity == node.rightParenthesis) {
+      // Parser ignores trailing commas
+      if (node.rightParenthesis.previous?.lexeme == ',') {
+        return node.arguments.length + 1;
+      }
+    }
     return node.arguments.length;
   }
   return 0;
@@ -96,12 +102,15 @@
 }
 
 /**
- * Determine if the completion target is an emtpy argument list.
+ * Return `true` if the [request] is inside of a [NamedExpression] name.
  */
-bool _isEmptyArgList(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  return node is ArgumentList &&
-      node.leftParenthesis.next == node.rightParenthesis;
+bool _isInNamedExpression(DartCompletionRequest request) {
+  Object entity = request.target.entity;
+  if (entity is NamedExpression) {
+    Label name = entity.name;
+    return name.offset < request.offset && request.offset < name.end;
+  }
+  return false;
 }
 
 /**
@@ -217,61 +226,30 @@
     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,
       [bool appendComma = false]) {
+    bool appendColon = !_isInNamedExpression(request);
     Iterable<String> namedArgs = _namedArgs(request);
     for (ParameterElement param in parameters) {
       if (param.parameterKind == ParameterKind.NAMED) {
         _addNamedParameterSuggestion(request, namedArgs, param.name,
-            param.type?.displayName, appendComma);
+            param.type?.displayName, appendColon, appendComma);
       }
     }
   }
 
-  void _addNamedParameterSuggestion(DartCompletionRequest request,
-      List<String> namedArgs, String name, String paramType, bool appendComma) {
+  void _addNamedParameterSuggestion(
+      DartCompletionRequest request,
+      List<String> namedArgs,
+      String name,
+      String paramType,
+      bool appendColon,
+      bool appendComma) {
     if (name != null && name.length > 0 && !namedArgs.contains(name)) {
-      String completion = '$name: ';
+      String completion = name;
+      if (appendColon) {
+        completion += ': ';
+      }
       if (appendComma) {
         completion += ',';
       }
@@ -295,10 +273,6 @@
     Iterable<ParameterElement> requiredParam = parameters.where(
         (ParameterElement p) => p.parameterKind == ParameterKind.REQUIRED);
     int requiredCount = requiredParam.length;
-    if (requiredCount > 0 && _isEmptyArgList(request)) {
-      _addArgListSuggestion(requiredParam);
-      return;
-    }
     // TODO (jwren) _isAppendingToArgList can be split into two cases (with and
     // without preceded), then _isAppendingToArgList,
     // _isInsertingToArgListWithNoSynthetic and
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index e582d37..f05284d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -286,7 +286,7 @@
     }
     _resolvedImports = <ImportElement>[];
     for (ImportElement importElem in libElem.imports) {
-      if (importElem.importedLibrary.exportNamespace == null) {
+      if (importElem.importedLibrary?.exportNamespace == null) {
         await _computeAsync(this, importElem.importedLibrary.source,
             LIBRARY_ELEMENT4, performance, 'resolve imported library');
         checkAborted();
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
index e46b7e5..f0c2b3a 100644
--- 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
@@ -71,31 +71,7 @@
 
   @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);
-              }
-            }
-          }
-        }
-      }
-    }
+    _visitStatements(node.statements);
     visitNode(node);
   }
 
@@ -220,6 +196,12 @@
   }
 
   @override
+  void visitSwitchMember(SwitchMember node) {
+    _visitStatements(node.statements);
+    visitNode(node);
+  }
+
+  @override
   void visitSwitchStatement(SwitchStatement node) {
     for (SwitchMember member in node.members) {
       for (Label label in member.labels) {
@@ -263,6 +245,34 @@
       });
     }
   }
+
+  _visitStatements(NodeList<Statement> statements) {
+    for (Statement stmt in 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);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
index 917542c..132c823 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
@@ -184,8 +184,19 @@
         if (elem is FunctionTypedElement) {
           List<ParameterElement> parameters = elem.parameters;
           if (parameters != null) {
-            int index =
-                node.arguments.isEmpty ? 0 : node.arguments.indexOf(entity);
+            int index;
+            if (node.arguments.isEmpty) {
+              index = 0;
+            } else if (entity == node.rightParenthesis) {
+              // Parser ignores trailing commas
+              if (node.rightParenthesis.previous?.lexeme == ',') {
+                index = node.arguments.length;
+              } else {
+                index = node.arguments.length - 1;
+              }
+            } else {
+              index = node.arguments.indexOf(entity);
+            }
             if (0 <= index && index < parameters.length) {
               ParameterElement param = parameters[index];
               if (param?.parameterKind == ParameterKind.NAMED) {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 2024b75..2bcf316 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -89,6 +89,10 @@
       'CONVERT_INTO_EXPRESSION_BODY', 30, "Convert into expression body");
   static const CONVERT_INTO_FOR_INDEX = const AssistKind(
       'CONVERT_INTO_FOR_INDEX', 30, "Convert into for-index loop");
+  static const CONVERT_INTO_FINAL_FIELD = const AssistKind(
+      'CONVERT_INTO_FINAL_FIELD', 30, "Convert into final field");
+  static const CONVERT_INTO_GETTER =
+      const AssistKind('CONVERT_INTO_GETTER', 30, "Convert into getter");
   static const CONVERT_INTO_IS_NOT =
       const AssistKind('CONVERT_INTO_IS_NOT', 30, "Convert into is!");
   static const CONVERT_INTO_IS_NOT_EMPTY = 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 f58469d..1ae3201 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -97,6 +97,8 @@
     _addProposal_addTypeAnnotation_SimpleFormalParameter();
     _addProposal_addTypeAnnotation_VariableDeclaration();
     _addProposal_assignToLocalVariable();
+    _addProposal_convertIntoFinalField();
+    _addProposal_convertIntoGetter();
     _addProposal_convertDocumentationIntoBlock();
     _addProposal_convertDocumentationIntoLine();
     _addProposal_convertToBlockFunctionBody();
@@ -481,6 +483,113 @@
     _addAssist(DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, []);
   }
 
+  void _addProposal_convertIntoFinalField() {
+    // Find the enclosing getter.
+    MethodDeclaration getter;
+    for (AstNode n = node; n != null; n = n.parent) {
+      if (n is MethodDeclaration) {
+        getter = n;
+        break;
+      }
+      if (n is SimpleIdentifier || n is TypeName || n is TypeArgumentList) {
+        continue;
+      }
+      break;
+    }
+    if (getter == null || !getter.isGetter) {
+      return;
+    }
+    // Check that there is no corresponding setter.
+    {
+      ExecutableElement element = getter.element;
+      if (element == null) {
+        return;
+      }
+      Element enclosing = element.enclosingElement;
+      if (enclosing is ClassElement) {
+        if (enclosing.getSetter(element.name) != null) {
+          return;
+        }
+      }
+    }
+    // Try to find the returned expression.
+    Expression expression;
+    {
+      FunctionBody body = getter.body;
+      if (body is ExpressionFunctionBody) {
+        expression = body.expression;
+      } else if (body is BlockFunctionBody) {
+        List<Statement> statements = body.block.statements;
+        if (statements.length == 1) {
+          Statement statement = statements.first;
+          if (statement is ReturnStatement) {
+            expression = statement.expression;
+          }
+        }
+      }
+    }
+    // Use the returned expression as the field initializer.
+    if (expression != null) {
+      AstNode beginNodeToReplace = getter.name;
+      String code = 'final';
+      if (getter.returnType != null) {
+        beginNodeToReplace = getter.returnType;
+        code += ' ' + _getNodeText(getter.returnType);
+      }
+      code += ' ' + _getNodeText(getter.name);
+      if (expression is! NullLiteral) {
+        code += ' = ' + _getNodeText(expression);
+      }
+      code += ';';
+      _addReplaceEdit(rangeStartEnd(beginNodeToReplace, getter), code);
+      _addAssist(DartAssistKind.CONVERT_INTO_FINAL_FIELD, []);
+    }
+  }
+
+  void _addProposal_convertIntoGetter() {
+    // Find the enclosing field declaration.
+    FieldDeclaration fieldDeclaration;
+    for (AstNode n = node; n != null; n = n.parent) {
+      if (n is FieldDeclaration) {
+        fieldDeclaration = n;
+        break;
+      }
+      if (n is SimpleIdentifier ||
+          n is VariableDeclaration ||
+          n is VariableDeclarationList ||
+          n is TypeName ||
+          n is TypeArgumentList) {
+        continue;
+      }
+      break;
+    }
+    if (fieldDeclaration == null) {
+      return;
+    }
+    // The field must be final and has only one variable.
+    VariableDeclarationList fieldList = fieldDeclaration.fields;
+    if (!fieldList.isFinal || fieldList.variables.length != 1) {
+      return;
+    }
+    VariableDeclaration field = fieldList.variables.first;
+    // Prepare the initializer.
+    Expression initializer = field.initializer;
+    if (initializer == null) {
+      return;
+    }
+    // Add proposal.
+    String code = '';
+    if (fieldList.type != null) {
+      code += _getNodeText(fieldList.type) + ' ';
+    }
+    code += 'get';
+    code += ' ' + _getNodeText(field.name);
+    code += ' => ' + _getNodeText(initializer);
+    code += ';';
+    _addReplaceEdit(rangeStartEnd(fieldList.keyword, fieldDeclaration), code);
+    _addAssist(DartAssistKind.CONVERT_INTO_GETTER, []);
+  }
+
   void _addProposal_convertToBlockFunctionBody() {
     FunctionBody body = getEnclosingFunctionBody();
     // prepare expression body
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 20ca00f..e25f0b4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -80,6 +80,7 @@
     errorCode ==
         CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT ||
     errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST ||
+    errorCode == CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED ||
     errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE ||
     errorCode == HintCode.DEAD_CODE ||
     errorCode == HintCode.DIVISION_OPTIMIZATION ||
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 117884d..b64f428 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -190,6 +190,9 @@
       _addFix_createPartUri();
       _addFix_replaceImportUri();
     }
+    if (errorCode == CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED) {
+      _addFix_replaceImportUri();
+    }
     if (errorCode == HintCode.CAN_BE_NULL_AFTER_NULL_AWARE) {
       _addFix_canBeNullAfterNullAware();
     }
@@ -293,17 +296,17 @@
       _addFix_updateConstructor_forUninitializedFinalFields();
     }
     if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) {
-      bool isAsync = _addFix_addAsync();
-      if (!isAsync) {
-        _addFix_undefinedClassAccessor_useSimilar();
-        _addFix_createClass();
-        _addFix_createField();
-        _addFix_createGetter();
-        _addFix_createFunction_forFunctionType();
-        _addFix_importLibrary_withType();
-        _addFix_importLibrary_withTopLevelVariable();
-        _addFix_createLocalVariable();
-      }
+      _addFix_undefinedClassAccessor_useSimilar();
+      _addFix_createClass();
+      _addFix_createField();
+      _addFix_createGetter();
+      _addFix_createFunction_forFunctionType();
+      _addFix_importLibrary_withType();
+      _addFix_importLibrary_withTopLevelVariable();
+      _addFix_createLocalVariable();
+    }
+    if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT) {
+      _addFix_addAsync();
     }
     if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) {
       _addFix_illegalAsyncReturnType();
@@ -371,8 +374,8 @@
     doSourceChange_addElementEdit(change, target, edit);
   }
 
-  void _addFix(FixKind kind, List args) {
-    if (change.edits.isEmpty) {
+  void _addFix(FixKind kind, List args, {bool importsOnly: false}) {
+    if (change.edits.isEmpty && !importsOnly) {
       return;
     }
     // configure Change
@@ -397,14 +400,12 @@
    */
   bool _addFix_addAsync() {
     AstNode node = this.node;
-    if (_isAwaitNode()) {
-      FunctionBody body = node.getAncestor((n) => n is FunctionBody);
-      if (body != null && body.keyword == null) {
-        _addReplaceEdit(rf.rangeStartLength(body, 0), 'async ');
-        _replaceReturnTypeWithFuture(body);
-        _addFix(DartFixKind.ADD_ASYNC, []);
-        return true;
-      }
+    FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+    if (body != null && body.keyword == null) {
+      _addReplaceEdit(rf.rangeStartLength(body, 0), 'async ');
+      _replaceReturnTypeWithFuture(body);
+      _addFix(DartFixKind.ADD_ASYNC, []);
+      return true;
     }
     return false;
   }
@@ -626,13 +627,16 @@
     } else {
       for (ImportElement import in unitLibraryElement.imports) {
         if (prefixElement is PrefixElement && import.prefix == prefixElement) {
-          targetUnit = import.importedLibrary.definingCompilationUnit;
-          Source targetSource = targetUnit.source;
-          int offset = targetSource.contents.data.length;
-          sb = new SourceBuilder(targetSource.fullName, offset);
-          prefix = '$eol';
-          suffix = '$eol';
-          break;
+          LibraryElement library = import.importedLibrary;
+          if (library != null) {
+            targetUnit = library.definingCompilationUnit;
+            Source targetSource = targetUnit.source;
+            int offset = targetSource.contents.data.length;
+            sb = new SourceBuilder(targetSource.fullName, offset);
+            prefix = '$eol';
+            suffix = '$eol';
+            break;
+          }
         }
       }
       if (sb == null) {
@@ -693,14 +697,12 @@
       }
     }
     // prepare location for a new constructor
-    _ConstructorLocation targetLocation =
+    _ClassMemberLocation targetLocation =
         _prepareNewConstructorLocation(classDeclaration);
     // build constructor source
     SourceBuilder sb = new SourceBuilder(file, targetLocation.offset);
     {
-      String indent = '  ';
       sb.append(targetLocation.prefix);
-      sb.append(indent);
       sb.append(classDeclaration.name.name);
       sb.append('(');
       sb.append(fieldNames.map((name) => 'this.$name').join(', '));
@@ -739,19 +741,17 @@
     if (targetTypeNode is! ClassDeclaration) {
       return;
     }
-    _ConstructorLocation targetLocation =
+    _ClassMemberLocation targetLocation =
         _prepareNewConstructorLocation(targetTypeNode);
     String targetFile = targetElement.source.fullName;
     // build method source
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
     {
-      String indent = '  ';
       sb.append(targetLocation.prefix);
-      sb.append(indent);
       sb.append(targetElement.name);
       _addFix_undefinedMethod_create_parameters(
           sb, instanceCreation.argumentList);
-      sb.append(') {$eol$indent}');
+      sb.append(');');
       sb.append(targetLocation.suffix);
     }
     // insert source
@@ -797,15 +797,13 @@
     if (targetTypeNode is! ClassDeclaration) {
       return;
     }
-    _ConstructorLocation targetLocation =
+    _ClassMemberLocation targetLocation =
         _prepareNewConstructorLocation(targetTypeNode);
     String targetFile = targetElement.source.fullName;
     // build method source
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
     {
-      String indent = '  ';
       sb.append(targetLocation.prefix);
-      sb.append(indent);
       sb.append(targetElement.name);
       sb.append('.');
       // append name
@@ -816,7 +814,7 @@
       }
       _addFix_undefinedMethod_create_parameters(
           sb, instanceCreation.argumentList);
-      sb.append(') {$eol$indent}');
+      sb.append(');');
       sb.append(targetLocation.suffix);
     }
     // insert source
@@ -937,13 +935,11 @@
         argumentsBuffer.append(parameterName);
       }
       // add proposal
-      _ConstructorLocation targetLocation =
+      _ClassMemberLocation targetLocation =
           _prepareNewConstructorLocation(targetClassNode);
       SourceBuilder sb = new SourceBuilder(file, targetLocation.offset);
       {
-        String indent = utils.getIndent(1);
         sb.append(targetLocation.prefix);
-        sb.append(indent);
         sb.append(targetClassName);
         if (!constructorName.isEmpty) {
           sb.startPosition('NAME');
@@ -1021,7 +1017,8 @@
     }
     ClassDeclaration targetClassNode = targetTypeNode;
     // prepare location
-    _FieldLocation targetLocation = _prepareNewFieldLocation(targetClassNode);
+    _ClassMemberLocation targetLocation =
+        _prepareNewFieldLocation(targetClassNode);
     // build method source
     String targetFile = targetClassElement.source.fullName;
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -1153,7 +1150,8 @@
     }
     ClassDeclaration targetClassNode = targetTypeNode;
     // prepare location
-    _FieldLocation targetLocation = _prepareNewGetterLocation(targetClassNode);
+    _ClassMemberLocation targetLocation =
+        _prepareNewGetterLocation(targetClassNode);
     // build method source
     String targetFile = targetClassElement.source.fullName;
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -1280,11 +1278,12 @@
     // EOL management
     bool isFirst = true;
     void addEolIfNotFirst() {
-      if (!isFirst || !targetClass.members.isEmpty) {
+      if (!isFirst || _isClassWithEmptyBody(targetClass)) {
         sb.append(eol);
       }
       isFirst = false;
     }
+
     // merge getter/setter pairs into fields
     String prefix = utils.getIndent(1);
     for (int i = 0; i < elements.length; i++) {
@@ -1349,7 +1348,10 @@
       sb.append(prefix);
     }
     // return type
-    _appendType(sb, element.type.returnType);
+    if (!isSetter) {
+      _appendType(sb, element.type.returnType);
+    }
+    // keyword
     if (isGetter) {
       sb.append('get ');
     } else if (isSetter) {
@@ -1424,40 +1426,11 @@
     _addFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, []);
   }
 
-  void _addFix_importLibrary(FixKind kind, String importPath) {
-    CompilationUnitElement libraryUnitElement =
-        unitLibraryElement.definingCompilationUnit;
-    CompilationUnit libraryUnit = getParsedUnit(libraryUnitElement);
-    // prepare new import location
-    int offset = 0;
-    String prefix;
-    String suffix;
-    {
-      // if no directives
-      prefix = '';
-      suffix = eol;
-      CorrectionUtils libraryUtils = new CorrectionUtils(libraryUnit);
-      // after last directive in library
-      for (Directive directive in libraryUnit.directives) {
-        if (directive is LibraryDirective || directive is ImportDirective) {
-          offset = directive.end;
-          prefix = eol;
-          suffix = '';
-        }
-      }
-      // if still beginning of file, skip shebang and line comments
-      if (offset == 0) {
-        CorrectionUtils_InsertDesc desc = libraryUtils.getInsertDescTop();
-        offset = desc.offset;
-        prefix = desc.prefix;
-        suffix = '${desc.suffix}$eol';
-      }
-    }
-    // insert new import
-    String importSource = "${prefix}import '$importPath';$suffix";
-    _addInsertEdit(offset, importSource, libraryUnitElement);
-    // add proposal
-    _addFix(kind, [importPath]);
+  void _addFix_importLibrary(FixKind kind, LibraryElement libraryElement) {
+    librariesToImport.add(libraryElement);
+    Source librarySource = libraryElement.source;
+    String libraryUri = getLibrarySourceUri(unitLibraryElement, librarySource);
+    _addFix(kind, [libraryUri], importsOnly: true);
   }
 
   void _addFix_importLibrary_withElement(String name, ElementKind kind) {
@@ -1544,7 +1517,7 @@
           continue;
         }
         // add import
-        _addFix_importLibrary(DartFixKind.IMPORT_LIBRARY_SDK, libraryUri);
+        _addFix_importLibrary(DartFixKind.IMPORT_LIBRARY_SDK, libraryElement);
       }
     }
     // check project libraries
@@ -1576,21 +1549,8 @@
         if (element.kind != kind) {
           continue;
         }
-        // prepare "library" file
-        String libraryFile = librarySource.fullName;
-        // may be "package:" URI
-        {
-          String libraryPackageUri = findNonFileUri(context, libraryFile);
-          if (libraryPackageUri != null) {
-            _addFix_importLibrary(
-                DartFixKind.IMPORT_LIBRARY_PROJECT, libraryPackageUri);
-            continue;
-          }
-        }
-        // relative URI
-        String relativeFile = relative(libraryFile, from: unitLibraryFolder);
-        relativeFile = split(relativeFile).join('/');
-        _addFix_importLibrary(DartFixKind.IMPORT_LIBRARY_PROJECT, relativeFile);
+        _addFix_importLibrary(
+            DartFixKind.IMPORT_LIBRARY_PROJECT, libraryElement);
       }
     }
   }
@@ -2773,74 +2733,62 @@
     return node is SimpleIdentifier && node.name == 'await';
   }
 
-  _ConstructorLocation _prepareNewConstructorLocation(
+  /**
+   * Return `true` if the given [classDeclaration] has open '{' and close '}'
+   * at the same line, e.g. `class X {}`.
+   */
+  bool _isClassWithEmptyBody(ClassDeclaration classDeclaration) {
+    return utils.getLineThis(classDeclaration.leftBracket.offset) ==
+        utils.getLineThis(classDeclaration.rightBracket.offset);
+  }
+
+  _ClassMemberLocation _prepareNewClassMemberLocation(
+      ClassDeclaration classDeclaration,
+      bool shouldSkip(ClassMember existingMember)) {
+    String indent = utils.getIndent(1);
+    // Find the last target member.
+    ClassMember targetMember = null;
+    List<ClassMember> members = classDeclaration.members;
+    for (ClassMember member in members) {
+      if (shouldSkip(member)) {
+        targetMember = member;
+      } else {
+        break;
+      }
+    }
+    // After the last target member.
+    if (targetMember != null) {
+      return new _ClassMemberLocation(eol + eol + indent, targetMember.end, '');
+    }
+    // At the beginning of the class.
+    String suffix = members.isNotEmpty ||
+        _isClassWithEmptyBody(classDeclaration) ? eol : '';
+    return new _ClassMemberLocation(
+        eol + indent, classDeclaration.leftBracket.end, suffix);
+  }
+
+  _ClassMemberLocation _prepareNewConstructorLocation(
       ClassDeclaration classDeclaration) {
-    List<ClassMember> members = classDeclaration.members;
-    // find the last field/constructor
-    ClassMember lastFieldOrConstructor = null;
-    for (ClassMember member in members) {
-      if (member is FieldDeclaration || member is ConstructorDeclaration) {
-        lastFieldOrConstructor = member;
-      } else {
-        break;
-      }
-    }
-    // after the last field/constructor
-    if (lastFieldOrConstructor != null) {
-      return new _ConstructorLocation(
-          eol + eol, lastFieldOrConstructor.end, '');
-    }
-    // at the beginning of the class
-    String suffix = members.isEmpty ? '' : eol;
-    return new _ConstructorLocation(
-        eol, classDeclaration.leftBracket.end, suffix);
+    return _prepareNewClassMemberLocation(
+        classDeclaration,
+        (member) =>
+            member is FieldDeclaration || member is ConstructorDeclaration);
   }
 
-  _FieldLocation _prepareNewFieldLocation(ClassDeclaration classDeclaration) {
-    String indent = utils.getIndent(1);
-    // find the last field
-    ClassMember lastFieldOrConstructor = null;
-    List<ClassMember> members = classDeclaration.members;
-    for (ClassMember member in members) {
-      if (member is FieldDeclaration) {
-        lastFieldOrConstructor = member;
-      } else {
-        break;
-      }
-    }
-    // after the last field
-    if (lastFieldOrConstructor != null) {
-      return new _FieldLocation(
-          eol + eol + indent, lastFieldOrConstructor.end, '');
-    }
-    // at the beginning of the class
-    String suffix = members.isEmpty ? '' : eol;
-    return new _FieldLocation(
-        eol + indent, classDeclaration.leftBracket.end, suffix);
+  _ClassMemberLocation _prepareNewFieldLocation(
+      ClassDeclaration classDeclaration) {
+    return _prepareNewClassMemberLocation(
+        classDeclaration, (member) => member is FieldDeclaration);
   }
 
-  _FieldLocation _prepareNewGetterLocation(ClassDeclaration classDeclaration) {
-    String indent = utils.getIndent(1);
-    // find an existing target member
-    ClassMember prevMember = null;
-    List<ClassMember> members = classDeclaration.members;
-    for (ClassMember member in members) {
-      if (member is FieldDeclaration ||
-          member is ConstructorDeclaration ||
-          member is MethodDeclaration && member.isGetter) {
-        prevMember = member;
-      } else {
-        break;
-      }
-    }
-    // after the last field/getter
-    if (prevMember != null) {
-      return new _FieldLocation(eol + eol + indent, prevMember.end, '');
-    }
-    // at the beginning of the class
-    String suffix = members.isEmpty ? '' : eol;
-    return new _FieldLocation(
-        eol + indent, classDeclaration.leftBracket.end, suffix);
+  _ClassMemberLocation _prepareNewGetterLocation(
+      ClassDeclaration classDeclaration) {
+    return _prepareNewClassMemberLocation(
+        classDeclaration,
+        (member) =>
+            member is FieldDeclaration ||
+            member is ConstructorDeclaration ||
+            member is MethodDeclaration && member.isGetter);
   }
 
   /**
@@ -2962,6 +2910,17 @@
 }
 
 /**
+ * Describes the location for a newly created [ClassMember].
+ */
+class _ClassMemberLocation {
+  final String prefix;
+  final int offset;
+  final String suffix;
+
+  _ClassMemberLocation(this.prefix, this.offset, this.suffix);
+}
+
+/**
  * Helper for finding [Element] with name closest to the given.
  */
 class _ClosestElementFinder {
@@ -2989,25 +2948,3 @@
     }
   }
 }
-
-/**
- * Describes the location for a newly created [ConstructorDeclaration].
- */
-class _ConstructorLocation {
-  final String prefix;
-  final int offset;
-  final String suffix;
-
-  _ConstructorLocation(this.prefix, this.offset, this.suffix);
-}
-
-/**
- * Describes the location for a newly created [FieldDeclaration].
- */
-class _FieldLocation {
-  final String prefix;
-  final int offset;
-  final String suffix;
-
-  _FieldLocation(this.prefix, this.offset, this.suffix);
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index 0aa0b8d..87c38dd 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -37,13 +37,14 @@
 }
 
 /**
- * Returns the [ImportElement] that is referenced by [prefixNode] with
- * an [PrefixElement], maybe `null`.
+ * Return the [ImportElement] that is referenced by [prefixNode], or `null` if
+ * the node does not reference a prefix or if we cannot determine which import
+ * is being referenced.
  */
 ImportElement getImportElement(SimpleIdentifier prefixNode) {
-  if (prefixNode.parent is ImportDirective) {
-    ImportDirective importDirective = prefixNode.parent;
-    return importDirective.element;
+  AstNode parent = prefixNode.parent;
+  if (parent is ImportDirective) {
+    return parent.element;
   }
   ImportElementInfo info = internal_getImportElementInfo(prefixNode);
   return info?.element;
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
index 0d35566..56d4bb0 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
@@ -47,7 +47,9 @@
 
   bool _isUnresolvedUri(UriBasedDirective directive) {
     for (AnalysisError error in errors) {
-      if (error.errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST &&
+      ErrorCode errorCode = error.errorCode;
+      if ((errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST ||
+              errorCode == CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED) &&
           directive.uri.offset == error.offset) {
         return true;
       }
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 551964a..445aab2 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -33,38 +33,91 @@
     Set<LibraryElement> libraries) {
   CompilationUnitElement libUnitElement = targetLibrary.definingCompilationUnit;
   CompilationUnit libUnit = getParsedUnit(libUnitElement);
-  // prepare new import location
-  int offset = 0;
-  String prefix;
-  String suffix;
-  {
-    // if no directives
-    prefix = '';
-    CorrectionUtils libraryUtils = new CorrectionUtils(libUnit);
-    String eol = libraryUtils.endOfLine;
-    suffix = eol;
-    // after last directive in library
-    for (Directive directive in libUnit.directives) {
-      if (directive is LibraryDirective || directive is ImportDirective) {
-        offset = directive.end;
-        prefix = eol;
-        suffix = '';
-      }
-    }
-    // if still at the beginning of the file, skip shebang and line comments
-    if (offset == 0) {
-      CorrectionUtils_InsertDesc desc = libraryUtils.getInsertDescTop();
-      offset = desc.offset;
-      prefix = desc.prefix;
-      suffix = desc.suffix + eol;
+  CorrectionUtils libUtils = new CorrectionUtils(libUnit);
+  String eol = libUtils.endOfLine;
+  // Prepare information about existing imports.
+  LibraryDirective libraryDirective;
+  List<_ImportDirectiveInfo> importDirectives = <_ImportDirectiveInfo>[];
+  for (Directive directive in libUnit.directives) {
+    if (directive is LibraryDirective) {
+      libraryDirective = directive;
+    } else if (directive is ImportDirective) {
+      importDirectives.add(new _ImportDirectiveInfo(
+          directive.uriContent, directive.offset, directive.end));
     }
   }
-  // insert imports
-  for (LibraryElement library in libraries) {
-    String importPath = getLibrarySourceUri(targetLibrary, library.source);
-    String importCode = "${prefix}import '$importPath';$suffix";
-    doSourceChange_addElementEdit(
-        change, targetLibrary, new SourceEdit(offset, 0, importCode));
+
+  // Prepare all URIs to import.
+  List<String> uriList = libraries
+      .map((library) => getLibrarySourceUri(targetLibrary, library.source))
+      .toList();
+  uriList.sort((a, b) => a.compareTo(b));
+
+  // Insert imports: between existing imports.
+  if (importDirectives.isNotEmpty) {
+    bool isFirstPackage = true;
+    for (String importUri in uriList) {
+      bool inserted = false;
+      bool isPackage = importUri.startsWith('package:');
+      bool isAfterDart = false;
+      for (_ImportDirectiveInfo existingImport in importDirectives) {
+        if (existingImport.uri.startsWith('dart:')) {
+          isAfterDart = true;
+        }
+        if (existingImport.uri.startsWith('package:')) {
+          isFirstPackage = false;
+        }
+        if (importUri.compareTo(existingImport.uri) < 0) {
+          String importCode = "import '$importUri';$eol";
+          doSourceChange_addElementEdit(change, targetLibrary,
+              new SourceEdit(existingImport.offset, 0, importCode));
+          inserted = true;
+          break;
+        }
+      }
+      if (!inserted) {
+        String importCode = "${eol}import '$importUri';";
+        if (isPackage && isFirstPackage && isAfterDart) {
+          importCode = eol + importCode;
+        }
+        doSourceChange_addElementEdit(change, targetLibrary,
+            new SourceEdit(importDirectives.last.end, 0, importCode));
+      }
+      if (isPackage) {
+        isFirstPackage = false;
+      }
+    }
+    return;
+  }
+
+  // Insert imports: after the library directive.
+  if (libraryDirective != null) {
+    String prefix = eol + eol;
+    for (String importUri in uriList) {
+      String importCode = "${prefix}import '$importUri';";
+      prefix = eol;
+      doSourceChange_addElementEdit(change, targetLibrary,
+          new SourceEdit(libraryDirective.end, 0, importCode));
+    }
+    return;
+  }
+
+  // If still at the beginning of the file, skip shebang and line comments.
+  {
+    CorrectionUtils_InsertDesc desc = libUtils.getInsertDescTop();
+    int offset = desc.offset;
+    for (int i = 0; i < uriList.length; i++) {
+      String importUri = uriList[i];
+      String importCode = "import '$importUri';$eol";
+      if (i == 0) {
+        importCode = desc.prefix + importCode;
+      }
+      if (i == uriList.length - 1) {
+        importCode = importCode + desc.suffix;
+      }
+      doSourceChange_addElementEdit(
+          change, targetLibrary, new SourceEdit(offset, 0, importCode));
+    }
   }
 }
 
@@ -1466,6 +1519,14 @@
   }
 }
 
+class _ImportDirectiveInfo {
+  final String uri;
+  final int offset;
+  final int end;
+
+  _ImportDirectiveInfo(this.uri, this.offset, this.end);
+}
+
 /**
  * A container with a source and its precedence.
  */
diff --git a/pkg/analysis_server/lib/src/services/index/index.dart b/pkg/analysis_server/lib/src/services/index/index.dart
index 7270ac2..aa06637 100644
--- a/pkg/analysis_server/lib/src/services/index/index.dart
+++ b/pkg/analysis_server/lib/src/services/index/index.dart
@@ -341,24 +341,39 @@
    * [element] is not referenced in the [index].
    */
   int findElementId(Element element) {
+    IndexElementInfo info = new IndexElementInfo(element);
+    element = info.element;
     // Find the id of the element's unit.
     int unitId = getUnitId(element);
     if (unitId == -1) {
       return -1;
     }
     // Prepare information about the element.
-    ElementInfo info = PackageIndexAssembler.newElementInfo(unitId, element);
-    // Find the first occurrence of an element with the same offset.
-    int elementId = _findFirstOccurrence(index.elementOffsets, info.offset);
+    int unitMemberId = getElementUnitMemberId(element);
+    if (unitMemberId == -1) {
+      return -1;
+    }
+    int classMemberId = getElementClassMemberId(element);
+    if (classMemberId == -1) {
+      return -1;
+    }
+    int parameterId = getElementParameterId(element);
+    if (parameterId == -1) {
+      return -1;
+    }
+    // Try to find the element id using classMemberId, parameterId, and kind.
+    int elementId =
+        _findFirstOccurrence(index.elementNameUnitMemberIds, unitMemberId);
     if (elementId == -1) {
       return -1;
     }
-    // Try to find the element id using offset, unit and kind.
     for (;
-        elementId < index.elementOffsets.length &&
-            index.elementOffsets[elementId] == info.offset;
+        elementId < index.elementNameUnitMemberIds.length &&
+            index.elementNameUnitMemberIds[elementId] == unitMemberId;
         elementId++) {
       if (index.elementUnits[elementId] == unitId &&
+          index.elementNameClassMemberIds[elementId] == classMemberId &&
+          index.elementNameParameterIds[elementId] == parameterId &&
           index.elementKinds[elementId] == info.kind) {
         return elementId;
       }
@@ -383,6 +398,45 @@
   }
 
   /**
+   * Return the [element]'s class member name identifier, `null` is not a class
+   * member, or `-1` if the [element] is not referenced in the [index].
+   */
+  int getElementClassMemberId(Element element) {
+    for (; element != null; element = element.enclosingElement) {
+      if (element.enclosingElement is ClassElement) {
+        return getStringId(element.name);
+      }
+    }
+    return getStringId(PackageIndexAssembler.NULL_STRING);
+  }
+
+  /**
+   * Return the [element]'s class member name identifier, `null` is not a class
+   * member, or `-1` if the [element] is not referenced in the [index].
+   */
+  int getElementParameterId(Element element) {
+    for (; element != null; element = element.enclosingElement) {
+      if (element is ParameterElement) {
+        return getStringId(element.name);
+      }
+    }
+    return getStringId(PackageIndexAssembler.NULL_STRING);
+  }
+
+  /**
+   * Return the [element]'s top-level name identifier, `0` is the unit, or
+   * `-1` if the [element] is not referenced in the [index].
+   */
+  int getElementUnitMemberId(Element element) {
+    for (; element != null; element = element.enclosingElement) {
+      if (element.enclosingElement is CompilationUnitElement) {
+        return getStringId(element.name);
+      }
+    }
+    return getStringId(PackageIndexAssembler.NULL_STRING);
+  }
+
+  /**
    * Complete with a list of locations where the given [element] has relation
    * of the given [kind].
    */
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 106684a..88e0d86 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -70,7 +70,7 @@
     implements ExtractMethodRefactoring {
   static const ERROR_EXITS =
       'Selected statements contain a return statement, but not all possible '
-      'execuion flows exit. Semantics may not be preserved.';
+      'execution flows exit. Semantics may not be preserved.';
 
   final SearchEngine searchEngine;
   final CompilationUnit unit;
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index c6b552f..1822f1b 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -58,15 +58,9 @@
  * Returns a [Set] with direct subclasses of [seed].
  */
 Future<Set<ClassElement>> getDirectSubClasses(
-    SearchEngine searchEngine, ClassElement seed) {
-  return searchEngine.searchSubtypes(seed).then((List<SearchMatch> matches) {
-    Set<ClassElement> subClasses = new HashSet<ClassElement>();
-    for (SearchMatch match in matches) {
-      ClassElement subClass = match.element;
-      subClasses.add(subClass);
-    }
-    return subClasses;
-  });
+    SearchEngine searchEngine, ClassElement seed) async {
+  List<SearchMatch> matches = await searchEngine.searchSubtypes(seed);
+  return matches.map((match) => match.element).toSet();
 }
 
 /**
@@ -74,17 +68,16 @@
  *         their subclasses.
  */
 Future<Set<ClassMemberElement>> getHierarchyMembers(
-    SearchEngine searchEngine, ClassMemberElement member) {
+    SearchEngine searchEngine, ClassMemberElement member) async {
   Set<ClassMemberElement> result = new HashSet<ClassMemberElement>();
-  // constructor
-  if (member is ConstructorElement) {
+  // static elements
+  if (member.isStatic || member is ConstructorElement) {
     result.add(member);
     return new Future.value(result);
   }
   // method, field, etc
   String name = member.displayName;
   ClassElement memberClass = member.enclosingElement;
-  List<Future> futures = <Future>[];
   Set<ClassElement> searchClasses = getSuperClasses(memberClass);
   searchClasses.add(memberClass);
   for (ClassElement superClass in searchClasses) {
@@ -93,23 +86,19 @@
       continue;
     }
     // check all sub- classes
-    var subClassFuture = getSubClasses(searchEngine, superClass);
-    var membersFuture = subClassFuture.then((Set<ClassElement> subClasses) {
-      subClasses.add(superClass);
-      for (ClassElement subClass in subClasses) {
-        List<Element> subClassMembers = getChildren(subClass, name);
-        for (Element member in subClassMembers) {
-          if (member is ClassMemberElement) {
-            result.add(member);
-          }
+    Set<ClassElement> subClasses =
+        await getSubClasses(searchEngine, superClass);
+    subClasses.add(superClass);
+    for (ClassElement subClass in subClasses) {
+      List<Element> subClassMembers = getChildren(subClass, name);
+      for (Element member in subClassMembers) {
+        if (member is ClassMemberElement) {
+          result.add(member);
         }
       }
-    });
-    futures.add(membersFuture);
+    }
   }
-  return Future.wait(futures).then((_) {
-    return result;
-  });
+  return result;
 }
 
 /**
@@ -133,15 +122,9 @@
  * Returns a [Set] with all direct and indirect subclasses of [seed].
  */
 Future<Set<ClassElement>> getSubClasses(
-    SearchEngine searchEngine, ClassElement seed) {
-  return searchEngine.searchAllSubtypes(seed).then((List<SearchMatch> matches) {
-    Set<ClassElement> ancestors = new HashSet<ClassElement>();
-    for (SearchMatch match in matches) {
-      ClassElement ancestor = match.element;
-      ancestors.add(ancestor);
-    }
-    return ancestors;
-  });
+    SearchEngine searchEngine, ClassElement seed) async {
+  List<SearchMatch> matches = await searchEngine.searchAllSubtypes(seed);
+  return matches.map((match) => match.element).toSet();
 }
 
 /**
@@ -167,8 +150,8 @@
       }
     }
     // append interfaces
-    for (InterfaceType intf in current.interfaces) {
-      queue.add(intf.element);
+    for (InterfaceType interface in current.interfaces) {
+      queue.add(interface.element);
     }
   }
   // we don't need "seed" itself
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 2d6f815..5b2b6e3 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
@@ -35,7 +35,8 @@
   }
 
   @override
-  Future<List<SearchMatch>> searchMemberDeclarations(String pattern) {
+  Future<List<SearchMatch>> searchMemberDeclarations(String name) {
+    String pattern = '^$name\$';
     return _searchDefinedNames(pattern, IndexNameKind.classMember);
   }
 
@@ -260,12 +261,10 @@
       ParameterElement parameter) async {
     List<SearchMatch> matches = <SearchMatch>[];
     matches.addAll(await _searchReferences(parameter));
-    matches.addAll(await _searchReferences_Local(
-        parameter,
-        (n) =>
-            n is ConstructorDeclaration ||
-            n is MethodDeclaration ||
-            n is FunctionExpression));
+    matches.addAll(await _searchReferences_Local(parameter, (AstNode node) {
+      AstNode parent = node.parent;
+      return parent is ClassDeclaration || parent is CompilationUnit;
+    }));
     return matches;
   }
 
@@ -407,7 +406,7 @@
   }
 
   void _addMatch(AstNode node, MatchKind kind) {
-    bool isQualified = node is SimpleIdentifier && node.isQualified;
+    bool isQualified = node.parent is Label;
     matches.add(new SearchMatch(context, libraryUri, unitUri, kind,
         rangeNode(node), true, isQualified));
   }
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index bce9dc8..887e1b7 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer/plugin/resolver_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:plugin/plugin.dart';
 
 /**
@@ -31,7 +30,7 @@
    */
   final DartSdkManager sdkManager;
 
-  final DirectoryBasedDartSdk defaultSdk;
+  final DartSdk defaultSdk;
   final InstrumentationService instrumentationService;
   final ServerPlugin serverPlugin;
   final ResolverProvider fileResolverProvider;
diff --git a/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart b/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
index 3d99622..48abf8e 100644
--- a/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
+++ b/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
@@ -11,8 +11,8 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -80,7 +80,7 @@
    * [RunPubList] and [WriteFile] implementations may be injected for testing
    */
   CachingPubPackageMapProvider(
-      ResourceProvider resourceProvider, DirectoryBasedDartSdk sdk,
+      ResourceProvider resourceProvider, FolderBasedDartSdk sdk,
       [RunPubList runPubList, this._writeFile])
       : super(resourceProvider, sdk, runPubList) {
     if (_writeFile == null) {
@@ -106,7 +106,8 @@
     // Check for cached entry
     Map entry = _cache[folder.path];
     if (entry != null) {
-      Map<String, int> modificationStamps = entry[modificationStampsKey];
+      Map<String, int> modificationStamps =
+          entry[modificationStampsKey] as Map<String, int>;
       if (modificationStamps != null) {
         //
         // Check to see if any dependencies have changed
@@ -217,7 +218,7 @@
         TimestampedData<String> data = source.contents;
         Map map = JSON.decode(data.data);
         if (map[cacheVersionKey] == cacheVersion) {
-          _cache = map[cacheKey];
+          _cache = map[cacheKey] as Map<String, Map>;
           _cacheModificationTime = data.modificationTime;
         }
       } catch (exception, stackTrace) {
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 0e9a2ed..d3a8cdf 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -21,24 +21,24 @@
 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/memory_use.dart';
 import 'package:analysis_server/src/status/validator.dart';
 import 'package:analysis_server/src/utilities/average.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/source/sdk_ext.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
 import 'package:analyzer/src/context/source.dart';
+import 'package:analyzer/src/dart/sdk/sdk.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/resolver.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/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
@@ -258,6 +258,11 @@
   static const String ELEMENT_PATH = '/element';
 
   /**
+   * The path used to request an analysis of the memory use of the analyzer.
+   */
+  static const String MEMORY_USE_PATH = '/memoryUse';
+
+  /**
    * The path used to request an overlay contents.
    */
   static const String OVERLAY_PATH = '/overlay';
@@ -390,6 +395,8 @@
       _returnDiagnosticInfo(request);
     } else if (path == ELEMENT_PATH) {
       _returnElement(request);
+    } else if (path == MEMORY_USE_PATH) {
+      _returnMemoryUsage(request);
     } else if (path == OVERLAY_PATH) {
       _returnOverlayContents(request);
     } else if (path == OVERLAYS_PATH) {
@@ -662,6 +669,7 @@
             _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label],
                 classes: ["right", "right", null]);
           }
+
           tags.forEach(writeRow);
           buffer.write('</table>');
           //
@@ -676,6 +684,7 @@
             }
             counts[key] = count;
           }
+
           Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>();
           Map<String, int> sourceTypeCounts = new HashMap<String, int>();
           Map<String, int> typeCounts = new HashMap<String, int>();
@@ -743,6 +752,7 @@
                 }
               });
             }
+
             explicitSourceCount += explicitSources.length;
             explicitLineCount += lineCount(explicitSources, true);
             implicitSourceCount += implicitSources.length;
@@ -812,6 +822,30 @@
                 classes: [null, "right"]);
           }
           buffer.write('</table>');
+
+          {
+            buffer.write('<p><b>Cache consistency statistics</b></p>');
+            buffer.write(
+                '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+            _writeRow(buffer, ['Name', 'Count'], header: true);
+            _writeRow(buffer, [
+              'Changed',
+              PerformanceStatistics
+                  .cacheConsistencyValidationStatistics.numOfChanged
+            ], classes: [
+              null,
+              "right"
+            ]);
+            _writeRow(buffer, [
+              'Removed',
+              PerformanceStatistics
+                  .cacheConsistencyValidationStatistics.numOfRemoved
+            ], classes: [
+              null,
+              "right"
+            ]);
+            buffer.write('</table>');
+          }
         }, (StringBuffer buffer) {
           //
           // Write task model timing information.
@@ -1367,6 +1401,7 @@
         buffer.write('</table></p>');
       }
     }
+
     void writeOptions(StringBuffer buffer, AnalysisOptionsImpl options,
         {void writeAdditionalOptions(StringBuffer buffer)}) {
       if (options == null) {
@@ -1383,8 +1418,6 @@
       _writeOption(
           buffer, 'Enable strict call checks', options.enableStrictCallChecks);
       _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
-      _writeOption(
-          buffer, 'Enable trailing commas', options.enableTrailingCommas);
       _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
       _writeOption(buffer, 'Generate errors in implicit files',
           options.generateImplicitErrors);
@@ -1419,7 +1452,7 @@
             DartSdk sdk = context?.sourceFactory?.dartSdk;
             writeOptions(buffer, sdk?.context?.analysisOptions,
                 writeAdditionalOptions: (StringBuffer buffer) {
-              if (sdk is DirectoryBasedDartSdk) {
+              if (sdk is FolderBasedDartSdk) {
                 _writeOption(buffer, 'Use summaries', sdk.useSummary);
               }
             });
@@ -1456,9 +1489,9 @@
               DartSdk sdk = resolver.dartSdk;
               buffer.write(' (sdk = ');
               buffer.write(sdk.runtimeType);
-              if (sdk is DirectoryBasedDartSdk) {
+              if (sdk is FolderBasedDartSdk) {
                 buffer.write(' (path = ');
-                buffer.write(sdk.directory.getAbsolutePath());
+                buffer.write(sdk.directory.path);
                 buffer.write(')');
               } else if (sdk is EmbedderSdk) {
                 buffer.write(' (map = ');
@@ -1620,6 +1653,85 @@
     });
   }
 
+  void _returnMemoryUsage(HttpRequest request) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Memory Use', [],
+          (StringBuffer buffer) {
+        AnalysisServer server = _server.analysisServer;
+        MemoryUseData data = new MemoryUseData();
+        data.processAnalysisServer(server);
+        Map<Type, Set> instances = data.instances;
+        List<Type> instanceTypes = instances.keys.toList();
+        instanceTypes.sort((Type left, Type right) =>
+            left.toString().compareTo(right.toString()));
+        Map<Type, Set> ownerMap = data.ownerMap;
+        List<Type> ownerTypes = ownerMap.keys.toList();
+        ownerTypes.sort((Type left, Type right) =>
+            left.toString().compareTo(right.toString()));
+
+        _writeTwoColumns(buffer, (StringBuffer buffer) {
+          buffer.write('<h3>Instance Counts (reachable from contexts)</h3>');
+          buffer.write('<table>');
+          _writeRow(buffer, ['Count', 'Class name'], header: true);
+          instanceTypes.forEach((Type type) {
+            _writeRow(buffer, [instances[type].length, type],
+                classes: ['right', null]);
+          });
+          buffer.write('</table>');
+
+          buffer.write(
+              '<h3>Ownership (which classes of objects hold on to others)</h3>');
+          buffer.write('<table>');
+          _writeRow(buffer, ['Referenced Type', 'Referencing Types'],
+              header: true);
+          ownerTypes.forEach((Type type) {
+            List<String> referencingTypes =
+                ownerMap[type].map((Type type) => type.toString()).toList();
+            referencingTypes.sort();
+            _writeRow(buffer, [type, referencingTypes.join('<br>')]);
+          });
+          buffer.write('</table>');
+
+          buffer.write('<h3>Other Data</h3>');
+          buffer.write('<p>');
+          buffer.write(data.uniqueTargetedResults.length);
+          buffer.write(' non-equal TargetedResults</p>');
+          buffer.write('<p>');
+          buffer.write(data.uniqueLSUs.length);
+          buffer.write(' non-equal LibrarySpecificUnits</p>');
+          int count = data.mismatchedTargets.length;
+          buffer.write('<p>');
+          buffer.write(count);
+          buffer.write(' mismatched targets</p>');
+          if (count < 100) {
+            for (AnalysisTarget target in data.mismatchedTargets) {
+              buffer.write(target);
+              buffer.write('<br>');
+            }
+          }
+        }, (StringBuffer buffer) {
+          void writeCountMap(String title, Map<Type, int> counts) {
+            List<Type> classNames = counts.keys.toList();
+            classNames.sort((Type left, Type right) =>
+                left.toString().compareTo(right.toString()));
+
+            buffer.write('<h3>$title</h3>');
+            buffer.write('<table>');
+            _writeRow(buffer, ['Count', 'Class name'], header: true);
+            classNames.forEach((Type type) {
+              _writeRow(buffer, [counts[type], type], classes: ['right', null]);
+            });
+            buffer.write('</table>');
+          }
+
+          writeCountMap('Directly Held AST Nodes', data.directNodeCounts);
+          writeCountMap('Indirectly Held AST Nodes', data.indirectNodeCounts);
+          writeCountMap('Directly Held Elements', data.elementCounts);
+        });
+      });
+    });
+  }
+
   void _returnOverlayContents(HttpRequest request) {
     String path = request.requestedUri.queryParameters[PATH_PARAM];
     if (path == null) {
@@ -2204,6 +2316,7 @@
     int length = keys.length;
     buffer.write('{');
     for (int i = 0; i < length; i++) {
+      buffer.write('<br>');
       String key = keys[i];
       if (i > 0) {
         buffer.write(', ');
@@ -2212,7 +2325,7 @@
       buffer.write(' = ');
       buffer.write(map[key]);
     }
-    buffer.write('}');
+    buffer.write('<br>}');
   }
 
   /**
@@ -2265,6 +2378,8 @@
         '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('th {text-align: left; vertical-align:top;}');
+    buffer.write('tr {vertical-align:top;}');
     buffer.write('</style>');
     buffer.write('</head>');
 
@@ -2307,6 +2422,7 @@
       buffer.write(plugin.runtimeType);
       buffer.write(')<br>');
     }
+
     buffer.write('<h3>Plugin Status</h3><p>');
     writePlugin(AnalysisEngine.instance.enginePlugin);
     writePlugin(_server.serverPlugin);
@@ -2423,6 +2539,9 @@
       buffer.write('<p>');
       buffer.write(makeLink(DIAGNOSTIC_PATH, {}, 'General diagnostics'));
       buffer.write('</p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(MEMORY_USE_PATH, {}, 'Memory usage'));
+      buffer.write(' <small>(long running)</small></p>');
     }, (StringBuffer buffer) {
       _writeSubscriptionList(buffer, ServerService.VALUES, services);
     });
diff --git a/pkg/analysis_server/lib/src/status/memory_use.dart b/pkg/analysis_server/lib/src/status/memory_use.dart
new file mode 100644
index 0000000..92657bc
--- /dev/null
+++ b/pkg/analysis_server/lib/src/status/memory_use.dart
@@ -0,0 +1,314 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.memory_use;
+
+import 'dart:collection';
+
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+
+/**
+ * A visitor that will count the number of instances of each type of AST node.
+ */
+class AstNodeCounter extends UnifyingAstVisitor<Null> {
+  /**
+   * A table mapping the types of the AST nodes to the number of instances
+   * visited.
+   */
+  final Map<Type, int> nodeCounts;
+
+  /**
+   * Initialize a newly created counter to increment the counts in the given map
+   * of [nodeCounts].
+   */
+  AstNodeCounter(this.nodeCounts);
+
+  @override
+  visitNode(AstNode node) {
+    Type type = node.runtimeType;
+    int count = nodeCounts[type] ?? 0;
+    nodeCounts[type] = count + 1;
+    super.visitNode(node);
+  }
+}
+
+/**
+ * A visitor that will count the number of instances of each type of element.
+ */
+class ElementCounter extends GeneralizingElementVisitor<Null> {
+  /**
+   * A table mapping the types of the elements to the number of instances
+   * visited.
+   */
+  final Map<Type, int> elementCounts;
+
+  /**
+   * A table mapping the types of the AST nodes to the number of instances
+   * visited.
+   */
+  final Map<Type, int> nodeCounts;
+
+  /**
+   * Initialize a newly created counter to increment the counts in the given map
+   * of [elementCounts].
+   */
+  ElementCounter(this.elementCounts, this.nodeCounts);
+
+  @override
+  visitConstructorElement(ConstructorElement element) {
+    if (element is ConstructorElementImpl) {
+      List<ConstructorInitializer> initializers = element.constantInitializers;
+      if (initializers != null) {
+        initializers.forEach((ConstructorInitializer initializer) {
+          _countNodes(initializer);
+        });
+      }
+    }
+    visitElement(element);
+  }
+
+  @override
+  visitElement(Element element) {
+    Type type = element.runtimeType;
+    int count = elementCounts[type] ?? 0;
+    elementCounts[type] = count + 1;
+    element.metadata.forEach((ElementAnnotation annotation) {
+      if (annotation is ElementAnnotationImpl) {
+        _countNodes(annotation.annotationAst);
+      }
+    });
+    super.visitElement(element);
+  }
+
+  visitFieldElement(FieldElement element) {
+    if (element is ConstVariableElement) {
+      _countInitializer(element as ConstVariableElement);
+    }
+    visitElement(element);
+  }
+
+  visitLocalVariableElement(LocalVariableElement element) {
+    if (element is ConstVariableElement) {
+      _countInitializer(element as ConstVariableElement);
+    }
+    visitElement(element);
+  }
+
+  visitParameterElement(ParameterElement element) {
+    if (element is ConstVariableElement) {
+      _countInitializer(element as ConstVariableElement);
+    }
+    visitElement(element);
+  }
+
+  visitTopLevelVariableElement(TopLevelVariableElement element) {
+    if (element is ConstVariableElement) {
+      _countInitializer(element as ConstVariableElement);
+    }
+    visitElement(element);
+  }
+
+  void _countInitializer(ConstVariableElement element) {
+    _countNodes(element.constantInitializer);
+  }
+
+  void _countNodes(AstNode node) {
+    if (node != null) {
+      node.accept(new AstNodeCounter(nodeCounts));
+    }
+  }
+}
+
+/**
+ * A set used when the number of instances of some type is too large to be kept.
+ */
+class InfiniteSet implements Set {
+  /**
+   * The unique instance of this class.
+   */
+  static final InfiniteSet instance = new InfiniteSet();
+
+  @override
+  int get length => -1;
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) {
+    throw new UnsupportedError('Do not use instances of InfiniteSet');
+  }
+}
+
+/**
+ * Computes memory usage data by traversing the data structures reachable from
+ * an analysis server.
+ */
+class MemoryUseData {
+  /**
+   * The maximum size of an instance set.
+   */
+  static const int maxInstanceSetSize = 1000000;
+
+  /**
+   * A table mapping classes to instances of the class.
+   */
+  Map<Type, Set> instances = new HashMap<Type, Set>();
+
+  /**
+   * A table mapping classes to the classes of objects from which they were
+   * reached.
+   */
+  Map<Type, Set<Type>> ownerMap = new HashMap<Type, Set<Type>>();
+
+  /**
+   * A set of all the library specific units, using equality rather than
+   * identity in order to determine whether re-using equal instances would save
+   * significant space.
+   */
+  Set<LibrarySpecificUnit> uniqueLSUs = new HashSet<LibrarySpecificUnit>();
+
+  /**
+   * A set of all the targeted results, using equality rather than identity in
+   * order to determine whether re-using equal instances would save significant
+   * space.
+   */
+  Set<TargetedResult> uniqueTargetedResults = new HashSet<TargetedResult>();
+
+  /**
+   * A set containing all of the analysis targets for which the key in the
+   * cache partition is not the same instance as the target stored in the entry.
+   */
+  Set<AnalysisTarget> mismatchedTargets = new HashSet<AnalysisTarget>();
+
+  /**
+   * A table mapping the types of AST nodes to the number of instances being
+   * held directly (as values in the cache).
+   */
+  Map<Type, int> directNodeCounts = new HashMap<Type, int>();
+
+  /**
+   * A table mapping the types of AST nodes to the number of instances being
+   * held indirectly (such as nodes reachable from element models).
+   */
+  Map<Type, int> indirectNodeCounts = new HashMap<Type, int>();
+
+  /**
+   * A table mapping the types of the elements to the number of instances being
+   * held directly (as values in the cache).
+   */
+  final Map<Type, int> elementCounts = new HashMap<Type, int>();
+
+  /**
+   * Initialize a newly created instance.
+   */
+  MemoryUseData();
+
+  /**
+   * Traverse an analysis [server] to compute memory usage data.
+   */
+  void processAnalysisServer(AnalysisServer server) {
+    _recordInstance(server, null);
+    Iterable<AnalysisContext> contexts = server.analysisContexts;
+    for (AnalysisContextImpl context in contexts) {
+      _processAnalysisContext(context, server);
+    }
+    DartSdkManager manager = server.sdkManager;
+    List<SdkDescription> descriptors = manager.sdkDescriptors;
+    for (SdkDescription descriptor in descriptors) {
+      _processAnalysisContext(
+          manager.getSdk(descriptor, () => null).context, manager);
+    }
+  }
+
+  void _processAnalysisContext(AnalysisContextImpl context, Object owner) {
+    _recordInstance(context, owner);
+    _recordInstance(context.analysisCache, context);
+    CachePartition partition = context.privateAnalysisCachePartition;
+    Map<AnalysisTarget, CacheEntry> map = partition.entryMap;
+    map.forEach((AnalysisTarget target, CacheEntry entry) {
+      _processAnalysisTarget(target, partition);
+      _processCacheEntry(entry, partition);
+      if (!identical(entry.target, target)) {
+        mismatchedTargets.add(target);
+      }
+    });
+  }
+
+  void _processAnalysisTarget(AnalysisTarget target, Object owner) {
+    _recordInstance(target, owner);
+  }
+
+  void _processCacheEntry(CacheEntry entry, Object owner) {
+    _recordInstance(entry, owner);
+    List<ResultDescriptor> descriptors = entry.nonInvalidResults;
+    for (ResultDescriptor descriptor in descriptors) {
+      _recordInstance(descriptor, entry);
+      _processResultData(entry.getResultDataOrNull(descriptor), entry);
+    }
+  }
+
+  void _processResultData(ResultData resultData, Object owner) {
+    _recordInstance(resultData, owner);
+    if (resultData != null) {
+      _recordInstance(resultData.state, resultData);
+      _recordInstance(resultData.value, resultData,
+          onFirstOccurrence: (Object object) {
+        if (object is AstNode) {
+          object.accept(new AstNodeCounter(directNodeCounts));
+        } else if (object is Element) {
+          object.accept(new ElementCounter(elementCounts, indirectNodeCounts));
+        }
+      });
+      resultData.dependedOnResults.forEach((TargetedResult result) =>
+          _processTargetedResult(result, resultData));
+      resultData.dependentResults.forEach((TargetedResult result) =>
+          _processTargetedResult(result, resultData));
+    }
+  }
+
+  void _processTargetedResult(TargetedResult result, Object owner) {
+    _recordInstance(result, owner);
+    uniqueTargetedResults.add(result);
+    _recordInstance(result.target, result);
+    _recordInstance(result.result, result);
+  }
+
+  /**
+   * Record the given [instance] that was found. If this is the first time that
+   * the instance has been found, execute the [onFirstOccurrence] function.
+   *
+   * Note that instances will not be recorded if there are more than
+   * [maxInstanceSetSize] instances of the same type, and that the
+   * [onFirstOccurrence] function will not be executed if the instance is not
+   * recorded.
+   */
+  void _recordInstance(Object instance, Object owner,
+      {void onFirstOccurrence(Object object)}) {
+    Type type = instance.runtimeType;
+    Set instanceSet = instances.putIfAbsent(type, () => new HashSet.identity());
+    if (instanceSet != InfiniteSet.instance) {
+      if (instanceSet.add(instance) && onFirstOccurrence != null) {
+        onFirstOccurrence(instance);
+      }
+      if (instanceSet.length >= maxInstanceSetSize) {
+        instances[type] = InfiniteSet.instance;
+      }
+    }
+    ownerMap
+        .putIfAbsent(instance.runtimeType, () => new HashSet<Type>())
+        .add(owner.runtimeType);
+    if (instance is LibrarySpecificUnit) {
+      uniqueLSUs.add(instance);
+    }
+  }
+}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 03722a1..0e3ba01 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -9,8 +9,10 @@
   analyzer: ^0.27.0
   args: '>=0.13.0 <0.14.0'
   dart_style: '>=0.2.0 <0.3.0'
+  isolate: ^0.2.2
   linter: ^0.1.16
   logging: any
+  package_config: '>=0.1.5 <2.0.0'
   path: any
   plugin: ^0.2.0
   watcher: any
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index eaea9a6..7699859e 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -447,7 +447,6 @@
     AnalysisResult firstResult = new AnalysisResult([notice], 0, '', 0);
     AnalysisResult lastResult = new AnalysisResult(null, 1, '', 1);
     when(context.analysisOptions).thenReturn(new AnalysisOptionsImpl());
-    when(context.validateCacheConsistency()).thenReturn(false);
     when(context.performAnalysisTask)
         .thenReturnList([firstResult, firstResult, firstResult, lastResult]);
     server.serverServices.add(ServerService.STATUS);
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 2f481cc..41b0983 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -9,10 +9,10 @@
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/file_system/physical_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/context/builder.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -2651,7 +2651,8 @@
     if (currentContext is InternalAnalysisContext) {
       EmbedderYamlLocator embedderYamlLocator =
           disposition.getEmbedderLocator(resourceProvider);
-      EmbedderSdk sdk = new EmbedderSdk(embedderYamlLocator.embedderYamls);
+      EmbedderSdk sdk =
+          new EmbedderSdk(resourceProvider, embedderYamlLocator.embedderYamls);
       if (sdk.libraryMap.size() > 0) {
         // We have some embedder dart: uri mappings, add the resolver
         // to the list.
@@ -2659,7 +2660,7 @@
       }
     }
     resolvers.addAll(disposition.createPackageUriResolvers(resourceProvider));
-    resolvers.add(new ResourceUriResolver(PhysicalResourceProvider.INSTANCE));
+    resolvers.add(new ResourceUriResolver(resourceProvider));
     currentContext.analysisOptions = options;
     currentContext.sourceFactory =
         new SourceFactory(resolvers, disposition.packages);
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index ec7c520..81d8a35 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -51,9 +51,9 @@
   test_ArgumentList_imported_function_named_param_label1() async {
     addTestFile('main() { int.parse("16", r^: 16);}');
     await getSuggestions();
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ',
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix',
         relevance: DART_RELEVANCE_NAMED_PARAMETER);
-    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ',
+    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError',
         relevance: DART_RELEVANCE_NAMED_PARAMETER);
     expect(suggestions, hasLength(2));
   }
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 7c9223a..eaaadc8 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -659,13 +659,11 @@
     return _sendExtractRequest();
   }
 
-  Future<ExtractMethodFeedback> _computeInitialFeedback() {
-    return waitForTasksFinished().then((_) {
-      return _sendExtractRequest();
-    }).then((Response response) {
-      var result = new EditGetRefactoringResult.fromResponse(response);
-      return result.feedback;
-    });
+  Future<ExtractMethodFeedback> _computeInitialFeedback() async {
+    await waitForTasksFinished();
+    Response response = await _sendExtractRequest();
+    var result = new EditGetRefactoringResult.fromResponse(response);
+    return result.feedback;
   }
 
   Future _prepareOptions() {
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
index 3ac66ce..bd07449 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
@@ -20,9 +20,11 @@
 
 @reflectiveTest
 class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
-  Future startServer({int servicesPort}) {
+  Future startServer({int servicesPort, bool checked: true}) {
     return server.start(
-        servicesPort: servicesPort, useAnalysisHighlight2: true);
+        servicesPort: servicesPort,
+        checked: checked,
+        useAnalysisHighlight2: true);
   }
 
   test_highlights() {
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index 1fbdd7e..20b8891 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -36,12 +36,10 @@
    *
    *   The version number of the analysis server.
    */
-  Future<ServerGetVersionResult> sendServerGetVersion() {
-    return server.send("server.getVersion", null)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new ServerGetVersionResult.fromJson(decoder, 'result', result);
-    });
+  Future<ServerGetVersionResult> sendServerGetVersion() async {
+    var result = await server.send("server.getVersion", null);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new ServerGetVersionResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -51,12 +49,10 @@
    * responded to. No further responses or notifications will be sent after the
    * response to this request has been sent.
    */
-  Future sendServerShutdown() {
-    return server.send("server.shutdown", null)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+  Future sendServerShutdown() async {
+    var result = await server.send("server.shutdown", null);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -73,13 +69,11 @@
    *
    *   A list of the services being subscribed to.
    */
-  Future sendServerSetSubscriptions(List<ServerService> subscriptions) {
+  Future sendServerSetSubscriptions(List<ServerService> subscriptions) async {
     var params = new ServerSetSubscriptionsParams(subscriptions).toJson();
-    return server.send("server.setSubscriptions", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("server.setSubscriptions", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -198,13 +192,11 @@
    *
    *   The errors associated with the file.
    */
-  Future<AnalysisGetErrorsResult> sendAnalysisGetErrors(String file) {
+  Future<AnalysisGetErrorsResult> sendAnalysisGetErrors(String file) async {
     var params = new AnalysisGetErrorsParams(file).toJson();
-    return server.send("analysis.getErrors", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new AnalysisGetErrorsResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("analysis.getErrors", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new AnalysisGetErrorsResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -232,13 +224,11 @@
    *   contexts in conflicting ways (such as a part that is included in
    *   multiple libraries).
    */
-  Future<AnalysisGetHoverResult> sendAnalysisGetHover(String file, int offset) {
+  Future<AnalysisGetHoverResult> sendAnalysisGetHover(String file, int offset) async {
     var params = new AnalysisGetHoverParams(file, offset).toJson();
-    return server.send("analysis.getHover", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new AnalysisGetHoverResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("analysis.getHover", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new AnalysisGetHoverResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -267,13 +257,11 @@
    *   reachable from a given file, clients can check for its presence in the
    *   resulting key set.
    */
-  Future<AnalysisGetReachableSourcesResult> sendAnalysisGetReachableSources(String file) {
+  Future<AnalysisGetReachableSourcesResult> sendAnalysisGetReachableSources(String file) async {
     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);
-    });
+    var result = await server.send("analysis.getReachableSources", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new AnalysisGetReachableSourcesResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -296,12 +284,10 @@
    *   names to source directories for use in client-side package URI
    *   resolution.
    */
-  Future<AnalysisGetLibraryDependenciesResult> sendAnalysisGetLibraryDependencies() {
-    return server.send("analysis.getLibraryDependencies", null)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new AnalysisGetLibraryDependenciesResult.fromJson(decoder, 'result', result);
-    });
+  Future<AnalysisGetLibraryDependenciesResult> sendAnalysisGetLibraryDependencies() async {
+    var result = await server.send("analysis.getLibraryDependencies", null);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new AnalysisGetLibraryDependenciesResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -358,13 +344,11 @@
    *   A list of the navigation regions within the requested region of the
    *   file.
    */
-  Future<AnalysisGetNavigationResult> sendAnalysisGetNavigation(String file, int offset, int length) {
+  Future<AnalysisGetNavigationResult> sendAnalysisGetNavigation(String file, int offset, int length) async {
     var params = new AnalysisGetNavigationParams(file, offset, length).toJson();
-    return server.send("analysis.getNavigation", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new AnalysisGetNavigationResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("analysis.getNavigation", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new AnalysisGetNavigationResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -385,13 +369,11 @@
    *
    *   A list of the analysis roots that are to be re-analyzed.
    */
-  Future sendAnalysisReanalyze({List<String> roots}) {
+  Future sendAnalysisReanalyze({List<String> roots}) async {
     var params = new AnalysisReanalyzeParams(roots: roots).toJson();
-    return server.send("analysis.reanalyze", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("analysis.reanalyze", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -453,13 +435,11 @@
    *   If this field is absent, or the empty map is specified, that indicates
    *   that the normal pubspec.yaml mechanism should always be used.
    */
-  Future sendAnalysisSetAnalysisRoots(List<String> included, List<String> excluded, {Map<String, String> packageRoots}) {
+  Future sendAnalysisSetAnalysisRoots(List<String> included, List<String> excluded, {Map<String, String> packageRoots}) async {
     var params = new AnalysisSetAnalysisRootsParams(included, excluded, packageRoots: packageRoots).toJson();
-    return server.send("analysis.setAnalysisRoots", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("analysis.setAnalysisRoots", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -477,13 +457,11 @@
    *
    *   A list of the services being subscribed to.
    */
-  Future sendAnalysisSetGeneralSubscriptions(List<GeneralAnalysisService> subscriptions) {
+  Future sendAnalysisSetGeneralSubscriptions(List<GeneralAnalysisService> subscriptions) async {
     var params = new AnalysisSetGeneralSubscriptionsParams(subscriptions).toJson();
-    return server.send("analysis.setGeneralSubscriptions", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("analysis.setGeneralSubscriptions", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -511,13 +489,11 @@
    *
    *   The files that are to be a priority for analysis.
    */
-  Future sendAnalysisSetPriorityFiles(List<String> files) {
+  Future sendAnalysisSetPriorityFiles(List<String> files) async {
     var params = new AnalysisSetPriorityFilesParams(files).toJson();
-    return server.send("analysis.setPriorityFiles", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("analysis.setPriorityFiles", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -552,13 +528,11 @@
    *   A table mapping services to a list of the files being subscribed to the
    *   service.
    */
-  Future sendAnalysisSetSubscriptions(Map<AnalysisService, List<String>> subscriptions) {
+  Future sendAnalysisSetSubscriptions(Map<AnalysisService, List<String>> subscriptions) async {
     var params = new AnalysisSetSubscriptionsParams(subscriptions).toJson();
-    return server.send("analysis.setSubscriptions", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("analysis.setSubscriptions", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -579,13 +553,11 @@
    *
    * Returns
    */
-  Future<AnalysisUpdateContentResult> sendAnalysisUpdateContent(Map<String, dynamic> files) {
+  Future<AnalysisUpdateContentResult> sendAnalysisUpdateContent(Map<String, dynamic> files) async {
     var params = new AnalysisUpdateContentParams(files).toJson();
-    return server.send("analysis.updateContent", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new AnalysisUpdateContentResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("analysis.updateContent", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new AnalysisUpdateContentResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -600,13 +572,11 @@
    *
    *   The options that are to be used to control analysis.
    */
-  Future sendAnalysisUpdateOptions(AnalysisOptions options) {
+  Future sendAnalysisUpdateOptions(AnalysisOptions options) async {
     var params = new AnalysisUpdateOptionsParams(options).toJson();
-    return server.send("analysis.updateOptions", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("analysis.updateOptions", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -943,13 +913,11 @@
    *
    *   The identifier used to associate results with this completion request.
    */
-  Future<CompletionGetSuggestionsResult> sendCompletionGetSuggestions(String file, int offset) {
+  Future<CompletionGetSuggestionsResult> sendCompletionGetSuggestions(String file, int offset) async {
     var params = new CompletionGetSuggestionsParams(file, offset).toJson();
-    return server.send("completion.getSuggestions", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new CompletionGetSuggestionsResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("completion.getSuggestions", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new CompletionGetSuggestionsResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1038,13 +1006,11 @@
    *   If no element was found at the given location, this field will be
    *   absent.
    */
-  Future<SearchFindElementReferencesResult> sendSearchFindElementReferences(String file, int offset, bool includePotential) {
+  Future<SearchFindElementReferencesResult> sendSearchFindElementReferences(String file, int offset, bool includePotential) async {
     var params = new SearchFindElementReferencesParams(file, offset, includePotential).toJson();
-    return server.send("search.findElementReferences", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new SearchFindElementReferencesResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("search.findElementReferences", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new SearchFindElementReferencesResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1066,13 +1032,11 @@
    *
    *   The identifier used to associate results with this search request.
    */
-  Future<SearchFindMemberDeclarationsResult> sendSearchFindMemberDeclarations(String name) {
+  Future<SearchFindMemberDeclarationsResult> sendSearchFindMemberDeclarations(String name) async {
     var params = new SearchFindMemberDeclarationsParams(name).toJson();
-    return server.send("search.findMemberDeclarations", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new SearchFindMemberDeclarationsResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("search.findMemberDeclarations", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new SearchFindMemberDeclarationsResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1096,13 +1060,11 @@
    *
    *   The identifier used to associate results with this search request.
    */
-  Future<SearchFindMemberReferencesResult> sendSearchFindMemberReferences(String name) {
+  Future<SearchFindMemberReferencesResult> sendSearchFindMemberReferences(String name) async {
     var params = new SearchFindMemberReferencesParams(name).toJson();
-    return server.send("search.findMemberReferences", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new SearchFindMemberReferencesResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("search.findMemberReferences", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new SearchFindMemberReferencesResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1126,13 +1088,11 @@
    *
    *   The identifier used to associate results with this search request.
    */
-  Future<SearchFindTopLevelDeclarationsResult> sendSearchFindTopLevelDeclarations(String pattern) {
+  Future<SearchFindTopLevelDeclarationsResult> sendSearchFindTopLevelDeclarations(String pattern) async {
     var params = new SearchFindTopLevelDeclarationsParams(pattern).toJson();
-    return server.send("search.findTopLevelDeclarations", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new SearchFindTopLevelDeclarationsResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("search.findTopLevelDeclarations", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new SearchFindTopLevelDeclarationsResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1169,13 +1129,11 @@
    *   not represent a type, or if the file has not been sufficiently analyzed
    *   to allow a type hierarchy to be produced.
    */
-  Future<SearchGetTypeHierarchyResult> sendSearchGetTypeHierarchy(String file, int offset, {bool superOnly}) {
+  Future<SearchGetTypeHierarchyResult> sendSearchGetTypeHierarchy(String file, int offset, {bool superOnly}) async {
     var params = new SearchGetTypeHierarchyParams(file, offset, superOnly: superOnly).toJson();
-    return server.send("search.getTypeHierarchy", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new SearchGetTypeHierarchyResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("search.getTypeHierarchy", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new SearchGetTypeHierarchyResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1254,13 +1212,11 @@
    *
    *   The length of the selection after formatting the code.
    */
-  Future<EditFormatResult> sendEditFormat(String file, int selectionOffset, int selectionLength, {int lineLength}) {
+  Future<EditFormatResult> sendEditFormat(String file, int selectionOffset, int selectionLength, {int lineLength}) async {
     var params = new EditFormatParams(file, selectionOffset, selectionLength, lineLength: lineLength).toJson();
-    return server.send("edit.format", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new EditFormatResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("edit.format", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new EditFormatResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1289,13 +1245,11 @@
    *
    *   The assists that are available at the given location.
    */
-  Future<EditGetAssistsResult> sendEditGetAssists(String file, int offset, int length) {
+  Future<EditGetAssistsResult> sendEditGetAssists(String file, int offset, int length) async {
     var params = new EditGetAssistsParams(file, offset, length).toJson();
-    return server.send("edit.getAssists", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new EditGetAssistsResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("edit.getAssists", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new EditGetAssistsResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1322,13 +1276,11 @@
    *
    *   The kinds of refactorings that are valid for the given selection.
    */
-  Future<EditGetAvailableRefactoringsResult> sendEditGetAvailableRefactorings(String file, int offset, int length) {
+  Future<EditGetAvailableRefactoringsResult> sendEditGetAvailableRefactorings(String file, int offset, int length) async {
     var params = new EditGetAvailableRefactoringsParams(file, offset, length).toJson();
-    return server.send("edit.getAvailableRefactorings", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new EditGetAvailableRefactoringsResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("edit.getAvailableRefactorings", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new EditGetAvailableRefactoringsResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1351,13 +1303,11 @@
    *
    *   The fixes that are available for the errors at the given offset.
    */
-  Future<EditGetFixesResult> sendEditGetFixes(String file, int offset) {
+  Future<EditGetFixesResult> sendEditGetFixes(String file, int offset) async {
     var params = new EditGetFixesParams(file, offset).toJson();
-    return server.send("edit.getFixes", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new EditGetFixesResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("edit.getFixes", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new EditGetFixesResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1441,13 +1391,11 @@
    *   if the change field is omitted or if there are no potential edits for
    *   the refactoring.
    */
-  Future<EditGetRefactoringResult> sendEditGetRefactoring(RefactoringKind kind, String file, int offset, int length, bool validateOnly, {RefactoringOptions options}) {
+  Future<EditGetRefactoringResult> sendEditGetRefactoring(RefactoringKind kind, String file, int offset, int length, bool validateOnly, {RefactoringOptions options}) async {
     var params = new EditGetRefactoringParams(kind, file, offset, length, validateOnly, options: options).toJson();
-    return server.send("edit.getRefactoring", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(kind);
-      return new EditGetRefactoringResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("edit.getRefactoring", params);
+    ResponseDecoder decoder = new ResponseDecoder(kind);
+    return new EditGetRefactoringResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1473,13 +1421,11 @@
    *   The file edit that is to be applied to the given file to effect the
    *   sorting.
    */
-  Future<EditSortMembersResult> sendEditSortMembers(String file) {
+  Future<EditSortMembersResult> sendEditSortMembers(String file) async {
     var params = new EditSortMembersParams(file).toJson();
-    return server.send("edit.sortMembers", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new EditSortMembersResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("edit.sortMembers", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new EditSortMembersResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1506,13 +1452,11 @@
    *   The file edit that is to be applied to the given file to effect the
    *   organizing.
    */
-  Future<EditOrganizeDirectivesResult> sendEditOrganizeDirectives(String file) {
+  Future<EditOrganizeDirectivesResult> sendEditOrganizeDirectives(String file) async {
     var params = new EditOrganizeDirectivesParams(file).toJson();
-    return server.send("edit.organizeDirectives", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new EditOrganizeDirectivesResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("edit.organizeDirectives", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new EditOrganizeDirectivesResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1534,13 +1478,11 @@
    *
    *   The identifier used to refer to the execution context that was created.
    */
-  Future<ExecutionCreateContextResult> sendExecutionCreateContext(String contextRoot) {
+  Future<ExecutionCreateContextResult> sendExecutionCreateContext(String contextRoot) async {
     var params = new ExecutionCreateContextParams(contextRoot).toJson();
-    return server.send("execution.createContext", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new ExecutionCreateContextResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("execution.createContext", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new ExecutionCreateContextResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1554,13 +1496,11 @@
    *
    *   The identifier of the execution context that is to be deleted.
    */
-  Future sendExecutionDeleteContext(String id) {
+  Future sendExecutionDeleteContext(String id) async {
     var params = new ExecutionDeleteContextParams(id).toJson();
-    return server.send("execution.deleteContext", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("execution.deleteContext", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -1611,13 +1551,11 @@
    *   The URI to which the file path was mapped. This field is omitted if the
    *   file field was not given in the request.
    */
-  Future<ExecutionMapUriResult> sendExecutionMapUri(String id, {String file, String uri}) {
+  Future<ExecutionMapUriResult> sendExecutionMapUri(String id, {String file, String uri}) async {
     var params = new ExecutionMapUriParams(id, file: file, uri: uri).toJson();
-    return server.send("execution.mapUri", params)
-        .then((result) {
-      ResponseDecoder decoder = new ResponseDecoder(null);
-      return new ExecutionMapUriResult.fromJson(decoder, 'result', result);
-    });
+    var result = await server.send("execution.mapUri", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new ExecutionMapUriResult.fromJson(decoder, 'result', result);
   }
 
   /**
@@ -1634,13 +1572,11 @@
    *
    *   A list of the services being subscribed to.
    */
-  Future sendExecutionSetSubscriptions(List<ExecutionService> subscriptions) {
+  Future sendExecutionSetSubscriptions(List<ExecutionService> subscriptions) async {
     var params = new ExecutionSetSubscriptionsParams(subscriptions).toJson();
-    return server.send("execution.setSubscriptions", params)
-        .then((result) {
-      expect(result, isNull);
-      return null;
-    });
+    var result = await server.send("execution.setSubscriptions", params);
+    expect(result, isNull);
+    return null;
   }
 
   /**
@@ -1683,12 +1619,10 @@
    *
    *   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);
-    });
+  Future<DiagnosticGetDiagnosticsResult> sendDiagnosticGetDiagnostics() async {
+    var result = await server.send("diagnostic.getDiagnostics", null);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new DiagnosticGetDiagnosticsResult.fromJson(decoder, 'result', result);
   }
 
   /**
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 9e764a0..9835a1e 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -205,8 +205,8 @@
   /**
    * Start [server].
    */
-  Future startServer({int servicesPort}) =>
-      server.start(servicesPort: servicesPort);
+  Future startServer({int servicesPort, bool checked: true}) =>
+      server.start(servicesPort: servicesPort, checked: checked);
 
   /**
    * After every test, the server is stopped and [sourceDirectory] is deleted.
@@ -601,6 +601,7 @@
       int diagnosticPort,
       bool profileServer: false,
       int servicesPort,
+      bool checked: true,
       bool useAnalysisHighlight2: false}) {
     if (_process != null) {
       throw new Exception('Process already started');
@@ -627,7 +628,9 @@
     if (Platform.packageRoot != null) {
       arguments.add('--package-root=${Platform.packageRoot}');
     }
-    arguments.add('--checked');
+    if (checked) {
+      arguments.add('--checked');
+    }
     arguments.add(serverPath);
     if (diagnosticPort != null) {
       arguments.add('--port');
diff --git a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart b/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
index a4ab04e..5cd0820 100644
--- a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
@@ -103,6 +103,7 @@
               equals(text.indexOf('class $name') + 'class '.length));
         }
       }
+
       checkElement('Object');
       checkElement('Base');
       checkElement('Pivot');
@@ -261,17 +262,15 @@
     return Future.forEach(tests, (test) => test());
   }
 
-  Future<HierarchyResults> typeHierarchyTest(String text) {
+  Future<HierarchyResults> typeHierarchyTest(String text) async {
     int offset = text.indexOf(' /* target */') - 1;
     sendAnalysisUpdateContent({pathname: new AddContentOverlay(text)});
-    return analysisFinished
-        .then((_) => sendSearchGetTypeHierarchy(pathname, offset))
-        .then((result) {
-      if (result.hierarchyItems == null) {
-        return null;
-      } else {
-        return new HierarchyResults(result.hierarchyItems);
-      }
-    });
+    await analysisFinished;
+    var result = await sendSearchGetTypeHierarchy(pathname, offset);
+    if (result.hierarchyItems == null) {
+      return null;
+    } else {
+      return new HierarchyResults(result.hierarchyItems);
+    }
   }
 }
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 504d536..18d5316 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -10,6 +10,7 @@
 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/summary/idl.dart' show PackageBundle;
 
 class MockSdk implements DartSdk {
   static const _MockSdkLibrary LIB_CORE = const _MockSdkLibrary(
@@ -316,6 +317,9 @@
   }
 
   @override
+  PackageBundle getLinkedBundle() => null;
+
+  @override
   SdkLibrary getSdkLibrary(String dartUri) {
     // getSdkLibrary() is only used to determine whether a library is internal
     // to the SDK.  The mock SDK doesn't have any internals, so it's safe to
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 809a962..cdd7e13 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -268,13 +268,13 @@
   test_hierarchy_method() async {
     addTestFile('''
 class A {
-  mmm() {} // in A
+  mmm(_) {} // in A
 }
 class B extends A {
-  mmm() {} // in B
+  mmm(_) {} // in B
 }
 class C extends B {
-  mmm() {} // in C
+  mmm(_) {} // in C
 }
 main(A a, B b, C c) {
   a.mmm(10);
@@ -282,13 +282,36 @@
   c.mmm(30);
 }
 ''');
-    await findElementReferences('mmm() {} // in B', false);
+    await findElementReferences('mmm(_) {} // in B', false);
     expect(searchElement.kind, ElementKind.METHOD);
     assertHasResult(SearchResultKind.INVOCATION, 'mmm(10)');
     assertHasResult(SearchResultKind.INVOCATION, 'mmm(20)');
     assertHasResult(SearchResultKind.INVOCATION, 'mmm(30)');
   }
 
+  test_hierarchy_method_static() async {
+    addTestFile('''
+class A {
+  static void mmm(_) {} // in A
+}
+class B extends A {
+  static void mmm(_) {} // in B
+}
+class C extends B {
+  static void mmm(_) {} // in C
+}
+main() {
+  A.mmm(10);
+  B.mmm(20);
+  C.mmm(30);
+}
+''');
+    await findElementReferences('mmm(_) {} // in B', false);
+    expect(searchElement.kind, ElementKind.METHOD);
+    expect(results, hasLength(1));
+    assertHasResult(SearchResultKind.INVOCATION, 'mmm(20)');
+  }
+
   test_label() async {
     addTestFile('''
 main() {
diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart
index 81fa08b..8b1829c 100644
--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/search/top_level_declarations_test.dart
@@ -39,6 +39,9 @@
     Request request =
         new SearchFindTopLevelDeclarationsParams(pattern).toRequest('0');
     Response response = await waitResponse(request);
+    if (response.error != null) {
+      return response.error;
+    }
     searchId =
         new SearchFindTopLevelDeclarationsResult.fromResponse(response).id;
     return waitForSearchResults();
@@ -71,4 +74,9 @@
     assertHasDeclaration(ElementKind.TOP_LEVEL_VARIABLE, 'E');
     assertNoDeclaration(ElementKind.CLASS, 'ABC');
   }
+
+  test_invalidRegex() async {
+    var result = await findTopLevelDeclarations('[A');
+    expect(result, new isInstanceOf<RequestError>());
+  }
 }
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index 6f9c273..0dfc892 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -142,6 +142,18 @@
       {
         'classElement': {
           'kind': 'CLASS',
+          'name': 'BBB',
+          'location': anything,
+          'flags': 0
+        },
+        'superclass': 0,
+        'interfaces': [],
+        'mixins': [],
+        'subclasses': [3]
+      },
+      {
+        'classElement': {
+          'kind': 'CLASS',
           'name': 'CCC',
           'location': anything,
           'flags': 0
@@ -151,18 +163,6 @@
         'mixins': [],
         'subclasses': []
       },
-      {
-        'classElement': {
-          'kind': 'CLASS',
-          'name': 'BBB',
-          'location': anything,
-          'flags': 0
-        },
-        'superclass': 0,
-        'interfaces': [],
-        'mixins': [],
-        'subclasses': [2]
-      }
     ]);
   }
 
diff --git a/pkg/analysis_server/test/services/completion/completion_target_test.dart b/pkg/analysis_server/test/services/completion/completion_target_test.dart
index 569610c..ce02343 100644
--- a/pkg/analysis_server/test/services/completion/completion_target_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_target_test.dart
@@ -61,6 +61,12 @@
     assertTarget(')', '()', argIndex: 0);
   }
 
+  test_ArgumentList_InstanceCreationExpression2() {
+    // ArgumentList  InstanceCreationExpression  Block
+    addTestSource('main() {new Foo(a,^)}');
+    assertTarget(')', '(a)', argIndex: 1);
+  }
+
   test_ArgumentList_InstanceCreationExpression_functionArg2() {
     // ArgumentList  InstanceCreationExpression  Block
     addTestSource('main() {new B(^)} class B{B(f()){}}');
@@ -85,10 +91,16 @@
     assertTarget('n', '(n)', argIndex: 0);
   }
 
+  test_ArgumentList_MethodInvocation3a() {
+    // ArgumentList  MethodInvocation  Block
+    addTestSource('main() {foo((n)^)}');
+    assertTarget(')', '((n))', argIndex: 0);
+  }
+
   test_ArgumentList_MethodInvocation4() {
     // ArgumentList  MethodInvocation  Block
     addTestSource('main() {foo(n,^)}');
-    assertTarget('', '(n, )', argIndex: 1);
+    assertTarget(')', '(n)', argIndex: 1);
   }
 
   test_ArgumentList_MethodInvocation_functionArg() {
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index db17859..44ddc2a 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -81,10 +81,11 @@
    * the only suggestions.
    */
   void assertSuggestArgumentsAndTypes(
-      {Map<String, String> namedArgumentsWithTypes}) {
+      {Map<String, String> namedArgumentsWithTypes, bool includeColon: true}) {
     List<CompletionSuggestion> expected = new List<CompletionSuggestion>();
     namedArgumentsWithTypes.forEach((String name, String type) {
-      expected.add(assertSuggest('$name: ',
+      String completion = includeColon ? '$name: ' : name;
+      expected.add(assertSuggest(completion,
           csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
           relevance: DART_RELEVANCE_NAMED_PARAMETER,
           paramName: name,
@@ -432,7 +433,8 @@
     addTestSource('main() { int.parse("16", r^: 16);}');
     await computeSuggestions();
     assertSuggestArgumentsAndTypes(
-        namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'});
+        namedArgumentsWithTypes: {'radix': 'int', 'onError': '(String) → int'},
+        includeColon: false);
   }
 
   test_ArgumentList_imported_function_named_param_label2() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 5740cad..8cbed55 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -4043,6 +4043,21 @@
     assertNotSuggested('String');
   }
 
+  test_SwitchStatement_case_var() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('g(int x) {var t; switch(x) {case 0: var bar; b^}}');
+    await computeSuggestions();
+
+    assertSuggestFunction('g', 'dynamic',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestLocalVariable('t', 'dynamic',
+        relevance: DART_RELEVANCE_LOCAL_VARIABLE);
+    assertSuggestParameter('x', 'int', relevance: DART_RELEVANCE_PARAMETER);
+    assertSuggestLocalVariable('bar', 'dynamic',
+        relevance: DART_RELEVANCE_LOCAL_VARIABLE);
+    assertNotSuggested('String');
+  }
+
   test_SwitchStatement_empty() async {
     // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {String g(int x) {switch(x) {^}}}');
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 5c84d35..4188664 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -326,8 +326,8 @@
         'future in',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
-import 'my_lib.dart';
 import 'dart:async';
+import 'my_lib.dart';
 main() {
   for (Future<int> future in getFutures()) {
   }
@@ -466,8 +466,8 @@
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
-import 'my_lib.dart';
 import 'dart:async';
+import 'my_lib.dart';
 main() {
   Future<int> v = getFutureInt();
 }
@@ -515,8 +515,8 @@
           resultCode,
           '''
 library my_app;
-import 'my_lib.dart';
 import 'dart:async';
+import 'my_lib.dart';
 part 'test.dart';
 ''');
     }
@@ -556,8 +556,8 @@
         'v =',
         DartAssistKind.ADD_TYPE_ANNOTATION,
         '''
-import 'ccc/lib_b.dart';
 import 'aa/bbb/lib_a.dart';
+import 'ccc/lib_b.dart';
 main() {
   MyClass v = newMyClass();
 }
@@ -1432,6 +1432,177 @@
 ''');
   }
 
+  test_convertToFinalField_BAD_hasSetter_inThisClass() async {
+    resolveTestUnit('''
+class A {
+  int get foo => null;
+  void set foo(_) {}
+}
+''');
+    await assertNoAssistAt('get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD);
+  }
+
+  test_convertToFinalField_BAD_notExpressionBody() async {
+    resolveTestUnit('''
+class A {
+  int get foo {
+    int v = 1 + 2;
+    return v + 3;
+  }
+}
+''');
+    await assertNoAssistAt('get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD);
+  }
+
+  test_convertToFinalField_BAD_notGetter() async {
+    resolveTestUnit('''
+class A {
+  int foo() => 42;
+}
+''');
+    await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD);
+  }
+
+  test_convertToFinalField_OK_blockBody_onlyReturnStatement() async {
+    resolveTestUnit('''
+class A {
+  int get foo {
+    return 1 + 2;
+  }
+}
+''');
+    await assertHasAssistAt(
+        'get foo',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+class A {
+  final int foo = 1 + 2;
+}
+''');
+  }
+
+  test_convertToFinalField_OK_hasOverride() async {
+    resolveTestUnit('''
+const myAnnotation = const Object();
+class A {
+  @myAnnotation
+  int get foo => 42;
+}
+''');
+    await assertHasAssistAt(
+        'get foo',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+const myAnnotation = const Object();
+class A {
+  @myAnnotation
+  final int foo = 42;
+}
+''');
+  }
+
+  test_convertToFinalField_OK_hasSetter_inSuper() async {
+    resolveTestUnit('''
+class A {
+  void set foo(_) {}
+}
+class B extends A {
+  int get foo => null;
+}
+''');
+    await assertHasAssistAt(
+        'get foo',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+class A {
+  void set foo(_) {}
+}
+class B extends A {
+  final int foo;
+}
+''');
+  }
+
+  test_convertToFinalField_OK_notNull() async {
+    resolveTestUnit('''
+class A {
+  int get foo => 1 + 2;
+}
+''');
+    await assertHasAssistAt(
+        'get foo',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+class A {
+  final int foo = 1 + 2;
+}
+''');
+  }
+
+  test_convertToFinalField_OK_null() async {
+    resolveTestUnit('''
+class A {
+  int get foo => null;
+}
+''');
+    await assertHasAssistAt(
+        'get foo',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+class A {
+  final int foo;
+}
+''');
+  }
+
+  test_convertToFinalField_OK_onName() async {
+    resolveTestUnit('''
+class A {
+  int get foo => 42;
+}
+''');
+    await assertHasAssistAt(
+        'foo',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+class A {
+  final int foo = 42;
+}
+''');
+  }
+
+  test_convertToFinalField_OK_onReturnType_parameterized() async {
+    resolveTestUnit('''
+class A {
+  List<int> get foo => null;
+}
+''');
+    await assertHasAssistAt(
+        'nt> get',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+class A {
+  final List<int> foo;
+}
+''');
+  }
+
+  test_convertToFinalField_OK_onReturnType_simple() async {
+    resolveTestUnit('''
+class A {
+  int get foo => 42;
+}
+''');
+    await assertHasAssistAt(
+        'int get',
+        DartAssistKind.CONVERT_INTO_FINAL_FIELD,
+        '''
+class A {
+  final int foo = 42;
+}
+''');
+  }
+
   test_convertToForIndex_BAD_bodyNotBlock() async {
     resolveTestUnit('''
 main(List<String> items) {
@@ -1598,6 +1769,69 @@
 ''');
   }
 
+  test_convertToGetter_BAD_noInitializer() async {
+    resolveTestUnit('''
+class A {
+  final int foo;
+}
+''');
+    await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER);
+  }
+
+  test_convertToGetter_BAD_notFinal() async {
+    resolveTestUnit('''
+class A {
+  int foo = 1;
+}
+''');
+    await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER);
+  }
+
+  test_convertToGetter_BAD_notSingleField() async {
+    resolveTestUnit('''
+class A {
+  final int foo = 1, bar = 2;
+}
+''');
+    await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER);
+  }
+
+  test_convertToGetter_OK() async {
+    resolveTestUnit('''
+const myAnnotation = const Object();
+class A {
+  @myAnnotation
+  final int foo = 1 + 2;
+}
+''');
+    await assertHasAssistAt(
+        'foo =',
+        DartAssistKind.CONVERT_INTO_GETTER,
+        '''
+const myAnnotation = const Object();
+class A {
+  @myAnnotation
+  int get foo => 1 + 2;
+}
+''');
+  }
+
+  test_convertToGetter_OK_noType() async {
+    resolveTestUnit('''
+class A {
+  final foo = 42;
+}
+''');
+    await assertHasAssistAt(
+        'foo =',
+        DartAssistKind.CONVERT_INTO_GETTER,
+        '''
+class A {
+  get foo => 42;
+}
+''');
+  }
+
   test_convertToIsNot_BAD_is_alreadyIsNot() async {
     resolveTestUnit('''
 main(p) {
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 4ec437f..5bde966 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -463,40 +463,42 @@
 ''');
     List<AnalysisError> errors = context.computeErrors(testSource);
     expect(errors, hasLength(2));
-    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,
-            '''
+    errors.sort((a, b) => a.message.compareTo(b.message));
+    // No fix for ";".
+    {
+      AnalysisError error = errors[0];
+      expect(error.message, "Expected to find ';'");
+      List<Fix> fixes = await _computeFixes(error);
+      expect(fixes, isEmpty);
+    }
+    // Has fix for "await".
+    {
+      AnalysisError error = errors[1];
+      expect(error.message, startsWith("Undefined name 'await';"));
+      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();
 }
 ''');
-      }
     }
   }
 
   test_addSync_expressionFunctionBody() async {
     errorFilter = (AnalysisError error) {
-      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
     resolveTestUnit('''
 foo() {}
@@ -512,7 +514,7 @@
 
   test_addSync_returnFuture() async {
     errorFilter = (AnalysisError error) {
-      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
     resolveTestUnit('''
 foo() {}
@@ -536,7 +538,7 @@
 
   test_addSync_returnFuture_alreadyFuture() async {
     errorFilter = (AnalysisError error) {
-      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
     resolveTestUnit('''
 import 'dart:async';
@@ -560,7 +562,7 @@
 
   test_addSync_returnFuture_dynamic() async {
     errorFilter = (AnalysisError error) {
-      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
     resolveTestUnit('''
 foo() {}
@@ -582,7 +584,7 @@
 
   test_addSync_returnFuture_noType() async {
     errorFilter = (AnalysisError error) {
-      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
     };
     resolveTestUnit('''
 foo() {}
@@ -708,8 +710,8 @@
     await assertHasFix(
         DartFixKind.CHANGE_TO_STATIC_ACCESS,
         '''
-import 'libB.dart';
 import 'libA.dart';
+import 'libB.dart';
 main(B b) {
   A.foo();
 }
@@ -779,8 +781,8 @@
     await assertHasFix(
         DartFixKind.CHANGE_TO_STATIC_ACCESS,
         '''
-import 'libB.dart';
 import 'libA.dart';
+import 'libB.dart';
 main(B b) {
   A.foo;
 }
@@ -1009,8 +1011,7 @@
 class A {
   int field;
 
-  A(int i, double d) {
-  }
+  A(int i, double d);
 
   method() {}
 }
@@ -1033,8 +1034,7 @@
         DartFixKind.CREATE_CONSTRUCTOR,
         '''
 class A {
-  A.named(int i, double d) {
-  }
+  A.named(int i, double d);
 
   method() {}
 }
@@ -1045,6 +1045,26 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
   }
 
+  test_createConstructor_named_emptyClassBody() async {
+    resolveTestUnit('''
+class A {}
+main() {
+  new A.named(1);
+}
+''');
+    await assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR,
+        '''
+class A {
+  A.named(int i);
+}
+main() {
+  new A.named(1);
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
+  }
+
   test_createConstructorForFinalFields_inTopLevelMethod() async {
     resolveTestUnit('''
 main() {
@@ -1239,8 +1259,8 @@
     await assertHasFix(
         DartFixKind.CREATE_CONSTRUCTOR_SUPER,
         '''
-import 'libB.dart';
 import 'libA.dart';
+import 'libB.dart';
 class C extends B {
   C(A a) : super(a);
 }
@@ -1563,8 +1583,8 @@
     await assertHasFix(
         DartFixKind.CREATE_FIELD,
         '''
-import 'libB.dart';
 import 'libA.dart';
+import 'libB.dart';
 class C {
   A test;
 }
@@ -2567,6 +2587,30 @@
     }
   }
 
+  test_createMissingOverrides_method_emptyClassBody() async {
+    resolveTestUnit('''
+abstract class A {
+  void foo();
+}
+
+class B extends A {}
+''');
+    await assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
+abstract class A {
+  void foo();
+}
+
+class B extends A {
+  @override
+  void foo() {
+    // TODO: implement foo
+  }
+}
+''');
+  }
+
   test_createMissingOverrides_operator() async {
     resolveTestUnit('''
 abstract class A {
@@ -2631,7 +2675,7 @@
   }
 
   @override
-  void set s3(String x) {
+  set s3(String x) {
     // TODO: implement s3
   }
 }
@@ -2802,8 +2846,8 @@
     await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
-import 'libB.dart';
 import 'libA.dart';
+import 'libB.dart';
 main() {
   useFunction(test);
 }
@@ -2976,6 +3020,7 @@
         DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
         '''
 library main;
+
 import 'dart:async';
 Future<int> main() async {
 }
@@ -3111,8 +3156,8 @@
     await assertHasFix(
         DartFixKind.IMPORT_LIBRARY_PROJECT,
         '''
-import 'b.dart' show Two;
 import 'a.dart';
+import 'b.dart' show Two;
 main () {
   new Two();
   new One();
@@ -4131,8 +4176,8 @@
     await assertHasFix(
         DartFixKind.CREATE_FUNCTION,
         '''
-import 'lib.dart';
 import 'dart:async';
+import 'lib.dart';
 main() {
   test(getFuture());
 }
diff --git a/pkg/analysis_server/test/services/correction/test_all.dart b/pkg/analysis_server/test/services/correction/test_all.dart
index d1a6bb5..f00f310 100644
--- a/pkg/analysis_server/test/services/correction/test_all.dart
+++ b/pkg/analysis_server/test/services/correction/test_all.dart
@@ -17,6 +17,7 @@
 import 'source_range_test.dart' as source_range_test;
 import 'status_test.dart' as status_test;
 import 'strings_test.dart' as strings_test;
+import 'util_test.dart' as util_test;
 
 /// Utility for manually running all tests.
 main() {
@@ -32,5 +33,6 @@
     source_range_test.main();
     status_test.main();
     strings_test.main();
+    util_test.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
new file mode 100644
index 0000000..a435b1c
--- /dev/null
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -0,0 +1,293 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.correction.util;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/element/element.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 '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(UtilTest);
+}
+
+@reflectiveTest
+class UtilTest extends AbstractSingleUnitTest {
+  test_addLibraryImports_dart_hasImports_between() {
+    resolveTestUnit('''
+import 'dart:async';
+import 'dart:math';
+''');
+    LibraryElement newLibrary = _getDartLibrary('dart:collection');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary],
+        '''
+import 'dart:async';
+import 'dart:collection';
+import 'dart:math';
+''');
+  }
+
+  test_addLibraryImports_dart_hasImports_first() {
+    resolveTestUnit('''
+import 'dart:collection';
+import 'dart:math';
+''');
+    LibraryElement newLibrary = _getDartLibrary('dart:async');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary],
+        '''
+import 'dart:async';
+import 'dart:collection';
+import 'dart:math';
+''');
+  }
+
+  test_addLibraryImports_dart_hasImports_last() {
+    resolveTestUnit('''
+import 'dart:async';
+import 'dart:collection';
+''');
+    LibraryElement newLibrary = _getDartLibrary('dart:math');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary],
+        '''
+import 'dart:async';
+import 'dart:collection';
+import 'dart:math';
+''');
+  }
+
+  test_addLibraryImports_dart_hasImports_multiple() {
+    resolveTestUnit('''
+import 'dart:collection';
+import 'dart:math';
+''');
+    LibraryElement newLibrary1 = _getDartLibrary('dart:async');
+    LibraryElement newLibrary2 = _getDartLibrary('dart:html');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+import 'dart:async';
+import 'dart:collection';
+import 'dart:html';
+import 'dart:math';
+''');
+  }
+
+  test_addLibraryImports_dart_hasImports_multiple_first() {
+    resolveTestUnit('''
+import 'dart:html';
+import 'dart:math';
+''');
+    LibraryElement newLibrary1 = _getDartLibrary('dart:async');
+    LibraryElement newLibrary2 = _getDartLibrary('dart:collection');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+import 'dart:async';
+import 'dart:collection';
+import 'dart:html';
+import 'dart:math';
+''');
+  }
+
+  test_addLibraryImports_dart_hasImports_multiple_last() {
+    resolveTestUnit('''
+import 'dart:async';
+import 'dart:collection';
+''');
+    LibraryElement newLibrary1 = _getDartLibrary('dart:html');
+    LibraryElement newLibrary2 = _getDartLibrary('dart:math');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+import 'dart:async';
+import 'dart:collection';
+import 'dart:html';
+import 'dart:math';
+''');
+  }
+
+  test_addLibraryImports_dart_hasLibraryDirective() {
+    resolveTestUnit('''
+library test;
+
+class A {}
+''');
+    LibraryElement newLibrary1 = _getDartLibrary('dart:math');
+    LibraryElement newLibrary2 = _getDartLibrary('dart:async');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+library test;
+
+import 'dart:async';
+import 'dart:math';
+
+class A {}
+''');
+  }
+
+  test_addLibraryImports_dart_noDirectives_hasComment() {
+    resolveTestUnit('''
+/// Comment.
+
+class A {}
+''');
+    LibraryElement newLibrary1 = _getDartLibrary('dart:math');
+    LibraryElement newLibrary2 = _getDartLibrary('dart:async');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+/// Comment.
+
+import 'dart:async';
+import 'dart:math';
+
+class A {}
+''');
+  }
+
+  test_addLibraryImports_dart_noDirectives_hasShebang() {
+    resolveTestUnit('''
+#!/bin/dart
+
+class A {}
+''');
+    LibraryElement newLibrary1 = _getDartLibrary('dart:math');
+    LibraryElement newLibrary2 = _getDartLibrary('dart:async');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+#!/bin/dart
+
+import 'dart:async';
+import 'dart:math';
+
+class A {}
+''');
+  }
+
+  test_addLibraryImports_dart_noDirectives_noShebang() {
+    resolveTestUnit('''
+class A {}
+''');
+    LibraryElement newLibrary1 = _getDartLibrary('dart:math');
+    LibraryElement newLibrary2 = _getDartLibrary('dart:async');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+import 'dart:async';
+import 'dart:math';
+
+class A {}
+''');
+  }
+
+  test_addLibraryImports_package_hasDart_hasPackages_insertAfter() {
+    resolveTestUnit('''
+import 'dart:async';
+
+import 'package:aaa/aaa.dart';
+''');
+    LibraryElement newLibrary =
+        _mockLibraryElement('/lib/bbb.dart', 'package:bbb/bbb.dart');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary],
+        '''
+import 'dart:async';
+
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart';
+''');
+  }
+
+  test_addLibraryImports_package_hasDart_hasPackages_insertBefore() {
+    resolveTestUnit('''
+import 'dart:async';
+
+import 'package:bbb/bbb.dart';
+''');
+    LibraryElement newLibrary =
+        _mockLibraryElement('/lib/aaa.dart', 'package:aaa/aaa.dart');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary],
+        '''
+import 'dart:async';
+
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart';
+''');
+  }
+
+  test_addLibraryImports_package_hasImports_between() {
+    resolveTestUnit('''
+import 'package:aaa/aaa.dart';
+import 'package:ddd/ddd.dart';
+''');
+    LibraryElement newLibrary1 =
+        _mockLibraryElement('/lib/bbb.dart', 'package:bbb/bbb.dart');
+    LibraryElement newLibrary2 =
+        _mockLibraryElement('/lib/ccc.dart', 'package:ccc/ccc.dart');
+    _assertAddLibraryImport(
+        <LibraryElement>[newLibrary1, newLibrary2],
+        '''
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart';
+import 'package:ccc/ccc.dart';
+import 'package:ddd/ddd.dart';
+''');
+  }
+
+  void _assertAddLibraryImport(
+      List<LibraryElement> newLibraries, String expectedCode) {
+    SourceChange change = new SourceChange('');
+    addLibraryImports(change, testLibraryElement, newLibraries.toSet());
+    SourceFileEdit testEdit = change.getFileEdit(testFile);
+    expect(testEdit, isNotNull);
+    String resultCode = SourceEdit.applySequence(testCode, testEdit.edits);
+    expect(resultCode, expectedCode);
+  }
+
+  LibraryElement _getDartLibrary(String uri) {
+    String path = removeStart(uri, 'dart:');
+    Source newSource = new _SourceMock('/sdk/lib/$path.dart', Uri.parse(uri));
+    return new _LibraryElementMock(newSource);
+  }
+
+  LibraryElement _mockLibraryElement(String path, String uri) {
+    Source newSource = new _SourceMock(path, Uri.parse(uri));
+    return new _LibraryElementMock(newSource);
+  }
+}
+
+class _LibraryElementMock implements LibraryElement {
+  @override
+  final Source source;
+
+  _LibraryElementMock(this.source);
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class _SourceMock implements Source {
+  @override
+  final String fullName;
+
+  @override
+  final Uri uri;
+
+  _SourceMock(this.fullName, this.uri);
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index 46ed173..d35c631 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -90,6 +91,22 @@
         expectedContextSearch: 'newName() {} // existing');
   }
 
+  test_checkFinalConditions_OK_dropSuffix() async {
+    indexTestUnit(r'''
+abstract class A {
+  void testOld();
+}
+class B implements A {
+  void testOld() {}
+}
+''');
+    createRenameRefactoringAtString('testOld() {}');
+    // check status
+    refactoring.newName = 'test';
+    RefactoringStatus status = await refactoring.checkFinalConditions();
+    assertRefactoringStatusOK(status);
+  }
+
   test_checkFinalConditions_OK_noShadow() async {
     indexTestUnit('''
 class A {
@@ -249,15 +266,15 @@
         expectedContextSearch: 'test(); // marker');
   }
 
-  test_checkFinalConditions_shadowed_inSubClass() async {
+  test_checkFinalConditions_shadowedBySub_MethodElement() async {
     indexTestUnit('''
 class A {
-  newName() {} // marker
+  test() {}
 }
 class B extends A {
-  test() {}
+  newName() {} // marker
   main() {
-    newName();
+    test();
   }
 }
 ''');
@@ -266,11 +283,12 @@
     refactoring.newName = 'newName';
     RefactoringStatus status = await refactoring.checkFinalConditions();
     assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
-        expectedMessage: "Renamed method will shadow method 'A.newName'.",
+        expectedMessage:
+            "Renamed method will be shadowed by method 'B.newName'.",
         expectedContextSearch: 'newName() {} // marker');
   }
 
-  test_checkFinalConditions_shadowsSuper_inSubClass_FieldElement() async {
+  test_checkFinalConditions_shadowsSuper_FieldElement() async {
     indexTestUnit('''
 class A {
   int newName; // marker
@@ -296,13 +314,10 @@
   test_checkFinalConditions_shadowsSuper_MethodElement() async {
     indexTestUnit('''
 class A {
-  test() {}
+  newName() {} // marker
 }
 class B extends A {
-  newName() {} // marker
-  main() {
-    test();
-  }
+  test() {}
 }
 ''');
     createRenameRefactoringAtString('test() {}');
@@ -310,11 +325,33 @@
     refactoring.newName = 'newName';
     RefactoringStatus status = await refactoring.checkFinalConditions();
     assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
-        expectedMessage:
-            "Renamed method will be shadowed by method 'B.newName'.",
+        expectedMessage: "Renamed method will shadow method 'A.newName'.",
         expectedContextSearch: 'newName() {} // marker');
   }
 
+  test_checkFinalConditions_shadowsSuper_MethodElement_otherLib() async {
+    var libCode = r'''
+class A {
+  newName() {} // marker
+}
+''';
+    indexUnit('/lib.dart', libCode);
+    indexTestUnit('''
+import 'lib.dart';
+class B extends A {
+  test() {}
+}
+''');
+    createRenameRefactoringAtString('test() {}');
+    // check status
+    refactoring.newName = 'newName';
+    RefactoringStatus status = await refactoring.checkFinalConditions();
+    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
+        expectedMessage: "Renamed method will shadow method 'A.newName'.",
+        expectedContextRange: new SourceRange(
+            libCode.indexOf('newName() {} // marker'), 'newName'.length));
+  }
+
   test_checkInitialConditions_inSDK() async {
     indexTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index 027c237..802f351 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -118,6 +118,41 @@
     return Future.wait([futureA, futureB, futureC, futureD]);
   }
 
+  Future test_getHierarchyMembers_fields_static() async {
+    _indexTestUnit('''
+class A {
+  static int foo;
+}
+class B extends A {
+  static get foo => null;
+}
+class C extends B {
+  static set foo(x) {}
+}
+''');
+    ClassElement classA = findElement('A');
+    ClassElement classB = findElement('B');
+    ClassElement classC = findElement('C');
+    ClassMemberElement memberA = classA.fields[0];
+    ClassMemberElement memberB = classB.fields[0];
+    ClassMemberElement memberC = classC.fields[0];
+    {
+      Set<ClassMemberElement> members =
+          await getHierarchyMembers(searchEngine, memberA);
+      expect(members, unorderedEquals([memberA]));
+    }
+    {
+      Set<ClassMemberElement> members =
+          await getHierarchyMembers(searchEngine, memberB);
+      expect(members, unorderedEquals([memberB]));
+    }
+    {
+      Set<ClassMemberElement> members =
+          await getHierarchyMembers(searchEngine, memberC);
+      expect(members, unorderedEquals([memberC]));
+    }
+  }
+
   Future test_getHierarchyMembers_methods() {
     _indexTestUnit('''
 class A {
@@ -164,6 +199,31 @@
     return Future.wait([futureA, futureB, futureC, futureD, futureE]);
   }
 
+  Future test_getHierarchyMembers_methods_static() async {
+    _indexTestUnit('''
+class A {
+  static foo() {}
+}
+class B extends A {
+  static foo() {}
+}
+''');
+    ClassElement classA = findElement('A');
+    ClassElement classB = findElement('B');
+    ClassMemberElement memberA = classA.methods[0];
+    ClassMemberElement memberB = classB.methods[0];
+    {
+      Set<ClassMemberElement> members =
+          await getHierarchyMembers(searchEngine, memberA);
+      expect(members, unorderedEquals([memberA]));
+    }
+    {
+      Set<ClassMemberElement> members =
+          await getHierarchyMembers(searchEngine, memberB);
+      expect(members, unorderedEquals([memberB]));
+    }
+  }
+
   Future test_getHierarchyMembers_withInterfaces() {
     _indexTestUnit('''
 class A {
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 4bf728d..7a9db13 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -101,8 +101,9 @@
 }
 class B {
   int test = 1;
+  int testTwo = 2;
   main() {
-    int test = 2;
+    int test = 3;
   }
 }
 ''');
@@ -460,6 +461,34 @@
     await _verifyReferences(element, expected);
   }
 
+  test_searchReferences_ImportElement_withPrefix_forMultipleImports() async {
+    _indexTestUnit('''
+import 'dart:async' as p;
+import 'dart:math' as p;
+main() {
+  p.Random;
+  p.Future;
+}
+''');
+    Element mainElement = findElement('main');
+    var kind = MatchKind.REFERENCE;
+    var length = 'p.'.length;
+    {
+      ImportElement element = testLibraryElement.imports[0];
+      var expected = [
+        _expectId(mainElement, kind, 'p.Future;', length: length),
+      ];
+      await _verifyReferences(element, expected);
+    }
+    {
+      ImportElement element = testLibraryElement.imports[1];
+      var expected = [
+        _expectId(mainElement, kind, 'p.Random', length: length),
+      ];
+      await _verifyReferences(element, expected);
+    }
+  }
+
   test_searchReferences_LabelElement() async {
     _indexTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index a3279d2..948bf43 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_test.dart
@@ -11,9 +11,10 @@
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/socket_server.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:plugin/manager.dart';
 import 'package:unittest/unittest.dart';
 
@@ -109,11 +110,13 @@
   }
 
   static SocketServer _createSocketServer() {
+    PhysicalResourceProvider resourceProvider =
+        PhysicalResourceProvider.INSTANCE;
     ServerPlugin serverPlugin = new ServerPlugin();
     ExtensionManager manager = new ExtensionManager();
     manager.processPlugins([serverPlugin]);
-    SdkCreator sdkCreator = (_) =>
-        new DirectoryBasedDartSdk(DirectoryBasedDartSdk.defaultSdkDirectory);
+    SdkCreator sdkCreator = (_) => new FolderBasedDartSdk(resourceProvider,
+        FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
     return new SocketServer(
         new AnalysisServerOptions(),
         new DartSdkManager('', false, sdkCreator),
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 98f1165..de239de 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
@@ -12,8 +12,8 @@
 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/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:unittest/unittest.dart';
 
 import '../utils.dart';
@@ -74,7 +74,8 @@
     CachingPubPackageMapProvider newPkgProvider() {
       return new CachingPubPackageMapProvider(
           resProvider,
-          DirectoryBasedDartSdk.defaultSdk,
+          new FolderBasedDartSdk(
+              resProvider, FolderBasedDartSdk.defaultSdkDirectory(resProvider)),
           mockRunner.runPubList,
           mockWriteFile);
     }
diff --git a/pkg/analysis_server/test/stress/replay/replay.dart b/pkg/analysis_server/test/stress/replay/replay.dart
index 6c56047..dd9016d 100644
--- a/pkg/analysis_server/test/stress/replay/replay.dart
+++ b/pkg/analysis_server/test/stress/replay/replay.dart
@@ -9,6 +9,7 @@
 
 import 'dart:async';
 import 'dart:io';
+import 'dart:math' as math;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -168,7 +169,8 @@
     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);
+      int srcEnd = info.getOffsetOfLine(
+          math.min(hunk.srcLine + hunk.removeLines.length, info.lineCount - 1));
       String addedText = _join(hunk.addLines);
       //
       // Create the source edits.
@@ -320,6 +322,7 @@
     //
     // Iterate over the history, applying changes.
     //
+    int dotCount = 0;
     bool firstCheckout = true;
     ErrorMap expectedErrors = null;
     Iterable<String> changedPubspecs;
@@ -363,6 +366,10 @@
       }
       changedPubspecs = commitDelta.filesMatching(PUBSPEC_FILE_NAME);
       stdout.write('.');
+      if (dotCount++ > 100) {
+        stdout.writeln();
+        dotCount = 0;
+      }
     }
     server.removeAllOverlays();
     stdout.writeln();
@@ -632,10 +639,8 @@
     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 '$minutes:$seconds.$milliseconds';
     }
-    return '$milliseconds ms';
+    return '$seconds.$milliseconds';
   }
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index 5819e20..b34cca3 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -225,7 +225,7 @@
           doCapitalize: true);
       futureClass = 'Future<$resultClass>';
     }
-    writeln('$futureClass $methodName(${args.join(', ')}) {');
+    writeln('$futureClass $methodName(${args.join(', ')}) async {');
     indent(() {
       String requestClass = camelJoin(
           [request.domainName, request.method, 'params'],
@@ -245,24 +245,19 @@
         args.addAll(optionalArgs);
         writeln('var params = new $requestClass(${args.join(', ')}).toJson();');
       }
-      writeln(
-          'return server.send(${JSON.encode(request.longMethod)}, $paramsVar)');
-      indent(() {
-        writeln('  .then((result) {');
-        if (request.result != null) {
-          String kind = 'null';
-          if (requestClass == 'EditGetRefactoringParams') {
-            kind = 'kind';
-          }
-          writeln('ResponseDecoder decoder = new ResponseDecoder($kind);');
-          writeln(
-              "return new $resultClass.fromJson(decoder, 'result', result);");
-        } else {
-          writeln('expect(result, isNull);');
-          writeln('return null;');
+      String methodJson = JSON.encode(request.longMethod);
+      writeln('var result = await server.send($methodJson, $paramsVar);');
+      if (request.result != null) {
+        String kind = 'null';
+        if (requestClass == 'EditGetRefactoringParams') {
+          kind = 'kind';
         }
-      });
-      writeln('});');
+        writeln('ResponseDecoder decoder = new ResponseDecoder($kind);');
+        writeln("return new $resultClass.fromJson(decoder, 'result', result);");
+      } else {
+        writeln('expect(result, isNull);');
+        writeln('return null;');
+      }
     });
     writeln('}');
   }
diff --git a/pkg/analyzer/.analysis_options b/pkg/analyzer/.analysis_options
index 2b11248..c952041 100644
--- a/pkg/analyzer/.analysis_options
+++ b/pkg/analyzer/.analysis_options
@@ -1,3 +1,5 @@
+analyzer:
+  strong-mode: true
 linter:
   rules:
     # TODO(pq): re-enable once we have a bulk edit tool
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 07f8a30..4be083e 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 0.27.4-alpha.19
+* Added support for running the dev compiler in the browser.
+
+## 0.27.4-alpha.18
+* Support for references to operators in doc comments (#26929).
+
+## 0.27.4-alpha.17
+* Support for trailing commas in parameter and argument lists (#26647).
+* Strong mode breaking change: can now infer generic type arguments from the constructor invocation arguments (#25220).
+
+## 0.27.4-alpha.16
+* (Internal) Corresponds with the analyzer/server in the `1.18.0-dev.4.0` SDK.
+
 ## 0.27.4-alpha.9
 * Restore EmbedderUriResolver API.
 
diff --git a/pkg/analyzer/benchmark/errors_in_all_libraries.dart b/pkg/analyzer/benchmark/errors_in_all_libraries.dart
index 6f02534..be42c2b 100644
--- a/pkg/analyzer/benchmark/errors_in_all_libraries.dart
+++ b/pkg/analyzer/benchmark/errors_in_all_libraries.dart
@@ -10,21 +10,18 @@
 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_io.dart' show DirectoryBasedDartSdk;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.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/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/source/source_resource.dart';
 import 'package:path/path.dart' as p;
 
 void main(List<String> args) {
-  JavaSystemIO.setProperty(
-      "com.google.dart.sdk",
-      p.normalize(
-          p.join(p.dirname(p.fromUri(Platform.script)), "../../../sdk")));
-
   // Assumes you have run "pub get" in the analyzer directory itself and uses
   // that "packages" directory as its package root.
   var packageRoot =
@@ -35,10 +32,14 @@
     var start = new DateTime.now();
     AnalysisEngine.instance.clearCaches();
 
-    var context = AnalysisEngine.instance.createAnalysisContext();
+    PhysicalResourceProvider resourceProvider =
+        PhysicalResourceProvider.INSTANCE;
+    DartSdk sdk = new FolderBasedDartSdk(
+        resourceProvider, resourceProvider.getFolder(args[0]));
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
     context.sourceFactory = new SourceFactory([
-      new DartUriResolver(DirectoryBasedDartSdk.defaultSdk),
-      new ResourceUriResolver(PhysicalResourceProvider.INSTANCE),
+      new DartUriResolver(sdk),
+      new ResourceUriResolver(resourceProvider),
       new PackageUriResolver([new JavaFile(packageRoot)])
     ]);
 
@@ -47,7 +48,7 @@
     options.strongModeHints = true;
 
     var mainSource =
-        new FileBasedSource(new JavaFile(p.fromUri(Platform.script)));
+        new FileSource(resourceProvider.getFile(p.fromUri(Platform.script)));
     context.applyChanges(new ChangeSet()..addedSource(mainSource));
 
     var initialLibrary =
@@ -86,6 +87,7 @@
     lib.importedLibraries.forEach(find);
     lib.exportedLibraries.forEach(find);
   }
+
   find(start);
   return results;
 }
diff --git a/pkg/analyzer/doc/tasks.html b/pkg/analyzer/doc/tasks.html
index eb19b8b..3129e1a 100644
--- a/pkg/analyzer/doc/tasks.html
+++ b/pkg/analyzer/doc/tasks.html
@@ -30,7 +30,6 @@
   BuildLibraryElementTask -> BUILD_LIBRARY_ERRORS
   BuildLibraryElementTask -> IS_LAUNCHABLE
   BuildLibraryElementTask -> LIBRARY_ELEMENT1
-  BuildLibraryElementTask -> REFERENCED_NAMES
   BuildPublicNamespaceTask -> LIBRARY_ELEMENT3
   BuildSourceExportClosureTask -> EXPORT_SOURCE_CLOSURE
   BuildTypeProviderTask -> TYPE_PROVIDER
@@ -96,6 +95,7 @@
   EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
   EXPORTED_LIBRARIES [shape=box]
   EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
+  EXPORT_SOURCE_CLOSURE -> ResolveTopLevelUnitTypeBoundsTask
   EXPORT_SOURCE_CLOSURE [shape=box]
   EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
   EvaluateUnitConstantsTask -> RESOLVED_UNIT13
@@ -127,8 +127,10 @@
   InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
   InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
   InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
+  InferStaticVariableTypeTask -> STATIC_VARIABLE_RESOLUTION_ERRORS
   InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
   InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
+  InferStaticVariableTypesInUnitTask -> STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
   LIBRARY_CYCLE [shape=box]
   LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
   LIBRARY_CYCLE_DEPENDENCIES -> InferStaticVariableTypeTask
@@ -192,6 +194,7 @@
   LibraryErrorsReadyTask -> LIBRARY_ERRORS_READY
   LibraryUnitErrorsTask -> LIBRARY_UNIT_ERRORS
   MODIFICATION_TIME -> BuildDirectiveElementsTask
+  MODIFICATION_TIME -> BuildLibraryElementTask
   MODIFICATION_TIME -> ParseDartTask
   MODIFICATION_TIME -> ScanDartTask
   MODIFICATION_TIME -> VerifyUnitTask
@@ -216,6 +219,7 @@
   ParseDartTask -> LIBRARY_SPECIFIC_UNITS
   ParseDartTask -> PARSED_UNIT
   ParseDartTask -> PARSE_ERRORS
+  ParseDartTask -> REFERENCED_NAMES
   ParseDartTask -> REFERENCED_SOURCES
   ParseDartTask -> SOURCE_KIND
   ParseDartTask -> UNITS
@@ -326,6 +330,10 @@
   SCAN_ERRORS [shape=box]
   SOURCE_KIND -> BuildDirectiveElementsTask
   SOURCE_KIND [shape=box]
+  STATIC_VARIABLE_RESOLUTION_ERRORS -> InferStaticVariableTypesInUnitTask
+  STATIC_VARIABLE_RESOLUTION_ERRORS [shape=box]
+  STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT -> LibraryUnitErrorsTask
+  STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT [shape=box]
   STRONG_MODE_ERRORS -> LibraryUnitErrorsTask
   STRONG_MODE_ERRORS [shape=box]
   ScanDartTask -> IGNORE_INFO
diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
index 885a5225..73c5733 100755
--- a/pkg/analyzer/example/resolver_driver.dart
+++ b/pkg/analyzer/example/resolver_driver.dart
@@ -8,14 +8,15 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart' hide File;
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.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;
-import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/file_system/file_system.dart' hide File;
-import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/source/source_resource.dart';
 
 void main(List<String> args) {
   print('working dir ${new File('.').resolveSymbolicLinksSync()}');
@@ -30,12 +31,13 @@
     packageRoot = args[2];
   }
 
-  JavaSystemIO.setProperty("com.google.dart.sdk", args[0]);
-  DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
+  PhysicalResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
+  DartSdk sdk = new FolderBasedDartSdk(
+      resourceProvider, resourceProvider.getFolder(args[0]));
 
   var resolvers = [
     new DartUriResolver(sdk),
-    new ResourceUriResolver(PhysicalResourceProvider.INSTANCE)
+    new ResourceUriResolver(resourceProvider)
   ];
 
   if (packageRoot != null) {
@@ -46,7 +48,7 @@
   AnalysisContext context = AnalysisEngine.instance.createAnalysisContext()
     ..sourceFactory = new SourceFactory(resolvers);
 
-  Source source = new FileBasedSource(new JavaFile(args[1]));
+  Source source = new FileSource(resourceProvider.getFile(args[1]));
   ChangeSet changeSet = new ChangeSet()..addedSource(source);
   context.applyChanges(changeSet);
   LibraryElement libElement = context.computeLibraryElement(source);
diff --git a/pkg/analyzer/lib/context/declared_variables.dart b/pkg/analyzer/lib/context/declared_variables.dart
index 9a0322c..86d6234 100644
--- a/pkg/analyzer/lib/context/declared_variables.dart
+++ b/pkg/analyzer/lib/context/declared_variables.dart
@@ -23,6 +23,11 @@
   HashMap<String, String> _declaredVariables = new HashMap<String, String>();
 
   /**
+   * Return the names of the variables for which a value has been defined.
+   */
+  Iterable<String> get variableNames => _declaredVariables.keys;
+
+  /**
    * Define a variable with the given [name] to have the given [value].
    */
   void define(String name, String value) {
diff --git a/pkg/analyzer/lib/dart/ast/token.dart b/pkg/analyzer/lib/dart/ast/token.dart
index 14ba3f9..687111a 100644
--- a/pkg/analyzer/lib/dart/ast/token.dart
+++ b/pkg/analyzer/lib/dart/ast/token.dart
@@ -409,6 +409,9 @@
   static const TokenType AMPERSAND_AMPERSAND = const TokenType._(
       'AMPERSAND_AMPERSAND', TokenClass.LOGICAL_AND_OPERATOR, '&&');
 
+  static const TokenType AMPERSAND_AMPERSAND_EQ = const TokenType._(
+      'AMPERSAND_AMPERSAND_EQ', TokenClass.ASSIGNMENT_OPERATOR, '&&=');
+
   static const TokenType AMPERSAND_EQ =
       const TokenType._('AMPERSAND_EQ', TokenClass.ASSIGNMENT_OPERATOR, '&=');
 
@@ -426,6 +429,9 @@
   static const TokenType BAR_BAR =
       const TokenType._('BAR_BAR', TokenClass.LOGICAL_OR_OPERATOR, '||');
 
+  static const TokenType BAR_BAR_EQ =
+      const TokenType._('BAR_BAR_EQ', TokenClass.ASSIGNMENT_OPERATOR, '||=');
+
   static const TokenType BAR_EQ =
       const TokenType._('BAR_EQ', TokenClass.ASSIGNMENT_OPERATOR, '|=');
 
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 7a12c6f1c..41d6f84 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -166,6 +166,11 @@
    * this folder.
    */
   bool isOrContains(String path);
+
+  /**
+   * Return a Uri representing this resource.
+   */
+  Uri toUri();
 }
 
 /**
@@ -198,6 +203,14 @@
   Folder getFolder(String path);
 
   /**
+   * Complete with a list of modification times for the given [sources].
+   *
+   * If the file of a source is not managed by this provider, return `null`.
+   * If the file a source does not exist, return `-1`.
+   */
+  Future<List<int>> getModificationTimes(List<Source> sources);
+
+  /**
    * Return the [Resource] that corresponds to the given [path].
    */
   Resource getResource(String path);
@@ -225,6 +238,8 @@
 
   ResourceUriResolver(this._provider);
 
+  ResourceProvider get provider => _provider;
+
   @override
   Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     if (!isFileUri(uri)) {
@@ -242,8 +257,6 @@
   Uri restoreAbsolute(Source source) =>
       _provider.pathContext.toUri(source.fullName);
 
-  ResourceProvider get provider => _provider;
-
   /**
    * Return `true` if the given [uri] is a `file` URI.
    */
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 3391433..dbc41d1 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -9,8 +9,8 @@
 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/source/source_resource.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
@@ -80,6 +80,14 @@
   Folder getFolder(String path) => newFolder(path);
 
   @override
+  Future<List<int>> getModificationTimes(List<Source> sources) async {
+    return sources.map((source) {
+      String path = source.fullName;
+      return _pathToTimestamp[path] ?? -1;
+    }).toList();
+  }
+
+  @override
   Resource getResource(String path) {
     path = pathContext.normalize(path);
     Resource resource = _pathToResource[path];
@@ -271,10 +279,6 @@
     return stamp;
   }
 
-  String get _content {
-    throw new FileSystemException(path, 'File could not be read');
-  }
-
   @override
   Source createSource([Uri uri]) {
     throw new FileSystemException(path, 'File could not be read');
@@ -306,6 +310,9 @@
   }
 
   @override
+  Uri toUri() => new Uri.file(path, windows: _provider.pathContext == windows);
+
+  @override
   void writeAsBytesSync(List<int> bytes) {
     throw new FileSystemException(path, 'File could not be written');
   }
@@ -330,20 +337,10 @@
     return stamp;
   }
 
-  String get _content {
-    String content = _provider._pathToContent[path];
-    if (content == null) {
-      throw new FileSystemException(path, 'File "$path" does not exist.');
-    }
-    return content;
-  }
-
   @override
   Source createSource([Uri uri]) {
-    if (uri == null) {
-      uri = _provider.pathContext.toUri(path);
-    }
-    return new _MemoryFileSource(this, uri);
+    uri ??= _provider.pathContext.toUri(path);
+    return new FileSource(this, uri);
   }
 
   @override
@@ -380,101 +377,15 @@
   }
 
   @override
+  Uri toUri() => new Uri.file(path, windows: _provider.pathContext == windows);
+
+  @override
   void writeAsBytesSync(List<int> bytes) {
     _provider._setFileBytes(this, bytes);
   }
 }
 
 /**
- * An in-memory implementation of [Source].
- */
-class _MemoryFileSource extends Source {
-  /**
-   * Map from encoded URI/filepath pair to a unique integer identifier.  This
-   * identifier is used for equality tests and hash codes.
-   *
-   * The URI and filepath are joined into a pair by separating them with an '@'
-   * character.
-   */
-  static final Map<String, int> _idTable = new HashMap<String, int>();
-
-  final _MemoryFile file;
-
-  @override
-  final Uri uri;
-
-  /**
-   * The unique ID associated with this [_MemoryFileSource].
-   */
-  final int id;
-
-  _MemoryFileSource(_MemoryFile file, Uri uri)
-      : uri = uri,
-        file = file,
-        id = _idTable.putIfAbsent('$uri@${file.path}', () => _idTable.length);
-
-  @override
-  TimestampedData<String> get contents {
-    return new TimestampedData<String>(modificationStamp, file._content);
-  }
-
-  @override
-  String get encoding {
-    return uri.toString();
-  }
-
-  @override
-  String get fullName => file.path;
-
-  @override
-  int get hashCode => id;
-
-  @override
-  bool get isInSystemLibrary => uriKind == UriKind.DART_URI;
-
-  @override
-  int get modificationStamp {
-    try {
-      return file.modificationStamp;
-    } on FileSystemException {
-      return -1;
-    }
-  }
-
-  @override
-  String get shortName => file.shortName;
-
-  @override
-  UriKind get uriKind {
-    String scheme = uri.scheme;
-    if (scheme == PackageUriResolver.PACKAGE_SCHEME) {
-      return UriKind.PACKAGE_URI;
-    } else if (scheme == DartUriResolver.DART_SCHEME) {
-      return UriKind.DART_URI;
-    } else if (scheme == ResourceUriResolver.FILE_SCHEME) {
-      return UriKind.FILE_URI;
-    }
-    return UriKind.FILE_URI;
-  }
-
-  @override
-  bool operator ==(other) {
-    if (other is _MemoryFileSource) {
-      return id == other.id;
-    } else if (other is Source) {
-      return uri == other.uri;
-    }
-    return false;
-  }
-
-  @override
-  bool exists() => file.exists;
-
-  @override
-  String toString() => file.toString();
-}
-
-/**
  * An in-memory implementation of [Folder].
  */
 class _MemoryFolder extends _MemoryResource implements Folder {
@@ -553,6 +464,10 @@
     }
     return contains(path);
   }
+
+  @override
+  Uri toUri() =>
+      new Uri.directory(path, windows: _provider.pathContext == windows);
 }
 
 /**
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 9cd62b6..3b02335 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -9,13 +9,37 @@
 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/source/source_resource.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:isolate/isolate_runner.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
 /**
+ * Return modification times for every file path in [paths].
+ *
+ * If a path is `null`, the modification time is also `null`.
+ *
+ * If any exception happens, the file is considered as a not existing and
+ * `-1` is its modification time.
+ */
+List<int> _pathsToTimes(List<String> paths) {
+  return paths.map((path) {
+    if (path != null) {
+      try {
+        io.File file = new io.File(path);
+        return file.lastModifiedSync().millisecondsSinceEpoch;
+      } catch (_) {
+        return -1;
+      }
+    } else {
+      return null;
+    }
+  }).toList();
+}
+
+/**
  * A `dart:io` based implementation of [ResourceProvider].
  */
 class PhysicalResourceProvider implements ResourceProvider {
@@ -31,6 +55,9 @@
    */
   static final String SERVER_DIR = ".dartServer";
 
+  static _SingleIsolateRunnerProvider pathsToTimesIsolateProvider =
+      new _SingleIsolateRunnerProvider();
+
   @override
   final AbsolutePathContext absolutePathContext =
       new AbsolutePathContext(io.Platform.isWindows);
@@ -45,10 +72,23 @@
   Context get pathContext => io.Platform.isWindows ? windows : posix;
 
   @override
-  File getFile(String path) => new _PhysicalFile(new io.File(path));
+  File getFile(String path) {
+    path = normalize(path);
+    return new _PhysicalFile(new io.File(path));
+  }
 
   @override
-  Folder getFolder(String path) => new _PhysicalFolder(new io.Directory(path));
+  Folder getFolder(String path) {
+    path = normalize(path);
+    return new _PhysicalFolder(new io.Directory(path));
+  }
+
+  @override
+  Future<List<int>> getModificationTimes(List<Source> sources) async {
+    List<String> paths = sources.map((source) => source.fullName).toList();
+    IsolateRunner runner = await pathsToTimesIsolateProvider.get();
+    return runner.run(_pathsToTimes, paths);
+  }
 
   @override
   Resource getResource(String path) {
@@ -98,12 +138,7 @@
 
   @override
   Source createSource([Uri uri]) {
-    io.File file = _entry as io.File;
-    JavaFile javaFile = new JavaFile(file.absolute.path);
-    if (uri == null) {
-      uri = javaFile.toURI();
-    }
-    return new FileBasedSource(javaFile, uri);
+    return new FileSource(this, uri ?? pathContext.toUri(path));
   }
 
   @override
@@ -143,6 +178,9 @@
   }
 
   @override
+  Uri toUri() => new Uri.file(path);
+
+  @override
   void writeAsBytesSync(List<int> bytes) {
     try {
       io.File file = _entry as io.File;
@@ -220,6 +258,9 @@
     }
     return contains(path);
   }
+
+  @override
+  Uri toUri() => new Uri.directory(path);
 }
 
 /**
@@ -251,6 +292,11 @@
   @override
   String get path => _entry.absolute.path;
 
+  /**
+   * Return the path context used by this resource provider.
+   */
+  Context get pathContext => io.Platform.isWindows ? windows : posix;
+
   @override
   String get shortName => absolutePathContext.basename(path);
 
@@ -274,3 +320,33 @@
   @override
   String toString() => path;
 }
+
+/**
+ * This class encapsulates logic for creating a single [IsolateRunner].
+ */
+class _SingleIsolateRunnerProvider {
+  bool _isSpawning = false;
+  IsolateRunner _runner;
+
+  /**
+   * Complete with the only [IsolateRunner] instance.
+   */
+  Future<IsolateRunner> get() async {
+    if (_runner != null) {
+      return _runner;
+    }
+    if (_isSpawning) {
+      Completer<IsolateRunner> completer = new Completer<IsolateRunner>();
+      new Timer.periodic(new Duration(milliseconds: 10), (Timer timer) {
+        if (_runner != null) {
+          completer.complete(_runner);
+          timer.cancel();
+        }
+      });
+      return completer.future;
+    }
+    _isSpawning = true;
+    _runner = await IsolateRunner.spawn();
+    return _runner;
+  }
+}
diff --git a/pkg/analyzer/lib/source/config.dart b/pkg/analyzer/lib/source/config.dart
index 0ca954a..db44b4e 100644
--- a/pkg/analyzer/lib/source/config.dart
+++ b/pkg/analyzer/lib/source/config.dart
@@ -91,7 +91,8 @@
               Uri pragma = new Uri.file('config/${descriptor.pragma}.yaml',
                   windows: false);
               Uri optionsUri = uri.resolveUri(pragma);
-              File file = resourceProvider.getFile(optionsUri.toFilePath());
+              String path = resourceProvider.pathContext.fromUri(optionsUri);
+              File file = resourceProvider.getFile(path);
               if (file.exists) {
                 return optionsProvider.getOptionsFromFile(file);
               }
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
index 56abc6a..ffcbfed 100644
--- a/pkg/analyzer/lib/source/embedder.dart
+++ b/pkg/analyzer/lib/source/embedder.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.
 
+@deprecated
 library analyzer.source.embedder;
 
 import 'dart:collection' show HashMap;
@@ -16,16 +17,20 @@
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
 import 'package:yaml/yaml.dart';
 
+export 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
+
 const String _DART_COLON_PREFIX = 'dart:';
 const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
 
 /// Check if this map defines embedded libraries.
+@deprecated
 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null;
 
 /// An SDK backed by URI mappings derived from an `_embedder.yaml` file.
+@deprecated
 class EmbedderSdk extends AbstractDartSdk {
   final Map<String, String> _urlMappings = new HashMap<String, String>();
 
@@ -41,6 +46,9 @@
   Map<String, String> get urlMappings => _urlMappings;
 
   @override
+  PackageBundle getLinkedBundle() => null;
+
+  @override
   String getRelativePathFromFile(JavaFile file) => file.getAbsolutePath();
 
   @override
@@ -175,74 +183,3 @@
     return sdkSource?.uri;
   }
 }
-
-/// 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) {
-      _processPackageMap(packageMap);
-    }
-  }
-
-  /// Programatically add an _embedder.yaml mapping.
-  void addEmbedderYaml(Folder libDir, String embedderYaml) {
-    _processEmbedderYaml(libDir, embedderYaml);
-  }
-
-  void refresh(Map<String, List<Folder>> packageMap) {
-    // Clear existing.
-    embedderYamls.clear();
-    if (packageMap != null) {
-      _processPackageMap(packageMap);
-    }
-  }
-
-  /// 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 (_) {
-      return;
-    }
-    if (yaml is! YamlMap) {
-      return;
-    }
-    embedderYamls[libDir] = yaml;
-  }
-
-  /// 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);
-      }
-    }
-  }
-
-  void _processPackageMap(Map<String, List<Folder>> packageMap) {
-    packageMap.forEach(_processPackage);
-  }
-
-  /// 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;
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index a7b2c42..c562232 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -11,8 +11,8 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/package_map_provider.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
 
 /**
  * The function used to run pub list.
@@ -40,7 +40,7 @@
   /**
    * Sdk that we use to find the pub executable.
    */
-  final DirectoryBasedDartSdk sdk;
+  final FolderBasedDartSdk sdk;
 
   /**
    * The function used to run pub list.
@@ -146,6 +146,7 @@
         packageMap[packageName] = folders;
       }
     }
+
     packages.forEach((key, value) {
       if (value is String) {
         processPaths(key, [value]);
@@ -169,7 +170,7 @@
    * Run pub list to determine the packages and input files.
    */
   io.ProcessResult _runPubListDefault(Folder folder) {
-    String executablePath = sdk.pubExecutable.getAbsolutePath();
+    String executablePath = sdk.pubExecutable.path;
     List<String> arguments = [PUB_LIST_COMMAND];
     String workingDirectory = folder.path;
     int subprocessId = AnalysisEngine.instance.instrumentationService
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index 3e833df..f25d65e 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -31,6 +31,12 @@
 
   final Map<String, String> _urlMappings = <String, String>{};
 
+  /**
+   * The absolute paths of the extension files that contributed to the
+   * [_urlMappings].
+   */
+  final List<String> extensionFilePaths = <String>[];
+
   /// Construct a [SdkExtUriResolver] from a package map
   /// (see [PackageMapProvider]).
   SdkExtUriResolver(Map<String, List<Folder>> packageMap) {
@@ -147,18 +153,27 @@
     if ((sdkExt == null) || (sdkExt is! Map)) {
       return;
     }
-    sdkExt.forEach((k, v) => _processSdkExtension(k, v, libDir));
+    bool contributed = false;
+    sdkExt.forEach((k, v) {
+      if (_processSdkExtension(k, v, libDir)) {
+        contributed = true;
+      }
+    });
+    if (contributed) {
+      extensionFilePaths.add(libDir.getChild(SDK_EXT_NAME).path);
+    }
   }
 
   /// Install the mapping from [name] to [libDir]/[file].
-  void _processSdkExtension(String name, String file, Folder libDir) {
+  bool _processSdkExtension(String name, String file, Folder libDir) {
     if (!name.startsWith(DART_COLON_PREFIX)) {
       // SDK extensions must begin with 'dart:'.
-      return;
+      return false;
     }
     var key = name;
     var value = libDir.canonicalizePath(file);
     _urlMappings[key] = value;
+    return true;
   }
 
   /// Read the contents of [libDir]/[SDK_EXT_NAME] as a string.
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
index 307e1d9..43eb00c 100644
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -252,7 +252,7 @@
       _completer._outerCompleter.future.catchError(onError, test: test);
 
   @override
-  Future/*<S>*/ then/*<S>*/(/*=S*/ onValue(T value), {Function onError}) =>
+  Future/*<S>*/ then/*<S>*/(onValue(T value), {Function onError}) =>
       _completer._outerCompleter.future.then(onValue, onError: onError);
 
   @override
@@ -288,7 +288,7 @@
       _future.catchError(onError, test: test);
 
   @override
-  Future/*<S>*/ then/*<S>*/(/*=S*/ onValue(T value), {Function onError}) =>
+  Future/*<S>*/ then/*<S>*/(onValue(T value), {Function onError}) =>
       _future.then(onValue, onError: onError);
 
   @override
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 6abd7bd..1ba7dd2 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -8,24 +8,20 @@
 import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
+import 'package:analyzer/context/declared_variables.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
-import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/dart/sdk/sdk.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/generated/source_io.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:package_config/discovery.dart';
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart';
 import 'package:package_config/src/packages_impl.dart';
-import 'package:path/path.dart' as path;
 import 'package:yaml/yaml.dart';
 
 /**
@@ -75,48 +71,83 @@
   ResolverProvider packageResolverProvider;
 
   /**
+   * The resolver provider used to create a file: URI resolver, or `null` if
+   * the normal file URI resolver is to be used.
+   */
+  ResolverProvider fileResolverProvider;
+
+  /**
    * The file path of the .packages file that should be used in place of any
-   * file found using the normal (Package Specification DEP) lookup mechanism.
+   * file found using the normal (Package Specification DEP) lookup mechanism,
+   * or `null` if the normal lookup mechanism should be used.
    */
   String defaultPackageFilePath;
 
   /**
    * The file path of the packages directory that should be used in place of any
-   * file found using the normal (Package Specification DEP) lookup mechanism.
+   * file found using the normal (Package Specification DEP) lookup mechanism,
+   * or `null` if the normal lookup mechanism should be used.
    */
   String defaultPackagesDirectoryPath;
 
   /**
    * The file path of the analysis options file that should be used in place of
-   * any file in the root directory.
+   * any file in the root directory or a parent of the root directory, or `null`
+   * if the normal lookup mechanism should be used.
    */
   String defaultAnalysisOptionsFilePath;
 
   /**
    * The default analysis options that should be used unless some or all of them
-   * are overridden in the analysis options file.
+   * are overridden in the analysis options file, or `null` if the default
+   * defaults should be used.
    */
   AnalysisOptions defaultOptions;
 
   /**
+   * A table mapping variable names to values for the declared variables, or
+   * `null` if no additional variables should be declared.
+   */
+  Map<String, String> declaredVariables;
+
+  /**
    * Initialize a newly created builder to be ready to build a context rooted in
    * the directory with the given [rootDirectoryPath].
    */
   ContextBuilder(this.resourceProvider, this.sdkManager, this.contentCache);
 
-  AnalysisContext buildContext(String rootDirectoryPath) {
+  /**
+   * Return an analysis context that is configured correctly to analyze code in
+   * the directory with the given [path].
+   *
+   * *Note:* This method is not yet fully implemented and should not be used.
+   */
+  AnalysisContext buildContext(String path) {
     // TODO(brianwilkerson) Split getAnalysisOptions so we can capture the
     // option map and use it to run the options processors.
-    AnalysisOptions options = getAnalysisOptions(rootDirectoryPath);
+    AnalysisOptions options = getAnalysisOptions(path);
     InternalAnalysisContext context =
         AnalysisEngine.instance.createAnalysisContext();
     context.contentCache = contentCache;
-    context.sourceFactory = createSourceFactory(rootDirectoryPath, options);
+    context.sourceFactory = createSourceFactory(path, options);
     context.analysisOptions = options;
     //_processAnalysisOptions(context, optionMap);
+    declareVariables(context);
     return context;
   }
 
+  Map<String, List<Folder>> convertPackagesToMap(Packages packages) {
+    if (packages == null || packages == Packages.noPackages) {
+      return null;
+    }
+    Map<String, List<Folder>> folderMap = new HashMap<String, List<Folder>>();
+    packages.asMap().forEach((String packagePath, Uri uri) {
+      String path = resourceProvider.pathContext.fromUri(uri);
+      folderMap[packagePath] = [resourceProvider.getFolder(path)];
+    });
+    return folderMap;
+  }
+
 //  void _processAnalysisOptions(
 //      AnalysisContext context, Map<String, YamlNode> optionMap) {
 //    List<OptionsProcessor> optionsProcessors =
@@ -140,15 +171,14 @@
 //    }
 //  }
 
-  Map<String, List<Folder>> convertPackagesToMap(Packages packages) {
-    if (packages == null || packages == Packages.noPackages) {
-      return null;
+  /**
+   * Return an analysis options object containing the default option values.
+   */
+  AnalysisOptions createDefaultOptions() {
+    if (defaultOptions == null) {
+      return new AnalysisOptionsImpl();
     }
-    Map<String, List<Folder>> folderMap = new HashMap<String, List<Folder>>();
-    packages.asMap().forEach((String packagePath, Uri uri) {
-      folderMap[packagePath] = [resourceProvider.getFolder(path.fromUri(uri))];
-    });
-    return folderMap;
+    return new AnalysisOptionsImpl.from(defaultOptions);
   }
 
   Packages createPackageMap(String rootDirectoryPath) {
@@ -169,17 +199,24 @@
 
   SourceFactory createSourceFactory(
       String rootDirectoryPath, AnalysisOptions options) {
+    Folder _folder = null;
+    Folder folder() {
+      return _folder ??= resourceProvider.getResource('.');
+    }
+
+    UriResolver fileResolver = fileResolverProvider == null
+        ? new ResourceUriResolver(resourceProvider)
+        : fileResolverProvider(folder());
     if (packageResolverProvider != null) {
-      Folder folder = resourceProvider.getResource('.');
-      UriResolver resolver = packageResolverProvider(folder);
-      if (resolver != null) {
+      UriResolver packageResolver = packageResolverProvider(folder());
+      if (packageResolver != null) {
         // TODO(brianwilkerson) This doesn't support either embedder files or
         // sdk extensions because we don't have a way to get the package map
         // from the resolver.
         List<UriResolver> resolvers = <UriResolver>[
           new DartUriResolver(findSdk(null, options)),
-          resolver,
-          new ResourceUriResolver(resourceProvider)
+          packageResolver,
+          fileResolver
         ];
         return new SourceFactory(resolvers);
       }
@@ -189,52 +226,98 @@
     List<UriResolver> resolvers = <UriResolver>[];
     resolvers.add(new DartUriResolver(findSdk(packageMap, options)));
     if (packageMap != null) {
-      resolvers.add(new SdkExtUriResolver(packageMap));
       resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap));
     }
-    resolvers.add(new ResourceUriResolver(resourceProvider));
+    resolvers.add(fileResolver);
     return new SourceFactory(resolvers);
   }
 
   /**
-   * Use the given [packageMap] and [options] to locate the SDK.
+   * Add any [declaredVariables] to the list of declared variables used by the
+   * given [context].
+   */
+  void declareVariables(InternalAnalysisContext context) {
+    if (declaredVariables != null && declaredVariables.isNotEmpty) {
+      DeclaredVariables contextVariables = context.declaredVariables;
+      declaredVariables.forEach((String variableName, String value) {
+        contextVariables.define(variableName, value);
+      });
+    }
+  }
+
+  /**
+   * Return the SDK that should be used to analyze code. Use the given
+   * [packageMap] and [options] to locate the SDK.
    */
   DartSdk findSdk(
       Map<String, List<Folder>> packageMap, AnalysisOptions options) {
     if (packageMap != null) {
+      SdkExtensionFinder extFinder = new SdkExtensionFinder(packageMap);
+      List<String> extFilePaths = extFinder.extensionFilePaths;
       EmbedderYamlLocator locator = new EmbedderYamlLocator(packageMap);
       Map<Folder, YamlMap> embedderYamls = locator.embedderYamls;
-      EmbedderSdk embedderSdk = new EmbedderSdk(embedderYamls);
+      EmbedderSdk embedderSdk =
+          new EmbedderSdk(resourceProvider, embedderYamls);
       if (embedderSdk.sdkLibraries.length > 0) {
+        //
+        // There is an embedder file that defines the content of the SDK and
+        // there might be an extension file that extends it.
+        //
         List<String> paths = <String>[];
         for (Folder folder in embedderYamls.keys) {
           paths.add(folder
               .getChildAssumingFile(EmbedderYamlLocator.EMBEDDER_FILE_NAME)
               .path);
         }
+        paths.addAll(extFilePaths);
         SdkDescription description = new SdkDescription(paths, options);
         DartSdk dartSdk = sdkManager.getSdk(description, () {
+          if (extFilePaths.isNotEmpty) {
+            embedderSdk.addExtensions(extFinder.urlMappings);
+          }
           embedderSdk.analysisOptions = options;
           embedderSdk.useSummary = sdkManager.canUseSummaries;
           return embedderSdk;
         });
         return dartSdk;
+      } else if (extFilePaths != null && extFilePaths.isNotEmpty) {
+        //
+        // We have an extension file, but no embedder file.
+        //
+        String sdkPath = sdkManager.defaultSdkDirectory;
+        List<String> paths = <String>[sdkPath];
+        paths.addAll(extFilePaths);
+        SdkDescription description = new SdkDescription(paths, options);
+        return sdkManager.getSdk(description, () {
+          FolderBasedDartSdk sdk = new FolderBasedDartSdk(
+              resourceProvider, resourceProvider.getFolder(sdkPath));
+          if (extFilePaths.isNotEmpty) {
+            sdk.addExtensions(extFinder.urlMappings);
+          }
+          sdk.analysisOptions = options;
+          sdk.useSummary = sdkManager.canUseSummaries;
+          return sdk;
+        });
       }
     }
     String sdkPath = sdkManager.defaultSdkDirectory;
     SdkDescription description = new SdkDescription(<String>[sdkPath], options);
     return sdkManager.getSdk(description, () {
-      DirectoryBasedDartSdk sdk =
-          new DirectoryBasedDartSdk(new JavaFile(sdkPath));
+      FolderBasedDartSdk sdk = new FolderBasedDartSdk(
+          resourceProvider, resourceProvider.getFolder(sdkPath));
       sdk.analysisOptions = options;
       sdk.useSummary = sdkManager.canUseSummaries;
       return sdk;
     });
   }
 
-  AnalysisOptions getAnalysisOptions(String rootDirectoryPath) {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl.from(defaultOptions);
-    File optionsFile = getOptionsFile(rootDirectoryPath);
+  /**
+   * Return the analysis options that should be used when analyzing code in the
+   * directory with the given [path].
+   */
+  AnalysisOptions getAnalysisOptions(String path) {
+    AnalysisOptionsImpl options = createDefaultOptions();
+    File optionsFile = getOptionsFile(path);
     if (optionsFile != null) {
       Map<String, YamlNode> fileOptions =
           new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
@@ -243,11 +326,15 @@
     return options;
   }
 
-  File getOptionsFile(String rootDirectoryPath) {
+  /**
+   * Return the analysis options file that should be used when analyzing code in
+   * the directory with the given [path].
+   */
+  File getOptionsFile(String path) {
     if (defaultAnalysisOptionsFilePath != null) {
       return resourceProvider.getFile(defaultAnalysisOptionsFilePath);
     }
-    Folder root = resourceProvider.getFolder(rootDirectoryPath);
+    Folder root = resourceProvider.getFolder(path);
     for (Folder folder = root; folder != null; folder = folder.parent) {
       File file =
           folder.getChildAssumingFile(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
@@ -263,3 +350,98 @@
     return null;
   }
 }
+
+/**
+ * Given a package map, 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 {
+  /**
+   * The name of the embedder files being searched for.
+   */
+  static const String EMBEDDER_FILE_NAME = '_embedder.yaml';
+
+  /**
+   * A mapping from a package's library directory to the parsed YamlMap.
+   */
+  final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>();
+
+  /**
+   * Initialize a newly created locator by processing the packages in the given
+   * [packageMap].
+   */
+  EmbedderYamlLocator(Map<String, List<Folder>> packageMap) {
+    if (packageMap != null) {
+      _processPackageMap(packageMap);
+    }
+  }
+
+  /**
+   * Programatically add an `_embedder.yaml` mapping.
+   */
+  void addEmbedderYaml(Folder libDir, String embedderYaml) {
+    _processEmbedderYaml(libDir, embedderYaml);
+  }
+
+  /**
+   * Refresh the map of located files to those found by processing the given
+   * [packageMap].
+   */
+  void refresh(Map<String, List<Folder>> packageMap) {
+    // Clear existing.
+    embedderYamls.clear();
+    if (packageMap != null) {
+      _processPackageMap(packageMap);
+    }
+  }
+
+  /**
+   * Given the yaml for an embedder ([embedderYaml]) and a folder ([libDir]),
+   * setup the uri mapping.
+   */
+  void _processEmbedderYaml(Folder libDir, String embedderYaml) {
+    try {
+      YamlNode yaml = loadYaml(embedderYaml);
+      if (yaml is YamlMap) {
+        embedderYamls[libDir] = yaml;
+      }
+    } catch (_) {
+      // Ignored
+    }
+  }
+
+  /**
+   * Given a package [name] and a list of folders ([libDirs]), process any
+   * `_embedder.yaml` files that are found in any of the folders.
+   */
+  void _processPackage(String name, List<Folder> libDirs) {
+    for (Folder libDir in libDirs) {
+      String embedderYaml = _readEmbedderYaml(libDir);
+      if (embedderYaml != null) {
+        _processEmbedderYaml(libDir, embedderYaml);
+      }
+    }
+  }
+
+  /**
+   * Process each of the entries in the [packageMap].
+   */
+  void _processPackageMap(Map<String, List<Folder>> packageMap) {
+    packageMap.forEach(_processPackage);
+  }
+
+  /**
+   * Read and return the contents of [libDir]/[EMBEDDER_FILE_NAME], or `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;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 1f0f42c..7b956a9 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/dart/element/element.dart'
-    show ElementImpl, Modifier;
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -17,6 +16,11 @@
 import 'package:analyzer/task/model.dart';
 
 /**
+ * The cache results visiting function type.
+ */
+typedef void CacheResultVisitor(AnalysisTarget target, ResultData data);
+
+/**
  * Return `true` if the [result] of the [target] should be flushed.
  */
 typedef bool FlushResultFilter<V>(
@@ -296,9 +300,9 @@
   static int _EXPLICITLY_ADDED_FLAG = 0;
 
   /**
-   * The next invalidation process identifier.
+   * The next visit process identifier.
    */
-  static int nextInvalidateId = 0;
+  static int nextVisitId = 0;
 
   /**
    * A table containing the number of times the value of a result descriptor was
@@ -340,9 +344,7 @@
   Map<ResultDescriptor, ResultData> _resultMap =
       new HashMap<ResultDescriptor, ResultData>();
 
-  CacheEntry(this.target) {
-    _markAsCacheKey(target);
-  }
+  CacheEntry(this.target);
 
   /**
    * The exception that caused one or more values to have a state of
@@ -391,10 +393,6 @@
       }
     });
     _resultMap.clear();
-    AnalysisTarget oldTarget = target;
-    if (oldTarget is ElementImpl) {
-      oldTarget.setModifier(Modifier.CACHE_KEY, false);
-    }
   }
 
   /**
@@ -526,7 +524,12 @@
     if (state == CacheState.INVALID) {
       ResultData data = _resultMap[descriptor];
       if (data != null) {
-        _invalidate(nextInvalidateId++, descriptor, delta, 0);
+        bool canUseDelta =
+            _gatherResultsInvalidatedByDelta(descriptor, delta, 0);
+        if (!canUseDelta) {
+          delta = null;
+        }
+        _invalidate(nextVisitId++, descriptor, delta, 0);
       }
     } else {
       ResultData data = getResultData(descriptor);
@@ -554,7 +557,7 @@
 //      }
 //      valueStr = valueStr.replaceAll('\n', '\\n');
 //      print(
-//          'setValue $descriptor for $target value=$valueStr $dependedOn=$dependedOn');
+//          'setValue $descriptor for $target value=$valueStr dependedOn=$dependedOn');
 //    }
     _validateStateChange(descriptor, CacheState.VALID);
     TargetedResult thisResult = new TargetedResult(target, descriptor);
@@ -583,7 +586,7 @@
       data.value = value;
     }
     if (invalidateDependent) {
-      _invalidateDependentResults(nextInvalidateId++, data, null, 0);
+      _invalidateDependentResults(nextVisitId++, data, null, 0);
     }
   }
 
@@ -595,6 +598,35 @@
   }
 
   /**
+   * Visit the given [result] and all results that depend on it, and
+   * ask [delta] to gather changes. Return `true` if the [delta] can be used
+   * to perform limited invalidation, or `false` if the changes collection
+   * process does not stop (should not happen).
+   */
+  bool _gatherResultsInvalidatedByDelta(
+      ResultDescriptor result, Delta delta, int level) {
+    if (delta == null) {
+      return false;
+    }
+    for (int i = 0; i < 64; i++) {
+      bool hasVisitChanges = false;
+      _visitResults(nextVisitId++, result,
+          (AnalysisTarget target, ResultData data) {
+        bool hasDeltaChanges = delta.gatherChanges(
+            _partition.context, target, data.descriptor, data.value);
+        if (hasDeltaChanges) {
+          hasVisitChanges = true;
+        }
+      });
+      delta.gatherEnd();
+      if (!hasVisitChanges) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
    * Return the value of the flag with the given [index].
    */
   bool _getFlag(int index) => BooleanArray.get(_flags, index);
@@ -611,10 +643,10 @@
     }
     // Stop if already validated.
     if (delta != null) {
-      if (thisData.invalidateId == id) {
+      if (thisData.visitId == id) {
         return;
       }
-      thisData.invalidateId = id;
+      thisData.visitId = id;
     }
     // Ask the delta to validate.
     DeltaResult deltaResult = null;
@@ -625,7 +657,7 @@
         return;
       }
     }
-//    if (deltaResult != null && deltaResult != DeltaResult.KEEP_CONTINUE) {
+//    if (deltaResult != null) {
 //      String indent = '  ' * level;
 //      String deltaResultName = deltaResult.toString().split('.').last;
 //      print('[$id]$indent$deltaResultName $descriptor for $target');
@@ -633,36 +665,39 @@
     if (deltaResult == DeltaResult.INVALIDATE_NO_DELTA) {
       delta = null;
     }
-    if (deltaResult == null ||
+    if (deltaResult == DeltaResult.INVALIDATE_KEEP_DEPENDENCIES) {
+      thisData.value = descriptor.defaultValue;
+      thisData.state = CacheState.INVALID;
+    } else if (deltaResult == null ||
         deltaResult == DeltaResult.INVALIDATE ||
         deltaResult == DeltaResult.INVALIDATE_NO_DELTA) {
       _resultMap.remove(descriptor);
-//      {
-//        String indent = '  ' * level;
-//        print('[$id]$indent invalidate $descriptor for $target');
-//      }
-    }
-    // Stop depending on other results.
-    if (deltaResult != DeltaResult.KEEP_CONTINUE) {
-      TargetedResult thisResult = new TargetedResult(target, descriptor);
-      List<AnalysisCache> caches = _partition.containingCaches;
-      int cacheLength = caches.length;
-      List<TargetedResult> results = thisData.dependedOnResults;
-      int resultLength = results.length;
-      for (int i = 0; i < resultLength; i++) {
-        TargetedResult dependedOnResult = results[i];
-        for (int j = 0; j < cacheLength; j++) {
-          AnalysisCache cache = caches[j];
-          CacheEntry entry = cache.get(dependedOnResult.target);
-          if (entry != null) {
-            ResultData data =
-                entry.getResultDataOrNull(dependedOnResult.result);
-            if (data != null) {
-              data.dependentResults.remove(thisResult);
+      // Stop depending on other results.
+      {
+        TargetedResult thisResult = new TargetedResult(target, descriptor);
+        List<AnalysisCache> caches = _partition.containingCaches;
+        int cacheLength = caches.length;
+        List<TargetedResult> results = thisData.dependedOnResults;
+        int resultLength = results.length;
+        for (int i = 0; i < resultLength; i++) {
+          TargetedResult dependedOnResult = results[i];
+          for (int j = 0; j < cacheLength; j++) {
+            AnalysisCache cache = caches[j];
+            CacheEntry entry = cache.get(dependedOnResult.target);
+            if (entry != null) {
+              ResultData data =
+                  entry.getResultDataOrNull(dependedOnResult.result);
+              if (data != null) {
+                data.dependentResults.remove(thisResult);
+              }
             }
           }
         }
       }
+//      if (deltaResult == null) {
+//        String indent = '  ' * level;
+//        print('[$id]$indent invalidate $descriptor for $target');
+//      }
     }
     // Invalidate results that depend on this result.
     _invalidateDependentResults(id, thisData, delta, level + 1);
@@ -675,8 +710,10 @@
       _partition._removeIfSource(target);
     }
     // Notify controller.
-    _partition.onResultInvalidated
-        .add(new InvalidatedResult(this, descriptor, thisData.value));
+    if (deltaResult != DeltaResult.KEEP_CONTINUE) {
+      _partition.onResultInvalidated
+          .add(new InvalidatedResult(this, descriptor, thisData.value));
+    }
   }
 
   /**
@@ -687,7 +724,7 @@
     int length = results.length;
     for (int i = 0; i < length; i++) {
       ResultDescriptor result = results[i];
-      _invalidate(nextInvalidateId++, result, null, 0);
+      _invalidate(nextVisitId++, result, null, 0);
     }
   }
 
@@ -715,15 +752,6 @@
   }
 
   /**
-   * If the given `target` is an element, mark it as being a cache key.
-   */
-  void _markAsCacheKey(AnalysisTarget target) {
-    if (target is ElementImpl) {
-      target.setModifier(Modifier.CACHE_KEY, true);
-    }
-  }
-
-  /**
    * Set the [dependedOn] on which this result depends.
    */
   void _setDependedOnResults(ResultData thisData, TargetedResult thisResult,
@@ -754,10 +782,8 @@
         AnalysisCache cache = caches[j];
         CacheEntry entry = cache.get(dependedOnResult.target);
         if (entry != null) {
-          ResultData data = entry.getResultDataOrNull(dependedOnResult.result);
-          if (data != null) {
-            data.dependentResults.add(thisResult);
-          }
+          ResultData data = entry.getResultData(dependedOnResult.result);
+          data.dependentResults.add(thisResult);
         }
       }
     }
@@ -818,6 +844,41 @@
   }
 
   /**
+   * Call [visitor] for the result described by the given [descriptor] and all
+   * results that depend on directly or indirectly. Each result is visited
+   * only once.
+   */
+  void _visitResults(
+      int id, ResultDescriptor descriptor, CacheResultVisitor visitor) {
+    ResultData thisData = _resultMap[descriptor];
+    if (thisData == null) {
+      return;
+    }
+    // Stop if already visited.
+    if (thisData.visitId == id) {
+      return;
+    }
+    thisData.visitId = id;
+    // Visit this result.
+    visitor(target, thisData);
+    // Visit results that depend on this result.
+    List<AnalysisCache> caches = _partition.containingCaches;
+    int cacheLength = caches.length;
+    List<TargetedResult> dependentResults = thisData.dependentResults.toList();
+    int resultLength = dependentResults.length;
+    for (int i = 0; i < resultLength; i++) {
+      TargetedResult dependentResult = dependentResults[i];
+      for (int j = 0; j < cacheLength; j++) {
+        AnalysisCache cache = caches[j];
+        CacheEntry entry = cache.get(dependentResult.target);
+        if (entry != null) {
+          entry._visitResults(id, dependentResult.result, visitor);
+        }
+      }
+    }
+  }
+
+  /**
    * Write a textual representation of this entry to the given [buffer]. The
    * result should only be used for debugging purposes.
    */
@@ -1185,6 +1246,16 @@
 
   Delta(this.source);
 
+  bool gatherChanges(InternalAnalysisContext context, AnalysisTarget target,
+      ResultDescriptor descriptor, Object value) {
+    return false;
+  }
+
+  /**
+   * The current cache results visit is done.
+   */
+  void gatherEnd() {}
+
   /**
    * Check whether this delta affects the result described by the given
    * [descriptor] and [target]. The current [value] of the result is provided.
@@ -1201,11 +1272,17 @@
 enum DeltaResult {
   /**
    * Invalidate this result and continue visiting dependent results
-   * with this [Delta].
+   * with this [Delta]. Remove the result and all its dependencies.
    */
   INVALIDATE,
 
   /**
+   * Invalidate this result and continue visiting dependent results
+   * with this [Delta]. Keep the dependencies of this result.
+   */
+  INVALIDATE_KEEP_DEPENDENCIES,
+
+  /**
    * Invalidate this result and stop using this [Delta], so unconditionally
    * invalidate all the dependent results.
    */
@@ -1250,6 +1327,29 @@
 }
 
 /**
+ * A cache partition that contains all of the targets in a single package.
+ */
+class PackageCachePartition extends CachePartition {
+  /**
+   * The root of the directory representing the package.
+   */
+  final Folder packageRoot;
+
+  /**
+   * Initialize a newly created cache partition, belonging to the given
+   * [context].
+   */
+  PackageCachePartition(InternalAnalysisContext context, this.packageRoot)
+      : super(context);
+
+  @override
+  bool isResponsibleFor(AnalysisTarget target) {
+    Source source = target.source;
+    return source != null && packageRoot.contains(source.fullName);
+  }
+}
+
+/**
  * A Stream-like interface, which broadcasts events synchronously.
  * If a second event is fired while delivering a first event, then the second
  * event will be delivered first, and then delivering of the first will be
@@ -1320,11 +1420,10 @@
   Object value;
 
   /**
-   * The identifier of the invalidation process that most recently checked
-   * this value. If it is the same as the current invalidation identifier,
-   * then there is no reason to check it (and its subtree again).
+   * The identifier of the most recent visiting process. We use it to visit
+   * every result only once.
    */
-  int invalidateId = -1;
+  int visitId = -1;
 
   /**
    * A list of the results on which this result depends.
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 27098db..6d861b5 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -13,8 +13,8 @@
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.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/builder.dart' show EmbedderYamlLocator;
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -34,6 +34,7 @@
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/incremental_element_builder.dart';
 import 'package:analyzer/src/task/manager.dart';
+import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/html.dart';
@@ -41,6 +42,13 @@
 import 'package:html/dom.dart' show Document;
 
 /**
+ * The descriptor used to associate exclude patterns with an analysis context in
+ * configuration data.
+ */
+final ListResultDescriptor<String> CONTEXT_EXCLUDES =
+    new ListResultDescriptorImpl('CONTEXT_EXCLUDES', const <String>[]);
+
+/**
  * Type of callback functions used by PendingFuture. Functions of this type
  * should perform a computation based on the data in [entry] and return it. If
  * the computation can't be performed yet because more analysis is needed,
@@ -158,6 +166,8 @@
    */
   List<Source> _priorityOrder = <Source>[];
 
+  CacheConsistencyValidatorImpl _cacheConsistencyValidator;
+
   /**
    * A map from all sources for which there are futures pending to a list of
    * the corresponding PendingFuture objects.  These sources will be analyzed
@@ -282,14 +292,16 @@
             ? this._options.implicitCasts != options.implicitCasts
             : false) ||
         ((options is AnalysisOptionsImpl)
+            ? this._options.nonnullableTypes != options.nonnullableTypes
+            : false) ||
+        ((options is AnalysisOptionsImpl)
             ? this._options.implicitDynamic != options.implicitDynamic
             : false) ||
         this._options.enableStrictCallChecks !=
             options.enableStrictCallChecks ||
         this._options.enableGenericMethods != options.enableGenericMethods ||
         this._options.enableAsync != options.enableAsync ||
-        this._options.enableSuperMixins != options.enableSuperMixins ||
-        this._options.enableTrailingCommas != options.enableTrailingCommas;
+        this._options.enableSuperMixins != options.enableSuperMixins;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
       this._options.cacheSize = cacheSize;
@@ -305,7 +317,6 @@
     this._options.enableAsync = options.enableAsync;
     this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.enableTiming = options.enableTiming;
-    this._options.enableTrailingCommas = options.enableTrailingCommas;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
     this._options.incrementalApi = options.incrementalApi;
@@ -318,6 +329,7 @@
     if (options is AnalysisOptionsImpl) {
       this._options.strongModeHints = options.strongModeHints;
       this._options.implicitCasts = options.implicitCasts;
+      this._options.nonnullableTypes = options.nonnullableTypes;
       this._options.implicitDynamic = options.implicitDynamic;
     }
     if (needsRecompute) {
@@ -347,6 +359,9 @@
     driver.reset();
   }
 
+  CacheConsistencyValidator get cacheConsistencyValidator =>
+      _cacheConsistencyValidator ??= new CacheConsistencyValidatorImpl(this);
+
   @override
   set contentCache(ContentCache value) {
     _contentCache = value;
@@ -1236,6 +1251,7 @@
       setValue(ResultDescriptor result, value) {
         entry.setValue(result, value, TargetedResult.EMPTY_LIST);
       }
+
       setValue(BUILD_DIRECTIVES_ERRORS, AnalysisError.NO_ERRORS);
       setValue(BUILD_LIBRARY_ERRORS, AnalysisError.NO_ERRORS);
       // CLASS_ELEMENTS
@@ -1375,57 +1391,6 @@
   }
 
   @override
-  bool validateCacheConsistency() {
-    int consistencyCheckStart = JavaSystem.nanoTime();
-    HashSet<Source> changedSources = new HashSet<Source>();
-    HashSet<Source> missingSources = new HashSet<Source>();
-    for (Source source in _cache.sources) {
-      CacheEntry entry = _cache.get(source);
-      int sourceTime = getModificationStamp(source);
-      if (sourceTime != entry.modificationTime) {
-        changedSources.add(source);
-      }
-      if (entry.exception != null) {
-        if (!exists(source)) {
-          missingSources.add(source);
-        }
-      }
-    }
-    for (Source source in changedSources) {
-      _sourceChanged(source);
-    }
-    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;
-  }
-
-  @override
   void visitContentCache(ContentCacheVisitor visitor) {
     _contentCache.accept(visitor);
   }
@@ -1803,6 +1768,7 @@
       }
       return false;
     }
+
     return _refHtml(librarySource);
   }
 
@@ -1871,21 +1837,25 @@
     // (For example, in getLibrariesContaining.)
     entry.setState(CONTENT, CacheState.FLUSHED);
 
-    if (oldContents != null) {
-      // Fast path if the content is the same as it was last time.
-      try {
-        TimestampedData<String> fileContents = getContents(source);
-        if (fileContents.data == oldContents) {
-          int time = fileContents.modificationTime;
-          for (CacheEntry entry in _entriesFor(source)) {
-            entry.modificationTime = time;
-          }
-          return;
-        }
-      } catch (e) {
-        entry.modificationTime = -1;
+    // Prepare the new contents.
+    TimestampedData<String> fileContents;
+    try {
+      fileContents = getContents(source);
+    } catch (e) {}
+
+    // Update 'modificationTime' - we are going to update the entry.
+    {
+      int time = fileContents?.modificationTime ?? -1;
+      for (CacheEntry entry in _entriesFor(source)) {
+        entry.modificationTime = time;
       }
     }
+
+    // Fast path if the contents is the same as it was last time.
+    if (oldContents != null && fileContents?.data == oldContents) {
+      return;
+    }
+
     // We need to invalidate the cache.
     {
       if (analysisOptions.finerGrainedInvalidation &&
@@ -1893,9 +1863,10 @@
         // TODO(scheglov) Incorrect implementation in general.
         entry.setState(TOKEN_STREAM, CacheState.FLUSHED);
         entry.setState(PARSED_UNIT, CacheState.FLUSHED);
-        List<Source> librarySources = getLibrariesContaining(source);
-        if (librarySources.length == 1) {
-          Source librarySource = librarySources[0];
+        SourceKind sourceKind = getKindOf(source);
+        List<Source> partSources = getResult(source, INCLUDED_PARTS);
+        if (sourceKind == SourceKind.LIBRARY && partSources.isEmpty) {
+          Source librarySource = source;
           // Try to find an old unit which has element model.
           CacheEntry unitEntry =
               getCacheEntry(new LibrarySpecificUnit(librarySource, source));
@@ -1910,18 +1881,12 @@
             builder.build();
             CompilationUnitElementDelta unitDelta = builder.unitDelta;
             if (!unitDelta.hasDirectiveChange) {
+              unitEntry.setValueIncremental(
+                  COMPILATION_UNIT_CONSTANTS, builder.unitConstants, false);
               DartDelta dartDelta = new DartDelta(source);
-              dartDelta.hasDirectiveChange = unitDelta.hasDirectiveChange;
               unitDelta.addedDeclarations.forEach(dartDelta.elementChanged);
               unitDelta.removedDeclarations.forEach(dartDelta.elementChanged);
               unitDelta.classDeltas.values.forEach(dartDelta.classChanged);
-              // Add other names in the library that are changed transitively.
-              {
-                ReferencedNames referencedNames = new ReferencedNames(source);
-                new ReferencedNamesBuilder(referencedNames).build(oldUnit);
-                dartDelta.addChangedElements(referencedNames);
-              }
-              // Invalidate using the prepared DartDelta.
               entry.setState(CONTENT, CacheState.INVALID, delta: dartDelta);
               return;
             }
@@ -2046,6 +2011,7 @@
       // schedule
       dartWorkManager.unitIncrementallyResolved(librarySource, unitSource);
       // OK
+      driver.reset();
       return true;
     });
   }
@@ -2097,6 +2063,73 @@
   }
 }
 
+class CacheConsistencyValidatorImpl implements CacheConsistencyValidator {
+  final AnalysisContextImpl context;
+
+  CacheConsistencyValidatorImpl(this.context);
+
+  @override
+  List<Source> getSourcesToComputeModificationTimes() {
+    return context._privatePartition.sources.toList();
+  }
+
+  @override
+  bool sourceModificationTimesComputed(List<Source> sources, List<int> times) {
+    Stopwatch timer = new Stopwatch()..start();
+    HashSet<Source> changedSources = new HashSet<Source>();
+    HashSet<Source> removedSources = new HashSet<Source>();
+    for (int i = 0; i < sources.length; i++) {
+      Source source = sources[i];
+      // When a source is in the content cache,
+      // its modification time in the file system does not matter.
+      if (context._contentCache.getModificationStamp(source) != null) {
+        continue;
+      }
+      // When we were not able to compute the modification time in the
+      // file system, there is nothing to compare with, so skip the source.
+      int sourceTime = times[i];
+      if (sourceTime == null) {
+        continue;
+      }
+      // Compare with the modification time in the cache entry.
+      CacheEntry entry = context._privatePartition.get(source);
+      if (entry != null) {
+        if (entry.modificationTime != sourceTime) {
+          if (sourceTime == -1) {
+            removedSources.add(source);
+            PerformanceStatistics
+                .cacheConsistencyValidationStatistics.numOfRemoved++;
+          } else {
+            changedSources.add(source);
+            PerformanceStatistics
+                .cacheConsistencyValidationStatistics.numOfChanged++;
+          }
+        }
+      }
+    }
+    for (Source source in changedSources) {
+      context._sourceChanged(source);
+    }
+    for (Source source in removedSources) {
+      context._sourceRemoved(source);
+    }
+    if (changedSources.length > 0 || removedSources.length > 0) {
+      StringBuffer buffer = new StringBuffer();
+      buffer.write("Consistency check took ");
+      buffer.write(timer.elapsedMilliseconds);
+      buffer.writeln(" ms and found");
+      buffer.write("  ");
+      buffer.write(changedSources.length);
+      buffer.writeln(" changed sources");
+      buffer.write("  ");
+      buffer.write(removedSources.length);
+      buffer.write(" removed sources.");
+      context._logInformation(buffer.toString());
+    }
+    return changedSources.isNotEmpty || removedSources.isNotEmpty;
+  }
+}
+
 /**
  * An object that manages the partitions that can be shared between analysis
  * contexts.
diff --git a/pkg/analyzer/lib/src/context/context_factory.dart b/pkg/analyzer/lib/src/context/context_factory.dart
deleted file mode 100644
index b96100d..0000000
--- a/pkg/analyzer/lib/src/context/context_factory.dart
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer.src.context_factory;
-
-import 'dart:convert';
-import 'dart:core' hide Resource;
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:yaml/yaml.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'dart:io' as io;
-
-/// (Placeholder)
-abstract class ContextFactory {
-  /// Create an analysis context for the given [source] directory or file, with
-  /// the given [defaultOptions].
-  AnalysisContext createContext(
-      io.FileSystemEntity source, AnalysisOptions defaultOptions);
-}
-
-/// Processes package maps, extracting SDK embedders and extenders, creating a
-/// consolidated [libraryMap].
-class PackageMapProcessor {
-  static const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
-  static const String _EMBEDDER_FILE_NAME = '_embedder.yaml';
-  static const String _SDK_EXT_NAME = '_sdkext';
-
-  /// Map of processed embedder libraries.
-  final LibraryMap embeddedLibraries = new LibraryMap();
-
-  /// Map of processed SDK extension libraries.
-  final LibraryMap extendedLibraries = new LibraryMap();
-
-  /// Combined map of processed libraries.
-  LibraryMap get libraryMap {
-    LibraryMap libraryMap = new LibraryMap();
-
-    // Add extenders first, allowing for overwrite by embedders who take precedence.
-    for (String uri in extendedLibraries.uris) {
-      libraryMap.setLibrary(uri, extendedLibraries.getLibrary(uri));
-    }
-    for (String uri in embeddedLibraries.uris) {
-      libraryMap.setLibrary(uri, embeddedLibraries.getLibrary(uri));
-    }
-    return libraryMap;
-  }
-
-  /// Create a processor for the given [packageMap].
-  PackageMapProcessor(Map<String, List<Folder>> packageMap) {
-    packageMap?.forEach(_processPackage);
-  }
-
-  /// Whether the package map contains an SDK embedder.
-  bool get hasEmbedder => embeddedLibraries.size() > 0;
-
-  /// Whether the package map contains an SDK extension.
-  bool get hasSdkExtension => extendedLibraries.size() > 0;
-
-  void _processEmbedderYaml(String embedderYaml, Folder libDir) {
-    try {
-      YamlNode map = loadYaml(embedderYaml);
-      if (map is YamlMap) {
-        YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
-        if (embedded_libs is YamlMap) {
-          embedded_libs.forEach(
-              (k, v) => _processMapping(embeddedLibraries, k, v, libDir));
-        }
-      }
-    } catch (_) {
-      // Ignored.
-    }
-  }
-
-  void _processMapping(
-      LibraryMap libraryMap, String name, String file, Folder libDir) {
-    if (!_hasDartPrefix(name)) {
-      // SDK libraries must begin with 'dart:'.
-      return;
-    }
-    if (libraryMap.getLibrary(name) != null) {
-      // Libraries can't be redefined.
-      return;
-    }
-    String libPath = libDir.canonicalizePath(file);
-    SdkLibraryImpl library = new SdkLibraryImpl(name)..path = libPath;
-    libraryMap.setLibrary(name, library);
-  }
-
-  void _processPackage(String name, List<Folder> libDirs) {
-    for (Folder libDir in libDirs) {
-      String embedderYaml = _readEmbedderYaml(libDir);
-      if (embedderYaml != null) {
-        _processEmbedderYaml(embedderYaml, libDir);
-      }
-      String sdkExt = _readDotSdkExt(libDir);
-      if (sdkExt != null) {
-        _processSdkExt(sdkExt, libDir);
-      }
-    }
-  }
-
-  void _processSdkExt(String sdkExtJSON, Folder libDir) {
-    try {
-      var sdkExt = JSON.decode(sdkExtJSON);
-      if (sdkExt is Map) {
-        sdkExt.forEach(
-            (k, v) => _processMapping(extendedLibraries, k, v, libDir));
-      }
-    } catch (_) {
-      // Ignored.
-    }
-  }
-
-  static bool _hasDartPrefix(String uri) =>
-      uri.startsWith(DartSdk.DART_LIBRARY_PREFIX);
-
-  static String _readDotSdkExt(Folder libDir) =>
-      _safeRead(libDir.getChild(_SDK_EXT_NAME));
-
-  static String _readEmbedderYaml(Folder libDir) =>
-      _safeRead(libDir.getChild(_EMBEDDER_FILE_NAME));
-
-  static String _safeRead(Resource file) {
-    try {
-      if (file is File) {
-        return file.readAsStringSync();
-      }
-    } on FileSystemException {
-      // File can't be read.
-    }
-    return null;
-  }
-}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 97defa6..6be013c 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -398,7 +398,7 @@
   @override
   void set correspondingPropagatedParameters(
       List<ParameterElement> parameters) {
-    if (parameters.length != _arguments.length) {
+    if (parameters != null && parameters.length != _arguments.length) {
       throw new IllegalArgumentException(
           "Expected ${_arguments.length} parameters, not ${parameters.length}");
     }
@@ -410,7 +410,7 @@
 
   @override
   void set correspondingStaticParameters(List<ParameterElement> parameters) {
-    if (parameters.length != _arguments.length) {
+    if (parameters != null && parameters.length != _arguments.length) {
       throw new IllegalArgumentException(
           "Expected ${_arguments.length} parameters, not ${parameters.length}");
     }
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 53f9109..59a51e9 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -72,7 +72,7 @@
    * [nodes].
    */
   List<AstNode/*=E*/ > cloneNodeList/*<E extends AstNode>*/(
-      NodeList/*<E>*/ nodes) {
+      List/*<E>*/ nodes) {
     int count = nodes.length;
     List/*<E>*/ clonedNodes = new List/*<E>*/();
     for (int i = 0; i < count; i++) {
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 0c8288a..8c48f49 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -23,7 +23,6 @@
 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/source.dart' show Source;
 import 'package:analyzer/src/generated/type_system.dart'
     show TypeSystem, TypeSystemImpl;
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -76,6 +75,9 @@
    */
   final ConstantEvaluationValidator validator;
 
+  /** Whether we are running in strong mode. */
+  final bool strongMode;
+
   /**
    * Initialize a newly created [ConstantEvaluationEngine].  The [typeProvider]
    * is used to access known types.  [_declaredVariables] is the set of
@@ -83,9 +85,12 @@
    * given, is used to verify correct dependency analysis when running unit
    * tests.
    */
-  ConstantEvaluationEngine(this.typeProvider, this._declaredVariables,
+  ConstantEvaluationEngine(TypeProvider typeProvider, this._declaredVariables,
       {ConstantEvaluationValidator validator, TypeSystem typeSystem})
-      : validator =
+      : typeProvider = typeProvider,
+        strongMode =
+            typeProvider.objectType.element.context.analysisOptions.strongMode,
+        validator =
             validator ?? new ConstantEvaluationValidator_ForProduction(),
         typeSystem = typeSystem ?? new TypeSystemImpl();
 
@@ -410,7 +415,7 @@
 
   DartObjectImpl evaluateConstructorCall(
       AstNode node,
-      NodeList<Expression> arguments,
+      List<Expression> arguments,
       ConstructorElement constructor,
       ConstantVisitor constantVisitor,
       ErrorReporter errorReporter) {
@@ -516,25 +521,49 @@
       // so consider it an unknown value to suppress further errors.
       return new DartObjectImpl.validWithUnknownValue(definingClass);
     }
-    HashMap<String, DartObjectImpl> fieldMap =
-        new HashMap<String, DartObjectImpl>();
+
+    // In strong mode, we allow constants to have type arguments.
+    //
+    // They will be added to the lexical environment when evaluating
+    // subexpressions.
+    HashMap<String, DartObjectImpl> typeArgumentMap;
+    if (strongMode) {
+      // Instantiate the constructor with the in-scope type arguments.
+      definingClass = constantVisitor.evaluateType(definingClass);
+      constructor = ConstructorMember.from(constructorBase, definingClass);
+
+      typeArgumentMap = new HashMap<String, DartObjectImpl>.fromIterables(
+          definingClass.typeParameters.map((t) => t.name),
+          definingClass.typeArguments.map(constantVisitor.typeConstant));
+    }
+
+    var fieldMap = new HashMap<String, DartObjectImpl>();
+    var fieldInitVisitor = new ConstantVisitor(this, errorReporter,
+        lexicalEnvironment: typeArgumentMap);
     // Start with final fields that are initialized at their declaration site.
-    for (FieldElement field in constructor.enclosingElement.fields) {
+    List<FieldElement> fields = constructor.enclosingElement.fields;
+    for (int i = 0; i < fields.length; i++) {
+      FieldElement field = fields[i];
       if ((field.isFinal || field.isConst) &&
           !field.isStatic &&
           field is ConstFieldElementImpl) {
         validator.beforeGetFieldEvaluationResult(field);
-        EvaluationResultImpl evaluationResult = field.evaluationResult;
+
+        DartObjectImpl fieldValue;
+        if (strongMode) {
+          fieldValue = field.constantInitializer.accept(fieldInitVisitor);
+        } else {
+          fieldValue = field.evaluationResult?.value;
+        }
         // 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) {
+        if (fieldValue == 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
@@ -550,6 +579,7 @@
         new HashMap<String, DartObjectImpl>();
     List<ParameterElement> parameters = constructor.parameters;
     int parameterCount = parameters.length;
+
     for (int i = 0; i < parameterCount; i++) {
       ParameterElement parameter = parameters[i];
       ParameterElement baseParameter = parameter;
@@ -575,12 +605,23 @@
         // The parameter is an optional positional parameter for which no value
         // was provided, so use the default value.
         validator.beforeGetParameterDefault(baseParameter);
-        EvaluationResultImpl evaluationResult = baseParameter.evaluationResult;
-        if (evaluationResult == null) {
-          // No default was provided, so the default value is null.
-          argumentValue = typeProvider.nullObject;
-        } else if (evaluationResult.value != null) {
-          argumentValue = evaluationResult.value;
+        if (strongMode && baseParameter is ConstVariableElement) {
+          var defaultValue =
+              (baseParameter as ConstVariableElement).constantInitializer;
+          if (defaultValue == null) {
+            argumentValue = typeProvider.nullObject;
+          } else {
+            argumentValue = defaultValue.accept(fieldInitVisitor);
+          }
+        } else {
+          EvaluationResultImpl evaluationResult =
+              baseParameter.evaluationResult;
+          if (evaluationResult == null) {
+            // No default was provided, so the default value is null.
+            argumentValue = typeProvider.nullObject;
+          } else if (evaluationResult.value != null) {
+            argumentValue = evaluationResult.value;
+          }
         }
       }
       if (argumentValue != null) {
@@ -678,6 +719,7 @@
         if (superArguments == null) {
           superArguments = new NodeList<Expression>(null);
         }
+
         evaluateSuperConstructorCall(node, fieldMap, superConstructor,
             superArguments, initializerVisitor, errorReporter);
       }
@@ -689,7 +731,7 @@
       AstNode node,
       HashMap<String, DartObjectImpl> fieldMap,
       ConstructorElement superConstructor,
-      NodeList<Expression> superArguments,
+      List<Expression> superArguments,
       ConstantVisitor initializerVisitor,
       ErrorReporter errorReporter) {
     if (superConstructor != null && superConstructor.isConst) {
@@ -930,15 +972,13 @@
    */
   final ConstantEvaluationEngine evaluationEngine;
 
-  final AnalysisContext _context;
-
   /**
    * Initialize a newly created constant value computer. The [typeProvider] is
    * the type provider used to access known types. The [declaredVariables] is
    * the set of variables declared on the command line using '-D'.
    */
-  ConstantValueComputer(this._context, TypeProvider typeProvider,
-      DeclaredVariables declaredVariables,
+  ConstantValueComputer(
+      TypeProvider typeProvider, DeclaredVariables declaredVariables,
       [ConstantEvaluationValidator validator, TypeSystem typeSystem])
       : evaluationEngine = new ConstantEvaluationEngine(
             typeProvider, declaredVariables,
@@ -948,9 +988,8 @@
    * Add the constants in the given compilation [unit] to the list of constants
    * whose value needs to be computed.
    */
-  void add(CompilationUnit unit, Source source, Source librarySource) {
-    ConstantFinder constantFinder =
-        new ConstantFinder(_context, source, librarySource);
+  void add(CompilationUnit unit) {
+    ConstantFinder constantFinder = new ConstantFinder();
     unit.accept(constantFinder);
     _constantsToCompute.addAll(constantFinder.constantsToCompute);
   }
@@ -1235,6 +1274,7 @@
       // problem - the error has already been reported.
       return null;
     }
+
     return evaluationEngine.evaluateConstructorCall(
         node, node.argumentList.arguments, constructor, this, _errorReporter);
   }
@@ -1278,9 +1318,9 @@
       return null;
     }
     DartType elementType = _typeProvider.dynamicType;
-    if (node.typeArguments != null &&
-        node.typeArguments.arguments.length == 1) {
-      DartType type = node.typeArguments.arguments[0].type;
+    NodeList<TypeName> typeArgs = node.typeArguments?.arguments;
+    if (typeArgs?.length == 1) {
+      DartType type = visitTypeName(typeArgs[0])?.toTypeValue();
       if (type != null) {
         elementType = type;
       }
@@ -1313,13 +1353,13 @@
     }
     DartType keyType = _typeProvider.dynamicType;
     DartType valueType = _typeProvider.dynamicType;
-    if (node.typeArguments != null &&
-        node.typeArguments.arguments.length == 2) {
-      DartType keyTypeCandidate = node.typeArguments.arguments[0].type;
+    NodeList<TypeName> typeArgs = node.typeArguments?.arguments;
+    if (typeArgs?.length == 2) {
+      DartType keyTypeCandidate = visitTypeName(typeArgs[0])?.toTypeValue();
       if (keyTypeCandidate != null) {
         keyType = keyTypeCandidate;
       }
-      DartType valueTypeCandidate = node.typeArguments.arguments[1].type;
+      DartType valueTypeCandidate = visitTypeName(typeArgs[1])?.toTypeValue();
       if (valueTypeCandidate != null) {
         valueType = valueTypeCandidate;
       }
@@ -1469,6 +1509,57 @@
         _typeProvider.symbolType, new SymbolState(buffer.toString()));
   }
 
+  @override
+  DartObjectImpl visitTypeName(TypeName node) {
+    DartType type = evaluateType(node.type);
+    if (type == null) {
+      return super.visitTypeName(node);
+    }
+    return typeConstant(type);
+  }
+
+  /**
+   * Given a [type], returns the constant value that contains that type value.
+   */
+  DartObjectImpl typeConstant(DartType type) {
+    return new DartObjectImpl(_typeProvider.typeType, new TypeState(type));
+  }
+
+  /**
+   * Given a [type] that may contain free type variables, evaluate them against
+   * the current lexical environment and return the substituted type.
+   */
+  DartType evaluateType(DartType type) {
+    if (type is TypeParameterType) {
+      // Constants may only refer to type parameters in strong mode.
+      if (!evaluationEngine.strongMode) {
+        return null;
+      }
+
+      String name = type.name;
+      if (_lexicalEnvironment != null) {
+        return _lexicalEnvironment[name]?.toTypeValue() ?? type;
+      }
+      return type;
+    }
+    if (type is ParameterizedType) {
+      List<DartType> typeArguments;
+      for (int i = 0; i < type.typeArguments.length; i++) {
+        DartType ta = type.typeArguments[i];
+        DartType t = evaluateType(ta);
+        if (!identical(t, ta)) {
+          if (typeArguments == null) {
+            typeArguments = type.typeArguments.toList(growable: false);
+          }
+          typeArguments[i] = t;
+        }
+      }
+      if (typeArguments == null) return type;
+      return type.substitute2(typeArguments, type.typeArguments);
+    }
+    return type;
+  }
+
   /**
    * Create an error associated with the given [node]. The error will have the
    * given error [code].
@@ -1501,10 +1592,13 @@
         }
         return new DartObjectImpl(functionType, new FunctionState(function));
       }
-    } else if (variableElement is ClassElement ||
-        variableElement is FunctionTypeAliasElement ||
-        variableElement is DynamicElementImpl) {
-      return new DartObjectImpl(_typeProvider.typeType, new TypeState(element));
+    } else if (variableElement is TypeDefiningElement) {
+      // Constants may only refer to type parameters in strong mode.
+      if (evaluationEngine.strongMode ||
+          variableElement is! TypeParameterElement) {
+        return new DartObjectImpl(
+            _typeProvider.typeType, new TypeState(variableElement.type));
+      }
     }
     // TODO(brianwilkerson) Figure out which error to report.
     _error(node, null);
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 62b3ec8..90c8a38 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -14,8 +14,6 @@
 import 'package:analyzer/src/dart/element/handle.dart'
     show ConstructorElementHandle;
 import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart' show Source;
 import 'package:analyzer/src/task/dart.dart';
 
 ConstructorElementImpl getConstructorImpl(ConstructorElement constructor) {
@@ -156,10 +154,6 @@
  * those compilation units.
  */
 class ConstantFinder extends RecursiveAstVisitor<Object> {
-  final AnalysisContext context;
-  final Source source;
-  final Source librarySource;
-
   /**
    * The elements and AST nodes whose constant values need to be computed.
    */
@@ -172,8 +166,6 @@
    */
   bool treatFinalInstanceVarAsConst = false;
 
-  ConstantFinder(this.context, this.source, this.librarySource);
-
   @override
   Object visitAnnotation(Annotation node) {
     super.visitAnnotation(node);
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index a269925..a0d1162 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -720,10 +720,7 @@
   DartType toTypeValue() {
     InstanceState state = _state;
     if (state is TypeState) {
-      Element element = state._element;
-      if (element is TypeDefiningElement) {
-        return element.type;
-      }
+      return state._type;
     }
     return null;
   }
@@ -2771,29 +2768,29 @@
   /**
    * The element representing the type being modeled.
    */
-  final Element _element;
+  final DartType _type;
 
   /**
    * Initialize a newly created state to represent the given [value].
    */
-  TypeState(this._element);
+  TypeState(this._type);
 
   @override
-  int get hashCode => _element == null ? 0 : _element.hashCode;
+  int get hashCode => _type?.hashCode ?? 0;
 
   @override
   String get typeName => "Type";
 
   @override
   bool operator ==(Object object) =>
-      object is TypeState && (_element == object._element);
+      object is TypeState && (_type == object._type);
 
   @override
   StringState convertToString() {
-    if (_element == null) {
+    if (_type == null) {
       return StringState.UNKNOWN_VALUE;
     }
-    return new StringState(_element.name);
+    return new StringState(_type.displayName);
   }
 
   @override
@@ -2804,15 +2801,15 @@
 
   @override
   BoolState isIdentical(InstanceState rightOperand) {
-    if (_element == null) {
+    if (_type == null) {
       return BoolState.UNKNOWN_VALUE;
     }
     if (rightOperand is TypeState) {
-      Element rightElement = rightOperand._element;
-      if (rightElement == null) {
+      DartType rightType = rightOperand._type;
+      if (rightType == null) {
         return BoolState.UNKNOWN_VALUE;
       }
-      return BoolState.from(_element == rightElement);
+      return BoolState.from(_type == rightType);
     } else if (rightOperand is DynamicState) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -2820,5 +2817,5 @@
   }
 
   @override
-  String toString() => _element == null ? "-unknown-" : _element.name;
+  String toString() => _type?.toString() ?? "-unknown-";
 }
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 3b09bef..6f06b5c 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -170,38 +170,37 @@
     node.element = null;
     Source exportedSource = node.source;
     int exportedTime = sourceModificationTimeMap[exportedSource] ?? -1;
-    if (exportedTime != -1) {
-      // The exported source will be null if the URI in the export
-      // directive was invalid.
-      LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
-      if (exportedLibrary != null) {
-        ExportElementImpl exportElement = new ExportElementImpl(node.offset);
-        exportElement.metadata = _getElementAnnotations(node.metadata);
-        StringLiteral uriLiteral = node.uri;
+    // The exported source will be null if the URI in the export
+    // directive was invalid.
+    LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
+    if (exportedLibrary != null) {
+      ExportElementImpl exportElement = new ExportElementImpl(node.offset);
+      exportElement.metadata = _getElementAnnotations(node.metadata);
+      StringLiteral uriLiteral = node.uri;
+      if (uriLiteral != null) {
+        exportElement.uriOffset = uriLiteral.offset;
+        exportElement.uriEnd = uriLiteral.end;
+      }
+      exportElement.uri = node.uriContent;
+      exportElement.combinators = _buildCombinators(node);
+      exportElement.exportedLibrary = exportedLibrary;
+      setElementDocumentationComment(exportElement, node);
+      node.element = exportElement;
+      exports.add(exportElement);
+      if (exportedTime >= 0 &&
+          exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
+        int offset = node.offset;
+        int length = node.length;
         if (uriLiteral != null) {
-          exportElement.uriOffset = uriLiteral.offset;
-          exportElement.uriEnd = uriLiteral.end;
+          offset = uriLiteral.offset;
+          length = uriLiteral.length;
         }
-        exportElement.uri = node.uriContent;
-        exportElement.combinators = _buildCombinators(node);
-        exportElement.exportedLibrary = exportedLibrary;
-        setElementDocumentationComment(exportElement, node);
-        node.element = exportElement;
-        exports.add(exportElement);
-        if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
-          int offset = node.offset;
-          int length = node.length;
-          if (uriLiteral != null) {
-            offset = uriLiteral.offset;
-            length = uriLiteral.length;
-          }
-          errors.add(new AnalysisError(
-              libraryElement.source,
-              offset,
-              length,
-              CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-              [uriLiteral.toSource()]));
-        }
+        errors.add(new AnalysisError(
+            libraryElement.source,
+            offset,
+            length,
+            CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+            [uriLiteral.toSource()]));
       }
     }
     return null;
@@ -213,53 +212,52 @@
     node.element = null;
     Source importedSource = node.source;
     int importedTime = sourceModificationTimeMap[importedSource] ?? -1;
-    if (importedTime != -1) {
-      // The imported source will be null if the URI in the import
-      // directive was invalid.
-      LibraryElement importedLibrary = importLibraryMap[importedSource];
-      if (importedLibrary != null) {
-        if (importedLibrary.isDartCore) {
-          explicitlyImportsCore = true;
+    // The imported source will be null if the URI in the import
+    // directive was invalid.
+    LibraryElement importedLibrary = importLibraryMap[importedSource];
+    if (importedLibrary != null) {
+      if (importedLibrary.isDartCore) {
+        explicitlyImportsCore = true;
+      }
+      ImportElementImpl importElement = new ImportElementImpl(node.offset);
+      importElement.metadata = _getElementAnnotations(node.metadata);
+      StringLiteral uriLiteral = node.uri;
+      if (uriLiteral != null) {
+        importElement.uriOffset = uriLiteral.offset;
+        importElement.uriEnd = uriLiteral.end;
+      }
+      importElement.uri = node.uriContent;
+      importElement.deferred = node.deferredKeyword != null;
+      importElement.combinators = _buildCombinators(node);
+      importElement.importedLibrary = importedLibrary;
+      setElementDocumentationComment(importElement, node);
+      SimpleIdentifier prefixNode = node.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;
         }
-        ImportElementImpl importElement = new ImportElementImpl(node.offset);
-        importElement.metadata = _getElementAnnotations(node.metadata);
-        StringLiteral uriLiteral = node.uri;
+        importElement.prefix = prefix;
+        prefixNode.staticElement = prefix;
+      }
+      node.element = importElement;
+      imports.add(importElement);
+      if (importedTime >= 0 &&
+          importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
+        int offset = node.offset;
+        int length = node.length;
         if (uriLiteral != null) {
-          importElement.uriOffset = uriLiteral.offset;
-          importElement.uriEnd = uriLiteral.end;
+          offset = uriLiteral.offset;
+          length = uriLiteral.length;
         }
-        importElement.uri = node.uriContent;
-        importElement.deferred = node.deferredKeyword != null;
-        importElement.combinators = _buildCombinators(node);
-        importElement.importedLibrary = importedLibrary;
-        setElementDocumentationComment(importElement, node);
-        SimpleIdentifier prefixNode = node.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;
-        }
-        node.element = importElement;
-        imports.add(importElement);
-        if (importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
-          int offset = node.offset;
-          int length = node.length;
-          if (uriLiteral != null) {
-            offset = uriLiteral.offset;
-            length = uriLiteral.length;
-          }
-          ErrorCode errorCode = (importElement.isDeferred
-              ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
-              : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-          errors.add(new AnalysisError(libraryElement.source, offset, length,
-              errorCode, [uriLiteral.toSource()]));
-        }
+        ErrorCode errorCode = importElement.isDeferred
+            ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
+            : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY;
+        errors.add(new AnalysisError(libraryElement.source, offset, length,
+            errorCode, [uriLiteral.toSource()]));
       }
     }
     return null;
@@ -975,8 +973,8 @@
       } else {
         SimpleIdentifier propertyNameNode = node.name;
         String propertyName = propertyNameNode.name;
-        FieldElementImpl field =
-            _currentHolder.getField(propertyName) as FieldElementImpl;
+        FieldElementImpl field = _currentHolder.getField(propertyName,
+            synthetic: true) as FieldElementImpl;
         if (field == null) {
           field = new FieldElementImpl(node.name.name, -1);
           field.final2 = true;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 4619738..491025e 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -474,6 +474,13 @@
   bool _hasBeenInferred = false;
 
   /**
+   * The version of this element. The version is changed when the element is
+   * incrementally updated, so that its lists of constructors, accessors and
+   * methods might be different.
+   */
+  int version = 0;
+
+  /**
    * 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.
    */
@@ -2526,7 +2533,7 @@
   /**
    * The compilation unit in which this annotation appears.
    */
-  final CompilationUnitElementImpl compilationUnit;
+  CompilationUnitElementImpl compilationUnit;
 
   /**
    * The AST of the annotation itself, cloned from the resolved AST for the
@@ -2777,7 +2784,6 @@
    */
   void set enclosingElement(Element element) {
     _enclosingElement = element as ElementImpl;
-    _updateCaches();
   }
 
   /**
@@ -2921,7 +2927,6 @@
    */
   void set name(String name) {
     this._name = name;
-    _updateCaches();
   }
 
   @override
@@ -2938,7 +2943,6 @@
    */
   void set nameOffset(int offset) {
     _nameOffset = offset;
-    _updateCaches();
   }
 
   @override
@@ -3150,33 +3154,14 @@
     }
   }
 
-  /**
-   *  Updates cached values after an input changed.
-   *
-   *  Throws [FrozenHashCodeException] if not allowed.
-   */
-  void _updateCaches() {
-    if (!hasModifier(Modifier.CACHE_KEY)) {
-      // Fast path.
-      _cachedLocation = null;
-      _cachedHashCode = null;
-      return;
+  static int _findElementIndexUsingIdentical(List items, Object item) {
+    int length = items.length;
+    for (int i = 0; i < length; i++) {
+      if (identical(items[i], item)) {
+        return i;
+      }
     }
-
-    // Save originals.
-    ElementLocation oldLocation = _cachedLocation;
-    int oldHashCode = _cachedHashCode;
-
-    _cachedLocation = null;
-    _cachedHashCode = null;
-
-    if (oldHashCode != hashCode) {
-      // Prevent cache corruption by restoring originals.
-      _cachedLocation = oldLocation;
-      _cachedHashCode = oldHashCode;
-      throw new FrozenHashCodeException(
-          "can't update hashCode for a cache key: $this ($runtimeType)");
-    }
+    throw new StateError('Unable to find $item in $items');
   }
 }
 
@@ -4343,18 +4328,6 @@
 }
 
 /**
- * Indicates that an ElementImpl's hashCode cannot currently be changed.
- */
-class FrozenHashCodeException implements Exception {
-  final String _message;
-
-  FrozenHashCodeException(this._message);
-
-  @override
-  String toString() => "FrozenHashCodeException($_message)";
-}
-
-/**
  * A concrete implementation of a [FunctionElement].
  */
 class FunctionElementImpl extends ExecutableElementImpl
@@ -4416,8 +4389,11 @@
   @override
   String get identifier {
     String identifier = super.identifier;
-    if (!isStatic) {
-      identifier += "@$nameOffset";
+    Element enclosing = this.enclosingElement;
+    if (enclosing is ExecutableElement) {
+      int id = ElementImpl._findElementIndexUsingIdentical(
+          enclosing.functions, this);
+      identifier += "@$id";
     }
     return identifier;
   }
@@ -5692,6 +5668,7 @@
           return lib;
         }
       }
+
       void recurse(LibraryElementImpl child) {
         if (!indices.containsKey(child)) {
           // We haven't visited this child yet, so recurse on the child,
@@ -5706,6 +5683,7 @@
           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
@@ -5732,6 +5710,7 @@
       }
       return root;
     }
+
     scc(library);
     return _libraryCycle;
   }
@@ -5896,17 +5875,6 @@
    * 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
@@ -5942,6 +5910,7 @@
         library.importedLibraries.forEach(invalidate);
       }
     }
+
     invalidate(this);
   }
 
@@ -6159,10 +6128,14 @@
 
   @override
   String get identifier {
-    int enclosingOffset =
-        enclosingElement != null ? enclosingElement.nameOffset : 0;
-    int delta = nameOffset - enclosingOffset;
-    return '${super.identifier}@$delta';
+    String identifier = super.identifier;
+    Element enclosing = this.enclosingElement;
+    if (enclosing is ExecutableElement) {
+      int id = ElementImpl._findElementIndexUsingIdentical(
+          enclosing.localVariables, this);
+      identifier += "@$id";
+    }
+    return identifier;
   }
 
   @override
@@ -6426,12 +6399,7 @@
    */
   static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 16);
 
-  /**
-   * Indicates that this element is being used as an analyzer cache key.
-   */
-  static const Modifier CACHE_KEY = const Modifier('CACHE_KEY', 17);
-
-  static const List<Modifier> persistedValues = const [
+  static const List<Modifier> values = const [
     ABSTRACT,
     ASYNCHRONOUS,
     CONST,
@@ -6451,11 +6419,6 @@
     SYNTHETIC
   ];
 
-  static const List<Modifier> transientValues = const [CACHE_KEY];
-
-  static final values = new List.unmodifiable(
-      []..addAll(persistedValues)..addAll(transientValues));
-
   const Modifier(String name, int ordinal) : super(name, ordinal);
 }
 
@@ -7366,7 +7329,7 @@
   DartType get type => setter.variable.type;
 
   @override
-  void set type(FunctionType type) {
+  void set type(DartType type) {
     assert(false); // Should never be called.
   }
 }
@@ -7686,7 +7649,7 @@
   }
 
   @override
-  DartType get type {
+  FunctionType get type {
     return _type ??= new FunctionTypeImpl(this);
   }
 
@@ -7729,7 +7692,7 @@
   }
 
   @override
-  DartType get type {
+  FunctionType get type {
     return _type ??= new FunctionTypeImpl(this);
   }
 
@@ -8290,20 +8253,20 @@
 abstract class UriReferencedElementImpl extends ElementImpl
     implements UriReferencedElement {
   /**
-   * The offset of the URI in the file, may be `-1` if synthetic.
+   * The offset of the URI in the file, or `-1` if this node is synthetic.
    */
-  int uriOffset = -1;
+  int _uriOffset = -1;
 
   /**
    * The offset of the character immediately following the last character of
-   * this node's URI, may be `-1` if synthetic.
+   * this node's URI, or `-1` if this node is synthetic.
    */
-  int uriEnd = -1;
+  int _uriEnd = -1;
 
   /**
    * The URI that is specified by this directive.
    */
-  String uri;
+  String _uri;
 
   /**
    * Initialize a newly created import element to have the given [name] and
@@ -8316,6 +8279,44 @@
    */
   UriReferencedElementImpl.forSerialized(ElementImpl enclosingElement)
       : super.forSerialized(enclosingElement);
+
+  /**
+   * Return the URI that is specified by this directive.
+   */
+  String get uri => _uri;
+
+  /**
+   * Set the URI that is specified by this directive to be the given [uri].
+   */
+  void set uri(String uri) {
+    _uri = uri;
+  }
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this node's URI, or `-1` if this node is synthetic.
+   */
+  int get uriEnd => _uriEnd;
+
+  /**
+   * Set the offset of the character immediately following the last character of
+   * this node's URI to the given [offset].
+   */
+  void set uriEnd(int offset) {
+    _uriEnd = offset;
+  }
+
+  /**
+   * Return the offset of the URI in the file, or `-1` if this node is synthetic.
+   */
+  int get uriOffset => _uriOffset;
+
+  /**
+   * Set the offset of the URI in the file to the given [offset].
+   */
+  void set uriOffset(int offset) {
+    _uriOffset = offset;
+  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 22a247a..2c59228 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1176,6 +1176,11 @@
   final List<FunctionTypeAliasElement> prunedTypedefs;
 
   /**
+   * The version of [element] for which members are cached.
+   */
+  int _versionOfCachedMembers = null;
+
+  /**
    * Cached [ConstructorElement]s - members or raw elements.
    */
   List<ConstructorElement> _constructors;
@@ -1223,6 +1228,7 @@
 
   @override
   List<PropertyAccessorElement> get accessors {
+    _flushCachedMembersIfStale();
     if (_accessors == null) {
       List<PropertyAccessorElement> accessors = element.accessors;
       List<PropertyAccessorElement> members =
@@ -1237,6 +1243,7 @@
 
   @override
   List<ConstructorElement> get constructors {
+    _flushCachedMembersIfStale();
     if (_constructors == null) {
       List<ConstructorElement> constructors = element.constructors;
       List<ConstructorElement> members =
@@ -1331,6 +1338,7 @@
 
   @override
   List<MethodElement> get methods {
+    _flushCachedMembersIfStale();
     if (_methods == null) {
       List<MethodElement> methods = element.methods;
       List<MethodElement> members = new List<MethodElement>(methods.length);
@@ -1891,6 +1899,23 @@
       instantiate(argumentTypes);
 
   /**
+   * Flush cache members if the version of [element] for which members are
+   * cached and the current version of the [element].
+   */
+  void _flushCachedMembersIfStale() {
+    ClassElement element = this.element;
+    if (element is ClassElementImpl) {
+      int currentVersion = element.version;
+      if (_versionOfCachedMembers != currentVersion) {
+        _constructors = null;
+        _accessors = null;
+        _methods = null;
+      }
+      _versionOfCachedMembers = currentVersion;
+    }
+  }
+
+  /**
    * Starting from this type, search its class hierarchy for types of the form
    * Future<R>, and return a list of the resulting R's.
    */
@@ -1932,11 +1957,19 @@
     sj.add(j);
     // compute intersection, reference as set 's'
     List<InterfaceType> s = _intersection(si, sj);
+    return computeTypeAtMaxUniqueDepth(s);
+  }
+  
+  /**
+   * Return the type from the [types] list that has the longest inheritence path
+   * to Object of unique length.
+   */
+  static InterfaceType computeTypeAtMaxUniqueDepth(List<InterfaceType> types) {
     // for each element in Set s, compute the largest inheritance path to Object
-    List<int> depths = new List<int>.filled(s.length, 0);
+    List<int> depths = new List<int>.filled(types.length, 0);
     int maxDepth = 0;
-    for (int n = 0; n < s.length; n++) {
-      depths[n] = computeLongestInheritancePathToObject(s[n]);
+    for (int n = 0; n < types.length; n++) {
+      depths[n] = computeLongestInheritancePathToObject(types[n]);
       if (depths[n] > maxDepth) {
         maxDepth = depths[n];
       }
@@ -1953,7 +1986,7 @@
         }
       }
       if (numberOfTypesAtMaxDepth == 1) {
-        return s[indexOfLeastUpperBound];
+        return types[indexOfLeastUpperBound];
       }
     }
     // Should be impossible--there should always be exactly one type with the
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 0e0229c..476334b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -28,6 +28,12 @@
   LibraryElement _library;
 
   /**
+   * A flag indicating whether abstract methods should be included when looking
+   * up the superclass chain.
+   */
+  bool _includeAbstractFromSuperclasses;
+
+  /**
    * This is a mapping between each [ClassElement] and a map between the [String] member
    * names and the associated [ExecutableElement] in the mixin and superclass chain.
    */
@@ -51,8 +57,10 @@
    *
    * @param library the library element context that the inheritance mappings are being generated
    */
-  InheritanceManager(LibraryElement library) {
+  InheritanceManager(LibraryElement library,
+      {bool includeAbstractFromSuperclasses: false}) {
     this._library = library;
+    _includeAbstractFromSuperclasses = includeAbstractFromSuperclasses;
     _classLookup = new HashMap<ClassElement, Map<String, ExecutableElement>>();
     _interfaceLookup =
         new HashMap<ClassElement, Map<String, ExecutableElement>>();
@@ -282,7 +290,8 @@
           //
           // Include the members from the superclass in the resultMap.
           //
-          _recordMapWithClassMembers(resultMap, supertype, false);
+          _recordMapWithClassMembers(
+              resultMap, supertype, _includeAbstractFromSuperclasses);
         } finally {
           visitedClasses.remove(superclassElt);
         }
@@ -311,7 +320,8 @@
             //
             // Include the members from the mixin in the resultMap.
             //
-            _recordMapWithClassMembers(map, mixin, false);
+            _recordMapWithClassMembers(
+                map, mixin, _includeAbstractFromSuperclasses);
             //
             // Add the members from map into result map.
             //
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 04da23d..ba5b275 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -125,7 +125,8 @@
             getSource(identifier),
             identifier.offset,
             identifier.length,
-            CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, []));
+            CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
+            [name]));
         return hiddenElement;
       }
     }
@@ -438,6 +439,53 @@
     return foundElement;
   }
 
+  @override
+  bool shouldIgnoreUndefined(Identifier node) {
+    Iterable<NamespaceCombinator> getShowCombinators(
+            ImportElement importElement) =>
+        importElement.combinators.where((NamespaceCombinator combinator) =>
+            combinator is ShowElementCombinator);
+    if (node is PrefixedIdentifier) {
+      String prefix = node.prefix.name;
+      String name = node.identifier.name;
+      List<ImportElement> imports = _definingLibrary.imports;
+      int count = imports.length;
+      for (int i = 0; i < count; i++) {
+        ImportElement importElement = imports[i];
+        if (importElement.prefix?.name == prefix &&
+            importElement.importedLibrary?.isSynthetic != false) {
+          Iterable<NamespaceCombinator> showCombinators =
+              getShowCombinators(importElement);
+          if (showCombinators.isEmpty) {
+            return true;
+          }
+          for (ShowElementCombinator combinator in showCombinators) {
+            if (combinator.shownNames.contains(name)) {
+              return true;
+            }
+          }
+        }
+      }
+    } else if (node is SimpleIdentifier) {
+      String name = node.name;
+      List<ImportElement> imports = _definingLibrary.imports;
+      int count = imports.length;
+      for (int i = 0; i < count; i++) {
+        ImportElement importElement = imports[i];
+        if (importElement.prefix == null &&
+            importElement.importedLibrary?.isSynthetic != false) {
+          for (ShowElementCombinator combinator
+              in getShowCombinators(importElement)) {
+            if (combinator.shownNames.contains(name)) {
+              return true;
+            }
+          }
+        }
+      }
+    }
+    return false;
+  }
+
   /**
    * Create all of the namespaces associated with the libraries imported into
    * this library. The names are not added to this scope, but are stored for
@@ -521,8 +569,7 @@
       return foundElement;
     }
     for (int i = 0; i < _importedNamespaces.length; i++) {
-      Namespace nameSpace = _importedNamespaces[i];
-      Element element = nameSpace.getPrefixed(prefix, name);
+      Element element = _importedNamespaces[i].getPrefixed(prefix, name);
       if (element != null) {
         if (foundElement == null) {
           foundElement = element;
@@ -1161,6 +1208,20 @@
   }
 
   /**
+   * Return `true` if the fact that the given [node] is not defined should be
+   * ignored (from the perspective of error reporting). This will be the case if
+   * there is at least one import that defines the node's prefix, and if that
+   * import either has no show combinators or has a show combinator that
+   * explicitly lists the node's name.
+   */
+  bool shouldIgnoreUndefined(Identifier node) {
+    if (enclosingScope != null) {
+      return enclosingScope.shouldIgnoreUndefined(node);
+    }
+    return false;
+  }
+
+  /**
    * Return the name that will be used to look up the given [element].
    */
   String _getName(Element element) {
diff --git a/pkg/analyzer/lib/src/dart/scanner/scanner.dart b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
index 7814eb7..0e60a90 100644
--- a/pkg/analyzer/lib/src/dart/scanner/scanner.dart
+++ b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:charcode/ascii.dart';
 
 /**
  * A state in a state machine used to scan keywords.
@@ -57,7 +58,7 @@
    * [character], or `null` if there is no valid state reachable from this state
    * with such a transition.
    */
-  KeywordState next(int character) => _table[character - 0x61];
+  KeywordState next(int character) => _table[character - $a];
 
   /**
    * Create the next state in the state machine where we have already recognized
@@ -69,7 +70,7 @@
       int start, List<String> strings, int offset, int length) {
     List<KeywordState> result = new List<KeywordState>(26);
     assert(length != 0);
-    int chunk = 0x0;
+    int chunk = $nul;
     int chunkStart = -1;
     bool isLeaf = false;
     for (int i = offset; i < offset + length; i++) {
@@ -80,7 +81,7 @@
         int c = strings[i].codeUnitAt(start);
         if (chunk != c) {
           if (chunkStart != -1) {
-            result[chunk - 0x61] = _computeKeywordStateTable(
+            result[chunk - $a] = _computeKeywordStateTable(
                 start + 1, strings, chunkStart, i - chunkStart);
           }
           chunkStart = i;
@@ -89,8 +90,8 @@
       }
     }
     if (chunkStart != -1) {
-      assert(result[chunk - 0x61] == null);
-      result[chunk - 0x61] = _computeKeywordStateTable(
+      assert(result[chunk - $a] == null);
+      result[chunk - $a] = _computeKeywordStateTable(
           start + 1, strings, chunkStart, offset + length - chunkStart);
     } else {
       assert(length == 1);
@@ -207,6 +208,12 @@
   bool scanGenericMethodComments = false;
 
   /**
+   * A flag indicating whether the lazy compound assignment operators '&&=' and
+   * '||=' are enabled.
+   */
+  bool scanLazyAssignmentOperators = 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
@@ -260,175 +267,175 @@
 
   int bigSwitch(int next) {
     _beginToken();
-    if (next == 0xD) {
+    if (next == $cr) {
       // '\r'
       next = _reader.advance();
-      if (next == 0xA) {
+      if (next == $lf) {
         // '\n'
         next = _reader.advance();
       }
       recordStartOfLine();
       return next;
-    } else if (next == 0xA) {
+    } else if (next == $lf) {
       // '\n'
       next = _reader.advance();
       recordStartOfLine();
       return next;
-    } else if (next == 0x9 || next == 0x20) {
+    } else if (next == $tab || next == $space) {
       // '\t' || ' '
       return _reader.advance();
     }
-    if (next == 0x72) {
+    if (next == $r) {
       // 'r'
       int peek = _reader.peek();
-      if (peek == 0x22 || peek == 0x27) {
+      if (peek == $double_quote || peek == $single_quote) {
         // '"' || "'"
         int start = _reader.offset;
         return _tokenizeString(_reader.advance(), start, true);
       }
     }
-    if (0x61 <= next && next <= 0x7A) {
+    if ($a <= next && next <= $z) {
       // 'a'-'z'
       return _tokenizeKeywordOrIdentifier(next, true);
     }
-    if ((0x41 <= next && next <= 0x5A) || next == 0x5F || next == 0x24) {
+    if (($A <= next && next <= $Z) || next == $_ || next == $$) {
       // 'A'-'Z' || '_' || '$'
       return _tokenizeIdentifier(next, _reader.offset, true);
     }
-    if (next == 0x3C) {
+    if (next == $lt) {
       // '<'
       return _tokenizeLessThan(next);
     }
-    if (next == 0x3E) {
+    if (next == $gt) {
       // '>'
       return _tokenizeGreaterThan(next);
     }
-    if (next == 0x3D) {
+    if (next == $equal) {
       // '='
       return _tokenizeEquals(next);
     }
-    if (next == 0x21) {
+    if (next == $exclamation) {
       // '!'
       return _tokenizeExclamation(next);
     }
-    if (next == 0x2B) {
+    if (next == $plus) {
       // '+'
       return _tokenizePlus(next);
     }
-    if (next == 0x2D) {
+    if (next == $minus) {
       // '-'
       return _tokenizeMinus(next);
     }
-    if (next == 0x2A) {
+    if (next == $asterisk) {
       // '*'
       return _tokenizeMultiply(next);
     }
-    if (next == 0x25) {
+    if (next == $percent) {
       // '%'
       return _tokenizePercent(next);
     }
-    if (next == 0x26) {
+    if (next == $ampersand) {
       // '&'
       return _tokenizeAmpersand(next);
     }
-    if (next == 0x7C) {
+    if (next == $bar) {
       // '|'
       return _tokenizeBar(next);
     }
-    if (next == 0x5E) {
+    if (next == $caret) {
       // '^'
       return _tokenizeCaret(next);
     }
-    if (next == 0x5B) {
+    if (next == $open_bracket) {
       // '['
       return _tokenizeOpenSquareBracket(next);
     }
-    if (next == 0x7E) {
+    if (next == $tilde) {
       // '~'
       return _tokenizeTilde(next);
     }
-    if (next == 0x5C) {
+    if (next == $backslash) {
       // '\\'
       _appendTokenOfType(TokenType.BACKSLASH);
       return _reader.advance();
     }
-    if (next == 0x23) {
+    if (next == $hash) {
       // '#'
       return _tokenizeTag(next);
     }
-    if (next == 0x28) {
+    if (next == $open_paren) {
       // '('
       _appendBeginToken(TokenType.OPEN_PAREN);
       return _reader.advance();
     }
-    if (next == 0x29) {
+    if (next == $close_paren) {
       // ')'
       _appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
       return _reader.advance();
     }
-    if (next == 0x2C) {
+    if (next == $comma) {
       // ','
       _appendTokenOfType(TokenType.COMMA);
       return _reader.advance();
     }
-    if (next == 0x3A) {
+    if (next == $colon) {
       // ':'
       _appendTokenOfType(TokenType.COLON);
       return _reader.advance();
     }
-    if (next == 0x3B) {
+    if (next == $semicolon) {
       // ';'
       _appendTokenOfType(TokenType.SEMICOLON);
       return _reader.advance();
     }
-    if (next == 0x3F) {
+    if (next == $question) {
       // '?'
       return _tokenizeQuestion();
     }
-    if (next == 0x5D) {
+    if (next == $close_bracket) {
       // ']'
       _appendEndToken(
           TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
       return _reader.advance();
     }
-    if (next == 0x60) {
+    if (next == $backquote) {
       // '`'
       _appendTokenOfType(TokenType.BACKPING);
       return _reader.advance();
     }
-    if (next == 0x7B) {
+    if (next == $lbrace) {
       // '{'
       _appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
       return _reader.advance();
     }
-    if (next == 0x7D) {
+    if (next == $rbrace) {
       // '}'
       _appendEndToken(
           TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
       return _reader.advance();
     }
-    if (next == 0x2F) {
+    if (next == $slash) {
       // '/'
       return _tokenizeSlashOrComment(next);
     }
-    if (next == 0x40) {
+    if (next == $at) {
       // '@'
       _appendTokenOfType(TokenType.AT);
       return _reader.advance();
     }
-    if (next == 0x22 || next == 0x27) {
+    if (next == $double_quote || next == $single_quote) {
       // '"' || "'"
       return _tokenizeString(next, _reader.offset, false);
     }
-    if (next == 0x2E) {
+    if (next == $dot) {
       // '.'
       return _tokenizeDotOrNumber(next);
     }
-    if (next == 0x30) {
+    if (next == $0) {
       // '0'
       return _tokenizeHexOrNumber(next);
     }
-    if (0x31 <= next && next <= 0x39) {
+    if ($1 <= next && next <= $9) {
       // '1'-'9'
       return _tokenizeNumber(next);
     }
@@ -648,12 +655,12 @@
   TokenType _matchGenericMethodCommentType(String value) {
     if (scanGenericMethodComments) {
       // Match /*< and >*/
-      if (StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x3C) &&
-          StringUtilities.endsWith3(value, 0x3E, 0x2A, 0x2F)) {
+      if (StringUtilities.startsWith3(value, 0, $slash, $asterisk, $lt) &&
+          StringUtilities.endsWith3(value, $gt, $asterisk, $slash)) {
         return TokenType.GENERIC_METHOD_TYPE_LIST;
       }
       // Match /*=
-      if (StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x3D)) {
+      if (StringUtilities.startsWith3(value, 0, $slash, $asterisk, $equal)) {
         return TokenType.GENERIC_METHOD_TYPE_ASSIGN;
       }
     }
@@ -694,12 +701,17 @@
   }
 
   int _tokenizeAmpersand(int next) {
-    // && &= &
+    // &&= && &= &
     next = _reader.advance();
-    if (next == 0x26) {
+    if (next == $ampersand) {
+      next = _reader.advance();
+      if (scanLazyAssignmentOperators && next == $equal) {
+        _appendTokenOfType(TokenType.AMPERSAND_AMPERSAND_EQ);
+        return _reader.advance();
+      }
       _appendTokenOfType(TokenType.AMPERSAND_AMPERSAND);
-      return _reader.advance();
-    } else if (next == 0x3D) {
+      return next;
+    } else if (next == $equal) {
       _appendTokenOfType(TokenType.AMPERSAND_EQ);
       return _reader.advance();
     } else {
@@ -709,12 +721,17 @@
   }
 
   int _tokenizeBar(int next) {
-    // | || |=
+    // ||= || |= |
     next = _reader.advance();
-    if (next == 0x7C) {
+    if (next == $bar) {
+      next = _reader.advance();
+      if (scanLazyAssignmentOperators && next == $equal) {
+        _appendTokenOfType(TokenType.BAR_BAR_EQ);
+        return _reader.advance();
+      }
       _appendTokenOfType(TokenType.BAR_BAR);
-      return _reader.advance();
-    } else if (next == 0x3D) {
+      return next;
+    } else if (next == $equal) {
       _appendTokenOfType(TokenType.BAR_EQ);
       return _reader.advance();
     } else {
@@ -724,16 +741,16 @@
   }
 
   int _tokenizeCaret(int next) =>
-      _select(0x3D, TokenType.CARET_EQ, TokenType.CARET);
+      _select($equal, TokenType.CARET_EQ, TokenType.CARET);
 
   int _tokenizeDotOrNumber(int next) {
     int start = _reader.offset;
     next = _reader.advance();
-    if (0x30 <= next && next <= 0x39) {
+    if ($0 <= next && next <= $9) {
       return _tokenizeFractionPart(next, start);
-    } else if (0x2E == next) {
+    } else if ($dot == next) {
       return _select(
-          0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
+          $dot, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
     } else {
       _appendTokenOfType(TokenType.PERIOD);
       return next;
@@ -743,10 +760,10 @@
   int _tokenizeEquals(int next) {
     // = == =>
     next = _reader.advance();
-    if (next == 0x3D) {
+    if (next == $equal) {
       _appendTokenOfType(TokenType.EQ_EQ);
       return _reader.advance();
-    } else if (next == 0x3E) {
+    } else if (next == $gt) {
       _appendTokenOfType(TokenType.FUNCTION);
       return _reader.advance();
     }
@@ -757,7 +774,7 @@
   int _tokenizeExclamation(int next) {
     // ! !=
     next = _reader.advance();
-    if (next == 0x3D) {
+    if (next == $equal) {
       _appendTokenOfType(TokenType.BANG_EQ);
       return _reader.advance();
     }
@@ -766,12 +783,12 @@
   }
 
   int _tokenizeExponent(int next) {
-    if (next == 0x2B || next == 0x2D) {
+    if (next == $plus || next == $minus) {
       next = _reader.advance();
     }
     bool hasDigits = false;
     while (true) {
-      if (0x30 <= next && next <= 0x39) {
+      if ($0 <= next && next <= $9) {
         hasDigits = true;
       } else {
         if (!hasDigits) {
@@ -787,9 +804,9 @@
     bool done = false;
     bool hasDigit = false;
     LOOP: while (!done) {
-      if (0x30 <= next && next <= 0x39) {
+      if ($0 <= next && next <= $9) {
         hasDigit = true;
-      } else if (0x65 == next || 0x45 == next) {
+      } else if ($e == next || $E == next) {
         hasDigit = true;
         next = _tokenizeExponent(_reader.advance());
         done = true;
@@ -802,8 +819,8 @@
     }
     if (!hasDigit) {
       _appendStringToken(TokenType.INT, _reader.getString(start, -2));
-      if (0x2E == next) {
-        return _selectWithOffset(0x2E, TokenType.PERIOD_PERIOD_PERIOD,
+      if ($dot == next) {
+        return _selectWithOffset($dot, TokenType.PERIOD_PERIOD_PERIOD,
             TokenType.PERIOD_PERIOD, _reader.offset - 1);
       }
       _appendTokenOfTypeWithOffset(TokenType.PERIOD, _reader.offset - 1);
@@ -817,12 +834,12 @@
   int _tokenizeGreaterThan(int next) {
     // > >= >> >>=
     next = _reader.advance();
-    if (0x3D == next) {
+    if ($equal == next) {
       _appendTokenOfType(TokenType.GT_EQ);
       return _reader.advance();
-    } else if (0x3E == next) {
+    } else if ($gt == next) {
       next = _reader.advance();
-      if (0x3D == next) {
+      if ($equal == next) {
         _appendTokenOfType(TokenType.GT_GT_EQ);
         return _reader.advance();
       } else {
@@ -840,9 +857,9 @@
     bool hasDigits = false;
     while (true) {
       next = _reader.advance();
-      if ((0x30 <= next && next <= 0x39) ||
-          (0x41 <= next && next <= 0x46) ||
-          (0x61 <= next && next <= 0x66)) {
+      if (($0 <= next && next <= $9) ||
+          ($A <= next && next <= $F) ||
+          ($a <= next && next <= $f)) {
         hasDigits = true;
       } else {
         if (!hasDigits) {
@@ -857,7 +874,7 @@
 
   int _tokenizeHexOrNumber(int next) {
     int x = _reader.peek();
-    if (x == 0x78 || x == 0x58) {
+    if (x == $x || x == $X) {
       _reader.advance();
       return _tokenizeHex(x);
     }
@@ -865,11 +882,11 @@
   }
 
   int _tokenizeIdentifier(int next, int start, bool allowDollar) {
-    while ((0x61 <= next && next <= 0x7A) ||
-        (0x41 <= next && next <= 0x5A) ||
-        (0x30 <= next && next <= 0x39) ||
-        next == 0x5F ||
-        (next == 0x24 && allowDollar)) {
+    while (($a <= next && next <= $z) ||
+        ($A <= next && next <= $Z) ||
+        ($0 <= next && next <= $9) ||
+        next == $_ ||
+        (next == $$ && allowDollar)) {
       next = _reader.advance();
     }
     _appendStringToken(
@@ -881,7 +898,7 @@
     _appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
     next = _reader.advance();
     while (next != -1) {
-      if (next == 0x7D) {
+      if (next == $rbrace) {
         BeginToken begin =
             _findTokenMatchingClosingBraceInInterpolationExpression();
         if (begin == null) {
@@ -914,9 +931,9 @@
   int _tokenizeInterpolatedIdentifier(int next, int start) {
     _appendStringTokenWithOffset(
         TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 0);
-    if ((0x41 <= next && next <= 0x5A) ||
-        (0x61 <= next && next <= 0x7A) ||
-        next == 0x5F) {
+    if (($A <= next && next <= $Z) ||
+        ($a <= next && next <= $z) ||
+        next == $_) {
       _beginToken();
       next = _tokenizeKeywordOrIdentifier(next, false);
     }
@@ -927,17 +944,17 @@
   int _tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
     KeywordState state = KeywordState.KEYWORD_STATE;
     int start = _reader.offset;
-    while (state != null && 0x61 <= next && next <= 0x7A) {
+    while (state != null && $a <= next && next <= $z) {
       state = state.next(next);
       next = _reader.advance();
     }
     if (state == null || state.keyword() == null) {
       return _tokenizeIdentifier(next, start, allowDollar);
     }
-    if ((0x41 <= next && next <= 0x5A) ||
-        (0x30 <= next && next <= 0x39) ||
-        next == 0x5F ||
-        next == 0x24) {
+    if (($A <= next && next <= $Z) ||
+        ($0 <= next && next <= $9) ||
+        next == $_ ||
+        next == $$) {
       return _tokenizeIdentifier(next, start, allowDollar);
     } else if (next < 128) {
       _appendKeywordToken(state.keyword());
@@ -950,11 +967,11 @@
   int _tokenizeLessThan(int next) {
     // < <= << <<=
     next = _reader.advance();
-    if (0x3D == next) {
+    if ($equal == next) {
       _appendTokenOfType(TokenType.LT_EQ);
       return _reader.advance();
-    } else if (0x3C == next) {
-      return _select(0x3D, TokenType.LT_LT_EQ, TokenType.LT_LT);
+    } else if ($lt == next) {
+      return _select($equal, TokenType.LT_LT_EQ, TokenType.LT_LT);
     } else {
       _appendTokenOfType(TokenType.LT);
       return next;
@@ -964,10 +981,10 @@
   int _tokenizeMinus(int next) {
     // - -- -=
     next = _reader.advance();
-    if (next == 0x2D) {
+    if (next == $minus) {
       _appendTokenOfType(TokenType.MINUS_MINUS);
       return _reader.advance();
-    } else if (next == 0x3D) {
+    } else if (next == $equal) {
       _appendTokenOfType(TokenType.MINUS_EQ);
       return _reader.advance();
     } else {
@@ -985,9 +1002,9 @@
         _appendCommentToken(
             TokenType.MULTI_LINE_COMMENT, _reader.getString(_tokenStart, 0));
         return next;
-      } else if (0x2A == next) {
+      } else if ($asterisk == next) {
         next = _reader.advance();
-        if (0x2F == next) {
+        if ($slash == next) {
           --nesting;
           if (0 == nesting) {
             _appendCommentToken(TokenType.MULTI_LINE_COMMENT,
@@ -997,19 +1014,19 @@
             next = _reader.advance();
           }
         }
-      } else if (0x2F == next) {
+      } else if ($slash == next) {
         next = _reader.advance();
-        if (0x2A == next) {
+        if ($asterisk == next) {
           next = _reader.advance();
           ++nesting;
         }
-      } else if (next == 0xD) {
+      } else if (next == $cr) {
         next = _reader.advance();
-        if (next == 0xA) {
+        if (next == $lf) {
           next = _reader.advance();
         }
         recordStartOfLine();
-      } else if (next == 0xA) {
+      } else if (next == $lf) {
         next = _reader.advance();
         recordStartOfLine();
       } else {
@@ -1024,13 +1041,13 @@
       while (next != quoteChar) {
         if (next == -1) {
           break outer;
-        } else if (next == 0xD) {
+        } else if (next == $cr) {
           next = _reader.advance();
-          if (next == 0xA) {
+          if (next == $lf) {
             next = _reader.advance();
           }
           recordStartOfLine();
-        } else if (next == 0xA) {
+        } else if (next == $lf) {
           next = _reader.advance();
           recordStartOfLine();
         } else {
@@ -1057,7 +1074,7 @@
     }
     int next = _reader.advance();
     while (next != -1) {
-      if (next == 0x24) {
+      if (next == $$) {
         _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
         next = _tokenizeStringInterpolation(start);
         _beginToken();
@@ -1075,30 +1092,30 @@
         }
         continue;
       }
-      if (next == 0x5C) {
+      if (next == $backslash) {
         next = _reader.advance();
         if (next == -1) {
           break;
         }
-        if (next == 0xD) {
+        if (next == $cr) {
           next = _reader.advance();
-          if (next == 0xA) {
+          if (next == $lf) {
             next = _reader.advance();
           }
           recordStartOfLine();
-        } else if (next == 0xA) {
+        } else if (next == $lf) {
           recordStartOfLine();
           next = _reader.advance();
         } else {
           next = _reader.advance();
         }
-      } else if (next == 0xD) {
+      } else if (next == $cr) {
         next = _reader.advance();
-        if (next == 0xA) {
+        if (next == $lf) {
           next = _reader.advance();
         }
         recordStartOfLine();
-      } else if (next == 0xA) {
+      } else if (next == $lf) {
         recordStartOfLine();
         next = _reader.advance();
       } else {
@@ -1115,17 +1132,17 @@
   }
 
   int _tokenizeMultiply(int next) =>
-      _select(0x3D, TokenType.STAR_EQ, TokenType.STAR);
+      _select($equal, TokenType.STAR_EQ, TokenType.STAR);
 
   int _tokenizeNumber(int next) {
     int start = _reader.offset;
     while (true) {
       next = _reader.advance();
-      if (0x30 <= next && next <= 0x39) {
+      if ($0 <= next && next <= $9) {
         continue;
-      } else if (next == 0x2E) {
+      } else if (next == $dot) {
         return _tokenizeFractionPart(_reader.advance(), start);
-      } else if (next == 0x65 || next == 0x45) {
+      } else if (next == $e || next == $E) {
         return _tokenizeFractionPart(next, start);
       } else {
         _appendStringToken(
@@ -1138,8 +1155,8 @@
   int _tokenizeOpenSquareBracket(int next) {
     // [ []  []=
     next = _reader.advance();
-    if (next == 0x5D) {
-      return _select(0x3D, TokenType.INDEX_EQ, TokenType.INDEX);
+    if (next == $close_bracket) {
+      return _select($equal, TokenType.INDEX_EQ, TokenType.INDEX);
     } else {
       _appendBeginToken(TokenType.OPEN_SQUARE_BRACKET);
       return next;
@@ -1147,15 +1164,15 @@
   }
 
   int _tokenizePercent(int next) =>
-      _select(0x3D, TokenType.PERCENT_EQ, TokenType.PERCENT);
+      _select($equal, TokenType.PERCENT_EQ, TokenType.PERCENT);
 
   int _tokenizePlus(int next) {
     // + ++ +=
     next = _reader.advance();
-    if (0x2B == next) {
+    if ($plus == next) {
       _appendTokenOfType(TokenType.PLUS_PLUS);
       return _reader.advance();
-    } else if (0x3D == next) {
+    } else if ($equal == next) {
       _appendTokenOfType(TokenType.PLUS_EQ);
       return _reader.advance();
     } else {
@@ -1167,14 +1184,14 @@
   int _tokenizeQuestion() {
     // ? ?. ?? ??=
     int next = _reader.advance();
-    if (next == 0x2E) {
+    if (next == $dot) {
       // '.'
       _appendTokenOfType(TokenType.QUESTION_PERIOD);
       return _reader.advance();
-    } else if (next == 0x3F) {
+    } else if (next == $question) {
       // '?'
       next = _reader.advance();
-      if (next == 0x3D) {
+      if (next == $equal) {
         // '='
         _appendTokenOfType(TokenType.QUESTION_QUESTION_EQ);
         return _reader.advance();
@@ -1195,7 +1212,7 @@
         _appendCommentToken(
             TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, 0));
         return next;
-      } else if (0xA == next || 0xD == next) {
+      } else if ($lf == next || $cr == next) {
         _appendCommentToken(
             TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, -1));
         return next;
@@ -1209,7 +1226,7 @@
       if (next == quoteChar) {
         _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
         return _reader.advance();
-      } else if (next == 0xD || next == 0xA) {
+      } else if (next == $cr || next == $lf) {
         _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
         _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
         return _reader.advance();
@@ -1223,16 +1240,16 @@
 
   int _tokenizeSingleLineString(int next, int quoteChar, int start) {
     while (next != quoteChar) {
-      if (next == 0x5C) {
+      if (next == $backslash) {
         next = _reader.advance();
-      } else if (next == 0x24) {
+      } else if (next == $$) {
         _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
         next = _tokenizeStringInterpolation(start);
         _beginToken();
         start = _reader.offset;
         continue;
       }
-      if (next <= 0xD && (next == 0xA || next == 0xD || next == -1)) {
+      if (next <= $cr && (next == $lf || next == $cr || next == -1)) {
         _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
         if (start == _reader.offset) {
           _appendStringTokenWithOffset(TokenType.STRING, "", 1);
@@ -1251,11 +1268,11 @@
 
   int _tokenizeSlashOrComment(int next) {
     next = _reader.advance();
-    if (0x2A == next) {
+    if ($asterisk == next) {
       return _tokenizeMultiLineComment(next);
-    } else if (0x2F == next) {
+    } else if ($slash == next) {
       return _tokenizeSingleLineComment(next);
-    } else if (0x3D == next) {
+    } else if ($equal == next) {
       _appendTokenOfType(TokenType.SLASH_EQ);
       return _reader.advance();
     } else {
@@ -1288,7 +1305,7 @@
   int _tokenizeStringInterpolation(int start) {
     _beginToken();
     int next = _reader.advance();
-    if (next == 0x7B) {
+    if (next == $lbrace) {
       return _tokenizeInterpolatedExpression(next, start);
     } else {
       return _tokenizeInterpolatedIdentifier(next, start);
@@ -1298,10 +1315,10 @@
   int _tokenizeTag(int next) {
     // # or #!.*[\n\r]
     if (_reader.offset == 0) {
-      if (_reader.peek() == 0x21) {
+      if (_reader.peek() == $exclamation) {
         do {
           next = _reader.advance();
-        } while (next != 0xA && next != 0xD && next > 0);
+        } while (next != $lf && next != $cr && next > 0);
         _appendStringToken(
             TokenType.SCRIPT_TAG, _reader.getString(_tokenStart, 0));
         return next;
@@ -1314,8 +1331,8 @@
   int _tokenizeTilde(int next) {
     // ~ ~/ ~/=
     next = _reader.advance();
-    if (next == 0x2F) {
-      return _select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
+    if (next == $slash) {
+      return _select($equal, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
     } else {
       _appendTokenOfType(TokenType.TILDE);
       return next;
@@ -1326,8 +1343,8 @@
    * Checks if [value] is a single-line or multi-line comment.
    */
   static bool _isDocumentationComment(String value) {
-    return StringUtilities.startsWith3(value, 0, 0x2F, 0x2F, 0x2F) ||
-        StringUtilities.startsWith3(value, 0, 0x2F, 0x2A, 0x2A);
+    return StringUtilities.startsWith3(value, 0, $slash, $slash, $slash) ||
+        StringUtilities.startsWith3(value, 0, $slash, $asterisk, $asterisk);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
new file mode 100644
index 0000000..d692a28
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -0,0 +1,853 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.sdk2;
+
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:io' as io;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+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/parser.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
+import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:yaml/yaml.dart';
+
+/**
+ * An abstract implementation of a Dart SDK in which the available libraries are
+ * stored in a library map. Subclasses are responsible for populating the
+ * library map.
+ */
+abstract class AbstractDartSdk implements DartSdk {
+  /**
+   * The resource provider used to access the file system.
+   */
+  ResourceProvider resourceProvider;
+
+  /**
+   * A mapping from Dart library URI's to the library represented by that URI.
+   */
+  LibraryMap libraryMap = new LibraryMap();
+
+  /**
+   * The [AnalysisOptions] to use to create the [context].
+   */
+  AnalysisOptions _analysisOptions;
+
+  /**
+   * The flag that specifies whether an SDK summary should be used. This is a
+   * temporary flag until summaries are enabled by default.
+   */
+  bool _useSummary = false;
+
+  /**
+   * The [AnalysisContext] which is used for all of the sources in this SDK.
+   */
+  InternalAnalysisContext _analysisContext;
+
+  /**
+   * The mapping from Dart URI's to the corresponding sources.
+   */
+  Map<String, Source> _uriToSourceMap = new HashMap<String, Source>();
+
+  PackageBundle _sdkBundle;
+
+  /**
+   * Set the [options] for this SDK analysis context.  Throw [StateError] if the
+   * context has been already created.
+   */
+  void set analysisOptions(AnalysisOptions options) {
+    if (_analysisContext != null) {
+      throw new StateError(
+          'Analysis options cannot be changed after context creation.');
+    }
+    _analysisOptions = options;
+  }
+
+  @override
+  AnalysisContext get context {
+    if (_analysisContext == null) {
+      _analysisContext = new SdkAnalysisContext(_analysisOptions);
+      SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
+      _analysisContext.sourceFactory = factory;
+      if (_useSummary) {
+        bool strongMode = _analysisOptions?.strongMode ?? false;
+        PackageBundle sdkBundle = getLinkedBundle();
+        if (sdkBundle != null) {
+          _analysisContext.resultProvider = new SdkSummaryResultProvider(
+              _analysisContext, sdkBundle, strongMode);
+        }
+      }
+    }
+    return _analysisContext;
+  }
+
+  @override
+  List<SdkLibrary> get sdkLibraries => libraryMap.sdkLibraries;
+
+  /**
+   * Return the path separator used by the resource provider.
+   */
+  String get separator => resourceProvider.pathContext.separator;
+
+  @override
+  List<String> get uris => libraryMap.uris;
+
+  /**
+   * Return `true` if the SDK summary will be used when available.
+   */
+  bool get useSummary => _useSummary;
+
+  /**
+   * Specify whether SDK summary should be used.
+   */
+  void set useSummary(bool use) {
+    if (_analysisContext != null) {
+      throw new StateError(
+          'The "useSummary" flag cannot be changed after context creation.');
+    }
+    _useSummary = use;
+  }
+
+  /**
+   * Add the extensions from one or more sdk extension files to this sdk. The
+   * [extensions] should be a table mapping the names of extensions to the paths
+   * where those extensions can be found.
+   */
+  void addExtensions(Map<String, String> extensions) {
+    extensions.forEach((String uri, String path) {
+      SdkLibraryImpl library = new SdkLibraryImpl(uri);
+      library.path = path;
+      libraryMap.setLibrary(uri, library);
+    });
+  }
+
+  @override
+  Source fromFileUri(Uri uri) {
+    File file =
+        resourceProvider.getFile(resourceProvider.pathContext.fromUri(uri));
+    String path = _getPath(file);
+    if (path == null) {
+      return null;
+    }
+    try {
+      return file.createSource(parseUriWithException(path));
+    } on URISyntaxException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Failed to create URI: $path",
+          new CaughtException(exception, stackTrace));
+    }
+    return null;
+  }
+
+  @override
+  PackageBundle getLinkedBundle() {
+    bool strongMode = _analysisOptions?.strongMode ?? false;
+    _sdkBundle ??= getSummarySdkBundle(strongMode);
+    return _sdkBundle;
+  }
+
+  String getRelativePathFromFile(File file);
+
+  @override
+  SdkLibrary getSdkLibrary(String dartUri) => libraryMap.getLibrary(dartUri);
+
+  /**
+   * Return the [PackageBundle] for this SDK, if it exists, or `null` otherwise.
+   * This method should not be used outside of `analyzer` and `analyzer_cli`
+   * packages.
+   */
+  PackageBundle getSummarySdkBundle(bool strongMode);
+
+  Source internalMapDartUri(String dartUri) {
+    // TODO(brianwilkerson) Figure out how to unify the implementations in the
+    // two subclasses.
+    String libraryName;
+    String relativePath;
+    int index = dartUri.indexOf('/');
+    if (index >= 0) {
+      libraryName = dartUri.substring(0, index);
+      relativePath = dartUri.substring(index + 1);
+    } else {
+      libraryName = dartUri;
+      relativePath = "";
+    }
+    SdkLibrary library = getSdkLibrary(libraryName);
+    if (library == null) {
+      return null;
+    }
+    String srcPath;
+    if (relativePath.isEmpty) {
+      srcPath = library.path;
+    } else {
+      String libraryPath = library.path;
+      int index = libraryPath.lastIndexOf(separator);
+      if (index == -1) {
+        index = libraryPath.lastIndexOf('/');
+        if (index == -1) {
+          return null;
+        }
+      }
+      String prefix = libraryPath.substring(0, index + 1);
+      srcPath = '$prefix$relativePath';
+    }
+    String filePath = srcPath.replaceAll('/', separator);
+    try {
+      File file = resourceProvider.getFile(filePath);
+      return file.createSource(parseUriWithException(dartUri));
+    } on URISyntaxException {
+      return null;
+    }
+  }
+
+  @override
+  Source mapDartUri(String dartUri) {
+    Source source = _uriToSourceMap[dartUri];
+    if (source == null) {
+      source = internalMapDartUri(dartUri);
+      _uriToSourceMap[dartUri] = source;
+    }
+    return source;
+  }
+
+  String _getPath(File file) {
+    List<SdkLibrary> libraries = libraryMap.sdkLibraries;
+    int length = libraries.length;
+    List<String> paths = new List(length);
+    String filePath = getRelativePathFromFile(file);
+    if (filePath == null) {
+      return null;
+    }
+    for (int i = 0; i < length; i++) {
+      SdkLibrary library = libraries[i];
+      String libraryPath = library.path.replaceAll('/', separator);
+      if (filePath == libraryPath) {
+        return library.shortName;
+      }
+      paths[i] = libraryPath;
+    }
+    for (int i = 0; i < length; i++) {
+      SdkLibrary library = libraries[i];
+      String libraryPath = paths[i];
+      int index = libraryPath.lastIndexOf(separator);
+      if (index >= 0) {
+        String prefix = libraryPath.substring(0, index + 1);
+        if (filePath.startsWith(prefix)) {
+          String relPath =
+              filePath.substring(prefix.length).replaceAll(separator, '/');
+          return '${library.shortName}/$relPath';
+        }
+      }
+    }
+    return null;
+  }
+}
+
+/**
+ * An SDK backed by URI mappings derived from an `_embedder.yaml` file.
+ */
+class EmbedderSdk extends AbstractDartSdk {
+  static const String _DART_COLON_PREFIX = 'dart:';
+
+  static const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
+  final Map<String, String> _urlMappings = new HashMap<String, String>();
+
+  EmbedderSdk(
+      ResourceProvider resourceProvider, Map<Folder, YamlMap> embedderYamls) {
+    this.resourceProvider = resourceProvider;
+    embedderYamls?.forEach(_processEmbedderYaml);
+  }
+
+  @override
+  // TODO(danrubel) Determine SDK version
+  String get sdkVersion => '0';
+
+  /**
+   * The url mappings for this SDK.
+   */
+  Map<String, String> get urlMappings => _urlMappings;
+
+  @override
+  PackageBundle getLinkedBundle() => null;
+
+  @override
+  String getRelativePathFromFile(File file) => file.path;
+
+  @override
+  PackageBundle getSummarySdkBundle(bool strongMode) => null;
+
+  @override
+  Source internalMapDartUri(String dartUri) {
+    String libraryName;
+    String relativePath;
+    int index = dartUri.indexOf('/');
+    if (index >= 0) {
+      libraryName = dartUri.substring(0, index);
+      relativePath = dartUri.substring(index + 1);
+    } else {
+      libraryName = dartUri;
+      relativePath = "";
+    }
+    SdkLibrary library = getSdkLibrary(libraryName);
+    if (library == null) {
+      return null;
+    }
+    String srcPath;
+    if (relativePath.isEmpty) {
+      srcPath = library.path;
+    } else {
+      String libraryPath = library.path;
+      int index = libraryPath.lastIndexOf(separator);
+      if (index == -1) {
+        index = libraryPath.lastIndexOf('/');
+        if (index == -1) {
+          return null;
+        }
+      }
+      String prefix = libraryPath.substring(0, index + 1);
+      srcPath = '$prefix$relativePath';
+    }
+    String filePath = srcPath.replaceAll('/', separator);
+    try {
+      File file = resourceProvider.getFile(filePath);
+      return file.createSource(parseUriWithException(dartUri));
+    } on URISyntaxException {
+      return null;
+    }
+  }
+
+  /**
+   * Install the mapping from [name] to [libDir]/[file].
+   */
+  void _processEmbeddedLibs(String name, String file, Folder libDir) {
+    if (!name.startsWith(_DART_COLON_PREFIX)) {
+      // SDK libraries must begin with 'dart:'.
+      return;
+    }
+    String libPath = libDir.canonicalizePath(file);
+    _urlMappings[name] = libPath;
+    SdkLibraryImpl library = new SdkLibraryImpl(name);
+    library.path = libPath;
+    libraryMap.setLibrary(name, library);
+  }
+
+  /**
+   * Given the 'embedderYamls' from [EmbedderYamlLocator] check each one for the
+   * top level key 'embedded_libs'. Under the 'embedded_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:
+   *
+   * embedded_libs:
+   *   'dart:io': '../../sdk/io/io.dart'
+   *
+   * If a key doesn't begin with `dart:` it is ignored.
+   */
+  void _processEmbedderYaml(Folder libDir, YamlMap map) {
+    YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
+    if (embedded_libs is YamlMap) {
+      embedded_libs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
+    }
+  }
+}
+
+/**
+ * A Dart SDK installed in a specified directory. Typical Dart SDK layout is
+ * something like...
+ *
+ *     dart-sdk/
+ *        bin/
+ *           dart[.exe]  <-- VM
+ *        lib/
+ *           core/
+ *              core.dart
+ *              ... other core library files ...
+ *           ... other libraries ...
+ *        util/
+ *           ... Dart utilities ...
+ *     Chromium/   <-- Dartium typically exists in a sibling directory
+ */
+class FolderBasedDartSdk extends AbstractDartSdk {
+  /**
+   * The name of the directory within the SDK directory that contains
+   * executables.
+   */
+  static String _BIN_DIRECTORY_NAME = "bin";
+
+  /**
+   * The name of the directory within the SDK directory that contains
+   * documentation for the libraries.
+   */
+  static String _DOCS_DIRECTORY_NAME = "docs";
+
+  /**
+   * The name of the directory within the SDK directory that contains the
+   * sdk_library_metadata directory.
+   */
+  static String _INTERNAL_DIR = "_internal";
+
+  /**
+   * The name of the sdk_library_metadata directory that contains the package
+   * holding the libraries.dart file.
+   */
+  static String _SDK_LIBRARY_METADATA_DIR = "sdk_library_metadata";
+
+  /**
+   * The name of the directory within the sdk_library_metadata that contains
+   * libraries.dart.
+   */
+  static String _SDK_LIBRARY_METADATA_LIB_DIR = "lib";
+
+  /**
+   * The name of the directory within the SDK directory that contains the
+   * libraries.
+   */
+  static String _LIB_DIRECTORY_NAME = "lib";
+
+  /**
+   * The name of the libraries file.
+   */
+  static String _LIBRARIES_FILE = "libraries.dart";
+
+  /**
+   * The name of the pub executable on windows.
+   */
+  static String _PUB_EXECUTABLE_NAME_WIN = "pub.bat";
+
+  /**
+   * The name of the pub executable on non-windows operating systems.
+   */
+  static String _PUB_EXECUTABLE_NAME = "pub";
+
+  /**
+   * The name of the file within the SDK directory that contains the version
+   * number of the SDK.
+   */
+  static String _VERSION_FILE_NAME = "version";
+
+  /**
+   * The directory containing the SDK.
+   */
+  Folder _sdkDirectory;
+
+  /**
+   * The directory within the SDK directory that contains the libraries.
+   */
+  Folder _libraryDirectory;
+
+  /**
+   * The revision number of this SDK, or `"0"` if the revision number cannot be
+   * discovered.
+   */
+  String _sdkVersion;
+
+  /**
+   * The file containing the pub executable.
+   */
+  File _pubExecutable;
+
+  /**
+   * 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
+   */
+  FolderBasedDartSdk(ResourceProvider resourceProvider, this._sdkDirectory,
+      [bool useDart2jsPaths = false]) {
+    this.resourceProvider = resourceProvider;
+    libraryMap = initialLibraryMap(useDart2jsPaths);
+  }
+
+  /**
+   * Return the directory containing the SDK.
+   */
+  Folder get directory => _sdkDirectory;
+
+  /**
+   * Return the directory containing documentation for the SDK.
+   */
+  Folder get docDirectory =>
+      _sdkDirectory.getChildAssumingFolder(_DOCS_DIRECTORY_NAME);
+
+  /**
+   * Return the directory within the SDK directory that contains the libraries.
+   */
+  Folder get libraryDirectory {
+    if (_libraryDirectory == null) {
+      _libraryDirectory =
+          _sdkDirectory.getChildAssumingFolder(_LIB_DIRECTORY_NAME);
+    }
+    return _libraryDirectory;
+  }
+
+  /**
+   * Return the file containing the Pub executable, or `null` if it does not exist.
+   */
+  File get pubExecutable {
+    if (_pubExecutable == null) {
+      _pubExecutable = _sdkDirectory
+          .getChildAssumingFolder(_BIN_DIRECTORY_NAME)
+          .getChildAssumingFile(OSUtilities.isWindows()
+              ? _PUB_EXECUTABLE_NAME_WIN
+              : _PUB_EXECUTABLE_NAME);
+    }
+    return _pubExecutable;
+  }
+
+  /**
+   * Return the revision number of this SDK, or `"0"` if the revision number
+   * cannot be discovered.
+   */
+  @override
+  String get sdkVersion {
+    if (_sdkVersion == null) {
+      _sdkVersion = DartSdk.DEFAULT_VERSION;
+      File revisionFile =
+          _sdkDirectory.getChildAssumingFile(_VERSION_FILE_NAME);
+      try {
+        String revision = revisionFile.readAsStringSync();
+        if (revision != null) {
+          _sdkVersion = revision.trim();
+        }
+      } on FileSystemException {
+        // Fall through to return the default.
+      }
+    }
+    return _sdkVersion;
+  }
+
+  /**
+   * Determine the search order for trying to locate the [_LIBRARIES_FILE].
+   */
+  Iterable<File> get _libraryMapLocations sync* {
+    yield libraryDirectory
+        .getChildAssumingFolder(_INTERNAL_DIR)
+        .getChildAssumingFolder(_SDK_LIBRARY_METADATA_DIR)
+        .getChildAssumingFolder(_SDK_LIBRARY_METADATA_LIB_DIR)
+        .getChildAssumingFile(_LIBRARIES_FILE);
+    yield libraryDirectory
+        .getChildAssumingFolder(_INTERNAL_DIR)
+        .getChildAssumingFile(_LIBRARIES_FILE);
+  }
+
+  @override
+  String getRelativePathFromFile(File file) {
+    String filePath = file.path;
+    String libPath = libraryDirectory.path;
+    if (!filePath.startsWith("$libPath$separator")) {
+      return null;
+    }
+    return filePath.substring(libPath.length + 1);
+  }
+
+  /**
+   * Return the [PackageBundle] for this SDK, if it exists, or `null` otherwise.
+   * This method should not be used outside of `analyzer` and `analyzer_cli`
+   * packages.
+   */
+  PackageBundle getSummarySdkBundle(bool strongMode) {
+    String rootPath = directory.path;
+    String name = strongMode ? 'strong.sum' : 'spec.sum';
+    String path =
+        resourceProvider.pathContext.join(rootPath, 'lib', '_internal', name);
+    try {
+      File file = resourceProvider.getFile(path);
+      if (file.exists) {
+        List<int> bytes = file.readAsBytesSync();
+        return new PackageBundle.fromBuffer(bytes);
+      }
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          'Failed to load SDK analysis summary from $path',
+          new CaughtException(exception, stackTrace));
+    }
+    return null;
+  }
+
+  /**
+   * Read all of the configuration files to initialize the library maps. The
+   * flag [useDart2jsPaths] is `true` if the dart2js path should be used when it
+   * is available. Return the initialized library map.
+   */
+  LibraryMap initialLibraryMap(bool useDart2jsPaths) {
+    List<String> searchedPaths = <String>[];
+    var lastStackTrace = null;
+    var lastException = null;
+    for (File librariesFile in _libraryMapLocations) {
+      try {
+        String contents = librariesFile.readAsStringSync();
+        return new SdkLibrariesReader(useDart2jsPaths)
+            .readFromFile(librariesFile, contents);
+      } catch (exception, stackTrace) {
+        searchedPaths.add(librariesFile.path);
+        lastException = exception;
+        lastStackTrace = stackTrace;
+      }
+    }
+    AnalysisEngine.instance.logger.logError(
+        "Could not initialize the library map from $searchedPaths",
+        new CaughtException(lastException, lastStackTrace));
+    return new LibraryMap();
+  }
+
+  @override
+  Source internalMapDartUri(String dartUri) {
+    String libraryName;
+    String relativePath;
+    int index = dartUri.indexOf('/');
+    if (index >= 0) {
+      libraryName = dartUri.substring(0, index);
+      relativePath = dartUri.substring(index + 1);
+    } else {
+      libraryName = dartUri;
+      relativePath = "";
+    }
+    SdkLibrary library = getSdkLibrary(libraryName);
+    if (library == null) {
+      return null;
+    }
+    try {
+      File file = libraryDirectory.getChildAssumingFile(library.path);
+      if (!relativePath.isEmpty) {
+        file = file.parent.getChildAssumingFile(relativePath);
+      }
+      return file.createSource(parseUriWithException(dartUri));
+    } on URISyntaxException {
+      return null;
+    }
+  }
+
+  /**
+   * Return the default directory for the Dart SDK, or `null` if the directory
+   * cannot be determined (or does not exist). The default directory is provided
+   * by a system property named `com.google.dart.sdk`.
+   */
+  static Folder defaultSdkDirectory(ResourceProvider resourceProvider) {
+    // TODO(brianwilkerson) This is currently only being used in the analysis
+    // server's Driver class to find the default SDK. The command-line analyzer
+    // uses cli_utils to find the SDK. Not sure why they're different.
+    String sdkProperty = getSdkProperty(resourceProvider);
+    if (sdkProperty == null) {
+      return null;
+    }
+    Folder sdkDirectory = resourceProvider.getFolder(sdkProperty);
+    if (!sdkDirectory.exists) {
+      return null;
+    }
+    return sdkDirectory;
+  }
+
+  static String getSdkProperty(ResourceProvider resourceProvider) {
+    String exec = io.Platform.resolvedExecutable;
+    if (exec.length == 0) {
+      return null;
+    }
+    pathos.Context pathContext = resourceProvider.pathContext;
+    // Might be "xcodebuild/ReleaseIA32/dart" with "sdk" sibling
+    String outDir = pathContext.dirname(pathContext.dirname(exec));
+    String sdkPath = pathContext.join(pathContext.dirname(outDir), "sdk");
+    if (resourceProvider.getFolder(sdkPath).exists) {
+      return sdkPath;
+    }
+    // probably be "dart-sdk/bin/dart"
+    return pathContext.dirname(pathContext.dirname(exec));
+  }
+}
+
+/**
+ * An object used to locate SDK extensions.
+ *
+ * Given a package map, it will check in each package's `lib` directory for the
+ * existence of a `_sdkext` file. This file must contain a JSON encoded map.
+ * Each key in the map is a `dart:` library name. Each value is a path (relative
+ * to the directory containing `_sdkext`) to a dart script for the given
+ * library. For example:
+ * ```
+ * {
+ *   "dart:sky": "../sdk_ext/dart_sky.dart"
+ * }
+ * ```
+ * If a key doesn't begin with `dart:` it is ignored.
+ */
+class SdkExtensionFinder {
+  /**
+   * The name of the extension file.
+   */
+  static const String SDK_EXT_NAME = '_sdkext';
+
+  /**
+   * The prefix required for all keys in an extension file that will not be
+   * ignored.
+   */
+  static const String DART_COLON_PREFIX = 'dart:';
+
+  /**
+   * A table mapping the names of extensions to the paths where those extensions
+   * can be found.
+   */
+  final Map<String, String> _urlMappings = <String, String>{};
+
+  /**
+   * The absolute paths of the extension files that contributed to the
+   * [_urlMappings].
+   */
+  final List<String> extensionFilePaths = <String>[];
+
+  /**
+   * Initialize a newly created finder to look in the packages in the given
+   * [packageMap] for SDK extension files.
+   */
+  SdkExtensionFinder(Map<String, List<Folder>> packageMap) {
+    if (packageMap == null) {
+      return;
+    }
+    packageMap.forEach(_processPackage);
+  }
+
+  /**
+   * Return a table mapping the names of extensions to the paths where those
+   * extensions can be found.
+   */
+  Map<String, String> get urlMappings =>
+      new Map<String, String>.from(_urlMappings);
+
+  /**
+   * Given a package [name] and a list of folders ([libDirs]), add any found sdk
+   * extensions.
+   */
+  void _processPackage(String name, List<Folder> libDirs) {
+    for (var libDir in libDirs) {
+      var sdkExt = _readDotSdkExt(libDir);
+      if (sdkExt != null) {
+        _processSdkExt(sdkExt, libDir);
+      }
+    }
+  }
+
+  /**
+   * Given the JSON for an SDK extension ([sdkExtJSON]) and a folder ([libDir]),
+   * setup the uri mapping.
+   */
+  void _processSdkExt(String sdkExtJSON, Folder libDir) {
+    var sdkExt;
+    try {
+      sdkExt = JSON.decode(sdkExtJSON);
+    } catch (e) {
+      return;
+    }
+    if ((sdkExt == null) || (sdkExt is! Map)) {
+      return;
+    }
+    bool contributed = false;
+    sdkExt.forEach((k, v) {
+      if (k is String && v is String && _processSdkExtension(libDir, k, v)) {
+        contributed = true;
+      }
+    });
+    if (contributed) {
+      extensionFilePaths.add(libDir.getChild(SDK_EXT_NAME).path);
+    }
+  }
+
+  /**
+   * Install the mapping from [name] to [libDir]/[file].
+   */
+  bool _processSdkExtension(Folder libDir, String name, String file) {
+    if (!name.startsWith(DART_COLON_PREFIX)) {
+      // SDK extensions must begin with 'dart:'.
+      return false;
+    }
+    _urlMappings[name] = libDir.canonicalizePath(file);
+    return true;
+  }
+
+  /**
+   * Read the contents of [libDir]/[SDK_EXT_NAME] as a string, or `null` if the
+   * file doesn't exist.
+   */
+  String _readDotSdkExt(Folder libDir) {
+    File file = libDir.getChild(SDK_EXT_NAME);
+    try {
+      return file.readAsStringSync();
+    } on FileSystemException {
+      // File can't be read.
+      return null;
+    }
+  }
+}
+
+/**
+ * An object used to read and parse the libraries file
+ * (dart-sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart) for information
+ * about the libraries in an SDK. The library information is represented as a
+ * Dart file containing a single top-level variable whose value is a const map.
+ * The keys of the map are the names of libraries defined in the SDK and the
+ * values in the map are info objects defining the library. For example, a
+ * subset of a typical SDK might have a libraries file that looks like the
+ * following:
+ *
+ *     final Map<String, LibraryInfo> LIBRARIES = const <LibraryInfo> {
+ *       // Used by VM applications
+ *       "builtin" : const LibraryInfo(
+ *         "builtin/builtin_runtime.dart",
+ *         category: "Server",
+ *         platforms: VM_PLATFORM),
+ *
+ *       "compiler" : const LibraryInfo(
+ *         "compiler/compiler.dart",
+ *         category: "Tools",
+ *         platforms: 0),
+ *     };
+ */
+class SdkLibrariesReader {
+  /**
+   * A flag indicating whether the dart2js path should be used when it is
+   * available.
+   */
+  final bool _useDart2jsPaths;
+
+  /**
+   * Initialize a newly created library reader to use the dart2js path if
+   * [_useDart2jsPaths] is `true`.
+   */
+  SdkLibrariesReader(this._useDart2jsPaths);
+
+  /**
+   * Return the library map read from the given [file], given that the content
+   * of the file is already known to be [libraryFileContents].
+   */
+  LibraryMap readFromFile(File file, String libraryFileContents) =>
+      readFromSource(file.createSource(), libraryFileContents);
+
+  /**
+   * Return the library map read from the given [source], given that the content
+   * of the file is already known to be [libraryFileContents].
+   */
+  LibraryMap readFromSource(Source source, String libraryFileContents) {
+    BooleanErrorListener errorListener = new BooleanErrorListener();
+    Scanner scanner = new Scanner(
+        source, new CharSequenceReader(libraryFileContents), errorListener);
+    Parser parser = new Parser(source, errorListener);
+    CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
+    SdkLibrariesReader_LibraryBuilder libraryBuilder =
+        new SdkLibrariesReader_LibraryBuilder(_useDart2jsPaths);
+    // If any syntactic errors were found then don't try to visit the AST
+    // structure.
+    if (!errorListener.errorReported) {
+      unit.accept(libraryBuilder);
+    }
+    return libraryBuilder.librariesMap;
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index dcb40d6..97150fc 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -156,7 +156,9 @@
   Object visitAssignmentExpression(AssignmentExpression node) {
     Token operator = node.operator;
     TokenType operatorType = operator.type;
-    if (operatorType != TokenType.EQ &&
+    if (operatorType != TokenType.AMPERSAND_AMPERSAND_EQ &&
+        operatorType != TokenType.BAR_BAR_EQ &&
+        operatorType != TokenType.EQ &&
         operatorType != TokenType.QUESTION_QUESTION_EQ) {
       operatorType = _operatorFromCompoundAssignment(operatorType);
       Expression leftHandSide = node.leftHandSide;
@@ -641,7 +643,9 @@
         }
         staticElement = _resolveElement(typeReference, methodName);
       } else {
-        DartType staticType = _getStaticType(target);
+        DartType staticType = _resolver.strongMode
+            ? _getStaticTypeOrFunctionType(target)
+            : _getStaticType(target);
         DartType propagatedType = _getPropagatedType(target);
         staticElement = _resolveInvokedElementWithTarget(
             target, staticType, methodName, isConditional);
@@ -698,21 +702,26 @@
     if (staticInvokeType != null) {
       List<ParameterElement> parameters =
           _computeCorrespondingParameters(argumentList, staticInvokeType);
-      if (parameters != null) {
-        argumentList.correspondingStaticParameters = parameters;
-      }
+      argumentList.correspondingStaticParameters = parameters;
     }
     if (propagatedInvokeType != null) {
       List<ParameterElement> parameters =
           _computeCorrespondingParameters(argumentList, propagatedInvokeType);
-      if (parameters != null) {
-        argumentList.correspondingPropagatedParameters = parameters;
-      }
+      argumentList.correspondingPropagatedParameters = parameters;
     }
     //
     // Then check for error conditions.
     //
     ErrorCode errorCode = _checkForInvocationError(target, true, staticElement);
+    if (errorCode != null &&
+        target is SimpleIdentifier &&
+        target.staticElement is PrefixElement) {
+      Identifier functionName =
+          new PrefixedIdentifierImpl.temp(target, methodName);
+      if (_resolver.nameScope.shouldIgnoreUndefined(functionName)) {
+        return null;
+      }
+    }
     bool generatedWithTypePropagation = false;
     if (_enableHints && errorCode == null && staticElement == null) {
       // The method lookup may have failed because there were multiple
@@ -752,8 +761,10 @@
         identical(errorCode,
             CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT) ||
         identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
-      _resolver.errorReporter
-          .reportErrorForNode(errorCode, methodName, [methodName.name]);
+      if (!_resolver.nameScope.shouldIgnoreUndefined(methodName)) {
+        _resolver.errorReporter
+            .reportErrorForNode(errorCode, methodName, [methodName.name]);
+      }
     } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
       String targetTypeName;
       if (target == null) {
@@ -819,6 +830,7 @@
         }
         return type;
       }
+
       DartType targetType = getSuperType(_getStaticType(target));
       String targetTypeName = targetType?.name;
       _resolver.errorReporter.reportErrorForNode(
@@ -896,6 +908,9 @@
                 "${node.identifier.name}=", node.identifier.offset - 1)));
         element = _resolver.nameScope.lookup(setterName, _definingLibrary);
       }
+      if (element == null && _resolver.nameScope.shouldIgnoreUndefined(node)) {
+        return null;
+      }
       if (element == null) {
         if (identifier.inSetterContext()) {
           _resolver.errorReporter.reportErrorForNode(
@@ -1100,19 +1115,23 @@
       if (_isConstructorReturnType(node)) {
         _resolver.errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
-      } else {
-        if (parent is Annotation) {
-          _resolver.errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.INVALID_ANNOTATION, parent);
-        } else if (element != null) {
-          _resolver.errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
-              node,
-              [element.name]);
-        } else {
-          _recordUndefinedNode(_resolver.enclosingClass,
-              StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
-        }
+      } else if (parent is Annotation) {
+        _resolver.errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.INVALID_ANNOTATION, parent);
+      } else if (element != null) {
+        _resolver.errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+            node,
+            [element.name]);
+      } else if (node.name == "await" && _resolver.enclosingFunction != null) {
+        _recordUndefinedNode(
+            _resolver.enclosingClass,
+            StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT,
+            node,
+            [_resolver.enclosingFunction.displayName]);
+      } else if (!_resolver.nameScope.shouldIgnoreUndefined(node)) {
+        _recordUndefinedNode(_resolver.enclosingClass,
+            StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
       }
     }
     node.staticElement = element;
@@ -1175,6 +1194,15 @@
       name.staticElement = element;
     }
     node.staticElement = element;
+    // TODO(brianwilkerson) Defer this check until we know there's an error (by
+    // in-lining _resolveArgumentsToFunction below).
+    ClassDeclaration declaration =
+        node.getAncestor((AstNode node) => node is ClassDeclaration);
+    Identifier superclassName = declaration.extendsClause?.superclass?.name;
+    if (superclassName != null &&
+        _resolver.nameScope.shouldIgnoreUndefined(superclassName)) {
+      return null;
+    }
     ArgumentList argumentList = node.argumentList;
     List<ParameterElement> parameters = _resolveArgumentsToFunction(
         isInConstConstructor, argumentList, element);
@@ -1210,7 +1238,7 @@
    * error code that should be reported, or `null` if no error should be
    * reported. The [target] is the target of the invocation, or `null` if there
    * was no target. The flag [useStaticContext] should be `true` if the
-   * invocation is in a static constant (does not have access to instance state.
+   * invocation is in a static constant (does not have access to instance state).
    */
   ErrorCode _checkForInvocationError(
       Expression target, bool useStaticContext, Element element) {
@@ -1281,6 +1309,10 @@
             targetType = _getBestType(target);
           }
           if (targetType == null) {
+            if (target is Identifier &&
+                _resolver.nameScope.shouldIgnoreUndefined(target)) {
+              return null;
+            }
             return StaticTypeWarningCode.UNDEFINED_FUNCTION;
           } else if (!targetType.isDynamic && !targetType.isBottom) {
             // Proxy-conditional warning, based on state of
@@ -1514,10 +1546,7 @@
    * type analysis.
    */
   DartType _getStaticType(Expression expression) {
-    if (expression is NullLiteral) {
-      return _resolver.typeProvider.bottomType;
-    }
-    DartType staticType = _resolveTypeParameter(expression.staticType);
+    DartType staticType = _getStaticTypeOrFunctionType(expression);
     if (staticType is FunctionType) {
       //
       // All function types are subtypes of 'Function', which is itself a
@@ -1528,6 +1557,13 @@
     return staticType;
   }
 
+  DartType _getStaticTypeOrFunctionType(Expression expression) {
+    if (expression is NullLiteral) {
+      return _resolver.typeProvider.bottomType;
+    }
+    return _resolveTypeParameter(expression.staticType);
+  }
+
   /**
    * Check for a generic method & apply type arguments if any were passed.
    */
@@ -2180,8 +2216,9 @@
    */
   Element _resolveInvokedElementWithTarget(Expression target,
       DartType targetType, SimpleIdentifier methodName, bool isConditional) {
+    String name = methodName.name;
     if (targetType is InterfaceType) {
-      Element element = _lookUpMethod(target, targetType, methodName.name);
+      Element element = _lookUpMethod(target, targetType, name);
       if (element == null) {
         //
         // If there's no method, then it's possible that 'm' is a getter that
@@ -2189,11 +2226,18 @@
         //
         // TODO (collinsn): need to add union type support here too, in the
         // style of [lookUpMethod].
-        element = _lookUpGetter(target, targetType, methodName.name);
+        element = _lookUpGetter(target, targetType, name);
       }
       return element;
+    } else if (targetType is FunctionType &&
+        _resolver.typeProvider.isObjectMethod(name)) {
+      return _resolver.typeProvider.objectType.element.getMethod(name);
     } else if (target is SimpleIdentifier) {
       Element targetElement = target.staticElement;
+      if (targetType is FunctionType &&
+          name == FunctionElement.CALL_METHOD_NAME) {
+        return targetElement;
+      }
       if (targetElement is PrefixElement) {
         if (isConditional) {
           _resolver.errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 67a931c7..b229169 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -12,8 +12,8 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
+import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/constant.dart';
@@ -629,14 +629,6 @@
    * so that the default contents will be returned.
    */
   void setContents(Source source, String contents);
-
-  /**
-   * Check the cache for any invalid entries (entries whose modification time
-   * does not match the modification time of the source associated with the
-   * entry). Invalid entries will be marked as invalid so that the source will
-   * be re-analyzed. Return `true` if at least one entry was invalid.
-   */
-  bool validateCacheConsistency();
 }
 
 /**
@@ -1078,6 +1070,12 @@
   bool get enableGenericMethods => null;
 
   /**
+   * Return `true` to enable the lazy compound assignment operators '&&=' and
+   * '||='.
+   */
+  bool get enableLazyAssignmentOperators;
+
+  /**
    * Return `true` to strictly follow the specification when generating
    * warnings on "call" methods (fixes dartbug.com/21938).
    */
@@ -1095,12 +1093,6 @@
   bool get enableTiming;
 
   /**
-   * Return `true` to enable trailing commas in parameter and argument lists
-   * (sdk#26647).
-   */
-  bool get enableTrailingCommas;
-
-  /**
    * A flag indicating whether finer grained dependencies should be used
    * instead of just source level dependencies.
    *
@@ -1199,6 +1191,11 @@
   static const int ENABLE_SUPER_MIXINS_FLAG = 0x40;
 
   /**
+   * The default list of non-nullable type names.
+   */
+  static const List<String> NONNULLABLE_TYPES = const <String>[];
+
+  /**
    * A predicate indicating whether analysis is to parse and analyze function
    * bodies.
    */
@@ -1233,6 +1230,9 @@
    */
   bool enableGenericMethods = false;
 
+  @override
+  bool enableLazyAssignmentOperators = false;
+
   /**
    * A flag indicating whether analysis is to strictly follow the specification
    * when generating warnings on "call" methods (fixes dartbug.com/21938).
@@ -1248,9 +1248,6 @@
   @override
   bool enableTiming = false;
 
-  @override
-  bool enableTrailingCommas = false;
-
   /**
    * A flag indicating whether errors, warnings and hints should be generated
    * for sources that are implicitly being analyzed.
@@ -1320,6 +1317,12 @@
    */
   bool implicitCasts = true;
 
+  /**
+   * A list of non-nullable type names, prefixed by the library URI they belong
+   * to, e.g., 'dart:core,int', 'dart:core,bool', 'file:///foo.dart,bar', etc.
+   */
+  List<String> nonnullableTypes = NONNULLABLE_TYPES;
+
   @override
   bool finerGrainedInvalidation = false;
 
@@ -1355,7 +1358,6 @@
     enableGenericMethods = options.enableGenericMethods;
     enableSuperMixins = options.enableSuperMixins;
     enableTiming = options.enableTiming;
-    enableTrailingCommas = options.enableTrailingCommas;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
     hint = options.hint;
@@ -1368,6 +1370,7 @@
     if (options is AnalysisOptionsImpl) {
       strongModeHints = options.strongModeHints;
       implicitCasts = options.implicitCasts;
+      nonnullableTypes = options.nonnullableTypes;
       implicitDynamic = options.implicitDynamic;
     }
     trackCacheDependencies = options.trackCacheDependencies;
@@ -1453,6 +1456,7 @@
       buffer.write(optionName);
       needsSeparator = true;
     }
+
     if (encoding & ENABLE_ASSERT_FLAG > 0) {
       add('assert');
     }
@@ -1553,6 +1557,58 @@
 }
 
 /**
+ * Statistics about cache consistency validation.
+ */
+class CacheConsistencyValidationStatistics {
+  /**
+   * Number of sources which were changed, but the context was not notified
+   * about it, so this fact was detected only during cache consistency
+   * validation.
+   */
+  int numOfChanged = 0;
+
+  /**
+   * Number of sources which stopped existing, but the context was not notified
+   * about it, so this fact was detected only during cache consistency
+   * validation.
+   */
+  int numOfRemoved = 0;
+
+  /**
+   * Reset all counters.
+   */
+  void reset() {
+    numOfChanged = 0;
+    numOfRemoved = 0;
+  }
+}
+
+/**
+ * Interface for cache consistency validation in an [InternalAnalysisContext].
+ */
+abstract class CacheConsistencyValidator {
+  /**
+   * Return sources for which the contexts needs to know modification times.
+   */
+  List<Source> getSourcesToComputeModificationTimes();
+
+  /**
+   * Notify the validator that modification [times] were computed for [sources].
+   * If a source does not exist, its modification time is `-1`.
+   *
+   * It's up to the validator and the context how to use this information,
+   * the list of sources the context has might have been changed since the
+   * previous invocation of [getSourcesToComputeModificationTimes].
+   *
+   * Check the cache for any invalid entries (entries whose modification time
+   * does not match the modification time of the source associated with the
+   * entry). Invalid entries will be marked as invalid so that the source will
+   * be re-analyzed. Return `true` if at least one entry was invalid.
+   */
+  bool sourceModificationTimesComputed(List<Source> sources, List<int> times);
+}
+
+/**
  * The possible states of cached data.
  */
 class CacheState extends Enum<CacheState> {
@@ -2037,6 +2093,11 @@
   AnalysisCache get analysisCache;
 
   /**
+   * The cache consistency validator for this context.
+   */
+  CacheConsistencyValidator get cacheConsistencyValidator;
+
+  /**
    * Allow the client to supply its own content cache.  This will take the
    * place of the content cache created by default, allowing clients to share
    * the content cache between contexts.
@@ -2332,6 +2393,13 @@
    * The [PerformanceTag] for time spent in summaries support.
    */
   static PerformanceTag summary = new PerformanceTag('summary');
+
+  /**
+   * Statistics about cache consistency validation.
+   */
+  static final CacheConsistencyValidationStatistics
+      cacheConsistencyValidationStatistics =
+      new CacheConsistencyValidationStatistics();
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index f8b369c..fd71772 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -2223,7 +2223,7 @@
    */
   static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION =
       const CompileTimeErrorCode('REFERENCED_BEFORE_DECLARATION',
-          "Local variables cannot be referenced before they are declared");
+          "Local variable '{0}' cannot be referenced before it is declared");
 
   /**
    * 12.8.1 Rethrow: It is a compile-time error if an expression of the form
@@ -2373,13 +2373,26 @@
    * Parameters:
    * 0: the URI pointing to a non-existent file
    *
-   * See [INVALID_URI].
+   * See [INVALID_URI], [URI_HAS_NOT_BEEN_GENERATED].
    */
   static const CompileTimeErrorCode URI_DOES_NOT_EXIST =
       const CompileTimeErrorCode(
           'URI_DOES_NOT_EXIST', "Target of URI does not exist: '{0}'");
 
   /**
+   * Just like [URI_DOES_NOT_EXIST], but used when the URI refers to a file that
+   * is expected to be generated.
+   *
+   * Parameters:
+   * 0: the URI pointing to a non-existent file
+   *
+   * See [INVALID_URI], [URI_DOES_NOT_EXIST].
+   */
+  static const CompileTimeErrorCode URI_HAS_NOT_BEEN_GENERATED =
+      const CompileTimeErrorCode('URI_HAS_NOT_BEEN_GENERATED',
+          "Target of URI has not been generated: '{0}'");
+
+  /**
    * 14.1 Imports: It is a compile-time error if <i>x</i> is not a compile-time
    * constant, or if <i>x</i> involves string interpolation.
    *
@@ -2698,6 +2711,7 @@
     HintCode.MISSING_RETURN,
     HintCode.NULL_AWARE_IN_CONDITION,
     HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER,
+    HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD,
     HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD,
     HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER,
     HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
@@ -2742,6 +2756,7 @@
     StaticTypeWarningCode.NON_BOOL_EXPRESSION,
     StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION,
     StaticTypeWarningCode.NON_BOOL_OPERAND,
+    StaticTypeWarningCode.NON_NULLABLE_FIELD_NOT_INITIALIZED,
     StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
     StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
     StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
@@ -2881,6 +2896,7 @@
     StrongModeCode.INVALID_SUPER_INVOCATION,
     StrongModeCode.NON_GROUND_TYPE_CHECK_INFO,
     StrongModeCode.STATIC_TYPE_ERROR,
+    StrongModeCode.UNSAFE_BLOCK_CLOSURE_INFERENCE,
 
     TodoCode.TODO,
 
@@ -2894,10 +2910,6 @@
     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.ASYNC_NOT_SUPPORTED,
     ParserErrorCode.BREAK_OUTSIDE_OF_LOOP,
@@ -3318,6 +3330,7 @@
       }
       return type.displayName;
     }
+
     if (_hasEqualTypeNames(arguments)) {
       int count = arguments.length;
       for (int i = 0; i < count; i++) {
@@ -3734,6 +3747,13 @@
       "Getter does not override an inherited getter");
 
   /**
+   * A field with the override annotation does not override a getter or setter.
+   */
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD = const HintCode(
+      'OVERRIDE_ON_NON_OVERRIDING_FIELD',
+      "Field does not override an inherited getter or setter");
+
+  /**
    * A method with the override annotation does not override an existing method.
    */
   static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = const HintCode(
@@ -4276,6 +4296,13 @@
           "The operands of the '{0}' operator must be assignable to 'bool'");
 
   /**
+   *
+   */
+  static const StaticTypeWarningCode NON_NULLABLE_FIELD_NOT_INITIALIZED =
+      const StaticTypeWarningCode('NON_NULLABLE_FIELD_NOT_INITIALIZED',
+          "Variable '{0}' of non-nullable type '{1}' must be initialized");
+
+  /**
    * 15.8 Parameterized Types: It is a static type warning if <i>A<sub>i</sub>,
    * 1 &lt;= i &lt;= n</i> does not denote a type in the enclosing lexical scope.
    */
@@ -5324,6 +5351,26 @@
           false);
 
   /**
+   * 17.9 Switch: It is a static warning if all of the following conditions
+   * hold:
+   * * The switch statement does not have a 'default' clause.
+   * * The static type of <i>e</i> is an enumerated typed with elements
+   *   <i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>.
+   * * The sets {<i>e<sub>1</sub></i>, &hellip;, <i>e<sub>k</sub></i>} and
+   *   {<i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>} are not the
+   *   same.
+   *
+   * Parameters:
+   * 0: the name of the constant that is missing
+   */
+  static const StaticWarningCode MISSING_ENUM_CONSTANT_IN_SWITCH =
+      const StaticWarningCode(
+          'MISSING_ENUM_CONSTANT_IN_SWITCH',
+          "Missing case clause for '{0}'",
+          "Add a case clause for the missing constant or add a default clause.",
+          false);
+
+  /**
    * 13.12 Return: It is a static warning if a function contains both one or
    * more return statements of the form <i>return;</i> and one or more return
    * statements of the form <i>return e;</i>.
@@ -5760,6 +5807,13 @@
       const StaticWarningCode('UNDEFINED_IDENTIFIER', "Undefined name '{0}'");
 
   /**
+   * If the identifier is 'await', be helpful about it.
+   */
+  static const StaticWarningCode UNDEFINED_IDENTIFIER_AWAIT =
+      const StaticWarningCode('UNDEFINED_IDENTIFIER_AWAIT',
+          "Undefined name 'await'; did you mean to add the 'async' marker to '{0}'?");
+
+  /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>,
    * <i>1<=i<=l</i>, must have a corresponding named parameter in the set
    * {<i>p<sub>n+1</sub></i> &hellip; <i>p<sub>n+k</sub></i>} or a static
@@ -5840,26 +5894,6 @@
           "The return type of the getter must not be 'void'", null, false);
 
   /**
-   * 17.9 Switch: It is a static warning if all of the following conditions
-   * hold:
-   * * The switch statement does not have a 'default' clause.
-   * * The static type of <i>e</i> is an enumerated typed with elements
-   *   <i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>.
-   * * The sets {<i>e<sub>1</sub></i>, &hellip;, <i>e<sub>k</sub></i>} and
-   *   {<i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>} are not the
-   *   same.
-   *
-   * Parameters:
-   * 0: the name of the constant that is missing
-   */
-  static const StaticWarningCode MISSING_ENUM_CONSTANT_IN_SWITCH =
-      const StaticWarningCode(
-          'MISSING_ENUM_CONSTANT_IN_SWITCH',
-          "Missing case clause for '{0}'",
-          "Add a case clause for the missing constant or add a default clause.",
-          false);
-
-  /**
    * A flag indicating whether this warning is an error when running with strong
    * mode enabled.
    */
@@ -5894,6 +5928,11 @@
   static const String _implicitCastMessage =
       'Unsound implicit cast from {0} to {1}';
 
+  static const String _unsafeBlockClosureInferenceMessage =
+      'Unsafe use of block closure in a type-inferred variable outside a '
+      'function body.  Workaround: add a type annotation for `{0}`.  See '
+      'dartbug.com/26947';
+
   static const String _typeCheckMessage =
       'Type check failed: {0} is not of type {1}';
 
@@ -6041,6 +6080,12 @@
       "Missing type arguments for calling generic function type '{0}'"
       "$_implicitDynamicTip");
 
+  static const StrongModeCode UNSAFE_BLOCK_CLOSURE_INFERENCE =
+      const StrongModeCode(
+          ErrorType.STATIC_WARNING,
+          'UNSAFE_BLOCK_CLOSURE_INFERENCE',
+          _unsafeBlockClosureInferenceMessage);
+
   @override
   final ErrorType type;
 
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 6d4177b..a9f2f6c 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -13,7 +13,6 @@
 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/ast/utilities.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';
@@ -498,8 +497,10 @@
       _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>();
       for (FieldElement fieldElement in fieldElements) {
         if (!fieldElement.isSynthetic) {
-          _initialFieldElementsMap[fieldElement] = fieldElement.initializer ==
-              null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION;
+          _initialFieldElementsMap[fieldElement] =
+              fieldElement.initializer == null
+                  ? INIT_STATE.NOT_INIT
+                  : INIT_STATE.INIT_IN_DECLARATION;
         }
       }
     }
@@ -868,7 +869,9 @@
           _checkForConstWithNonConst(node);
           _checkForConstWithUndefinedConstructor(
               node, constructorName, typeName);
-          _checkForConstWithTypeParameters(typeName);
+          if (!_options.strongMode) {
+            _checkForConstWithTypeParameters(typeName);
+          }
           _checkForConstDeferredClass(node, constructorName, typeName);
         } else {
           _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
@@ -891,9 +894,9 @@
   Object visitListLiteral(ListLiteral node) {
     TypeArgumentList typeArguments = node.typeArguments;
     if (typeArguments != null) {
-      if (node.constKeyword != null) {
+      if (!_options.strongMode && node.constKeyword != null) {
         NodeList<TypeName> arguments = typeArguments.arguments;
-        if (arguments.length != 0) {
+        if (arguments.isNotEmpty) {
           _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
               CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
         }
@@ -910,7 +913,7 @@
     TypeArgumentList typeArguments = node.typeArguments;
     if (typeArguments != null) {
       NodeList<TypeName> arguments = typeArguments.arguments;
-      if (arguments.length != 0) {
+      if (!_options.strongMode && arguments.isNotEmpty) {
         if (node.constKeyword != null) {
           _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
               CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
@@ -1304,6 +1307,7 @@
         }
         return parameter;
       }
+
       FormalParameter parameter = baseParameter(formalParameter);
       if (parameter is FieldFormalParameter) {
         FieldElement fieldElement =
@@ -1412,8 +1416,8 @@
   }
 
   /**
-   * Check the given [executableElement] against override-error codes. The
-   * [overriddenExecutable] is the element that the executable element is
+   * Check the given [derivedElement] against override-error codes. The
+   * [baseElement] is the element that the executable element is
    * overriding. The [parameters] is the parameters of the executable element.
    * The [errorNameTarget] is the node to report problems on.
    *
@@ -1430,25 +1434,24 @@
    * [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES].
    */
   bool _checkForAllInvalidOverrideErrorCodes(
-      ExecutableElement executableElement,
-      ExecutableElement overriddenExecutable,
+      ExecutableElement derivedElement,
+      ExecutableElement baseElement,
       List<ParameterElement> parameters,
       List<AstNode> parameterLocations,
       SimpleIdentifier errorNameTarget) {
     bool isGetter = false;
     bool isSetter = false;
-    if (executableElement is PropertyAccessorElement) {
-      isGetter = executableElement.isGetter;
-      isSetter = executableElement.isSetter;
+    if (derivedElement is PropertyAccessorElement) {
+      isGetter = derivedElement.isGetter;
+      isSetter = derivedElement.isSetter;
     }
-    String executableElementName = executableElement.name;
-    FunctionType overridingFT = executableElement.type;
-    FunctionType overriddenFT = overriddenExecutable.type;
+    String executableElementName = derivedElement.name;
+    FunctionType derivedFT = derivedElement.type;
+    FunctionType baseFT = baseElement.type;
     InterfaceType enclosingType = _enclosingClass.type;
-    overriddenFT =
-        _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(
-            overriddenFT, executableElementName, enclosingType);
-    if (overridingFT == null || overriddenFT == null) {
+    baseFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(
+        baseFT, executableElementName, enclosingType);
+    if (derivedFT == null || baseFT == null) {
       return false;
     }
 
@@ -1456,12 +1459,12 @@
     // 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) {
-        overridingFT = _typeSystem.instantiateToBounds(overridingFT);
+    if (!derivedFT.typeFormals.isEmpty) {
+      if (baseFT.typeFormals.isEmpty) {
+        derivedFT = _typeSystem.instantiateToBounds(derivedFT);
       } else {
-        List<TypeParameterElement> params1 = overridingFT.typeFormals;
-        List<TypeParameterElement> params2 = overriddenFT.typeFormals;
+        List<TypeParameterElement> params1 = derivedFT.typeFormals;
+        List<TypeParameterElement> params2 = baseFT.typeFormals;
         int count = params1.length;
         if (params2.length != count) {
           _errorReporter.reportErrorForNode(
@@ -1469,7 +1472,7 @@
               errorNameTarget, [
             count,
             params2.length,
-            overriddenExecutable.enclosingElement.displayName
+            baseElement.enclosingElement.displayName
           ]);
           return true;
         }
@@ -1505,74 +1508,73 @@
               p1.bound,
               p2.displayName,
               p2.bound,
-              overriddenExecutable.enclosingElement.displayName
+              baseElement.enclosingElement.displayName
             ]);
             return true;
           }
         }
         // Proceed with the rest of the checks, using instantiated types.
-        overridingFT = overridingFT.instantiate(variablesFresh);
-        overriddenFT = overriddenFT.instantiate(variablesFresh);
+        derivedFT = derivedFT.instantiate(variablesFresh);
+        baseFT = baseFT.instantiate(variablesFresh);
       }
     }
 
-    DartType overridingFTReturnType = overridingFT.returnType;
-    DartType overriddenFTReturnType = overriddenFT.returnType;
-    List<DartType> overridingNormalPT = overridingFT.normalParameterTypes;
-    List<DartType> overriddenNormalPT = overriddenFT.normalParameterTypes;
-    List<DartType> overridingPositionalPT = overridingFT.optionalParameterTypes;
-    List<DartType> overriddenPositionalPT = overriddenFT.optionalParameterTypes;
-    Map<String, DartType> overridingNamedPT = overridingFT.namedParameterTypes;
-    Map<String, DartType> overriddenNamedPT = overriddenFT.namedParameterTypes;
+    DartType derivedFTReturnType = derivedFT.returnType;
+    DartType baseFTReturnType = baseFT.returnType;
+    List<DartType> derivedNormalPT = derivedFT.normalParameterTypes;
+    List<DartType> baseNormalPT = baseFT.normalParameterTypes;
+    List<DartType> derivedPositionalPT = derivedFT.optionalParameterTypes;
+    List<DartType> basePositionalPT = baseFT.optionalParameterTypes;
+    Map<String, DartType> derivedNamedPT = derivedFT.namedParameterTypes;
+    Map<String, DartType> baseNamedPT = baseFT.namedParameterTypes;
     // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and
     // CTEC.INVALID_OVERRIDE_NAMED
-    if (overridingNormalPT.length > overriddenNormalPT.length) {
+    if (derivedNormalPT.length > baseNormalPT.length) {
       _errorReporter.reportErrorForNode(
           StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
-        overriddenNormalPT.length,
-        overriddenExecutable,
-        overriddenExecutable.enclosingElement.displayName
+        baseNormalPT.length,
+        baseElement,
+        baseElement.enclosingElement.displayName
       ]);
       return true;
     }
-    if (overridingNormalPT.length + overridingPositionalPT.length <
-        overriddenPositionalPT.length + overriddenNormalPT.length) {
+    if (derivedNormalPT.length + derivedPositionalPT.length <
+        basePositionalPT.length + baseNormalPT.length) {
       _errorReporter.reportErrorForNode(
           StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
-        overriddenPositionalPT.length + overriddenNormalPT.length,
-        overriddenExecutable,
-        overriddenExecutable.enclosingElement.displayName
+        basePositionalPT.length + baseNormalPT.length,
+        baseElement,
+        baseElement.enclosingElement.displayName
       ]);
       return true;
     }
     // For each named parameter in the overridden method, verify that there is
     // the same name in the overriding method.
-    for (String overriddenParamName in overriddenNamedPT.keys) {
-      if (!overridingNamedPT.containsKey(overriddenParamName)) {
+    for (String overriddenParamName in baseNamedPT.keys) {
+      if (!derivedNamedPT.containsKey(overriddenParamName)) {
         // The overridden method expected the overriding method to have
         // overridingParamName, but it does not.
         _errorReporter.reportErrorForNode(
             StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
           overriddenParamName,
-          overriddenExecutable,
-          overriddenExecutable.enclosingElement.displayName
+          baseElement,
+          baseElement.enclosingElement.displayName
         ]);
         return true;
       }
     }
     // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE
-    if (overriddenFTReturnType != VoidTypeImpl.instance &&
-        !_typeSystem.isAssignableTo(
-            overridingFTReturnType, overriddenFTReturnType)) {
+    if (baseFTReturnType != VoidTypeImpl.instance &&
+        !_typeSystem.isAssignableTo(derivedFTReturnType, baseFTReturnType)) {
       _errorReporter.reportTypeErrorForNode(
           !isGetter
               ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE
               : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
           errorNameTarget,
           [
-            overridingFTReturnType,
-            overriddenFTReturnType,
-            overriddenExecutable.enclosingElement.displayName
+            derivedFTReturnType,
+            baseFTReturnType,
+            baseElement.enclosingElement.displayName
           ]);
       return true;
     }
@@ -1581,33 +1583,32 @@
       return false;
     }
     int parameterIndex = 0;
-    for (int i = 0; i < overridingNormalPT.length; i++) {
-      if (!_typeSystem.isAssignableTo(
-          overridingNormalPT[i], overriddenNormalPT[i])) {
+    for (int i = 0; i < derivedNormalPT.length; i++) {
+      if (!_typeSystem.isAssignableTo(baseNormalPT[i], derivedNormalPT[i])) {
         _errorReporter.reportTypeErrorForNode(
             !isSetter
                 ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
                 : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE,
             parameterLocations[parameterIndex],
             [
-              overridingNormalPT[i],
-              overriddenNormalPT[i],
-              overriddenExecutable.enclosingElement.displayName
+              derivedNormalPT[i],
+              baseNormalPT[i],
+              baseElement.enclosingElement.displayName
             ]);
         return true;
       }
       parameterIndex++;
     }
     // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
-    for (int i = 0; i < overriddenPositionalPT.length; i++) {
+    for (int i = 0; i < basePositionalPT.length; i++) {
       if (!_typeSystem.isAssignableTo(
-          overridingPositionalPT[i], overriddenPositionalPT[i])) {
+          basePositionalPT[i], derivedPositionalPT[i])) {
         _errorReporter.reportTypeErrorForNode(
             StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE,
             parameterLocations[parameterIndex], [
-          overridingPositionalPT[i],
-          overriddenPositionalPT[i],
-          overriddenExecutable.enclosingElement.displayName
+          derivedPositionalPT[i],
+          basePositionalPT[i],
+          baseElement.enclosingElement.displayName
         ]);
         return true;
       }
@@ -1615,15 +1616,15 @@
     }
     // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE &
     // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
-    for (String overriddenName in overriddenNamedPT.keys) {
-      DartType overridingType = overridingNamedPT[overriddenName];
-      if (overridingType == null) {
+    for (String overriddenName in baseNamedPT.keys) {
+      DartType derivedType = derivedNamedPT[overriddenName];
+      if (derivedType == null) {
         // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been
         // created above if this could be reached.
         continue;
       }
-      DartType overriddenType = overriddenNamedPT[overriddenName];
-      if (!_typeSystem.isAssignableTo(overriddenType, overridingType)) {
+      DartType baseType = baseNamedPT[overriddenName];
+      if (!_typeSystem.isAssignableTo(baseType, derivedType)) {
         // lookup the parameter for the error to select
         ParameterElement parameterToSelect = null;
         AstNode parameterLocationToSelect = null;
@@ -1640,9 +1641,9 @@
           _errorReporter.reportTypeErrorForNode(
               StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE,
               parameterLocationToSelect, [
-            overridingType,
-            overriddenType,
-            overriddenExecutable.enclosingElement.displayName
+            derivedType,
+            baseType,
+            baseElement.enclosingElement.displayName
           ]);
           return true;
         }
@@ -1660,7 +1661,7 @@
     List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
     List<ParameterElementImpl> overriddenParameterElts =
         new List<ParameterElementImpl>();
-    List<ParameterElement> overriddenPEs = overriddenExecutable.parameters;
+    List<ParameterElement> overriddenPEs = baseElement.parameters;
     for (int i = 0; i < parameters.length; i++) {
       ParameterElement parameter = parameters[i];
       if (parameter.parameterKind.isOptional) {
@@ -1713,8 +1714,8 @@
                         .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
                     formalParameters[i],
                     [
-                      overriddenExecutable.enclosingElement.displayName,
-                      overriddenExecutable.displayName,
+                      baseElement.enclosingElement.displayName,
+                      baseElement.displayName,
                       parameterName
                     ]);
                 foundError = true;
@@ -1752,8 +1753,8 @@
                     .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
                 formalParameters[i],
                 [
-                  overriddenExecutable.enclosingElement.displayName,
-                  overriddenExecutable.displayName
+                  baseElement.enclosingElement.displayName,
+                  baseElement.displayName
                 ]);
             foundError = true;
           }
@@ -2201,6 +2202,7 @@
     Element toVariable(Element element) {
       return element is PropertyAccessorElement ? element.variable : element;
     }
+
     element = toVariable(element);
     if (element is VariableElement) {
       if (element.isConst) {
@@ -3399,29 +3401,34 @@
    */
   void _checkForFieldInitializingFormalRedirectingConstructor(
       FieldFormalParameter parameter) {
-    ConstructorDeclaration constructor =
-        parameter.getAncestor((node) => node is ConstructorDeclaration);
-    if (constructor == null) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
-          parameter);
-      return;
+    // prepare the node that should be a ConstructorDeclaration
+    AstNode formalParameterList = parameter.parent;
+    if (formalParameterList is! FormalParameterList) {
+      formalParameterList = formalParameterList?.parent;
     }
-    // constructor cannot be a factory
-    if (constructor.factoryKeyword != null) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
-          parameter);
-      return;
-    }
-    // constructor cannot have a redirection
-    for (ConstructorInitializer initializer in constructor.initializers) {
-      if (initializer is RedirectingConstructorInvocation) {
+    AstNode constructor = formalParameterList?.parent;
+    // now check whether the node is actually a ConstructorDeclaration
+    if (constructor is ConstructorDeclaration) {
+      // constructor cannot be a factory
+      if (constructor.factoryKeyword != null) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
+            CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
             parameter);
         return;
       }
+      // constructor cannot have a redirection
+      for (ConstructorInitializer initializer in constructor.initializers) {
+        if (initializer is RedirectingConstructorInvocation) {
+          _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
+              parameter);
+          return;
+        }
+      }
+    } else {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+          parameter);
     }
   }
 
@@ -4065,18 +4072,8 @@
     if (lhs == null) {
       return;
     }
-    VariableElement leftVariableElement = getVariableElement(lhs);
-    DartType leftType = (leftVariableElement == null)
-        ? getStaticType(lhs)
-        : leftVariableElement.type;
-    MethodElement invokedMethod = assignment.staticElement;
-    if (invokedMethod == null) {
-      return;
-    }
-    DartType rightType = invokedMethod.type.returnType;
-    if (leftType == null || rightType == null) {
-      return;
-    }
+    DartType leftType = getStaticType(lhs);
+    DartType rightType = getStaticType(assignment);
     if (!_typeSystem.isAssignableTo(rightType, leftType)) {
       _errorReporter.reportTypeErrorForNode(
           StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]);
@@ -4398,10 +4395,9 @@
 
   void _checkForMissingJSLibAnnotation(Annotation node) {
     if (node.elementAnnotation?.isJS ?? false) {
-      Element element = ElementLocator.locate(node.parent);
-      if (element?.library?.isJS != true) {
+      if (_currentLibrary.isJS != true) {
         _errorReporter.reportErrorForNode(
-            HintCode.MISSING_JS_LIB_ANNOTATION, node, [element.name]);
+            HintCode.MISSING_JS_LIB_ANNOTATION, node);
       }
     }
   }
@@ -5818,6 +5814,7 @@
           argument,
           [argumentType, parameterType]);
     }
+
     if (element is FunctionTypedElement) {
       _checkTypeArgumentsAgainstBounds(
           element.typeParameters, typeArguments, targetType, reportError);
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 77907db..9e2a1d4 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -95,6 +95,7 @@
         isByTask(BuildSourceExportClosureTask.DESCRIPTOR) ||
         isByTask(ComputeConstantDependenciesTask.DESCRIPTOR) ||
         isByTask(ComputeConstantValueTask.DESCRIPTOR) ||
+        isByTask(ComputeInferableStaticVariableDependenciesTask.DESCRIPTOR) ||
         isByTask(ComputeLibraryCycleTask.DESCRIPTOR) ||
         isByTask(ComputePropagableVariableDependenciesTask.DESCRIPTOR) ||
         isByTask(DartErrorsTask.DESCRIPTOR) ||
@@ -106,6 +107,7 @@
         isByTask(GenerateHintsTask.DESCRIPTOR) ||
         isByTask(InferInstanceMembersInUnitTask.DESCRIPTOR) ||
         isByTask(InferStaticVariableTypesInUnitTask.DESCRIPTOR) ||
+        isByTask(InferStaticVariableTypeTask.DESCRIPTOR) ||
         isByTask(LibraryErrorsReadyTask.DESCRIPTOR) ||
         isByTask(LibraryUnitErrorsTask.DESCRIPTOR) ||
         isByTask(ParseDartTask.DESCRIPTOR) ||
@@ -295,9 +297,9 @@
     // compute values
     {
       CompilationUnit unit = node.getAncestor((n) => n is CompilationUnit);
-      ConstantValueComputer computer = new ConstantValueComputer(_context,
+      ConstantValueComputer computer = new ConstantValueComputer(
           _typeProvider, _context.declaredVariables, null, _typeSystem);
-      computer.add(unit, _source, _librarySource);
+      computer.add(unit);
       computer.computeValues();
     }
     // validate
@@ -383,6 +385,7 @@
     _shiftErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS);
     _shiftErrors_NEW(RESOLVE_TYPE_BOUNDS_ERRORS);
     _shiftErrors_NEW(RESOLVE_UNIT_ERRORS);
+    _shiftErrors_NEW(STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT);
     _shiftErrors_NEW(STRONG_MODE_ERRORS);
     _shiftErrors_NEW(VARIABLE_REFERENCE_ERRORS);
     _shiftErrors_NEW(VERIFY_ERRORS);
@@ -567,41 +570,52 @@
         int endOffsetOld = math.max(firstOffsetOld, lastOffsetOld);
         int beginOffsetNew = math.min(firstOffsetNew, lastOffsetNew);
         int endOffsetNew = math.max(firstOffsetNew, lastOffsetNew);
-        // check for a whitespace only change
-        if (identical(lastPair.oldToken, firstPair.oldToken) &&
-            identical(lastPair.newToken, firstPair.newToken)) {
+        // A pure whitespace change.
+        if (identical(firstPair.oldToken, lastPair.oldToken) &&
+            identical(firstPair.newToken, lastPair.newToken) &&
+            firstPair.kind == _TokenDifferenceKind.OFFSET) {
           _updateOffset = beginOffsetOld - 1;
           _updateEndOld = endOffsetOld;
           _updateEndNew = endOffsetNew;
           _updateDelta = newUnit.length - _oldUnit.length;
-          // A Dart documentation comment change.
-          if (firstPair.kind == _TokenDifferenceKind.COMMENT_DOC) {
-            bool success = _resolveCommentDoc(newUnit, firstPair);
+          logger.log('Whitespace change.');
+          _shiftTokens(firstPair.oldToken, true);
+          IncrementalResolver incrementalResolver = new IncrementalResolver(
+              _cache,
+              _sourceEntry,
+              _unitEntry,
+              _unitElement,
+              _updateOffset,
+              _updateEndOld,
+              _updateEndNew);
+          incrementalResolver._updateCache();
+          incrementalResolver._updateElementNameOffsets();
+          incrementalResolver._shiftEntryErrors();
+          _updateEntry();
+          logger.log('Success.');
+          return true;
+        }
+        // A Dart documentation comment change.
+        {
+          Token firstOldToken = firstPair.oldToken;
+          Token firstNewToken = firstPair.newToken;
+          Token lastOldToken = lastPair.oldToken;
+          Token lastNewToken = lastPair.newToken;
+          if (firstOldToken is DocumentationCommentToken &&
+              firstNewToken is DocumentationCommentToken &&
+              lastOldToken is DocumentationCommentToken &&
+              lastNewToken is DocumentationCommentToken &&
+              identical(firstOldToken.parent, lastOldToken.parent) &&
+              identical(firstNewToken.parent, lastNewToken.parent)) {
+            _updateOffset = beginOffsetOld;
+            _updateEndOld = firstOldToken.parent.offset;
+            _updateEndNew = firstNewToken.parent.offset;
+            _updateDelta = newUnit.length - _oldUnit.length;
+            bool success =
+                _resolveCommentDoc(newUnit, firstOldToken, firstNewToken);
             logger.log('Documentation comment resolved: $success');
             return success;
           }
-          // A pure whitespace change.
-          if (firstPair.kind == _TokenDifferenceKind.OFFSET) {
-            logger.log('Whitespace change.');
-            _shiftTokens(firstPair.oldToken);
-            {
-              IncrementalResolver incrementalResolver = new IncrementalResolver(
-                  _cache,
-                  _sourceEntry,
-                  _unitEntry,
-                  _unitElement,
-                  _updateOffset,
-                  _updateEndOld,
-                  _updateEndNew);
-              incrementalResolver._updateCache();
-              incrementalResolver._updateElementNameOffsets();
-              incrementalResolver._shiftEntryErrors();
-            }
-            _updateEntry();
-            logger.log('Success.');
-            return true;
-          }
-          // fall-through, end-of-line comment
         }
         // Find nodes covering the "old" and "new" token ranges.
         AstNode oldNode =
@@ -675,14 +689,6 @@
             logger.log('Failure: no enclosing function body or executable.');
             return false;
           }
-          // fail if a comment change outside the bodies
-          if (firstPair.kind == _TokenDifferenceKind.COMMENT) {
-            if (beginOffsetOld <= oldNode.offset ||
-                beginOffsetNew <= newNode.offset) {
-              logger.log('Failure: comment outside a function body.');
-              return false;
-            }
-          }
         }
         logger.log(() => 'oldNode: $oldNode');
         logger.log(() => 'newNode: $newNode');
@@ -740,6 +746,7 @@
       RecordingErrorListener errorListener = new RecordingErrorListener();
       Parser parser = new Parser(_unitSource, errorListener);
       AnalysisOptions options = _unitElement.context.analysisOptions;
+      parser.parseGenericMethodComments = options.strongMode;
       parser.parseGenericMethods = options.enableGenericMethods;
       CompilationUnit unit = parser.parseCompilationUnit(token);
       _newParseErrors = errorListener.errors;
@@ -753,16 +760,13 @@
    * Attempts to resolve a documentation comment change.
    * Returns `true` if success.
    */
-  bool _resolveCommentDoc(CompilationUnit newUnit, _TokenPair firstPair) {
-    Token oldToken = firstPair.oldToken;
-    Token newToken = firstPair.newToken;
-    CommentToken oldComments = oldToken.precedingComments;
-    CommentToken newComments = newToken.precedingComments;
-    if (oldComments == null || newComments == null) {
+  bool _resolveCommentDoc(
+      CompilationUnit newUnit, CommentToken oldToken, CommentToken newToken) {
+    if (oldToken == null || newToken == null) {
       return false;
     }
     // find nodes
-    int offset = oldComments.offset;
+    int offset = oldToken.offset;
     logger.log('offset: $offset');
     AstNode oldNode = _findNodeCovering(_oldUnit, offset, offset);
     AstNode newNode = _findNodeCovering(newUnit, offset, offset);
@@ -773,10 +777,9 @@
     Comment newComment = newNode;
     logger.log('oldComment.beginToken: ${oldComment.beginToken}');
     logger.log('newComment.beginToken: ${newComment.beginToken}');
-    _updateOffset = oldToken.offset - 1;
     // update token references
-    _shiftTokens(firstPair.oldToken);
-    _setPrecedingComments(oldToken, newComment.tokens.first);
+    _shiftTokens(oldToken.parent);
+    _setPrecedingComments(oldToken.parent, newComment.tokens.first);
     // replace node
     NodeReplacer.replace(oldComment, newComment);
     // update elements
@@ -798,16 +801,21 @@
     {
       AstNode parent = newComment.parent;
       if (parent is AnnotatedNode) {
+        setElementDocumentationForVariables(VariableDeclarationList list) {
+          for (VariableDeclaration variable in list.variables) {
+            Element variableElement = variable.element;
+            if (variableElement is ElementImpl) {
+              setElementDocumentationComment(variableElement, parent);
+            }
+          }
+        }
         Element parentElement = ElementLocator.locate(newComment.parent);
         if (parentElement is ElementImpl) {
           setElementDocumentationComment(parentElement, parent);
-        } else if (parentElement == null && parent is FieldDeclaration) {
-          for (VariableDeclaration field in parent.fields.variables) {
-            Element fieldElement = field.element;
-            if (fieldElement is ElementImpl) {
-              setElementDocumentationComment(fieldElement, parent);
-            }
-          }
+        } else if (parent is FieldDeclaration) {
+          setElementDocumentationForVariables(parent.fields);
+        } else if (parent is TopLevelVariableDeclaration) {
+          setElementDocumentationForVariables(parent.variables);
         }
       }
     }
@@ -819,6 +827,8 @@
     RecordingErrorListener errorListener = new RecordingErrorListener();
     CharSequenceReader reader = new CharSequenceReader(code);
     Scanner scanner = new Scanner(_unitSource, reader, errorListener);
+    AnalysisOptions options = _unitElement.context.analysisOptions;
+    scanner.scanGenericMethodComments = options.strongMode;
     Token token = scanner.tokenize();
     _newLineInfo = new LineInfo(scanner.lineStarts);
     _newScanErrors = errorListener.errors;
@@ -843,8 +853,11 @@
     }
   }
 
-  void _shiftTokens(Token token) {
+  void _shiftTokens(Token token, [bool goUpComment = false]) {
     while (token != null) {
+      if (goUpComment && token is CommentToken) {
+        token = (token as CommentToken).parent;
+      }
       if (token.offset > _updateOffset) {
         token.offset += _updateDelta;
       }
@@ -870,6 +883,10 @@
     // parse results
     _sourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
     _sourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
+    // referenced names
+    ReferencedNames referencedNames = new ReferencedNames(_unitSource);
+    new ReferencedNamesBuilder(referencedNames).build(_oldUnit);
+    _sourceEntry.setValueIncremental(REFERENCED_NAMES, referencedNames, false);
   }
 
   /**
@@ -884,29 +901,21 @@
   }
 
   static _TokenDifferenceKind _compareToken(
-      Token oldToken, Token newToken, int delta, bool forComment) {
-    while (true) {
-      if (oldToken == null && newToken == null) {
-        return null;
-      }
-      if (oldToken == null || newToken == null) {
-        return _TokenDifferenceKind.CONTENT;
-      }
-      if (oldToken.type != newToken.type) {
-        return _TokenDifferenceKind.CONTENT;
-      }
-      if (oldToken.lexeme != newToken.lexeme) {
-        return _TokenDifferenceKind.CONTENT;
-      }
-      if (newToken.offset - oldToken.offset != delta) {
-        return _TokenDifferenceKind.OFFSET;
-      }
-      // continue if comment tokens are being checked
-      if (!forComment) {
-        break;
-      }
-      oldToken = oldToken.next;
-      newToken = newToken.next;
+      Token oldToken, Token newToken, int delta) {
+    if (oldToken == null && newToken == null) {
+      return null;
+    }
+    if (oldToken == null || newToken == null) {
+      return _TokenDifferenceKind.CONTENT;
+    }
+    if (oldToken.type != newToken.type) {
+      return _TokenDifferenceKind.CONTENT;
+    }
+    if (oldToken.lexeme != newToken.lexeme) {
+      return _TokenDifferenceKind.CONTENT;
+    }
+    if (newToken.offset - oldToken.offset != delta) {
+      return _TokenDifferenceKind.OFFSET;
     }
     return null;
   }
@@ -920,18 +929,22 @@
       {
         Token oldComment = oldToken.precedingComments;
         Token newComment = newToken.precedingComments;
-        if (_compareToken(oldComment, newComment, 0, true) != null) {
-          _TokenDifferenceKind diffKind = _TokenDifferenceKind.COMMENT;
-          if (oldComment is DocumentationCommentToken &&
-              newComment is DocumentationCommentToken) {
-            diffKind = _TokenDifferenceKind.COMMENT_DOC;
+        while (true) {
+          _TokenDifferenceKind diffKind =
+              _compareToken(oldComment, newComment, 0);
+          if (diffKind != null) {
+            return new _TokenPair(
+                diffKind, oldComment ?? oldToken, newComment ?? newToken);
           }
-          return new _TokenPair(diffKind, oldToken, newToken);
+          if (oldComment == null && newComment == null) {
+            break;
+          }
+          oldComment = oldComment.next;
+          newComment = newComment.next;
         }
       }
       // compare tokens
-      _TokenDifferenceKind diffKind =
-          _compareToken(oldToken, newToken, 0, false);
+      _TokenDifferenceKind diffKind = _compareToken(oldToken, newToken, 0);
       if (diffKind != null) {
         return new _TokenPair(diffKind, oldToken, newToken);
       }
@@ -945,24 +958,40 @@
 
   static _TokenPair _findLastDifferentToken(Token oldToken, Token newToken) {
     int delta = newToken.offset - oldToken.offset;
+    Token prevOldToken;
+    Token prevNewToken;
     while (oldToken.previous != oldToken && newToken.previous != newToken) {
       // compare tokens
-      _TokenDifferenceKind diffKind =
-          _compareToken(oldToken, newToken, delta, false);
+      _TokenDifferenceKind diffKind = _compareToken(oldToken, newToken, delta);
       if (diffKind != null) {
-        return new _TokenPair(diffKind, oldToken.next, newToken.next);
+        return new _TokenPair(diffKind, prevOldToken, prevNewToken);
       }
+      prevOldToken = oldToken;
+      prevNewToken = newToken;
       // compare comments
       {
         Token oldComment = oldToken.precedingComments;
         Token newComment = newToken.precedingComments;
-        if (_compareToken(oldComment, newComment, delta, true) != null) {
-          _TokenDifferenceKind diffKind = _TokenDifferenceKind.COMMENT;
-          if (oldComment is DocumentationCommentToken &&
-              newComment is DocumentationCommentToken) {
-            diffKind = _TokenDifferenceKind.COMMENT_DOC;
+        while (oldComment?.next != null) {
+          oldComment = oldComment.next;
+        }
+        while (newComment?.next != null) {
+          newComment = newComment.next;
+        }
+        while (true) {
+          _TokenDifferenceKind diffKind =
+              _compareToken(oldComment, newComment, delta);
+          if (diffKind != null) {
+            return new _TokenPair(
+                diffKind, oldComment ?? oldToken, newComment ?? newToken);
           }
-          return new _TokenPair(diffKind, oldToken, newToken);
+          if (oldComment == null && newComment == null) {
+            break;
+          }
+          prevOldToken = oldComment;
+          prevNewToken = newComment;
+          oldComment = oldComment.previous;
+          newComment = newComment.previous;
         }
       }
       // next tokens
@@ -1196,19 +1225,13 @@
     // name offset
     int nameOffset = element.nameOffset;
     if (nameOffset > updateOffset) {
-      // TODO(scheglov) make sure that we don't put local variables
-      // and functions into the cache at all.
-      try {
-        (element as ElementImpl).nameOffset = nameOffset + updateDelta;
-      } on FrozenHashCodeException {
-        cache.remove(element);
-        (element as ElementImpl).nameOffset = nameOffset + updateDelta;
-      }
+      (element as ElementImpl).nameOffset = nameOffset + updateDelta;
       if (element is ConstVariableElement) {
         Expression initializer = element.constantInitializer;
         if (initializer != null) {
           _shiftTokens(initializer.beginToken);
         }
+        _shiftErrors(element.evaluationResult?.errors);
       }
     }
     // code range
@@ -1251,6 +1274,17 @@
     super.visitElement(element);
   }
 
+  void _shiftErrors(List<AnalysisError> errors) {
+    if (errors != null) {
+      for (AnalysisError error in errors) {
+        int errorOffset = error.offset;
+        if (errorOffset > updateOffset) {
+          error.offset += updateDelta;
+        }
+      }
+    }
+  }
+
   void _shiftTokens(Token token) {
     while (token != null) {
       if (token.offset > updateOffset) {
@@ -1276,8 +1310,6 @@
  * Describes how two [Token]s are different.
  */
 class _TokenDifferenceKind {
-  static const COMMENT = const _TokenDifferenceKind('COMMENT');
-  static const COMMENT_DOC = const _TokenDifferenceKind('COMMENT_DOC');
   static const CONTENT = const _TokenDifferenceKind('CONTENT');
   static const OFFSET = const _TokenDifferenceKind('OFFSET');
 
diff --git a/pkg/analyzer/lib/src/generated/package.dart b/pkg/analyzer/lib/src/generated/package.dart
new file mode 100644
index 0000000..a9576d1
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/package.dart
@@ -0,0 +1,239 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.package;
+
+import 'dart:collection';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:package_config/packages.dart';
+import 'package:yaml/yaml.dart';
+
+/**
+ * Traverses the package structure to determine the transitive dependencies for
+ * a given package.
+ */
+class DependencyFinder {
+  /**
+   * The name of the pubspec.yaml file.
+   */
+  static const String pubspecName = 'pubspec.yaml';
+
+  /**
+   * The resource provider used to access the file system.
+   */
+  final ResourceProvider resourceProvider;
+
+  /**
+   * A table mapping the absolute paths of packages to a list of the names of
+   * the packages on which those packages depend.
+   */
+  final Map<String, List<String>> dependencyMap =
+      new HashMap<String, List<String>>();
+
+  /**
+   * Initialize a newly created dependency finder to use the given
+   * [resourceProvider] to access the file system.
+   */
+  DependencyFinder(this.resourceProvider);
+
+  /**
+   * Return a sorted list of the directories containing all of the packages on
+   * which the package at the given [packagePath] depends. The [packageMap]
+   * maps the names of packages to the directories in which they are contained.
+   *
+   * Throws an [AnalysisException] if any of the packages are missing their
+   * 'pubspec.yaml' file.
+   */
+  List<String> transitiveDependenciesFor(
+      Map<String, List<Folder>> packageMap, String packagePath) {
+    Set<String> processedPackages = new HashSet<String>();
+    Set<String> processedPaths = new HashSet<String>();
+    void process(String packageName) {
+      if (processedPackages.add(packageName)) {
+        List<Folder> folderList = packageMap[packageName];
+        if (folderList == null || folderList.isEmpty) {
+          throw new StateError('No mapping for package "$packageName"');
+        }
+        String packagePath = folderList[0].path;
+        processedPaths.add(packagePath);
+        List<String> dependencies = _dependenciesFor(packagePath);
+        for (String dependency in dependencies) {
+          process(dependency);
+        }
+      }
+    }
+
+    List<String> dependencies = _dependenciesFor(packagePath);
+    dependencies.forEach(process);
+    processedPaths.remove(packagePath);
+    List<String> transitiveDependencies = processedPaths.toList();
+    transitiveDependencies.sort();
+    return transitiveDependencies;
+  }
+
+  /**
+   * Add to the given set of [dependecies] all of the package names used as keys
+   * in the given [yamlMap].
+   */
+  void _collectDependencies(HashSet<String> dependencies, YamlMap yamlMap) {
+    if (yamlMap is Map) {
+      for (var key in yamlMap.keys) {
+        if (key is String) {
+          dependencies.add(key);
+        }
+      }
+    }
+  }
+
+  /**
+   * Return a list of the names of the packages on which the package at the
+   * [packagePath] depends.
+   */
+  List<String> _dependenciesFor(String packagePath) {
+    return dependencyMap.putIfAbsent(packagePath, () {
+      Set<String> dependencies = new HashSet<String>();
+      YamlNode yamlNode = _readPubspec(packagePath);
+      if (yamlNode is YamlMap) {
+        _collectDependencies(dependencies, yamlNode['dependencies']);
+      }
+      return dependencies.toList();
+    });
+  }
+
+  /**
+   * Read the content of the pubspec file in the directory at the given
+   * [directoryPath]. Return `null` if the file does not exist, cannot be read,
+   * or has content that is not valid YAML.
+   */
+  YamlNode _readPubspec(String directoryPath) {
+    try {
+      File yamlFile = resourceProvider
+          .getFolder(directoryPath)
+          .getChildAssumingFile(pubspecName);
+      String yamlContent = yamlFile.readAsStringSync();
+      return loadYamlNode(yamlContent);
+    } catch (exception, stackTrace) {
+      throw new AnalysisException('Missing $pubspecName in $directoryPath',
+          new CaughtException(exception, stackTrace));
+    }
+  }
+}
+
+/**
+ * A description of the context in which a package will be analyzed.
+ */
+class PackageDescription {
+  /**
+   * The id of the package being described. The id encodes the actual locations
+   * of the package itself and all of the packages on which it depends.
+   */
+  final String id;
+
+  /**
+   * The SDK against which the package will be analyzed.
+   */
+  final DartSdk sdk;
+
+  /**
+   * The analysis options that will be used when analyzing the package.
+   */
+  final AnalysisOptions options;
+
+  /**
+   * Initialize a newly create package description to describe the package with
+   * the given [id] that is being analyzed against the given [sdk] using the
+   * given [options].
+   */
+  PackageDescription(this.id, this.sdk, this.options);
+
+  @override
+  int get hashCode {
+    int hashCode = options.encodeCrossContextOptions();
+    hashCode = JenkinsSmiHash.combine(hashCode, id.hashCode);
+    hashCode = JenkinsSmiHash.combine(hashCode, sdk.hashCode);
+    return JenkinsSmiHash.finish(hashCode);
+  }
+
+  @override
+  bool operator ==(Object other) {
+    return other is PackageDescription &&
+        other.sdk == sdk &&
+        other.options.encodeCrossContextOptions() ==
+            options.encodeCrossContextOptions() &&
+        other.id == id;
+  }
+}
+
+/**
+ * Manages the contexts in which each package is analyzed.
+ */
+class PackageManager {
+  /**
+   * The resource provider used to access the file system.
+   */
+  final ResourceProvider resourceProvider;
+
+  /**
+   * A table mapping the id's of packages to the context in which the package is
+   * analyzed.
+   */
+  final Map<PackageDescription, AnalysisContext> contextMap =
+      new HashMap<PackageDescription, AnalysisContext>();
+
+  /**
+   * Initialize a newly created package manager.
+   */
+  PackageManager(this.resourceProvider);
+
+  /**
+   * Return the context in which the package at the given [packagePath] should
+   * be analyzed when the given [packages] object is used to resolve package
+   * names, the given [resolver] will be used to resolve 'dart:' URI's, and the
+   * given [options] will control the analysis.
+   */
+  AnalysisContext getContext(String packagePath, Packages packages,
+      DartUriResolver resolver, AnalysisOptions options) {
+    DartSdk sdk = resolver.dartSdk;
+    Map<String, List<Folder>> packageMap =
+        new ContextBuilder(resourceProvider, null, null)
+            .convertPackagesToMap(packages);
+    PackageDescription description =
+        new PackageDescription(_buildId(packagePath, packageMap), sdk, options);
+    return contextMap.putIfAbsent(description, () {
+      AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+      context.sourceFactory = new SourceFactory(<UriResolver>[
+        resolver,
+        new PackageMapUriResolver(resourceProvider, packageMap),
+        new ResourceUriResolver(resourceProvider)
+      ], packages, resourceProvider);
+      context.analysisOptions = options;
+      return context;
+    });
+  }
+
+  /**
+   * Return the id associated with the package at the given [packagePath] when
+   * the given [packageMap] is used to resolve package names.
+   */
+  String _buildId(String packagePath, Map<String, List<Folder>> packageMap) {
+    DependencyFinder finder = new DependencyFinder(resourceProvider);
+    List<String> dependencies =
+        finder.transitiveDependenciesFor(packageMap, packagePath);
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(packagePath);
+    for (String dependency in dependencies) {
+      buffer.write(';');
+      buffer.write(dependency);
+    }
+    return buffer.toString();
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index ab3b05e..fcf9b01 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2189,12 +2189,6 @@
   bool parseGenericMethodComments = false;
 
   /**
-   * A flag indicating whether the parser is to parse trailing commas in
-   * parameter and argument lists (sdk#26647).
-   */
-  bool parseTrailingCommas = false;
-
-  /**
    * Initialize a newly created parser to parse tokens in the given [_source]
    * and to report any errors that are found to the given [_errorListener].
    */
@@ -2330,7 +2324,7 @@
       bool foundNamedArgument = argument is NamedExpression;
       bool generatedError = false;
       while (_optional(TokenType.COMMA)) {
-        if (parseTrailingCommas && _matches(TokenType.CLOSE_PAREN)) {
+        if (_matches(TokenType.CLOSE_PAREN)) {
           break;
         }
         argument = parseArgument();
@@ -4357,25 +4351,12 @@
    * This method assumes that the current token matches `Keyword.ASSERT`.
    *
    *     assertStatement ::=
-   *         'assert' '(' conditionalExpression ')' ';'
+   *         'assert' '(' expression [',' expression] ')' ';'
    */
   AssertStatement _parseAssertStatement() {
     Token keyword = getAndAdvance();
     Token leftParen = _expect(TokenType.OPEN_PAREN);
     Expression expression = parseExpression2();
-    if (expression is AssignmentExpression) {
-      _reportErrorForNode(
-          ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT, expression);
-    } else if (expression is CascadeExpression) {
-      _reportErrorForNode(
-          ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE, expression);
-    } else if (expression is ThrowExpression) {
-      _reportErrorForNode(
-          ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW, expression);
-    } else if (expression is RethrowExpression) {
-      _reportErrorForNode(
-          ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW, expression);
-    }
     Token comma;
     Expression message;
     if (_matches(TokenType.COMMA)) {
@@ -5062,16 +5043,52 @@
         newKeyword = firstToken;
         firstToken = firstToken.next;
       }
-      if (_tokenMatchesIdentifier(firstToken)) {
+      if (firstToken.isUserDefinableOperator) {
+        if (firstToken.next.type != TokenType.EOF) {
+          return null;
+        }
+        Identifier identifier = new SimpleIdentifier(firstToken);
+        return new CommentReference(null, identifier);
+      } else if (_tokenMatchesKeyword(firstToken, Keyword.OPERATOR)) {
+        Token secondToken = firstToken.next;
+        if (secondToken.isUserDefinableOperator) {
+          if (secondToken.next.type != TokenType.EOF) {
+            return null;
+          }
+          Identifier identifier = new SimpleIdentifier(secondToken);
+          return new CommentReference(null, identifier);
+        }
+        return null;
+      } else if (_tokenMatchesIdentifier(firstToken)) {
         Token secondToken = firstToken.next;
         Token thirdToken = secondToken.next;
         Token nextToken;
         Identifier identifier;
-        if (_tokenMatches(secondToken, TokenType.PERIOD) &&
-            _tokenMatchesIdentifier(thirdToken)) {
-          identifier = new PrefixedIdentifier(new SimpleIdentifier(firstToken),
-              secondToken, new SimpleIdentifier(thirdToken));
-          nextToken = thirdToken.next;
+        if (_tokenMatches(secondToken, TokenType.PERIOD)) {
+          if (thirdToken.isUserDefinableOperator) {
+            identifier = new PrefixedIdentifier(
+                new SimpleIdentifier(firstToken),
+                secondToken,
+                new SimpleIdentifier(thirdToken));
+            nextToken = thirdToken.next;
+          } else if (_tokenMatchesKeyword(thirdToken, Keyword.OPERATOR)) {
+            Token fourthToken = thirdToken.next;
+            if (fourthToken.isUserDefinableOperator) {
+              identifier = new PrefixedIdentifier(
+                  new SimpleIdentifier(firstToken),
+                  secondToken,
+                  new SimpleIdentifier(fourthToken));
+              nextToken = fourthToken.next;
+            } else {
+              return null;
+            }
+          } else if (_tokenMatchesIdentifier(thirdToken)) {
+            identifier = new PrefixedIdentifier(
+                new SimpleIdentifier(firstToken),
+                secondToken,
+                new SimpleIdentifier(thirdToken));
+            nextToken = thirdToken.next;
+          }
         } else {
           identifier = new SimpleIdentifier(firstToken);
           nextToken = firstToken.next;
@@ -6123,7 +6140,7 @@
       type = _currentToken.type;
 
       // Advance past trailing commas as appropriate.
-      if (parseTrailingCommas && type == TokenType.COMMA) {
+      if (type == TokenType.COMMA) {
         // Only parse commas trailing normal (non-positional/named) params.
         if (rightSquareBracket == null && rightCurlyBracket == null) {
           Token next = _peek();
@@ -9896,22 +9913,6 @@
       const ParserErrorCode('ANNOTATION_ON_ENUM_CONSTANT',
           "Enum constants cannot have annotations");
 
-  static const ParserErrorCode ASSERT_DOES_NOT_TAKE_ASSIGNMENT =
-      const ParserErrorCode('ASSERT_DOES_NOT_TAKE_ASSIGNMENT',
-          "Assert cannot be called on an assignment");
-
-  static const ParserErrorCode ASSERT_DOES_NOT_TAKE_CASCADE =
-      const ParserErrorCode(
-          'ASSERT_DOES_NOT_TAKE_CASCADE', "Assert cannot be called on cascade");
-
-  static const ParserErrorCode ASSERT_DOES_NOT_TAKE_THROW =
-      const ParserErrorCode(
-          'ASSERT_DOES_NOT_TAKE_THROW', "Assert cannot be called on throws");
-
-  static const ParserErrorCode ASSERT_DOES_NOT_TAKE_RETHROW =
-      const ParserErrorCode('ASSERT_DOES_NOT_TAKE_RETHROW',
-          "Assert cannot be called on rethrows");
-
   /**
    * 16.32 Identifier Reference: It is a compile-time error if any of the
    * identifiers async, await, or yield is used as an identifier in a function
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 15c41d6..db027ac 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -562,6 +562,7 @@
       }
       return element.isDeprecated;
     }
+
     if (!inDeprecatedMember && isDeprecated(element)) {
       String displayName = element.displayName;
       if (element is ConstructorElement) {
@@ -971,6 +972,7 @@
       }
       return false;
     }
+
     FunctionBody body = node.body;
     if (body is ExpressionFunctionBody) {
       if (isNonObjectNoSuchMethodInvocation(body.expression)) {
@@ -1919,7 +1921,7 @@
     if (exportElement != null) {
       // The element is null when the URI is invalid
       LibraryElement library = exportElement.exportedLibrary;
-      if (library != null) {
+      if (library != null && !library.isSynthetic) {
         for (Combinator combinator in node.combinators) {
           _checkCombinator(exportElement.exportedLibrary, combinator);
         }
@@ -1961,9 +1963,10 @@
   Object visitImportDirective(ImportDirective node) {
     ImportElement importElement = node.element;
     if (importElement != null) {
-      // The element is null when the URI is invalid
+      // The element is null when the URI is invalid, but not when the URI is
+      // valid but refers to a non-existent file.
       LibraryElement library = importElement.importedLibrary;
-      if (library != null) {
+      if (library != null && !library.isSynthetic) {
         for (Combinator combinator in node.combinators) {
           _checkCombinator(library, combinator);
         }
@@ -2547,8 +2550,10 @@
       String nameOfMethod = methodName.name;
       if (property == null) {
         String elementName = nameOfMethod == '-' &&
-            node.parameters != null &&
-            node.parameters.parameters.isEmpty ? 'unary-' : nameOfMethod;
+                node.parameters != null &&
+                node.parameters.parameters.isEmpty
+            ? 'unary-'
+            : nameOfMethod;
         _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods,
             methodName, elementName, methodName.offset);
         _expectedElements.remove(_enclosingExecutable);
@@ -2855,10 +2860,12 @@
  * The resulting AST must have everything resolved that would have been resolved
  * by a [DirectiveElementBuilder].
  */
-class DirectiveResolver extends SimpleAstVisitor with ExistingElementResolver {
+class DirectiveResolver extends SimpleAstVisitor {
+  LibraryElement _enclosingLibrary;
+
   @override
   void visitCompilationUnit(CompilationUnit node) {
-    _enclosingUnit = node.element;
+    _enclosingLibrary = node.element.library;
     for (Directive directive in node.directives) {
       directive.accept(this);
     }
@@ -2866,124 +2873,31 @@
 
   @override
   void visitExportDirective(ExportDirective node) {
-    String uri = _getStringValue(node.uri);
-    if (uri != null) {
-      LibraryElement library = _enclosingUnit.library;
-      Source source = _enclosingUnit.context.sourceFactory
-          .resolveUri(_enclosingUnit.source, uri);
-      ExportElement exportElement = _findExport(node, library.exports, source);
-      node.element = exportElement;
-    } else {
-      node.element = null;
+    int nodeOffset = node.offset;
+    node.element = null;
+    for (ExportElement element in _enclosingLibrary.exports) {
+      if (element.nameOffset == nodeOffset) {
+        node.element = element;
+        break;
+      }
     }
   }
 
   @override
   void visitImportDirective(ImportDirective node) {
-    String uri = _getStringValue(node.uri);
-    if (uri != null) {
-      LibraryElement library = _enclosingUnit.library;
-      Source source = _enclosingUnit.context.sourceFactory
-          .resolveUri(_enclosingUnit.source, uri);
-      ImportElement importElement = _findImport(node, library.imports, source);
-      node.element = importElement;
-    } else {
-      node.element = null;
+    int nodeOffset = node.offset;
+    node.element = null;
+    for (ImportElement element in _enclosingLibrary.imports) {
+      if (element.nameOffset == nodeOffset) {
+        node.element = element;
+        break;
+      }
     }
   }
 
   @override
   void visitLibraryDirective(LibraryDirective node) {
-    node.element = _enclosingUnit.library;
-  }
-
-  /**
-   * Return the export element from the given list of [exports] whose library
-   * has the given [source]. Throw an [ElementMismatchException] if an element
-   * corresponding to the identifier cannot be found.
-   */
-  ExportElement _findExport(
-      ExportDirective node, List<ExportElement> exports, Source source) {
-    if (source == null) {
-      return null;
-    }
-    int length = exports.length;
-    for (int i = 0; i < length; i++) {
-      ExportElement export = exports[i];
-      if (export.exportedLibrary.source == source) {
-        // Must have the same offset.
-        if (export.nameOffset != node.offset) {
-          continue;
-        }
-        // In general we should also match combinators.
-        // But currently we invalidate element model on any directive change.
-        // So, either the combinators are the same, or we build new elements.
-        return export;
-      }
-    }
-    if (!_enclosingUnit.context.exists(source)) {
-      return null;
-    }
-    _mismatch("Could not find export element for '$source'", node);
-    return null; // Never reached
-  }
-
-  /**
-   * Return the import element from the given list of [imports] whose library
-   * has the given [source]. Throw an [ElementMismatchException] if an element
-   * corresponding to the [source] cannot be found.
-   */
-  ImportElement _findImport(
-      ImportDirective node, List<ImportElement> imports, Source source) {
-    if (source == null) {
-      return null;
-    }
-    SimpleIdentifier prefix = node.prefix;
-    bool foundSource = false;
-    int length = imports.length;
-    for (int i = 0; i < length; i++) {
-      ImportElement element = imports[i];
-      if (element.importedLibrary.source == source) {
-        foundSource = true;
-        // Must have the same offset.
-        if (element.nameOffset != node.offset) {
-          continue;
-        }
-        // Must have the same prefix.
-        if (element.prefix?.displayName != prefix?.name) {
-          continue;
-        }
-        // In general we should also match combinators.
-        // But currently we invalidate element model on any directive change.
-        // So, either the combinators are the same, or we build new elements.
-        return element;
-      }
-    }
-    if (!_enclosingUnit.context.exists(source)) {
-      return null;
-    }
-    if (foundSource) {
-      if (prefix == null) {
-        _mismatch(
-            "Could not find import element for '$source' with no prefix", node);
-      }
-      _mismatch(
-          "Could not find import element for '$source' with prefix ${prefix.name}",
-          node);
-    }
-    _mismatch("Could not find any import element for '$source'", node);
-    return null; // Never reached
-  }
-
-  /**
-   * Return the value of the given string [literal], or `null` if the string is
-   * not a constant string without any string interpolation.
-   */
-  String _getStringValue(StringLiteral literal) {
-    if (literal is StringInterpolation) {
-      return null;
-    }
-    return literal.stringValue;
+    node.element = _enclosingLibrary;
   }
 }
 
@@ -3234,14 +3148,14 @@
     _typeParameters.add(element);
   }
 
-  FieldElement getField(String fieldName) {
+  FieldElement getField(String fieldName, {bool synthetic: false}) {
     if (_fields == null) {
       return null;
     }
     int length = _fields.length;
     for (int i = 0; i < length; i++) {
       FieldElement field = _fields[i];
-      if (field.name == fieldName) {
+      if (field.name == fieldName && field.isSynthetic == synthetic) {
         return field;
       }
     }
@@ -3525,7 +3439,10 @@
     if (_nodeExits(leftHandSide)) {
       return true;
     }
-    if (node.operator.type == TokenType.QUESTION_QUESTION_EQ) {
+    TokenType operatorType = node.operator.type;
+    if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
+        operatorType == TokenType.BAR_BAR_EQ ||
+        operatorType == TokenType.QUESTION_QUESTION_EQ) {
       return false;
     }
     if (leftHandSide is PropertyAccess &&
@@ -4051,6 +3968,7 @@
       }
       return false;
     }
+
     AstNode parent = identifier.parent;
     if (parent is MethodInvocation && parent.methodName == identifier) {
       return recordIfTargetIsPrefixElement(parent.target);
@@ -4299,7 +4217,8 @@
     _usedImportedElementsVisitor =
         new GatherUsedImportedElementsVisitor(_library);
     _enableDart2JSHints = _context.analysisOptions.dart2jsHint;
-    _manager = new InheritanceManager(_library);
+    _manager =
+        new InheritanceManager(_library, includeAbstractFromSuperclasses: true);
     _usedLocalElementsVisitor = new GatherUsedLocalElementsVisitor(_library);
   }
 
@@ -4527,11 +4446,13 @@
     int length = _unusedImports.length;
     for (int i = 0; i < length; i++) {
       ImportDirective unusedImport = _unusedImports[i];
-      // Check that the import isn't dart:core
+      // Check that the imported URI exists and isn't dart:core
       ImportElement importElement = unusedImport.element;
       if (importElement != null) {
         LibraryElement libraryElement = importElement.importedLibrary;
-        if (libraryElement != null && libraryElement.isDartCore) {
+        if (libraryElement == null ||
+            libraryElement.isDartCore ||
+            libraryElement.isSynthetic) {
           continue;
         }
       }
@@ -4655,7 +4576,9 @@
     for (Combinator combinator in importDirective.combinators) {
       if (combinator is ShowCombinator) {
         for (SimpleIdentifier name in combinator.shownNames) {
-          identifiers.add(name);
+          if (name.staticElement != null) {
+            identifiers.add(name);
+          }
         }
       }
     }
@@ -4775,8 +4698,6 @@
    * 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
   final List<DartType> _returnStack = <DartType>[];
 
   InferenceContext._(this._errorReporter, TypeProvider typeProvider,
@@ -4805,12 +4726,10 @@
     if (_returnStack.isEmpty) {
       return;
     }
-    DartType context = _returnStack.last;
-    if (context == null || context.isDynamic) {
-      DartType inferred = _inferredReturn.last;
-      inferred = _typeSystem.getLeastUpperBound(_typeProvider, type, inferred);
-      _inferredReturn[_inferredReturn.length - 1] = inferred;
-    }
+
+    DartType inferred = _inferredReturn.last;
+    inferred = _typeSystem.getLeastUpperBound(_typeProvider, type, inferred);
+    _inferredReturn[_inferredReturn.length - 1] = inferred;
   }
 
   /**
@@ -4832,15 +4751,24 @@
    * bound of all types added with [addReturnOrYieldType].
    */
   void popReturnContext(BlockFunctionBody node) {
-    assert(_returnStack.isNotEmpty && _inferredReturn.isNotEmpty);
-    if (_returnStack.isNotEmpty) {
-      _returnStack.removeLast();
-    }
-    if (_inferredReturn.isNotEmpty) {
+    if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) {
+      DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance;
       DartType inferred = _inferredReturn.removeLast();
-      if (!inferred.isBottom) {
+      if (inferred.isBottom) {
+        return;
+      }
+
+      if (context is FutureUnionType) {
+        // Try and match the Future type first.
+        if (_typeSystem.isSubtypeOf(inferred, context.futureOfType) ||
+            _typeSystem.isSubtypeOf(inferred, context.type)) {
+          setType(node, inferred);
+        }
+      } else if (_typeSystem.isSubtypeOf(inferred, context)) {
         setType(node, inferred);
       }
+    } else {
+      assert(false);
     }
   }
 
@@ -4848,8 +4776,7 @@
    * Push a block function body's return type onto the return stack.
    */
   void pushReturnContext(BlockFunctionBody node) {
-    DartType returnType = getType(node);
-    _returnStack.add(returnType);
+    _returnStack.add(getContext(node));
     _inferredReturn.add(BottomTypeImpl.instance);
   }
 
@@ -4993,8 +4920,41 @@
   /**
    * Look for contextual type information attached to [node].  Returns
    * the type if found, otherwise null.
+   *
+   * If [node] has a contextual union type like `T | Future<T>` this will be
+   * returned. You can use [getType] if you prefer to only get the `T`.
    */
-  static DartType getType(AstNode node) => node?.getProperty(_typeProperty);
+  static DartType getContext(AstNode node) => node?.getProperty(_typeProperty);
+
+  /**
+   * Look for a single contextual type attached to [node], and returns the type
+   * if found, otherwise null.
+   *
+   * If [node] has a contextual union type like `T | Future<T>` this will
+   * simplify it to only return `T`. If the caller can handle a union type,
+   * [getContext] should be used instead.
+   */
+  static DartType getType(AstNode node) {
+    DartType t = getContext(node);
+    if (t is FutureUnionType) {
+      return t.type;
+    }
+    return t;
+  }
+
+  /**
+   * Like [getContext] but expands a union type into a list of types.
+   */
+  static Iterable<DartType> getTypes(AstNode node) {
+    DartType t = getContext(node);
+    if (t == null) {
+      return DartType.EMPTY_LIST;
+    }
+    if (t is FutureUnionType) {
+      return t.types;
+    }
+    return <DartType>[t];
+  }
 
   /**
    * Attach contextual type information [type] to [node] for use during
@@ -5009,7 +4969,7 @@
    * inference.
    */
   static void setTypeFromNode(AstNode innerNode, AstNode outerNode) {
-    setType(innerNode, getType(outerNode));
+    setType(innerNode, getContext(outerNode));
   }
 }
 
@@ -5141,7 +5101,7 @@
  * Instances of the class `OverrideVerifier` visit all of the declarations in a compilation
  * unit to verify that if they have an override annotation it is being used correctly.
  */
-class OverrideVerifier extends RecursiveAstVisitor<Object> {
+class OverrideVerifier extends RecursiveAstVisitor {
   /**
    * The error reporter used to report errors.
    */
@@ -5161,7 +5121,23 @@
   OverrideVerifier(this._errorReporter, this._manager);
 
   @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
+  visitFieldDeclaration(FieldDeclaration node) {
+    for (VariableDeclaration field in node.fields.variables) {
+      VariableElement fieldElement = field.element;
+      if (fieldElement is FieldElement && _isOverride(fieldElement)) {
+        PropertyAccessorElement getter = fieldElement.getter;
+        PropertyAccessorElement setter = fieldElement.setter;
+        if (!(getter != null && _getOverriddenMember(getter) != null ||
+            setter != null && _getOverriddenMember(setter) != null)) {
+          _errorReporter.reportErrorForNode(
+              HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD, field.name);
+        }
+      }
+    }
+  }
+
+  @override
+  visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement element = node.element;
     if (_isOverride(element)) {
       if (_getOverriddenMember(element) == null) {
@@ -5179,7 +5155,6 @@
         }
       }
     }
-    return super.visitMethodDeclaration(node);
   }
 
   /**
@@ -5658,6 +5633,11 @@
   FunctionBody _currentFunctionBody;
 
   /**
+   * Are we running in strong mode or not.
+   */
+  bool strongMode;
+
+  /**
    * Initialize a newly created visitor to resolve the nodes in an AST node.
    *
    * The [definingLibrary] is the element for the library containing the node
@@ -5679,10 +5659,11 @@
       {Scope nameScope})
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
+    AnalysisOptions options = definingLibrary.context.analysisOptions;
+    this.strongMode = options.strongMode;
     this.elementResolver = new ElementResolver(this);
     this.typeSystem = definingLibrary.context.typeSystem;
     bool strongModeHints = false;
-    AnalysisOptions options = definingLibrary.context.analysisOptions;
     if (options is AnalysisOptionsImpl) {
       strongModeHints = options.strongModeHints;
     }
@@ -5785,6 +5766,28 @@
   }
 
   /**
+   * Returns true if this method is `Future.then` or an override thereof.
+   *
+   * If so we will apply special typing rules in strong mode, to handle the
+   * implicit union of `S | Future<S>`
+   */
+  bool isFutureThen(Element element) {
+    // If we are a method named then
+    if (element is MethodElement && element.name == 'then') {
+      DartType type = element.enclosingElement.type;
+      // On Future or a subtype, then we're good.
+      return (type.isDartAsyncFuture || isSubtypeOfFuture(type));
+    }
+    return false;
+  }
+
+  /**
+   * Returns true if this type is any subtype of the built in Future type.
+   */
+  bool isSubtypeOfFuture(DartType type) =>
+      typeSystem.isSubtypeOf(type, typeProvider.futureDynamicType);
+
+  /**
    * Given a downward inference type [fnType], and the declared
    * [typeParameterList] for a function expression, determines if we can enable
    * downward inference and if so, returns the function type to use for
@@ -6072,13 +6075,11 @@
 
   @override
   Object visitAwaitExpression(AwaitExpression node) {
-    // TODO(leafp): Handle the implicit union type here
-    // https://github.com/dart-lang/sdk/issues/25322
-    DartType contextType = InferenceContext.getType(node);
+    DartType contextType = InferenceContext.getContext(node);
     if (contextType != null) {
-      InterfaceType futureT = typeProvider.futureType
-          .instantiate([contextType.flattenFutures(typeSystem)]);
-      InferenceContext.setType(node.expression, futureT);
+      var futureUnion =
+          FutureUnionType.from(contextType, typeProvider, typeSystem);
+      InferenceContext.setType(node.expression, futureUnion);
     }
     return super.visitAwaitExpression(node);
   }
@@ -6127,9 +6128,18 @@
       // of the binary operator for other cases.
       if (operatorType == TokenType.QUESTION_QUESTION) {
         InferenceContext.setTypeFromNode(leftOperand, node);
-        InferenceContext.setTypeFromNode(rightOperand, node);
       }
       leftOperand?.accept(this);
+      if (operatorType == TokenType.QUESTION_QUESTION) {
+        // Set the right side, either from the context, or using the information
+        // from the left side if it is more precise.
+        DartType contextType = InferenceContext.getContext(node);
+        DartType leftType = leftOperand?.staticType;
+        if (contextType == null || contextType.isDynamic) {
+          contextType = leftType;
+        }
+        InferenceContext.setType(rightOperand, contextType);
+      }
       rightOperand?.accept(this);
     }
     node.accept(elementResolver);
@@ -6601,8 +6611,24 @@
               matchFunctionTypeParameters(node.typeParameters, functionType);
           if (functionType is FunctionType) {
             _inferFormalParameterList(node.parameters, functionType);
-            DartType returnType =
-                _computeReturnOrYieldType(functionType.returnType);
+
+            DartType returnType;
+            if (isFutureThen(node.staticParameterElement?.enclosingElement)) {
+              var futureThenType =
+                  InferenceContext.getContext(node.parent) as FunctionType;
+
+              // Pretend the return type of Future<T>.then<S> first parameter is
+              //
+              //     T -> (S | Future<S>)
+              //
+              // We can't represent this in Dart so we populate it here during
+              // inference.
+              returnType = FutureUnionType.from(
+                  futureThenType.returnType, typeProvider, typeSystem);
+            } else {
+              returnType = _computeReturnOrYieldType(functionType.returnType);
+            }
+
             InferenceContext.setType(node.body, returnType);
           }
         }
@@ -6621,7 +6647,6 @@
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     node.function?.accept(this);
     node.accept(elementResolver);
-    _inferFunctionExpressionsParametersTypes(node.argumentList);
     _inferArgumentTypesFromContext(node);
     node.argumentList?.accept(this);
     node.accept(typeAnalyzer);
@@ -6718,21 +6743,44 @@
   @override
   Object visitInstanceCreationExpression(InstanceCreationExpression node) {
     TypeName classTypeName = node.constructorName.type;
+    // TODO(leafp): Currently, we may re-infer types here, since we
+    // sometimes resolve multiple times.  We should really check that we
+    // have not already inferred something.  However, the obvious ways to
+    // check this don't work, since we may have been instantiated
+    // to bounds in an earlier phase, and we *do* want to do inference
+    // in that case.
     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);
+      // Given a union of context types ` T0 | T1 | ... | Tn`, find the first
+      // valid instantiation `new C<Ti>`, if it exists.
+      // TODO(jmesserly): if we support union types for real, `new C<Ti | Tj>`
+      // will become a valid possibility. Right now the only allowed union is
+      // `T | Future<T>` so we can take a simple approach.
+      for (var contextType in InferenceContext.getTypes(node)) {
+        if (contextType is InterfaceType &&
+            contextType.typeArguments != null &&
+            contextType.typeArguments.isNotEmpty) {
+          // TODO(jmesserly): for generic methods we use the
+          // StrongTypeSystemImpl.inferGenericFunctionCall, which appears to
+          // be a tad more powerful than matchTypes.
+          //
+          // For example it can infer this case:
+          //
+          //     class E<S, T> extends A<C<S>, T> { ... }
+          //     A<C<int>, String> a0 = /*infer<int, String>*/new E("hello");
+          //
+          // See _inferArgumentTypesFromContext in this file for use of it.
+          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);
+            break;
+          }
         }
       }
     }
@@ -6838,7 +6886,6 @@
     node.target?.accept(this);
     node.typeArguments?.accept(this);
     node.accept(elementResolver);
-    _inferFunctionExpressionsParametersTypes(node.argumentList);
     _inferArgumentTypesFromContext(node);
     node.argumentList?.accept(this);
     node.accept(typeAnalyzer);
@@ -6847,7 +6894,7 @@
 
   @override
   Object visitNamedExpression(NamedExpression node) {
-    InferenceContext.setType(node.expression, InferenceContext.getType(node));
+    InferenceContext.setTypeFromNode(node.expression, node);
     return super.visitNamedExpression(node);
   }
 
@@ -6861,7 +6908,7 @@
 
   @override
   Object visitParenthesizedExpression(ParenthesizedExpression node) {
-    InferenceContext.setType(node.expression, InferenceContext.getType(node));
+    InferenceContext.setTypeFromNode(node.expression, node);
     return super.visitParenthesizedExpression(node);
   }
 
@@ -6979,7 +7026,7 @@
 
   @override
   Object visitVariableDeclaration(VariableDeclaration node) {
-    InferenceContext.setType(node.initializer, InferenceContext.getType(node));
+    InferenceContext.setTypeFromNode(node.initializer, node);
     super.visitVariableDeclaration(node);
     VariableElement element = node.element;
     if (element.initializer != null && node.initializer != null) {
@@ -7123,21 +7170,22 @@
     if (!isGenerator && !isAsynchronous) {
       return declaredType;
     }
-    if (isGenerator) {
-      if (declaredType is! InterfaceType) {
-        return null;
+    if (declaredType is InterfaceType) {
+      if (isGenerator) {
+        // If it's sync* we expect Iterable<T>
+        // If it's async* we expect 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;
       }
-      // 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;
+      // async functions expect `Future<T> | T`
+      return new FutureUnionType(declaredType, typeProvider, typeSystem);
     }
-    // Must be asynchronous to reach here, so strip off any layers of Future
-    return declaredType.flattenFutures(typeSystem);
+    return declaredType;
   }
 
   /**
@@ -7201,6 +7249,12 @@
   }
 
   void _inferArgumentTypesFromContext(InvocationExpression node) {
+    if (!strongMode) {
+      // Use propagated type inference for lambdas if not in strong mode.
+      _inferFunctionExpressionsParametersTypes(node.argumentList);
+      return;
+    }
+
     DartType contextType = node.staticInvokeType;
     if (contextType is FunctionType) {
       DartType originalType = node.function.staticType;
@@ -7223,6 +7277,20 @@
     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.
+      //
+      // TODO(jmesserly): this is reporting the context type, and therefore not
+      // necessarily the correct inferred type for the lambda.
+      //
+      // For example, `([x]) {}`  could be passed to `int -> void` but its type
+      // will really be `([int]) -> void`. Similar issue for named arguments.
+      // It can also happen if the return type is inferred later on to be
+      // more precise.
+      //
+      // This reporting bug defeats the deduplication of error messages and
+      // results in the same inference message being reported twice.
+      //
+      // To get this right, we'd have to delay reporting until we have the
+      // complete type including return type.
       inferenceContext.recordInference(node.parent, type);
     }
   }
@@ -7247,7 +7315,12 @@
     // return.
     DartType staticClosureType = closure.element?.type;
     if (staticClosureType != null &&
-        !expectedClosureType.isMoreSpecificThan(staticClosureType)) {
+        !FunctionTypeImpl.relate(
+            expectedClosureType,
+            staticClosureType,
+            (DartType t, DartType s) => (t as TypeImpl).isMoreSpecificThan(s),
+            new TypeSystemImpl().instantiateToBounds,
+            returnRelation: (s, t) => true)) {
       return;
     }
     // set propagated type for the closure
@@ -8577,6 +8650,11 @@
         node.type = voidType;
         return;
       }
+      if (nameScope.shouldIgnoreUndefined(typeName)) {
+        typeName.staticType = undefinedType;
+        node.type = undefinedType;
+        return;
+      }
       //
       // If not, the look to see whether we might have created the wrong AST
       // structure for a constructor name. If so, fix the AST structure and then
@@ -8593,6 +8671,11 @@
           SimpleIdentifier prefix = prefixedIdentifier.prefix;
           element = nameScope.lookup(prefix, definingLibrary);
           if (element is PrefixElement) {
+            if (nameScope.shouldIgnoreUndefined(typeName)) {
+              typeName.staticType = undefinedType;
+              node.type = undefinedType;
+              return;
+            }
             AstNode grandParent = parent.parent;
             if (grandParent is InstanceCreationExpression &&
                 grandParent.isConst) {
@@ -8627,6 +8710,11 @@
           }
         }
       }
+      if (nameScope.shouldIgnoreUndefined(typeName)) {
+        typeName.staticType = undefinedType;
+        node.type = undefinedType;
+        return;
+      }
     }
     // check element
     bool elementValid = element is! MultiplyDefinedElement;
@@ -9549,13 +9637,64 @@
    * Return the type representing typenames that can't be resolved.
    */
   DartType get undefinedType;
+
+  /**
+   * Return 'true' if [id] is the name of a getter on
+   * the Object type.
+   */
+  bool isObjectGetter(String id);
+
+  /**
+   * Return 'true' if [id] is the name of a method or getter on
+   * the Object type.
+   */
+  bool isObjectMember(String id);
+
+  /**
+   * Return 'true' if [id] is the name of a method on
+   * the Object type.
+   */
+  bool isObjectMethod(String id);
+}
+
+/**
+ * Provide common functionality shared by the various TypeProvider
+ * implementations.
+ */
+abstract class TypeProviderBase implements TypeProvider {
+  @override
+  List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
+        nullType,
+        numType,
+        intType,
+        doubleType,
+        boolType,
+        stringType
+      ];
+
+  @override
+  bool isObjectGetter(String id) {
+    PropertyAccessorElement element = objectType.element.getGetter(id);
+    return (element != null && !element.isStatic);
+  }
+
+  @override
+  bool isObjectMember(String id) {
+    return isObjectGetter(id) || isObjectMethod(id);
+  }
+
+  @override
+  bool isObjectMethod(String id) {
+    MethodElement element = objectType.element.getMethod(id);
+    return (element != null && !element.isStatic);
+  }
 }
 
 /**
  * Instances of the class `TypeProviderImpl` provide access to types defined by the language
  * by looking for those types in the element model for the core library.
  */
-class TypeProviderImpl implements TypeProvider {
+class TypeProviderImpl extends TypeProviderBase {
   /**
    * The type representing the built-in type 'bool'.
    */
@@ -9745,16 +9884,6 @@
   InterfaceType get mapType => _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);
@@ -10448,7 +10577,7 @@
     Identifier name = typeName.name;
     if (name.name == Keyword.DYNAMIC.syntax) {
       errorReporter.reportErrorForNode(dynamicTypeError, name, [name.name]);
-    } else {
+    } else if (!nameScope.shouldIgnoreUndefined(name)) {
       errorReporter.reportErrorForNode(nonTypeError, name, [name.name]);
     }
     return null;
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index e46b644..7e86d8d 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -12,6 +12,7 @@
     show AnalysisContext, AnalysisOptions, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/source.dart' show Source;
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
 
 /**
  * A function used to create a new DartSdk with the given [options]. If the
@@ -78,6 +79,14 @@
   Source fromFileUri(Uri uri);
 
   /**
+   * Return the linked [PackageBundle] for this SDK, if it can be provided, or
+   * `null` otherwise.
+   *
+   * This is a temporary API, don't use it.
+   */
+  PackageBundle getLinkedBundle();
+
+  /**
    * Return the library representing the library with the given 'dart:' [uri],
    * or `null` if the given URI does not denote a library in this SDK.
    */
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index be7c27a..d9dbcbc 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.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.
 
+@deprecated
 library analyzer.src.generated.sdk_io;
 
 import 'dart:collection';
@@ -29,6 +30,7 @@
  * stored in a library map. Subclasses are responsible for populating the
  * library map.
  */
+@deprecated
 abstract class AbstractDartSdk implements DartSdk {
   /**
    * A mapping from Dart library URI's to the library represented by that URI.
@@ -108,6 +110,20 @@
     _useSummary = use;
   }
 
+  /**
+   * Add the extensions from one or more sdk extension files to this sdk. The
+   * [extensions] should be a table mapping the names of extensions to the paths
+   * where those extensions can be found.
+   */
+  void addExtensions(Map<String, String> extensions) {
+    extensions.forEach((String uri, String path) {
+      String shortName = uri.substring(uri.indexOf(':') + 1);
+      SdkLibraryImpl library = new SdkLibraryImpl(shortName);
+      library.path = path;
+      libraryMap.setLibrary(uri, library);
+    });
+  }
+
   @override
   Source fromFileUri(Uri uri) {
     JavaFile file = new JavaFile.fromUri(uri);
@@ -238,7 +254,10 @@
  *        util/
  *           ... Dart utilities ...
  *     Chromium/   <-- Dartium typically exists in a sibling directory
+ *
+ * This class is deprecated. Please use FolderBasedDartSdk instead.
  */
+@deprecated
 class DirectoryBasedDartSdk extends AbstractDartSdk {
   /**
    * The default SDK, or `null` if the default SDK either has not yet been
@@ -619,6 +638,9 @@
   }
 
   @override
+  PackageBundle getLinkedBundle() => null;
+
+  @override
   String getRelativePathFromFile(JavaFile file) {
     String filePath = file.getAbsolutePath();
     String libPath = libraryDirectory.getAbsolutePath();
@@ -736,6 +758,7 @@
  *         platforms: 0),
  *     };
  */
+@deprecated
 class SdkLibrariesReader {
   /**
    * A flag indicating whether the dart2js path should be used when it is
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 6412de3..2d0acf5d 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -184,19 +184,19 @@
    * A list containing the offsets of the first character of each line in the
    * source code.
    */
-  final List<int> _lineStarts;
+  final List<int> lineStarts;
 
   /**
-   * The zero-based [_lineStarts] index resulting from the last call to
+   * The zero-based [lineStarts] index resulting from the last call to
    * [getLocation].
    */
   int _previousLine = 0;
 
   /**
    * Initialize a newly created set of line information to represent the data
-   * encoded in the given list of [_lineStarts].
+   * encoded in the given list of [lineStarts].
    */
-  factory LineInfo(List<int> _lineStarts) => new LineInfoWithCount(_lineStarts);
+  factory LineInfo(List<int> lineStarts) => new LineInfoWithCount(lineStarts);
 
   /**
    * Initialize a newly created set of line information corresponding to the
@@ -207,12 +207,12 @@
 
   /**
    * Initialize a newly created set of line information to represent the data
-   * encoded in the given list of [_lineStarts].
+   * encoded in the given list of [lineStarts].
    */
-  LineInfo._(this._lineStarts) {
-    if (_lineStarts == null) {
+  LineInfo._(this.lineStarts) {
+    if (lineStarts == null) {
       throw new IllegalArgumentException("lineStarts must be non-null");
-    } else if (_lineStarts.length < 1) {
+    } else if (lineStarts.length < 1) {
       throw new IllegalArgumentException("lineStarts must be non-empty");
     }
   }
@@ -220,26 +220,26 @@
   /**
    * The number of lines.
    */
-  int get lineCount => _lineStarts.length;
+  int get lineCount => lineStarts.length;
 
   /**
    * Return the location information for the character at the given [offset].
    */
   LineInfo_Location getLocation(int offset) {
     var min = 0;
-    var max = _lineStarts.length - 1;
+    var max = lineStarts.length - 1;
 
     // Subsequent calls to [getLocation] are often for offsets near each other.
     // To take advantage of that, we cache the index of the line start we found
     // when this was last called. If the current offset is on that line or
     // later, we'll skip those early indices completely when searching.
-    if (offset >= _lineStarts[_previousLine]) {
+    if (offset >= lineStarts[_previousLine]) {
       min = _previousLine;
 
       // Before kicking off a full binary search, do a quick check here to see
       // if the new offset is on that exact line.
-      if (min == _lineStarts.length - 1 || offset < _lineStarts[min + 1]) {
-        return new LineInfo_Location(min + 1, offset - _lineStarts[min] + 1);
+      if (min == lineStarts.length - 1 || offset < lineStarts[min + 1]) {
+        return new LineInfo_Location(min + 1, offset - lineStarts[min] + 1);
       }
     }
 
@@ -247,7 +247,7 @@
     while (min < max) {
       var midpoint = (max - min + 1) ~/ 2 + min;
 
-      if (_lineStarts[midpoint] > offset) {
+      if (lineStarts[midpoint] > offset) {
         max = midpoint - 1;
       } else {
         min = midpoint;
@@ -256,7 +256,7 @@
 
     _previousLine = min;
 
-    return new LineInfo_Location(min + 1, offset - _lineStarts[min] + 1);
+    return new LineInfo_Location(min + 1, offset - lineStarts[min] + 1);
   }
 
   /**
@@ -265,9 +265,10 @@
    */
   int getOffsetOfLine(int lineNumber) {
     if (lineNumber < 0 || lineNumber >= lineCount) {
-      throw new ArgumentError('Invalid line number: $lineNumber');
+      throw new ArgumentError(
+          'Invalid line number: $lineNumber; must be between 0 and ${lineCount - 1}');
     }
-    return _lineStarts[lineNumber];
+    return lineStarts[lineNumber];
   }
 }
 
@@ -309,14 +310,9 @@
 class LineInfoWithCount extends LineInfo {
   /**
    * Initialize a newly created set of line information to represent the data
-   * encoded in the given list of [_lineStarts].
+   * encoded in the given list of [lineStarts].
    */
-  LineInfoWithCount(List<int> _lineStarts) : super._(_lineStarts);
-
-  /**
-   * Return the number of lines in the file.
-   */
-  int get lineCount => _lineStarts.length;
+  LineInfoWithCount(List<int> lineStarts) : super._(lineStarts);
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index f7b47ef..82e4e86 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -221,7 +221,7 @@
   }
 
   @override
-  int get hashCode => id;
+  int get hashCode => uri.hashCode;
 
   @override
   bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 5c57bb8..628c340 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -12,10 +12,12 @@
 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' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/strong/checker.dart' show getDefiniteType;
 
 /**
  * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
@@ -92,7 +94,7 @@
     _dynamicType = _typeProvider.dynamicType;
     _overrideManager = _resolver.overrideManager;
     _promoteManager = _resolver.promoteManager;
-    _strongMode = _resolver.definingLibrary.context.analysisOptions.strongMode;
+    _strongMode = _resolver.strongMode;
   }
 
   /**
@@ -130,29 +132,15 @@
       }
 
       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++]);
+        Iterator<ParameterElement> positional = parameters
+            .where((p) => p.parameterKind != ParameterKind.NAMED)
+            .iterator;
+        Iterator<ParameterElement> fnPositional = functionType.parameters
+            .where((p) => p.parameterKind != ParameterKind.NAMED)
+            .iterator;
+        while (positional.moveNext() && fnPositional.moveNext()) {
+          inferType(positional.current, fnPositional.current.type);
         }
       }
 
@@ -254,16 +242,29 @@
       // bound of the static types of the LHS and RHS.
       _analyzeLeastUpperBound(node, node.leftHandSide, node.rightHandSide);
       return null;
+    } else if (operator == TokenType.AMPERSAND_AMPERSAND_EQ ||
+        operator == TokenType.BAR_BAR_EQ) {
+      _recordStaticType(node, _typeProvider.boolType);
     } else {
       ExecutableElement staticMethodElement = node.staticElement;
       DartType staticType = _computeStaticReturnType(staticMethodElement);
-      staticType =
-          _refineAssignmentExpressionType(node, staticType, _getStaticType);
+      staticType = _typeSystem.refineBinaryExpressionType(
+          _typeProvider,
+          node.leftHandSide.staticType,
+          operator,
+          node.rightHandSide.staticType,
+          staticType);
       _recordStaticType(node, staticType);
       MethodElement propagatedMethodElement = node.propagatedElement;
       if (!identical(propagatedMethodElement, staticMethodElement)) {
         DartType propagatedType =
             _computeStaticReturnType(propagatedMethodElement);
+        propagatedType = _typeSystem.refineBinaryExpressionType(
+            _typeProvider,
+            node.leftHandSide.propagatedType,
+            operator,
+            node.rightHandSide.propagatedType,
+            propagatedType);
         _resolver.recordPropagatedTypeIfBetter(node, propagatedType);
       }
     }
@@ -427,6 +428,10 @@
     if (node.parent is FunctionDeclarationStatement) {
       // TypeResolverVisitor sets the return type for top-level functions, so
       // we only need to handle local functions.
+      if (_strongMode && node.returnType == null) {
+        _inferLocalFunctionReturnType(node.functionExpression);
+        return null;
+      }
       functionElement.returnType =
           _computeStaticReturnTypeOfFunctionDeclaration(node);
       _recordPropagatedTypeOfFunction(functionElement, function.body);
@@ -472,37 +477,7 @@
       // node.
       return null;
     }
-    bool recordInference = false;
-    ExecutableElementImpl functionElement =
-        node.element as ExecutableElementImpl;
-
-    FunctionBody body = node.body;
-    DartType computedType;
-    if (body is ExpressionFunctionBody) {
-      computedType = _getStaticType(body.expression);
-    } else {
-      computedType = _dynamicType;
-    }
-
-    // If we had a better type from the function body, use it.
-    //
-    // This helps in a few cases:
-    // * ExpressionFunctionBody, when the surrounding context had a better type.
-    // * BlockFunctionBody, if we inferred a type from yield/return.
-    // * we also normalize bottom to dynamic here.
-    if (_strongMode && (computedType.isBottom || computedType.isDynamic)) {
-      computedType = InferenceContext.getType(body) ?? _dynamicType;
-      recordInference = !computedType.isDynamic;
-    }
-
-    computedType = _computeReturnTypeOfFunction(body, computedType);
-
-    functionElement.returnType = computedType;
-    _recordPropagatedTypeOfFunction(functionElement, node.body);
-    _recordStaticType(node, functionElement.type);
-    if (recordInference) {
-      _resolver.inferenceContext.recordInference(node, functionElement.type);
-    }
+    _inferLocalFunctionReturnType(node);
     return null;
   }
 
@@ -521,7 +496,7 @@
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     if (_strongMode) {
-      _inferGenericInvoke(node);
+      _inferGenericInvocationExpression(node);
     }
     DartType staticType = _computeInvokeReturnType(node.staticInvokeType);
     _recordStaticType(node, staticType);
@@ -574,6 +549,10 @@
    */
   @override
   Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    if (_strongMode) {
+      _inferInstanceCreationExpression(node);
+    }
+
     _recordStaticType(node, node.constructorName.type.type);
     ConstructorElement element = node.staticElement;
     if (element != null && "Element" == element.enclosingElement.name) {
@@ -812,7 +791,7 @@
     SimpleIdentifier methodNameNode = node.methodName;
     Element staticMethodElement = methodNameNode.staticElement;
     if (_strongMode) {
-      _inferGenericInvoke(node);
+      _inferGenericInvocationExpression(node);
     }
     // Record types of the variable invoked as a function.
     if (staticMethodElement is VariableElement) {
@@ -1445,8 +1424,8 @@
    */
   void _analyzeLeastUpperBound(
       Expression node, Expression expr1, Expression expr2) {
-    DartType staticType1 = _getStaticType(expr1);
-    DartType staticType2 = _getStaticType(expr2);
+    DartType staticType1 = _getDefiniteType(expr1);
+    DartType staticType2 = _getDefiniteType(expr2);
     if (staticType1 == null) {
       // TODO(brianwilkerson) Determine whether this can still happen.
       staticType1 = _dynamicType;
@@ -1605,6 +1584,33 @@
     return returnType.type;
   }
 
+  /**
+   * Given a constructor for a generic type, returns the equivalent generic
+   * function type that we could use to forward to the constructor, or for a
+   * non-generic type simply returns the constructor type.
+   *
+   * For example given the type `class C<T> { C(T arg); }`, the generic function
+   * type is `<T>(T) -> C<T>`.
+   */
+  FunctionType _constructorToGenericFunctionType(
+      ConstructorElement constructor) {
+    // TODO(jmesserly): it may be worth making this available from the
+    // constructor. It's nice if our inference code can operate uniformly on
+    // function types.
+    ClassElement cls = constructor.enclosingElement;
+    FunctionType type = constructor.type;
+    if (cls.typeParameters.isEmpty) {
+      return type;
+    }
+
+    FunctionElementImpl function = new FunctionElementImpl("", -1);
+    function.synthetic = true;
+    function.returnType = type.returnType;
+    function.shareTypeParameters(cls.typeParameters);
+    function.shareParameters(type.parameters);
+    return function.type = new FunctionTypeImpl(function);
+  }
+
   DartType _findIteratedType(DartType type, DartType targetType) {
     // TODO(vsm): Use leafp's matchType here?
     // Set by _find if match is found
@@ -1640,6 +1646,7 @@
         visitedClasses.remove(element);
       }
     }
+
     if (type is InterfaceType) {
       _find(type);
     }
@@ -1647,6 +1654,17 @@
   }
 
   /**
+   * Gets the definite type of expression, which can be used in cases where
+   * the most precise type is desired, for example computing the least upper
+   * bound.
+   *
+   * See [getDefiniteType] for more information. Without strong mode, this is
+   * equivalent to [_getStaticType].
+   */
+  DartType _getDefiniteType(Expression expr) =>
+      getDefiniteType(expr, _typeSystem, _typeProvider);
+
+  /**
    * If the given element name can be mapped to the name of a class defined within the given
    * library, return the type specified by the argument.
    *
@@ -1864,8 +1882,8 @@
   }
 
   /**
-   * Given an uninstantiated generic type, try to infer the instantiated generic
-   * type from the surrounding context.
+   * Given an uninstantiated generic function type, try to infer the
+   * instantiated generic function type from the surrounding context.
    */
   DartType _inferGenericInstantiationFromContext(
       DartType context, DartType type) {
@@ -1878,14 +1896,40 @@
     return type;
   }
 
-  bool _inferGenericInvoke(InvocationExpression node) {
+  /**
+   * Given a possibly generic invocation like `o.m(args)` or `(f)(args)` try to
+   * infer the instantiated generic function type.
+   *
+   * This takes into account both the context type, as well as information from
+   * the argument types.
+   */
+  void _inferGenericInvocationExpression(InvocationExpression node) {
+    ArgumentList arguments = node.argumentList;
+    FunctionType inferred = _inferGenericInvoke(
+        node, node.function.staticType, node.typeArguments, arguments);
+    if (inferred != null && inferred != node.staticInvokeType) {
+      // Fix up the parameter elements based on inferred method.
+      arguments.correspondingStaticParameters = ResolverVisitor
+          .resolveArgumentsToParameters(arguments, inferred.parameters, null);
+      node.staticInvokeType = inferred;
+    }
+  }
+
+  /**
+   * Given a possibly generic invocation or instance creation, such as
+   * `o.m(args)` or `(f)(args)` or `new T(args)` try to infer the instantiated
+   * generic function type.
+   *
+   * This takes into account both the context type, as well as information from
+   * the argument types.
+   */
+  FunctionType _inferGenericInvoke(Expression node, DartType fnType,
+      TypeArgumentList typeArguments, ArgumentList argumentList) {
     TypeSystem ts = _typeSystem;
-    DartType fnType = node.function.staticType;
-    if (node.typeArguments == null &&
+    if (typeArguments == null &&
         fnType is FunctionType &&
         fnType.typeFormals.isNotEmpty &&
         ts is StrongTypeSystemImpl) {
-      ArgumentList argumentList = node.argumentList;
       // Get the parameters that correspond to the uninstantiated generic.
       List<ParameterElement> rawParameters = ResolverVisitor
           .resolveArgumentsToParameters(argumentList, fnType.parameters, null);
@@ -1900,20 +1944,149 @@
         }
       }
 
-      FunctionType inferred = ts.inferGenericFunctionCall(_typeProvider, fnType,
-          paramTypes, argTypes, InferenceContext.getType(node));
-
-      if (inferred != node.staticInvokeType) {
-        // Fix up the parameter elements based on inferred method.
-        List<ParameterElement> inferredParameters =
-            ResolverVisitor.resolveArgumentsToParameters(
-                argumentList, inferred.parameters, null);
-        argumentList.correspondingStaticParameters = inferredParameters;
-        node.staticInvokeType = inferred;
-        return true;
+      DartType returnContext = InferenceContext.getContext(node);
+      DartType returnType;
+      if (returnContext is FutureUnionType) {
+        returnType = _resolver.isSubtypeOfFuture(fnType.returnType)
+            ? returnContext.futureOfType
+            : returnContext.type;
+      } else {
+        returnType = returnContext;
       }
+
+      // Special case Future<T>.then upwards inference. It has signature:
+      //
+      //     <S>(T -> (S | Future<S>)) -> Future<S>
+      //
+      // Based on the first argument type, we'll pick one of these signatures:
+      //
+      //     <S>(T -> S) -> Future<S>
+      //     <S>(T -> Future<S>) -> Future<S>
+      //
+      // ... and finish the inference using that.
+      if (argTypes.isNotEmpty && _resolver.isFutureThen(fnType.element)) {
+        var firstArgType = argTypes[0];
+        var firstParamType = paramTypes[0] as FunctionType;
+        if (firstArgType is FunctionType) {
+          var argReturnType = firstArgType.returnType;
+          // Skip the inference if we have the top type. It can only lead to
+          // worse inference. For example, this happens when the lambda returns
+          // S or Future<S> in a conditional.
+          if (!argReturnType.isObject && !argReturnType.isDynamic) {
+            DartType paramReturnType = fnType.typeFormals[0].type;
+            if (_resolver.isSubtypeOfFuture(argReturnType)) {
+              // Given an argument of (T) -> Future<S>, instantiate with <S>
+              paramReturnType =
+                  _typeProvider.futureType.instantiate([paramReturnType]);
+            }
+
+            // Adjust the expected parameter type to have this return type.
+            var function = new FunctionElementImpl(firstParamType.name, -1)
+              ..synthetic = true
+              ..shareParameters(firstParamType.parameters)
+              ..returnType = paramReturnType;
+            function.type = new FunctionTypeImpl(function);
+            // Use this as the expected 1st parameter type.
+            paramTypes[0] = function.type;
+          }
+        }
+      }
+      return ts.inferGenericFunctionCall(
+          _typeProvider, fnType, paramTypes, argTypes, returnType);
     }
-    return false;
+    return null;
+  }
+
+  /**
+   * Given an instance creation of a possibly generic type, infer the type
+   * arguments using the current context type as well as the argument types.
+   */
+  void _inferInstanceCreationExpression(InstanceCreationExpression node) {
+    ConstructorName constructor = node.constructorName;
+    ConstructorElement originalElement = constructor.staticElement;
+    // If the constructor is generic, we'll have a ConstructorMember that
+    // substitutes in type arguments (possibly `dynamic`) from earlier in
+    // resolution.
+    //
+    // Otherwise we'll have a ConstructorElement, and we can skip inference
+    // because there's nothing to infer in a non-generic type.
+    if (originalElement is! ConstructorMember) {
+      return;
+    }
+
+    // TODO(leafp): Currently, we may re-infer types here, since we
+    // sometimes resolve multiple times.  We should really check that we
+    // have not already inferred something.  However, the obvious ways to
+    // check this don't work, since we may have been instantiated
+    // to bounds in an earlier phase, and we *do* want to do inference
+    // in that case.
+
+    // Get back to the uninstantiated generic constructor.
+    // TODO(jmesserly): should we store this earlier in resolution?
+    // Or look it up, instead of jumping backwards through the Member?
+    var rawElement = (originalElement as ConstructorMember).baseElement;
+
+    FunctionType constructorType =
+        _constructorToGenericFunctionType(rawElement);
+
+    ArgumentList arguments = node.argumentList;
+    FunctionType inferred = _inferGenericInvoke(
+        node, constructorType, constructor.type.typeArguments, arguments);
+
+    if (inferred != null && inferred != originalElement.type) {
+      // Fix up the parameter elements based on inferred method.
+      arguments.correspondingStaticParameters = ResolverVisitor
+          .resolveArgumentsToParameters(arguments, inferred.parameters, null);
+      inferConstructorName(constructor, inferred.returnType);
+      // Update the static element as well. This is used in some cases, such as
+      // computing constant values. It is stored in two places.
+      constructor.staticElement =
+          ConstructorMember.from(rawElement, inferred.returnType);
+      node.staticElement = constructor.staticElement;
+    }
+  }
+
+  /**
+   * Infers the return type of a local function, either a lambda or
+   * (in strong mode) a local function declaration.
+   */
+  void _inferLocalFunctionReturnType(FunctionExpression node) {
+    bool recordInference = false;
+    ExecutableElementImpl functionElement =
+        node.element as ExecutableElementImpl;
+
+    FunctionBody body = node.body;
+    DartType computedType;
+    if (body is ExpressionFunctionBody) {
+      computedType = _getStaticType(body.expression);
+    } else {
+      computedType = _dynamicType;
+    }
+
+    // If we had a better type from the function body, use it.
+    //
+    // This helps in a few cases:
+    // * ExpressionFunctionBody, when the surrounding context had a better type.
+    // * BlockFunctionBody, if we inferred a type from yield/return.
+    // * we also normalize bottom to dynamic here.
+    if (_strongMode && (computedType.isBottom || computedType.isDynamic)) {
+      DartType contextType = InferenceContext.getContext(body);
+      if (contextType is FutureUnionType) {
+        // TODO(jmesserly): can we do something better here?
+        computedType = body.isAsynchronous ? contextType.type : _dynamicType;
+      } else {
+        computedType = contextType ?? _dynamicType;
+      }
+      recordInference = !computedType.isDynamic;
+    }
+
+    computedType = _computeReturnTypeOfFunction(body, computedType);
+    functionElement.returnType = computedType;
+    _recordPropagatedTypeOfFunction(functionElement, node.body);
+    _recordStaticType(node, functionElement.type);
+    if (recordInference) {
+      _resolver.inferenceContext.recordInference(node, functionElement.type);
+    }
   }
 
   /**
@@ -2146,44 +2319,6 @@
   }
 
   /**
-   * Attempts to make a better guess for the type of the given assignment
-   * [expression], given that resolution has so far produced the [currentType].
-   * The [typeAccessor] is used to access the corresponding type of the left
-   * and right operands.
-   */
-  DartType _refineAssignmentExpressionType(AssignmentExpression expression,
-      DartType currentType, DartType typeAccessor(Expression node)) {
-    Expression leftHandSize = expression.leftHandSide;
-    Expression rightHandSide = expression.rightHandSide;
-    TokenType operator = expression.operator.type;
-    DartType intType = _typeProvider.intType;
-    if (typeAccessor(leftHandSize) == intType) {
-      // int op= double
-      if (operator == TokenType.MINUS_EQ ||
-          operator == TokenType.PERCENT_EQ ||
-          operator == TokenType.PLUS_EQ ||
-          operator == TokenType.STAR_EQ) {
-        DartType doubleType = _typeProvider.doubleType;
-        if (typeAccessor(rightHandSide) == doubleType) {
-          return doubleType;
-        }
-      }
-      // int op= int
-      if (operator == TokenType.MINUS_EQ ||
-          operator == TokenType.PERCENT_EQ ||
-          operator == TokenType.PLUS_EQ ||
-          operator == TokenType.STAR_EQ ||
-          operator == TokenType.TILDE_SLASH_EQ) {
-        if (typeAccessor(rightHandSide) == intType) {
-          return intType;
-        }
-      }
-    }
-    // default
-    return currentType;
-  }
-
-  /**
    * Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that
    * implement those tags.
    *
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 0a524fa..6a36a8b 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -22,7 +22,7 @@
  * A type provider that can be used by tests without creating the element model
  * for the core library.
  */
-class TestTypeProvider implements TypeProvider {
+class TestTypeProvider extends TypeProviderBase {
   /**
    * The type representing the built-in type 'bool'.
    */
@@ -388,16 +388,6 @@
   }
 
   @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);
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 74e3fd2..9a4a5cf 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -15,7 +15,9 @@
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
-import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
+import 'package:analyzer/src/generated/utilities_general.dart'
+    show JenkinsSmiHash;
 
 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
 
@@ -31,14 +33,52 @@
    */
   final bool implicitCasts;
 
-  StrongTypeSystemImpl({this.implicitCasts: true});
+  /**
+   * A list of non-nullable type names (e.g., 'int', 'bool', etc.).
+   */
+  final List<String> nonnullableTypes;
+
+  StrongTypeSystemImpl(
+      {this.implicitCasts: true,
+      this.nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES});
 
   bool anyParameterType(FunctionType ft, bool predicate(DartType t)) {
     return ft.parameters.any((p) => predicate(p.type));
   }
 
   @override
-  bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from);
+  bool canPromoteToType(DartType to, DartType from) {
+    // Allow promoting to a subtype, for example:
+    //
+    //     f(Base b) {
+    //       if (b is SubTypeOfBase) {
+    //         // promote `b` to SubTypeOfBase for this block
+    //       }
+    //     }
+    //
+    // This allows the variable to be used wherever the supertype (here `Base`)
+    // is expected, while gaining a more precise type.
+    if (isSubtypeOf(to, from)) {
+      return true;
+    }
+    // For a type parameter `T extends U`, allow promoting from the upper bound
+    // `U` to `S` where `S <: U`.
+    //
+    // This does restrict the variable, because `S </: T`, it can no longer be
+    // used as a `T` without another cast.
+    //
+    // However the members you could access from a variable of type `T`, were
+    // already those on the upper bound `U`. So all members on `U` will be
+    // accessible, as well as those on `S`. Pragmatically this feels like a
+    // useful enough trade-off to allow promotion.
+    //
+    // (In general we would need union types to support this feature precisely.)
+    if (from is TypeParameterType) {
+      return isSubtypeOf(to, from.resolveToBound(DynamicTypeImpl.instance));
+    }
+
+    return false;
+  }
 
   @override
   FunctionType functionTypeToConcreteType(
@@ -84,26 +124,24 @@
 
   /// Computes the greatest lower bound of [type1] and [type2].
   DartType getGreatestLowerBound(
-      TypeProvider provider, DartType type1, DartType type2) {
+      TypeProvider provider, DartType type1, DartType type2,
+      {dynamicIsBottom: false}) {
     // The greatest lower bound relation is reflexive.
     if (identical(type1, type2)) {
       return type1;
     }
 
-    // Treat dynamic as top. The GLB of dynamic and any type is just that type
-    // since dynamic permits all values.
-    if (type1.isDynamic) {
+    // The GLB of top and any type is just that type.
+    // Also GLB of bottom and any type is bottom.
+    if (_isTop(type1, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(type2, dynamicIsBottom: dynamicIsBottom)) {
       return type2;
     }
-    if (type2.isDynamic) {
+    if (_isTop(type2, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(type1, dynamicIsBottom: dynamicIsBottom)) {
       return type1;
     }
 
-    // You can't get any lower than bottom.
-    if (type1.isBottom || type2.isBottom) {
-      return provider.bottomType;
-    }
-
     // Treat void as top-like for GLB. This only comes into play with the
     // return types of two functions whose GLB is being taken. We allow a
     // non-void-returning function to subtype a void-returning one, so match
@@ -135,6 +173,41 @@
   }
 
   /**
+   * Compute the least upper bound of two types.
+   */
+  @override
+  DartType getLeastUpperBound(
+      TypeProvider typeProvider, DartType type1, DartType type2,
+      {bool dynamicIsBottom: false}) {
+    if (isNullableType(type1) && isNonNullableType(type2)) {
+      assert(type2 is InterfaceType);
+      type2 = getLeastNullableSupertype(type2 as InterfaceType);
+    }
+    if (isNullableType(type2) && isNonNullableType(type1)) {
+      assert(type1 is InterfaceType);
+      type1 = getLeastNullableSupertype(type1 as InterfaceType);
+    }
+    return super.getLeastUpperBound(typeProvider, type1, type2,
+        dynamicIsBottom: dynamicIsBottom);
+  }
+
+  /**
+   * Compute the least supertype of [type], which is known to be an interface
+   * type.
+   *
+   * In the event that the algorithm fails (which might occur due to a bug in
+   * the analyzer), `null` is returned.
+   */
+  DartType getLeastNullableSupertype(InterfaceType type) {
+    // compute set of supertypes
+    List<InterfaceType> s = InterfaceTypeImpl
+        .computeSuperinterfaceSet(type)
+        .where(isNullableType)
+        .toList();
+    return InterfaceTypeImpl.computeTypeAtMaxUniqueDepth(s);
+  }
+
+  /**
    * Given a generic function type `F<T0, T1, ... Tn>` and a context type C,
    * infer an instantiation of F, such that `F<S0, S1, ..., Sn>` <: C.
    *
@@ -156,7 +229,7 @@
     // subtypes (or supertypes) as necessary, and track the constraints that
     // are implied by this.
     var inferringTypeSystem =
-        new _StrongInferenceTypeSystem(typeProvider, fnType.typeFormals);
+        new _StrongInferenceTypeSystem(typeProvider, this, fnType.typeFormals);
 
     // Since we're trying to infer the instantiation, we want to ignore type
     // formals as we check the parameters and return type.
@@ -167,8 +240,7 @@
     }
 
     // Try to infer and instantiate the resulting type.
-    var resultType =
-        inferringTypeSystem._infer(fnType, allowPartialSolution: false);
+    var resultType = inferringTypeSystem._infer(fnType);
 
     // If the instantiation failed (because some type variable constraints
     // could not be solved, in other words, we could not find a valid subtype),
@@ -210,24 +282,7 @@
     // subtypes (or supertypes) as necessary, and track the constraints that
     // are implied by this.
     var inferringTypeSystem =
-        new _StrongInferenceTypeSystem(typeProvider, fnType.typeFormals);
-
-    // Special case inference for Future.then.
-    //
-    // We don't have union types, so Future<T>.then<S> is typed to take a
-    // callback `T -> S`. However, the lambda might actually return a
-    // Future<S>. So we handle that special case here.
-    if (argumentTypes.isNotEmpty && argumentTypes[0] is FunctionType) {
-      Element element = fnType?.element;
-      bool isFutureThen = element is MethodElement &&
-          element.name == 'then' &&
-          element.enclosingElement.type.isDartAsyncFuture;
-      if (isFutureThen) {
-        // Ignore return context. We'll let the onValue function's return type
-        // drive inference.
-        returnContextType = null;
-      }
-    }
+        new _StrongInferenceTypeSystem(typeProvider, this, fnType.typeFormals);
 
     if (returnContextType != null) {
       inferringTypeSystem.isSubtypeOf(fnType.returnType, returnContextType);
@@ -240,14 +295,7 @@
           argumentTypes[i], correspondingParameterTypes[i]);
     }
 
-    // We are okay inferring some type variables and not others.
-    //
-    // This lets our return type be as precise as possible, which will help
-    // make any type information resulting from it more precise.
-    //
-    // This is simply a heuristic: the code is incorrect, and we'll issue an
-    // error on this call, to indicate that types don't match.
-    return inferringTypeSystem._infer(fnType, allowPartialSolution: true);
+    return inferringTypeSystem._infer(fnType);
   }
 
   /**
@@ -306,8 +354,7 @@
 
     // 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)) {
+    if (fromType is FunctionType && getCallMethodType(toType) != null) {
       return false;
     }
 
@@ -325,7 +372,7 @@
 
     // If the subtype relation goes the other way, allow the implicit
     // downcast.
-    if (isSubtypeOf(toType, fromType) || toType.isAssignableTo(fromType)) {
+    if (isSubtypeOf(toType, fromType)) {
       // TODO(leafp,jmesserly): we emit warnings/hints for these in
       // src/task/strong/checker.dart, which is a bit inconsistent. That
       // code should be handled into places that use isAssignableTo, such as
@@ -444,7 +491,8 @@
       DartType paramType;
       if (fType != null && gType != null) {
         // If both functions have this parameter, include both of their types.
-        paramType = getLeastUpperBound(provider, fType, gType);
+        paramType =
+            getLeastUpperBound(provider, fType, gType, dynamicIsBottom: true);
       } else {
         paramType = fType ?? gType;
       }
@@ -528,7 +576,7 @@
   @override
   DartType _functionParameterBound(
           TypeProvider provider, DartType f, DartType g) =>
-      getGreatestLowerBound(provider, f, g);
+      getGreatestLowerBound(provider, f, g, dynamicIsBottom: true);
 
   /**
    * Guard against loops in the class hierarchy
@@ -607,10 +655,6 @@
         provider.dynamicType;
   }
 
-  bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
-    return (t.isDynamic && dynamicIsBottom) || t.isBottom;
-  }
-
   /**
    * Check that [f1] is a subtype of [f2].
    *
@@ -630,8 +674,9 @@
   bool _isInterfaceSubtypeOf(
       InterfaceType i1, InterfaceType i2, Set<Element> visited) {
     // Guard recursive calls
-    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
-        _guard(_isInterfaceSubtypeOf);
+    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype = _guard(
+        (DartType i1, DartType i2, Set<Element> visited) =>
+            _isInterfaceSubtypeOf(i1, i2, visited));
 
     if (i1 == i2) {
       return true;
@@ -690,8 +735,8 @@
       return true;
     }
 
-    // The types are void, dynamic, bottom, interface types, function types
-    // and type parameters.  We proceed by eliminating these different classes
+    // The types are void, dynamic, bottom, interface types, function types,
+    // and type parameters. We proceed by eliminating these different classes
     // from consideration.
 
     // Trivially true.
@@ -758,9 +803,22 @@
     return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType);
   }
 
-  bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
-    // TODO(leafp): Document the rules in play here
-    return (t.isDynamic && !dynamicIsBottom) || t.isObject;
+  /// Check if [type] is in a set of preselected non-nullable types.
+  /// [FunctionType]s are always nullable.
+  bool isNonNullableType(DartType type) {
+    return !isNullableType(type);
+  }
+
+  /// Opposite of [isNonNullableType].
+  bool isNullableType(DartType type) {
+    return type is FunctionType ||
+        !nonnullableTypes.contains(_getTypeFullyQualifiedName(type));
+  }
+
+  /// Given a type return its name prepended with the URI to its containing
+  /// library and separated by a comma.
+  String _getTypeFullyQualifiedName(DartType type) {
+    return "${type?.element?.library?.identifier},$type";
   }
 
   /**
@@ -863,16 +921,20 @@
    * Compute the least upper bound of two types.
    */
   DartType getLeastUpperBound(
-      TypeProvider typeProvider, DartType type1, DartType type2) {
+      TypeProvider typeProvider, DartType type1, DartType type2,
+      {bool dynamicIsBottom: false}) {
     // 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) {
+    // The least upper bound of top and any type T is top.
+    // The least upper bound of bottom and any type T is T.
+    if (_isTop(type1, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(type2, dynamicIsBottom: dynamicIsBottom)) {
       return type1;
     }
-    if (type2.isDynamic) {
+    if (_isTop(type2, dynamicIsBottom: dynamicIsBottom) ||
+        _isBottom(type1, dynamicIsBottom: dynamicIsBottom)) {
       return type2;
     }
     // The least upper bound of void and any type T != dynamic is void.
@@ -882,13 +944,6 @@
     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;
-    }
 
     if (type1 is TypeParameterType || type2 is TypeParameterType) {
       return _typeParameterLeastUpperBound(typeProvider, type1, type2);
@@ -1193,7 +1248,9 @@
   static TypeSystem create(AnalysisContext context) {
     var options = context.analysisOptions as AnalysisOptionsImpl;
     return options.strongMode
-        ? new StrongTypeSystemImpl(implicitCasts: options.implicitCasts)
+        ? new StrongTypeSystemImpl(
+            implicitCasts: options.implicitCasts,
+            nonnullableTypes: options.nonnullableTypes)
         : new TypeSystemImpl();
   }
 }
@@ -1267,45 +1324,60 @@
 }
 
 /// Tracks upper and lower type bounds for a set of type parameters.
+///
+/// This class is used by calling [isSubtypeOf]. When it encounters one of
+/// the type parameters it is inferring, it will record the constraint, and
+/// optimistically assume the constraint will be satisfied.
+///
+/// For example if we are inferring type parameter A, and we ask if
+/// `A <: num`, this will record that A must be a subytpe of `num`. It also
+/// handles cases when A appears as part of the structure of another type, for
+/// example `Iterable<A> <: Iterable<num>` would infer the same constraint
+/// (due to covariant generic types) as would `() -> A <: () -> num`. In
+/// contrast `(A) -> void <: (num) -> void`.
+///
+/// Once the lower/upper bounds are determined, [_infer] should be called to
+/// finish the inference. It will instantiate a generic function type with the
+/// inferred types for each type parameter.
+///
+/// It can also optionally compute a partial solution, in case some of the type
+/// parameters could not be inferred (because the constraints cannot be
+/// satisfied), or bail on the inference when this happens.
+///
+/// As currently designed, an instance of this class should only be used to
+/// infer a single call and discarded immediately afterwards.
 class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
   final TypeProvider _typeProvider;
+
+  /// The outer strong mode type system, used for GLB and LUB, so we don't
+  /// recurse into our constraint solving code.
+  final StrongTypeSystemImpl _typeSystem;
   final Map<TypeParameterType, _TypeParameterBound> _bounds;
 
-  _StrongInferenceTypeSystem(
-      this._typeProvider, Iterable<TypeParameterElement> typeFormals)
-      : _bounds =
-            new Map.fromIterable(typeFormals, key: (t) => t.type, value: (t) {
-          _TypeParameterBound bound = new _TypeParameterBound();
-          if (t.bound != null) bound.upper = t.bound;
-          return bound;
-        });
+  _StrongInferenceTypeSystem(this._typeProvider, this._typeSystem,
+      Iterable<TypeParameterElement> typeFormals)
+      : _bounds = new Map.fromIterable(typeFormals,
+            key: (t) => t.type, value: (t) => new _TypeParameterBound());
 
   /// Given the constraints that were given by calling [isSubtypeOf], find the
   /// instantiation of the generic function that satisfies these constraints.
-  FunctionType _infer(FunctionType fnType, {bool allowPartialSolution: false}) {
+  FunctionType _infer(FunctionType fnType) {
     List<TypeParameterType> fnTypeParams =
         TypeParameterTypeImpl.getTypes(fnType.typeFormals);
 
-    var inferredTypes = new List<DartType>.from(fnTypeParams, growable: false);
+    // Initialize the inferred type array.
+    //
+    // They all start as `dynamic` to offer reasonable degradation for f-bounded
+    // type parameters.
+    var inferredTypes = new List<DartType>.filled(
+        fnTypeParams.length, DynamicTypeImpl.instance,
+        growable: false);
+
     for (int i = 0; i < fnTypeParams.length; i++) {
       TypeParameterType typeParam = fnTypeParams[i];
-      _TypeParameterBound bound = _bounds[typeParam];
 
-      // Now we've computed lower and upper bounds for each type parameter.
+      // Apply the `extends` clause for the type parameter, if any.
       //
-      // 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:
@@ -1321,8 +1393,28 @@
       // Or if the type parameter's bound depends on itself such as:
       //
       //     <T extends Clonable<T>>
+      DartType declaredUpperBound = typeParam.element.bound;
+      if (declaredUpperBound != null) {
+        // Assert that the type parameter is a subtype of its bound.
+        _inferTypeParameterSubtypeOf(typeParam,
+            declaredUpperBound.substitute2(inferredTypes, fnTypeParams), null);
+      }
+
+      // 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);
+
+      _TypeParameterBound bound = _bounds[typeParam];
       inferredTypes[i] =
-          inferredTypes[i].substitute2(inferredTypes, fnTypeParams);
+          variance.passedIn || bound.lower.isBottom ? bound.upper : bound.lower;
 
       // See if the constraints on the type variable are satisfied.
       //
@@ -1335,16 +1427,8 @@
               bound.upper.substitute2(inferredTypes, fnTypeParams)) ||
           !isSubtypeOf(bound.lower.substitute2(inferredTypes, fnTypeParams),
               inferredTypes[i])) {
-        // Unless a partial solution was requested, bail.
-        if (!allowPartialSolution) {
-          return null;
-        }
-
-        inferredTypes[i] = DynamicTypeImpl.instance;
-        if (typeParam.element.bound != null) {
-          inferredTypes[i] =
-              typeParam.element.bound.substitute2(inferredTypes, fnTypeParams);
-        }
+        // Inference failed. Bail.
+        return null;
       }
     }
 
@@ -1364,7 +1448,8 @@
         // We already know T1 <: U, for some U.
         // So update U to reflect the new constraint T1 <: GLB(U, T2)
         //
-        bound.upper = getGreatestLowerBound(_typeProvider, bound.upper, t2);
+        bound.upper =
+            _typeSystem.getGreatestLowerBound(_typeProvider, bound.upper, t2);
         // Optimistically assume we will be able to satisfy the constraint.
         return true;
       }
@@ -1378,7 +1463,8 @@
         // We already know L <: T2, for some L.
         // So update L to reflect the new constraint LUB(L, T1) <: T2
         //
-        bound.lower = getLeastUpperBound(_typeProvider, bound.lower, t1);
+        bound.lower =
+            _typeSystem.getLeastUpperBound(_typeProvider, bound.lower, t1);
         // Optimistically assume we will be able to satisfy the constraint.
         return true;
       }
@@ -1497,3 +1583,106 @@
     }
   }
 }
+
+/**
+ * A special union type of `Future<T> | T` used for Strong Mode inference.
+ */
+class FutureUnionType extends TypeImpl {
+  // TODO(jmesserly): a Set would be better.
+  //
+  // For now we know `Future<T> | T` is the only valid use, so we can rely on
+  // the order, which simplifies some things.
+  //
+  // This will need clean up before this can function as a real union type.
+  final List<DartType> _types;
+
+  /**
+   * Creates a union of `Future< flatten(T) > | flatten(T)`.
+   */
+  factory FutureUnionType(
+      DartType type, TypeProvider provider, TypeSystem system) {
+    type = type.flattenFutures(system);
+
+    // The order of these types is important: T could be a type variable, so
+    // we want to try and match `Future<T>` before we try and match `T`.
+    return new FutureUnionType._([
+      provider.futureType.instantiate([type]),
+      type
+    ]);
+  }
+
+  FutureUnionType._(this._types) : super(null, null);
+
+  DartType get futureOfType => _types[0];
+
+  DartType get type => _types[1];
+
+  Iterable<DartType> get types => _types;
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write('(');
+    for (int i = 0; i < _types.length; i++) {
+      if (i != 0) {
+        buffer.write(' | ');
+      }
+      (_types[i] as TypeImpl).appendTo(buffer);
+    }
+    buffer.write(')');
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    for (var t in types) {
+      hash = JenkinsSmiHash.combine(hash, t.hashCode);
+    }
+    return JenkinsSmiHash.finish(hash);
+  }
+
+  @override
+  bool operator ==(Object obj) {
+    if (obj is FutureUnionType) {
+      if (identical(obj, this)) return true;
+      return types.length == obj.types.length &&
+          types.toSet().containsAll(obj.types);
+    }
+    return false;
+  }
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+          [bool withDynamic = false, Set<Element> visitedElements]) =>
+      throw new UnsupportedError(
+          'Future unions are not part of the Dart 1 type system');
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) =>
+      throw new UnsupportedError('Future unions are not substituted');
+
+  @override
+  DartType substitute2(List<DartType> args, List<DartType> params,
+          [List<FunctionTypeAliasElement> prune]) =>
+      throw new UnsupportedError('Future unions are not used in typedefs');
+
+  /**
+   * Creates a union of `flatten(T) | Future<flatten(T)>`, unless `T` is
+   * already a future-union, in which case it simply returns `T`
+   */
+  static DartType from(
+      DartType type, TypeProvider provider, TypeSystem system) {
+    if (type is FutureUnionType) {
+      return type;
+    }
+    return new FutureUnionType(type, provider, system);
+  }
+}
+
+bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
+  return (t.isDynamic && dynamicIsBottom) || t.isBottom;
+}
+
+bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
+  // TODO(leafp): Document the rules in play here
+  return (t.isDynamic && !dynamicIsBottom) || t.isObject;
+}
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index 1409cd5..d244dce 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -27,21 +27,14 @@
   }
   Uri origBaseUri = baseUri;
   try {
-    bool isOpaque = baseUri.isAbsolute && !baseUri.path.startsWith('/');
-    if (isOpaque) {
-      String scheme = baseUri.scheme;
+    String scheme = baseUri.scheme;
+    if (scheme == DartUriResolver.DART_SCHEME) {
       String part = baseUri.path;
-      if (scheme == DartUriResolver.DART_SCHEME && part.indexOf('/') < 0) {
-        part = "$part/$part.dart";
+      if (part.indexOf('/') < 0) {
+        baseUri = FastUri.parse('$scheme:$part/$part.dart');
       }
-      baseUri = FastUri.parse("$scheme:/$part");
     }
-    Uri result = baseUri.resolveUri(containedUri);
-    if (isOpaque) {
-      result =
-          FastUri.parse("${result.scheme}:${result.path.substring(1)}");
-    }
-    return result;
+    return baseUri.resolveUri(containedUri);
   } catch (exception, stackTrace) {
     throw new AnalysisException(
         "Could not resolve URI ($containedUri) relative to source ($origBaseUri)",
diff --git a/pkg/analyzer/lib/src/source/source_resource.dart b/pkg/analyzer/lib/src/source/source_resource.dart
new file mode 100644
index 0000000..2d188d8
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/source_resource.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.source.source_resource;
+
+import 'dart:collection';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+/**
+ * A source that represents a file.
+ */
+class FileSource extends Source {
+  /**
+   * A function that changes the way that files are read off of disk.
+   */
+  static Function fileReadMode = (String s) => s;
+
+  /**
+   * Map from encoded URI/filepath pair to a unique integer identifier.  This
+   * identifier is used for equality tests and hash codes.
+   *
+   * The URI and filepath are joined into a pair by separating them with an '@'
+   * character.
+   */
+  static final Map<String, int> _idTable = new HashMap<String, int>();
+
+  /**
+   * The URI from which this source was originally derived.
+   */
+  @override
+  final Uri uri;
+
+  /**
+   * The unique ID associated with this source.
+   */
+  final int id;
+
+  /**
+   * The file represented by this source.
+   */
+  final File file;
+
+  /**
+   * The cached absolute path of this source.
+   */
+  String _absolutePath;
+
+  /**
+   * The cached encoding for this source.
+   */
+  String _encoding;
+
+  /**
+   * Initialize a newly created source object to represent the given [file]. If
+   * a [uri] is given, then it will be used as the URI from which the source was
+   * derived, otherwise a `file:` URI will be created based on the [file].
+   */
+  FileSource(File file, [Uri uri])
+      : this.uri = uri ?? file.toUri(),
+        this.file = file,
+        id = _idTable.putIfAbsent(
+            '${uri ?? file.toUri()}@${file.path}', () => _idTable.length);
+
+  @override
+  TimestampedData<String> get contents {
+    return PerformanceStatistics.io.makeCurrentWhile(() {
+      return contentsFromFile;
+    });
+  }
+
+  /**
+   * Get and return the contents and timestamp of the underlying file.
+   *
+   * Clients should consider using the method [AnalysisContext.getContents]
+   * because contexts can have local overrides of the content of a source that
+   * the source is not aware of.
+   *
+   * Throws an exception if the contents of this source could not be accessed.
+   * See [contents].
+   */
+  TimestampedData<String> get contentsFromFile {
+    return new TimestampedData<String>(
+        modificationStamp, fileReadMode(file.readAsStringSync()));
+  }
+
+  @override
+  String get encoding => _encoding ??= uri.toString();
+
+  @override
+  String get fullName => _absolutePath ??= file.path;
+
+  @override
+  int get hashCode => uri.hashCode;
+
+  @override
+  bool get isInSystemLibrary => uri.scheme == DartUriResolver.DART_SCHEME;
+
+  @override
+  int get modificationStamp {
+    try {
+      return file.modificationStamp;
+    } on FileSystemException {
+      return -1;
+    }
+  }
+
+  @override
+  String get shortName => file.shortName;
+
+  @override
+  UriKind get uriKind => UriKind.fromScheme(uri.scheme);
+
+  @override
+  bool operator ==(Object object) {
+    if (object is FileSource) {
+      return id == object.id;
+    } else if (object is Source) {
+      return uri == object.uri;
+    }
+    return false;
+  }
+
+  @override
+  bool exists() => file.exists;
+
+  @override
+  String toString() {
+    if (file == null) {
+      return "<unknown source>";
+    }
+    return file.path;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/api_signature.dart b/pkg/analyzer/lib/src/summary/api_signature.dart
new file mode 100644
index 0000000..f2fd506
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/api_signature.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.api_signature;
+
+import 'dart:convert';
+import 'dart:typed_data';
+
+import 'package:convert/convert.dart';
+import 'package:crypto/crypto.dart';
+
+/**
+ * An instance of [ApiSignature] collects data in the form of primitive types
+ * (strings, ints, bools, etc.) from a summary "builder" object, and uses them
+ * to generate an MD5 signature of a the non-informative parts of the summary
+ * (i.e. those parts representing the API of the code being summarized).
+ *
+ * Note that the data passed to the MD5 signature algorithm is untyped.  So, for
+ * instance, an API signature built from a sequence of `false` booleans is
+ * likely to match an API signature built from a sequence of zeros.  The caller
+ * should take this into account; e.g. if a data structure may be represented
+ * either by a boolean or an int, the caller should encode a tag distinguishing
+ * the two representations before encoding the data.
+ */
+class ApiSignature {
+  /**
+   * Version number of the code in this class.  Any time this class is changed
+   * in a way that affects the data collected in [_data], this version number
+   * should be incremented, so that a summary signed by a newer version of the
+   * signature algorithm won't accidentally have the same signature as a summary
+   * signed by an older version.
+   */
+  static const int _VERSION = 0;
+
+  /**
+   * Data accumulated so far.
+   */
+  ByteData _data = new ByteData(4096);
+
+  /**
+   * Offset into [_data] where the next byte should be written.
+   */
+  int _offset = 0;
+
+  /**
+   * Create an [ApiSignature] which is ready to accept data.
+   */
+  ApiSignature() {
+    addInt(_VERSION);
+  }
+
+  /**
+   * For testing only: create an [ApiSignature] which doesn't include any
+   * version information.  This makes it easier to unit tests, since the data
+   * is stable even if [_VERSION] is changed.
+   */
+  ApiSignature.unversioned();
+
+  /**
+   * Collect a boolean value.
+   */
+  void addBool(bool b) {
+    _makeRoom(1);
+    _data.setUint8(_offset, b ? 1 : 0);
+    _offset++;
+  }
+
+  /**
+   * Collect a sequence of arbitrary bytes.  Note that the length is not
+   * collected, so for example `addBytes([1, 2]);` will have the same effect as
+   * `addBytes([1]); addBytes([2]);`.
+   */
+  void addBytes(List<int> bytes) {
+    _makeRoom(bytes.length);
+    new Uint8List.view(_data.buffer)
+        .setRange(_offset, _offset + bytes.length, bytes);
+    _offset += bytes.length;
+  }
+
+  /**
+   * Collect a double-precision floating point value.
+   */
+  void addDouble(double d) {
+    _makeRoom(8);
+    _data.setFloat64(_offset, d, Endianness.LITTLE_ENDIAN);
+    _offset += 8;
+  }
+
+  /**
+   * Collect a 32-bit unsigned integer value.
+   */
+  void addInt(int i) {
+    _makeRoom(4);
+    _data.setUint32(_offset, i, Endianness.LITTLE_ENDIAN);
+    _offset += 4;
+  }
+
+  /**
+   * Collect a string.
+   */
+  void addString(String s) {
+    List<int> bytes = UTF8.encode(s);
+    addInt(bytes.length);
+    addBytes(bytes);
+  }
+
+  /**
+   * For testing only: retrieve the internal representation of the data that
+   * has been collected.
+   */
+  List<int> getBytes_forDebug() {
+    return new Uint8List.view(_data.buffer, 0, _offset).toList();
+  }
+
+  /**
+   * Return a hex-encoded MD5 signature of the data collected so far.
+   */
+  String toHex() {
+    return hex.encode(
+        md5.convert(new Uint8List.view(_data.buffer, 0, _offset)).bytes);
+  }
+
+  /**
+   * Ensure that [spaceNeeded] bytes can be added to [_data] at [_offset]
+   * (copying it to a larger object if necessary).
+   */
+  void _makeRoom(int spaceNeeded) {
+    int oldLength = _data.lengthInBytes;
+    if (_offset + spaceNeeded > oldLength) {
+      int newLength = 2 * (_offset + spaceNeeded);
+      ByteData newData = new ByteData(newLength);
+      new Uint8List.view(newData.buffer)
+          .setRange(0, oldLength, new Uint8List.view(_data.buffer));
+      _data = newData;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 1034bc5..626f443 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -10,6 +10,7 @@
 import 'flat_buffers.dart' as fb;
 import 'idl.dart' as idl;
 import 'dart:convert' as convert;
+import 'api_signature.dart' as api_sig;
 
 class _CacheSourceKindReader extends fb.Reader<idl.CacheSourceKind> {
   const _CacheSourceKindReader() : super();
@@ -216,6 +217,17 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._errorCodeUniqueName ?? '');
+    signature.addInt(this._offset ?? 0);
+    signature.addInt(this._length ?? 0);
+    signature.addString(this._message ?? '');
+    signature.addString(this._correction ?? '');
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_correction;
     fb.Offset offset_errorCodeUniqueName;
@@ -385,6 +397,37 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+    if (this._importedUris == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._importedUris.length);
+      for (var x in this._importedUris) {
+        signature.addString(x);
+      }
+    }
+    if (this._exportedUris == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._exportedUris.length);
+      for (var x in this._exportedUris) {
+        signature.addString(x);
+      }
+    }
+    if (this._partUris == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._partUris.length);
+      for (var x in this._partUris) {
+        signature.addString(x);
+      }
+    }
+  }
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder), "CaSS");
@@ -514,6 +557,20 @@
     _errors?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._errors == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._errors.length);
+      for (var x in this._errors) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder), "CSEL");
@@ -612,6 +669,14 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addInt(this._offset ?? 0);
+    signature.addInt(this._length ?? 0);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fbBuilder.startTable();
     if (_length != null && _length != 0) {
@@ -820,6 +885,41 @@
     _typeArguments?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addInt(this._reference ?? 0);
+    if (this._typeArguments == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._typeArguments.length);
+      for (var x in this._typeArguments) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addInt(this._slot ?? 0);
+    signature.addInt(this._paramReference ?? 0);
+    if (this._implicitFunctionTypeIndices == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._implicitFunctionTypeIndices.length);
+      for (var x in this._implicitFunctionTypeIndices) {
+        signature.addInt(x);
+      }
+    }
+    signature.addBool(this._syntheticReturnType != null);
+    this._syntheticReturnType?.collectApiSignature(signature);
+    if (this._syntheticParams == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._syntheticParams.length);
+      for (var x in this._syntheticParams) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_implicitFunctionTypeIndices;
     fb.Offset offset_syntheticParams;
@@ -995,6 +1095,21 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._uri ?? '');
+    if (this._parts == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parts.length);
+      for (var x in this._parts) {
+        signature.addString(x);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_parts;
     fb.Offset offset_uri;
@@ -1128,6 +1243,16 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addInt(this._dependency ?? 0);
+    signature.addString(this._name ?? '');
+    signature.addInt(this._unit ?? 0);
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_name;
     if (_name != null) {
@@ -1341,6 +1466,54 @@
     _units?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._dependencies == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._dependencies.length);
+      for (var x in this._dependencies) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._importDependencies == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._importDependencies.length);
+      for (var x in this._importDependencies) {
+        signature.addInt(x);
+      }
+    }
+    signature.addInt(this._numPrelinkedDependencies ?? 0);
+    if (this._units == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._units.length);
+      for (var x in this._units) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._exportNames == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._exportNames.length);
+      for (var x in this._exportNames) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._fallbackMode == true);
+    if (this._exportDependencies == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._exportDependencies.length);
+      for (var x in this._exportDependencies) {
+        signature.addInt(x);
+      }
+    }
+  }
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder), "LLib");
@@ -1617,6 +1790,19 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addInt(this._unit ?? 0);
+    signature.addInt(this._dependency ?? 0);
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+    signature.addString(this._name ?? '');
+    signature.addInt(this._numTypeParameters ?? 0);
+    signature.addInt(this._containingReference ?? 0);
+    signature.addInt(this._localIndex ?? 0);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_name;
     if (_name != null) {
@@ -1797,6 +1983,36 @@
     _types?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._references == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._references.length);
+      for (var x in this._references) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._types == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._types.length);
+      for (var x in this._types) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._constCycles == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._constCycles.length);
+      for (var x in this._constCycles) {
+        signature.addInt(x);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_constCycles;
     fb.Offset offset_references;
@@ -1882,6 +2098,8 @@
 }
 
 class PackageBundleBuilder extends Object with _PackageBundleMixin implements idl.PackageBundle {
+  String _apiSignature;
+  List<PackageDependencyInfoBuilder> _dependencies;
   List<LinkedLibraryBuilder> _linkedLibraries;
   List<String> _linkedLibraryUris;
   int _majorVersion;
@@ -1891,6 +2109,28 @@
   List<String> _unlinkedUnitUris;
 
   @override
+  String get apiSignature => _apiSignature ??= '';
+
+  /**
+   * MD5 hash of the non-informative fields of the [PackageBundle] (not
+   * including this one).  This can be used to identify when the API of a
+   * package may have changed.
+   */
+  void set apiSignature(String _value) {
+    _apiSignature = _value;
+  }
+
+  @override
+  List<PackageDependencyInfoBuilder> get dependencies => _dependencies ??= <PackageDependencyInfoBuilder>[];
+
+  /**
+   * Information about the packages this package depends on, if known.
+   */
+  void set dependencies(List<PackageDependencyInfoBuilder> _value) {
+    _dependencies = _value;
+  }
+
+  @override
   List<LinkedLibraryBuilder> get linkedLibraries => _linkedLibraries ??= <LinkedLibraryBuilder>[];
 
   /**
@@ -1966,8 +2206,10 @@
     _unlinkedUnitUris = _value;
   }
 
-  PackageBundleBuilder({List<LinkedLibraryBuilder> linkedLibraries, List<String> linkedLibraryUris, int majorVersion, int minorVersion, List<String> unlinkedUnitHashes, List<UnlinkedUnitBuilder> unlinkedUnits, List<String> unlinkedUnitUris})
-    : _linkedLibraries = linkedLibraries,
+  PackageBundleBuilder({String apiSignature, List<PackageDependencyInfoBuilder> dependencies, List<LinkedLibraryBuilder> linkedLibraries, List<String> linkedLibraryUris, int majorVersion, int minorVersion, List<String> unlinkedUnitHashes, List<UnlinkedUnitBuilder> unlinkedUnits, List<String> unlinkedUnitUris})
+    : _apiSignature = apiSignature,
+      _dependencies = dependencies,
+      _linkedLibraries = linkedLibraries,
       _linkedLibraryUris = linkedLibraryUris,
       _majorVersion = majorVersion,
       _minorVersion = minorVersion,
@@ -1979,22 +2221,72 @@
    * Flush [informative] data recursively.
    */
   void flushInformative() {
+    _dependencies = null;
     _linkedLibraries?.forEach((b) => b.flushInformative());
     _unlinkedUnitHashes = null;
     _unlinkedUnits?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._linkedLibraries == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._linkedLibraries.length);
+      for (var x in this._linkedLibraries) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._linkedLibraryUris == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._linkedLibraryUris.length);
+      for (var x in this._linkedLibraryUris) {
+        signature.addString(x);
+      }
+    }
+    if (this._unlinkedUnits == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._unlinkedUnits.length);
+      for (var x in this._unlinkedUnits) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._unlinkedUnitUris == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._unlinkedUnitUris.length);
+      for (var x in this._unlinkedUnitUris) {
+        signature.addString(x);
+      }
+    }
+    signature.addInt(this._majorVersion ?? 0);
+    signature.addInt(this._minorVersion ?? 0);
+    signature.addString(this._apiSignature ?? '');
+  }
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder), "PBdl");
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_apiSignature;
+    fb.Offset offset_dependencies;
     fb.Offset offset_linkedLibraries;
     fb.Offset offset_linkedLibraryUris;
     fb.Offset offset_unlinkedUnitHashes;
     fb.Offset offset_unlinkedUnits;
     fb.Offset offset_unlinkedUnitUris;
+    if (_apiSignature != null) {
+      offset_apiSignature = fbBuilder.writeString(_apiSignature);
+    }
+    if (!(_dependencies == null || _dependencies.isEmpty)) {
+      offset_dependencies = fbBuilder.writeList(_dependencies.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (!(_linkedLibraries == null || _linkedLibraries.isEmpty)) {
       offset_linkedLibraries = fbBuilder.writeList(_linkedLibraries.map((b) => b.finish(fbBuilder)).toList());
     }
@@ -2011,6 +2303,12 @@
       offset_unlinkedUnitUris = fbBuilder.writeList(_unlinkedUnitUris.map((b) => fbBuilder.writeString(b)).toList());
     }
     fbBuilder.startTable();
+    if (offset_apiSignature != null) {
+      fbBuilder.addOffset(7, offset_apiSignature);
+    }
+    if (offset_dependencies != null) {
+      fbBuilder.addOffset(8, offset_dependencies);
+    }
     if (offset_linkedLibraries != null) {
       fbBuilder.addOffset(0, offset_linkedLibraries);
     }
@@ -2054,6 +2352,8 @@
 
   _PackageBundleImpl(this._bc, this._bcOffset);
 
+  String _apiSignature;
+  List<idl.PackageDependencyInfo> _dependencies;
   List<idl.LinkedLibrary> _linkedLibraries;
   List<String> _linkedLibraryUris;
   int _majorVersion;
@@ -2063,6 +2363,18 @@
   List<String> _unlinkedUnitUris;
 
   @override
+  String get apiSignature {
+    _apiSignature ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 7, '');
+    return _apiSignature;
+  }
+
+  @override
+  List<idl.PackageDependencyInfo> get dependencies {
+    _dependencies ??= const fb.ListReader<idl.PackageDependencyInfo>(const _PackageDependencyInfoReader()).vTableGet(_bc, _bcOffset, 8, const <idl.PackageDependencyInfo>[]);
+    return _dependencies;
+  }
+
+  @override
   List<idl.LinkedLibrary> get linkedLibraries {
     _linkedLibraries ??= const fb.ListReader<idl.LinkedLibrary>(const _LinkedLibraryReader()).vTableGet(_bc, _bcOffset, 0, const <idl.LinkedLibrary>[]);
     return _linkedLibraries;
@@ -2109,6 +2421,8 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (apiSignature != '') _result["apiSignature"] = apiSignature;
+    if (dependencies.isNotEmpty) _result["dependencies"] = dependencies.map((_value) => _value.toJson()).toList();
     if (linkedLibraries.isNotEmpty) _result["linkedLibraries"] = linkedLibraries.map((_value) => _value.toJson()).toList();
     if (linkedLibraryUris.isNotEmpty) _result["linkedLibraryUris"] = linkedLibraryUris;
     if (majorVersion != 0) _result["majorVersion"] = majorVersion;
@@ -2121,6 +2435,8 @@
 
   @override
   Map<String, Object> toMap() => {
+    "apiSignature": apiSignature,
+    "dependencies": dependencies,
     "linkedLibraries": linkedLibraries,
     "linkedLibraryUris": linkedLibraryUris,
     "majorVersion": majorVersion,
@@ -2134,9 +2450,217 @@
   String toString() => convert.JSON.encode(toJson());
 }
 
+class PackageDependencyInfoBuilder extends Object with _PackageDependencyInfoMixin implements idl.PackageDependencyInfo {
+  String _apiSignature;
+  List<String> _includedPackageNames;
+  bool _includesDartUris;
+  bool _includesFileUris;
+  String _summaryPath;
+
+  @override
+  String get apiSignature => _apiSignature ??= '';
+
+  /**
+   * API signature of this dependency.
+   */
+  void set apiSignature(String _value) {
+    _apiSignature = _value;
+  }
+
+  @override
+  List<String> get includedPackageNames => _includedPackageNames ??= <String>[];
+
+  /**
+   * If this dependency summarizes any files whose URI takes the form
+   * "package:<package_name>/...", a list of all such package names, sorted
+   * lexicographically.  Otherwise empty.
+   */
+  void set includedPackageNames(List<String> _value) {
+    _includedPackageNames = _value;
+  }
+
+  @override
+  bool get includesDartUris => _includesDartUris ??= false;
+
+  /**
+   * Indicates whether this dependency summarizes any files whose URI takes the
+   * form "dart:...".
+   */
+  void set includesDartUris(bool _value) {
+    _includesDartUris = _value;
+  }
+
+  @override
+  bool get includesFileUris => _includesFileUris ??= false;
+
+  /**
+   * Indicates whether this dependency summarizes any files whose URI takes the
+   * form "file:...".
+   */
+  void set includesFileUris(bool _value) {
+    _includesFileUris = _value;
+  }
+
+  @override
+  String get summaryPath => _summaryPath ??= '';
+
+  /**
+   * Relative path to the summary file for this dependency.  This is intended as
+   * a hint to help the analysis server locate summaries of dependencies.  We
+   * don't specify precisely what this path is relative to, but we expect it to
+   * be relative to a directory the analysis server can find (e.g. for projects
+   * built using Bazel, it would be relative to the "bazel-bin" directory).
+   *
+   * Absent if the path is not known.
+   */
+  void set summaryPath(String _value) {
+    _summaryPath = _value;
+  }
+
+  PackageDependencyInfoBuilder({String apiSignature, List<String> includedPackageNames, bool includesDartUris, bool includesFileUris, String summaryPath})
+    : _apiSignature = apiSignature,
+      _includedPackageNames = includedPackageNames,
+      _includesDartUris = includesDartUris,
+      _includesFileUris = includesFileUris,
+      _summaryPath = summaryPath;
+
+  /**
+   * Flush [informative] data recursively.
+   */
+  void flushInformative() {
+  }
+
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._apiSignature ?? '');
+    signature.addString(this._summaryPath ?? '');
+    if (this._includedPackageNames == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._includedPackageNames.length);
+      for (var x in this._includedPackageNames) {
+        signature.addString(x);
+      }
+    }
+    signature.addBool(this._includesFileUris == true);
+    signature.addBool(this._includesDartUris == true);
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_apiSignature;
+    fb.Offset offset_includedPackageNames;
+    fb.Offset offset_summaryPath;
+    if (_apiSignature != null) {
+      offset_apiSignature = fbBuilder.writeString(_apiSignature);
+    }
+    if (!(_includedPackageNames == null || _includedPackageNames.isEmpty)) {
+      offset_includedPackageNames = fbBuilder.writeList(_includedPackageNames.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (_summaryPath != null) {
+      offset_summaryPath = fbBuilder.writeString(_summaryPath);
+    }
+    fbBuilder.startTable();
+    if (offset_apiSignature != null) {
+      fbBuilder.addOffset(0, offset_apiSignature);
+    }
+    if (offset_includedPackageNames != null) {
+      fbBuilder.addOffset(2, offset_includedPackageNames);
+    }
+    if (_includesDartUris == true) {
+      fbBuilder.addBool(4, true);
+    }
+    if (_includesFileUris == true) {
+      fbBuilder.addBool(3, true);
+    }
+    if (offset_summaryPath != null) {
+      fbBuilder.addOffset(1, offset_summaryPath);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+class _PackageDependencyInfoReader extends fb.TableReader<_PackageDependencyInfoImpl> {
+  const _PackageDependencyInfoReader();
+
+  @override
+  _PackageDependencyInfoImpl createObject(fb.BufferContext bc, int offset) => new _PackageDependencyInfoImpl(bc, offset);
+}
+
+class _PackageDependencyInfoImpl extends Object with _PackageDependencyInfoMixin implements idl.PackageDependencyInfo {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _PackageDependencyInfoImpl(this._bc, this._bcOffset);
+
+  String _apiSignature;
+  List<String> _includedPackageNames;
+  bool _includesDartUris;
+  bool _includesFileUris;
+  String _summaryPath;
+
+  @override
+  String get apiSignature {
+    _apiSignature ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+    return _apiSignature;
+  }
+
+  @override
+  List<String> get includedPackageNames {
+    _includedPackageNames ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 2, const <String>[]);
+    return _includedPackageNames;
+  }
+
+  @override
+  bool get includesDartUris {
+    _includesDartUris ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 4, false);
+    return _includesDartUris;
+  }
+
+  @override
+  bool get includesFileUris {
+    _includesFileUris ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 3, false);
+    return _includesFileUris;
+  }
+
+  @override
+  String get summaryPath {
+    _summaryPath ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
+    return _summaryPath;
+  }
+}
+
+abstract class _PackageDependencyInfoMixin implements idl.PackageDependencyInfo {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (apiSignature != '') _result["apiSignature"] = apiSignature;
+    if (includedPackageNames.isNotEmpty) _result["includedPackageNames"] = includedPackageNames;
+    if (includesDartUris != false) _result["includesDartUris"] = includesDartUris;
+    if (includesFileUris != false) _result["includesFileUris"] = includesFileUris;
+    if (summaryPath != '') _result["summaryPath"] = summaryPath;
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+    "apiSignature": apiSignature,
+    "includedPackageNames": includedPackageNames,
+    "includesDartUris": includesDartUris,
+    "includesFileUris": includesFileUris,
+    "summaryPath": summaryPath,
+  };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
+}
+
 class PackageIndexBuilder extends Object with _PackageIndexMixin implements idl.PackageIndex {
   List<idl.IndexSyntheticElementKind> _elementKinds;
-  List<int> _elementOffsets;
+  List<int> _elementNameClassMemberIds;
+  List<int> _elementNameParameterIds;
+  List<int> _elementNameUnitMemberIds;
   List<int> _elementUnits;
   List<String> _strings;
   List<int> _unitLibraryUris;
@@ -2155,17 +2679,47 @@
   }
 
   @override
-  List<int> get elementOffsets => _elementOffsets ??= <int>[];
+  List<int> get elementNameClassMemberIds => _elementNameClassMemberIds ??= <int>[];
 
   /**
    * Each item of this list corresponds to a unique referenced element.  It is
-   * the offset of the element name relative to the beginning of the file.  The
-   * list is sorted in ascending order, so that the client can quickly check
-   * whether an element is referenced in this [PackageIndex].
+   * the identifier of the class member element name, or `null` if the element is
+   * a top-level element.  The list is sorted in ascending order, so that the
+   * client can quickly check whether an element is referenced in this
+   * [PackageIndex].
    */
-  void set elementOffsets(List<int> _value) {
+  void set elementNameClassMemberIds(List<int> _value) {
     assert(_value == null || _value.every((e) => e >= 0));
-    _elementOffsets = _value;
+    _elementNameClassMemberIds = _value;
+  }
+
+  @override
+  List<int> get elementNameParameterIds => _elementNameParameterIds ??= <int>[];
+
+  /**
+   * Each item of this list corresponds to a unique referenced element.  It is
+   * the identifier of the named parameter name, or `null` if the element is not
+   * a named parameter.  The list is sorted in ascending order, so that the
+   * client can quickly check whether an element is referenced in this
+   * [PackageIndex].
+   */
+  void set elementNameParameterIds(List<int> _value) {
+    assert(_value == null || _value.every((e) => e >= 0));
+    _elementNameParameterIds = _value;
+  }
+
+  @override
+  List<int> get elementNameUnitMemberIds => _elementNameUnitMemberIds ??= <int>[];
+
+  /**
+   * Each item of this list corresponds to a unique referenced element.  It is
+   * the identifier of the top-level element name, or `null` if the element is
+   * the unit.  The list is sorted in ascending order, so that the client can
+   * quickly check whether an element is referenced in this [PackageIndex].
+   */
+  void set elementNameUnitMemberIds(List<int> _value) {
+    assert(_value == null || _value.every((e) => e >= 0));
+    _elementNameUnitMemberIds = _value;
   }
 
   @override
@@ -2229,9 +2783,11 @@
     _unitUnitUris = _value;
   }
 
-  PackageIndexBuilder({List<idl.IndexSyntheticElementKind> elementKinds, List<int> elementOffsets, List<int> elementUnits, List<String> strings, List<int> unitLibraryUris, List<UnitIndexBuilder> units, List<int> unitUnitUris})
+  PackageIndexBuilder({List<idl.IndexSyntheticElementKind> elementKinds, List<int> elementNameClassMemberIds, List<int> elementNameParameterIds, List<int> elementNameUnitMemberIds, List<int> elementUnits, List<String> strings, List<int> unitLibraryUris, List<UnitIndexBuilder> units, List<int> unitUnitUris})
     : _elementKinds = elementKinds,
-      _elementOffsets = elementOffsets,
+      _elementNameClassMemberIds = elementNameClassMemberIds,
+      _elementNameParameterIds = elementNameParameterIds,
+      _elementNameUnitMemberIds = elementNameUnitMemberIds,
       _elementUnits = elementUnits,
       _strings = strings,
       _unitLibraryUris = unitLibraryUris,
@@ -2245,6 +2801,84 @@
     _units?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._elementUnits == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._elementUnits.length);
+      for (var x in this._elementUnits) {
+        signature.addInt(x);
+      }
+    }
+    if (this._elementNameUnitMemberIds == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._elementNameUnitMemberIds.length);
+      for (var x in this._elementNameUnitMemberIds) {
+        signature.addInt(x);
+      }
+    }
+    if (this._unitLibraryUris == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._unitLibraryUris.length);
+      for (var x in this._unitLibraryUris) {
+        signature.addInt(x);
+      }
+    }
+    if (this._unitUnitUris == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._unitUnitUris.length);
+      for (var x in this._unitUnitUris) {
+        signature.addInt(x);
+      }
+    }
+    if (this._units == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._units.length);
+      for (var x in this._units) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._elementKinds == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._elementKinds.length);
+      for (var x in this._elementKinds) {
+        signature.addInt(x.index);
+      }
+    }
+    if (this._strings == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._strings.length);
+      for (var x in this._strings) {
+        signature.addString(x);
+      }
+    }
+    if (this._elementNameClassMemberIds == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._elementNameClassMemberIds.length);
+      for (var x in this._elementNameClassMemberIds) {
+        signature.addInt(x);
+      }
+    }
+    if (this._elementNameParameterIds == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._elementNameParameterIds.length);
+      for (var x in this._elementNameParameterIds) {
+        signature.addInt(x);
+      }
+    }
+  }
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder), "Indx");
@@ -2252,7 +2886,9 @@
 
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_elementKinds;
-    fb.Offset offset_elementOffsets;
+    fb.Offset offset_elementNameClassMemberIds;
+    fb.Offset offset_elementNameParameterIds;
+    fb.Offset offset_elementNameUnitMemberIds;
     fb.Offset offset_elementUnits;
     fb.Offset offset_strings;
     fb.Offset offset_unitLibraryUris;
@@ -2261,8 +2897,14 @@
     if (!(_elementKinds == null || _elementKinds.isEmpty)) {
       offset_elementKinds = fbBuilder.writeListUint8(_elementKinds.map((b) => b.index).toList());
     }
-    if (!(_elementOffsets == null || _elementOffsets.isEmpty)) {
-      offset_elementOffsets = fbBuilder.writeListUint32(_elementOffsets);
+    if (!(_elementNameClassMemberIds == null || _elementNameClassMemberIds.isEmpty)) {
+      offset_elementNameClassMemberIds = fbBuilder.writeListUint32(_elementNameClassMemberIds);
+    }
+    if (!(_elementNameParameterIds == null || _elementNameParameterIds.isEmpty)) {
+      offset_elementNameParameterIds = fbBuilder.writeListUint32(_elementNameParameterIds);
+    }
+    if (!(_elementNameUnitMemberIds == null || _elementNameUnitMemberIds.isEmpty)) {
+      offset_elementNameUnitMemberIds = fbBuilder.writeListUint32(_elementNameUnitMemberIds);
     }
     if (!(_elementUnits == null || _elementUnits.isEmpty)) {
       offset_elementUnits = fbBuilder.writeListUint32(_elementUnits);
@@ -2283,8 +2925,14 @@
     if (offset_elementKinds != null) {
       fbBuilder.addOffset(5, offset_elementKinds);
     }
-    if (offset_elementOffsets != null) {
-      fbBuilder.addOffset(1, offset_elementOffsets);
+    if (offset_elementNameClassMemberIds != null) {
+      fbBuilder.addOffset(7, offset_elementNameClassMemberIds);
+    }
+    if (offset_elementNameParameterIds != null) {
+      fbBuilder.addOffset(8, offset_elementNameParameterIds);
+    }
+    if (offset_elementNameUnitMemberIds != null) {
+      fbBuilder.addOffset(1, offset_elementNameUnitMemberIds);
     }
     if (offset_elementUnits != null) {
       fbBuilder.addOffset(0, offset_elementUnits);
@@ -2324,7 +2972,9 @@
   _PackageIndexImpl(this._bc, this._bcOffset);
 
   List<idl.IndexSyntheticElementKind> _elementKinds;
-  List<int> _elementOffsets;
+  List<int> _elementNameClassMemberIds;
+  List<int> _elementNameParameterIds;
+  List<int> _elementNameUnitMemberIds;
   List<int> _elementUnits;
   List<String> _strings;
   List<int> _unitLibraryUris;
@@ -2338,9 +2988,21 @@
   }
 
   @override
-  List<int> get elementOffsets {
-    _elementOffsets ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
-    return _elementOffsets;
+  List<int> get elementNameClassMemberIds {
+    _elementNameClassMemberIds ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 7, const <int>[]);
+    return _elementNameClassMemberIds;
+  }
+
+  @override
+  List<int> get elementNameParameterIds {
+    _elementNameParameterIds ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 8, const <int>[]);
+    return _elementNameParameterIds;
+  }
+
+  @override
+  List<int> get elementNameUnitMemberIds {
+    _elementNameUnitMemberIds ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
+    return _elementNameUnitMemberIds;
   }
 
   @override
@@ -2379,7 +3041,9 @@
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
     if (elementKinds.isNotEmpty) _result["elementKinds"] = elementKinds.map((_value) => _value.toString().split('.')[1]).toList();
-    if (elementOffsets.isNotEmpty) _result["elementOffsets"] = elementOffsets;
+    if (elementNameClassMemberIds.isNotEmpty) _result["elementNameClassMemberIds"] = elementNameClassMemberIds;
+    if (elementNameParameterIds.isNotEmpty) _result["elementNameParameterIds"] = elementNameParameterIds;
+    if (elementNameUnitMemberIds.isNotEmpty) _result["elementNameUnitMemberIds"] = elementNameUnitMemberIds;
     if (elementUnits.isNotEmpty) _result["elementUnits"] = elementUnits;
     if (strings.isNotEmpty) _result["strings"] = strings;
     if (unitLibraryUris.isNotEmpty) _result["unitLibraryUris"] = unitLibraryUris;
@@ -2391,7 +3055,9 @@
   @override
   Map<String, Object> toMap() => {
     "elementKinds": elementKinds,
-    "elementOffsets": elementOffsets,
+    "elementNameClassMemberIds": elementNameClassMemberIds,
+    "elementNameParameterIds": elementNameParameterIds,
+    "elementNameUnitMemberIds": elementNameUnitMemberIds,
     "elementUnits": elementUnits,
     "strings": strings,
     "unitLibraryUris": unitLibraryUris,
@@ -2590,6 +3256,109 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addInt(this._unit ?? 0);
+    if (this._usedElementLengths == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedElementLengths.length);
+      for (var x in this._usedElementLengths) {
+        signature.addInt(x);
+      }
+    }
+    if (this._usedElementOffsets == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedElementOffsets.length);
+      for (var x in this._usedElementOffsets) {
+        signature.addInt(x);
+      }
+    }
+    if (this._usedElements == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedElements.length);
+      for (var x in this._usedElements) {
+        signature.addInt(x);
+      }
+    }
+    if (this._usedElementKinds == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedElementKinds.length);
+      for (var x in this._usedElementKinds) {
+        signature.addInt(x.index);
+      }
+    }
+    if (this._definedNames == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._definedNames.length);
+      for (var x in this._definedNames) {
+        signature.addInt(x);
+      }
+    }
+    if (this._definedNameKinds == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._definedNameKinds.length);
+      for (var x in this._definedNameKinds) {
+        signature.addInt(x.index);
+      }
+    }
+    if (this._definedNameOffsets == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._definedNameOffsets.length);
+      for (var x in this._definedNameOffsets) {
+        signature.addInt(x);
+      }
+    }
+    if (this._usedNames == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedNames.length);
+      for (var x in this._usedNames) {
+        signature.addInt(x);
+      }
+    }
+    if (this._usedNameOffsets == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedNameOffsets.length);
+      for (var x in this._usedNameOffsets) {
+        signature.addInt(x);
+      }
+    }
+    if (this._usedNameKinds == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedNameKinds.length);
+      for (var x in this._usedNameKinds) {
+        signature.addInt(x.index);
+      }
+    }
+    if (this._usedElementIsQualifiedFlags == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedElementIsQualifiedFlags.length);
+      for (var x in this._usedElementIsQualifiedFlags) {
+        signature.addBool(x);
+      }
+    }
+    if (this._usedNameIsQualifiedFlags == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._usedNameIsQualifiedFlags.length);
+      for (var x in this._usedNameIsQualifiedFlags) {
+        signature.addBool(x);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_definedNameKinds;
     fb.Offset offset_definedNameOffsets;
@@ -3023,6 +3792,66 @@
     _typeParameters?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    if (this._executables == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._executables.length);
+      for (var x in this._executables) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._supertype != null);
+    this._supertype?.collectApiSignature(signature);
+    if (this._fields == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._fields.length);
+      for (var x in this._fields) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._interfaces == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._interfaces.length);
+      for (var x in this._interfaces) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._isAbstract == true);
+    if (this._typeParameters == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._typeParameters.length);
+      for (var x in this._typeParameters) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._mixins == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._mixins.length);
+      for (var x in this._mixins) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._isMixinApplication == true);
+    signature.addBool(this._hasNoSupertype == true);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_codeRange;
@@ -3331,6 +4160,28 @@
     _offset = null;
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._shows == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._shows.length);
+      for (var x in this._shows) {
+        signature.addString(x);
+      }
+    }
+    if (this._hides == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._hides.length);
+      for (var x in this._hides) {
+        signature.addString(x);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_hides;
     fb.Offset offset_shows;
@@ -3527,6 +4378,61 @@
     _references?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._operations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._operations.length);
+      for (var x in this._operations) {
+        signature.addInt(x.index);
+      }
+    }
+    if (this._ints == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._ints.length);
+      for (var x in this._ints) {
+        signature.addInt(x);
+      }
+    }
+    if (this._references == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._references.length);
+      for (var x in this._references) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._strings == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._strings.length);
+      for (var x in this._strings) {
+        signature.addString(x);
+      }
+    }
+    if (this._doubles == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._doubles.length);
+      for (var x in this._doubles) {
+        signature.addDouble(x);
+      }
+    }
+    signature.addBool(this._isValidConst == true);
+    if (this._assignmentOperators == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._assignmentOperators.length);
+      for (var x in this._assignmentOperators) {
+        signature.addInt(x.index);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_assignmentOperators;
     fb.Offset offset_doubles;
@@ -3750,6 +4656,32 @@
     _expression?.flushInformative();
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addBool(this._expression != null);
+    this._expression?.collectApiSignature(signature);
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+    if (this._arguments == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._arguments.length);
+      for (var x in this._arguments) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._argumentNames == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._argumentNames.length);
+      for (var x in this._argumentNames) {
+        signature.addString(x);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_argumentNames;
     fb.Offset offset_arguments;
@@ -3914,6 +4846,15 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addInt(this._length ?? 0);
+    signature.addString(this._text ?? '');
+    signature.addInt(this._offset ?? 0);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_text;
     if (_text != null) {
@@ -4079,6 +5020,29 @@
     _values?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    if (this._values == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._values.length);
+      for (var x in this._values) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_codeRange;
@@ -4257,6 +5221,13 @@
     _nameOffset = null;
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_documentationComment;
     fb.Offset offset_name;
@@ -4766,6 +5737,71 @@
     _typeParameters?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    if (this._parameters == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parameters.length);
+      for (var x in this._parameters) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._returnType != null);
+    this._returnType?.collectApiSignature(signature);
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+    signature.addInt(this._inferredReturnTypeSlot ?? 0);
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._isFactory == true);
+    signature.addBool(this._isStatic == true);
+    signature.addBool(this._isAbstract == true);
+    signature.addBool(this._isExternal == true);
+    signature.addBool(this._isConst == true);
+    signature.addBool(this._isRedirectedConstructor == true);
+    if (this._constantInitializers == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._constantInitializers.length);
+      for (var x in this._constantInitializers) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._redirectedConstructor != null);
+    this._redirectedConstructor?.collectApiSignature(signature);
+    if (this._typeParameters == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._typeParameters.length);
+      for (var x in this._typeParameters) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addString(this._redirectedConstructorName ?? '');
+    if (this._localFunctions == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._localFunctions.length);
+      for (var x in this._localFunctions) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addInt(this._visibleLength ?? 0);
+    signature.addInt(this._visibleOffset ?? 0);
+    signature.addInt(this._constCycleSlot ?? 0);
+    signature.addBool(this._bodyExpr != null);
+    this._bodyExpr?.collectApiSignature(signature);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_bodyExpr;
@@ -5285,6 +6321,20 @@
     _uriOffset = null;
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     if (!(_annotations == null || _annotations.isEmpty)) {
@@ -5408,6 +6458,21 @@
     _combinators?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._uri ?? '');
+    if (this._combinators == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._combinators.length);
+      for (var x in this._combinators) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_combinators;
     fb.Offset offset_uri;
@@ -5624,6 +6689,32 @@
     _uriOffset = null;
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._uri ?? '');
+    if (this._combinators == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._combinators.length);
+      for (var x in this._combinators) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._isImplicit == true);
+    signature.addInt(this._prefixReference ?? 0);
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._isDeferred == true);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_combinators;
@@ -5853,6 +6944,15 @@
     _nameOffset = null;
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addBool(this._isOnSwitchMember == true);
+    signature.addBool(this._isOnSwitchStatement == true);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_name;
     if (_name != null) {
@@ -6143,6 +7243,39 @@
     _type?.flushInformative();
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addInt(this._inferredTypeSlot ?? 0);
+    signature.addBool(this._type != null);
+    this._type?.collectApiSignature(signature);
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+    signature.addBool(this._isFunctionTyped == true);
+    signature.addBool(this._isInitializingFormal == true);
+    if (this._parameters == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parameters.length);
+      for (var x in this._parameters) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addInt(this._visibleLength ?? 0);
+    signature.addInt(this._visibleOffset ?? 0);
+    signature.addBool(this._initializer != null);
+    this._initializer?.collectApiSignature(signature);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_codeRange;
@@ -6428,6 +7561,20 @@
     _uriOffset = null;
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     if (!(_annotations == null || _annotations.isEmpty)) {
@@ -6570,6 +7717,23 @@
     _members?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+    if (this._members == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._members.length);
+      for (var x in this._members) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addInt(this._numTypeParameters ?? 0);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_members;
     fb.Offset offset_name;
@@ -6713,6 +7877,36 @@
     _names?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._names == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._names.length);
+      for (var x in this._names) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._parts == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parts.length);
+      for (var x in this._parts) {
+        signature.addString(x);
+      }
+    }
+    if (this._exports == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._exports.length);
+      for (var x in this._exports) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder), "UPNS");
@@ -6849,6 +8043,14 @@
   void flushInformative() {
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addInt(this._prefixReference ?? 0);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_name;
     if (_name != null) {
@@ -7028,6 +8230,39 @@
     _typeParameters?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addBool(this._returnType != null);
+    this._returnType?.collectApiSignature(signature);
+    if (this._parameters == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parameters.length);
+      for (var x in this._parameters) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._typeParameters == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._typeParameters.length);
+      for (var x in this._typeParameters) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_codeRange;
@@ -7264,6 +8499,23 @@
     _nameOffset = null;
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addBool(this._bound != null);
+    this._bound?.collectApiSignature(signature);
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_bound;
@@ -7389,6 +8641,7 @@
   String _libraryName;
   int _libraryNameLength;
   int _libraryNameOffset;
+  List<int> _lineStarts;
   List<UnlinkedPartBuilder> _parts;
   UnlinkedPublicNamespaceBuilder _publicNamespace;
   List<UnlinkedReferenceBuilder> _references;
@@ -7527,6 +8780,17 @@
   }
 
   @override
+  List<int> get lineStarts => _lineStarts ??= <int>[];
+
+  /**
+   * Offsets of the first character of each line in the source code.
+   */
+  void set lineStarts(List<int> _value) {
+    assert(_value == null || _value.every((e) => e >= 0));
+    _lineStarts = _value;
+  }
+
+  @override
   List<UnlinkedPartBuilder> get parts => _parts ??= <UnlinkedPartBuilder>[];
 
   /**
@@ -7580,7 +8844,7 @@
     _variables = _value;
   }
 
-  UnlinkedUnitBuilder({List<UnlinkedClassBuilder> classes, CodeRangeBuilder codeRange, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, String fallbackModePath, List<UnlinkedImportBuilder> imports, List<UnlinkedConstBuilder> libraryAnnotations, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, String libraryName, int libraryNameLength, int libraryNameOffset, List<UnlinkedPartBuilder> parts, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables})
+  UnlinkedUnitBuilder({List<UnlinkedClassBuilder> classes, CodeRangeBuilder codeRange, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, String fallbackModePath, List<UnlinkedImportBuilder> imports, List<UnlinkedConstBuilder> libraryAnnotations, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, String libraryName, int libraryNameLength, int libraryNameOffset, List<int> lineStarts, List<UnlinkedPartBuilder> parts, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables})
     : _classes = classes,
       _codeRange = codeRange,
       _enums = enums,
@@ -7593,6 +8857,7 @@
       _libraryName = libraryName,
       _libraryNameLength = libraryNameLength,
       _libraryNameOffset = libraryNameOffset,
+      _lineStarts = lineStarts,
       _parts = parts,
       _publicNamespace = publicNamespace,
       _references = references,
@@ -7613,6 +8878,7 @@
     _libraryDocumentationComment = null;
     _libraryNameLength = null;
     _libraryNameOffset = null;
+    _lineStarts = null;
     _parts?.forEach((b) => b.flushInformative());
     _publicNamespace?.flushInformative();
     _references?.forEach((b) => b.flushInformative());
@@ -7620,6 +8886,96 @@
     _variables?.forEach((b) => b.flushInformative());
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addBool(this._publicNamespace != null);
+    this._publicNamespace?.collectApiSignature(signature);
+    if (this._references == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._references.length);
+      for (var x in this._references) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._classes == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._classes.length);
+      for (var x in this._classes) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._variables == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._variables.length);
+      for (var x in this._variables) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._executables == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._executables.length);
+      for (var x in this._executables) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._imports == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._imports.length);
+      for (var x in this._imports) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addString(this._libraryName ?? '');
+    if (this._typedefs == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._typedefs.length);
+      for (var x in this._typedefs) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._parts == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parts.length);
+      for (var x in this._parts) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._enums == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._enums.length);
+      for (var x in this._enums) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._exports == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._exports.length);
+      for (var x in this._exports) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._libraryAnnotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._libraryAnnotations.length);
+      for (var x in this._libraryAnnotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addString(this._fallbackModePath ?? '');
+  }
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder), "UUnt");
@@ -7636,6 +8992,7 @@
     fb.Offset offset_libraryAnnotations;
     fb.Offset offset_libraryDocumentationComment;
     fb.Offset offset_libraryName;
+    fb.Offset offset_lineStarts;
     fb.Offset offset_parts;
     fb.Offset offset_publicNamespace;
     fb.Offset offset_references;
@@ -7671,6 +9028,9 @@
     if (_libraryName != null) {
       offset_libraryName = fbBuilder.writeString(_libraryName);
     }
+    if (!(_lineStarts == null || _lineStarts.isEmpty)) {
+      offset_lineStarts = fbBuilder.writeListUint32(_lineStarts);
+    }
     if (!(_parts == null || _parts.isEmpty)) {
       offset_parts = fbBuilder.writeList(_parts.map((b) => b.finish(fbBuilder)).toList());
     }
@@ -7723,6 +9083,9 @@
     if (_libraryNameOffset != null && _libraryNameOffset != 0) {
       fbBuilder.addUint32(8, _libraryNameOffset);
     }
+    if (offset_lineStarts != null) {
+      fbBuilder.addOffset(17, offset_lineStarts);
+    }
     if (offset_parts != null) {
       fbBuilder.addOffset(11, offset_parts);
     }
@@ -7772,6 +9135,7 @@
   String _libraryName;
   int _libraryNameLength;
   int _libraryNameOffset;
+  List<int> _lineStarts;
   List<idl.UnlinkedPart> _parts;
   idl.UnlinkedPublicNamespace _publicNamespace;
   List<idl.UnlinkedReference> _references;
@@ -7851,6 +9215,12 @@
   }
 
   @override
+  List<int> get lineStarts {
+    _lineStarts ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 17, const <int>[]);
+    return _lineStarts;
+  }
+
+  @override
   List<idl.UnlinkedPart> get parts {
     _parts ??= const fb.ListReader<idl.UnlinkedPart>(const _UnlinkedPartReader()).vTableGet(_bc, _bcOffset, 11, const <idl.UnlinkedPart>[]);
     return _parts;
@@ -7897,6 +9267,7 @@
     if (libraryName != '') _result["libraryName"] = libraryName;
     if (libraryNameLength != 0) _result["libraryNameLength"] = libraryNameLength;
     if (libraryNameOffset != 0) _result["libraryNameOffset"] = libraryNameOffset;
+    if (lineStarts.isNotEmpty) _result["lineStarts"] = lineStarts;
     if (parts.isNotEmpty) _result["parts"] = parts.map((_value) => _value.toJson()).toList();
     if (publicNamespace != null) _result["publicNamespace"] = publicNamespace.toJson();
     if (references.isNotEmpty) _result["references"] = references.map((_value) => _value.toJson()).toList();
@@ -7919,6 +9290,7 @@
     "libraryName": libraryName,
     "libraryNameLength": libraryNameLength,
     "libraryNameOffset": libraryNameOffset,
+    "lineStarts": lineStarts,
     "parts": parts,
     "publicNamespace": publicNamespace,
     "references": references,
@@ -8133,6 +9505,32 @@
     _type?.flushInformative();
   }
 
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    signature.addInt(this._propagatedTypeSlot ?? 0);
+    signature.addBool(this._type != null);
+    this._type?.collectApiSignature(signature);
+    signature.addBool(this._isStatic == true);
+    signature.addBool(this._isConst == true);
+    signature.addBool(this._isFinal == true);
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addInt(this._inferredTypeSlot ?? 0);
+    signature.addInt(this._visibleLength ?? 0);
+    signature.addInt(this._visibleOffset ?? 0);
+    signature.addBool(this._initializer != null);
+    this._initializer?.collectApiSignature(signature);
+  }
+
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_annotations;
     fb.Offset offset_codeRange;
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index d08851c..ba46f01 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1181,6 +1181,18 @@
  */
 table PackageBundle {
   /**
+   * MD5 hash of the non-informative fields of the [PackageBundle] (not
+   * including this one).  This can be used to identify when the API of a
+   * package may have changed.
+   */
+  apiSignature:string (id: 7);
+
+  /**
+   * Information about the packages this package depends on, if known.
+   */
+  dependencies:[PackageDependencyInfo] (id: 8);
+
+  /**
    * Linked libraries.
    */
   linkedLibraries:[LinkedLibrary] (id: 0);
@@ -1221,6 +1233,46 @@
 }
 
 /**
+ * Information about a single dependency of a summary package.
+ */
+table PackageDependencyInfo {
+  /**
+   * API signature of this dependency.
+   */
+  apiSignature:string (id: 0);
+
+  /**
+   * If this dependency summarizes any files whose URI takes the form
+   * "package:<package_name>/...", a list of all such package names, sorted
+   * lexicographically.  Otherwise empty.
+   */
+  includedPackageNames:[string] (id: 2);
+
+  /**
+   * Indicates whether this dependency summarizes any files whose URI takes the
+   * form "dart:...".
+   */
+  includesDartUris:bool (id: 4);
+
+  /**
+   * Indicates whether this dependency summarizes any files whose URI takes the
+   * form "file:...".
+   */
+  includesFileUris:bool (id: 3);
+
+  /**
+   * Relative path to the summary file for this dependency.  This is intended as
+   * a hint to help the analysis server locate summaries of dependencies.  We
+   * don't specify precisely what this path is relative to, but we expect it to
+   * be relative to a directory the analysis server can find (e.g. for projects
+   * built using Bazel, it would be relative to the "bazel-bin" directory).
+   *
+   * Absent if the path is not known.
+   */
+  summaryPath:string (id: 1);
+}
+
+/**
  * Index information about a package.
  */
 table PackageIndex {
@@ -1232,11 +1284,29 @@
 
   /**
    * Each item of this list corresponds to a unique referenced element.  It is
-   * the offset of the element name relative to the beginning of the file.  The
-   * list is sorted in ascending order, so that the client can quickly check
-   * whether an element is referenced in this [PackageIndex].
+   * the identifier of the class member element name, or `null` if the element is
+   * a top-level element.  The list is sorted in ascending order, so that the
+   * client can quickly check whether an element is referenced in this
+   * [PackageIndex].
    */
-  elementOffsets:[uint] (id: 1);
+  elementNameClassMemberIds:[uint] (id: 7);
+
+  /**
+   * Each item of this list corresponds to a unique referenced element.  It is
+   * the identifier of the named parameter name, or `null` if the element is not
+   * a named parameter.  The list is sorted in ascending order, so that the
+   * client can quickly check whether an element is referenced in this
+   * [PackageIndex].
+   */
+  elementNameParameterIds:[uint] (id: 8);
+
+  /**
+   * Each item of this list corresponds to a unique referenced element.  It is
+   * the identifier of the top-level element name, or `null` if the element is
+   * the unit.  The list is sorted in ascending order, so that the client can
+   * quickly check whether an element is referenced in this [PackageIndex].
+   */
+  elementNameUnitMemberIds:[uint] (id: 1);
 
   /**
    * Each item of this list corresponds to a unique referenced element.  It is
@@ -2304,6 +2374,11 @@
   libraryNameOffset:uint (id: 8);
 
   /**
+   * Offsets of the first character of each line in the source code.
+   */
+  lineStarts:[uint] (id: 17);
+
+  /**
    * Part declarations in the compilation unit.
    */
   parts:[UnlinkedPart] (id: 11);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 505ade8..70b329b 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -650,6 +650,21 @@
       generated.readPackageBundle(buffer);
 
   /**
+   * MD5 hash of the non-informative fields of the [PackageBundle] (not
+   * including this one).  This can be used to identify when the API of a
+   * package may have changed.
+   */
+  @Id(7)
+  String get apiSignature;
+
+  /**
+   * Information about the packages this package depends on, if known.
+   */
+  @Id(8)
+  @informative
+  List<PackageDependencyInfo> get dependencies;
+
+  /**
    * Linked libraries.
    */
   @Id(0)
@@ -698,6 +713,51 @@
 }
 
 /**
+ * Information about a single dependency of a summary package.
+ */
+abstract class PackageDependencyInfo extends base.SummaryClass {
+  /**
+   * API signature of this dependency.
+   */
+  @Id(0)
+  String get apiSignature;
+
+  /**
+   * If this dependency summarizes any files whose URI takes the form
+   * "package:<package_name>/...", a list of all such package names, sorted
+   * lexicographically.  Otherwise empty.
+   */
+  @Id(2)
+  List<String> get includedPackageNames;
+
+  /**
+   * Indicates whether this dependency summarizes any files whose URI takes the
+   * form "dart:...".
+   */
+  @Id(4)
+  bool get includesDartUris;
+
+  /**
+   * Indicates whether this dependency summarizes any files whose URI takes the
+   * form "file:...".
+   */
+  @Id(3)
+  bool get includesFileUris;
+
+  /**
+   * Relative path to the summary file for this dependency.  This is intended as
+   * a hint to help the analysis server locate summaries of dependencies.  We
+   * don't specify precisely what this path is relative to, but we expect it to
+   * be relative to a directory the analysis server can find (e.g. for projects
+   * built using Bazel, it would be relative to the "bazel-bin" directory).
+   *
+   * Absent if the path is not known.
+   */
+  @Id(1)
+  String get summaryPath;
+}
+
+/**
  * Index information about a package.
  */
 @TopLevel('Indx')
@@ -714,12 +774,32 @@
 
   /**
    * Each item of this list corresponds to a unique referenced element.  It is
-   * the offset of the element name relative to the beginning of the file.  The
-   * list is sorted in ascending order, so that the client can quickly check
-   * whether an element is referenced in this [PackageIndex].
+   * the identifier of the class member element name, or `null` if the element is
+   * a top-level element.  The list is sorted in ascending order, so that the
+   * client can quickly check whether an element is referenced in this
+   * [PackageIndex].
+   */
+  @Id(7)
+  List<int> get elementNameClassMemberIds;
+
+  /**
+   * Each item of this list corresponds to a unique referenced element.  It is
+   * the identifier of the named parameter name, or `null` if the element is not
+   * a named parameter.  The list is sorted in ascending order, so that the
+   * client can quickly check whether an element is referenced in this
+   * [PackageIndex].
+   */
+  @Id(8)
+  List<int> get elementNameParameterIds;
+
+  /**
+   * Each item of this list corresponds to a unique referenced element.  It is
+   * the identifier of the top-level element name, or `null` if the element is
+   * the unit.  The list is sorted in ascending order, so that the client can
+   * quickly check whether an element is referenced in this [PackageIndex].
    */
   @Id(1)
-  List<int> get elementOffsets;
+  List<int> get elementNameUnitMemberIds;
 
   /**
    * Each item of this list corresponds to a unique referenced element.  It is
@@ -2632,6 +2712,13 @@
   int get libraryNameOffset;
 
   /**
+   * Offsets of the first character of each line in the source code.
+   */
+  @informative
+  @Id(17)
+  List<int> get lineStarts;
+
+  /**
    * Part declarations in the compilation unit.
    */
   @Id(11)
diff --git a/pkg/analyzer/lib/src/summary/index_unit.dart b/pkg/analyzer/lib/src/summary/index_unit.dart
index bc09ee3..5a9cb47 100644
--- a/pkg/analyzer/lib/src/summary/index_unit.dart
+++ b/pkg/analyzer/lib/src/summary/index_unit.dart
@@ -13,46 +13,78 @@
 import 'package:analyzer/src/summary/idl.dart';
 
 /**
- * Information about an element referenced in index.
+ * Information about an element that is actually put into index for some other
+ * related element. For example for a synthetic getter this is the corresponding
+ * non-synthetic field and [IndexSyntheticElementKind.getter] as the [kind].
  */
-class ElementInfo {
-  /**
-   * The identifier of the [CompilationUnitElement] containing this element.
-   */
-  final int unitId;
-
-  /**
-   * The name offset of the element.
-   */
-  final int offset;
-
-  /**
-   * The kind of the element.
-   */
+class IndexElementInfo {
+  final Element element;
   final IndexSyntheticElementKind kind;
 
-  /**
-   * The unique id of the element.  It is set after indexing of the whole
-   * package is done and we are assembling the full package index.
-   */
-  int id;
-
-  ElementInfo(this.unitId, this.offset, this.kind) {
-    assert(offset >= 0);
+  factory IndexElementInfo(Element element) {
+    IndexSyntheticElementKind kind = IndexSyntheticElementKind.notSynthetic;
+    if (element is LibraryElement || element is CompilationUnitElement) {
+      kind = IndexSyntheticElementKind.unit;
+    } else if (element.isSynthetic) {
+      if (element is ConstructorElement) {
+        kind = IndexSyntheticElementKind.constructor;
+        element = element.enclosingElement;
+      } else if (element is FunctionElement && element.name == 'loadLibrary') {
+        kind = IndexSyntheticElementKind.loadLibrary;
+        element = element.library;
+      } else if (element is FieldElement) {
+        FieldElement field = element;
+        kind = IndexSyntheticElementKind.field;
+        element = field.getter;
+        element ??= field.setter;
+      } else if (element is PropertyAccessorElement) {
+        PropertyAccessorElement accessor = element;
+        Element enclosing = element.enclosingElement;
+        bool isEnumGetter = enclosing is ClassElement && enclosing.isEnum;
+        if (isEnumGetter && accessor.name == 'index') {
+          kind = IndexSyntheticElementKind.enumIndex;
+          element = enclosing;
+        } else if (isEnumGetter && accessor.name == 'values') {
+          kind = IndexSyntheticElementKind.enumValues;
+          element = enclosing;
+        } else {
+          kind = accessor.isGetter
+              ? IndexSyntheticElementKind.getter
+              : IndexSyntheticElementKind.setter;
+          element = accessor.variable;
+        }
+      } else if (element is TopLevelVariableElement) {
+        TopLevelVariableElement property = element;
+        kind = IndexSyntheticElementKind.topLevelVariable;
+        element = property.getter;
+        element ??= property.setter;
+      } else {
+        throw new ArgumentError(
+            'Unsupported synthetic element ${element.runtimeType}');
+      }
+    }
+    return new IndexElementInfo._(element, kind);
   }
+
+  IndexElementInfo._(this.element, this.kind);
 }
 
 /**
  * Object that gathers information about the whole package index and then uses
- * it to assemble a new [PackageIndexBuilder].  Call [index] on each compilation
- * unit to be indexed, then call [assemble] to retrieve the complete index for
- * the package.
+ * it to assemble a new [PackageIndexBuilder].  Call [indexUnit] on each
+ * compilation unit to be indexed, then call [assemble] to retrieve the
+ * complete index for the package.
  */
 class PackageIndexAssembler {
   /**
-   * Map associating referenced elements with their [ElementInfo]s.
+   * The string to use place of the `null` string.
    */
-  final Map<Element, ElementInfo> _elementMap = <Element, ElementInfo>{};
+  static const NULL_STRING = '--nullString--';
+
+  /**
+   * Map associating referenced elements with their [_ElementInfo]s.
+   */
+  final Map<Element, _ElementInfo> _elementMap = <Element, _ElementInfo>{};
 
   /**
    * Map associating [CompilationUnitElement]s with their identifiers, which
@@ -84,6 +116,15 @@
   final List<_UnitIndexAssembler> _units = <_UnitIndexAssembler>[];
 
   /**
+   * The [_StringInfo] to use for `null` strings.
+   */
+  _StringInfo _nullString;
+
+  PackageIndexAssembler() {
+    _nullString = _getStringInfo(NULL_STRING);
+  }
+
+  /**
    * Assemble a new [PackageIndexBuilder] using the information gathered by
    * [indexDeclarations] or [indexUnit].
    */
@@ -97,9 +138,18 @@
       stringInfoList[i].id = i;
     }
     // sort elements and set IDs
-    List<ElementInfo> elementInfoList = _elementMap.values.toList();
+    List<_ElementInfo> elementInfoList = _elementMap.values.toList();
     elementInfoList.sort((a, b) {
-      return a.offset - b.offset;
+      int delta;
+      delta = a.nameIdUnitMember.id - b.nameIdUnitMember.id;
+      if (delta != null) {
+        return delta;
+      }
+      delta = a.nameIdClassMember.id - b.nameIdClassMember.id;
+      if (delta != null) {
+        return delta;
+      }
+      return a.nameIdParameter.id - b.nameIdParameter.id;
     });
     for (int i = 0; i < elementInfoList.length; i++) {
       elementInfoList[i].id = i;
@@ -108,7 +158,12 @@
         unitLibraryUris: _unitLibraryUris.map((s) => s.id).toList(),
         unitUnitUris: _unitUnitUris.map((s) => s.id).toList(),
         elementUnits: elementInfoList.map((e) => e.unitId).toList(),
-        elementOffsets: elementInfoList.map((e) => e.offset).toList(),
+        elementNameUnitMemberIds:
+            elementInfoList.map((e) => e.nameIdUnitMember.id).toList(),
+        elementNameClassMemberIds:
+            elementInfoList.map((e) => e.nameIdClassMember.id).toList(),
+        elementNameParameterIds:
+            elementInfoList.map((e) => e.nameIdParameter.id).toList(),
         elementKinds: elementInfoList.map((e) => e.kind).toList(),
         strings: stringInfoList.map((s) => s.value).toList(),
         units: _units.map((unit) => unit.assemble()).toList());
@@ -135,17 +190,17 @@
   }
 
   /**
-   * Return the unique [ElementInfo] corresponding the [element].  The field
-   * [ElementInfo.id] is filled by [assemble] during final sorting.
+   * Return the unique [_ElementInfo] corresponding the [element].  The field
+   * [_ElementInfo.id] is filled by [assemble] during final sorting.
    */
-  ElementInfo _getElementInfo(Element element) {
+  _ElementInfo _getElementInfo(Element element) {
     if (element is Member) {
       element = (element as Member).baseElement;
     }
     return _elementMap.putIfAbsent(element, () {
       CompilationUnitElement unitElement = getUnitElement(element);
       int unitId = _getUnitId(unitElement);
-      return newElementInfo(unitId, element);
+      return _newElementInfo(unitId, element);
     });
   }
 
@@ -184,6 +239,32 @@
   }
 
   /**
+   * Return a new [_ElementInfo] for the given [element] in the given [unitId].
+   * This method is static, so it cannot add any information to the index.
+   */
+  _ElementInfo _newElementInfo(int unitId, Element element) {
+    IndexElementInfo info = new IndexElementInfo(element);
+    element = info.element;
+    // Prepare name identifiers.
+    _StringInfo nameIdParameter = _nullString;
+    _StringInfo nameIdClassMember = _nullString;
+    _StringInfo nameIdUnitMember = _nullString;
+    if (element is ParameterElement) {
+      nameIdParameter = _getStringInfo(element.name);
+      element = element.enclosingElement;
+    }
+    if (element?.enclosingElement is ClassElement) {
+      nameIdClassMember = _getStringInfo(element.name);
+      element = element.enclosingElement;
+    }
+    if (element?.enclosingElement is CompilationUnitElement) {
+      nameIdUnitMember = _getStringInfo(element.name);
+    }
+    return new _ElementInfo(unitId, nameIdUnitMember, nameIdClassMember,
+        nameIdParameter, info.kind);
+  }
+
+  /**
    * Return the [CompilationUnitElement] that should be used for [element].
    * Throw [StateError] if the [element] is not linked into a unit.
    */
@@ -198,58 +279,6 @@
     }
     throw new StateError(element.toString());
   }
-
-  /**
-   * Return a new [ElementInfo] for the given [element] in the given [unitId].
-   * This method is static, so it cannot add any information to the index.
-   */
-  static ElementInfo newElementInfo(int unitId, Element element) {
-    int offset = null;
-    IndexSyntheticElementKind kind = IndexSyntheticElementKind.notSynthetic;
-    if (element.isSynthetic) {
-      if (element is ConstructorElement) {
-        kind = IndexSyntheticElementKind.constructor;
-        element = element.enclosingElement;
-      } else if (element is FunctionElement && element.name == 'loadLibrary') {
-        kind = IndexSyntheticElementKind.loadLibrary;
-        element = element.library;
-      } else if (element is FieldElement) {
-        FieldElement field = element;
-        kind = IndexSyntheticElementKind.field;
-        element = field.getter;
-        element ??= field.setter;
-      } else if (element is PropertyAccessorElement) {
-        PropertyAccessorElement accessor = element;
-        Element enclosing = element.enclosingElement;
-        bool isEnumGetter = enclosing is ClassElement && enclosing.isEnum;
-        if (isEnumGetter && accessor.name == 'index') {
-          kind = IndexSyntheticElementKind.enumIndex;
-          element = enclosing;
-        } else if (isEnumGetter && accessor.name == 'values') {
-          kind = IndexSyntheticElementKind.enumValues;
-          element = enclosing;
-        } else {
-          kind = accessor.isGetter
-              ? IndexSyntheticElementKind.getter
-              : IndexSyntheticElementKind.setter;
-          element = accessor.variable;
-        }
-      } else if (element is TopLevelVariableElement) {
-        TopLevelVariableElement property = element;
-        kind = IndexSyntheticElementKind.topLevelVariable;
-        element = property.getter;
-        element ??= property.setter;
-      } else {
-        throw new ArgumentError(
-            'Unsupported synthetic element ${element.runtimeType}');
-      }
-    } else if (element is LibraryElement || element is CompilationUnitElement) {
-      kind = IndexSyntheticElementKind.unit;
-      offset = 0;
-    }
-    offset ??= element.nameOffset;
-    return new ElementInfo(unitId, offset, kind);
-  }
 }
 
 /**
@@ -278,13 +307,55 @@
 }
 
 /**
+ * Information about an element referenced in index.
+ */
+class _ElementInfo {
+  /**
+   * The identifier of the [CompilationUnitElement] containing this element.
+   */
+  final int unitId;
+
+  /**
+   * The identifier of the top-level name, or `null` if the element is a
+   * reference to the unit.
+   */
+  final _StringInfo nameIdUnitMember;
+
+  /**
+   * The identifier of the class member name, or `null` if the element is not a
+   * class member or a named parameter of a class member.
+   */
+  final _StringInfo nameIdClassMember;
+
+  /**
+   * The identifier of the named parameter name, or `null` if the element is not
+   * a named parameter.
+   */
+  final _StringInfo nameIdParameter;
+
+  /**
+   * The kind of the element.
+   */
+  final IndexSyntheticElementKind kind;
+
+  /**
+   * The unique id of the element.  It is set after indexing of the whole
+   * package is done and we are assembling the full package index.
+   */
+  int id;
+
+  _ElementInfo(this.unitId, this.nameIdUnitMember, this.nameIdClassMember,
+      this.nameIdParameter, this.kind);
+}
+
+/**
  * Information about a single relation.  Any [_ElementRelationInfo] is always
  * part of a [_UnitIndexAssembler], so [offset] and [length] should be
  * understood within the context of the compilation unit pointed to by the
  * [_UnitIndexAssembler].
  */
 class _ElementRelationInfo {
-  final ElementInfo elementInfo;
+  final _ElementInfo elementInfo;
   final IndexRelationKind kind;
   final int offset;
   final int length;
@@ -770,7 +841,7 @@
  *    compilation unit.
  *  - Call [addNameRelation] for each name relation found in the
  *    compilation unit.
- *  - Assign ids to all the [ElementInfo] objects reachable from
+ *  - Assign ids to all the [_ElementInfo] objects reachable from
  *    [elementRelations].
  *  - Call [assemble] to produce the final unit index.
  */
@@ -786,7 +857,7 @@
   void addElementRelation(Element element, IndexRelationKind kind, int offset,
       int length, bool isQualified) {
     try {
-      ElementInfo elementInfo = pkg._getElementInfo(element);
+      _ElementInfo elementInfo = pkg._getElementInfo(element);
       elementRelations.add(new _ElementRelationInfo(
           elementInfo, kind, offset, length, isQualified));
     } on StateError {}
diff --git a/pkg/analyzer/lib/src/summary/inspect.dart b/pkg/analyzer/lib/src/summary/inspect.dart
deleted file mode 100644
index 799c15e..0000000
--- a/pkg/analyzer/lib/src/summary/inspect.dart
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:mirrors';
-
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/base.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-
-const int MAX_LINE_LENGTH = 80;
-
-/**
- * Cache used to speed up [isEnum].
- */
-Map<Type, bool> _isEnumCache = <Type, bool>{};
-
-/**
- * Determine if the given [obj] has an enumerated type.
- */
-bool isEnum(Object obj) {
-  return _isEnumCache.putIfAbsent(
-      obj.runtimeType, () => reflect(obj).type.isEnum);
-}
-
-/**
- * Decoded reprensentation of a part of a summary that occupies multiple lines
- * of output.
- */
-class BrokenEntity implements DecodedEntity {
-  final String opener;
-  final Map<String, DecodedEntity> parts;
-  final String closer;
-
-  BrokenEntity(this.opener, this.parts, this.closer);
-
-  @override
-  List<String> getLines() {
-    List<String> result = <String>[opener];
-    bool first = true;
-    for (String key in parts.keys) {
-      if (first) {
-        first = false;
-      } else {
-        result[result.length - 1] += ',';
-      }
-      List<String> subResult = parts[key].getLines();
-      subResult[0] = '$key: ${subResult[0]}';
-      result.addAll(subResult.map((String s) => '  $s'));
-    }
-    result.add(closer);
-    return result;
-  }
-}
-
-/**
- * Decoded representation of a part of a summary.
- */
-abstract class DecodedEntity {
-  /**
-   * Create a representation of a part of the summary that consists of a group
-   * of entities (represented by [parts]) contained between [opener] and
-   * [closer].
-   *
-   * If [forceKeys] is `true`, the keys in [parts] will always be shown.  If
-   * [forceKeys] is `false`, they keys will only be shown if the output is
-   * broken into multiple lines.
-   */
-  factory DecodedEntity.group(String opener, Map<String, DecodedEntity> parts,
-      String closer, bool forceKeys) {
-    // Attempt to format the entity in a single line; if not bail out and
-    // construct a _BrokenEntity.
-    DecodedEntity bailout() => new BrokenEntity(opener, parts, closer);
-    String short = opener;
-    bool first = true;
-    for (String key in parts.keys) {
-      if (first) {
-        first = false;
-      } else {
-        short += ', ';
-      }
-      DecodedEntity value = parts[key];
-      if (forceKeys) {
-        short += '$key: ';
-      }
-      if (value is UnbrokenEntity) {
-        short += value._s;
-      } else {
-        return bailout();
-      }
-      if (short.length > MAX_LINE_LENGTH) {
-        return bailout();
-      }
-    }
-    return new DecodedEntity.short(short + closer);
-  }
-
-  /**
-   * Create a representation of a part of the summary that is represented by a
-   * single unbroken string.
-   */
-  factory DecodedEntity.short(String s) = UnbrokenEntity;
-
-  /**
-   * Format this entity into a sequence of strings (one per output line).
-   */
-  List<String> getLines();
-}
-
-/**
- * Wrapper around a [LinkedLibrary] and its constituent [UnlinkedUnit]s.
- */
-class LibraryWrapper {
-  final LinkedLibrary _linked;
-  final List<UnlinkedUnit> _unlinked;
-
-  LibraryWrapper(this._linked, this._unlinked);
-}
-
-/**
- * Wrapper around a [LinkedReference] and its corresponding [UnlinkedReference].
- */
-class ReferenceWrapper {
-  final LinkedReference _linked;
-  final UnlinkedReference _unlinked;
-
-  ReferenceWrapper(this._linked, this._unlinked);
-
-  String get name {
-    if (_linked != null && _linked.name.isNotEmpty) {
-      return _linked.name;
-    } else if (_unlinked != null && _unlinked.name.isNotEmpty) {
-      return _unlinked.name;
-    } else {
-      return '???';
-    }
-  }
-}
-
-/**
- * Instances of [SummaryInspector] are capable of traversing a summary and
- * converting it to semi-human-readable output.
- */
-class SummaryInspector {
-  /**
-   * The dependencies of the library currently being visited.
-   */
-  List<LinkedDependency> _dependencies;
-
-  /**
-   * The references of the unit currently being visited.
-   */
-  List<ReferenceWrapper> _references;
-
-  /**
-   * Indicates whether summary inspection should operate in "raw" mode.  In this
-   * mode, the structure of the summary file is not altered for easier
-   * readability; everything is output in exactly the form in which it appears
-   * in the file.
-   */
-  final bool raw;
-
-  SummaryInspector(this.raw);
-
-  /**
-   * Decode the object [obj], which was reached by examining [key] inside
-   * another object.
-   */
-  DecodedEntity decode(Object obj, String key) {
-    if (!raw && obj is PackageBundle) {
-      return decodePackageBundle(obj);
-    }
-    if (obj is LibraryWrapper) {
-      return decodeLibrary(obj);
-    }
-    if (obj is UnitWrapper) {
-      return decodeUnit(obj);
-    }
-    if (obj is ReferenceWrapper) {
-      return decodeReference(obj);
-    }
-    if (obj is DecodedEntity) {
-      return obj;
-    }
-    if (obj is SummaryClass) {
-      Map<String, Object> map = obj.toMap();
-      return decodeMap(map);
-    } else if (obj is List) {
-      Map<String, DecodedEntity> parts = <String, DecodedEntity>{};
-      for (int i = 0; i < obj.length; i++) {
-        parts[i.toString()] = decode(obj[i], key);
-      }
-      return new DecodedEntity.group('[', parts, ']', false);
-    } else if (obj is String) {
-      return new DecodedEntity.short(JSON.encode(obj));
-    } else if (isEnum(obj)) {
-      return new DecodedEntity.short(obj.toString().split('.')[1]);
-    } else if (obj is int &&
-        key == 'dependency' &&
-        _dependencies != null &&
-        obj < _dependencies.length) {
-      return new DecodedEntity.short('$obj (${_dependencies[obj].uri})');
-    } else if (obj is int &&
-        key == 'reference' &&
-        _references != null &&
-        obj < _references.length) {
-      return new DecodedEntity.short('$obj (${_references[obj].name})');
-    } else {
-      return new DecodedEntity.short(obj.toString());
-    }
-  }
-
-  /**
-   * Decode the given [LibraryWrapper].
-   */
-  DecodedEntity decodeLibrary(LibraryWrapper obj) {
-    try {
-      LinkedLibrary linked = obj._linked;
-      List<UnlinkedUnit> unlinked = obj._unlinked;
-      _dependencies = linked.dependencies;
-      Map<String, Object> result = linked.toMap();
-      result.remove('units');
-      result['defining compilation unit'] =
-          new UnitWrapper(linked.units[0], unlinked[0]);
-      for (int i = 1; i < linked.units.length; i++) {
-        String partUri = unlinked[0].publicNamespace.parts[i - 1];
-        result['part ${JSON.encode(partUri)}'] =
-            new UnitWrapper(linked.units[i], unlinked[i]);
-      }
-      return decodeMap(result);
-    } finally {
-      _dependencies = null;
-    }
-  }
-
-  /**
-   * Decode the given [map].
-   */
-  DecodedEntity decodeMap(Map<String, Object> map) {
-    Map<String, DecodedEntity> parts = <String, DecodedEntity>{};
-    map = reorderMap(map);
-    map.forEach((String key, Object value) {
-      if (value is String && value.isEmpty) {
-        return;
-      }
-      if (isEnum(value) && (value as dynamic).index == 0) {
-        return;
-      }
-      if (value is int && value == 0) {
-        return;
-      }
-      if (value is bool && value == false) {
-        return;
-      }
-      if (value == null) {
-        return;
-      }
-      if (value is List) {
-        if (value.isEmpty) {
-          return;
-        }
-        DecodedEntity entity = decode(value, key);
-        if (entity is BrokenEntity) {
-          for (int i = 0; i < value.length; i++) {
-            parts['$key[$i]'] = decode(value[i], key);
-          }
-          return;
-        } else {
-          parts[key] = entity;
-        }
-      }
-      parts[key] = decode(value, key);
-    });
-    return new DecodedEntity.group('{', parts, '}', true);
-  }
-
-  /**
-   * Decode the given [PackageBundle].
-   */
-  DecodedEntity decodePackageBundle(PackageBundle bundle) {
-    Map<String, UnlinkedUnit> units = <String, UnlinkedUnit>{};
-    Set<String> seenUnits = new Set<String>();
-    for (int i = 0; i < bundle.unlinkedUnits.length; i++) {
-      units[bundle.unlinkedUnitUris[i]] = bundle.unlinkedUnits[i];
-    }
-    Map<String, Object> restOfMap = bundle.toMap();
-    Map<String, Object> result = <String, Object>{};
-    result['version'] = new DecodedEntity.short(
-        '${bundle.majorVersion}.${bundle.minorVersion}');
-    restOfMap.remove('majorVersion');
-    restOfMap.remove('minorVersion');
-    result['linkedLibraryUris'] = restOfMap['linkedLibraryUris'];
-    result['unlinkedUnitUris'] = restOfMap['unlinkedUnitUris'];
-    for (int i = 0; i < bundle.linkedLibraries.length; i++) {
-      String libraryUriString = bundle.linkedLibraryUris[i];
-      Uri libraryUri = Uri.parse(libraryUriString);
-      UnlinkedUnit unlinkedDefiningUnit = units[libraryUriString];
-      seenUnits.add(libraryUriString);
-      List<UnlinkedUnit> libraryUnits = <UnlinkedUnit>[unlinkedDefiningUnit];
-      LinkedLibrary linkedLibrary = bundle.linkedLibraries[i];
-      for (int j = 1; j < linkedLibrary.units.length; j++) {
-        String partUriString = resolveRelativeUri(libraryUri,
-                Uri.parse(unlinkedDefiningUnit.publicNamespace.parts[j - 1]))
-            .toString();
-        libraryUnits.add(units[partUriString]);
-        seenUnits.add(partUriString);
-      }
-      result['library ${JSON.encode(libraryUriString)}'] =
-          new LibraryWrapper(linkedLibrary, libraryUnits);
-    }
-    for (String uriString in units.keys) {
-      if (seenUnits.contains(uriString)) {
-        continue;
-      }
-      result['orphan unit ${JSON.encode(uriString)}'] =
-          new UnitWrapper(null, units[uriString]);
-    }
-    restOfMap.remove('linkedLibraries');
-    restOfMap.remove('linkedLibraryUris');
-    restOfMap.remove('unlinkedUnits');
-    restOfMap.remove('unlinkedUnitUris');
-    result.addAll(restOfMap);
-    return decodeMap(result);
-  }
-
-  /**
-   * Decode the given [ReferenceWrapper].
-   */
-  DecodedEntity decodeReference(ReferenceWrapper obj) {
-    Map<String, Object> result = obj._unlinked != null
-        ? obj._unlinked.toMap()
-        : <String, Object>{'linkedOnly': true};
-    if (obj._linked != null) {
-      mergeMaps(result, obj._linked.toMap());
-    }
-    return decodeMap(result);
-  }
-
-  /**
-   * Decode the given [UnitWrapper].
-   */
-  DecodedEntity decodeUnit(UnitWrapper obj) {
-    try {
-      LinkedUnit linked = obj._linked;
-      UnlinkedUnit unlinked = obj._unlinked ?? new UnlinkedUnitBuilder();
-      Map<String, Object> unlinkedMap = unlinked.toMap();
-      Map<String, Object> linkedMap =
-          linked != null ? linked.toMap() : <String, Object>{};
-      Map<String, Object> result = <String, Object>{};
-      List<ReferenceWrapper> references = <ReferenceWrapper>[];
-      int numReferences = linked != null
-          ? linked.references.length
-          : unlinked.references.length;
-      for (int i = 0; i < numReferences; i++) {
-        references.add(new ReferenceWrapper(
-            linked != null ? linked.references[i] : null,
-            i < unlinked.references.length ? unlinked.references[i] : null));
-      }
-      result['references'] = references;
-      _references = references;
-      unlinkedMap.remove('references');
-      linkedMap.remove('references');
-      linkedMap.forEach((String key, Object value) {
-        result['linked $key'] = value;
-      });
-      unlinkedMap.forEach((String key, Object value) {
-        result[key] = value;
-      });
-      return decodeMap(result);
-    } finally {
-      _references = null;
-    }
-  }
-
-  /**
-   * Decode the given [PackageBundle] and dump it to a list of strings.
-   */
-  List<String> dumpPackageBundle(PackageBundle bundle) {
-    DecodedEntity decoded = decode(bundle, 'PackageBundle');
-    return decoded.getLines();
-  }
-
-  /**
-   * Merge the contents of [other] into [result], discarding empty entries.
-   */
-  void mergeMaps(Map<String, Object> result, Map<String, Object> other) {
-    other.forEach((String key, Object value) {
-      if (value is String && value.isEmpty) {
-        return;
-      }
-      if (result.containsKey(key)) {
-        Object oldValue = result[key];
-        if (oldValue is String && oldValue.isEmpty) {
-          result[key] = value;
-        } else {
-          throw new Exception(
-              'Duplicate values for $key: $oldValue and $value');
-        }
-      } else {
-        result[key] = value;
-      }
-    });
-  }
-
-  /**
-   * Reorder [map] for more intuitive display.
-   */
-  Map<String, Object> reorderMap(Map<String, Object> map) {
-    Map<String, Object> result = <String, Object>{};
-    if (map.containsKey('name')) {
-      result['name'] = map['name'];
-    }
-    result.addAll(map);
-    return result;
-  }
-}
-
-/**
- * Decoded reprensentation of a part of a summary that occupies a single line of
- * output.
- */
-class UnbrokenEntity implements DecodedEntity {
-  final String _s;
-
-  UnbrokenEntity(this._s);
-
-  @override
-  List<String> getLines() => <String>[_s];
-}
-
-/**
- * Wrapper around a [LinkedUnit] and its corresponding [UnlinkedUnit].
- */
-class UnitWrapper {
-  final LinkedUnit _linked;
-  final UnlinkedUnit _unlinked;
-
-  UnitWrapper(this._linked, this._unlinked);
-}
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 57dccf1..7d77fb8 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -347,7 +347,7 @@
   @override
   final CompilationUnitElementForLink enclosingElement;
 
-  @override
+  /// TODO(brianwilkerson) This appears to be unused and might be removable.
   bool hasBeenInferred;
 
   ClassElementForLink(CompilationUnitElementForLink enclosingElement)
@@ -368,7 +368,7 @@
   List<ConstructorElementForLink> get constructors;
 
   @override
-  CompilationUnitElementForLink get enclosingUnit => enclosingElement;
+  CompilationUnitElementImpl get enclosingUnit => enclosingElement;
 
   @override
   List<FieldElementForLink> get fields;
@@ -571,7 +571,7 @@
   }
 
   @override
-  DartType get type =>
+  InterfaceType get type =>
       _type ??= buildType((int i) => typeParameterTypes[i], null);
 
   @override
@@ -593,6 +593,9 @@
   }
 
   @override
+  int get version => 0;
+
+  @override
   DartType buildType(
       DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
     int numTypeParameters = _unlinkedClass.typeParameters.length;
@@ -737,7 +740,7 @@
   InterfaceType get supertype => library._linker.typeProvider.objectType;
 
   @override
-  DartType get type => _type ??= new InterfaceTypeImpl(this);
+  InterfaceType get type => _type ??= new InterfaceTypeImpl(this);
 
   @override
   List<TypeParameterElement> get typeParameters => const [];
@@ -1055,6 +1058,7 @@
           return null;
         }
       }
+
       ReferenceableElementForLink element = resolveRef(type.reference);
       return element.buildType(
           getTypeArgument, type.implicitFunctionTypeIndices);
@@ -1195,7 +1199,7 @@
               enclosingClass != null ? addReference(enclosingClass) : null,
           dependency: enclosingClass != null
               ? null
-              : library.addDependency(element.library),
+              : library.addDependency(element.library as LibraryElementForLink),
           kind: kind);
     } else if (element is FunctionElementForLink_Initializer) {
       return addRawReference('',
@@ -1361,6 +1365,7 @@
         dependencies.add(target);
       }
     }
+
     UnlinkedExecutable unlinkedExecutable =
         constructorElement._unlinkedExecutable;
     ClassElementForLink_Class enclosingClass =
@@ -1626,6 +1631,9 @@
   ConstructorElementForLink get asConstructor => this;
 
   @override
+  ClassElementImpl get enclosingElement => super.enclosingClass;
+
+  @override
   bool get isCycleFree {
     if (!_constNode.isEvaluated) {
       new ConstDependencyWalker().walk(_constNode);
@@ -1849,7 +1857,6 @@
   String _name;
   String _displayName;
 
-  @override
   final CompilationUnitElementForLink compilationUnit;
 
   ExecutableElementForLink(this.compilationUnit, this._unlinkedExecutable);
@@ -1926,7 +1933,7 @@
   bool get isSynthetic => false;
 
   @override
-  LibraryElementForLink get library => enclosingElement.library;
+  LibraryElement get library => enclosingElement.library;
 
   @override
   String get name {
@@ -1972,7 +1979,7 @@
    */
   DartType _computeDefaultReturnType() {
     if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter &&
-        library._linker.strongMode) {
+        (library as LibraryElementForLink)._linker.strongMode) {
       // In strong mode, setters without an explicit return type are
       // considered to return `void`.
       return VoidTypeImpl.instance;
@@ -3725,6 +3732,9 @@
   DartType get asStaticType => type;
 
   @override
+  ClassElementImpl get enclosingElement => super.enclosingClass;
+
+  @override
   String get identifier => name;
 
   @override
@@ -3995,7 +4005,7 @@
  * Mixin used by elements that can have parameters.
  */
 abstract class ParameterParentElementForLink implements Element {
-  List<ParameterElementForLink> _parameters;
+  List<ParameterElement> _parameters;
 
   /**
    * Get the appropriate integer list to store in
@@ -4009,11 +4019,11 @@
   /**
    * Get all the parameters of this element.
    */
-  List<ParameterElementForLink> get parameters {
+  List<ParameterElement> get parameters {
     if (_parameters == null) {
       List<UnlinkedParam> unlinkedParameters = this.unlinkedParameters;
       int numParameters = unlinkedParameters.length;
-      _parameters = new List<ParameterElementForLink>(numParameters);
+      _parameters = new List<ParameterElement>(numParameters);
       for (int i = 0; i < numParameters; i++) {
         UnlinkedParam unlinkedParam = unlinkedParameters[i];
         _parameters[i] = new ParameterElementForLink(
@@ -4139,7 +4149,7 @@
     with ReferenceableElementForLink
     implements PropertyAccessorElementForLink {
   @override
-  SyntheticVariableElementForLink variable;
+  PropertyInducingElement variable;
 
   PropertyAccessorElementForLink_Executable(
       CompilationUnitElementForLink enclosingUnit,
@@ -4167,12 +4177,15 @@
   bool get isStatic => enclosingClass == null || super.isStatic;
 
   @override
-  ElementKind get kind => _unlinkedExecutable.kind ==
-      UnlinkedExecutableKind.getter ? ElementKind.GETTER : ElementKind.SETTER;
+  ElementKind get kind =>
+      _unlinkedExecutable.kind == UnlinkedExecutableKind.getter
+          ? ElementKind.GETTER
+          : ElementKind.SETTER;
 
   @override
   ReferenceableElementForLink getContainedName(String name) {
-    return new NonstaticMemberElementForLink(library, this, name);
+    return new NonstaticMemberElementForLink(
+        library as LibraryElementForLink, this, name);
   }
 
   @override
@@ -4647,7 +4660,7 @@
   String toString() => 'TypeInferenceNode($functionElement)';
 }
 
-class TypeProviderForLink implements TypeProvider {
+class TypeProviderForLink extends TypeProviderBase {
   final Linker _linker;
 
   InterfaceType _boolType;
@@ -4729,16 +4742,6 @@
       _mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
 
   @override
-  List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
-        nullType,
-        numType,
-        intType,
-        doubleType,
-        boolType,
-        stringType
-      ];
-
-  @override
   DartObjectImpl get nullObject {
     // TODO(paulberry): implement if needed
     throw new UnimplementedError();
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 0055866..719dbab 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -1,6 +1,7 @@
 import 'dart:io' as io;
 
 import 'package:analyzer/dart/element/element.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/dart/element/element.dart';
@@ -9,10 +10,15 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/source/source_resource.dart';
+import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
 import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:path/path.dart' as pathos;
 
@@ -37,9 +43,8 @@
 /**
  * The [UriResolver] that knows about sources that are served from their
  * summaries.
- *
- * TODO(scheglov) rename to `InSummaryUriResolver` - it's not `package:` specific.
  */
+@deprecated
 class InSummaryPackageUriResolver extends UriResolver {
   final SummaryDataStore _dataStore;
 
@@ -113,6 +118,36 @@
 }
 
 /**
+ * The [UriResolver] that knows about sources that are served from their
+ * summaries.
+ */
+class InSummaryUriResolver extends UriResolver {
+  ResourceProvider resourceProvider;
+  final SummaryDataStore _dataStore;
+
+  InSummaryUriResolver(this.resourceProvider, this._dataStore);
+
+  @override
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    actualUri ??= uri;
+    String uriString = uri.toString();
+    UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
+    if (unit != null) {
+      String summaryPath = _dataStore.uriToSummaryPath[uriString];
+      if (unit.fallbackModePath.isNotEmpty) {
+        return new _InSummaryFallbackFileSource(
+            resourceProvider.getFile(unit.fallbackModePath),
+            actualUri,
+            summaryPath);
+      } else {
+        return new InSummarySource(actualUri, summaryPath);
+      }
+    }
+    return null;
+  }
+}
+
+/**
  * The [ResultProvider] that provides results using summary resynthesizer.
  */
 abstract class ResynthesizerResultProvider extends ResultProvider {
@@ -182,6 +217,27 @@
           return true;
         }
         return false;
+      } else if (result == CONTAINING_LIBRARIES) {
+        List<String> libraryUriStrings =
+            _dataStore.getContainingLibraryUris(uriString);
+        if (libraryUriStrings != null) {
+          List<Source> librarySources = libraryUriStrings
+              .map((libraryUriString) =>
+                  context.sourceFactory.resolveUri(target, libraryUriString))
+              .toList(growable: false);
+          entry.setValue(result, librarySources, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        return false;
+      } else if (result == LINE_INFO) {
+        UnlinkedUnit unlinkedUnit = _dataStore.unlinkedMap[uriString];
+        List<int> lineStarts = unlinkedUnit.lineStarts;
+        if (lineStarts.isNotEmpty) {
+          LineInfo lineInfo = new LineInfo(lineStarts);
+          entry.setValue(result, lineInfo, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        return false;
       }
     } else if (target is LibrarySpecificUnit) {
       if (result == CREATED_RESOLVED_UNIT1 ||
@@ -259,6 +315,15 @@
   final List<PackageBundle> bundles = <PackageBundle>[];
 
   /**
+   * List of dependency information for the package bundles in this
+   * [SummaryDataStore], in a form that is ready to store in a newly generated
+   * summary.  Computing this information has nonzero cost, so it is only
+   * recorded if the [SummaryDataStore] is constructed with the argument
+   * `recordDependencies`.  Otherwise `null`.
+   */
+  final List<PackageDependencyInfoBuilder> dependencies;
+
+  /**
    * Map from the URI of a compilation unit to the unlinked summary of that
    * compilation unit.
    */
@@ -274,7 +339,16 @@
    */
   final Map<String, String> uriToSummaryPath = <String, String>{};
 
-  SummaryDataStore(Iterable<String> summaryPaths) {
+  /**
+   * Create a [SummaryDataStore] and populate it with the summaries in
+   * [summaryPaths].  If [recordDependencyInfo] is `true`, record
+   * [PackageDependencyInfo] for each summary, for later access via
+   * [dependencies].
+   */
+  SummaryDataStore(Iterable<String> summaryPaths,
+      {bool recordDependencyInfo: false})
+      : dependencies =
+            recordDependencyInfo ? <PackageDependencyInfoBuilder>[] : null {
     summaryPaths.forEach(_fillMaps);
   }
 
@@ -283,6 +357,29 @@
    */
   void addBundle(String path, PackageBundle bundle) {
     bundles.add(bundle);
+    if (dependencies != null) {
+      Set<String> includedPackageNames = new Set<String>();
+      bool includesDartUris = false;
+      bool includesFileUris = false;
+      for (String uriString in bundle.unlinkedUnitUris) {
+        Uri uri = FastUri.parse(uriString);
+        String scheme = uri.scheme;
+        if (scheme == 'package') {
+          List<String> pathSegments = uri.pathSegments;
+          includedPackageNames.add(pathSegments.isEmpty ? '' : pathSegments[0]);
+        } else if (scheme == 'file') {
+          includesFileUris = true;
+        } else if (scheme == 'dart') {
+          includesDartUris = true;
+        }
+      }
+      dependencies.add(new PackageDependencyInfoBuilder(
+          includedPackageNames: includedPackageNames.toList()..sort(),
+          includesDartUris: includesDartUris,
+          includesFileUris: includesFileUris,
+          apiSignature: bundle.apiSignature,
+          summaryPath: path));
+    }
     for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
       String uri = bundle.unlinkedUnitUris[i];
       uriToSummaryPath[uri] = path;
@@ -294,6 +391,31 @@
     }
   }
 
+  /**
+   * Return a list of absolute URIs of the libraries that contain the unit with
+   * the given [unitUriString], or `null` if no such library is in the store.
+   */
+  List<String> getContainingLibraryUris(String unitUriString) {
+    // The unit is the defining unit of a library.
+    if (linkedMap.containsKey(unitUriString)) {
+      return <String>[unitUriString];
+    }
+    // Check every unlinked unit whether it uses [unitUri] as a part.
+    List<String> libraryUriStrings = <String>[];
+    unlinkedMap.forEach((unlinkedUnitUriString, unlinkedUnit) {
+      Uri libraryUri = FastUri.parse(unlinkedUnitUriString);
+      for (String partUriString in unlinkedUnit.publicNamespace.parts) {
+        Uri partUri = FastUri.parse(partUriString);
+        String partAbsoluteUriString =
+            resolveRelativeUri(libraryUri, partUri).toString();
+        if (partAbsoluteUriString == unitUriString) {
+          libraryUriStrings.add(unlinkedUnitUriString);
+        }
+      }
+    });
+    return libraryUriStrings.isNotEmpty ? libraryUriStrings : null;
+  }
+
   void _fillMaps(String path) {
     io.File file = new io.File(path);
     List<int> buffer = file.readAsBytesSync();
@@ -336,9 +458,24 @@
 
 /**
  * A source that is part of a package whose summary was generated in fallback
- * mode.  This source behaves identically to a [FileBasedSource] except that it
+ * mode. This source behaves identically to a [FileSource] except that it also
+ * provides [summaryPath].
+ */
+class _InSummaryFallbackFileSource extends FileSource
+    implements InSummarySource {
+  @override
+  final String summaryPath;
+
+  _InSummaryFallbackFileSource(File file, Uri uri, this.summaryPath)
+      : super(file, uri);
+}
+
+/**
+ * A source that is part of a package whose summary was generated in fallback
+ * mode. This source behaves identically to a [FileBasedSource] except that it
  * also provides [summaryPath].
  */
+@deprecated
 class _InSummaryFallbackSource extends FileBasedSource
     implements InSummarySource {
   @override
diff --git a/pkg/analyzer/lib/src/summary/pub_summary.dart b/pkg/analyzer/lib/src/summary/pub_summary.dart
new file mode 100644
index 0000000..dc2d110
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/pub_summary.dart
@@ -0,0 +1,765 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:core' hide Resource;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/link.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart'
+    show ResynthesizerResultProvider, SummaryDataStore;
+import 'package:analyzer/src/summary/summarize_ast.dart'
+    show serializeAstUnlinked;
+import 'package:analyzer/src/summary/summarize_elements.dart'
+    show PackageBundleAssembler;
+import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:meta/meta.dart';
+import 'package:path/path.dart' as pathos;
+
+/**
+ * Unlinked and linked information about a [PubPackage].
+ */
+class LinkedPubPackage {
+  final PubPackage package;
+  final PackageBundle unlinked;
+  final PackageBundle linked;
+
+  final String linkedHash;
+
+  LinkedPubPackage(this.package, this.unlinked, this.linked, this.linkedHash);
+
+  @override
+  String toString() => package.toString();
+}
+
+/**
+ * A package in the pub cache.
+ */
+class PubPackage {
+  final String name;
+  final Folder libFolder;
+
+  PubPackage(this.name, this.libFolder);
+
+  Folder get folder => libFolder.parent;
+
+  @override
+  int get hashCode => libFolder.hashCode;
+
+  @override
+  bool operator ==(other) {
+    return other is PubPackage && other.libFolder == libFolder;
+  }
+
+  @override
+  String toString() => '($name in $folder)';
+}
+
+/**
+ * Class that manages summaries for pub packages.
+ *
+ * The client should call [getLinkedBundles] after creating a new
+ * [AnalysisContext] and configuring its source factory, but before computing
+ * any analysis results.  The returned linked bundles can be used to create and
+ * configure [ResynthesizerResultProvider] for the context.
+ */
+class PubSummaryManager {
+  static const UNLINKED_NAME = 'unlinked.ds';
+  static const UNLINKED_SPEC_NAME = 'unlinked_spec.ds';
+
+  final ResourceProvider resourceProvider;
+
+  /**
+   * The name of the temporary file that is used for atomic writes.
+   */
+  final String tempFileName;
+
+  /**
+   * The map from [PubPackage]s to their unlinked [PackageBundle]s in the pub
+   * cache.
+   */
+  final Map<PubPackage, PackageBundle> unlinkedBundleMap =
+      new HashMap<PubPackage, PackageBundle>();
+
+  /**
+   * The map from linked file paths to the corresponding linked bundles.
+   */
+  final Map<String, PackageBundle> linkedBundleMap =
+      new HashMap<String, PackageBundle>();
+
+  /**
+   * The set of packages to compute unlinked summaries for.
+   */
+  final Set<PubPackage> packagesToComputeUnlinked = new Set<PubPackage>();
+
+  /**
+   * The set of already processed packages, which we have already checked
+   * for their unlinked bundle existence, or scheduled its computing.
+   */
+  final Set<PubPackage> seenPackages = new Set<PubPackage>();
+
+  /**
+   * The [Completer] that completes when computing of all scheduled unlinked
+   * bundles is complete.
+   */
+  Completer _onUnlinkedCompleteCompleter;
+
+  PubSummaryManager(this.resourceProvider, this.tempFileName);
+
+  /**
+   * The [Future] that completes when computing of all scheduled unlinked
+   * bundles is complete.
+   */
+  Future get onUnlinkedComplete {
+    if (packagesToComputeUnlinked.isEmpty) {
+      return new Future.value();
+    }
+    _onUnlinkedCompleteCompleter ??= new Completer();
+    return _onUnlinkedCompleteCompleter.future;
+  }
+
+  /**
+   * Return the [pathos.Context] corresponding to the [resourceProvider].
+   */
+  pathos.Context get pathContext => resourceProvider.pathContext;
+
+  /**
+   * Compute and return the linked bundle for the SDK extension for the given
+   * [context], or `null` if none of the packages has an SDK extension.  At most
+   * one extension library is supported, if more than one is found, then an
+   * error will be logged, and `null` returned.
+   */
+  PackageBundle computeSdkExtension(
+      AnalysisContext context, PackageBundle sdkBundle) {
+    // Prepare SDK extension library files.
+    String libUriStr;
+    String libPath;
+    {
+      Map<String, List<Folder>> packageMap = context.sourceFactory.packageMap;
+      SdkExtensionFinder extFinder = new SdkExtensionFinder(packageMap);
+      Map<String, String> sdkExtMappings = extFinder.urlMappings;
+      if (sdkExtMappings.length == 1) {
+        libUriStr = sdkExtMappings.keys.first;
+        libPath = sdkExtMappings.values.first;
+      } else if (sdkExtMappings.length > 1) {
+        AnalysisEngine.instance.logger
+            .logError('At most one _sdkext file is supported, '
+                'with at most one extension library. $sdkExtMappings found.');
+        return null;
+      } else {
+        return null;
+      }
+    }
+    // Compute the extension unlinked bundle.
+    bool strong = context.analysisOptions.strongMode;
+    PackageBundleAssembler assembler = new PackageBundleAssembler();
+    try {
+      File libFile = resourceProvider.getFile(libPath);
+      Uri libUri = FastUri.parse(libUriStr);
+      Source libSource = libFile.createSource(libUri);
+      CompilationUnit libraryUnit = _parse(libSource, strong);
+      // Add the library unit.
+      assembler.addUnlinkedUnit(libSource, serializeAstUnlinked(libraryUnit));
+      // Add part units.
+      for (Directive directive in libraryUnit.directives) {
+        if (directive is PartDirective) {
+          Source partSource;
+          {
+            String partUriStr = directive.uri.stringValue;
+            Uri partUri = resolveRelativeUri(libUri, FastUri.parse(partUriStr));
+            pathos.Context pathContext = resourceProvider.pathContext;
+            String partPath =
+                pathContext.join(pathContext.dirname(libPath), partUriStr);
+            File partFile = resourceProvider.getFile(partPath);
+            partSource = partFile.createSource(partUri);
+          }
+          CompilationUnit partUnit = _parse(partSource, strong);
+          assembler.addUnlinkedUnit(partSource, serializeAstUnlinked(partUnit));
+        }
+      }
+      // Add the SDK and the unlinked extension bundle.
+      PackageBundleBuilder unlinkedBuilder = assembler.assemble();
+      SummaryDataStore store = new SummaryDataStore(const <String>[]);
+      store.addBundle(null, sdkBundle);
+      store.addBundle(null, unlinkedBuilder);
+      // Link the extension bundle.
+      Map<String, LinkedLibraryBuilder> linkedLibraries =
+          link([libUriStr].toSet(), (String absoluteUri) {
+        return store.linkedMap[absoluteUri];
+      }, (String absoluteUri) {
+        return store.unlinkedMap[absoluteUri];
+      }, strong);
+      if (linkedLibraries.length != 1) {
+        return null;
+      }
+      // Append linked libraries into the assembler.
+      linkedLibraries.forEach((uri, library) {
+        assembler.addLinkedLibrary(uri, library);
+      });
+      List<int> bytes = assembler.assemble().toBuffer();
+      return new PackageBundle.fromBuffer(bytes);
+    } on FileSystemException {
+      return null;
+    }
+  }
+
+  /**
+   * Complete when the unlinked bundles for the package with the given [name]
+   * and the [libFolder] are computed and written to the files.
+   *
+   * This method is intended to be used for generating unlinked bundles for
+   * the `Flutter` packages.
+   */
+  Future<Null> computeUnlinkedForFolder(String name, Folder libFolder) async {
+    PubPackage package = new PubPackage(name, libFolder);
+    _scheduleUnlinked(package);
+    await onUnlinkedComplete;
+  }
+
+  /**
+   * Return the list of linked [LinkedPubPackage]s that can be provided at this
+   * time for a subset of the packages used by the given [context].  If
+   * information about some of the used packages is not available yet, schedule
+   * its computation, so that it might be available later for other contexts
+   * referencing the same packages.
+   */
+  List<LinkedPubPackage> getLinkedBundles(AnalysisContext context) {
+//    Stopwatch timer = new Stopwatch()..start();
+
+    PackageBundle sdkBundle = context.sourceFactory.dartSdk.getLinkedBundle();
+    if (sdkBundle == null) {
+      return const <LinkedPubPackage>[];
+    }
+
+    // Prepare all SDK bundles.
+    List<PackageBundle> sdkBundles = <PackageBundle>[sdkBundle];
+    {
+      PackageBundle extension = computeSdkExtension(context, sdkBundle);
+      if (extension != null) {
+        sdkBundles.add(extension);
+      }
+    }
+
+    bool strong = context.analysisOptions.strongMode;
+    Map<PubPackage, PackageBundle> unlinkedBundles =
+        getUnlinkedBundles(context);
+
+    // TODO(scheglov) remove debug output after optimizing
+//    print('LOADED ${unlinkedBundles.length} unlinked bundles'
+//        ' in ${timer.elapsedMilliseconds} ms');
+//    timer..reset();
+
+    // If no unlinked bundles, there is nothing we can try to link.
+    if (unlinkedBundles.isEmpty) {
+      return const <LinkedPubPackage>[];
+    }
+
+    // Create graph nodes for packages.
+    List<_LinkedNode> nodes = <_LinkedNode>[];
+    Map<String, _LinkedNode> packageToNode = <String, _LinkedNode>{};
+    unlinkedBundles.forEach((package, unlinked) {
+      _LinkedNode node =
+          new _LinkedNode(sdkBundles, package, unlinked, packageToNode);
+      nodes.add(node);
+      packageToNode[package.name] = node;
+    });
+
+    // Attempt to read existing linked bundles.
+    for (_LinkedNode node in nodes) {
+      _readLinked(node, strong);
+    }
+
+    // Fill the store with bundles.
+    // Append linked SDK bundles.
+    // Append unlinked and (if read from a cache) linked package bundles.
+    SummaryDataStore store = new SummaryDataStore(const <String>[]);
+    sdkBundles.forEach((bundle) => store.addBundle(null, bundle));
+    for (_LinkedNode node in nodes) {
+      store.addBundle(null, node.unlinked);
+      if (node.linked != null) {
+        store.addBundle(null, node.linked);
+      }
+    }
+
+    // Link each package node.
+    for (_LinkedNode node in nodes) {
+      if (!node.isEvaluated) {
+        new _LinkedWalker(store, strong).walk(node);
+      }
+    }
+
+    // Write newly linked bundles.
+    for (_LinkedNode node in nodes) {
+      _writeLinked(node, strong);
+    }
+
+    // Create successfully linked packages.
+    List<LinkedPubPackage> linkedPackages = <LinkedPubPackage>[];
+    for (_LinkedNode node in nodes) {
+      if (node.linked != null) {
+        linkedPackages.add(new LinkedPubPackage(
+            node.package, node.unlinked, node.linked, node._linkedHash));
+      }
+    }
+
+    // TODO(scheglov) remove debug output after optimizing
+//    print('LINKED ${linkedPackages.length} bundles'
+//        ' in ${timer.elapsedMilliseconds} ms');
+
+    // Done.
+    return linkedPackages;
+  }
+
+  /**
+   * Return all available unlinked [PackageBundle]s for the given [context],
+   * maybe an empty map, but not `null`.
+   */
+  @visibleForTesting
+  Map<PubPackage, PackageBundle> getUnlinkedBundles(AnalysisContext context) {
+    bool strong = context.analysisOptions.strongMode;
+    Map<PubPackage, PackageBundle> unlinkedBundles =
+        new HashMap<PubPackage, PackageBundle>();
+    Map<String, List<Folder>> packageMap = context.sourceFactory.packageMap;
+    if (packageMap != null) {
+      packageMap.forEach((String packageName, List<Folder> libFolders) {
+        if (libFolders.length == 1) {
+          Folder libFolder = libFolders.first;
+          PubPackage package = new PubPackage(packageName, libFolder);
+          PackageBundle unlinkedBundle =
+              _getUnlinkedOrSchedule(package, strong);
+          if (unlinkedBundle != null) {
+            unlinkedBundles[package] = unlinkedBundle;
+          }
+        }
+      });
+    }
+    return unlinkedBundles;
+  }
+
+  /**
+   * Compute unlinked bundle for a package from [packagesToComputeUnlinked],
+   * and schedule delayed computation for the next package, if any.
+   */
+  void _computeNextUnlinked() {
+    if (packagesToComputeUnlinked.isNotEmpty) {
+      PubPackage package = packagesToComputeUnlinked.first;
+      _computeUnlinked(package, false);
+      _computeUnlinked(package, true);
+      packagesToComputeUnlinked.remove(package);
+      _scheduleNextUnlinked();
+    } else {
+      if (_onUnlinkedCompleteCompleter != null) {
+        _onUnlinkedCompleteCompleter.complete(true);
+        _onUnlinkedCompleteCompleter = null;
+      }
+    }
+  }
+
+  /**
+   * Compute the unlinked bundle for the package with the given path, put
+   * it in the [unlinkedBundleMap] and store into the [resourceProvider].
+   *
+   * TODO(scheglov) Consider moving into separate isolate(s).
+   */
+  void _computeUnlinked(PubPackage package, bool strong) {
+    Folder libFolder = package.libFolder;
+    String libPath = libFolder.path + pathContext.separator;
+    PackageBundleAssembler assembler = new PackageBundleAssembler();
+
+    /**
+     * Return the `package` [Uri] for the given [path] in the `lib` folder
+     * of the current package.
+     */
+    Uri getUri(String path) {
+      String pathInLib = path.substring(libPath.length);
+      String uriPath = pathos.posix.joinAll(pathContext.split(pathInLib));
+      String uriStr = 'package:${package.name}/$uriPath';
+      return FastUri.parse(uriStr);
+    }
+
+    /**
+     * If the given [file] is a Dart file, add its unlinked unit.
+     */
+    void addDartFile(File file) {
+      String path = file.path;
+      if (AnalysisEngine.isDartFileName(path)) {
+        Uri uri = getUri(path);
+        Source source = file.createSource(uri);
+        CompilationUnit unit = _parse(source, strong);
+        UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
+        assembler.addUnlinkedUnit(source, unlinkedUnit);
+      }
+    }
+
+    /**
+     * Visit the [folder] recursively.
+     */
+    void addDartFiles(Folder folder) {
+      List<Resource> children = folder.getChildren();
+      for (Resource child in children) {
+        if (child is File) {
+          addDartFile(child);
+        }
+      }
+      for (Resource child in children) {
+        if (child is Folder) {
+          addDartFiles(child);
+        }
+      }
+    }
+
+    try {
+      addDartFiles(libFolder);
+      List<int> bytes = assembler.assemble().toBuffer();
+      String fileName = _getUnlinkedName(strong);
+      _writeAtomic(package.folder, fileName, bytes);
+    } on FileSystemException {
+      // Ignore file system exceptions.
+    }
+  }
+
+  /**
+   * Return the name of the file for a linked bundle, in strong or spec mode.
+   */
+  String _getLinkedName(String hash, bool strong) {
+    if (strong) {
+      return 'linked_$hash.ds';
+    } else {
+      return 'linked_spec_$hash.ds';
+    }
+  }
+
+  /**
+   * Return the name of the file for an unlinked bundle, in strong or spec mode.
+   */
+  String _getUnlinkedName(bool strong) {
+    if (strong) {
+      return UNLINKED_NAME;
+    } else {
+      return UNLINKED_SPEC_NAME;
+    }
+  }
+
+  /**
+   * Return the unlinked [PackageBundle] for the given [package]. If the bundle
+   * has not been compute yet, return `null` and schedule its computation.
+   */
+  PackageBundle _getUnlinkedOrSchedule(PubPackage package, bool strong) {
+    // Try to find in the cache.
+    PackageBundle bundle = unlinkedBundleMap[package];
+    if (bundle != null) {
+      return bundle;
+    }
+    // Try to read from the file system.
+    String fileName = _getUnlinkedName(strong);
+    File unlinkedFile = package.folder.getChildAssumingFile(fileName);
+    if (unlinkedFile.exists) {
+      try {
+        List<int> bytes = unlinkedFile.readAsBytesSync();
+        bundle = new PackageBundle.fromBuffer(bytes);
+        unlinkedBundleMap[package] = bundle;
+        // TODO(scheglov) if not in the pub cache, check for consistency
+        return bundle;
+      } on FileSystemException {
+        // Ignore file system exceptions.
+      }
+    }
+    // Schedule computation in the background, if in the pub cache.
+    if (isPathInPubCache(pathContext, package.folder.path)) {
+      if (seenPackages.add(package)) {
+        _scheduleUnlinked(package);
+      }
+    }
+    // The bundle is for available.
+    return null;
+  }
+
+  /**
+   * Parse the given [source] into AST.
+   */
+  CompilationUnit _parse(Source source, bool strong) {
+    String code = source.contents.data;
+    AnalysisErrorListener errorListener = AnalysisErrorListener.NULL_LISTENER;
+    CharSequenceReader reader = new CharSequenceReader(code);
+    Scanner scanner = new Scanner(source, reader, errorListener);
+    scanner.scanGenericMethodComments = strong;
+    Token token = scanner.tokenize();
+    LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+    Parser parser = new Parser(source, errorListener);
+    parser.parseGenericMethodComments = strong;
+    CompilationUnit unit = parser.parseCompilationUnit(token);
+    unit.lineInfo = lineInfo;
+    return unit;
+  }
+
+  /**
+   * Attempt to find the linked bundle that corresponds to the given [node]
+   * with all its transitive dependencies and put it into [_LinkedNode.linked].
+   */
+  void _readLinked(_LinkedNode node, bool strong) {
+    String hash = node.linkedHash;
+    if (hash != null) {
+      String fileName = _getLinkedName(hash, strong);
+      File file = node.package.folder.getChildAssumingFile(fileName);
+      // Try to find in the cache.
+      PackageBundle linked = linkedBundleMap[file.path];
+      if (linked != null) {
+        node.linked = linked;
+        return;
+      }
+      // Try to read from the file system.
+      if (file.exists) {
+        try {
+          List<int> bytes = file.readAsBytesSync();
+          linked = new PackageBundle.fromBuffer(bytes);
+          linkedBundleMap[file.path] = linked;
+          node.linked = linked;
+        } on FileSystemException {
+          // Ignore file system exceptions.
+        }
+      }
+    }
+  }
+
+  /**
+   * Schedule delayed computation of the next package unlinked bundle from the
+   * set of [packagesToComputeUnlinked].  We delay each computation because we
+   * want operations in analysis server to proceed, and computing bundles of
+   * packages is a background task.
+   */
+  void _scheduleNextUnlinked() {
+    new Future.delayed(new Duration(milliseconds: 10), _computeNextUnlinked);
+  }
+
+  /**
+   * Schedule computing unlinked bundles for the given [package].
+   */
+  void _scheduleUnlinked(PubPackage package) {
+    if (packagesToComputeUnlinked.isEmpty) {
+      _scheduleNextUnlinked();
+    }
+    packagesToComputeUnlinked.add(package);
+  }
+
+  /**
+   * Atomically write the given [bytes] into the file in the [folder].
+   */
+  void _writeAtomic(Folder folder, String fileName, List<int> bytes) {
+    String filePath = folder.getChildAssumingFile(fileName).path;
+    File tempFile = folder.getChildAssumingFile(tempFileName);
+    tempFile.writeAsBytesSync(bytes);
+    tempFile.renameSync(filePath);
+  }
+
+  /**
+   * If a new linked bundle was linked for the given [node], write the bundle
+   * into the memory cache and the file system.
+   */
+  void _writeLinked(_LinkedNode node, bool strong) {
+    String hash = node.linkedHash;
+    if (hash != null && node.linkedNewBytes != null) {
+      String fileName = _getLinkedName(hash, strong);
+      File file = node.package.folder.getChildAssumingFile(fileName);
+      linkedBundleMap[file.path] = node.linked;
+      _writeAtomic(node.package.folder, fileName, node.linkedNewBytes);
+    }
+  }
+
+  /**
+   * If the given [uri] has the `package` scheme, return the name of the
+   * package that contains the referenced resource.  Otherwise return `null`.
+   *
+   * For example `package:foo/bar.dart` => `foo`.
+   */
+  static String getPackageName(String uri) {
+    const String PACKAGE_SCHEME = 'package:';
+    if (uri.startsWith(PACKAGE_SCHEME)) {
+      int index = uri.indexOf('/');
+      if (index != -1) {
+        return uri.substring(PACKAGE_SCHEME.length, index);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return `true` if the given absolute [path] is in the pub cache.
+   */
+  static bool isPathInPubCache(pathos.Context pathContext, String path) {
+    List<String> parts = pathContext.split(path);
+    for (int i = 0; i < parts.length - 1; i++) {
+      if (parts[i] == '.pub-cache') {
+        return true;
+      }
+      if (parts[i] == 'Pub' && parts[i + 1] == 'Cache') {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * Specialization of [Node] for linking packages in proper dependency order.
+ */
+class _LinkedNode extends Node<_LinkedNode> {
+  final List<PackageBundle> sdkBundles;
+  final PubPackage package;
+  final PackageBundle unlinked;
+  final Map<String, _LinkedNode> packageToNode;
+
+  String _linkedHash;
+
+  List<int> linkedNewBytes;
+  PackageBundle linked;
+
+  _LinkedNode(this.sdkBundles, this.package, this.unlinked, this.packageToNode);
+
+  @override
+  bool get isEvaluated => linked != null;
+
+  /**
+   * Return the hash string that corresponds to this linked bundle in the
+   * context of its [sdkBundles] and transitive dependencies.  Return `null` if
+   * the hash computation fails, because for example the full transitive
+   * dependencies cannot computed.
+   */
+  String get linkedHash {
+    if (_linkedHash == null) {
+      List<String> signatures = <String>[];
+      Set<_LinkedNode> transitiveDependencies = computeTransitiveDependencies();
+      sdkBundles
+          .map((sdkBundle) => sdkBundle.apiSignature)
+          .forEach(signatures.add);
+      transitiveDependencies
+          .map((node) => node.unlinked.apiSignature)
+          .forEach(signatures.add);
+      signatures.sort();
+      // Combine sorted unlinked API signatures into a single hash.
+      ApiSignature signature = new ApiSignature();
+      signatures.forEach(signature.addString);
+      _linkedHash = signature.toHex();
+    }
+    return _linkedHash;
+  }
+
+  @override
+  List<_LinkedNode> computeDependencies() {
+    Set<_LinkedNode> dependencies = new Set<_LinkedNode>();
+
+    void appendDependency(String uriStr) {
+      Uri uri = FastUri.parse(uriStr);
+      if (!uri.hasScheme) {
+        // A relative path in this package, skip it.
+      } else if (uri.scheme == 'dart') {
+        // Dependency on the SDK is implicit and always added.
+        // The SDK linked bundle is precomputed before linking packages.
+      } else if (uriStr.startsWith('package:')) {
+        String package = PubSummaryManager.getPackageName(uriStr);
+        _LinkedNode packageNode = packageToNode[package];
+        if (packageNode != null) {
+          dependencies.add(packageNode);
+        }
+      }
+    }
+
+    for (UnlinkedUnit unit in unlinked.unlinkedUnits) {
+      for (UnlinkedImport import in unit.imports) {
+        if (!import.isImplicit) {
+          appendDependency(import.uri);
+        }
+      }
+      for (UnlinkedExportPublic export in unit.publicNamespace.exports) {
+        appendDependency(export.uri);
+      }
+    }
+
+    return dependencies.toList();
+  }
+
+  /**
+   * Return the set of existing transitive dependencies for this node, skipping
+   * any missing dependencies.  Only [unlinked] is used, so this method can be
+   * called before linking.
+   */
+  Set<_LinkedNode> computeTransitiveDependencies() {
+    Set<_LinkedNode> allDependencies = new Set<_LinkedNode>();
+    _appendDependencies(allDependencies);
+    return allDependencies;
+  }
+
+  @override
+  String toString() => package.toString();
+
+  /**
+   * Append this node and its dependencies to [allDependencies] recursively.
+   */
+  void _appendDependencies(Set<_LinkedNode> allDependencies) {
+    if (allDependencies.add(this)) {
+      for (_LinkedNode dependency in dependencies) {
+        dependency._appendDependencies(allDependencies);
+      }
+    }
+  }
+}
+
+/**
+ * Specialization of [DependencyWalker] for linking packages.
+ */
+class _LinkedWalker extends DependencyWalker<_LinkedNode> {
+  final SummaryDataStore store;
+  final bool strong;
+
+  _LinkedWalker(this.store, this.strong);
+
+  @override
+  void evaluate(_LinkedNode node) {
+    evaluateScc([node]);
+  }
+
+  @override
+  void evaluateScc(List<_LinkedNode> scc) {
+    Map<String, _LinkedNode> uriToNode = <String, _LinkedNode>{};
+    for (_LinkedNode node in scc) {
+      for (String uri in node.unlinked.unlinkedUnitUris) {
+        uriToNode[uri] = node;
+      }
+    }
+    Set<String> libraryUris = uriToNode.keys.toSet();
+    // Perform linking.
+    Map<String, LinkedLibraryBuilder> linkedLibraries =
+        link(libraryUris, (String absoluteUri) {
+      return store.linkedMap[absoluteUri];
+    }, (String absoluteUri) {
+      return store.unlinkedMap[absoluteUri];
+    }, strong);
+    // Assemble linked bundles and put them into the store.
+    for (_LinkedNode node in scc) {
+      PackageBundleAssembler assembler = new PackageBundleAssembler();
+      linkedLibraries.forEach((uri, linkedLibrary) {
+        if (identical(uriToNode[uri], node)) {
+          assembler.addLinkedLibrary(uri, linkedLibrary);
+        }
+      });
+      List<int> bytes = assembler.assemble().toBuffer();
+      node.linkedNewBytes = bytes;
+      node.linked = new PackageBundle.fromBuffer(bytes);
+      store.addBundle(null, node.linked);
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index e929b67..2df51d4 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 
 /**
@@ -151,6 +152,7 @@
                 e is PropertyAccessorElementImpl ? e.identifier : e.name;
             elementsInUnit[id] = e;
           }
+
           unitElement.accessors.forEach(putElement);
           unitElement.enums.forEach(putElement);
           unitElement.functions.forEach(putElement);
@@ -204,15 +206,29 @@
       return parent.getLibraryElement(uri);
     }
     return _resynthesizedLibraries.putIfAbsent(uri, () {
-      LinkedLibrary serializedLibrary = _getLinkedSummaryOrThrow(uri);
-      List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[
-        _getUnlinkedSummaryOrThrow(uri)
-      ];
+      LinkedLibrary serializedLibrary = _getLinkedSummaryOrNull(uri);
       Source librarySource = _getSource(uri);
+      if (serializedLibrary == null) {
+        LibraryElementImpl libraryElement =
+            new LibraryElementImpl(context, '', -1, 0);
+        libraryElement.synthetic = true;
+        CompilationUnitElementImpl unitElement =
+            new CompilationUnitElementImpl(librarySource.shortName);
+        libraryElement.definingCompilationUnit = unitElement;
+        unitElement.source = librarySource;
+        unitElement.librarySource = librarySource;
+        return libraryElement..synthetic = true;
+      }
+      UnlinkedUnit unlinkedSummary = _getUnlinkedSummaryOrNull(uri);
+      if (unlinkedSummary == null) {
+        throw new StateError('Unable to find unlinked summary: $uri');
+      }
+      List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[unlinkedSummary];
       for (String part in serializedUnits[0].publicNamespace.parts) {
         Source partSource = sourceFactory.resolveUri(librarySource, part);
         String partAbsUri = partSource.uri.toString();
-        serializedUnits.add(_getUnlinkedSummaryOrThrow(partAbsUri));
+        serializedUnits.add(_getUnlinkedSummaryOrNull(partAbsUri) ??
+            new UnlinkedUnitBuilder(codeRange: new CodeRangeBuilder()));
       }
       _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
           this, serializedLibrary, serializedUnits, librarySource);
@@ -244,18 +260,14 @@
   bool hasLibrarySummary(String uri);
 
   /**
-   * Return the [LinkedLibrary] for the given [uri] or throw [StateError] if it
+   * Return the [LinkedLibrary] for the given [uri] or return `null` if it
    * could not be found.
    */
-  LinkedLibrary _getLinkedSummaryOrThrow(String uri) {
+  LinkedLibrary _getLinkedSummaryOrNull(String uri) {
     if (parent != null && parent._hasLibrarySummary(uri)) {
-      return parent._getLinkedSummaryOrThrow(uri);
+      return parent._getLinkedSummaryOrNull(uri);
     }
-    LinkedLibrary summary = getLinkedSummary(uri);
-    if (summary != null) {
-      return summary;
-    }
-    throw new StateError('Unable to find linked summary: $uri');
+    return getLinkedSummary(uri);
   }
 
   /**
@@ -266,18 +278,14 @@
   }
 
   /**
-   * Return the [UnlinkedUnit] for the given [uri] or throw [StateError] if it
+   * Return the [UnlinkedUnit] for the given [uri] or return `null` if it
    * could not be found.
    */
-  UnlinkedUnit _getUnlinkedSummaryOrThrow(String uri) {
+  UnlinkedUnit _getUnlinkedSummaryOrNull(String uri) {
     if (parent != null && parent._hasLibrarySummary(uri)) {
-      return parent._getUnlinkedSummaryOrThrow(uri);
+      return parent._getUnlinkedSummaryOrNull(uri);
     }
-    UnlinkedUnit summary = getUnlinkedSummary(uri);
-    if (summary != null) {
-      return summary;
-    }
-    throw new StateError('Unable to find unlinked summary: $uri');
+    return getUnlinkedSummary(uri);
   }
 
   /**
@@ -1277,12 +1285,23 @@
       InterfaceTypeImpl type =
           new InterfaceTypeImpl.elementWithNameAndArgs(element, name, () {
         if (typeArguments == null) {
-          typeArguments = element.typeParameters.map((typeParameter) {
-            DartType bound = typeParameter.bound;
-            return libraryResynthesizer.summaryResynthesizer.strongMode &&
-                instantiateToBoundsAllowed &&
-                bound != null ? bound : DynamicTypeImpl.instance;
-          }).toList();
+          typeArguments = element.typeParameters
+              .map/*<DartType>*/((_) => DynamicTypeImpl.instance)
+              .toList();
+          if (libraryResynthesizer.summaryResynthesizer.strongMode &&
+              instantiateToBoundsAllowed) {
+            List<DartType> typeParameterTypes;
+            for (int i = 0; i < typeArguments.length; i++) {
+              DartType bound = element.typeParameters[i].bound;
+              if (bound != null) {
+                typeParameterTypes ??= element.typeParameters
+                    .map/*<DartType>*/((TypeParameterElement e) => e.type)
+                    .toList();
+                typeArguments[i] =
+                    bound.substitute2(typeArguments, typeParameterTypes);
+              }
+            }
+          }
         }
         return typeArguments;
       });
@@ -1573,6 +1592,7 @@
           return DynamicTypeImpl.instance;
         }
       }
+
       _ReferenceInfo referenceInfo = getReferenceInfo(type.reference);
       return referenceInfo.buildType(
           instantiateToBoundsAllowed,
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index c2a625b..ec4f609 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -511,6 +511,7 @@
     }
     compilationUnit.declarations.accept(this);
     UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
+    b.lineStarts = compilationUnit.lineInfo?.lineStarts;
     b.libraryName = libraryName;
     b.libraryNameOffset = libraryNameOffset;
     b.libraryNameLength = libraryNameLength;
@@ -641,7 +642,7 @@
     bool isSemanticallyStatic = isTopLevel || isDeclaredStatic;
     if (formalParameters != null) {
       b.parameters = formalParameters.parameters
-          .map((FormalParameter p) => p.accept(this))
+          .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
           .toList();
       if (!isSemanticallyStatic) {
         for (int i = 0; i < formalParameters.parameters.length; i++) {
@@ -751,7 +752,7 @@
       b.type = serializedReturnType;
     }
     b.parameters = parameters.parameters
-        .map((FormalParameter p) => p.accept(this))
+        .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
         .toList();
   }
 
@@ -1042,7 +1043,7 @@
       b.nameOffset = node.returnType.offset;
     }
     b.parameters = node.parameters.parameters
-        .map((FormalParameter p) => p.accept(this))
+        .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
         .toList();
     b.kind = UnlinkedExecutableKind.constructor;
     if (node.factoryKeyword != null) {
@@ -1235,7 +1236,7 @@
       b.returnType = serializedReturnType;
     }
     b.parameters = node.parameters.parameters
-        .map((FormalParameter p) => p.accept(this))
+        .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
         .toList();
     b.documentationComment = serializeDocumentation(node.documentationComment);
     b.annotations = serializeAnnotations(node.metadata);
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 98e3de4..e62f408 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -15,9 +15,11 @@
 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/summary/api_signature.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/name_filter.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary/summarize_const_expr.dart';
 import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
@@ -137,7 +139,11 @@
   final List<LinkedLibraryBuilder> _linkedLibraries = <LinkedLibraryBuilder>[];
   final List<String> _unlinkedUnitUris = <String>[];
   final List<UnlinkedUnitBuilder> _unlinkedUnits = <UnlinkedUnitBuilder>[];
+  final Map<String, UnlinkedUnitBuilder> _unlinkedUnitMap =
+      <String, UnlinkedUnitBuilder>{};
   final List<String> _unlinkedUnitHashes;
+  final List<PackageDependencyInfoBuilder> _dependencies =
+      <PackageDependencyInfoBuilder>[];
   final bool _excludeHashes;
 
   /**
@@ -166,9 +172,11 @@
    */
   void addFallbackUnit(Source source) {
     String uri = source.uri.toString();
+    UnlinkedUnitBuilder unit = new UnlinkedUnitBuilder(
+        fallbackModePath: path.relative(source.fullName));
     _unlinkedUnitUris.add(uri);
-    _unlinkedUnits.add(new UnlinkedUnitBuilder(
-        fallbackModePath: path.relative(source.fullName)));
+    _unlinkedUnits.add(unit);
+    _unlinkedUnitMap[uri] = unit;
   }
 
   void addLinkedLibrary(String uri, LinkedLibraryBuilder library) {
@@ -185,6 +193,7 @@
       String uri, UnlinkedUnitBuilder unit, String hash) {
     _unlinkedUnitUris.add(uri);
     _unlinkedUnits.add(unit);
+    _unlinkedUnitMap[uri] = unit;
     _unlinkedUnitHashes?.add(hash);
   }
 
@@ -199,7 +208,17 @@
         unlinkedUnits: _unlinkedUnits,
         unlinkedUnitHashes: _unlinkedUnitHashes,
         majorVersion: currentMajorVersion,
-        minorVersion: currentMinorVersion);
+        minorVersion: currentMinorVersion,
+        dependencies: _dependencies,
+        apiSignature: _computeApiSignature());
+  }
+
+  /**
+   * Use the dependency information in [summaryDataStore] to populate the
+   * dependencies in the package bundle being assembled.
+   */
+  void recordDependencies(SummaryDataStore summaryDataStore) {
+    _dependencies.addAll(summaryDataStore.dependencies);
   }
 
   /**
@@ -215,12 +234,28 @@
     _linkedLibraries.add(libraryResult.linked);
     _unlinkedUnitUris.addAll(libraryResult.unitUris);
     _unlinkedUnits.addAll(libraryResult.unlinkedUnits);
+    for (int i = 0; i < libraryResult.unitUris.length; i++) {
+      _unlinkedUnitMap[libraryResult.unitUris[i]] =
+          libraryResult.unlinkedUnits[i];
+    }
     for (Source source in libraryResult.unitSources) {
       _unlinkedUnitHashes?.add(_hash(source.contents.data));
     }
   }
 
   /**
+   * Compute the API signature for this package bundle.
+   */
+  String _computeApiSignature() {
+    ApiSignature apiSignature = new ApiSignature();
+    for (String unitUri in _unlinkedUnitMap.keys.toList()..sort()) {
+      apiSignature.addString(unitUri);
+      _unlinkedUnitMap[unitUri].collectApiSignature(apiSignature);
+    }
+    return apiSignature.toHex();
+  }
+
+  /**
    * Compute a hash of the given file contents.
    */
   String _hash(String contents) {
@@ -445,6 +480,8 @@
     }
     unlinkedUnit.variables = variables;
     unlinkedUnit.references = unlinkedReferences;
+    unlinkedUnit.lineStarts =
+        compilationUnit.context?.computeLineInfo(unitSource)?.lineStarts;
     linkedUnit.references = linkedReferences;
     unitUri = compilationUnit.source.uri.toString();
   }
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 3cd21f1..c9c835e 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -5,14 +5,15 @@
 library analyzer.src.summary.summary_file_builder;
 
 import 'dart:collection';
-import 'dart:io';
+import 'dart:io' as io;
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.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/flat_buffers.dart' as fb;
 import 'package:analyzer/src/summary/index_unit.dart';
@@ -34,14 +35,14 @@
     // Write summary.
     {
       String outputPath = join(outputDirectoryPath, '$modeName.sum');
-      File file = new File(outputPath);
-      file.writeAsBytesSync(sum, mode: FileMode.WRITE_ONLY);
+      io.File file = new io.File(outputPath);
+      file.writeAsBytesSync(sum, mode: io.FileMode.WRITE_ONLY);
     }
     // Write index.
     {
       String outputPath = join(outputDirectoryPath, '$modeName.index');
-      File file = new File(outputPath);
-      file.writeAsBytesSync(index, mode: FileMode.WRITE_ONLY);
+      io.File file = new io.File(outputPath);
+      file.writeAsBytesSync(index, mode: io.FileMode.WRITE_ONLY);
     }
   }
 }
@@ -50,7 +51,6 @@
  * Summary build configuration.
  */
 class SummaryBuildConfig {
-
   /**
    * Whether to use exclude informative data from created summaries.
    */
@@ -115,8 +115,9 @@
     //
     // Prepare SDK.
     //
-    DirectoryBasedDartSdk sdk =
-        new DirectoryBasedDartSdk(new JavaFile(sdkPath), strongMode);
+    ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
+    FolderBasedDartSdk sdk = new FolderBasedDartSdk(
+        resourceProvider, resourceProvider.getFolder(sdkPath), strongMode);
     sdk.useSummary = false;
     sdk.analysisOptions = new AnalysisOptionsImpl()..strongMode = strongMode;
 
@@ -153,7 +154,7 @@
    * Write this summary output to the given [outputPath] and return the
    * created file.
    */
-  File write(String outputPath) {
+  io.File write(String outputPath) {
     fb.Builder builder = new fb.Builder();
     fb.Offset specSumOffset = builder.writeListUint8(spec.sum);
     fb.Offset specIndexOffset = builder.writeListUint8(spec.index);
@@ -165,8 +166,8 @@
     builder.addOffset(FIELD_STRONG_SUM, strongSumOffset);
     builder.addOffset(FIELD_STRONG_INDEX, strongIndexOffset);
     fb.Offset offset = builder.endTable();
-    return new File(outputPath)
-      ..writeAsBytesSync(builder.finish(offset), mode: FileMode.WRITE_ONLY);
+    return new io.File(outputPath)
+      ..writeAsBytesSync(builder.finish(offset), mode: io.FileMode.WRITE_ONLY);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 987a187..8d13a55 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
 import 'package:analyzer/src/context/cache.dart' show CacheEntry;
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -104,8 +105,9 @@
 class SummaryBasedDartSdk implements DartSdk {
   final bool strongMode;
   SummaryDataStore _dataStore;
-  InSummaryPackageUriResolver _uriResolver;
+  InSummaryUriResolver _uriResolver;
   PackageBundle _bundle;
+  ResourceProvider resourceProvider;
 
   /**
    * The [AnalysisContext] which is used for all of the sources in this sdk.
@@ -114,10 +116,18 @@
 
   SummaryBasedDartSdk(String summaryPath, this.strongMode) {
     _dataStore = new SummaryDataStore(<String>[summaryPath]);
-    _uriResolver = new InSummaryPackageUriResolver(_dataStore);
+    _uriResolver = new InSummaryUriResolver(resourceProvider, _dataStore);
     _bundle = _dataStore.bundles.single;
   }
 
+  SummaryBasedDartSdk.fromBundle(
+      this.strongMode, PackageBundle bundle, this.resourceProvider) {
+    _dataStore = new SummaryDataStore([]);
+    _dataStore.addBundle('dart_sdk.sum', bundle);
+    _uriResolver = new InSummaryUriResolver(resourceProvider, _dataStore);
+    _bundle = bundle;
+  }
+
   /**
    * Return the [PackageBundle] for this SDK, not `null`.
    */
@@ -129,7 +139,8 @@
       AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl()
         ..strongMode = strongMode;
       _analysisContext = new SdkAnalysisContext(analysisOptions);
-      SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
+      SourceFactory factory = new SourceFactory(
+          [new DartUriResolver(this)], null, resourceProvider);
       _analysisContext.sourceFactory = factory;
       _analysisContext.resultProvider =
           new SdkSummaryResultProvider(_analysisContext, _bundle, strongMode);
@@ -158,6 +169,9 @@
   }
 
   @override
+  PackageBundle getLinkedBundle() => _bundle;
+
+  @override
   SdkLibrary getSdkLibrary(String uri) {
     // This is not quite correct, but currently it's used only in
     // to report errors on importing or exporting of internal libraries.
@@ -175,7 +189,7 @@
  * Implementation of [TypeProvider] which can be initialized separately with
  * `dart:core` and `dart:async` libraries.
  */
-class SummaryTypeProvider implements TypeProvider {
+class SummaryTypeProvider extends TypeProviderBase {
   LibraryElement _coreLibrary;
   LibraryElement _asyncLibrary;
 
@@ -293,16 +307,6 @@
   }
 
   @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);
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 25e74ec..da8fcec 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -327,6 +327,33 @@
     new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT9', false);
 
 /**
+ * All [AnalysisError]s results for [Source]s.
+ */
+final List<ListResultDescriptor<AnalysisError>> ERROR_SOURCE_RESULTS =
+    <ListResultDescriptor<AnalysisError>>[
+  BUILD_DIRECTIVES_ERRORS,
+  BUILD_LIBRARY_ERRORS,
+  PARSE_ERRORS,
+  SCAN_ERRORS,
+];
+
+/**
+ * All [AnalysisError]s results in for [LibrarySpecificUnit]s.
+ */
+final List<ListResultDescriptor<AnalysisError>> ERROR_UNIT_RESULTS =
+    <ListResultDescriptor<AnalysisError>>[
+  HINTS,
+  LIBRARY_UNIT_ERRORS,
+  LINTS,
+  RESOLVE_TYPE_BOUNDS_ERRORS,
+  RESOLVE_TYPE_NAMES_ERRORS,
+  RESOLVE_UNIT_ERRORS,
+  STRONG_MODE_ERRORS,
+  VARIABLE_REFERENCE_ERRORS,
+  VERIFY_ERRORS
+];
+
+/**
  * The sources representing the export closure of a library.
  * The [Source]s include only library sources, not their units.
  *
@@ -929,6 +956,28 @@
         'SCAN_ERRORS', AnalysisError.NO_ERRORS);
 
 /**
+ * The errors produced while resolving a static [VariableElement] initializer.
+ *
+ * The result is only available for [VariableElement]s, and only when strong
+ * mode is enabled.
+ */
+final ListResultDescriptor<AnalysisError> STATIC_VARIABLE_RESOLUTION_ERRORS =
+    new ListResultDescriptor<AnalysisError>(
+        'STATIC_VARIABLE_RESOLUTION_ERRORS', AnalysisError.NO_ERRORS);
+
+/**
+ * A list of the [AnalysisError]s reported while resolving static
+ * [INFERABLE_STATIC_VARIABLES_IN_UNIT] defined in a unit.
+ *
+ * The result is only available for [LibrarySpecificUnit]s, and only when strong
+ * mode is enabled.
+ */
+final ListResultDescriptor<AnalysisError>
+    STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT =
+    new ListResultDescriptor<AnalysisError>(
+        'STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT', null);
+
+/**
  * The additional strong mode errors produced while verifying a
  * compilation unit.
  *
@@ -1075,12 +1124,10 @@
     //
     // Prepare constants.
     //
-    ConstantFinder constantFinder =
-        new ConstantFinder(context, source, librarySpecificUnit.library);
+    ConstantFinder constantFinder = new ConstantFinder();
     unit.accept(constantFinder);
     List<ConstantEvaluationTarget> constants =
-        new List<ConstantEvaluationTarget>.from(
-            constantFinder.constantsToCompute);
+        constantFinder.constantsToCompute.toList();
     //
     // Record outputs.
     //
@@ -1319,6 +1366,7 @@
       }
       return null;
     }
+
     EnumDeclaration firstEnum = findFirstEnum();
     if (firstEnum != null && firstEnum.element.accessors.isEmpty) {
       EnumMemberBuilder builder = new EnumMemberBuilder(typeProvider);
@@ -1444,14 +1492,18 @@
   static const String PARTS_UNIT_INPUT = 'PARTS_UNIT_INPUT';
 
   /**
+   * The name of the input whose value is the modification time of the source.
+   */
+  static const String MODIFICATION_TIME_INPUT = 'MODIFICATION_TIME_INPUT';
+
+  /**
    * The task descriptor describing this kind of task.
    */
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
       'BuildLibraryElementTask', createTask, buildInputs, <ResultDescriptor>[
     BUILD_LIBRARY_ERRORS,
     LIBRARY_ELEMENT1,
-    IS_LAUNCHABLE,
-    REFERENCED_NAMES
+    IS_LAUNCHABLE
   ]);
 
   /**
@@ -1480,6 +1532,7 @@
     CompilationUnit definingCompilationUnit =
         getRequiredInput(DEFINING_UNIT_INPUT);
     List<CompilationUnit> partUnits = getRequiredInput(PARTS_UNIT_INPUT);
+    int modificationTime = getRequiredInput(MODIFICATION_TIME_INPUT);
     //
     // Process inputs.
     //
@@ -1600,6 +1653,7 @@
     if (libraryElement == null) {
       libraryElement =
           new LibraryElementImpl.forNode(owningContext, libraryNameNode);
+      libraryElement.synthetic = modificationTime < 0;
       libraryElement.definingCompilationUnit = definingCompilationUnitElement;
       libraryElement.entryPoint = entryPoint;
       libraryElement.parts = sourcedCompilationUnits;
@@ -1623,19 +1677,12 @@
       Directive directive = directivesToResolve[i];
       directive.element = libraryElement;
     }
-    // Compute referenced names.
-    ReferencedNames referencedNames = new ReferencedNames(librarySource);
-    new ReferencedNamesBuilder(referencedNames).build(definingCompilationUnit);
-    for (CompilationUnit partUnit in partUnits) {
-      new ReferencedNamesBuilder(referencedNames).build(partUnit);
-    }
     //
     // Record outputs.
     //
     outputs[BUILD_LIBRARY_ERRORS] = errors;
     outputs[LIBRARY_ELEMENT1] = libraryElement;
     outputs[IS_LAUNCHABLE] = entryPoint != null;
-    outputs[REFERENCED_NAMES] = referencedNames;
   }
 
   /**
@@ -1705,7 +1752,8 @@
           RESOLVED_UNIT1.of(new LibrarySpecificUnit(source, source)),
       PARTS_UNIT_INPUT: INCLUDED_PARTS.of(source).toList((Source unit) {
         return RESOLVED_UNIT1.of(new LibrarySpecificUnit(source, unit));
-      })
+      }),
+      MODIFICATION_TIME_INPUT: MODIFICATION_TIME.of(source)
     };
   }
 
@@ -2211,6 +2259,7 @@
           deps.addAll(l.units);
         }
       }
+
       int length = component.length;
       for (int i = 0; i < length; i++) {
         LibraryElement library = component[i];
@@ -2484,8 +2533,6 @@
  * The description for a change in a Dart source.
  */
 class DartDelta extends Delta {
-  bool hasDirectiveChange = false;
-
   final Set<String> changedNames = new Set<String>();
   final Map<Source, Set<String>> changedPrivateNames = <Source, Set<String>>{};
 
@@ -2495,23 +2542,36 @@
   /**
    * The cache of libraries in which all results are invalid.
    */
-  final Set<Source> librariesWithInvalidResults = new Set<Source>();
+  final Set<Source> librariesWithAllInvalidResults = new Set<Source>();
 
   /**
    * The cache of libraries in which all results are valid.
    */
-  final Set<Source> librariesWithValidResults = new Set<Source>();
+  final Set<Source> librariesWithAllValidResults = new Set<Source>();
+
+  /**
+   * The cache of libraries with all, but [HINTS] and [VERIFY_ERRORS] results
+   * are valid.
+   */
+  final Set<Source> libraryWithInvalidErrors = new Set<Source>();
+
+  /**
+   * This set is cleared in every [gatherEnd], and [gatherChanges] uses it
+   * to find changes in every source only once per visit process.
+   */
+  final Set<Source> currentVisitUnits = new Set<Source>();
 
   DartDelta(Source source) : super(source);
 
   /**
    * Add names that are changed in the given [references].
+   * Return `true` if any change was added.
    */
-  void addChangedElements(ReferencedNames references) {
-    Source refLibrary = references.librarySource;
-    bool hasProgress = true;
-    while (hasProgress) {
-      hasProgress = false;
+  bool addChangedElements(ReferencedNames references, Source refLibrary) {
+    int numberOfChanges = 0;
+    int lastNumberOfChange = -1;
+    while (numberOfChanges != lastNumberOfChange) {
+      lastNumberOfChange = numberOfChanges;
       // Classes that extend changed classes are also changed.
       // If there is a delta for a superclass, use it for the subclass.
       // Otherwise mark the subclass as "general name change".
@@ -2524,13 +2584,13 @@
             _log(() => '$subName in $refLibrary has delta because of its '
                 'superclass $superName has delta');
             if (subDelta.superDeltas.add(superDelta)) {
-              hasProgress = true;
+              numberOfChanges++;
             }
           } else if (isChanged(refLibrary, superName)) {
             if (nameChanged(refLibrary, subName)) {
               _log(() => '$subName in $refLibrary is changed because its '
                   'superclass $superName is changed');
-              hasProgress = true;
+              numberOfChanges++;
             }
           }
         }
@@ -2545,12 +2605,13 @@
             if (nameChanged(refLibrary, user)) {
               _log(() => '$user in $refLibrary is changed because '
                   'of $dependency in $dependencies');
-              hasProgress = true;
+              numberOfChanges++;
             }
           }
         }
       });
     }
+    return numberOfChanges != 0;
   }
 
   void classChanged(ClassElementDelta classDelta) {
@@ -2562,23 +2623,60 @@
     nameChanged(librarySource, element.name);
   }
 
-  bool hasAffectedReferences(ReferencedNames references) {
-    Source refLibrary = references.librarySource;
-    // Verify errors must be recomputed when a superclass changes.
+  @override
+  bool gatherChanges(InternalAnalysisContext context, AnalysisTarget target,
+      ResultDescriptor descriptor, Object value) {
+    // Prepare target source.
+    Source targetUnit = target.source;
+    Source targetLibrary = target.librarySource;
+    if (target is Source) {
+      if (context.getKindOf(target) == SourceKind.LIBRARY) {
+        targetLibrary = target;
+      }
+    }
+    // We don't know what to do with the given target.
+    if (targetUnit == null || targetUnit != targetLibrary) {
+      return false;
+    }
+    // Attempt to find new changed names for the unit only once.
+    if (!currentVisitUnits.add(targetUnit)) {
+      return false;
+    }
+    // Add changes.
+    ReferencedNames referencedNames =
+        context.getResult(targetUnit, REFERENCED_NAMES);
+    if (referencedNames == null) {
+      return false;
+    }
+    return addChangedElements(referencedNames, targetLibrary);
+  }
+
+  @override
+  void gatherEnd() {
+    currentVisitUnits.clear();
+  }
+
+  bool hasAffectedHintsVerifyErrors(
+      ReferencedNames references, Source refLibrary) {
     for (String superName in references.superToSubs.keys) {
       if (isChangedOrClass(refLibrary, superName)) {
-        _log(() => '$refLibrary is affected because '
+        _log(() => '$refLibrary hints/verify errors are affected because '
             '${references.superToSubs[superName]} subclasses $superName');
         return true;
       }
     }
-    // Verify errors must be recomputed when an instantiated class changes.
-    for (String name in references.instantiatedNames) {
-      if (isChangedOrClass(refLibrary, name)) {
-        _log(() => '$refLibrary is affected because $name is instantiated');
+    for (String name in references.names) {
+      ClassElementDelta classDelta = changedClasses[name];
+      if (classDelta != null && classDelta.hasAnnotationChanges) {
+        _log(() => '$refLibrary hints/verify errors are  affected because '
+            '$name has a class delta with annotation changes');
         return true;
       }
     }
+    return false;
+  }
+
+  bool hasAffectedReferences(ReferencedNames references, Source refLibrary) {
     // Resolution must be performed when a referenced element changes.
     for (String name in references.names) {
       if (isChangedOrClassMember(refLibrary, name)) {
@@ -2586,6 +2684,27 @@
         return true;
       }
     }
+    // Resolution must be performed when the unnamed constructor of
+    // an instantiated class is added/changed/removed.
+    // TODO(scheglov) Use only instantiations with default constructor.
+    for (String name in references.instantiatedNames) {
+      for (ClassElementDelta classDelta in changedClasses.values) {
+        if (classDelta.name == name && classDelta.hasUnnamedConstructorChange) {
+          _log(() =>
+              '$refLibrary is affected by the default constructor of $name');
+          return true;
+        }
+      }
+    }
+    for (String name in references.extendedUsedUnnamedConstructorNames) {
+      for (ClassElementDelta classDelta in changedClasses.values) {
+        if (classDelta.name == name && classDelta.hasUnnamedConstructorChange) {
+          _log(() =>
+              '$refLibrary is affected by the default constructor of $name');
+          return true;
+        }
+      }
+    }
     return false;
   }
 
@@ -2647,23 +2766,29 @@
   @override
   DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target,
       ResultDescriptor descriptor, Object value) {
-    if (hasDirectiveChange) {
-      return DeltaResult.INVALIDATE;
+    // Always invalidate compounding results.
+    if (descriptor == LIBRARY_ELEMENT4 ||
+        descriptor == READY_LIBRARY_ELEMENT6 ||
+        descriptor == READY_LIBRARY_ELEMENT7) {
+      return DeltaResult.INVALIDATE_KEEP_DEPENDENCIES;
     }
     // Prepare target source.
-    Source targetSource = target.source;
-    Source librarySource = target.librarySource;
+    Source targetUnit = target.source;
+    Source targetLibrary = target.librarySource;
     if (target is Source) {
       if (context.getKindOf(target) == SourceKind.LIBRARY) {
-        librarySource = target;
+        targetLibrary = target;
       }
     }
     // We don't know what to do with the given target, invalidate it.
-    if (targetSource == null) {
+    if (targetUnit == null || targetUnit != targetLibrary) {
       return DeltaResult.INVALIDATE;
     }
     // Keep results that don't change: any library.
-    if (_isTaskResult(BuildLibraryElementTask.DESCRIPTOR, descriptor) ||
+    if (_isTaskResult(ScanDartTask.DESCRIPTOR, descriptor) ||
+        _isTaskResult(ParseDartTask.DESCRIPTOR, descriptor) ||
+        _isTaskResult(BuildCompilationUnitElementTask.DESCRIPTOR, descriptor) ||
+        _isTaskResult(BuildLibraryElementTask.DESCRIPTOR, descriptor) ||
         _isTaskResult(BuildDirectiveElementsTask.DESCRIPTOR, descriptor) ||
         _isTaskResult(ResolveDirectiveElementsTask.DESCRIPTOR, descriptor) ||
         _isTaskResult(BuildEnumMemberElementsTask.DESCRIPTOR, descriptor) ||
@@ -2673,44 +2798,48 @@
       return DeltaResult.KEEP_CONTINUE;
     }
     // Keep results that don't change: changed library.
-    if (targetSource == source) {
-      if (_isTaskResult(ScanDartTask.DESCRIPTOR, descriptor) ||
-          _isTaskResult(ParseDartTask.DESCRIPTOR, descriptor) ||
-          _isTaskResult(
-              BuildCompilationUnitElementTask.DESCRIPTOR, descriptor) ||
-          _isTaskResult(BuildLibraryElementTask.DESCRIPTOR, descriptor)) {
-        return DeltaResult.KEEP_CONTINUE;
-      }
+    if (targetUnit == source) {
       return DeltaResult.INVALIDATE;
     }
     // Keep results that don't change: dependent library.
-    if (targetSource != source) {
+    if (targetUnit != source) {
       if (_isTaskResult(BuildPublicNamespaceTask.DESCRIPTOR, descriptor)) {
         return DeltaResult.KEEP_CONTINUE;
       }
     }
     // Handle in-library results only for now.
-    if (librarySource != null) {
+    if (targetLibrary != null) {
       // Use cached library results.
-      if (librariesWithInvalidResults.contains(librarySource)) {
+      if (librariesWithAllInvalidResults.contains(targetLibrary)) {
         return DeltaResult.INVALIDATE;
       }
-      if (librariesWithValidResults.contains(librarySource)) {
-        return DeltaResult.STOP;
+      if (librariesWithAllValidResults.contains(targetLibrary)) {
+        return DeltaResult.KEEP_CONTINUE;
+      }
+      // The library is almost, but not completely valid.
+      // Some error results are invalid.
+      if (libraryWithInvalidErrors.contains(targetLibrary)) {
+        if (descriptor == HINTS || descriptor == VERIFY_ERRORS) {
+          return DeltaResult.INVALIDATE_NO_DELTA;
+        }
+        return DeltaResult.KEEP_CONTINUE;
       }
       // Compute the library result.
       ReferencedNames referencedNames =
-          context.getResult(librarySource, REFERENCED_NAMES);
+          context.getResult(targetUnit, REFERENCED_NAMES);
       if (referencedNames == null) {
         return DeltaResult.INVALIDATE_NO_DELTA;
       }
-      addChangedElements(referencedNames);
-      if (hasAffectedReferences(referencedNames)) {
-        librariesWithInvalidResults.add(librarySource);
+      if (hasAffectedReferences(referencedNames, targetLibrary)) {
+        librariesWithAllInvalidResults.add(targetLibrary);
         return DeltaResult.INVALIDATE;
       }
-      librariesWithValidResults.add(librarySource);
-      return DeltaResult.STOP;
+      if (hasAffectedHintsVerifyErrors(referencedNames, targetLibrary)) {
+        libraryWithInvalidErrors.add(targetLibrary);
+        return DeltaResult.KEEP_CONTINUE;
+      }
+      librariesWithAllValidResults.add(targetLibrary);
+      return DeltaResult.KEEP_CONTINUE;
     }
     // We don't know what to do with the given target, invalidate it.
     return DeltaResult.INVALIDATE;
@@ -3149,8 +3278,9 @@
       unit.accept(new Dart2JSVerifier(errorReporter));
     }
     // Dart best practices.
-    InheritanceManager inheritanceManager =
-        new InheritanceManager(libraryElement);
+    InheritanceManager inheritanceManager = new InheritanceManager(
+        libraryElement,
+        includeAbstractFromSuperclasses: true);
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
 
     unit.accept(new BestPracticesVerifier(
@@ -3527,10 +3657,10 @@
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
   /**
-   * The name of the input whose value is a list of the inferable static
-   * variables whose types have been computed.
+   * The name of the [STATIC_VARIABLE_RESOLUTION_ERRORS] for all static
+   * variables in the compilation unit.
    */
-  static const String INFERRED_VARIABLES_INPUT = 'INFERRED_VARIABLES_INPUT';
+  static const String ERRORS_LIST_INPUT = 'INFERRED_VARIABLES_INPUT';
 
   /**
    * The task descriptor describing this kind of task.
@@ -3538,8 +3668,11 @@
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
       'InferStaticVariableTypesInUnitTask',
       createTask,
-      buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
+      buildInputs, <ResultDescriptor>[
+    CREATED_RESOLVED_UNIT9,
+    RESOLVED_UNIT9,
+    STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
+  ]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -3558,6 +3691,7 @@
     // Prepare inputs.
     //
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+    List<List<AnalysisError>> errorLists = getRequiredInput(ERRORS_LIST_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
@@ -3565,6 +3699,8 @@
     //
     outputs[RESOLVED_UNIT9] = unit;
     outputs[CREATED_RESOLVED_UNIT9] = true;
+    outputs[STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT] =
+        AnalysisError.mergeLists(errorLists);
   }
 
   /**
@@ -3575,9 +3711,12 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      INFERRED_VARIABLES_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
+      'inferredTypes': INFERABLE_STATIC_VARIABLES_IN_UNIT
           .of(unit)
           .toListOf(INFERRED_STATIC_VARIABLE),
+      ERRORS_LIST_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
+          .of(unit)
+          .toListOf(STATIC_VARIABLE_RESOLUTION_ERRORS),
       UNIT_INPUT: RESOLVED_UNIT8.of(unit)
     };
   }
@@ -3616,8 +3755,10 @@
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
       'InferStaticVariableTypeTask',
       createTask,
-      buildInputs,
-      <ResultDescriptor>[INFERRED_STATIC_VARIABLE]);
+      buildInputs, <ResultDescriptor>[
+    INFERRED_STATIC_VARIABLE,
+    STATIC_VARIABLE_RESOLUTION_ERRORS
+  ]);
 
   InferStaticVariableTypeTask(
       InternalAnalysisContext context, VariableElement variable)
@@ -3645,17 +3786,19 @@
 
     // If we're not in a dependency cycle, and we have no type annotation,
     // re-resolve the right hand side and do inference.
+    List<AnalysisError> errors = AnalysisError.NO_ERRORS;
     if (dependencyCycle == null && variable.hasImplicitType) {
       VariableDeclaration declaration = getDeclaration(unit);
       //
       // Re-resolve the variable's initializer so that the inferred types
       // of other variables will be propagated.
       //
+      RecordingErrorListener errorListener = new RecordingErrorListener();
       Expression initializer = declaration.initializer;
       ResolutionContext resolutionContext = ResolutionContextBuilder.contextFor(
           initializer, AnalysisErrorListener.NULL_LISTENER);
-      ResolverVisitor visitor = new ResolverVisitor(variable.library,
-          variable.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
+      ResolverVisitor visitor = new ResolverVisitor(
+          variable.library, variable.source, typeProvider, errorListener,
           nameScope: resolutionContext.scope);
       if (resolutionContext.enclosingClassDeclaration != null) {
         visitor.prepareToResolveMembersInClass(
@@ -3672,6 +3815,7 @@
         newType = typeProvider.dynamicType;
       }
       setFieldType(variable, newType);
+      errors = getUniqueErrors(errorListener.errors);
     } else {
       // TODO(brianwilkerson) For now we simply don't infer any type for
       // variables or fields involved in a cycle. We could try to be smarter
@@ -3684,6 +3828,7 @@
     // Record outputs.
     //
     outputs[INFERRED_STATIC_VARIABLE] = variable;
+    outputs[STATIC_VARIABLE_RESOLUTION_ERRORS] = errors;
   }
 
   /**
@@ -3798,6 +3943,12 @@
   static const String LINTS_INPUT = 'LINTS';
 
   /**
+   * The name of the [STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT] input.
+   */
+  static const String STATIC_VARIABLE_RESOLUTION_ERRORS_INPUT =
+      'STATIC_VARIABLE_RESOLUTION_ERRORS_INPUT';
+
+  /**
    * The name of the [STRONG_MODE_ERRORS] input.
    */
   static const String STRONG_MODE_ERRORS_INPUT = 'STRONG_MODE_ERRORS';
@@ -3858,6 +4009,7 @@
     errorLists.add(getRequiredInput(RESOLVE_TYPE_NAMES_ERRORS_INPUT));
     errorLists.add(getRequiredInput(RESOLVE_TYPE_NAMES_ERRORS2_INPUT));
     errorLists.add(getRequiredInput(RESOLVE_UNIT_ERRORS_INPUT));
+    errorLists.add(getRequiredInput(STATIC_VARIABLE_RESOLUTION_ERRORS_INPUT));
     errorLists.add(getRequiredInput(STRONG_MODE_ERRORS_INPUT));
     errorLists.add(getRequiredInput(VARIABLE_REFERENCE_ERRORS_INPUT));
     errorLists.add(getRequiredInput(VERIFY_ERRORS_INPUT));
@@ -3880,6 +4032,8 @@
       RESOLVE_TYPE_NAMES_ERRORS_INPUT: RESOLVE_TYPE_NAMES_ERRORS.of(unit),
       RESOLVE_TYPE_NAMES_ERRORS2_INPUT: RESOLVE_TYPE_BOUNDS_ERRORS.of(unit),
       RESOLVE_UNIT_ERRORS_INPUT: RESOLVE_UNIT_ERRORS.of(unit),
+      STATIC_VARIABLE_RESOLUTION_ERRORS_INPUT:
+          STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT.of(unit),
       STRONG_MODE_ERRORS_INPUT: STRONG_MODE_ERRORS.of(unit),
       VARIABLE_REFERENCE_ERRORS_INPUT: VARIABLE_REFERENCE_ERRORS.of(unit),
       VERIFY_ERRORS_INPUT: VERIFY_ERRORS.of(unit)
@@ -3943,9 +4097,10 @@
     LIBRARY_SPECIFIC_UNITS,
     PARSE_ERRORS,
     PARSED_UNIT,
+    REFERENCED_NAMES,
+    REFERENCED_SOURCES,
     SOURCE_KIND,
     UNITS,
-    REFERENCED_SOURCES
   ]);
 
   /**
@@ -3972,7 +4127,6 @@
     parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
     parser.parseGenericMethods = options.enableGenericMethods;
     parser.parseGenericMethodComments = options.strongMode;
-    parser.parseTrailingCommas = options.enableTrailingCommas;
     CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
     unit.lineInfo = lineInfo;
 
@@ -4034,6 +4188,11 @@
       sourceKind = SourceKind.PART;
     }
     //
+    // Compute referenced names.
+    //
+    ReferencedNames referencedNames = new ReferencedNames(source);
+    new ReferencedNamesBuilder(referencedNames).build(unit);
+    //
     // Record outputs.
     //
     List<Source> explicitlyImportedSources =
@@ -4057,9 +4216,10 @@
     outputs[LIBRARY_SPECIFIC_UNITS] = librarySpecificUnits;
     outputs[PARSE_ERRORS] = parseErrors;
     outputs[PARSED_UNIT] = unit;
+    outputs[REFERENCED_NAMES] = referencedNames;
+    outputs[REFERENCED_SOURCES] = referencedSources;
     outputs[SOURCE_KIND] = sourceKind;
     outputs[UNITS] = unitSources;
-    outputs[REFERENCED_SOURCES] = referencedSources;
   }
 
   /**
@@ -4684,11 +4844,11 @@
 }
 
 /**
- * Information about a library - which names it uses, which names it defines
- * with their externally visible dependencies.
+ * Information about a Dart [source] - which names it uses, which names it
+ * defines with their externally visible dependencies.
  */
 class ReferencedNames {
-  final Source librarySource;
+  final Source source;
 
   /**
    * The mapping from the name of a class to the set of names of other classes
@@ -4702,6 +4862,13 @@
   final Map<String, Set<String>> superToSubs = <String, Set<String>>{};
 
   /**
+   * The names of extended classes for which the unnamed constructor is
+   * invoked. Because we cannot use the name of the constructor to identify
+   * whether the unit is affected, we need to use the class name.
+   */
+  final Set<String> extendedUsedUnnamedConstructorNames = new Set<String>();
+
+  /**
    * The names of instantiated classes.
    *
    * If one of these classes changes its set of members, it might change
@@ -4723,7 +4890,7 @@
    */
   final Map<String, Set<String>> userToDependsOn = <String, Set<String>>{};
 
-  ReferencedNames(this.librarySource);
+  ReferencedNames(this.source);
 
   void addSubclass(String subName, String superName) {
     superToSubs.putIfAbsent(superName, () => new Set<String>()).add(subName);
@@ -4737,6 +4904,7 @@
   final Set<String> importPrefixNames = new Set<String>();
   final ReferencedNames names;
 
+  String enclosingSuperClassName;
   ReferencedNamesScope scope = new ReferencedNamesScope(null);
 
   int localLevel = 0;
@@ -4766,6 +4934,8 @@
     try {
       scope = new ReferencedNamesScope.forClass(scope, node);
       dependsOn = new Set<String>();
+      enclosingSuperClassName =
+          _getSimpleName(node.extendsClause?.superclass?.name);
       super.visitClassDeclaration(node);
       String className = node.name.name;
       names.userToDependsOn[className] = dependsOn;
@@ -4773,6 +4943,7 @@
       _addSuperNames(className, node.withClause?.mixinTypes);
       _addSuperNames(className, node.implementsClause?.interfaces);
     } finally {
+      enclosingSuperClassName = null;
       dependsOn = null;
       scope = outerScope;
     }
@@ -4926,6 +5097,14 @@
   }
 
   @override
+  visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    if (node.constructorName == null && enclosingSuperClassName != null) {
+      names.extendedUsedUnnamedConstructorNames.add(enclosingSuperClassName);
+    }
+    super.visitSuperConstructorInvocation(node);
+  }
+
+  @override
   visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     VariableDeclarationList variableList = node.variables;
     // Prepare type dependencies.
@@ -4957,6 +5136,16 @@
   void _addSuperNames(String className, List<TypeName> types) {
     types?.forEach((type) => _addSuperName(className, type));
   }
+
+  static String _getSimpleName(Identifier identifier) {
+    if (identifier is SimpleIdentifier) {
+      return identifier.name;
+    }
+    if (identifier is PrefixedIdentifier) {
+      return identifier.identifier.name;
+    }
+    return null;
+  }
 }
 
 class ReferencedNamesScope {
@@ -5632,6 +5821,8 @@
     return <String, TaskInput>{
       'importsExportNamespace':
           IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
+      'dependOnAllExportedSources':
+          IMPORTED_LIBRARIES.of(unit.library).toMapOf(EXPORT_SOURCE_CLOSURE),
       LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library),
       UNIT_INPUT: RESOLVED_UNIT3.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
@@ -6008,6 +6199,8 @@
       scanner.setSourceStart(fragment.line, fragment.column);
       scanner.preserveComments = context.analysisOptions.preserveComments;
       scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
+      scanner.scanLazyAssignmentOperators =
+          context.analysisOptions.enableLazyAssignmentOperators;
 
       LineInfo lineInfo = new LineInfo(scanner.lineStarts);
 
@@ -6023,6 +6216,8 @@
           new Scanner(source, new CharSequenceReader(content), errorListener);
       scanner.preserveComments = context.analysisOptions.preserveComments;
       scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
+      scanner.scanLazyAssignmentOperators =
+          context.analysisOptions.enableLazyAssignmentOperators;
 
       LineInfo lineInfo = new LineInfo(scanner.lineStarts);
 
@@ -6129,7 +6324,9 @@
     if (options.strongMode) {
       CodeChecker checker = new CodeChecker(
           typeProvider,
-          new StrongTypeSystemImpl(implicitCasts: options.implicitCasts),
+          new StrongTypeSystemImpl(
+              implicitCasts: options.implicitCasts,
+              nonnullableTypes: options.nonnullableTypes),
           errorListener,
           options);
       checker.visitCompilationUnit(unit);
@@ -6300,8 +6497,38 @@
       }
     }
     StringLiteral uriLiteral = directive.uri;
-    errorReporter.reportErrorForNode(CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-        uriLiteral, [directive.uriContent]);
+    CompileTimeErrorCode errorCode = CompileTimeErrorCode.URI_DOES_NOT_EXIST;
+    if (_isGenerated(source)) {
+      errorCode = CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED;
+    }
+    errorReporter
+        .reportErrorForNode(errorCode, uriLiteral, [directive.uriContent]);
+  }
+
+  /**
+   * Return `true` if the given [source] refers to a file that is assumed to be
+   * generated.
+   */
+  bool _isGenerated(Source source) {
+    if (source == null) {
+      return false;
+    }
+    // TODO(brianwilkerson) Generalize this mechanism.
+    const List<String> suffixes = const <String>[
+      '.g.dart',
+      '.pb.dart',
+      '.pbenum.dart',
+      '.pbserver.dart',
+      '.pbjson.dart',
+      '.template.dart'
+    ];
+    String fullName = source.fullName;
+    for (String suffix in suffixes) {
+      if (fullName.endsWith(suffix)) {
+        return true;
+      }
+    }
+    return false;
   }
 
   /**
@@ -6403,8 +6630,10 @@
         int length = imports.length;
         for (int i = 0; i < length; i++) {
           ImportElement importElement = imports[i];
-          Source importedSource = importElement.importedLibrary.source;
-          _newSources.add(importedSource);
+          Source importedSource = importElement.importedLibrary?.source;
+          if (importedSource != null) {
+            _newSources.add(importedSource);
+          }
         }
       }
       if (kind == _SourceClosureKind.EXPORT ||
@@ -6413,8 +6642,10 @@
         int length = exports.length;
         for (int i = 0; i < length; i++) {
           ExportElement exportElement = exports[i];
-          Source exportedSource = exportElement.exportedLibrary.source;
-          _newSources.add(exportedSource);
+          Source exportedSource = exportElement.exportedLibrary?.source;
+          if (exportedSource != null) {
+            _newSources.add(exportedSource);
+          }
         }
       }
     }
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 3d6dc33..f3dd0b6 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -117,7 +117,10 @@
   void applyChange(List<Source> addedSources, List<Source> changedSources,
       List<Source> removedSources) {
     addedSources = addedSources.where(_isDartSource).toList();
-    changedSources = changedSources.where(_isDartSource).toList();
+    changedSources = changedSources
+        .where(_isDartSource)
+        .where((source) => _needsComputing(source, SOURCE_KIND))
+        .toList();
     removedSources = removedSources.where(_isDartSource).toList();
     // unknown queue
     unknownSourceQueue.addAll(addedSources);
@@ -199,6 +202,7 @@
       }
     }
     List<Source> libraries = partLibrariesMap[part];
+    libraries ??= _getLibrariesContainingPartFromResultProvider(part);
     return libraries?.toList() ?? Source.EMPTY_LIST;
   }
 
@@ -347,11 +351,28 @@
     }
   }
 
+  /**
+   * The given unit was incrementally resolved. Some of its error results might
+   * have been invalidated, so we schedule it for computing errors.
+   */
   void unitIncrementallyResolved(Source librarySource, Source unitSource) {
     librarySourceQueue.add(librarySource);
   }
 
   /**
+   * Ask the [context]'s result provider for [CONTAINING_LIBRARIES].
+   * Return the list of containing libraries, or `null` if unknown.
+   */
+  List<Source> _getLibrariesContainingPartFromResultProvider(Source part) {
+    CacheEntry cacheEntry = context.getCacheEntry(part);
+    bool knows = context.aboutToComputeResult(cacheEntry, CONTAINING_LIBRARIES);
+    if (knows) {
+      return cacheEntry.getValue(CONTAINING_LIBRARIES);
+    }
+    return null;
+  }
+
+  /**
    * Return the SDK [DartWorkManager] or this one.
    */
   DartWorkManager _getSdkDartWorkManager() {
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index 9bc30f8..bd317cf 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -12,10 +12,12 @@
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/constant/utilities.dart';
 import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/dart.dart';
 
 /**
  * The change of a single [ClassElement].
@@ -27,6 +29,8 @@
 
   final Set<ClassElementDelta> superDeltas = new Set<ClassElementDelta>();
 
+  bool hasAnnotationChanges = false;
+
   final List<PropertyAccessorElement> addedAccessors =
       <PropertyAccessorElement>[];
   final List<PropertyAccessorElement> removedAccessors =
@@ -34,6 +38,7 @@
 
   final List<ConstructorElement> addedConstructors = <ConstructorElement>[];
   final List<ConstructorElement> removedConstructors = <ConstructorElement>[];
+  bool hasUnnamedConstructorChange = false;
 
   final List<MethodElement> addedMethods = <MethodElement>[];
   final List<MethodElement> removedMethods = <MethodElement>[];
@@ -99,6 +104,9 @@
   final CompilationUnit newUnit;
   final ElementHolder unitElementHolder = new ElementHolder();
 
+  final List<ConstantEvaluationTarget> unitConstants =
+      <ConstantEvaluationTarget>[];
+
   /**
    * The change between element models of [oldUnit] and [newUnit].
    */
@@ -124,11 +132,14 @@
    * Fills [unitDelta] with added/remove elements.
    */
   void build() {
+    _materializeLazyElements();
     new CompilationUnitBuilder()
         .buildCompilationUnit(unitSource, newUnit, librarySource);
+    newUnit.accept(new EnumMemberBuilder(unitElement.context.typeProvider));
     _processDirectives();
     _processUnitMembers();
     _replaceUnitContents(oldUnit, newUnit);
+    _findConstants();
     newUnit.element = unitElement;
     unitElement.setCodeRange(0, newUnit.endToken.end);
   }
@@ -151,11 +162,29 @@
     }
   }
 
+  void _findConstants() {
+    ConstantFinder finder = new ConstantFinder();
+    oldUnit.accept(finder);
+    unitConstants.addAll(finder.constantsToCompute);
+    // Update annotation constants to using the old unit element.
+    for (ConstantEvaluationTarget constant in unitConstants) {
+      if (constant is ElementAnnotationImpl) {
+        constant.compilationUnit = unitElement;
+      }
+    }
+  }
+
+  void _materializeLazyElements() {
+    unitElement.accept(new RecursiveElementVisitor());
+  }
+
   ClassElementDelta _processClassMembers(
       ClassDeclaration oldClass, ClassDeclaration newClass) {
     // If the class hierarchy or type parameters are changed,
     // then the class changed too much - don't compute the delta.
-    if (TokenUtils.getFullCode(newClass.typeParameters) !=
+    if (newClass.abstractKeyword != null && oldClass.abstractKeyword == null ||
+        newClass.abstractKeyword == null && oldClass.abstractKeyword != null ||
+        TokenUtils.getFullCode(newClass.typeParameters) !=
             TokenUtils.getFullCode(oldClass.typeParameters) ||
         TokenUtils.getFullCode(newClass.extendsClause) !=
             TokenUtils.getFullCode(oldClass.extendsClause) ||
@@ -186,10 +215,19 @@
     ElementHolder classElementHolder = new ElementHolder();
     ClassElementDelta classDelta =
         new ClassElementDelta(classElement, librarySource, classElement.name);
+    // Check for annotation changes.
+    {
+      String oldAnnotationsCode =
+          TokenUtils.getFullCodeOfList(oldClass.metadata);
+      String newAnnotationsCode =
+          TokenUtils.getFullCodeOfList(newClass.metadata);
+      classDelta.hasAnnotationChanges =
+          oldAnnotationsCode != newAnnotationsCode;
+    }
     // Prepare all old member elements.
-    var removedAccessors = new Set<PropertyAccessorElement>();
-    var removedConstructors = new Set<ConstructorElement>();
-    var removedMethods = new Set<MethodElement>();
+    var removedAccessors = new Set<PropertyAccessorElement>.identity();
+    var removedConstructors = new Set<ConstructorElement>.identity();
+    var removedMethods = new Set<MethodElement>.identity();
     removedAccessors.addAll(classElement.accessors);
     removedConstructors.addAll(classElement.constructors);
     removedMethods.addAll(classElement.methods);
@@ -330,10 +368,12 @@
       }
     }
     // Update ClassElement.
+    classElement.metadata = newElement.metadata;
     classElement.accessors = newAccessors;
     classElement.constructors = classElementHolder.constructors;
     classElement.fields = newFields.values.toList();
     classElement.methods = classElementHolder.methods;
+    classElement.version++;
     classElementHolder.validate();
     // Ensure at least a default synthetic constructor.
     if (classElement.constructors.isEmpty) {
@@ -341,7 +381,11 @@
           new ConstructorElementImpl.forNode(null);
       constructor.synthetic = true;
       classElement.constructors = <ConstructorElement>[constructor];
+      classDelta.addedConstructors.add(constructor);
     }
+    classDelta.hasUnnamedConstructorChange =
+        classDelta.addedConstructors.any((c) => c.name == '') ||
+            classDelta.removedConstructors.any((c) => c.name == '');
     // OK
     return classDelta;
   }
@@ -538,22 +582,35 @@
   static void copyTokenOffsets(Map<int, int> offsetMap, Token oldToken,
       Token newToken, Token oldEndToken, Token newEndToken) {
     if (oldToken is CommentToken && newToken is CommentToken) {
-      // Update (otherwise unlinked) reference tokens in documentation.
-      if (oldToken is DocumentationCommentToken &&
-          newToken is DocumentationCommentToken) {
-        List<Token> oldReferences = oldToken.references;
-        List<Token> newReferences = newToken.references;
-        assert(oldReferences.length == newReferences.length);
-        for (int i = 0; i < oldReferences.length; i++) {
-          copyTokenOffsets(offsetMap, oldReferences[i], newReferences[i],
-              oldEndToken, newEndToken);
-        }
-      }
       // Update documentation tokens.
       while (oldToken != null) {
         offsetMap[oldToken.offset] = newToken.offset;
         offsetMap[oldToken.end] = newToken.end;
         oldToken.offset = newToken.offset;
+        // Update (otherwise unlinked) reference tokens in documentation.
+        if (oldToken is DocumentationCommentToken &&
+            newToken is DocumentationCommentToken) {
+          List<Token> oldReferences = oldToken.references;
+          List<Token> newReferences = newToken.references;
+          assert(oldReferences.length == newReferences.length);
+          for (int i = 0; i < oldReferences.length; i++) {
+            Token oldToken = oldReferences[i];
+            Token newToken = newReferences[i];
+            // For [new Name] the 'Name' token is the reference.
+            // But we need to process all tokens, including 'new'.
+            while (oldToken.previous != null &&
+                oldToken.previous.type != TokenType.EOF) {
+              oldToken = oldToken.previous;
+            }
+            while (newToken.previous != null &&
+                newToken.previous.type != TokenType.EOF) {
+              newToken = newToken.previous;
+            }
+            copyTokenOffsets(
+                offsetMap, oldToken, newToken, oldEndToken, newEndToken);
+          }
+        }
+        // Next tokens.
         oldToken = oldToken.next;
         newToken = newToken.next;
       }
@@ -592,7 +649,7 @@
   }
 
   /**
-   * Return the token string of all the [node] tokens.
+   * Return the token string of all the [node].
    */
   static String getFullCode(AstNode node) {
     if (node == null) {
@@ -603,6 +660,16 @@
   }
 
   /**
+   * Return the token string of all the [nodes].
+   */
+  static String getFullCodeOfList(List<AstNode> nodes) {
+    if (nodes == null) {
+      return '';
+    }
+    return nodes.map(getFullCode).join(_SEPARATOR);
+  }
+
+  /**
    * Returns all tokens (including comments) of the given [node].
    */
   static List<Token> getTokens(AstNode node) {
@@ -610,6 +677,10 @@
     Token token = getBeginTokenNotComment(node);
     Token endToken = node.endToken;
     while (true) {
+      // stop if past the end token
+      if (token.offset > endToken.end) {
+        break;
+      }
       // append comment tokens
       for (Token commentToken = token.precedingComments;
           commentToken != null;
@@ -641,20 +712,28 @@
   _UpdateElementOffsetsVisitor(this.map);
 
   void visitElement(Element element) {
-    if (element is LibraryElement) {
-      return;
-    }
-    if (element.isSynthetic && !_isVariableInitializer(element)) {
-      return;
-    }
     if (element is ElementImpl) {
       // name offset
       {
         int oldOffset = element.nameOffset;
         int newOffset = map[oldOffset];
-        assert(newOffset != null);
+        // Some synthetic elements have new offsets, e.g. synthetic accessors
+        // of property inducing elements.  But some are purely synthetic, e.g.
+        // synthetic enum fields and their accessors.
+        // PrefixElement(s) can be shared between import directives, so
+        // their name offsets are outside of the second and subsequent import
+        // directives. But we update the name offsets while visiting the first
+        // import directive.
+        if (newOffset == null) {
+          assert(element.isSynthetic || element is PrefixElement);
+          return;
+        }
         element.nameOffset = newOffset;
       }
+      // stop here for LibraryElement
+      if (element is LibraryElementImpl) {
+        return;
+      }
       // code range
       {
         int oldOffset = element.codeOffset;
@@ -694,9 +773,4 @@
     }
     super.visitElement(element);
   }
-
-  static bool _isVariableInitializer(Element element) {
-    return element is FunctionElement &&
-        element.enclosingElement is VariableElement;
-  }
 }
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 7bc5fa1..14d127c 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -92,7 +92,9 @@
   ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/(
       ListResultDescriptor/*<V>*/ subListResult) {
     return new ListToFlattenListTaskInput<E, dynamic/*=V*/ >(
-        this, subListResult.of as dynamic);
+        this,
+        (E element) =>
+            subListResult.of(element as AnalysisTarget) as TaskInput/*<V>*/);
   }
 
   ListTaskInput/*<V>*/ toList/*<V>*/(UnaryFunction<E, dynamic/*=V*/ > mapper) {
@@ -370,7 +372,7 @@
       if (currentBuilder.moveNext()) {
         return true;
       }
-      baseMap = currentBuilder.inputValue;
+      baseMap = currentBuilder.inputValue as dynamic/*=Map<K, List<V>>*/;
       if (baseMap == null) {
         // No base map could be computed due to a circular dependency.  Use an
         // empty map so that no further results will be computed.
@@ -386,7 +388,7 @@
         return true;
       }
       // Add the result value for the current Map key/value.
-      E resultValue = currentBuilder.inputValue;
+      E resultValue = currentBuilder.inputValue as dynamic/*=E*/;
       if (resultValue != null) {
         inputValue.add(resultValue);
       }
@@ -444,20 +446,22 @@
   ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/(
       ListResultDescriptor/*<V>*/ subListResult) {
     return new ListToFlattenListTaskInput<E, dynamic/*=V*/ >(
-        this, subListResult.of as dynamic);
+        this,
+        (E element) =>
+            subListResult.of(element as AnalysisTarget) as TaskInput/*<V>*/);
   }
 
   @override
   ListTaskInput/*<V>*/ toListOf/*<V>*/(ResultDescriptor/*<V>*/ valueResult) {
     return new ListToListTaskInput<E, dynamic/*=V*/ >(
-        this, valueResult.of as dynamic);
+        this, (E element) => valueResult.of(element as AnalysisTarget));
   }
 
   @override
   MapTaskInput<AnalysisTarget, dynamic/*=V*/ > toMapOf/*<V>*/(
       ResultDescriptor/*<V>*/ valueResult) {
     return new ListToMapTaskInput<AnalysisTarget, dynamic/*=V*/ >(
-        this as dynamic, valueResult.of);
+        this as dynamic/*=TaskInput<List<AnalysisTarget>>*/, valueResult.of);
   }
 }
 
@@ -696,7 +700,8 @@
 abstract class TaskInputImpl<V> implements TaskInput<V> {
   @override
   ListTaskInput/*<E>*/ mappedToList/*<E>*/(List/*<E>*/ mapper(V value)) {
-    return new ObjectToListTaskInput(this, mapper);
+    return new ObjectToListTaskInput(
+        this, (Object element) => mapper(element as V));
   }
 }
 
@@ -967,7 +972,7 @@
     if (_resultValue == null) {
       // We have finished computing the list of values from which the results
       // will be derived.
-      _baseList = currentBuilder.inputValue;
+      _baseList = currentBuilder.inputValue as dynamic/*=List<B>*/;
       if (_baseList == null) {
         // No base list could be computed due to a circular dependency.  Use an
         // empty list so that no further results will be computed.
@@ -978,7 +983,8 @@
     } else {
       // We have finished computing one of the elements in the result list.
       if (currentBuilder.inputValue != null) {
-        _addResultElement(_baseListElement, currentBuilder.inputValue);
+        _addResultElement(
+            _baseListElement, currentBuilder.inputValue as dynamic/*=E*/);
       }
       _baseListIndex++;
     }
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index a25d146..6cf5585 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -10,11 +10,13 @@
 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/context/context.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/util/yaml.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
@@ -47,17 +49,17 @@
   static const String enableGenericMethods = 'enableGenericMethods';
   static const String enableStrictCallChecks = 'enableStrictCallChecks';
   static const String enableSuperMixins = 'enableSuperMixins';
-  static const String enableTrailingCommas = 'enableTrailingCommas';
 
-  /// This option is deprecated.
-  static const String enableConditionalDirectives =
-      "enableConditionalDirectives";
   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';
 
+  // Strong mode options, see AnalysisOptionsImpl for documentation.
+  static const String implicitCasts = 'implicit-casts';
+  static const String implicitDynamic = 'implicit-dynamic';
+
   /// Ways to say `ignore`.
   static const List<String> ignoreSynonyms = const ['ignore', 'false'];
 
@@ -83,7 +85,6 @@
   /// Supported `analyzer` language configuration options.
   static const List<String> languageOptions = const [
     enableAsync,
-    enableConditionalDirectives,
     enableGenericMethods,
     enableStrictCallChecks,
     enableSuperMixins
@@ -431,9 +432,8 @@
     if (analyzer is Map) {
       // Process strong mode option.
       var strongMode = analyzer[AnalyzerOptions.strong_mode];
-      if (strongMode is bool) {
-        options.strongMode = strongMode;
-      }
+      _applyStrongOptions(options, strongMode);
+
       // Process language options.
       var language = analyzer[AnalyzerOptions.language];
       _applyLanguageOptions(options, language);
@@ -460,6 +460,19 @@
       // Process language options.
       var language = analyzer[AnalyzerOptions.language];
       setLanguageOptions(context, language);
+
+      // Process excludes.
+      var excludes = analyzer[AnalyzerOptions.exclude];
+      setExcludes(context, excludes);
+    }
+  }
+
+  void setExcludes(AnalysisContext context, Object excludes) {
+    if (excludes is YamlList) {
+      List<String> excludeList = toStringList(excludes);
+      if (excludeList != null) {
+        context.setConfigurationData(CONTEXT_EXCLUDES, excludeList);
+      }
     }
   }
 
@@ -489,14 +502,6 @@
         context.analysisOptions = options;
       }
     }
-    if (feature == AnalyzerOptions.enableTrailingCommas) {
-      if (isTrue(value)) {
-        AnalysisOptionsImpl options =
-            new AnalysisOptionsImpl.from(context.analysisOptions);
-        options.enableTrailingCommas = true;
-        context.analysisOptions = options;
-      }
-    }
     if (feature == AnalyzerOptions.enableGenericMethods) {
       if (isTrue(value)) {
         AnalysisOptionsImpl options =
@@ -527,12 +532,19 @@
   }
 
   void setStrongMode(AnalysisContext context, Object strongMode) {
-    bool strong = strongMode is bool ? strongMode : false;
-    if (context.analysisOptions.strongMode != strong) {
+    if (strongMode is Map) {
       AnalysisOptionsImpl options =
           new AnalysisOptionsImpl.from(context.analysisOptions);
-      options.strongMode = strong;
+      _applyStrongOptions(options, strongMode);
       context.analysisOptions = options;
+    } else {
+      strongMode = strongMode is bool ? strongMode : false;
+      if (context.analysisOptions.strongMode != strongMode) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.strongMode = strongMode;
+        context.analysisOptions = options;
+      }
     }
   }
 
@@ -565,4 +577,33 @@
           .forEach((key, value) => _applyLanguageOption(options, key, value));
     }
   }
+
+  void _applyStrongModeOption(
+      AnalysisOptionsImpl options, Object feature, Object value) {
+    bool boolValue = toBool(value);
+    if (boolValue != null) {
+      if (feature == AnalyzerOptions.implicitCasts) {
+        options.implicitCasts = boolValue;
+      }
+      if (feature == AnalyzerOptions.implicitDynamic) {
+        options.implicitDynamic = boolValue;
+      }
+    }
+  }
+
+  void _applyStrongOptions(AnalysisOptionsImpl options, Object config) {
+    if (config is YamlMap) {
+      options.strongMode = true;
+      config.nodes.forEach((k, v) {
+        if (k is YamlScalar && v is YamlScalar) {
+          _applyStrongModeOption(options, k.value?.toString(), v.value);
+        }
+      });
+    } else if (config is Map) {
+      options.strongMode = true;
+      config.forEach((k, v) => _applyStrongModeOption(options, k, v));
+    } else {
+      options.strongMode = config is bool ? config : false;
+    }
+  }
 }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 783cdf0..d0b55fe 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart' show TokenType;
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -20,6 +21,54 @@
 
 import 'ast_properties.dart';
 
+bool isKnownFunction(Expression expression) {
+  var element = _getKnownElement(expression);
+  // First class functions and static methods, where we know the original
+  // declaration, will have an exact type, so we know a downcast will fail.
+  return element is FunctionElement ||
+      element is MethodElement && element.isStatic;
+}
+
+/// Given an [expression] and a corresponding [typeSystem] and [typeProvider],
+/// gets the known static type of the expression.
+///
+/// Normally when we ask for an expression's type, we get the type of the
+/// storage slot that would contain it. For function types, this is necessarily
+/// a "fuzzy arrow" that treats `dynamic` as bottom. However, if we're
+/// interested in the expression's own type, it can often be a "strict arrow"
+/// because we know it evaluates to a specific, concrete function, and we can
+/// treat "dynamic" as top for that case, which is more permissive.
+DartType getDefiniteType(
+    Expression expression, TypeSystem typeSystem, TypeProvider typeProvider) {
+  DartType type = expression.staticType ?? DynamicTypeImpl.instance;
+  if (typeSystem is StrongTypeSystemImpl &&
+      type is FunctionType &&
+      _hasStrictArrow(expression)) {
+    // Remove fuzzy arrow if possible.
+    return typeSystem.functionTypeToConcreteType(typeProvider, type);
+  }
+  return type;
+}
+
+bool _hasStrictArrow(Expression expression) {
+  var element = _getKnownElement(expression);
+  return element is FunctionElement || element is MethodElement;
+}
+
+Element _getKnownElement(Expression expression) {
+  if (expression is ParenthesizedExpression) {
+    expression = (expression as ParenthesizedExpression).expression;
+  }
+  if (expression is FunctionExpression) {
+    return expression.element;
+  } else if (expression is PropertyAccess) {
+    return expression.propertyName.staticElement;
+  } else if (expression is Identifier) {
+    return expression.staticElement;
+  }
+  return null;
+}
+
 DartType _elementType(Element e) {
   if (e == null) {
     // Malformed code - just return dynamic.
@@ -28,6 +77,8 @@
   return (e as dynamic).type;
 }
 
+// Return the field on type corresponding to member, or null if none
+// exists or the "field" is actually a getter/setter.
 PropertyInducingElement _getMemberField(
     InterfaceType type, PropertyAccessorElement member) {
   String memberName = member.name;
@@ -53,8 +104,6 @@
   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) =>
@@ -92,6 +141,7 @@
     if (baseMethod == null || baseMethod.isStatic) return null;
     return baseMethod.type;
   }
+
   return f;
 }
 
@@ -146,7 +196,9 @@
     if (expr is ParenthesizedExpression) {
       checkAssignment(expr.expression, type);
     } else {
-      _checkDowncast(expr, type);
+      if (_checkNonNullAssignment(expr, type)) {
+        _checkDowncast(expr, type);
+      }
     }
   }
 
@@ -156,14 +208,15 @@
   void checkBoolean(Expression expr) =>
       checkAssignment(expr, typeProvider.boolType);
 
-  void checkFunctionApplication(
-      Expression node, Expression f, ArgumentList list) {
-    if (_isDynamicCall(f)) {
+  void checkFunctionApplication(InvocationExpression node) {
+    var ft = _getTypeAsCaller(node);
+
+    if (_isDynamicCall(node, ft)) {
       // 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);
+      _recordDynamicInvoke(node, node.function);
     } else {
-      checkArgumentList(list, _getTypeAsCaller(f));
+      checkArgumentList(node.argumentList, ft);
     }
   }
 
@@ -176,13 +229,6 @@
   }
 
   @override
-  void visitCompilationUnit(CompilationUnit node) {
-    _hasImplicitCasts = false;
-    node.visitChildren(this);
-    setHasImplicitCasts(node, _hasImplicitCasts);
-  }
-
-  @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
@@ -192,11 +238,16 @@
 
   @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);
+    Token operator = node.operator;
+    TokenType operatorType = operator.type;
+    if (operatorType == TokenType.EQ ||
+        operatorType == TokenType.QUESTION_QUESTION_EQ) {
+      DartType staticType = _getDefiniteType(node.leftHandSide);
       checkAssignment(node.rightHandSide, staticType);
+    } else if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
+        operatorType == TokenType.BAR_BAR_EQ) {
+      checkAssignment(node.leftHandSide, typeProvider.boolType);
+      checkAssignment(node.rightHandSide, typeProvider.boolType);
     } else {
       _checkCompoundAssignment(node);
     }
@@ -207,14 +258,14 @@
   void visitBinaryExpression(BinaryExpression node) {
     var op = node.operator;
     if (op.isUserDefinableOperator) {
-      if (_isDynamicTarget(node.leftOperand)) {
+      var element = node.staticElement;
+      if (element == null) {
         // 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;
@@ -259,6 +310,13 @@
   }
 
   @override
+  void visitCompilationUnit(CompilationUnit node) {
+    _hasImplicitCasts = false;
+    node.visitChildren(this);
+    setHasImplicitCasts(node, _hasImplicitCasts);
+  }
+
+  @override
   void visitConditionalExpression(ConditionalExpression node) {
     checkBoolean(node.condition);
     node.visitChildren(this);
@@ -341,7 +399,7 @@
       var sequenceInterface = node.awaitKeyword != null
           ? typeProvider.streamType
           : typeProvider.iterableType;
-      var iterableType = _getStaticType(node.iterable);
+      var iterableType = _getDefiniteType(node.iterable);
       var elementType =
           rules.mostSpecificTypeArgument(iterableType, sequenceInterface);
 
@@ -363,7 +421,7 @@
       if (elementType != null) {
         // Insert a cast from the sequence's element type to the loop variable's
         // if needed.
-        _checkDowncast(loopVariable, _getStaticType(loopVariable),
+        _checkDowncast(loopVariable, _getDefiniteType(loopVariable),
             from: elementType);
       }
     }
@@ -380,8 +438,14 @@
   }
 
   @override
+  void visitFunctionExpression(FunctionExpression node) {
+    _checkForUnsafeBlockClosureInference(node);
+    super.visitFunctionExpression(node);
+  }
+
+  @override
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    checkFunctionApplication(node, node.function, node.argumentList);
+    checkFunctionApplication(node);
     node.visitChildren(this);
   }
 
@@ -394,20 +458,18 @@
   @override
   void visitIndexExpression(IndexExpression node) {
     var target = node.realTarget;
-    if (_isDynamicTarget(target)) {
+    var element = node.staticElement;
+    if (element == null) {
       _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?
+    } else 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);
   }
@@ -491,7 +553,8 @@
   @override
   visitMethodInvocation(MethodInvocation node) {
     var target = node.realTarget;
-    if (_isDynamicTarget(target) && !_isObjectMethod(node, node.methodName)) {
+    var element = node.methodName.staticElement;
+    if (element == null && !typeProvider.isObjectMethod(node.methodName.name)) {
       _recordDynamicInvoke(node, target);
 
       // Mark the tear-off as being dynamic, too. This lets us distinguish
@@ -509,14 +572,14 @@
       // we call [checkFunctionApplication].
       setIsDynamicInvoke(node.methodName, true);
     } else {
-      checkFunctionApplication(node, node.methodName, node.argumentList);
+      checkFunctionApplication(node);
     }
     node.visitChildren(this);
   }
 
   @override
   void visitPostfixExpression(PostfixExpression node) {
-    _checkUnary(node);
+    _checkUnary(node, node.staticElement);
     node.visitChildren(this);
   }
 
@@ -530,7 +593,7 @@
     if (node.operator.type == TokenType.BANG) {
       checkBoolean(node.operand);
     } else {
-      _checkUnary(node);
+      _checkUnary(node, node.staticElement);
     }
     node.visitChildren(this);
   }
@@ -586,11 +649,10 @@
       // 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);
+          checkAssignment(initializer, type.type);
         }
       }
     }
@@ -598,6 +660,20 @@
   }
 
   @override
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    if (!node.isConst &&
+        !node.isFinal &&
+        node.initializer == null &&
+        rules.isNonNullableType(node?.element?.type)) {
+      _recordMessage(
+          node,
+          StaticTypeWarningCode.NON_NULLABLE_FIELD_NOT_INITIALIZED,
+          [node.name, node?.element?.type]);
+    }
+    return super.visitVariableDeclaration(node);
+  }
+
+  @override
   void visitWhileStatement(WhileStatement node) {
     checkBoolean(node.condition);
     node.visitChildren(this);
@@ -626,13 +702,14 @@
       assert(functionType.optionalParameterTypes.isEmpty);
 
       // Check the LHS type.
-      var rhsType = _getStaticType(expr.rightHandSide);
-      var lhsType = _getStaticType(expr.leftHandSide);
+      var rhsType = _getDefiniteType(expr.rightHandSide);
+      var lhsType = _getDefiniteType(expr.leftHandSide);
       var returnType = rules.refineBinaryExpressionType(
           typeProvider, lhsType, op, rhsType, functionType.returnType);
 
       if (!rules.isSubtypeOf(returnType, lhsType)) {
         final numType = typeProvider.numType;
+        // TODO(jmesserly): this seems to duplicate logic in StaticTypeAnalyzer.
         // Try to fix up the numerical case if possible.
         if (rules.isSubtypeOf(lhsType, numType) &&
             rules.isSubtypeOf(lhsType, rhsType)) {
@@ -640,6 +717,8 @@
           // compound operators in the int += num and num += dynamic cases.
           _recordImplicitCast(expr.rightHandSide, rhsType, lhsType);
         } else {
+          // TODO(jmesserly): this results in a duplicate error, because
+          // ErrorVerifier also reports it.
           _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR,
               [expr, returnType, lhsType]);
         }
@@ -661,7 +740,7 @@
   /// or is already a subtype of it, does nothing.
   void _checkDowncast(Expression expr, DartType to, {DartType from}) {
     if (from == null) {
-      from = _getStaticType(expr);
+      from = _getDefiniteType(expr);
     }
 
     // We can use anything as void.
@@ -670,14 +749,10 @@
     // fromT <: toT, no coercion needed.
     if (rules.isSubtypeOf(from, to)) return;
 
-    // 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 ((from is FunctionType && rules.getCallMethodType(to) != null) ||
-        (to is FunctionType && rules.getCallMethodType(from) != null)) {
+    if (from is FunctionType && rules.getCallMethodType(to) != null) {
       return;
     }
 
@@ -687,29 +762,131 @@
       return;
     }
 
-    // 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 (from.isAssignableTo(to)) {
-      _recordImplicitCast(expr, from, to);
-    }
+    // Anything else is an illegal sideways cast.
+    // However, these will have been reported already in error_verifier, so we
+    // don't need to report them again.
   }
 
   void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
-    if ((_isDynamicTarget(target) || field.staticElement == null) &&
-        !_isObjectProperty(target, field)) {
+    if (field.staticElement == null &&
+        !typeProvider.isObjectMember(field.name)) {
       _recordDynamicInvoke(node, target);
     }
     node.visitChildren(this);
   }
 
+  /**
+   * Check if the closure [node] is unsafe due to dartbug.com/26947.  If so,
+   * issue a warning.
+   *
+   * TODO(paulberry): eliminate this once dartbug.com/26947 is fixed.
+   */
+  void _checkForUnsafeBlockClosureInference(FunctionExpression node) {
+    if (node.body is! BlockFunctionBody) {
+      return;
+    }
+    if (node.element.returnType.isDynamic) {
+      return;
+    }
+    // Find the enclosing variable declaration whose inferred type might depend
+    // on the inferred return type of the block closure (if any).
+    AstNode prevAncestor = node;
+    AstNode ancestor = node.parent;
+    while (ancestor != null && ancestor is! VariableDeclaration) {
+      if (ancestor is BlockFunctionBody) {
+        // node is inside another block function body; if that block
+        // function body is unsafe, we've already warned about it.
+        return;
+      }
+      if (ancestor is InstanceCreationExpression) {
+        // node appears inside an instance creation expression; we may be safe
+        // if the type of the instance creation expression requires no
+        // inference.
+        TypeName typeName = ancestor.constructorName.type;
+        if (typeName.typeArguments != null) {
+          // Type arguments were explicitly specified.  We are safe.
+          return;
+        }
+        DartType type = typeName.type;
+        if (!(type is ParameterizedType && type.typeParameters.isNotEmpty)) {
+          // Type is not generic.  We are safe.
+          return;
+        }
+      }
+      if (ancestor is MethodInvocation) {
+        // node appears inside a method or function invocation; we may be safe
+        // if the type of the method or function requires no inference.
+        if (ancestor.typeArguments != null) {
+          // Type arguments were explicitly specified.  We are safe.
+          return;
+        }
+        Element methodElement = ancestor.methodName.staticElement;
+        if (!(methodElement is ExecutableElement &&
+            methodElement.typeParameters.isNotEmpty)) {
+          // Method is not generic.  We are safe.
+          return;
+        }
+      }
+      if (ancestor is FunctionExpressionInvocation &&
+          !identical(prevAncestor, ancestor.function)) {
+        // node appears inside an argument to a function expression invocation;
+        // we may be safe if the type of the function expression requires no
+        // inference.
+        if (ancestor.typeArguments != null) {
+          // Type arguments were explicitly specified.  We are safe.
+          return;
+        }
+        DartType type = ancestor.function.staticType;
+        if (!(type is FunctionTypeImpl && type.typeFormals.isNotEmpty)) {
+          // Type is not generic or has had its type parameters instantiated.
+          // We are safe.
+          return;
+        }
+      }
+      if ((ancestor is ListLiteral && ancestor.typeArguments != null) ||
+          (ancestor is MapLiteral && ancestor.typeArguments != null)) {
+        // node appears inside a list or map literal with an explicit type.  We
+        // are safe because no type inference is required.
+        return;
+      }
+      prevAncestor = ancestor;
+      ancestor = ancestor.parent;
+    }
+    if (ancestor == null) {
+      // node is not inside a variable declaration, so it is safe.
+      return;
+    }
+    VariableDeclaration decl = ancestor;
+    VariableElement declElement = decl.element;
+    if (!declElement.hasImplicitType) {
+      // Variable declaration has an explicit type, so it's safe.
+      return;
+    }
+    if (declElement.type.isDynamic) {
+      // No type was successfully inferred for this variable, so it's safe.
+      return;
+    }
+    if (declElement.enclosingElement is ExecutableElement) {
+      // Variable declaration is inside a function or method, so it's safe.
+      return;
+    }
+    _recordMessage(node, StrongModeCode.UNSAFE_BLOCK_CLOSURE_INFERENCE,
+        [declElement.name]);
+  }
+
+  /// Checks if the assignment is valid with respect to non-nullable types.
+  /// Returns `false` if a nullable expression is assigned to a variable of
+  /// non-nullable type and `true` otherwise.
+  bool _checkNonNullAssignment(Expression expression, DartType type) {
+    var exprType = expression.staticType;
+    if (rules.isNonNullableType(type) && rules.isNullableType(exprType)) {
+      _recordMessage(expression, StaticTypeWarningCode.INVALID_ASSIGNMENT,
+          [exprType, type]);
+      return false;
+    }
+    return true;
+  }
+
   void _checkReturnOrYield(Expression expression, AstNode node,
       {bool yieldStar: false}) {
     FunctionBody body = node.getAncestor((n) => n is FunctionBody);
@@ -720,14 +897,6 @@
       // 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.instantiate([type]);
-    }
     // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
     if (expression != null) checkAssignment(expression, type);
   }
@@ -739,12 +908,14 @@
     }
   }
 
-  void _checkUnary(/*PrefixExpression|PostfixExpression*/ node) {
+  void _checkUnary(
+      /*PrefixExpression|PostfixExpression*/ node,
+      Element element) {
     var op = node.operator;
     if (op.isUserDefinableOperator ||
         op.type == TokenType.PLUS_PLUS ||
         op.type == TokenType.MINUS_MINUS) {
-      if (_isDynamicTarget(node.operand)) {
+      if (element == null) {
         _recordDynamicInvoke(node, node.operand);
       }
       // For ++ and --, even if it is not dynamic, we still need to check
@@ -753,6 +924,103 @@
     }
   }
 
+  /// 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 as FunctionExpression).staticType ?? DynamicTypeImpl.instance;
+    }
+
+    var type = functionType.returnType;
+
+    InterfaceType expectedType = null;
+    if (body.isAsynchronous) {
+      if (body.isGenerator) {
+        // Stream<T> -> T
+        expectedType = typeProvider.streamType;
+      } else {
+        // Don't validate return type of async methods.
+        // They're handled by the runtime implementation.
+        return null;
+      }
+    } 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.instantiate([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 _getDefiniteType(Expression expr) =>
+      getDefiniteType(expr, rules, typeProvider);
+
+  /// 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(InvocationExpression node) {
+    DartType type = node.staticInvokeType;
+    if (type is FunctionType) {
+      return type;
+    } else if (type is InterfaceType) {
+      return rules.getCallMethodType(type);
+    }
+    return null;
+  }
+
+  /// Returns `true` if the expression is a dynamic function call or method
+  /// invocation.
+  bool _isDynamicCall(InvocationExpression call, FunctionType ft) {
+    // 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 (_hasStrictArrow(call.function)) {
+      return false;
+    }
+    return rules.anyParameterType(ft, (pt) => pt.isDynamic);
+  }
+
+  void _recordDynamicInvoke(AstNode node, Expression target) {
+    _recordMessage(node, StrongModeCode.DYNAMIC_INVOKE, [node]);
+    // 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.
+    if (target != null) setIsDynamicInvoke(target, true);
+  }
+
   /// Records an implicit cast for the [expression] from [fromType] to [toType].
   ///
   /// This will emit the appropriate error/warning/hint message as well as mark
@@ -762,7 +1030,7 @@
     // toT <:_R fromT => to <: fromT
     // NB: classes with call methods are subtypes of function
     // types, but the function type is not assignable to the class
-    assert(toType.isSubtypeOf(fromType) || fromType.isAssignableTo(toType));
+    assert(toType.isSubtypeOf(fromType));
 
     // Inference "casts":
     if (expression is Literal || expression is FunctionExpression) {
@@ -833,158 +1101,6 @@
     _hasImplicitCasts = true;
   }
 
-  // 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 as FunctionExpression).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.instantiate([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) {
-    DartType t = expr.staticType ?? DynamicTypeImpl.instance;
-
-    // Remove fuzzy arrow if possible.
-    if (t is FunctionType && isKnownFunction(expr)) {
-      t = rules.functionTypeToConcreteType(typeProvider, t);
-    }
-
-    return t;
-  }
-
-  /// 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;
-  }
-
-  /// 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, Expression target) {
-    _recordMessage(node, StrongModeCode.DYNAMIC_INVOKE, [node]);
-    // 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.
-    setIsDynamicInvoke(target, true);
-  }
-
   void _recordMessage(AstNode node, ErrorCode errorCode, List arguments) {
     var severity = errorCode.errorSeverity;
     if (severity == ErrorSeverity.ERROR) _failure = true;
@@ -1001,21 +1117,6 @@
   }
 }
 
-bool isKnownFunction(Expression expression) {
-  Element element = null;
-  if (expression is FunctionExpression) {
-    return true;
-  } else if (expression is PropertyAccess) {
-    element = expression.propertyName.staticElement;
-  } else if (expression is Identifier) {
-    element = expression.staticElement;
-  }
-// First class functions and static methods, where we know the original
-// declaration, will have an exact type, so we know a downcast will fail.
-  return element is FunctionElement ||
-      element is MethodElement && element.isStatic;
-}
-
 /// Checks for overriding declarations of fields and methods. This is used to
 /// check overrides between classes and superclasses, interfaces, and mixin
 /// applications.
@@ -1160,6 +1261,7 @@
         seen.add(e.name);
       }
     }
+
     subType.methods.forEach(checkHelper);
     subType.accessors.forEach(checkHelper);
   }
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 420fd61..ea4e0b3 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -279,6 +279,12 @@
     List<FunctionType> overriddenTypes = new List<FunctionType>();
     for (ExecutableElement overriddenMethod in overriddenMethods) {
       FunctionType overriddenType = overriddenMethod.type;
+      if (overriddenType == null) {
+        // TODO(brianwilkerson) I think the overridden method should always have
+        // a type, but there appears to be a bug that causes it to sometimes be
+        // null, we guard against that case by not performing inference.
+        return;
+      }
       if (overriddenType.typeFormals.isNotEmpty) {
         if (overriddenType.typeFormals.length != typeFormals.length) {
           return;
@@ -466,6 +472,7 @@
         }
         return element;
       }
+
       Element element = nonAccessor(node.staticElement);
       if (element is VariableElement && (filter == null || filter(element))) {
         results.add(element);
diff --git a/pkg/analyzer/lib/src/util/fast_uri.dart b/pkg/analyzer/lib/src/util/fast_uri.dart
index 8af548c..0df5ce05 100644
--- a/pkg/analyzer/lib/src/util/fast_uri.dart
+++ b/pkg/analyzer/lib/src/util/fast_uri.dart
@@ -62,23 +62,7 @@
   bool get hasFragment => false;
 
   @override
-  int get hashCode {
-    // This code is copied from the standard Uri implementation.
-    // It is important that Uri and FastUri generate compatible hashCodes
-    // because Uri and FastUri may be used as keys in the same map.
-    int combine(part, current) {
-      // The sum is truncated to 30 bits to make sure it fits into a Smi.
-      return (current * 31 + part.hashCode) & 0x3FFFFFFF;
-    }
-    return _hashCode ??= combine(
-        scheme,
-        combine(
-            userInfo,
-            combine(
-                host,
-                combine(port,
-                    combine(path, combine(query, combine(fragment, 1)))))));
-  }
+  int get hashCode => _text.hashCode;
 
   @override
   bool get hasPort => false;
diff --git a/pkg/analyzer/lib/src/util/yaml.dart b/pkg/analyzer/lib/src/util/yaml.dart
index 4f71bd7..aa988e6 100644
--- a/pkg/analyzer/lib/src/util/yaml.dart
+++ b/pkg/analyzer/lib/src/util/yaml.dart
@@ -6,9 +6,28 @@
 
 import 'dart:collection';
 
+import 'package:yaml/yaml.dart';
+
+/// If all of the elements of [list] are strings, return a list of strings
+/// containing the same elements. Otherwise, return `null`.
+List<String> toStringList(YamlList list) {
+  if (list == null) {
+    return null;
+  }
+  List<String> stringList = <String>[];
+  for (var element in list) {
+    if (element is String) {
+      stringList.add(element);
+    } else {
+      return null;
+    }
+  }
+  return stringList;
+}
+
 /// 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.
+/// (and possibly overridden) by an overriding map.
 class Merger {
   /// Merges a default [o1] with an overriding object [o2].
   ///
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 42066a8..1ad2b79 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.27.4-alpha.15
+version: 0.28.0-alpha.1
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -7,10 +7,13 @@
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
   args: '>=0.12.1 <0.14.0'
+  charcode: ^1.1.0
   crypto: '>=1.1.1 <3.0.0'
   glob: ^1.0.3
-  html: ^0.12.0
-  package_config: ^0.1.5
+  html: '>=0.12.0 <1.14.0'
+  isolate: ^0.2.2
+  meta: ^1.0.2
+  package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
   plugin: ^0.2.0
   watcher: '>=0.9.6 <0.10.0'
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 a6adddd..5c931b1 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -204,6 +204,12 @@
     expect(file.toString(), '/foo/bar/file.txt');
   }
 
+  void test_toUri() {
+    String path = '/foo/file.txt';
+    File file = provider.newFile(path, '');
+    expect(file.toUri(), new Uri.file(path, windows: false));
+  }
+
   void test_writeAsBytesSync_existing() {
     File file = provider.newFileWithBytes('/foo/file.bin', <int>[1, 2]);
     expect(file.readAsBytesSync(), <int>[1, 2]);
@@ -387,6 +393,12 @@
     expect(parent2.path, equals('/'));
     expect(parent2.parent, isNull);
   }
+
+  void test_toUri() {
+    String path = '/foo/directory';
+    Folder folder = provider.newFolder(path);
+    expect(folder.toUri(), new Uri.directory(path, windows: false));
+  }
 }
 
 @reflectiveTest
@@ -539,6 +551,13 @@
     expect(file.exists, isFalse);
   }
 
+  test_getModificationTimes() async {
+    File file = provider.newFile('/test.dart', '');
+    Source source = file.createSource();
+    List<int> times = await provider.getModificationTimes([source]);
+    expect(times, [source.modificationStamp]);
+  }
+
   void test_getStateLocation_uniqueness() {
     String idOne = 'one';
     Folder folderOne = provider.getStateLocation(idOne);
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 790eff7..a7c7c1f 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -188,6 +188,12 @@
     expect(file.toString(), path);
   }
 
+  void test_toUri() {
+    String path = '/foo/file.txt';
+    File file = PhysicalResourceProvider.INSTANCE.getFile(path);
+    expect(file.toUri(), new Uri.file(path));
+  }
+
   void test_writeAsBytesSync() {
     new io.File(path).writeAsBytesSync(<int>[1, 2]);
     expect(file.readAsBytesSync(), <int>[1, 2]);
@@ -373,10 +379,32 @@
       parent = grandParent;
     }
   }
+
+  void test_toUri() {
+    String path = '/foo/directory';
+    Folder folder = PhysicalResourceProvider.INSTANCE.getFolder(path);
+    expect(folder.toUri(), new Uri.directory(path));
+  }
 }
 
 @reflectiveTest
 class PhysicalResourceProviderTest extends _BaseTest {
+  test_getFolder_trailingSeparator() {
+    String path = tempPath;
+    PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
+    Folder folder = provider.getFolder('$path$separator');
+    expect(folder.path, path);
+  }
+
+  test_getModificationTimes() async {
+    PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
+    String path = join(tempPath, 'file1.txt');
+    new io.File(path).writeAsStringSync('');
+    Source source = provider.getFile(path).createSource();
+    List<int> times = await provider.getModificationTimes([source]);
+    expect(times, [source.modificationStamp]);
+  }
+
   void test_getStateLocation_uniqueness() {
     PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
     String idOne = 'one';
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 70e1c73..0f06f13 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/dart/ast/utilities.dart' hide ConstantEvaluator;
 import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart' hide SdkLibrariesReader;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -44,6 +45,7 @@
   runReflectiveTests(ContentCacheTest);
   runReflectiveTests(CustomUriResolverTest);
   runReflectiveTests(DartUriResolverTest);
+  // ignore: deprecated_member_use
   runReflectiveTests(DirectoryBasedDartSdkTest);
   runReflectiveTests(DirectoryBasedSourceContainerTest);
   runReflectiveTests(ElementBuilderTest);
@@ -55,6 +57,7 @@
   runReflectiveTests(ExitDetectorTest2);
   runReflectiveTests(FileBasedSourceTest);
   runReflectiveTests(ResolveRelativeUriTest);
+  // ignore: deprecated_member_use
   runReflectiveTests(SDKLibrariesReaderTest);
   runReflectiveTests(UriKindTest);
 }
@@ -85,8 +88,9 @@
   }
 
   void test_resolve_unknown_uri() {
-    UriResolver resolver =
-        new CustomUriResolver({'custom:library': '/path/to/library.dart',});
+    UriResolver resolver = new CustomUriResolver({
+      'custom:library': '/path/to/library.dart',
+    });
     Source result =
         resolver.resolveAbsolute(parseUriWithException("custom:non_library"));
     expect(result, isNull);
@@ -95,7 +99,9 @@
   void test_resolve_uri() {
     String path =
         FileUtilities2.createFile("/path/to/library.dart").getAbsolutePath();
-    UriResolver resolver = new CustomUriResolver({'custom:library': path,});
+    UriResolver resolver = new CustomUriResolver({
+      'custom:library': path,
+    });
     Source result =
         resolver.resolveAbsolute(parseUriWithException("custom:library"));
     expect(result, isNotNull);
@@ -106,9 +112,7 @@
 @reflectiveTest
 class DartUriResolverTest {
   void test_creation() {
-    JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
-    expect(sdkDirectory, isNotNull);
-    DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+    DartSdk sdk = _createSdk();
     expect(new DartUriResolver(sdk), isNotNull);
   }
 
@@ -119,9 +123,7 @@
   }
 
   void test_resolve_dart() {
-    JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
-    expect(sdkDirectory, isNotNull);
-    DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+    DartSdk sdk = _createSdk();
     UriResolver resolver = new DartUriResolver(sdk);
     Source result =
         resolver.resolveAbsolute(parseUriWithException("dart:core"));
@@ -129,25 +131,29 @@
   }
 
   void test_resolve_dart_nonExistingLibrary() {
-    JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
-    expect(sdkDirectory, isNotNull);
-    DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+    DartSdk sdk = _createSdk();
     UriResolver resolver = new DartUriResolver(sdk);
     Source result = resolver.resolveAbsolute(parseUriWithException("dart:cor"));
     expect(result, isNull);
   }
 
   void test_resolve_nonDart() {
-    JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
-    expect(sdkDirectory, isNotNull);
-    DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+    DartSdk sdk = _createSdk();
     UriResolver resolver = new DartUriResolver(sdk);
     Source result = resolver
         .resolveAbsolute(parseUriWithException("package:some/file.dart"));
     expect(result, isNull);
   }
+
+  DartSdk _createSdk() {
+    ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
+    Folder sdkFolder = FolderBasedDartSdk.defaultSdkDirectory(resourceProvider);
+    expect(sdkFolder, isNotNull);
+    return new FolderBasedDartSdk(resourceProvider, sdkFolder);
+  }
 }
 
+@deprecated
 @reflectiveTest
 class DirectoryBasedDartSdkTest {
   void fail_getDocFileFor() {
@@ -1591,6 +1597,43 @@
     expect(method.isSynthetic, isFalse);
   }
 
+  void test_visitMethodDeclaration_duplicateField_synthetic() {
+    buildElementsForText(r'''
+class A {
+  int f;
+  int get f => 42;
+}
+''');
+    ClassDeclaration classNode = compilationUnit.declarations.single;
+    // ClassElement
+    ClassElement classElement = classNode.element;
+    expect(classElement.fields, hasLength(2));
+    expect(classElement.accessors, hasLength(3));
+    FieldElement notSyntheticFieldElement = classElement.fields
+        .singleWhere((f) => f.displayName == 'f' && !f.isSynthetic);
+    FieldElement syntheticFieldElement = classElement.fields
+        .singleWhere((f) => f.displayName == 'f' && f.isSynthetic);
+    PropertyAccessorElement syntheticGetterElement = classElement.accessors
+        .singleWhere(
+            (a) => a.displayName == 'f' && a.isGetter && a.isSynthetic);
+    PropertyAccessorElement syntheticSetterElement = classElement.accessors
+        .singleWhere(
+            (a) => a.displayName == 'f' && a.isSetter && a.isSynthetic);
+    PropertyAccessorElement notSyntheticGetterElement = classElement.accessors
+        .singleWhere(
+            (a) => a.displayName == 'f' && a.isGetter && !a.isSynthetic);
+    expect(notSyntheticFieldElement.getter, same(syntheticGetterElement));
+    expect(notSyntheticFieldElement.setter, same(syntheticSetterElement));
+    expect(syntheticFieldElement.getter, same(notSyntheticGetterElement));
+    expect(syntheticFieldElement.setter, isNull);
+    // class members nodes and their elements
+    FieldDeclaration fieldDeclNode = classNode.members[0];
+    VariableDeclaration fieldNode = fieldDeclNode.fields.variables.single;
+    MethodDeclaration getterNode = classNode.members[1];
+    expect(fieldNode.element, notSyntheticFieldElement);
+    expect(getterNode.element, notSyntheticGetterElement);
+  }
+
   void test_visitMethodDeclaration_external() {
     // external m();
     ElementHolder holder = new ElementHolder();
@@ -2565,20 +2608,6 @@
 
 @reflectiveTest
 class ElementLocatorTest extends ResolverTestCase {
-  void test_locate_ExportDirective() {
-    AstNode id = _findNodeIn("export", "export 'dart:core';");
-    Element element = ElementLocator.locate(id);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ExportElement, ExportElement, element);
-  }
-
-  void test_locate_Identifier_libraryDirective() {
-    AstNode id = _findNodeIn("foo", "library foo.bar;");
-    Element element = ElementLocator.locate(id);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is LibraryElement, LibraryElement, element);
-  }
-
   void fail_locate_Identifier_partOfDirective() {
     // Can't resolve the library element without the library declaration.
     //    AstNode id = findNodeIn("foo", "part of foo.bar;");
@@ -2643,6 +2672,13 @@
         (obj) => obj is ConstructorElement, ConstructorElement, element);
   }
 
+  void test_locate_ExportDirective() {
+    AstNode id = _findNodeIn("export", "export 'dart:core';");
+    Element element = ElementLocator.locate(id);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is ExportElement, ExportElement, element);
+  }
+
   void test_locate_FunctionDeclaration() {
     AstNode id = _findNodeIn("f", "int f() => 3;");
     FunctionDeclaration declaration =
@@ -2724,6 +2760,13 @@
         (obj) => obj is FieldElement, FieldElement, element);
   }
 
+  void test_locate_Identifier_libraryDirective() {
+    AstNode id = _findNodeIn("foo", "library foo.bar;");
+    Element element = ElementLocator.locate(id);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is LibraryElement, LibraryElement, element);
+  }
+
   void test_locate_Identifier_propertyAccess() {
     AstNode id = _findNodeIn(
         "length",
@@ -3287,6 +3330,11 @@
     _assertFalse("v = 1;");
   }
 
+  void test_assignmentExpression_compound_lazy() {
+    enableLazyAssignmentOperators = true;
+    _assertFalse("v ||= false;");
+  }
+
   void test_assignmentExpression_lhs_throw() {
     _assertTrue("a[throw ''] = 0;");
   }
@@ -3467,14 +3515,6 @@
     expect(new ExitDetector(), isNotNull);
   }
 
-  void test_doStatement_return() {
-    _assertTrue("{ do { return null; } while (1 == 2); }");
-  }
-
-  void test_doStatement_throwCondition() {
-    _assertTrue("{ do {} while (throw ''); }");
-  }
-
   void test_doStatement_break_and_throw() {
     _assertFalse("{ do { if (1==1) break; throw 'T'; } while (0==1); }");
   }
@@ -3483,19 +3523,6 @@
     _assertFalse("{ do { if (1==1) continue; throw 'T'; } while (0==1); }");
   }
 
-  void test_doStatement_continueInSwitch_and_throw() {
-    _assertFalse('''
-{
-  do {
-    switch (1) {
-      L: case 0: continue;
-      M: case 1: break;
-    }
-    throw 'T';
-  } while (0 == 1);
-}''');
-  }
-
   void test_doStatement_continueDoInSwitch_and_throw() {
     _assertFalse('''
 {
@@ -3509,6 +3536,27 @@
 }''');
   }
 
+  void test_doStatement_continueInSwitch_and_throw() {
+    _assertFalse('''
+{
+  do {
+    switch (1) {
+      L: case 0: continue;
+      M: case 1: break;
+    }
+    throw 'T';
+  } while (0 == 1);
+}''');
+  }
+
+  void test_doStatement_return() {
+    _assertTrue("{ do { return null; } while (1 == 2); }");
+  }
+
+  void test_doStatement_throwCondition() {
+    _assertTrue("{ do {} while (throw ''); }");
+  }
+
   void test_doStatement_true_break() {
     _assertFalse("{ do { break; } while (true); }");
   }
@@ -3521,7 +3569,6 @@
     _assertTrue("{ x: do { continue x; } while (true); }");
   }
 
-
   void test_doStatement_true_if_return() {
     _assertTrue("{ do { if (true) {return null;} } while (true); }");
   }
@@ -3924,6 +3971,10 @@
     _assertFalse("{ while (true) { break; } }");
   }
 
+  void test_whileStatement_true_break_and_throw() {
+    _assertFalse("{ while (true) { if (1==1) break; throw 'T'; } }");
+  }
+
   void test_whileStatement_true_continue() {
     _assertTrue("{ while (true) { continue; } }");
   }
@@ -3952,16 +4003,13 @@
     _assertTrue("{ while (true) { throw ''; } }");
   }
 
-  void test_whileStatement_true_break_and_throw() {
-    _assertFalse("{ while (true) { if (1==1) break; throw 'T'; } }");
-  }
-
   void _assertFalse(String source) {
     _assertHasReturn(false, source);
   }
 
   void _assertHasReturn(bool expectedResult, String source) {
-    Statement statement = ParserTestCase.parseStatement(source);
+    Statement statement = ParserTestCase.parseStatement(
+        source, [], enableLazyAssignmentOperators);
     expect(ExitDetector.exits(statement), expectedResult);
   }
 
@@ -4085,20 +4133,6 @@
     _assertNthStatementDoesNotExit(source, 0);
   }
 
-  void test_whileStatement_switchWithBreakWithLabel() {
-    Source source = addSource(r'''
-void f() {
-  x: while (true) {
-    switch (true) {
-      case false: break;
-      case true: break x;
-    }
-  }
-}
-''');
-    _assertNthStatementDoesNotExit(source, 0);
-  }
-
   void test_whileStatement_breakWithLabel_afterExting() {
     Source source = addSource(r'''
 void f() {
@@ -4113,6 +4147,20 @@
     _assertNthStatementExits(source, 0);
   }
 
+  void test_whileStatement_switchWithBreakWithLabel() {
+    Source source = addSource(r'''
+void f() {
+  x: while (true) {
+    switch (true) {
+      case false: break;
+      case true: break x;
+    }
+  }
+}
+''');
+    _assertNthStatementDoesNotExit(source, 0);
+  }
+
   void test_yieldStatement_plain() {
     Source source = addSource(r'''
 void f() sync* {
@@ -4268,9 +4316,7 @@
   }
 
   void test_isInSystemLibrary_contagious() {
-    JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
-    expect(sdkDirectory, isNotNull);
-    DartSdk sdk = new DirectoryBasedDartSdk(sdkDirectory);
+    DartSdk sdk = _createSdk();
     UriResolver resolver = new DartUriResolver(sdk);
     SourceFactory factory = new SourceFactory([resolver]);
     // resolve dart:core
@@ -4355,76 +4401,69 @@
     expect(source.fullName, file.getAbsolutePath());
     expect(source.isInSystemLibrary, isTrue);
   }
+
+  DartSdk _createSdk() {
+    ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
+    Folder sdkFolder = FolderBasedDartSdk.defaultSdkDirectory(resourceProvider);
+    expect(sdkFolder, isNotNull);
+    return new FolderBasedDartSdk(resourceProvider, sdkFolder);
+  }
 }
 
 @reflectiveTest
 class ResolveRelativeUriTest {
   void test_resolveRelative_dart_dartUri() {
-    Uri uri = parseUriWithException('dart:foo');
-    Uri relative = resolveRelativeUri(uri, parseUriWithException('dart:bar'));
-    expect(relative, isNotNull);
-    expect(relative.toString(), 'dart:bar');
+    _assertResolve('dart:foo', 'dart:bar', 'dart:bar');
   }
 
   void test_resolveRelative_dart_fileName() {
-    Uri uri = parseUriWithException("dart:test");
-    Uri relative = resolveRelativeUri(uri, parseUriWithException("lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "dart:test/lib.dart");
+    _assertResolve('dart:test', 'lib.dart', 'dart:test/lib.dart');
   }
 
   void test_resolveRelative_dart_filePath() {
-    Uri uri = parseUriWithException("dart:test");
-    Uri relative = resolveRelativeUri(uri, parseUriWithException("c/lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "dart:test/c/lib.dart");
+    _assertResolve('dart:test', 'c/lib.dart', 'dart:test/c/lib.dart');
   }
 
   void test_resolveRelative_dart_filePathWithParent() {
-    Uri uri = parseUriWithException("dart:test/b/test.dart");
-    Uri relative =
-        resolveRelativeUri(uri, parseUriWithException("../c/lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "dart:test/c/lib.dart");
+    _assertResolve(
+        'dart:test/b/test.dart', '../c/lib.dart', 'dart:test/c/lib.dart');
   }
 
   void test_resolveRelative_package_dartUri() {
-    Uri uri = parseUriWithException('package:foo/bar.dart');
-    Uri relative = resolveRelativeUri(uri, parseUriWithException('dart:test'));
-    expect(relative, isNotNull);
-    expect(relative.toString(), 'dart:test');
+    _assertResolve('package:foo/bar.dart', 'dart:test', 'dart:test');
+  }
+
+  void test_resolveRelative_package_emptyPath() {
+    _assertResolve('package:foo/bar.dart', '', 'package:foo/bar.dart');
   }
 
   void test_resolveRelative_package_fileName() {
-    Uri uri = parseUriWithException("package:b/test.dart");
-    Uri relative = resolveRelativeUri(uri, parseUriWithException("lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "package:b/lib.dart");
+    _assertResolve('package:b/test.dart', 'lib.dart', 'package:b/lib.dart');
   }
 
   void test_resolveRelative_package_fileNameWithoutPackageName() {
-    Uri uri = parseUriWithException("package:test.dart");
-    Uri relative = resolveRelativeUri(uri, parseUriWithException("lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "package:lib.dart");
+    _assertResolve('package:test.dart', 'lib.dart', 'package:lib.dart');
   }
 
   void test_resolveRelative_package_filePath() {
-    Uri uri = parseUriWithException("package:b/test.dart");
-    Uri relative = resolveRelativeUri(uri, parseUriWithException("c/lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "package:b/c/lib.dart");
+    _assertResolve('package:b/test.dart', 'c/lib.dart', 'package:b/c/lib.dart');
   }
 
   void test_resolveRelative_package_filePathWithParent() {
-    Uri uri = parseUriWithException("package:a/b/test.dart");
-    Uri relative =
-        resolveRelativeUri(uri, parseUriWithException("../c/lib.dart"));
-    expect(relative, isNotNull);
-    expect(relative.toString(), "package:a/c/lib.dart");
+    _assertResolve(
+        'package:a/b/test.dart', '../c/lib.dart', 'package:a/c/lib.dart');
+  }
+
+  void _assertResolve(String baseStr, String containedStr, String expectedStr) {
+    Uri base = Uri.parse(baseStr);
+    Uri contained = Uri.parse(containedStr);
+    Uri result = resolveRelativeUri(base, contained);
+    expect(result, isNotNull);
+    expect(result.toString(), expectedStr);
   }
 }
 
+@deprecated
 @reflectiveTest
 class SDKLibrariesReaderTest extends EngineTestCase {
   void test_readFrom_dart2js() {
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index cca5d3b..dc8920b 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -10,15 +10,16 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
 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';
@@ -39,46 +40,60 @@
   static String _DART_JS_HELPER = "dart:_js_helper";
 
   /**
-   * Create an analysis context that has a fake core library already resolved.
-   * Return the context that was created.
+   * Create and return an analysis context that has a fake core library already
+   * resolved. The given [resourceProvider] will be used when accessing the file
+   * system.
    */
-  static InternalAnalysisContext contextWithCore() {
+  static InternalAnalysisContext contextWithCore(
+      {ResourceProvider resourceProvider}) {
     AnalysisContextForTests context = new AnalysisContextForTests();
-    return initContextWithCore(context);
+    return initContextWithCore(context, null, resourceProvider);
   }
 
   /**
-   * Create an analysis context that uses the given [options] and has a fake
-   * core library already resolved. Return the context that was created.
+   * Create and return an analysis context that uses the given [options] and has
+   * a fake core library already resolved. The given [resourceProvider] will be
+   * used when accessing the file system.
    */
   static InternalAnalysisContext contextWithCoreAndOptions(
-      AnalysisOptions options) {
+      AnalysisOptions options,
+      {ResourceProvider resourceProvider}) {
     AnalysisContextForTests context = new AnalysisContextForTests();
     context._internalSetAnalysisOptions(options);
-    return initContextWithCore(context);
-  }
-
-  static InternalAnalysisContext contextWithCoreAndPackages(
-      Map<String, String> packages) {
-    AnalysisContextForTests context = new AnalysisContextForTests();
-    return initContextWithCore(context, new TestPackageUriResolver(packages));
+    return initContextWithCore(context, null, resourceProvider);
   }
 
   /**
-   * Initialize the given analysis context with a fake core library already resolved.
-   *
-   * @param context the context to be initialized (not `null`)
-   * @return the analysis context that was created
+   * Create and return an analysis context that has a fake core library already
+   * resolved. If not `null`, the given [packages] map will be used to create a
+   * package URI resolver. The given [resourceProvider] will be used when
+   * accessing the file system.
+   */
+  static InternalAnalysisContext contextWithCoreAndPackages(
+      Map<String, String> packages,
+      {ResourceProvider resourceProvider}) {
+    AnalysisContextForTests context = new AnalysisContextForTests();
+    return initContextWithCore(
+        context, new TestPackageUriResolver(packages), resourceProvider);
+  }
+
+  /**
+   * Initialize the given analysis [context] with a fake core library that has
+   * already been resolved. If not `null`, the given [contributedResolver] will
+   * be added to the context's source factory. The given [resourceProvider] will
+   * be used when accessing the file system.
    */
   static InternalAnalysisContext initContextWithCore(
       InternalAnalysisContext context,
-      [UriResolver contributedResolver]) {
-    DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
-        new JavaFile("/fake/sdk"),
+      [UriResolver contributedResolver,
+      ResourceProvider resourceProvider]) {
+    resourceProvider ??= PhysicalResourceProvider.INSTANCE;
+    DartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
+        resourceProvider, '/fake/sdk',
         enableAsync: context.analysisOptions.enableAsync);
     List<UriResolver> resolvers = <UriResolver>[
       new DartUriResolver(sdk),
-      new FileUriResolver()
+      new ResourceUriResolver(resourceProvider)
     ];
     if (contributedResolver != null) {
       resolvers.add(contributedResolver);
@@ -97,6 +112,8 @@
     Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
     coreContext.setContents(coreSource, "");
     coreUnit.librarySource = coreUnit.source = coreSource;
+    ClassElementImpl overrideClassElement =
+        ElementFactory.classElement2("_Override");
     ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
     proxyClassElement.constructors = <ConstructorElement>[
       ElementFactory.constructorElement(proxyClassElement, '', true)
@@ -117,6 +134,7 @@
       provider.nullType.element,
       provider.numType.element,
       objectClassElement,
+      overrideClassElement,
       proxyClassElement,
       provider.stackTraceType.element,
       provider.stringType.element,
@@ -134,6 +152,9 @@
     ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt =
         ElementFactory.topLevelVariableElement3(
             "deprecated", true, false, provider.deprecatedType);
+    TopLevelVariableElement overrideTopLevelVariableElt =
+        ElementFactory.topLevelVariableElement3(
+            "override", true, false, overrideClassElement.type);
     {
       ClassElement deprecatedElement = provider.deprecatedType.element;
       InstanceCreationExpression initializer = AstFactory
@@ -147,12 +168,14 @@
       deprecatedTopLevelVariableElt.constantInitializer = initializer;
     }
     coreUnit.accessors = <PropertyAccessorElement>[
-      proxyTopLevelVariableElt.getter,
-      deprecatedTopLevelVariableElt.getter
+      deprecatedTopLevelVariableElt.getter,
+      overrideTopLevelVariableElt.getter,
+      proxyTopLevelVariableElt.getter
     ];
     coreUnit.topLevelVariables = <TopLevelVariableElement>[
-      proxyTopLevelVariableElt,
-      deprecatedTopLevelVariableElt
+      deprecatedTopLevelVariableElt,
+      overrideTopLevelVariableElt,
+      proxyTopLevelVariableElt
     ];
     LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
         coreContext, AstFactory.libraryIdentifier2(["dart", "core"]));
@@ -189,7 +212,10 @@
         futureThenR = ElementFactory.typeParameterWithType('R');
       }
       FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
-          'onValue', futureThenR, [futureElement.typeParameters[0]], null);
+          'onValue',
+          DynamicElementImpl.instance,
+          [futureElement.typeParameters[0]],
+          null);
       thenOnValue.synthetic = true;
 
       DartType futureRType = futureElement.type.instantiate([futureThenR.type]);
@@ -233,7 +259,9 @@
           <TypeDefiningElement>[streamElement.typeParameters[0]],
           null);
       listenOnData.synthetic = true;
-      List<DartType> parameterTypes = <DartType>[listenOnData.type,];
+      List<DartType> parameterTypes = <DartType>[
+        listenOnData.type,
+      ];
       // TODO(brianwilkerson) This is missing the optional parameters.
       MethodElementImpl listenMethod =
           ElementFactory.methodElement('listen', returnType, parameterTypes);
@@ -530,12 +558,12 @@
   Uri restoreAbsolute(Source source) => throw new UnimplementedError();
 }
 
-class _AnalysisContextFactory_initContextWithCore
-    extends DirectoryBasedDartSdk {
+class _AnalysisContextFactory_initContextWithCore extends FolderBasedDartSdk {
   final bool enableAsync;
-  _AnalysisContextFactory_initContextWithCore(JavaFile arg0,
+  _AnalysisContextFactory_initContextWithCore(
+      ResourceProvider resourceProvider, String sdkPath,
       {this.enableAsync: true})
-      : super(arg0);
+      : super(resourceProvider, resourceProvider.getFolder(sdkPath));
 
   @override
   LibraryMap initialLibraryMap(bool useDart2jsPaths) {
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 5bd95e5..f3e477a 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2244,6 +2244,18 @@
     verify([source]);
   }
 
+  void test_fieldInitializerOutsideConstructor_inFunctionTypeParameter() {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A(int p(this.x));
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
   void test_fieldInitializerRedirectingConstructor_afterRedirection() {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index da95f04..aaefc2a 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/src/generated/element_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_engine_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -301,6 +302,25 @@
     _listener.assertNoErrors();
   }
 
+  void test_visitCommentReference_prefixedIdentifier_class_operator() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    // set method
+    MethodElement method =
+        ElementFactory.methodElement("==", _typeProvider.boolType);
+    classA.methods = <MethodElement>[method];
+    // set name scope
+    _visitor.nameScope = new EnclosedScope(null)
+      ..defineNameWithoutChecking('A', classA);
+    // prepare "A.=="
+    PrefixedIdentifier prefixed = AstFactory.identifier5('A', '==');
+    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";
@@ -808,6 +828,9 @@
     subclass.constructors = <ConstructorElement>[subConstructor];
     SuperConstructorInvocation invocation =
         AstFactory.superConstructorInvocation();
+    AstFactory.classDeclaration(null, 'C', null, null, null, null, [
+      AstFactory.constructorDeclaration(null, 'C', null, [invocation])
+    ]);
     _resolveInClass(invocation, subclass);
     expect(invocation.staticElement, superConstructor);
     _listener.assertNoErrors();
@@ -830,6 +853,9 @@
         .superConstructorInvocation([
       AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
     ]);
+    AstFactory.classDeclaration(null, 'C', null, null, null, null, [
+      AstFactory.constructorDeclaration(null, 'C', null, [invocation])
+    ]);
     _resolveInClass(invocation, subclass);
     expect(invocation.staticElement, superConstructor);
     expect(
@@ -930,8 +956,9 @@
         _visitor.enclosingClass = null;
         _visitor.nameScope = outerScope;
       }
-    } catch (exception) {
-      throw new IllegalArgumentException("Could not resolve node", exception);
+    } catch (exception, stackTrace) {
+      throw new IllegalArgumentException(
+          "Could not resolve node", new CaughtException(exception, stackTrace));
     }
   }
 
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index b3ceaa5..92c7007 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -9,8 +9,8 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
+import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/context/source.dart';
@@ -225,6 +225,12 @@
   }
 
   @override
+  CacheConsistencyValidator get cacheConsistencyValidator {
+    fail("Unexpected invocation of cacheConsistencyValidator");
+    return null;
+  }
+
+  @override
   set contentCache(ContentCache value) {
     fail("Unexpected invocation of setContentCache");
   }
@@ -702,12 +708,6 @@
   }
 
   @override
-  bool validateCacheConsistency() {
-    fail("Unexpected invocation of validateCacheConsistency");
-    return false;
-  }
-
-  @override
   void visitContentCache(ContentCacheVisitor visitor) {
     fail("Unexpected invocation of visitContentCache");
   }
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 6644ccd..e14df67 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:unittest/unittest.dart';
 
@@ -21,54 +22,6 @@
 
 @reflectiveTest
 class HintCodeTest extends ResolverTestCase {
-  void fail_isInt() {
-    Source source = addSource("var v = 1 is int;");
-    computeLibrarySourceErrors(source);
-    assertErrors(source, [HintCode.IS_INT]);
-    verify([source]);
-  }
-
-  void fail_isNotInt() {
-    Source source = addSource("var v = 1 is! int;");
-    computeLibrarySourceErrors(source);
-    assertErrors(source, [HintCode.IS_NOT_INT]);
-    verify([source]);
-  }
-
-  void fail_overrideEqualsButNotHashCode() {
-    Source source = addSource(r'''
-class A {
-  bool operator ==(x) {}
-}''');
-    computeLibrarySourceErrors(source);
-    assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
-    verify([source]);
-  }
-
-  void fail_unusedImport_as_equalPrefixes() {
-    // See todo at ImportsVerifier.prefixElementMap.
-    Source source = addSource(r'''
-library L;
-import 'lib1.dart' as one;
-import 'lib2.dart' as one;
-one.A a;''');
-    Source source2 = addNamedSource(
-        "/lib1.dart",
-        r'''
-library lib1;
-class A {}''');
-    Source source3 = addNamedSource(
-        "/lib2.dart",
-        r'''
-library lib2;
-class B {}''');
-    computeLibrarySourceErrors(source);
-    assertErrors(source, [HintCode.UNUSED_IMPORT]);
-    assertNoErrors(source2);
-    assertNoErrors(source3);
-    verify([source, source2, source3]);
-  }
-
   @override
   void reset() {
     analysisContext2 = AnalysisContextFactory.contextWithCoreAndPackages({
@@ -78,7 +31,6 @@
 const _Factory factory = const _Factory();
 const _Literal literal = const _Literal();
 const _MustCallSuper mustCallSuper = const _MustCallSuper();
-const _Override override = const _Override();
 const _Protected protected = const _Protected();
 const Required required = const Required();
 class Required {
@@ -95,9 +47,6 @@
 class _MustCallSuper {
   const _MustCallSuper();
 }
-class _Override {
-  const _Override();
-}
 class _Protected {
   const _Protected();
 }
@@ -1359,21 +1308,6 @@
     verify([source, source2]);
   }
 
-  void test_invalidUseOfProtectedMember_function_OK2() {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-main() {
-  new A().a();
-}''');
-    computeLibrarySourceErrors(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   void test_invalidUseOfProtectedMember_function_OK() {
     Source source = addSource(r'''
 import 'package:meta/meta.dart';
@@ -1390,6 +1324,21 @@
     verify([source]);
   }
 
+  void test_invalidUseOfProtectedMember_function_OK2() {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void a(){ }
+}
+main() {
+  new A().a();
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_invalidUseOfProtectedMember_getter() {
     Source source = addNamedSource(
         '/lib1.dart',
@@ -1726,6 +1675,14 @@
     verify([source]);
   }
 
+  @failingTest
+  void test_isInt() {
+    Source source = addSource("var v = 1 is int;");
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.IS_INT]);
+    verify([source]);
+  }
+
   void test_isNotDouble() {
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.dart2jsHint = true;
@@ -1736,6 +1693,14 @@
     verify([source]);
   }
 
+  @failingTest
+  void test_isNotInt() {
+    Source source = addSource("var v = 1 is! int;");
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.IS_NOT_INT]);
+    verify([source]);
+  }
+
   void test_js_lib_OK() {
     Source source = addSource(r'''
 @JS()
@@ -1751,7 +1716,7 @@
     verify([source]);
   }
 
-  void test_missing_js_lib_on_class_decl() {
+  void test_missingJsLibAnnotation_class() {
     Source source = addSource(r'''
 library foo;
 
@@ -1765,7 +1730,21 @@
     verify([source]);
   }
 
-  void test_missing_js_lib_on_function() {
+  void test_missingJsLibAnnotation_externalField() {
+    // https://github.com/dart-lang/sdk/issues/26987
+    Source source = addSource(r'''
+import 'package:js/js.dart';
+
+@JS()
+external dynamic exports;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source,
+        [ParserErrorCode.EXTERNAL_FIELD, HintCode.MISSING_JS_LIB_ANNOTATION]);
+    verify([source]);
+  }
+
+  void test_missingJsLibAnnotation_function() {
     Source source = addSource(r'''
 library foo;
 
@@ -1779,7 +1758,7 @@
     verify([source]);
   }
 
-  void test_missing_js_lib_on_member() {
+  void test_missingJsLibAnnotation_method() {
     Source source = addSource(r'''
 library foo;
 
@@ -1795,6 +1774,18 @@
     verify([source]);
   }
 
+  void test_missingJsLibAnnotation_variable() {
+    Source source = addSource(r'''
+import 'package:js/js.dart';
+
+@JS()
+dynamic variable;
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.MISSING_JS_LIB_ANNOTATION]);
+    verify([source]);
+  }
+
   void test_missingReturn_async() {
     Source source = addSource('''
 import 'dart:async';
@@ -2047,10 +2038,32 @@
     verify([source]);
   }
 
+  @failingTest
+  void test_overrideEqualsButNotHashCode() {
+    Source source = addSource(r'''
+class A {
+  bool operator ==(x) {}
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
+    verify([source]);
+  }
+
+  void test_overrideOnNonOverridingField_invalid() {
+    Source source = addSource(r'''
+class A {
+}
+class B extends A {
+  @override
+  final int m = 1;
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD]);
+    verify([source]);
+  }
+
   void test_overrideOnNonOverridingGetter_invalid() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
 }
 class B extends A {
@@ -2064,8 +2077,6 @@
 
   void test_overrideOnNonOverridingMethod_invalid() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
 }
 class B extends A {
@@ -2079,8 +2090,6 @@
 
   void test_overrideOnNonOverridingSetter_invalid() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
 }
 class B extends A {
@@ -3496,6 +3505,31 @@
     verify([source, source2]);
   }
 
+  @failingTest
+  void test_unusedImport_as_equalPrefixes() {
+    // See todo at ImportsVerifier.prefixElementMap.
+    Source source = addSource(r'''
+library L;
+import 'lib1.dart' as one;
+import 'lib2.dart' as one;
+one.A a;''');
+    Source source2 = addNamedSource(
+        "/lib1.dart",
+        r'''
+library lib1;
+class A {}''');
+    Source source3 = addNamedSource(
+        "/lib2.dart",
+        r'''
+library lib2;
+class B {}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.UNUSED_IMPORT]);
+    assertNoErrors(source2);
+    assertNoErrors(source3);
+    verify([source, source2, source3]);
+  }
+
   void test_unusedImport_hide() {
     Source source = addSource(r'''
 library L;
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index f0b0107..10c227e 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -520,6 +520,19 @@
   CompilationUnit oldUnit;
   CompilationUnitElement oldUnitElement;
 
+  void assertSameReferencedNames(
+      ReferencedNames incNames, ReferencedNames fullNames) {
+    expectEqualSets(Iterable actual, Iterable expected) {
+      expect(actual, unorderedEquals(expected));
+    }
+    expectEqualSets(incNames.names, fullNames.names);
+    expectEqualSets(incNames.instantiatedNames, fullNames.instantiatedNames);
+    expectEqualSets(incNames.superToSubs.keys, fullNames.superToSubs.keys);
+    for (String key in fullNames.superToSubs.keys) {
+      expectEqualSets(incNames.superToSubs[key], fullNames.superToSubs[key]);
+    }
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -565,6 +578,22 @@
 ''');
   }
 
+  void test_dartDoc_beforeTopLevelVariable() {
+    _resolveUnit(r'''
+/**
+ * Variables [V1] and [V2] of type [int].
+ */
+int V1, V2;
+''');
+    _updateAndValidate(r'''
+/**
+ * Variables [V1] and [V2] of type [int].
+ * Updated, with a reference to the [String] type.
+ */
+int V1, V2;
+''');
+  }
+
   void test_dartDoc_clumsy_addReference() {
     _resolveUnit(r'''
 /**
@@ -1300,6 +1329,25 @@
     }
   }
 
+  void test_strongMode_typeComments_insertWhitespace() {
+    _resolveUnit(r'''
+import 'dart:async';
+
+void fadeIn(int milliseconds) {
+  Future<String> f;
+  f.then/*<String>*/((e) {print("hello");});
+}
+''');
+    _updateAndValidate(r'''
+import 'dart:async';
+
+void fadeIn(int milliseconds) {
+  Future<String> f;
+  f.then/*<String>*/((e) {print("hello") ;});
+}
+''');
+  }
+
   void test_true_emptyLine_betweenClassMembers_insert() {
     _resolveUnit(r'''
 class A {
@@ -1316,6 +1364,24 @@
 ''');
   }
 
+  void test_true_emptyLine_betweenClassMembers_insert_beforeComment() {
+    _resolveUnit(r'''
+class A {
+  a() {}
+  /// BBB
+  b() {}
+}
+''');
+    _updateAndValidate(r'''
+class A {
+  a() {}
+
+  /// BBB
+  b() {}
+}
+''');
+  }
+
   void test_true_emptyLine_betweenClassMembers_remove() {
     _resolveUnit(r'''
 class A {
@@ -1332,7 +1398,25 @@
 ''');
   }
 
-  void test_true_emptyLine_betweenCompilationUnitMembers_insert() {
+  void test_true_emptyLine_betweenClassMembers_remove_beforeComment() {
+    _resolveUnit(r'''
+class A {
+  a() {}
+
+  /// BBB
+  b() {}
+}
+''');
+    _updateAndValidate(r'''
+class A {
+  a() {}
+  /// BBB
+  b() {}
+}
+''');
+  }
+
+  void test_true_emptyLine_betweenUnitMembers_insert() {
     _resolveUnit(r'''
 a() {}
 b() {}
@@ -1344,7 +1428,23 @@
 ''');
   }
 
-  void test_true_emptyLine_betweenCompilationUnitMembers_remove() {
+  void test_true_emptyLine_betweenUnitMembers_insert_beforeComment() {
+    _resolveUnit(r'''
+a() {}
+
+// BBB
+b() {}
+''');
+    _updateAndValidate(r'''
+a() {}
+
+
+// BBB
+b() {}
+''');
+  }
+
+  void test_true_emptyLine_betweenUnitMembers_remove() {
     _resolveUnit(r'''
 a() {
   print(1)
@@ -1366,6 +1466,20 @@
 ''');
   }
 
+  void test_true_emptyLine_betweenUnitMembers_remove_beforeComment() {
+    _resolveUnit(r'''
+a() {}
+
+// BBB
+b() {}
+''');
+    _updateAndValidate(r'''
+a() {}
+// BBB
+b() {}
+''');
+  }
+
   void test_true_todoHint() {
     _resolveUnit(r'''
 main() {
@@ -1870,6 +1984,7 @@
    */
   void _resetWithIncremental(bool enable) {
     AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
+    analysisOptions.strongMode = true;
     analysisOptions.incremental = enable;
     analysisOptions.incrementalApi = enable;
     logging.logger = logger;
@@ -1909,6 +2024,8 @@
     logger.expectNoErrors();
     List<AnalysisError> newErrors = analysisContext.computeErrors(source);
     LineInfo newLineInfo = analysisContext.getLineInfo(source);
+    ReferencedNames newReferencedNames =
+        analysisContext.getResult(source, REFERENCED_NAMES);
     // check for expected failure
     if (!expectedSuccess) {
       expect(newUnit.element, isNot(same(oldUnitElement)));
@@ -1941,6 +2058,10 @@
       _assertEqualTokens(newUnit, fullNewUnit);
       // Validate LineInfo
       _assertEqualLineInfo(newLineInfo, analysisContext.getLineInfo(source));
+      // Validate referenced names.
+      ReferencedNames fullReferencedNames =
+          analysisContext.getResult(source, REFERENCED_NAMES);
+      assertSameReferencedNames(newReferencedNames, fullReferencedNames);
       // Validate that "incremental" and "full" units have the same resolution.
       try {
         assertSameResolution(newUnit, fullNewUnit, validateTypes: true);
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 1be8c5b..6156487 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -5770,6 +5770,17 @@
     verify([source]);
   }
 
+  void test_unusedShownName_unresolved() {
+    Source source = addSource(r'''
+import 'dart:math' show max, FooBar;
+main() {
+  print(max(1, 2));
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.UNDEFINED_SHOWN_NAME]);
+  }
+
   void test_uriDoesNotExist_dll() {
     addNamedSource("/lib.dll", "");
     Source source = addSource("import 'dart-ext:lib';");
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index 13abb03..16ba3a9 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -155,6 +155,26 @@
     verify([source]);
   }
 
+  void test_deadCode_deadFinalBreakInCase() {
+    Source source = addSource(r'''
+f() {
+  switch (true) {
+  case true:
+    try {
+      int a = 1;
+    } finally {
+      return;
+    }
+    break;
+  default:
+    break;
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_deadCode_deadOperandLHS_and_debugConst() {
     Source source = addSource(r'''
 const bool DEBUG = false;
@@ -190,26 +210,6 @@
     verify([source]);
   }
 
-  void test_deadCode_deadFinalBreakInCase() {
-    Source source = addSource(r'''
-f() {
-  switch (true) {
-  case true:
-    try {
-      int a = 1;
-    } finally {
-      return;
-    }
-    break;
-  default:
-    break;
-  }
-}''');
-    computeLibrarySourceErrors(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   void test_deprecatedMemberUse_inDeprecatedClass() {
     Source source = addSource(r'''
 @deprecated
@@ -486,10 +486,48 @@
     verify([source]);
   }
 
+  void test_overrideOnNonOverridingField_inInterface() {
+    Source source = addSource(r'''
+class A {
+  int get a => 0;
+  void set b(_) {}
+  int c;
+}
+class B implements A {
+  @override
+  final int a = 1;
+  @override
+  int b;
+  @override
+  int c;
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_overrideOnNonOverridingField_inSuperclass() {
+    Source source = addSource(r'''
+class A {
+  int get a => 0;
+  void set b(_) {}
+  int c;
+}
+class B extends A {
+  @override
+  final int a = 1;
+  @override
+  int b;
+  @override
+  int c;
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_overrideOnNonOverridingGetter_inInterface() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
   int get m => 0;
 }
@@ -504,8 +542,6 @@
 
   void test_overrideOnNonOverridingGetter_inSuperclass() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
   int get m => 0;
 }
@@ -520,8 +556,6 @@
 
   void test_overrideOnNonOverridingMethod_inInterface() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
   int m() => 0;
 }
@@ -536,8 +570,6 @@
 
   void test_overrideOnNonOverridingMethod_inSuperclass() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
   int m() => 0;
 }
@@ -550,10 +582,22 @@
     verify([source]);
   }
 
+  void test_overrideOnNonOverridingMethod_inSuperclass_abstract() {
+    Source source = addSource(r'''
+abstract class A {
+  int m();
+}
+class B extends A {
+  @override
+  int m() => 1;
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_overrideOnNonOverridingSetter_inInterface() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
   set m(int x) {}
 }
@@ -568,8 +612,6 @@
 
   void test_overrideOnNonOverridingSetter_inSuperclass() {
     Source source = addSource(r'''
-library dart.core;
-const override = null;
 class A {
   set m(int x) {}
 }
diff --git a/pkg/analyzer/test/generated/package_test.dart b/pkg/analyzer/test/generated/package_test.dart
new file mode 100644
index 0000000..dadb9fc
--- /dev/null
+++ b/pkg/analyzer/test/generated/package_test.dart
@@ -0,0 +1,294 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.package_test;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/package.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:package_config/packages.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../src/context/mock_sdk.dart';
+import '../utils.dart';
+import 'resolver_test_case.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(DependencyFinderTest);
+  runReflectiveTests(PackageDescriptionTest);
+  runReflectiveTests(PackageManagerTest);
+}
+
+/**
+ * The name of the pubspec.yaml file.
+ */
+const String pubspecName = 'pubspec.yaml';
+
+@reflectiveTest
+class DependencyFinderTest extends ResolverTestCase {
+  /**
+   * The resource provider to be used by tests.
+   */
+  MemoryResourceProvider resourceProvider;
+
+  @override
+  void setUp() {
+    resourceProvider = new MemoryResourceProvider();
+  }
+
+  void test_transitiveDependenciesFor_circularDependencies() {
+    String packageA = '/pub-cache/a-1.0';
+    String packageB = '/pub-cache/b-1.0';
+    String packageC = '/pub-cache/c-1.0';
+    resourceProvider.newFile(
+        '$packageA/$pubspecName',
+        '''
+    dependencies:
+      b: any
+    ''');
+    resourceProvider.newFile(
+        '$packageB/$pubspecName',
+        '''
+    dependencies:
+      c: any
+    ''');
+    resourceProvider.newFile(
+        '$packageC/$pubspecName',
+        '''
+    dependencies:
+      a: any
+    ''');
+    Map<String, List<Folder>> packageMap = <String, List<Folder>>{
+      'a': <Folder>[resourceProvider.getFolder(packageA)],
+      'b': <Folder>[resourceProvider.getFolder(packageB)],
+      'c': <Folder>[resourceProvider.getFolder(packageC)],
+    };
+
+    DependencyFinder finder = new DependencyFinder(resourceProvider);
+    List<String> result =
+        finder.transitiveDependenciesFor(packageMap, packageA);
+    expect(result, unorderedEquals([packageB, packageC]));
+  }
+
+  void test_transitiveDependenciesFor_missingPubspec() {
+    String packagePath = '/pub-cache/a-1.0';
+    Map<String, List<Folder>> packageMap = <String, List<Folder>>{
+      'a': <Folder>[resourceProvider.getFolder(packagePath)]
+    };
+
+    DependencyFinder finder = new DependencyFinder(resourceProvider);
+    expect(() => finder.transitiveDependenciesFor(packageMap, packagePath),
+        throws);
+  }
+
+  void test_transitiveDependenciesFor_noDependencies() {
+    String packagePath = '/pub-cache/a-1.0';
+    resourceProvider.newFile('$packagePath/$pubspecName', '');
+    Map<String, List<Folder>> packageMap = <String, List<Folder>>{
+      'a': <Folder>[resourceProvider.getFolder(packagePath)]
+    };
+
+    DependencyFinder finder = new DependencyFinder(resourceProvider);
+    List<String> result =
+        finder.transitiveDependenciesFor(packageMap, packagePath);
+    expect(result, hasLength(0));
+  }
+
+  void test_transitiveDependenciesFor_overlappingDependencies() {
+    String packageA = '/pub-cache/a-1.0';
+    String packageB = '/pub-cache/b-1.0';
+    String packageC = '/pub-cache/c-1.0';
+    String packageD = '/pub-cache/d-1.0';
+    resourceProvider.newFile(
+        '$packageA/$pubspecName',
+        '''
+    dependencies:
+      b: any
+      c: any
+    ''');
+    resourceProvider.newFile(
+        '$packageB/$pubspecName',
+        '''
+    dependencies:
+      d: any
+    ''');
+    resourceProvider.newFile(
+        '$packageC/$pubspecName',
+        '''
+    dependencies:
+      d: any
+    ''');
+    resourceProvider.newFile('$packageD/$pubspecName', '');
+    Map<String, List<Folder>> packageMap = <String, List<Folder>>{
+      'a': <Folder>[resourceProvider.getFolder(packageA)],
+      'b': <Folder>[resourceProvider.getFolder(packageB)],
+      'c': <Folder>[resourceProvider.getFolder(packageC)],
+      'd': <Folder>[resourceProvider.getFolder(packageD)],
+    };
+
+    DependencyFinder finder = new DependencyFinder(resourceProvider);
+    List<String> result =
+        finder.transitiveDependenciesFor(packageMap, packageA);
+    expect(result, unorderedEquals([packageB, packageC, packageD]));
+  }
+
+  void test_transitiveDependenciesFor_simpleDependencies() {
+    String packageA = '/pub-cache/a-1.0';
+    String packageB = '/pub-cache/b-1.0';
+    String packageC = '/pub-cache/c-1.0';
+    resourceProvider.newFile(
+        '$packageA/$pubspecName',
+        '''
+    dependencies:
+      b: any
+      c: any
+    ''');
+    resourceProvider.newFile('$packageB/$pubspecName', '');
+    resourceProvider.newFile('$packageC/$pubspecName', '');
+    Map<String, List<Folder>> packageMap = <String, List<Folder>>{
+      'a': <Folder>[resourceProvider.getFolder(packageA)],
+      'b': <Folder>[resourceProvider.getFolder(packageB)],
+      'c': <Folder>[resourceProvider.getFolder(packageC)],
+    };
+
+    DependencyFinder finder = new DependencyFinder(resourceProvider);
+    List<String> result =
+        finder.transitiveDependenciesFor(packageMap, packageA);
+    expect(result, unorderedEquals([packageB, packageC]));
+  }
+}
+
+@reflectiveTest
+class PackageDescriptionTest extends ResolverTestCase {
+  void test_equal_false_differentOptions() {
+    String packageId = 'path1;path2';
+    DartSdk sdk = new MockSdk();
+    AnalysisOptionsImpl options1 = new AnalysisOptionsImpl();
+    AnalysisOptionsImpl options2 = new AnalysisOptionsImpl();
+    options2.enableAsync = !options1.enableAsync;
+    PackageDescription first = new PackageDescription(packageId, sdk, options1);
+    PackageDescription second =
+        new PackageDescription(packageId, sdk, options2);
+    expect(first == second, isFalse);
+  }
+
+  void test_equal_false_differentPaths() {
+    String packageId1 = 'path1;path2';
+    String packageId2 = 'path1;path3';
+    DartSdk sdk = new MockSdk();
+    AnalysisOptions options = new AnalysisOptionsImpl();
+    PackageDescription first = new PackageDescription(packageId1, sdk, options);
+    PackageDescription second =
+        new PackageDescription(packageId2, sdk, options);
+    expect(first == second, isFalse);
+  }
+
+  void test_equal_false_differentSdks() {
+    String packageId = 'path1;path2';
+    DartSdk sdk1 = new MockSdk();
+    DartSdk sdk2 = new MockSdk();
+    AnalysisOptions options = new AnalysisOptionsImpl();
+    PackageDescription first = new PackageDescription(packageId, sdk1, options);
+    PackageDescription second =
+        new PackageDescription(packageId, sdk2, options);
+    expect(first == second, isFalse);
+  }
+
+  void test_equal_true() {
+    String packageId = 'path1;path2';
+    DartSdk sdk = new MockSdk();
+    AnalysisOptions options = new AnalysisOptionsImpl();
+    PackageDescription first = new PackageDescription(packageId, sdk, options);
+    PackageDescription second = new PackageDescription(packageId, sdk, options);
+    expect(first == second, isTrue);
+  }
+}
+
+@reflectiveTest
+class PackageManagerTest extends ResolverTestCase {
+  /**
+   * The resource provider to be used by tests.
+   */
+  MemoryResourceProvider resourceProvider;
+
+  @override
+  void setUp() {
+    resourceProvider = new MemoryResourceProvider();
+  }
+
+  void test_getContext() {
+    String packageA = '/pub-cache/a-1.0';
+    String packageB1 = '/pub-cache/b-1.0';
+    String packageB2 = '/pub-cache/b-2.0';
+    String packageC = '/pub-cache/c-1.0';
+    resourceProvider.newFile(
+        '$packageA/$pubspecName',
+        '''
+    dependencies:
+      b: any
+      c: any
+    ''');
+    resourceProvider.newFile('$packageB1/$pubspecName', '');
+    resourceProvider.newFile('$packageB2/$pubspecName', '');
+    resourceProvider.newFile('$packageC/$pubspecName', '');
+
+    Packages packages1 = new _MockPackages(<String, Uri>{
+      'a': new Uri.file(packageA),
+      'b': new Uri.file(packageB1),
+      'c': new Uri.file(packageC),
+    });
+    DartUriResolver resolver = new DartUriResolver(new MockSdk());
+    AnalysisOptions options = new AnalysisOptionsImpl();
+    //
+    // Verify that we can compute a context for a package.
+    //
+    PackageManager manager = new PackageManager(resourceProvider);
+    AnalysisContext context1 =
+        manager.getContext(packageA, packages1, resolver, options);
+    expect(context1, isNotNull);
+    //
+    // Verify that if we have the same package map we get the same context.
+    //
+    AnalysisContext context2 =
+        manager.getContext(packageA, packages1, resolver, options);
+    expect(context2, same(context1));
+    //
+    // Verify that if we have a different package map we get a different context.
+    //
+    Packages packages3 = new _MockPackages(<String, Uri>{
+      'a': new Uri.file(packageA),
+      'b': new Uri.file(packageB2),
+      'c': new Uri.file(packageC),
+    });
+    AnalysisContext context3 =
+        manager.getContext(packageA, packages3, resolver, options);
+    expect(context3, isNot(same(context1)));
+  }
+}
+
+/**
+ * An implementation of [Packages] used for testing.
+ */
+class _MockPackages implements Packages {
+  final Map<String, Uri> map;
+
+  _MockPackages(this.map);
+
+  @override
+  Iterable<String> get packages => map.keys;
+
+  @override
+  Map<String, Uri> asMap() => map;
+
+  @override
+  Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
+    fail('Unexpected invocation of resolve');
+    return null;
+  }
+}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 58c7c6f..1d3577e 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -717,26 +717,6 @@
         [ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT]);
   }
 
-  void test_assertDoesNotTakeAssignment() {
-    parse4("parseAssertStatement", "assert(b = true);",
-        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT]);
-  }
-
-  void test_assertDoesNotTakeCascades() {
-    parse4("parseAssertStatement", "assert(new A()..m());",
-        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE]);
-  }
-
-  void test_assertDoesNotTakeRethrow() {
-    parse4("parseAssertStatement", "assert(rethrow);",
-        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW]);
-  }
-
-  void test_assertDoesNotTakeThrow() {
-    parse4("parseAssertStatement", "assert(throw x);",
-        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW]);
-  }
-
   void test_breakOutsideOfLoop_breakInDoStatement() {
     parse4("parseDoStatement", "do {break;} while (x);");
   }
@@ -1217,21 +1197,11 @@
   }
 
   void test_extraCommaInParameterList() {
-    parseTrailingCommas = true;
-    parse4("parseFormalParameterList", "(int a, , int b)",
-        [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
-    parseTrailingCommas = false;
     parse4("parseFormalParameterList", "(int a, , int b)",
         [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_extraCommaTrailingNamedParameterGroup() {
-    parseTrailingCommas = true;
-    parse4("parseFormalParameterList", "({int b},)", [
-      ParserErrorCode.MISSING_IDENTIFIER,
-      ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
-    ]);
-    parseTrailingCommas = false;
     parse4("parseFormalParameterList", "({int b},)", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
@@ -1239,12 +1209,6 @@
   }
 
   void test_extraCommaTrailingPositionalParameterGroup() {
-    parseTrailingCommas = true;
-    parse4("parseFormalParameterList", "([int b],)", [
-      ParserErrorCode.MISSING_IDENTIFIER,
-      ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
-    ]);
-    parseTrailingCommas = false;
     parse4("parseFormalParameterList", "([int b],)", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
@@ -1252,12 +1216,8 @@
   }
 
   void test_extraTrailingCommaInParameterList() {
-    parseTrailingCommas = true;
     parse4("parseFormalParameterList", "(a,,)",
         [ParserErrorCode.MISSING_IDENTIFIER]);
-    parseTrailingCommas = false;
-    parse4("parseFormalParameterList", "(a,,)",
-        [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_factoryTopLevelDeclaration_class() {
@@ -1760,7 +1720,6 @@
   }
 
   void test_missingIdentifierForParameterGroup() {
-    parseTrailingCommas = true;
     parse4("parseFormalParameterList", "(,)",
         [ParserErrorCode.MISSING_IDENTIFIER]);
   }
@@ -2827,10 +2786,10 @@
   bool enableGenericMethodComments = false;
 
   /**
-   * A flag indicating whether parsing trailing commas in parameter and argument
-   * lists should be enabled for this test.
+   * A flag indicating whether lazy assignment operators should be enabled for
+   * the test.
    */
-  bool parseTrailingCommas = false;
+  bool enableLazyAssignmentOperators = false;
 
   /**
    * Return a CommentAndMetadata object with the given values that can be used for testing.
@@ -2876,6 +2835,7 @@
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
     scanner.scanGenericMethodComments = enableGenericMethodComments;
+    scanner.scanLazyAssignmentOperators = enableLazyAssignmentOperators;
     Token tokenStream = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     //
@@ -2886,7 +2846,6 @@
     parser.parseGenericMethods = enableGenericMethods;
     parser.parseGenericMethodComments = enableGenericMethodComments;
     parser.parseFunctionBodies = parseFunctionBodies;
-    parser.parseTrailingCommas = parseTrailingCommas;
     Object result =
         invokeParserMethodImpl(parser, methodName, objects, tokenStream);
     //
@@ -3088,19 +3047,18 @@
   }
 
   /**
-   * Parse the given source as a statement.
-   *
-   * @param source the source to be parsed
-   * @param errorCodes the error codes of the errors that are expected to be found
-   * @return the statement that was parsed
-   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
-   *           not match those that are expected, or if the result would have been `null`
+   * Parse the given [source] as a statement. The [errorCodes] are the error
+   * codes of the errors that are expected to be found. If
+   * [enableLazyAssignmentOperators] is `true`, then lazy assignment operators
+   * should be enabled.
    */
   static Statement parseStatement(String source,
-      [List<ErrorCode> errorCodes = ErrorCode.EMPTY_LIST]) {
+      [List<ErrorCode> errorCodes = ErrorCode.EMPTY_LIST,
+      bool enableLazyAssignmentOperators]) {
     GatheringErrorListener listener = new GatheringErrorListener();
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
+    scanner.scanLazyAssignmentOperators = enableLazyAssignmentOperators;
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = createParser(listener);
@@ -4813,7 +4771,6 @@
   }
 
   void test_parseArgumentList_trailing_comma() {
-    parseTrailingCommas = true;
     ArgumentList argumentList = parse4("parseArgumentList", "(x, y, z,)");
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(3));
@@ -6002,7 +5959,6 @@
   }
 
   void test_parseClassMember_method_trailing_commas() {
-    parseTrailingCommas = true;
     MethodDeclaration method =
         parse("parseClassMember", <Object>["C"], "void f(int x, int y,) {}");
     expect(method.documentationComment, isNull);
@@ -6301,6 +6257,66 @@
     expect(identifier.offset, 9);
   }
 
+  void test_parseCommentReference_operator_withKeyword_notPrefixed() {
+    CommentReference reference =
+        parse("parseCommentReference", <Object>["operator ==", 5], "");
+    SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
+        (obj) => obj is SimpleIdentifier,
+        SimpleIdentifier,
+        reference.identifier);
+    expect(identifier.token, isNotNull);
+    expect(identifier.name, "==");
+    expect(identifier.offset, 14);
+  }
+
+  void test_parseCommentReference_operator_withKeyword_prefixed() {
+    CommentReference reference =
+        parse("parseCommentReference", <Object>["Object.operator==", 7], "");
+    PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(
+        (obj) => obj is PrefixedIdentifier,
+        PrefixedIdentifier,
+        reference.identifier);
+    SimpleIdentifier prefix = prefixedIdentifier.prefix;
+    expect(prefix.token, isNotNull);
+    expect(prefix.name, "Object");
+    expect(prefix.offset, 7);
+    expect(prefixedIdentifier.period, isNotNull);
+    SimpleIdentifier identifier = prefixedIdentifier.identifier;
+    expect(identifier.token, isNotNull);
+    expect(identifier.name, "==");
+    expect(identifier.offset, 22);
+  }
+
+  void test_parseCommentReference_operator_withoutKeyword_notPrefixed() {
+    CommentReference reference =
+        parse("parseCommentReference", <Object>["==", 5], "");
+    SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
+        (obj) => obj is SimpleIdentifier,
+        SimpleIdentifier,
+        reference.identifier);
+    expect(identifier.token, isNotNull);
+    expect(identifier.name, "==");
+    expect(identifier.offset, 5);
+  }
+
+  void test_parseCommentReference_operator_withoutKeyword_prefixed() {
+    CommentReference reference =
+        parse("parseCommentReference", <Object>["Object.==", 7], "");
+    PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(
+        (obj) => obj is PrefixedIdentifier,
+        PrefixedIdentifier,
+        reference.identifier);
+    SimpleIdentifier prefix = prefixedIdentifier.prefix;
+    expect(prefix.token, isNotNull);
+    expect(prefix.name, "Object");
+    expect(prefix.offset, 7);
+    expect(prefixedIdentifier.period, isNotNull);
+    SimpleIdentifier identifier = prefixedIdentifier.identifier;
+    expect(identifier.token, isNotNull);
+    expect(identifier.name, "==");
+    expect(identifier.offset, 14);
+  }
+
   void test_parseCommentReference_prefixed() {
     CommentReference reference =
         parse("parseCommentReference", <Object>["a.b", 7], "");
@@ -7442,6 +7458,15 @@
     expect(expression.rightHandSide, isNotNull);
   }
 
+  void test_parseExpression_assign_compound() {
+    enableLazyAssignmentOperators = true;
+    AssignmentExpression expression = parse4("parseExpression", "x ||= y");
+    expect(expression.leftHandSide, isNotNull);
+    expect(expression.operator, isNotNull);
+    expect(expression.operator.type, TokenType.BAR_BAR_EQ);
+    expect(expression.rightHandSide, isNotNull);
+  }
+
   void test_parseExpression_comparison() {
     BinaryExpression expression = parse4("parseExpression", "--a.b == c");
     expect(expression.leftOperand, isNotNull);
@@ -7859,7 +7884,6 @@
   }
 
   void test_parseFormalParameterList_named_trailing_comma() {
-    parseTrailingCommas = true;
     FormalParameterList parameterList =
         parse4("parseFormalParameterList", "(A a, {B b,})");
     expect(parameterList.leftParenthesis, isNotNull);
@@ -7910,7 +7934,6 @@
   }
 
   void test_parseFormalParameterList_normal_single_trailing_comma() {
-    parseTrailingCommas = true;
     FormalParameterList parameterList =
         parse4("parseFormalParameterList", "(A a,)");
     expect(parameterList.leftParenthesis, isNotNull);
@@ -7941,7 +7964,6 @@
   }
 
   void test_parseFormalParameterList_positional_trailing_comma() {
-    parseTrailingCommas = true;
     FormalParameterList parameterList =
         parse4("parseFormalParameterList", "(A a, [B b,])");
     expect(parameterList.leftParenthesis, isNotNull);
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 071231e..cb75945 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -192,6 +192,11 @@
     _assertToken(TokenType.AMPERSAND_AMPERSAND, "&&");
   }
 
+  void test_ampersand_ampersand_eq() {
+    _assertToken(TokenType.AMPERSAND_AMPERSAND_EQ, "&&=",
+        lazyAssignmentOperators: true);
+  }
+
   void test_ampersand_eq() {
     _assertToken(TokenType.AMPERSAND_EQ, "&=");
   }
@@ -224,6 +229,10 @@
     _assertToken(TokenType.BAR_BAR, "||");
   }
 
+  void test_bar_bar_eq() {
+    _assertToken(TokenType.BAR_BAR_EQ, "||=", lazyAssignmentOperators: true);
+  }
+
   void test_bar_eq() {
     _assertToken(TokenType.BAR_EQ, "|=");
   }
@@ -1177,8 +1186,10 @@
    * Assert that the token scanned from the given [source] has the
    * [expectedType].
    */
-  Token _assertToken(TokenType expectedType, String source) {
-    Token originalToken = _scan(source);
+  Token _assertToken(TokenType expectedType, String source,
+      {bool lazyAssignmentOperators: false}) {
+    Token originalToken =
+        _scan(source, lazyAssignmentOperators: lazyAssignmentOperators);
     expect(originalToken, isNotNull);
     expect(originalToken.type, expectedType);
     expect(originalToken.offset, 0);
@@ -1190,7 +1201,8 @@
       return originalToken;
     } else if (expectedType == TokenType.SINGLE_LINE_COMMENT) {
       // Adding space to an end-of-line comment changes the comment.
-      Token tokenWithSpaces = _scan(" $source");
+      Token tokenWithSpaces =
+          _scan(" $source", lazyAssignmentOperators: lazyAssignmentOperators);
       expect(tokenWithSpaces, isNotNull);
       expect(tokenWithSpaces.type, expectedType);
       expect(tokenWithSpaces.offset, 1);
@@ -1199,20 +1211,23 @@
       return originalToken;
     } else if (expectedType == TokenType.INT ||
         expectedType == TokenType.DOUBLE) {
-      Token tokenWithLowerD = _scan("${source}d");
+      Token tokenWithLowerD =
+          _scan("${source}d", lazyAssignmentOperators: lazyAssignmentOperators);
       expect(tokenWithLowerD, isNotNull);
       expect(tokenWithLowerD.type, expectedType);
       expect(tokenWithLowerD.offset, 0);
       expect(tokenWithLowerD.length, source.length);
       expect(tokenWithLowerD.lexeme, source);
-      Token tokenWithUpperD = _scan("${source}D");
+      Token tokenWithUpperD =
+          _scan("${source}D", lazyAssignmentOperators: lazyAssignmentOperators);
       expect(tokenWithUpperD, isNotNull);
       expect(tokenWithUpperD.type, expectedType);
       expect(tokenWithUpperD.offset, 0);
       expect(tokenWithUpperD.length, source.length);
       expect(tokenWithUpperD.lexeme, source);
     }
-    Token tokenWithSpaces = _scan(" $source ");
+    Token tokenWithSpaces =
+        _scan(" $source ", lazyAssignmentOperators: lazyAssignmentOperators);
     expect(tokenWithSpaces, isNotNull);
     expect(tokenWithSpaces.type, expectedType);
     expect(tokenWithSpaces.offset, 1);
@@ -1249,21 +1264,24 @@
     expect(token.type, TokenType.EOF);
   }
 
-  Token _scan(String source, {bool genericMethodComments: false}) {
+  Token _scan(String source,
+      {bool genericMethodComments: false,
+      bool lazyAssignmentOperators: false}) {
     GatheringErrorListener listener = new GatheringErrorListener();
     Token token = _scanWithListener(source, listener,
-        genericMethodComments: genericMethodComments);
+        genericMethodComments: genericMethodComments,
+        lazyAssignmentOperators: lazyAssignmentOperators);
     listener.assertNoErrors();
     return token;
   }
 
   Token _scanWithListener(String source, GatheringErrorListener listener,
-      {bool genericMethodComments: false}) {
+      {bool genericMethodComments: false,
+      bool lazyAssignmentOperators: false}) {
     Scanner scanner =
         new Scanner(null, new CharSequenceReader(source), listener);
-    if (genericMethodComments) {
-      scanner.scanGenericMethodComments = true;
-    }
+    scanner.scanGenericMethodComments = genericMethodComments;
+    scanner.scanLazyAssignmentOperators = lazyAssignmentOperators;
     Token result = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     return result;
diff --git a/pkg/analyzer/test/generated/sdk_test.dart b/pkg/analyzer/test/generated/sdk_test.dart
index 8976b9c..ab634cb 100644
--- a/pkg/analyzer/test/generated/sdk_test.dart
+++ b/pkg/analyzer/test/generated/sdk_test.dart
@@ -4,14 +4,8 @@
 
 library analyzer.test.generated.sdk_test;
 
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
@@ -72,7 +66,7 @@
     return null;
   }
 
-  DartSdk _failIfCreated(_) {
+  DartSdk _failIfCreated(AnalysisOptions _) {
     fail('Use of sdkCreator');
     return null;
   }
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index fcd3a5f..dedab71 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -26,59 +26,6 @@
 
 @reflectiveTest
 class SimpleResolverTest extends ResolverTestCase {
-  void fail_getter_and_setter_fromMixins_property_access() {
-    // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
-    // a SimpleIdentifier that's inside a property access.  This bug should be
-    // fixed.
-    Source source = addSource('''
-class B {}
-class M1 {
-  get x => null;
-  set x(value) {}
-}
-class M2 {
-  get x => null;
-  set x(value) {}
-}
-class C extends B with M1, M2 {}
-void main() {
-  new C().x += 1;
-}
-''');
-    LibraryElement library = resolve2(source);
-    assertNoErrors(source);
-    verify([source]);
-    // Verify that both the getter and setter for "x" in "new C().x" refer to
-    // the accessors defined in M2.
-    FunctionDeclaration main =
-        library.definingCompilationUnit.functions[0].computeNode();
-    BlockFunctionBody body = main.functionExpression.body;
-    ExpressionStatement stmt = body.block.statements[0];
-    AssignmentExpression assignment = stmt.expression;
-    PropertyAccess propertyAccess = assignment.leftHandSide;
-    expect(
-        propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
-    expect(
-        propertyAccess
-            .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
-        'M2');
-  }
-
-  void fail_staticInvocation() {
-    Source source = addSource(r'''
-class A {
-  static int get g => (a,b) => 0;
-}
-class B {
-  f() {
-    A.g(1,0);
-  }
-}''');
-    computeLibrarySourceErrors(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   void test_argumentResolution_required_matching() {
     Source source = addSource(r'''
 class A {
@@ -791,6 +738,45 @@
         'M2');
   }
 
+  @failingTest
+  void test_getter_and_setter_fromMixins_property_access() {
+    // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
+    // a SimpleIdentifier that's inside a property access.  This bug should be
+    // fixed.
+    Source source = addSource('''
+class B {}
+class M1 {
+  get x => null;
+  set x(value) {}
+}
+class M2 {
+  get x => null;
+  set x(value) {}
+}
+class C extends B with M1, M2 {}
+void main() {
+  new C().x += 1;
+}
+''');
+    LibraryElement library = resolve2(source);
+    assertNoErrors(source);
+    verify([source]);
+    // Verify that both the getter and setter for "x" in "new C().x" refer to
+    // the accessors defined in M2.
+    FunctionDeclaration main =
+        library.definingCompilationUnit.functions[0].computeNode();
+    BlockFunctionBody body = main.functionExpression.body;
+    ExpressionStatement stmt = body.block.statements[0];
+    AssignmentExpression assignment = stmt.expression;
+    PropertyAccess propertyAccess = assignment.leftHandSide;
+    expect(
+        propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
+    expect(
+        propertyAccess
+            .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
+        'M2');
+  }
+
   void test_getter_fromMixins_bare_identifier() {
     Source source = addSource('''
 class B {}
@@ -926,6 +912,66 @@
     verify([source]);
   }
 
+  void test_import_prefix_doesNotExist() {
+    //
+    // The primary purpose of this test is to ensure that we are only getting a
+    // single error generated when the only problem is that an imported file
+    // does not exist.
+    //
+    Source source = addNamedSource(
+        "/a.dart",
+        r'''
+import 'missing.dart' as p;
+int a = p.q + p.r.s;
+String b = p.t(a) + p.u(v: 0);
+p.T c = new p.T();
+class D<E> extends p.T {
+  D(int i) : super(i);
+  p.U f = new p.V();
+}
+class F implements p.T {
+  p.T m(p.U u) => null;
+}
+class G extends Object with p.V {}
+class H extends D<p.W> {
+  H(int i) : super(i);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+    verify([source]);
+  }
+
+  void test_import_show_doesNotExist() {
+    //
+    // The primary purpose of this test is to ensure that we are only getting a
+    // single error generated when the only problem is that an imported file
+    // does not exist.
+    //
+    Source source = addNamedSource(
+        "/a.dart",
+        r'''
+import 'missing.dart' show q, r, t, u, T, U, V, W;
+int a = q + r.s;
+String b = t(a) + u(v: 0);
+T c = new T();
+class D<E> extends T {
+  D(int i) : super(i);
+  U f = new V();
+}
+class F implements T {
+  T m(U u) => null;
+}
+class G extends Object with V {}
+class H extends D<W> {
+  H(int i) : super(i);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+    verify([source]);
+  }
+
   void test_import_spaceInUri() {
     addNamedSource(
         "/sub folder/lib.dart",
@@ -1679,6 +1725,22 @@
     verify([source]);
   }
 
+  @failingTest
+  void test_staticInvocation() {
+    Source source = addSource(r'''
+class A {
+  static int get g => (a,b) => 0;
+}
+class B {
+  f() {
+    A.g(1,0);
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   /**
    * Resolve the given source and verify that the arguments in a specific method invocation were
    * correctly resolved.
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 23fac6b..2795236 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -394,6 +394,19 @@
     validate(TokenType.TILDE_SLASH_EQ);
   }
 
+  void test_visitAssignmentExpression_compound_lazy() {
+    validate(TokenType operator) {
+      InterfaceType boolType = _typeProvider.boolType;
+      SimpleIdentifier identifier = _resolvedVariable(boolType, "b");
+      AssignmentExpression node = AstFactory.assignmentExpression(
+          identifier, operator, _resolvedBool(true));
+      expect(_analyze(node), same(boolType));
+      _listener.assertNoErrors();
+    }
+    validate(TokenType.AMPERSAND_AMPERSAND_EQ);
+    validate(TokenType.BAR_BAR_EQ);
+  }
+
   void test_visitAssignmentExpression_compound_plusID() {
     validate(TokenType operator) {
       InterfaceType numType = _typeProvider.numType;
@@ -1565,6 +1578,16 @@
   }
 
   /**
+   * Return a boolean literal with the given [value] that has been resolved to
+   * the correct type.
+   */
+  BooleanLiteral _resolvedBool(bool value) {
+    BooleanLiteral literal = AstFactory.booleanLiteral(value);
+    literal.staticType = _typeProvider.intType;
+    return literal;
+  }
+
+  /**
    * Return an integer literal that has been resolved to the correct type.
    *
    * @param value the value of the literal
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 9eb44ab..21c3778 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -3527,6 +3527,12 @@
     assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
   }
 
+  void test_undefinedIdentifierAwait_function() {
+    Source source = addSource("void a() { await; }");
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT]);
+  }
+
   void test_undefinedIdentifier_importCore_withShow() {
     Source source = addSource(r'''
 import 'dart:core' show List;
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 277f8bb..ddf6dc0 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -121,9 +121,7 @@
     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("f4", _isFutureOfInt);
     check("f5", _isFutureOfInt);
 
     check("g0", _isFutureOfDynamic);
@@ -131,9 +129,7 @@
     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("g4", _isFutureOfInt);
     check("g5", _isFutureOfInt);
   }
 
@@ -181,9 +177,7 @@
     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("f4", _isFutureOfInt);
     check("f5", _isFutureOfInt);
 
     check("g0", _isFutureOfDynamic);
@@ -191,9 +185,7 @@
     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("g4", _isFutureOfInt);
     check("g5", _isFutureOfInt);
   }
 
@@ -222,7 +214,7 @@
     check("g1", _isStreamOf([_isDynamic]));
 
     check("g2", _isListOf(_isInt));
-    check("g3", _isStreamOf([_isListOf(_isInt)]));
+    check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
   }
 
   void test_async_star_propagation() {
@@ -249,7 +241,7 @@
     check("g1", _isStreamOf([_isDynamic]));
 
     check("g2", _isListOf(_isInt));
-    check("g3", _isStreamOf([_isListOf(_isInt)]));
+    check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
   }
 
   void test_cascadeExpression() {
@@ -271,6 +263,7 @@
       CascadeExpression exp = decl.initializer;
       return exp;
     }
+
     Element elementA = AstFinder.getClass(unit, "A").element;
 
     CascadeExpression cascade = fetch(0);
@@ -391,6 +384,7 @@
       FunctionExpression exp = decl.initializer;
       return exp.element.type;
     }
+
     _isFunction2Of(_isInt, _isString)(literal(0));
     _isFunction2Of(_isInt, _isString)(literal(1));
     _isFunction2Of(_isString, _isString)(literal(2));
@@ -419,6 +413,7 @@
       FunctionExpression exp = decl.initializer;
       return exp.element.type;
     }
+
     _isFunction2Of(_isInt, _isString)(literal(0));
     _isFunction2Of(_isInt, _isString)(literal(1));
     _isFunction2Of(_isInt, _isString)(literal(2));
@@ -452,6 +447,7 @@
         return (stmt as ReturnStatement).expression;
       }
     }
+
     Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
     assertListOfString(functionReturnValue(0).staticType);
     assertListOfString(functionReturnValue(1).staticType);
@@ -482,6 +478,7 @@
       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));
@@ -512,6 +509,7 @@
       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));
@@ -540,6 +538,7 @@
       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));
@@ -568,6 +567,7 @@
       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));
@@ -598,6 +598,7 @@
       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));
@@ -628,6 +629,7 @@
       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));
@@ -662,6 +664,7 @@
         return (stmt as ReturnStatement).expression;
       }
     }
+
     expect(functionReturnValue(0).staticType, typeProvider.intType);
     expect(functionReturnValue(1).staticType, typeProvider.intType);
     expect(functionReturnValue(2).staticType, typeProvider.intType);
@@ -698,7 +701,7 @@
 
     Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
     Asserter<InterfaceType> assertMapOfIntToListOfInt =
-        _isMapOf(_isInt, assertListOfInt);
+        _isMapOf(_isInt, (DartType type) => assertListOfInt(type));
 
     VariableDeclaration mapB = AstFinder.getFieldInClass(unit, "B", "map");
     MethodDeclaration mapC = AstFinder.getMethodInClass(unit, "C", "map");
@@ -798,7 +801,6 @@
         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
@@ -921,7 +923,7 @@
     {
       List<Statement> statements =
           AstFinder.getStatementsInTopLevelFunction(unit, "test8");
-      hasType(assertEOf([_isDynamic, _isDynamic]), rhs(statements[0]));
+      hasType(assertEOf([_isInt, _isString]), rhs(statements[0]));
     }
 
     {
@@ -956,7 +958,8 @@
     }
 
     Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-    Asserter<InterfaceType> assertListOfListOfInt = _isListOf(assertListOfInt);
+    Asserter<InterfaceType> assertListOfListOfInt =
+        _isListOf((DartType type) => assertListOfInt(type));
 
     assertListOfListOfInt(literal(0).staticType);
     assertListOfListOfInt(literal(1).staticType);
@@ -1096,7 +1099,7 @@
 
     Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
     Asserter<InterfaceType> assertMapOfIntToListOfString =
-        _isMapOf(_isInt, assertListOfString);
+        _isMapOf(_isInt, (DartType type) => assertListOfString(type));
 
     assertMapOfIntToListOfString(literal(0).staticType);
     assertMapOfIntToListOfString(literal(1).staticType);
@@ -1186,6 +1189,7 @@
         return (stmt as ReturnStatement).expression;
       }
     }
+
     Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
     assertListOfString(methodReturnValue("m0").staticType);
     assertListOfString(methodReturnValue("m1").staticType);
@@ -1250,7 +1254,7 @@
     check("f1", _isListOf(_isDynamic));
 
     check("f2", _isListOf(_isInt));
-    check("f3", _isListOf(_isListOf(_isInt)));
+    check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
   }
 
   void test_sync_star_propagation() {
@@ -1277,7 +1281,7 @@
     check("f1", _isListOf(_isDynamic));
 
     check("f2", _isListOf(_isInt));
-    check("f3", _isListOf(_isListOf(_isInt)));
+    check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
   }
 }
 
@@ -1317,6 +1321,16 @@
     expectIdentifierType('paramTearOffInst', "(int) → int");
   }
 
+  void objectMethodOnFunctions_helper(String code) {
+    resolveTestUnit(code);
+    expectIdentifierType('t0', "String");
+    expectIdentifierType('t1', "() → String");
+    expectIdentifierType('t2', "int");
+    expectIdentifierType('t3', "String");
+    expectIdentifierType('t4', "() → String");
+    expectIdentifierType('t5', "int");
+  }
+
   void setUp() {
     super.setUp();
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
@@ -1745,7 +1759,7 @@
 }
 ''');
     expectIdentifierType('f', '<S>(S) → S');
-    expectIdentifierType('g', '<S>(S) → dynamic');
+    expectIdentifierType('g', '<S>(S) → <S>(S) → S');
   }
 
   void test_genericMethod_override() {
@@ -1969,6 +1983,116 @@
     expectIdentifierType('cc', "C<int, B<int>, B<dynamic>>");
   }
 
+  void test_objectMethodOnFunctions_Anonymous() {
+    String code = r'''
+void main() {
+  var f = (x) => 3;
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    objectMethodOnFunctions_helper(code);
+  }
+
+  void test_objectMethodOnFunctions_Function() {
+    String code = r'''
+void main() {
+  Function f;
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    objectMethodOnFunctions_helper(code);
+  }
+
+  void test_objectMethodOnFunctions_Static() {
+    String code = r'''
+int f(int x) => null;
+void main() {
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    objectMethodOnFunctions_helper(code);
+  }
+
+  void test_objectMethodOnFunctions_Typedef() {
+    String code = r'''
+typedef bool Predicate<T>(T object);
+
+void main() {
+  Predicate<int> f;
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    objectMethodOnFunctions_helper(code);
+  }
+
   void test_setterWithDynamicTypeIsError() {
     Source source = addSource(r'''
 class A {
@@ -2007,7 +2131,9 @@
 set g(int x) => 42;
 ''');
     computeLibrarySourceErrors(source);
-    assertErrors(source, [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,]);
+    assertErrors(source, [
+      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+    ]);
     verify([source]);
   }
 
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index c164540..d7d72f8 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -621,7 +621,11 @@
       numType,
       bottomType
     ];
-    List<DartType> unrelated = <DartType>[intType, stringType, interfaceType,];
+    List<DartType> unrelated = <DartType>[
+      intType,
+      stringType,
+      interfaceType,
+    ];
 
     _checkGroups(doubleType,
         interassignable: interassignable, unrelated: unrelated);
@@ -751,7 +755,10 @@
       doubleType,
       bottomType
     ];
-    List<DartType> unrelated = <DartType>[stringType, interfaceType,];
+    List<DartType> unrelated = <DartType>[
+      stringType,
+      interfaceType,
+    ];
 
     _checkGroups(numType,
         interassignable: interassignable, unrelated: unrelated);
@@ -781,10 +788,12 @@
 
   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]);
+    _checkGroups(top, interassignable: [top, left, right, bottom]);
+    _checkGroups(left,
+        interassignable: [top, left, bottom], unrelated: [right]);
+    _checkGroups(right,
+        interassignable: [top, right, bottom], unrelated: [left]);
+    _checkGroups(bottom, interassignable: [top, left, right, bottom]);
   }
 
   void _checkEquivalent(DartType type1, DartType type2) {
@@ -891,9 +900,7 @@
     expect(_inferCall(clone, [foo.type, foo.type]), [foo.type]);
 
     // Something invalid...
-    expect(_inferCall(clone, [stringType, numType]), [
-      clonable.type.instantiate([dynamicType])
-    ]);
+    expect(_inferCall(clone, [stringType, numType]), null);
   }
 
   void test_genericCastFunction() {
@@ -1007,7 +1014,7 @@
     // <T extends num>() -> T
     var t = TypeBuilder.variable('T', bound: numType);
     var f = TypeBuilder.function(types: [t], required: [], result: t);
-    expect(_inferCall(f, [], stringType), [numType]);
+    expect(_inferCall(f, [], stringType), null);
   }
 
   void test_unifyParametersToFunctionParam() {
@@ -1024,7 +1031,7 @@
           TypeBuilder.function(required: [intType], result: dynamicType),
           TypeBuilder.function(required: [doubleType], result: dynamicType)
         ]),
-        [dynamicType]);
+        null);
   }
 
   void test_unusedReturnTypeIsDynamic() {
@@ -1045,7 +1052,7 @@
       [DartType returnType]) {
     FunctionType inferred = typeSystem.inferGenericFunctionCall(typeProvider,
         ft, ft.parameters.map((p) => p.type).toList(), arguments, returnType);
-    return inferred.typeArguments;
+    return inferred?.typeArguments;
   }
 }
 
@@ -1144,6 +1151,13 @@
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
+  void test_functionsFuzzyArrows() {
+    FunctionType type1 = _functionType([dynamicType]);
+    FunctionType type2 = _functionType([intType]);
+    FunctionType expected = _functionType([intType]);
+    _checkGreatestLowerBound(type1, type2, expected);
+  }
+
   void test_functionsGlbReturnType() {
     FunctionType type1 = _functionType([], returns: intType);
     FunctionType type2 = _functionType([], returns: numType);
@@ -1313,6 +1327,13 @@
     super.setUp();
   }
 
+  void test_functionsFuzzyArrows() {
+    FunctionType type1 = _functionType([dynamicType]);
+    FunctionType type2 = _functionType([intType]);
+    FunctionType expected = _functionType([dynamicType]);
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
   void test_functionsGlbNamedParams() {
     FunctionType type1 =
         _functionType([], named: {'a': stringType, 'b': intType});
diff --git a/pkg/analyzer/test/resource_utils.dart b/pkg/analyzer/test/resource_utils.dart
index 5936144..65f7069 100644
--- a/pkg/analyzer/test/resource_utils.dart
+++ b/pkg/analyzer/test/resource_utils.dart
@@ -4,10 +4,12 @@
 
 library analyzer.test.resource_utils;
 
+import 'dart:async';
 import 'dart:core' hide Resource;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart' as path;
 import 'package:unittest/unittest.dart';
@@ -104,6 +106,11 @@
   Folder getFolder(String path) => _provider.getFolder(_assertPath(path));
 
   @override
+  Future<List<int>> getModificationTimes(List<Source> sources) async {
+    return sources.map((source) => 0).toList();
+  }
+
+  @override
   Resource getResource(String path) => _provider.getResource(_assertPath(path));
 
   @override
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index c16e6f9..ea20cd7 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -22,7 +22,6 @@
   runReflectiveTests(DartUriResolverTest);
   runReflectiveTests(EmbedderSdkTest);
   runReflectiveTests(EmbedderUriResolverTest);
-  runReflectiveTests(EmbedderYamlLocatorTest);
 }
 
 @reflectiveTest
@@ -39,6 +38,7 @@
       expect(source, isNotNull, reason: dartUri);
       expect(source.fullName, posixToOSPath(posixPath));
     }
+
     // Check that they map to the correct paths.
     expectResolved('dart:core', '/tmp/core.dart');
     expectResolved('dart:fox', '/tmp/slippy.dart');
@@ -205,26 +205,3 @@
     expectRestore('dart:deep/deep/file.dart');
   }
 }
-
-@reflectiveTest
-class EmbedderYamlLocatorTest extends EmbedderRelatedTest {
-  void test_empty() {
-    EmbedderYamlLocator locator = new EmbedderYamlLocator({
-      'fox': [pathTranslator.getResource('/empty')]
-    });
-    expect(locator.embedderYamls, hasLength(0));
-  }
-
-  void test_invalid() {
-    EmbedderYamlLocator locator = new EmbedderYamlLocator(null);
-    locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
-    expect(locator.embedderYamls, hasLength(0));
-  }
-
-  void test_valid() {
-    EmbedderYamlLocator locator = new EmbedderYamlLocator({
-      'fox': [pathTranslator.getResource('/tmp')]
-    });
-    expect(locator.embedderYamls, hasLength(1));
-  }
-}
diff --git a/pkg/analyzer/test/source/package_map_provider_test.dart b/pkg/analyzer/test/source/package_map_provider_test.dart
index f02b60a..bb0e142 100644
--- a/pkg/analyzer/test/source/package_map_provider_test.dart
+++ b/pkg/analyzer/test/source/package_map_provider_test.dart
@@ -8,8 +8,8 @@
 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/dart/sdk/sdk.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';
@@ -24,7 +24,7 @@
 class PubPackageMapProviderTest {
   static const String projectPath = '/path/to/project';
 
-  DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
+  DartSdk sdk;
   MemoryResourceProvider resourceProvider;
   PubPackageMapProvider packageMapProvider;
   Folder projectFolder;
@@ -35,6 +35,8 @@
 
   void setUp() {
     resourceProvider = new MemoryResourceProvider();
+    sdk = new FolderBasedDartSdk(resourceProvider,
+        FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
     packageMapProvider = new PubPackageMapProvider(resourceProvider, sdk);
     projectFolder = resourceProvider.newFolder(projectPath);
   }
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index dbb7425..e46ed7d 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -8,79 +8,77 @@
 import 'package:analyzer/source/sdk_ext.dart';
 import 'package:unittest/unittest.dart';
 
+import '../reflective_tests.dart';
 import '../utils.dart';
 
 main() {
   initializeTestEnvironment();
-  group('SdkExtUriResolverTest', () {
-    setUp(() {
-      buildResourceProvider();
-    });
-    tearDown(() {
-      clearResourceProvider();
-    });
-    test('test_NullPackageMap', () {
-      var resolver = new SdkExtUriResolver(null);
-      expect(resolver.length, equals(0));
-    });
-    test('test_NoSdkExtPackageMap', () {
-      var resolver = new SdkExtUriResolver({
-        'fox': [resourceProvider.getResource('/empty')]
-      });
-      expect(resolver.length, equals(0));
-    });
-    test('test_SdkExtPackageMap', () {
-      var resolver = new SdkExtUriResolver({
-        'fox': [resourceProvider.getResource('/tmp')]
-      });
-      // 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_BadJSON', () {
-      var resolver = new SdkExtUriResolver(null);
-      resolver.addSdkExt(r'''{{{,{{}}},}}''', null);
-      expect(resolver.length, equals(0));
-    });
-    test('test_restoreAbsolute', () {
-      var resolver = new SdkExtUriResolver({
-        'fox': [resourceProvider.getResource('/tmp')]
-      });
-      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'));
-    });
-  });
+  runReflectiveTests(SdkExtUriResolverTest);
 }
 
-MemoryResourceProvider resourceProvider;
+@reflectiveTest
+class SdkExtUriResolverTest {
+  MemoryResourceProvider resourceProvider;
 
-buildResourceProvider() {
-  resourceProvider = new MemoryResourceProvider();
-  resourceProvider.newFolder('/empty');
-  resourceProvider.newFolder('/tmp');
-  resourceProvider.newFile(
-      '/tmp/_sdkext',
-      r'''
-  {
-    "dart:fox": "slippy.dart",
-    "dart:bear": "grizzly.dart",
-    "dart:relative": "../relative.dart",
-    "dart:deep": "deep/directory/file.dart",
-    "fart:loudly": "nomatter.dart"
-  }''');
-}
+  void setUp() {
+    resourceProvider = new MemoryResourceProvider();
+    resourceProvider.newFolder('/empty');
+    resourceProvider.newFolder('/tmp');
+    resourceProvider.newFile(
+        '/tmp/_sdkext',
+        r'''
+{
+  "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;
+  test_create_badJSON() {
+    var resolver = new SdkExtUriResolver(null);
+    resolver.addSdkExt(r'''{{{,{{}}},}}''', null);
+    expect(resolver.length, equals(0));
+  }
+
+  test_create_noSdkExtPackageMap() {
+    var resolver = new SdkExtUriResolver({
+      'fox': [resourceProvider.getResource('/empty')]
+    });
+    expect(resolver.length, equals(0));
+  }
+
+  test_create_nullPackageMap() {
+    var resolver = new SdkExtUriResolver(null);
+    expect(resolver.length, equals(0));
+  }
+
+  test_create_sdkExtPackageMap() {
+    var resolver = new SdkExtUriResolver({
+      'fox': [resourceProvider.getResource('/tmp')]
+    });
+    // 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_restoreAbsolute() {
+    var resolver = new SdkExtUriResolver({
+      'fox': [resourceProvider.getResource('/tmp')]
+    });
+    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'));
+  }
 }
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index be85eff..ba11f84 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -123,7 +123,7 @@
     return new AnalysisContextImpl();
   }
 
-  DartSdk createDartSdk() => new MockSdk();
+  DartSdk createDartSdk() => new MockSdk(resourceProvider: resourceProvider);
 
   Source newSource(String path, [String content = '']) {
     File file = resourceProvider.newFile(path, content);
@@ -143,8 +143,8 @@
     sdk = createDartSdk();
     sdkResolver = new DartUriResolver(sdk);
     resourceResolver = new ResourceUriResolver(resourceProvider);
-    sourceFactory =
-        new SourceFactory(<UriResolver>[sdkResolver, resourceResolver]);
+    sourceFactory = new SourceFactory(
+        <UriResolver>[sdkResolver, resourceResolver], null, resourceProvider);
     context = createAnalysisContext();
     if (options != null) {
       context.analysisOptions = options;
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 758a03c..cba70fa 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -9,7 +9,9 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -20,6 +22,7 @@
 
 import '../../generated/test_support.dart';
 import '../../reflective_tests.dart';
+import '../../source/embedder_test.dart';
 import '../../utils.dart';
 import 'mock_sdk.dart';
 
@@ -27,6 +30,7 @@
   initializeTestEnvironment();
   runReflectiveTests(ContextBuilderTest_WithDisk);
   runReflectiveTests(ContextBuilderTest_WithoutDisk);
+  runReflectiveTests(EmbedderYamlLocatorTest);
 }
 
 @reflectiveTest
@@ -51,12 +55,56 @@
    */
   ContentCache contentCache;
 
+  /**
+   * The context builder to be used in the test.
+   */
+  ContextBuilder builder;
+
+  /**
+   * The path to the default SDK, or `null` if the test has not explicitly
+   * invoked [createDefaultSdk].
+   */
+  String defaultSdkPath = null;
+
+  void createDefaultSdk(io.Directory tempDir) {
+    defaultSdkPath = pathContext.join(tempDir.path, 'default', 'sdk');
+    String librariesFilePath = pathContext.join(defaultSdkPath, 'lib',
+        '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart');
+    createFile(
+        librariesFilePath,
+        r'''
+const Map<String, LibraryInfo> libraries = const {
+  "async": const LibraryInfo("async/async.dart"),
+  "core": const LibraryInfo("core/core.dart"),
+};
+''');
+    sdkManager =
+        new DartSdkManager(defaultSdkPath, false, (_) => new MockSdk());
+    builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
+  }
+
+  void createDirectory(String path) {
+    new io.Directory(path).createSync(recursive: true);
+  }
+
+  void createFile(String path, String content) {
+    new io.File(path)
+      ..createSync(recursive: true)
+      ..writeAsStringSync(content);
+  }
+
   @override
   void setUp() {
     resourceProvider = PhysicalResourceProvider.INSTANCE;
     pathContext = resourceProvider.pathContext;
     sdkManager = new DartSdkManager('', false, (_) => new MockSdk());
     contentCache = new ContentCache();
+    builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
+  }
+
+  @failingTest
+  void test_buildContext() {
+    fail('Incomplete test');
   }
 
   void test_createPackageMap_fromPackageDirectory_explicit() {
@@ -69,12 +117,10 @@
       String fooPath = pathContext.join(packageDirPath, fooName);
       String barName = 'bar';
       String barPath = pathContext.join(packageDirPath, barName);
-      new io.Directory(projectPath).createSync(recursive: true);
-      new io.Directory(fooPath).createSync(recursive: true);
-      new io.Directory(barPath).createSync(recursive: true);
+      createDirectory(projectPath);
+      createDirectory(fooPath);
+      createDirectory(barPath);
 
-      ContextBuilder builder =
-          new ContextBuilder(resourceProvider, sdkManager, contentCache);
       builder.defaultPackagesDirectoryPath = packageDirPath;
 
       Packages packages = builder.createPackageMap(projectPath);
@@ -95,11 +141,9 @@
       String fooPath = pathContext.join(packageDirPath, fooName);
       String barName = 'bar';
       String barPath = pathContext.join(packageDirPath, barName);
-      new io.Directory(fooPath).createSync(recursive: true);
-      new io.Directory(barPath).createSync(recursive: true);
+      createDirectory(fooPath);
+      createDirectory(barPath);
 
-      ContextBuilder builder =
-          new ContextBuilder(resourceProvider, sdkManager, contentCache);
       Packages packages = builder.createPackageMap(projectPath);
       expect(packages, isNotNull);
       Map<String, Uri> map = packages.asMap();
@@ -115,16 +159,14 @@
       String rootPath = tempDir.path;
       String projectPath = pathContext.join(rootPath, 'project');
       String packageFilePath = pathContext.join(rootPath, 'child', '.packages');
-      new io.Directory(projectPath).createSync(recursive: true);
-      new io.File(packageFilePath)
-        ..createSync(recursive: true)
-        ..writeAsStringSync(r'''
+      createDirectory(projectPath);
+      createFile(
+          packageFilePath,
+          r'''
 foo:/pkg/foo
 bar:/pkg/bar
 ''');
 
-      ContextBuilder builder =
-          new ContextBuilder(resourceProvider, sdkManager, contentCache);
       builder.defaultPackageFilePath = packageFilePath;
       Packages packages = builder.createPackageMap(projectPath);
       expect(packages, isNotNull);
@@ -141,16 +183,14 @@
       String rootPath = tempDir.path;
       String projectPath = pathContext.join(rootPath, 'project');
       String packageFilePath = pathContext.join(rootPath, '.packages');
-      new io.Directory(projectPath).createSync(recursive: true);
-      new io.File(packageFilePath)
-        ..createSync(recursive: true)
-        ..writeAsStringSync(r'''
+      createDirectory(projectPath);
+      createFile(
+          packageFilePath,
+          r'''
 foo:/pkg/foo
 bar:/pkg/bar
 ''');
 
-      ContextBuilder builder =
-          new ContextBuilder(resourceProvider, sdkManager, contentCache);
       Packages packages = builder.createPackageMap(projectPath);
       expect(packages, isNotNull);
       Map<String, Uri> map = packages.asMap();
@@ -166,16 +206,14 @@
       String rootPath = tempDir.path;
       String projectPath = pathContext.join(rootPath, 'project');
       String packageFilePath = pathContext.join(projectPath, '.packages');
-      new io.Directory(projectPath).createSync(recursive: true);
-      new io.File(packageFilePath)
-        ..createSync(recursive: true)
-        ..writeAsStringSync(r'''
+      createDirectory(projectPath);
+      createFile(
+          packageFilePath,
+          r'''
 foo:/pkg/foo
 bar:/pkg/bar
 ''');
 
-      ContextBuilder builder =
-          new ContextBuilder(resourceProvider, sdkManager, contentCache);
       Packages packages = builder.createPackageMap(projectPath);
       expect(packages, isNotNull);
       Map<String, Uri> map = packages.asMap();
@@ -187,13 +225,192 @@
 
   void test_createPackageMap_none() {
     withTempDir((io.Directory tempDir) {
-      ContextBuilder builder =
-          new ContextBuilder(resourceProvider, sdkManager, contentCache);
       Packages packages = builder.createPackageMap(tempDir.path);
       expect(packages, same(Packages.noPackages));
     });
   }
 
+  void test_createSourceFactory_fileProvider() {
+    withTempDir((io.Directory tempDir) {
+      createDefaultSdk(tempDir);
+      String rootPath = tempDir.path;
+      String projectPath = pathContext.join(rootPath, 'project');
+      String packageFilePath = pathContext.join(projectPath, '.packages');
+      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
+      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
+      createFile(
+          packageFilePath,
+          '''
+a:${pathContext.toUri(packageA)}
+b:${pathContext.toUri(packageB)}
+''');
+      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+      UriResolver resolver = new ResourceUriResolver(resourceProvider);
+      builder.fileResolverProvider = (folder) => resolver;
+      SourceFactoryImpl factory =
+          builder.createSourceFactory(projectPath, options);
+      expect(factory.resolvers, contains(same(resolver)));
+    });
+  }
+
+  void test_createSourceFactory_noProvider_packages_embedder_extensions() {
+    withTempDir((io.Directory tempDir) {
+      createDefaultSdk(tempDir);
+      String rootPath = tempDir.path;
+      String projectPath = pathContext.join(rootPath, 'project');
+      String packageFilePath = pathContext.join(projectPath, '.packages');
+      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
+      String embedderPath = pathContext.join(packageA, '_embedder.yaml');
+      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
+      String extensionPath = pathContext.join(packageB, '_sdkext');
+      createFile(
+          packageFilePath,
+          '''
+a:${pathContext.toUri(packageA)}
+b:${pathContext.toUri(packageB)}
+''');
+      String asyncPath = pathContext.join(packageA, 'sdk', 'async.dart');
+      String corePath = pathContext.join(packageA, 'sdk', 'core.dart');
+      createFile(
+          embedderPath,
+          '''
+embedded_libs:
+  "dart:async": ${_relativeUri(asyncPath, from: packageA)}
+  "dart:core": ${_relativeUri(corePath, from: packageA)}
+''');
+      String fooPath = pathContext.join(packageB, 'ext', 'foo.dart');
+      createFile(
+          extensionPath,
+          '''{
+"dart:foo": "${_relativeUri(fooPath, from: packageB)}"
+}''');
+      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+
+      SourceFactory factory = builder.createSourceFactory(projectPath, options);
+
+      Source asyncSource = factory.forUri('dart:async');
+      expect(asyncSource, isNotNull);
+      expect(asyncSource.fullName, asyncPath);
+
+      Source fooSource = factory.forUri('dart:foo');
+      expect(fooSource, isNotNull);
+      expect(fooSource.fullName, fooPath);
+
+      Source packageSource = factory.forUri('package:b/b.dart');
+      expect(packageSource, isNotNull);
+      expect(packageSource.fullName, pathContext.join(packageB, 'b.dart'));
+    });
+  }
+
+  void test_createSourceFactory_noProvider_packages_embedder_noExtensions() {
+    withTempDir((io.Directory tempDir) {
+      createDefaultSdk(tempDir);
+      String rootPath = tempDir.path;
+      String projectPath = pathContext.join(rootPath, 'project');
+      String packageFilePath = pathContext.join(projectPath, '.packages');
+      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
+      String embedderPath = pathContext.join(packageA, '_embedder.yaml');
+      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
+      createFile(
+          packageFilePath,
+          '''
+a:${pathContext.toUri(packageA)}
+b:${pathContext.toUri(packageB)}
+''');
+      String asyncPath = pathContext.join(packageA, 'sdk', 'async.dart');
+      String corePath = pathContext.join(packageA, 'sdk', 'core.dart');
+      createFile(
+          embedderPath,
+          '''
+embedded_libs:
+  "dart:async": ${_relativeUri(asyncPath, from: packageA)}
+  "dart:core": ${_relativeUri(corePath, from: packageA)}
+''');
+      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+
+      SourceFactory factory = builder.createSourceFactory(projectPath, options);
+
+      Source dartSource = factory.forUri('dart:async');
+      expect(dartSource, isNotNull);
+      expect(dartSource.fullName, asyncPath);
+
+      Source packageSource = factory.forUri('package:b/b.dart');
+      expect(packageSource, isNotNull);
+      expect(packageSource.fullName, pathContext.join(packageB, 'b.dart'));
+    });
+  }
+
+  @failingTest
+  void test_createSourceFactory_noProvider_packages_noEmbedder_extensions() {
+    fail('Incomplete test');
+  }
+
+  void test_createSourceFactory_noProvider_packages_noEmbedder_noExtensions() {
+    withTempDir((io.Directory tempDir) {
+      createDefaultSdk(tempDir);
+      String rootPath = tempDir.path;
+      String projectPath = pathContext.join(rootPath, 'project');
+      String packageFilePath = pathContext.join(projectPath, '.packages');
+      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
+      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
+      createFile(
+          packageFilePath,
+          '''
+a:${pathContext.toUri(packageA)}
+b:${pathContext.toUri(packageB)}
+''');
+      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+
+      SourceFactory factory = builder.createSourceFactory(projectPath, options);
+
+      Source dartSource = factory.forUri('dart:core');
+      expect(dartSource, isNotNull);
+      expect(dartSource.fullName, '$defaultSdkPath/lib/core/core.dart');
+
+      Source packageSource = factory.forUri('package:a/a.dart');
+      expect(packageSource, isNotNull);
+      expect(packageSource.fullName, pathContext.join(packageA, 'a.dart'));
+    });
+  }
+
+  void test_createSourceFactory_packageProvider() {
+    withTempDir((io.Directory tempDir) {
+      createDefaultSdk(tempDir);
+      String rootPath = tempDir.path;
+      String projectPath = pathContext.join(rootPath, 'project');
+      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+      UriResolver resolver = new PackageMapUriResolver(resourceProvider, {});
+      builder.packageResolverProvider = (folder) => resolver;
+      SourceFactoryImpl factory =
+          builder.createSourceFactory(projectPath, options);
+      expect(factory.resolvers, contains(same(resolver)));
+    });
+  }
+
+  @failingTest
+  void test_findSdk_embedder_extensions() {
+    // See test_createSourceFactory_noProvider_packages_embedder_extensions
+    fail('Incomplete test');
+  }
+
+  @failingTest
+  void test_findSdk_embedder_noExtensions() {
+    // See test_createSourceFactory_noProvider_packages_embedder_noExtensions
+    fail('Incomplete test');
+  }
+
+  @failingTest
+  void test_findSdk_noEmbedder_extensions() {
+    // See test_createSourceFactory_noProvider_packages_noEmbedder_extensions
+    fail('Incomplete test');
+  }
+
+  @failingTest
+  void test_findSdk_noEmbedder_noExtensions() {
+    // See test_createSourceFactory_noProvider_packages_noEmbedder_noExtensions
+    fail('Incomplete test');
+  }
+
   /**
    * Execute the [test] function with a temporary [directory]. The test function
    * can perform any disk operations within the directory and the directory (and
@@ -208,6 +425,11 @@
       directory.deleteSync(recursive: true);
     }
   }
+
+  Uri _relativeUri(String path, {String from}) {
+    String relativePath = pathContext.relative(path, from: from);
+    return pathContext.toUri(relativePath);
+  }
 }
 
 @reflectiveTest
@@ -227,30 +449,27 @@
    */
   ContentCache contentCache;
 
-  void fail_createSourceFactory() {
-    fail('Incomplete test');
-  }
-
-  void fail_findSdkResolver() {
-    fail('Incomplete test');
-  }
+  /**
+   * The context builder to be used in the test.
+   */
+  ContextBuilder builder;
 
   @override
   void setUp() {
     resourceProvider = new MemoryResourceProvider();
-    sdkManager = new DartSdkManager('', false, (_) => new MockSdk());
+    new MockSdk(resourceProvider: resourceProvider);
+    sdkManager = new DartSdkManager('/', false, (_) {
+      fail('Should not be used to create an SDK');
+    });
     contentCache = new ContentCache();
+    builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
   }
 
   void test_convertPackagesToMap_noPackages() {
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     expect(builder.convertPackagesToMap(Packages.noPackages), isNull);
   }
 
   void test_convertPackagesToMap_null() {
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     expect(builder.convertPackagesToMap(null), isNull);
   }
 
@@ -262,8 +481,6 @@
     String barPath = '/pkg/bar';
     Uri barUri = new Uri.directory(barPath);
 
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     MapPackages packages = new MapPackages({fooName: fooUri, barName: barUri});
     Map<String, List<Folder>> result = builder.convertPackagesToMap(packages);
     expect(result, isNotNull);
@@ -274,13 +491,137 @@
     expect(result[barName][0].path, barPath);
   }
 
+  void test_createDefaultOptions_default() {
+    // Invert a subset of the options to ensure that the default options are
+    // being returned.
+    AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
+    defaultOptions.dart2jsHint = !defaultOptions.dart2jsHint;
+    defaultOptions.enableAssertMessage = !defaultOptions.enableAssertMessage;
+    defaultOptions.enableAsync = !defaultOptions.enableAsync;
+    defaultOptions.enableGenericMethods = !defaultOptions.enableGenericMethods;
+    defaultOptions.enableStrictCallChecks =
+        !defaultOptions.enableStrictCallChecks;
+    defaultOptions.enableSuperMixins = !defaultOptions.enableSuperMixins;
+    builder.defaultOptions = defaultOptions;
+    AnalysisOptions options = builder.createDefaultOptions();
+    _expectEqualOptions(options, defaultOptions);
+  }
+
+  void test_createDefaultOptions_noDefault() {
+    AnalysisOptions options = builder.createDefaultOptions();
+    _expectEqualOptions(options, new AnalysisOptionsImpl());
+  }
+
+  void test_declareVariables_emptyMap() {
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    Iterable<String> expected = context.declaredVariables.variableNames;
+    builder.declaredVariables = <String, String>{};
+
+    builder.declareVariables(context);
+    expect(context.declaredVariables.variableNames, unorderedEquals(expected));
+  }
+
+  void test_declareVariables_nonEmptyMap() {
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    List<String> expected = context.declaredVariables.variableNames.toList();
+    expect(expected, isNot(contains('a')));
+    expect(expected, isNot(contains('b')));
+    expected.addAll(['a', 'b']);
+    builder.declaredVariables = <String, String>{'a': 'a', 'b': 'b'};
+
+    builder.declareVariables(context);
+    expect(context.declaredVariables.variableNames, unorderedEquals(expected));
+  }
+
+  void test_declareVariables_null() {
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    Iterable<String> expected = context.declaredVariables.variableNames;
+
+    builder.declareVariables(context);
+    expect(context.declaredVariables.variableNames, unorderedEquals(expected));
+  }
+
+  void test_findSdk_noPackageMap() {
+    DartSdk sdk = builder.findSdk(null, new AnalysisOptionsImpl());
+    expect(sdk, isNotNull);
+  }
+
+  void test_getAnalysisOptions_default_noOverrides() {
+    AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
+    defaultOptions.enableGenericMethods = true;
+    builder.defaultOptions = defaultOptions;
+    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
+    expected.enableGenericMethods = true;
+    String path = '/some/directory/path';
+    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+    resourceProvider.newFile(
+        filePath,
+        '''
+linter:
+  rules:
+    - empty_constructor_bodies
+''');
+
+    AnalysisOptions options = builder.getAnalysisOptions(path);
+    _expectEqualOptions(options, expected);
+  }
+
+  void test_getAnalysisOptions_default_overrides() {
+    AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
+    defaultOptions.enableGenericMethods = true;
+    builder.defaultOptions = defaultOptions;
+    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
+    expected.enableAsync = true;
+    expected.enableGenericMethods = true;
+    String path = '/some/directory/path';
+    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+    resourceProvider.newFile(
+        filePath,
+        '''
+analyzer:
+  enableAsync : true
+''');
+
+    AnalysisOptions options = builder.getAnalysisOptions(path);
+    _expectEqualOptions(options, expected);
+  }
+
+  void test_getAnalysisOptions_noDefault_noOverrides() {
+    String path = '/some/directory/path';
+    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+    resourceProvider.newFile(
+        filePath,
+        '''
+linter:
+  rules:
+    - empty_constructor_bodies
+''');
+
+    AnalysisOptions options = builder.getAnalysisOptions(path);
+    _expectEqualOptions(options, new AnalysisOptionsImpl());
+  }
+
+  void test_getAnalysisOptions_noDefault_overrides() {
+    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
+    expected.enableAsync = true;
+    String path = '/some/directory/path';
+    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+    resourceProvider.newFile(
+        filePath,
+        '''
+analyzer:
+  enableAsync : true
+''');
+
+    AnalysisOptions options = builder.getAnalysisOptions(path);
+    _expectEqualOptions(options, expected);
+  }
+
   void test_getOptionsFile_explicit() {
     String path = '/some/directory/path';
     String filePath = '/options/analysis.yaml';
     resourceProvider.newFile(filePath, '');
 
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     builder.defaultAnalysisOptionsFilePath = filePath;
     File result = builder.getOptionsFile(path);
     expect(result, isNotNull);
@@ -294,8 +635,6 @@
         '$parentPath/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
     resourceProvider.newFile(filePath, '');
 
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     File result = builder.getOptionsFile(path);
     expect(result, isNotNull);
     expect(result.path, filePath);
@@ -307,8 +646,6 @@
     String filePath = '$parentPath/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
     resourceProvider.newFile(filePath, '');
 
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     File result = builder.getOptionsFile(path);
     expect(result, isNotNull);
     expect(result.path, filePath);
@@ -319,8 +656,6 @@
     String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
     resourceProvider.newFile(filePath, '');
 
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     File result = builder.getOptionsFile(path);
     expect(result, isNotNull);
     expect(result.path, filePath);
@@ -331,10 +666,60 @@
     String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
     resourceProvider.newFile(filePath, '');
 
-    ContextBuilder builder =
-        new ContextBuilder(resourceProvider, sdkManager, contentCache);
     File result = builder.getOptionsFile(path);
     expect(result, isNotNull);
     expect(result.path, filePath);
   }
+
+  void _expectEqualOptions(
+      AnalysisOptionsImpl actual, AnalysisOptionsImpl expected) {
+    // TODO(brianwilkerson) Consider moving this to AnalysisOptionsImpl.==.
+    expect(actual.analyzeFunctionBodiesPredicate,
+        same(expected.analyzeFunctionBodiesPredicate));
+    expect(actual.cacheSize, expected.cacheSize);
+    expect(actual.dart2jsHint, expected.dart2jsHint);
+    expect(actual.enableAssertMessage, expected.enableAssertMessage);
+    expect(actual.enableAsync, expected.enableAsync);
+    expect(actual.enableStrictCallChecks, expected.enableStrictCallChecks);
+    expect(actual.enableGenericMethods, expected.enableGenericMethods);
+    expect(actual.enableSuperMixins, expected.enableSuperMixins);
+    expect(actual.enableTiming, expected.enableTiming);
+    expect(actual.generateImplicitErrors, expected.generateImplicitErrors);
+    expect(actual.generateSdkErrors, expected.generateSdkErrors);
+    expect(actual.hint, expected.hint);
+    expect(actual.incremental, expected.incremental);
+    expect(actual.incrementalApi, expected.incrementalApi);
+    expect(actual.incrementalValidation, expected.incrementalValidation);
+    expect(actual.lint, expected.lint);
+    expect(actual.preserveComments, expected.preserveComments);
+    expect(actual.strongMode, expected.strongMode);
+    expect(actual.strongModeHints, expected.strongModeHints);
+    expect(actual.implicitCasts, expected.implicitCasts);
+    expect(actual.implicitDynamic, expected.implicitDynamic);
+    expect(actual.trackCacheDependencies, expected.trackCacheDependencies);
+    expect(actual.finerGrainedInvalidation, expected.finerGrainedInvalidation);
+  }
+}
+
+@reflectiveTest
+class EmbedderYamlLocatorTest extends EmbedderRelatedTest {
+  void test_empty() {
+    EmbedderYamlLocator locator = new EmbedderYamlLocator({
+      'fox': [pathTranslator.getResource('/empty')]
+    });
+    expect(locator.embedderYamls, hasLength(0));
+  }
+
+  void test_invalid() {
+    EmbedderYamlLocator locator = new EmbedderYamlLocator(null);
+    locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
+    expect(locator.embedderYamls, hasLength(0));
+  }
+
+  void test_valid() {
+    EmbedderYamlLocator locator = new EmbedderYamlLocator({
+      'fox': [pathTranslator.getResource('/tmp')]
+    });
+    expect(locator.embedderYamls, hasLength(1));
+  }
 }
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index b03791a..bc8342a 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -4,10 +4,14 @@
 
 library analyzer.test.src.context.cache_test;
 
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 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';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/task/model.dart';
@@ -698,6 +702,12 @@
         unorderedEquals([new TargetedResult(target, result2)]));
     expect(entry.getResultData(result2).dependedOnResults,
         unorderedEquals([new TargetedResult(target, result1)]));
+    // record invalidated results
+    Set<TargetedResult> reportedInvalidatedResults = new Set<TargetedResult>();
+    cache.onResultInvalidated.listen((InvalidatedResult invalidatedResult) {
+      reportedInvalidatedResults.add(new TargetedResult(
+          invalidatedResult.entry.target, invalidatedResult.descriptor));
+    });
     // invalidate result2 with Delta: keep result2, invalidate result3
     entry.setState(result2, CacheState.INVALID,
         delta: new _KeepContinueDelta(target, result2));
@@ -709,6 +719,10 @@
         unorderedEquals([new TargetedResult(target, result2)]));
     expect(entry.getResultData(result2).dependedOnResults,
         unorderedEquals([new TargetedResult(target, result1)]));
+    // (target, result3) was reported as invalidated
+    // (target, result2) was NOT reported
+    expect(reportedInvalidatedResults,
+        unorderedEquals([new TargetedResult(target, result3)]));
   }
 
   test_setState_valid() {
@@ -778,6 +792,28 @@
     expect(entry.getValue(result2), 222);
   }
 
+  test_setValue_userBeforeProvider_invalidateProvider_alsoUser() {
+    AnalysisTarget target1 = new TestSource('/a.dart');
+    AnalysisTarget target2 = new TestSource('/b.dart');
+    CacheEntry entry1 = new CacheEntry(target1);
+    CacheEntry entry2 = new CacheEntry(target2);
+    cache.put(entry1);
+    cache.put(entry2);
+    ResultDescriptor result1 = new ResultDescriptor('result1', -1);
+    ResultDescriptor result2 = new ResultDescriptor('result2', -2);
+    // set results, all of them are VALID
+    entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
+    entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    expect(entry1.getState(result1), CacheState.VALID);
+    expect(entry2.getState(result2), CacheState.VALID);
+    expect(entry1.getValue(result1), 111);
+    expect(entry2.getValue(result2), 222);
+    // invalidate result1, should invalidate also result2
+    entry1.setState(result1, CacheState.INVALID);
+    expect(entry1.getState(result1), CacheState.INVALID);
+    expect(entry2.getState(result2), CacheState.INVALID);
+  }
+
   test_setValueIncremental() {
     AnalysisTarget target = new TestSource();
     CacheEntry entry = new CacheEntry(target);
@@ -1079,6 +1115,35 @@
 }
 
 @reflectiveTest
+class PackageCachePartitionTest extends CachePartitionTest {
+  MemoryResourceProvider resourceProvider;
+  Folder rootFolder;
+
+  CachePartition createPartition() {
+    resourceProvider = new MemoryResourceProvider();
+    rootFolder = resourceProvider.newFolder('/package/root');
+    return new PackageCachePartition(null, rootFolder);
+  }
+
+  void test_contains_false() {
+    CachePartition partition = createPartition();
+    AnalysisTarget target = new TestSource();
+    expect(partition.isResponsibleFor(target), isFalse);
+  }
+
+  void test_contains_true() {
+    SdkCachePartition partition = new SdkCachePartition(null);
+    SourceFactory factory = new SourceFactory([
+      new PackageMapUriResolver(resourceProvider, <String, List<Folder>>{
+        'root': <Folder>[rootFolder]
+      })
+    ]);
+    AnalysisTarget target = factory.forUri("package:root/root.dart");
+    expect(partition.isResponsibleFor(target), isTrue);
+  }
+}
+
+@reflectiveTest
 class ResultDataTest extends EngineTestCase {
   test_creation() {
     String value = 'value';
@@ -1113,8 +1178,10 @@
 
   void test_contains_true() {
     SdkCachePartition partition = new SdkCachePartition(null);
-    SourceFactory factory = new SourceFactory(
-        [new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]);
+    ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
+    FolderBasedDartSdk sdk = new FolderBasedDartSdk(resourceProvider,
+        FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
+    SourceFactory factory = new SourceFactory([new DartUriResolver(sdk)]);
     AnalysisTarget target = factory.forUri("dart:core");
     expect(partition.isResponsibleFor(target), isTrue);
   }
@@ -1177,6 +1244,15 @@
   _KeepContinueDelta(this.source, this.keepDescriptor);
 
   @override
+  bool gatherChanges(InternalAnalysisContext context, AnalysisTarget target,
+      ResultDescriptor descriptor, Object value) {
+    return false;
+  }
+
+  @override
+  void gatherEnd() {}
+
+  @override
   DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target,
       ResultDescriptor descriptor, Object value) {
     if (descriptor == keepDescriptor) {
diff --git a/pkg/analyzer/test/src/context/context_factory_test.dart b/pkg/analyzer/test/src/context/context_factory_test.dart
deleted file mode 100644
index a116d29..0000000
--- a/pkg/analyzer/test/src/context/context_factory_test.dart
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer.test.src.context.context_factory_test;
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/context/context_factory.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../reflective_tests.dart';
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  runReflectiveTests(PackageMapProcessorTest);
-}
-
-@reflectiveTest
-class PackageMapProcessorTest {
-  MemoryResourceProvider resourceProvider;
-
-  Folder empty;
-  Folder tmp_sdk_ext;
-  Folder tmp_embedder;
-  Map<String, List<Folder>> packageMap;
-
-  void setUp() {
-    resourceProvider = new MemoryResourceProvider();
-    empty = resourceProvider.newFolder('/empty');
-    tmp_sdk_ext = resourceProvider.newFolder('/tmp_sdk_ext');
-    tmp_embedder = resourceProvider.newFolder('/tmp_embedder');
-    packageMap = <String, List<Folder>>{
-      'empty': [empty],
-      'tmp_embedder': [tmp_embedder],
-      'tmp_sdk_ext': [tmp_sdk_ext]
-    };
-  }
-
-  void test_basic_processing() {
-    resourceProvider.newFile(
-        '/tmp_sdk_ext/_sdkext',
-        r'''
-  {
-    "dart:ui": "ui.dart"
-  }''');
-    resourceProvider.newFile(
-        '/tmp_embedder/_embedder.yaml',
-        r'''
-embedded_libs:
-  "dart:core" : "core.dart"
-  "dart:fox": "slippy.dart"
-  "dart:bear": "grizzly.dart"
-  "dart:relative": "../relative.dart"
-  "dart:deep": "deep/directory/file.dart"
-''');
-
-    PackageMapProcessor proc = new PackageMapProcessor(packageMap);
-    expect(proc.embeddedLibraries.size(), 5);
-    expect(proc.embeddedLibraries.getLibrary('dart:core').path,
-        '/tmp_embedder/core.dart');
-    expect(proc.extendedLibraries.size(), 1);
-    expect(proc.extendedLibraries.getLibrary('dart:ui').path,
-        '/tmp_sdk_ext/ui.dart');
-  }
-
-  void test_empty_package_map() {
-    PackageMapProcessor proc =
-        new PackageMapProcessor(<String, List<Folder>>{});
-    expect(proc.embeddedLibraries.size(), 0);
-    expect(proc.extendedLibraries.size(), 0);
-    expect(proc.libraryMap.size(), 0);
-  }
-
-  void test_extenders_do_not_override() {
-    resourceProvider.newFile(
-        '/tmp_sdk_ext/_sdkext',
-        r'''
-  {
-    "dart:ui": "ui2.dart"
-  }''');
-    resourceProvider.newFile(
-        '/tmp_embedder/_embedder.yaml',
-        r'''
-embedded_libs:
-  "dart:core" : "core.dart"
-  "dart:ui": "ui.dart"
-''');
-
-    PackageMapProcessor proc = new PackageMapProcessor(packageMap);
-    expect(proc.embeddedLibraries.size(), 2);
-    expect(proc.extendedLibraries.size(), 1);
-    expect(proc.libraryMap.size(), 2);
-    expect(proc.libraryMap.getLibrary('dart:ui').path, '/tmp_embedder/ui.dart');
-  }
-
-  void test_invalid_embedder() {
-    resourceProvider.newFile(
-        '/tmp_embedder/_embedder.yaml',
-        r'''
-invalid contents, will not parse
-''');
-
-    PackageMapProcessor proc = new PackageMapProcessor(packageMap);
-    expect(proc.embeddedLibraries.size(), 0);
-    expect(proc.extendedLibraries.size(), 0);
-    expect(proc.libraryMap.size(), 0);
-  }
-
-  void test_invalid_extender() {
-    resourceProvider.newFile(
-        '/tmp_sdk_ext/_sdkext',
-        r'''
-invalid contents, will not parse
-''');
-
-    PackageMapProcessor proc = new PackageMapProcessor(packageMap);
-    expect(proc.embeddedLibraries.size(), 0);
-    expect(proc.extendedLibraries.size(), 0);
-    expect(proc.libraryMap.size(), 0);
-  }
-
-  void test_no_embedder() {
-    resourceProvider.newFile(
-        '/tmp_sdk_ext/_sdkext',
-        r'''
-  {
-    "dart:ui": "ui2.dart"
-  }''');
-
-    PackageMapProcessor proc = new PackageMapProcessor(packageMap);
-    expect(proc.embeddedLibraries.size(), 0);
-    expect(proc.extendedLibraries.size(), 1);
-    expect(proc.libraryMap.size(), 1);
-  }
-
-  void test_no_embedder_or_extender() {
-    PackageMapProcessor proc = new PackageMapProcessor(packageMap);
-    expect(proc.embeddedLibraries.size(), 0);
-    expect(proc.extendedLibraries.size(), 0);
-    expect(proc.libraryMap.size(), 0);
-  }
-
-  void test_no_extender() {
-    resourceProvider.newFile(
-        '/tmp_embedder/_embedder.yaml',
-        r'''
-embedded_libs:
-  "dart:core" : "core.dart"
-  "dart:ui": "ui.dart"
-''');
-
-    PackageMapProcessor proc = new PackageMapProcessor(packageMap);
-    expect(proc.embeddedLibraries.size(), 2);
-    expect(proc.extendedLibraries.size(), 0);
-    expect(proc.libraryMap.size(), 2);
-  }
-}
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index a2f3cb3..adc7778 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -11,11 +11,13 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.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/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -153,6 +155,43 @@
     expect(entry.explicitlyAdded, isTrue);
   }
 
+  void test_applyChanges_addNewImport_invalidateLibraryCycle() {
+    context.analysisOptions =
+        new AnalysisOptionsImpl.from(context.analysisOptions)
+          ..strongMode = true;
+    Source embedder = addSource(
+        '/a.dart',
+        r'''
+library a;
+import 'b.dart';
+//import 'c.dart';
+''');
+    addSource(
+        '/b.dart',
+        r'''
+library b;
+import 'a.dart';
+''');
+    addSource(
+        '/c.dart',
+        r'''
+library c;
+import 'b.dart';
+''');
+    _performPendingAnalysisTasks();
+    // Add a new import into a.dart, this should invalidate its library cycle.
+    // If it doesn't, we will get a task cycle exception.
+    context.setContents(
+        embedder,
+        r'''
+library a;
+import 'b.dart';
+import 'c.dart';
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getCacheEntry(embedder).exception, isNull);
+  }
+
   Future test_applyChanges_change() {
     SourcesChangedListener listener = new SourcesChangedListener();
     context.onSourcesChanged.listen(listener.onData);
@@ -279,11 +318,74 @@
     });
   }
 
+  void test_applyChanges_changedSource_updateModificationTime() {
+    String path = '/test.dart';
+    File file = resourceProvider.newFile(path, 'var V = 1;');
+    Source source = file.createSource();
+    context.applyChanges(new ChangeSet()..addedSource(source));
+    // Analyze all.
+    _analyzeAll_assertFinished();
+    expect(context.analysisCache.getState(source, RESOLVED_UNIT),
+        CacheState.INVALID);
+    // Update the file and notify the context about the change.
+    resourceProvider.updateFile(path, 'var V = 2;');
+    context.applyChanges(new ChangeSet()..changedSource(source));
+    // The analysis results are invalidated.
+    // We have seen the new contents, so 'modificationTime' is also updated.
+    expect(context.analysisCache.getState(source, RESOLVED_UNIT),
+        CacheState.INVALID);
+    expect(
+        context.getCacheEntry(source).modificationTime, file.modificationStamp);
+  }
+
   void test_applyChanges_empty() {
     context.applyChanges(new ChangeSet());
     expect(context.performAnalysisTask().changeNotices, isNull);
   }
 
+  void test_applyChanges_incremental_resetDriver() {
+    context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
+    Source source = addSource(
+        "/test.dart",
+        r'''
+main() {
+  print(42);
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(source).errors, hasLength(0));
+    // Update the source to have a parse error.
+    // This is an incremental change, but we always invalidate DART_ERRORS.
+    context.setContents(
+        source,
+        r'''
+main() {
+  print(42)
+}
+''');
+    AnalysisCache cache = context.analysisCache;
+    expect(cache.getValue(source, PARSE_ERRORS), hasLength(1));
+    expect(cache.getState(source, DART_ERRORS), CacheState.INVALID);
+    // Perform enough analysis to prepare inputs (is not actually tested) for
+    // the DART_ERRORS computing task, but don't compute it yet.
+    context.performAnalysisTask();
+    context.performAnalysisTask();
+    expect(cache.getState(source, DART_ERRORS), CacheState.INVALID);
+    // Update the source so that PARSE_ERRORS is empty.
+    context.setContents(
+        source,
+        r'''
+main() {
+  print(42);
+}
+''');
+    expect(cache.getValue(source, PARSE_ERRORS), hasLength(0));
+    // After full analysis DART_ERRORS should also be empty.
+    _performPendingAnalysisTasks();
+    expect(cache.getValue(source, DART_ERRORS), hasLength(0));
+    expect(context.getErrors(source).errors, hasLength(0));
+  }
+
   void test_applyChanges_overriddenSource() {
     String content = "library test;";
     Source source = addSource("/test.dart", content);
@@ -316,7 +418,7 @@
     // initially: A
     {
       LibraryElement libraryElement =
-          context.getResult(exporterSource, LIBRARY_ELEMENT1) as LibraryElement;
+          context.getResult(exporterSource, LIBRARY_ELEMENT1);
       expect(libraryElement.exportNamespace.definedNames.keys,
           unorderedEquals(['A']));
     }
@@ -328,7 +430,7 @@
     _performPendingAnalysisTasks();
     {
       LibraryElement libraryElement =
-          context.getResult(exporterSource, LIBRARY_ELEMENT1) as LibraryElement;
+          context.getResult(exporterSource, LIBRARY_ELEMENT1);
       expect(libraryElement.exportNamespace.definedNames.keys,
           unorderedEquals(['B']));
     }
@@ -356,7 +458,7 @@
     expect(sources[0], same(libA));
     libAElement = context.computeLibraryElement(libA);
     importedLibraries = libAElement.importedLibraries;
-    expect(importedLibraries, hasLength(1));
+    expect(importedLibraries, hasLength(2));
     return pumpEventQueue().then((_) {
       listener.assertEvent(wereSourcesAdded: true);
       listener.assertEvent(wereSourcesAdded: true);
@@ -401,7 +503,6 @@
     expect(context.getResolvedCompilationUnit2(source, source), unit);
     // remove overlay
     context.setContents(source, null);
-    context.validateCacheConsistency();
     _analyzeAll_assertFinished();
     expect(context.getResolvedCompilationUnit2(source, source), unit);
   }
@@ -434,6 +535,127 @@
     });
   }
 
+  void test_applyChanges_removeUsedLibrary_addAgain() {
+    String codeA = r'''
+import 'b.dart';
+B b = null;
+''';
+    String codeB = r'''
+class B {}
+''';
+    Source a = addSource('/a.dart', codeA);
+    Source b = addSource('/b.dart', codeB);
+    CacheState getErrorsState(Source source) =>
+        context.analysisCache.getState(source, LIBRARY_ERRORS_READY);
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(a).errors, hasLength(0));
+    // Remove b.dart - errors in a.dart are invalidated and recomputed.
+    // Now a.dart has an error.
+    _removeSource(b);
+    expect(getErrorsState(a), CacheState.INVALID);
+    _performPendingAnalysisTasks();
+    expect(getErrorsState(a), CacheState.VALID);
+    expect(context.getErrors(a).errors, hasLength(isPositive));
+    // Add b.dart - errors in a.dart are invalidated and recomputed.
+    // The reason is that a.dart adds dependencies on (not existing) b.dart
+    // results in cache.
+    // Now a.dart does not have errors.
+    addSource('/b.dart', codeB);
+    expect(getErrorsState(a), CacheState.INVALID);
+    _performPendingAnalysisTasks();
+    expect(getErrorsState(a), CacheState.VALID);
+    expect(context.getErrors(a).errors, hasLength(0));
+  }
+
+  void test_cacheConsistencyValidator_computed_deleted() {
+    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
+    var stat = PerformanceStatistics.cacheConsistencyValidationStatistics;
+    stat.reset();
+    // Add sources.
+    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+    String path1 = '/test1.dart';
+    String path2 = '/test2.dart';
+    Source source1 = resourceProvider.newFile(path1, '// 1-1').createSource();
+    Source source2 = resourceProvider.newFile(path2, '// 2-1').createSource();
+    context.applyChanges(
+        new ChangeSet()..addedSource(source1)..addedSource(source2));
+    // Same modification times.
+    expect(
+        validator.sourceModificationTimesComputed([source1, source2],
+            [source1.modificationStamp, source2.modificationStamp]),
+        isFalse);
+    expect(stat.numOfChanged, 0);
+    expect(stat.numOfRemoved, 0);
+    // Add overlay
+    context.setContents(source1, '// 1-2');
+    expect(
+        validator.sourceModificationTimesComputed(
+            [source1, source2], [-1, source2.modificationStamp]),
+        isFalse);
+    context.setContents(source1, null);
+    expect(stat.numOfChanged, 0);
+    expect(stat.numOfRemoved, 0);
+    // Different modification times.
+    expect(
+        validator.sourceModificationTimesComputed(
+            [source1, source2], [-1, source2.modificationStamp]),
+        isTrue);
+    expect(stat.numOfChanged, 0);
+    expect(stat.numOfRemoved, 1);
+  }
+
+  void test_cacheConsistencyValidator_computed_modified() {
+    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
+    var stat = PerformanceStatistics.cacheConsistencyValidationStatistics;
+    stat.reset();
+    // Add sources.
+    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+    String path1 = '/test1.dart';
+    String path2 = '/test2.dart';
+    Source source1 = resourceProvider.newFile(path1, '// 1-1').createSource();
+    Source source2 = resourceProvider.newFile(path2, '// 2-1').createSource();
+    context.applyChanges(
+        new ChangeSet()..addedSource(source1)..addedSource(source2));
+    // Same modification times.
+    expect(
+        validator.sourceModificationTimesComputed([source1, source2],
+            [source1.modificationStamp, source2.modificationStamp]),
+        isFalse);
+    expect(stat.numOfChanged, 0);
+    expect(stat.numOfRemoved, 0);
+    // Add overlay
+    context.setContents(source1, '// 1-2');
+    expect(
+        validator.sourceModificationTimesComputed([source1, source2],
+            [source1.modificationStamp + 1, source2.modificationStamp]),
+        isFalse);
+    context.setContents(source1, null);
+    expect(stat.numOfChanged, 0);
+    expect(stat.numOfRemoved, 0);
+    // Different modification times.
+    expect(
+        validator.sourceModificationTimesComputed([source1, source2],
+            [source1.modificationStamp + 1, source2.modificationStamp]),
+        isTrue);
+    expect(stat.numOfChanged, 1);
+    expect(stat.numOfRemoved, 0);
+  }
+
+  void test_cacheConsistencyValidator_getSources() {
+    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
+    // Add sources.
+    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+    String path1 = '/test1.dart';
+    String path2 = '/test2.dart';
+    Source source1 = resourceProvider.newFile(path1, '// 1-1').createSource();
+    Source source2 = resourceProvider.newFile(path2, '// 2-1').createSource();
+    context.applyChanges(
+        new ChangeSet()..addedSource(source1)..addedSource(source2));
+    // Verify.
+    expect(validator.getSourcesToComputeModificationTimes(),
+        unorderedEquals([source1, source2]));
+  }
+
   void test_computeDocumentationComment_class_block() {
     String comment = "/** Comment */";
     Source source = addSource(
@@ -2079,7 +2301,7 @@
     if (context.analysisOptions.finerGrainedInvalidation) {
       expect(source.readCount, 7);
     } else {
-      expect(source.readCount, 4);
+      expect(source.readCount, 5);
     }
   }
 
@@ -2561,24 +2783,13 @@
    * Perform analysis tasks up to 512 times and assert that it was enough.
    */
   void _analyzeAll_assertFinished([int maxIterations = 512]) {
-    bool finishedAnalyzing = false;
     for (int i = 0; i < maxIterations; i++) {
       List<ChangeNotice> notice = context.performAnalysisTask().changeNotices;
       if (notice == null) {
-        finishedAnalyzing = true;
-        bool inconsistent = context.validateCacheConsistency();
-        if (!inconsistent) {
-          return;
-        }
+        return;
       }
     }
-    if (finishedAnalyzing) {
-      fail(
-          "performAnalysisTask failed to finish analyzing all sources after $maxIterations iterations");
-    } else {
-      fail(
-          "performAnalysisTask failed to terminate after analyzing all sources");
-    }
+    fail("performAnalysisTask failed to terminate after analyzing all sources");
   }
 
   void _assertNoExceptions() {
@@ -2675,6 +2886,49 @@
     context.analysisOptions = options;
   }
 
+  void test_class_addMethod_useAsHole_inTopLevelVariable() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {
+}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+var B = A.foo;
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+import 'b.dart';
+var C = B;
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(1));
+    // Update a.dart: add A.foo.
+    //   'B' in b.dart is invalid, because 'B' references 'foo'
+    //   c.dart is invalid, because 'C' references 'B'
+    context.setContents(
+        a,
+        r'''
+class A {
+  static void foo(int p) {}
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+
+    _assertValidForDependentLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(b, RESOLVED_UNIT4);
+
+    _assertValidForDependentLibrary(c);
+    _assertInvalid(c, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(c, RESOLVED_UNIT4);
+  }
+
   void test_class_addMethod_useClass() {
     Source a = addSource(
         '/a.dart',
@@ -2709,6 +2963,328 @@
     _assertValid(b, LIBRARY_ERRORS_READY);
   }
 
+  void test_class_annotation_add_deprecated() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+List<A> foo() => [];
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(0));
+    // Add @deprecated annotation.
+    // b.dart has valid resolution, because A is still A, so only errors are
+    // invalidated.
+    context.setContents(
+        a,
+        r'''
+@deprecated
+class A {}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertValidAllResolution(b);
+    // Analysis is done successfully.
+    _performPendingAnalysisTasks();
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(a, READY_RESOLVED_UNIT);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(b, READY_RESOLVED_UNIT);
+    expect(context.getErrors(b).errors, hasLength(1));
+  }
+
+  void test_class_annotation_remove_deprecated() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+@deprecated
+class A {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+List<A> foo() => [];
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(1));
+    // Add @deprecated annotation.
+    // b.dart has valid resolution, because A is still A, so only errors are
+    // invalidated.
+    context.setContents(
+        a,
+        r'''
+class A {}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertValidAllResolution(b);
+    // Analysis is done successfully.
+    _performPendingAnalysisTasks();
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(a, READY_RESOLVED_UNIT);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(b, READY_RESOLVED_UNIT);
+    expect(context.getErrors(b).errors, hasLength(0));
+  }
+
+  void test_class_constructor_named_changeName() {
+    // Update a.dart: change A.named() to A.named2().
+    //   b.dart is invalid, because it references A.named().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A.named();
+}
+''',
+        r'''
+class A {
+  A.named2();
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A.named();
+}
+''');
+  }
+
+  void test_class_constructor_named_parameters_add() {
+    // Update a.dart: add a new parameter to A.named().
+    //   b.dart is invalid, because it references A.named().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A.named();
+}
+''',
+        r'''
+class A {
+  A.named(int p);
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A.named();
+}
+''');
+  }
+
+  void test_class_constructor_named_parameters_change_usedSuper() {
+    // Update a.dart: change A.named().
+    //   b.dart is invalid, because it references A.named().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A.named(int a);
+}
+''',
+        r'''
+class A {
+  A.named(String a);
+}
+''',
+        r'''
+import 'a.dart';
+class B extends A {
+  B() : super.named(42);
+}
+''');
+  }
+
+  void test_class_constructor_named_parameters_remove() {
+    // Update a.dart: remove a new parameter of A.named().
+    //   b.dart is invalid, because it references A.named().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A.named(int p);
+}
+''',
+        r'''
+class A {
+  A.named();
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A.named();
+}
+''');
+  }
+
+  void test_class_constructor_named_remove_notUsed() {
+    // Update a.dart: remove A.foo().
+    //   b.dart is valid, because it does not reference A.foo().
+    _verifyTwoLibrariesAllValid(
+        r'''
+class A {
+  A.foo();
+  A.bar();
+}
+''',
+        r'''
+class A {
+  A.bar();
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A.bar();
+}
+''');
+  }
+
+  void test_class_constructor_named_remove_used() {
+    // Update a.dart: remove A.named().
+    //   b.dart is invalid, because it references A.named().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A.named();
+}
+''',
+        r'''
+class A {
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A.named();
+}
+''');
+  }
+
+  void test_class_constructor_unnamed_parameters_change_notUsedSuper() {
+    // Update a.dart: change A().
+    //   Resolution of b.dart is valid, because it does not reference A().
+    //   Hints and verify errors are invalid, because it extends A.
+    // TODO(scheglov) we could keep valid hints and verify errors,
+    // because only constructor is changed - this cannot add/remove
+    // inherited unimplemented members.
+    _verifyTwoLibrariesInvalidHintsVerifyErrors(
+        r'''
+class A {
+  A(int a);
+  A.named(int a);
+}
+''',
+        r'''
+class A {
+  A(String a);
+  A.named(int a);
+}
+''',
+        r'''
+import 'a.dart';
+class B extends A {
+  B() : super.named(42);
+}
+''');
+  }
+
+  void test_class_constructor_unnamed_parameters_change_usedSuper() {
+    // Update a.dart: change A().
+    //   b.dart is invalid, because it references A().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A(int a);
+}
+''',
+        r'''
+class A {
+  A(String a);
+}
+''',
+        r'''
+import 'a.dart';
+class B extends A {
+  B() : super(42);
+}
+''');
+  }
+
+  void test_class_constructor_unnamed_parameters_remove() {
+    // Update a.dart: change A().
+    //   b.dart is invalid, because it references A().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A(int a, int b);
+}
+''',
+        r'''
+class A {
+  A(int a);
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A(1, 2);
+}
+''');
+  }
+
+  void test_class_constructor_unnamed_remove_notUsed() {
+    // Update a.dart: remove A().
+    //   b.dart is invalid, because it instantiates A.
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A();
+  A.named();
+}
+''',
+        r'''
+class A {
+  A.named();
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A.named();
+}
+''');
+  }
+
+  void test_class_constructor_unnamed_remove_used() {
+    // Update a.dart: remove A().
+    //   b.dart is invalid, because it references A().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A();
+}
+''',
+        r'''
+class A {
+}
+''',
+        r'''
+import 'a.dart';
+main() {
+  new A();
+}
+''');
+  }
+
   void test_class_method_change_notUsed() {
     Source a = addSource(
         '/a.dart',
@@ -2816,6 +3392,88 @@
     _assertInvalid(b, LIBRARY_ERRORS_READY);
   }
 
+  void test_class_method_remove_notUsed_instantiated() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+abstract class I {
+ void foo();
+}
+class A implements I {
+ void foo() {}
+}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+main() {
+  new A();
+}
+''');
+    _performPendingAnalysisTasks();
+    // Update a.dart: remove 'A.foo'.
+    //   b.dart is valid because it does not reference 'foo'.
+    //     The class 'A' has a warning, but it is still not abstract.
+    context.setContents(
+        a,
+        r'''
+abstract class I {
+ void fo();
+}
+class A implements I {
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+
+    _assertValidForDependentLibrary(b);
+    _assertValidAllLibraryUnitResults(b);
+    _assertValidAllResolution(b);
+    _assertValidAllErrors(b);
+  }
+
+  void test_class_method_remove_subclass() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+abstract class I {
+ void foo();
+}
+class A implements I {
+ void foo() {}
+}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+class B extends A {}
+''');
+    _performPendingAnalysisTasks();
+    // Update a.dart: remove A.bar, add A.bar2.
+    //   b.dart
+    //     Resolution is valid because 'foo' is not referenced.
+    //     HINTS are invalid because 'B' might have invalid @override.
+    //     VERIFY_ERRORS are invalid because 'B' might not implement something.
+    //     Other errors are also invalid.
+    context.setContents(
+        a,
+        r'''
+abstract class I {
+ void foo();
+}
+class A implements I {
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+
+    _assertValidForDependentLibrary(b);
+    _assertValidAllResolution(b);
+    _assertInvalidHintsVerifyErrors(b);
+  }
+
   void test_class_private_member() {
     Source a = addSource(
         '/a.dart',
@@ -2865,52 +3523,27 @@
     _assertValid(b, LIBRARY_ERRORS_READY);
   }
 
-  void test_class_super_makeAbstract_instantiate() {
+  void test_enum_add() {
     Source a = addSource(
         '/a.dart',
         r'''
-abstract class I {
- void m();
-}
-class A implements I {
- void m() {}
-}
-''');
-    Source b = addSource(
-        '/b.dart',
-        r'''
-import 'a.dart';
-class B extends A {}
-''');
-    Source c = addSource(
-        '/c.dart',
-        r'''
-import 'b.dart';
 main() {
-  new B();
+  print(MyEnum.A);
 }
 ''');
     _performPendingAnalysisTasks();
-    // Update a.dart: remove A.bar, add A.bar2.
-    //   b.dart is valid, because it doesn't references 'bar' or 'bar2'.
+    // Insert a new enum declaration.
+    // No errors expected.
     context.setContents(
         a,
         r'''
-abstract class I {
- void m();
+main() {
+  print(MyEnum.A);
 }
-class A implements I {
- void m2() {}
-}
+enum MyEnum { A, B, C }
 ''');
-    _assertValidForChangedLibrary(a);
-    _assertInvalid(a, LIBRARY_ERRORS_READY);
-
-    _assertValidForDependentLibrary(b);
-    _assertInvalid(b, LIBRARY_ERRORS_READY);
-
-    _assertValidForDependentLibrary(c);
-    _assertInvalid(c, LIBRARY_ERRORS_READY);
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(a).errors, isEmpty);
   }
 
   void test_private_class() {
@@ -3005,6 +3638,48 @@
     _assertInvalid(b, LIBRARY_ERRORS_READY);
   }
 
+  void test_sequence_applyChanges_changedSource() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {}
+class B {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+main() {
+  new A();
+  new B();
+}
+''');
+    _performPendingAnalysisTasks();
+    resourceProvider.updateFile(
+        '/a.dart',
+        r'''
+class A2 {}
+class B {}
+''');
+    // Update a.dart: remove A, add A2.
+    //   b.dart is invalid, because it references A.
+    var changeSet = new ChangeSet()..changedSource(a);
+    context.applyChanges(changeSet);
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(b, RESOLVED_UNIT4);
+    // Analyze.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(a).errors, hasLength(0));
+    expect(context.getErrors(b).errors, hasLength(1));
+    _assertValid(a, READY_RESOLVED_UNIT);
+    _assertValid(b, READY_RESOLVED_UNIT);
+    _assertValidAllLibraryUnitResults(a);
+    _assertValidAllLibraryUnitResults(b);
+  }
+
   void test_sequence_class_give_take() {
     Source a = addSource(
         '/a.dart',
@@ -3060,6 +3735,580 @@
     expect(context.getErrors(b).errors, hasLength(1));
   }
 
+  void test_sequence_class_removeMethod_overridden() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {
+  void foo() {}
+}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+class B extends A {
+  @override
+  void foo() {}
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(0));
+    // Update a.dart: remove add A.foo.
+    //   b.dart has a new hint, because B.foo does not override anything
+    context.setContents(
+        a,
+        r'''
+class A {
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertValidAllResolution(b);
+    _assertInvalidHintsVerifyErrors(b);
+
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(1));
+  }
+
+  void test_sequence_clearParameterElements() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {
+  foo(int p) {}
+}
+final a = new A();
+main() {
+  a.foo(42);
+}
+''');
+    _performPendingAnalysisTasks();
+    Expression find42() {
+      CompilationUnit unit =
+          context.getResult(new LibrarySpecificUnit(a, a), RESOLVED_UNIT);
+      ExpressionStatement statement =
+          AstFinder.getStatementsInTopLevelFunction(unit, 'main').single;
+      MethodInvocation invocation = statement.expression;
+      return invocation.argumentList.arguments[0];
+    }
+
+    {
+      Expression argument = find42();
+      expect(argument.staticParameterElement, isNull);
+      expect(argument.propagatedParameterElement, isNotNull);
+    }
+    // Update a.dart: add type annotation for 'a'.
+    // '42' has 'staticParameterElement', but not 'propagatedParameterElement'.
+    context.setContents(
+        a,
+        r'''
+class A {
+  foo(int p) {}
+}
+final A a = new A();
+main() {
+  a.foo(42);
+}
+''');
+    _performPendingAnalysisTasks();
+    {
+      Expression argument = find42();
+      expect(argument.staticParameterElement, isNotNull);
+      expect(argument.propagatedParameterElement, isNull);
+    }
+    // Update a.dart: remove type annotation for 'a'.
+    // '42' has 'propagatedParameterElement', but not 'staticParameterElement'.
+    context.setContents(
+        a,
+        r'''
+class A {
+  foo(int p) {}
+}
+final a = new A();
+main() {
+  a.foo(42);
+}
+''');
+    _performPendingAnalysisTasks();
+    {
+      Expression argument = find42();
+      expect(argument.staticParameterElement, isNull);
+      expect(argument.propagatedParameterElement, isNotNull);
+    }
+  }
+
+  void test_sequence_closureParameterTypesPropagation() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+main() {
+  f((p) => 4.2);
+}
+f(c(int p)) {}
+''');
+    _performPendingAnalysisTasks();
+    LibrarySpecificUnit targetA = new LibrarySpecificUnit(a, a);
+    // Update and analyze.
+    String newCode = r'''
+newFunction() {}
+main() {
+  f((p) => 4.2);
+}
+f(c(int p)) {}
+''';
+    context.setContents(a, newCode);
+    _performPendingAnalysisTasks();
+    // Validate "(p) => 4.2" types.
+    CompilationUnit unit = context.getResult(targetA, RESOLVED_UNIT2);
+    SimpleIdentifier parameterName =
+        EngineTestCase.findSimpleIdentifier(unit, newCode, 'p) => 4.2);');
+    expect(parameterName.staticType, context.typeProvider.dynamicType);
+    expect(parameterName.propagatedType, context.typeProvider.intType);
+  }
+
+  void test_sequence_closureParameterTypesPropagation2() {
+    var code = r'''
+import 'b.dart';
+main(x) {
+  x.toMap();
+  f((p) => 'z');
+}
+f(double c(int p)) {}
+''';
+    Source a = addSource('/a.dart', code);
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'c.dart';
+''');
+    addSource(
+        '/c.dart',
+        r'''
+import 'd.dart';
+''');
+    Source d = addSource(
+        '/d.dart',
+        r'''
+class D {}
+''');
+    _performPendingAnalysisTasks();
+    LibrarySpecificUnit targetA = new LibrarySpecificUnit(a, a);
+    // Update b.dart, resolution in a.dart is not affected.
+    context.setContents(
+        b,
+        r'''
+import 'c.dart';
+class B {}
+''');
+    _assertValidAllResolution(a);
+    _performPendingAnalysisTasks();
+    // Update d.dart, this should invalidate a.dart and type propagation
+    // performed for the closure parameter.
+    context.setContents(
+        d,
+        r'''
+class D {
+  toMap() {}
+}
+''');
+    _assertValidUnits(a, RESOLVED_UNIT6);
+    _assertInvalidUnits(a, RESOLVED_UNIT7);
+    _performPendingAnalysisTasks();
+    // Validate "(p) =>" types.
+    {
+      CompilationUnit unit = context.getResult(targetA, RESOLVED_UNIT2);
+      SimpleIdentifier parameterName =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'p) =>');
+      expect(parameterName.staticType, context.typeProvider.dynamicType);
+      expect(parameterName.propagatedType, context.typeProvider.intType);
+    }
+  }
+
+  void test_sequence_compoundingResults_exportNamespace() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A<T> {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+export 'a.dart';
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+import 'b.dart';
+main() {
+  new A<int>();
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(c).errors, isEmpty);
+    // Update a.dart, so that `A<T>` has a type bound.
+    //   This should invalidate export namespace for b.dart.
+    //   Currently we invalidate the whole LIBRARY_ELEMENT4.
+    //   So, c.dart will see the new `A<T extends B>` and report an error.
+    context.setContents(
+        a,
+        r'''
+class A<T extends B> {}
+class B {}
+''');
+    _assertInvalid(b, LIBRARY_ELEMENT4);
+    // Analyze and validate that a new error is reported.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(c).errors, hasLength(1));
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(c, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_compoundingResults_invalidateButKeepDependency() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+import 'b.dart';
+class A {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+import 'c.dart';
+class B {}
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+class C {}
+''');
+    Source d = addSource(
+        '/d.dart',
+        r'''
+export 'b.dart';
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(c).errors, isEmpty);
+    // Update: a.dart (limited) and b.dart (limited).
+    //   This should invalidate LIBRARY_ELEMENT4 in d.dart, but it should be
+    //   done in a way that keep dependency of other results od d.dart on
+    //   LIBRARY_ELEMENT4 of d.dart, so that when we perform unlimited
+    //   invalidation of c.dart, this makes d.dart invalid.
+    context.setContents(
+        a,
+        r'''
+import 'b.dart';
+class A2 {}
+''');
+    context.setContents(
+        b,
+        r'''
+import 'a.dart';
+import 'c.dart';
+class B2 {}
+''');
+    context.setContents(
+        c,
+        r'''
+import 'dart:async';
+class C {}
+''');
+    _assertInvalid(d, LIBRARY_ELEMENT4);
+    _assertInvalid(d, LIBRARY_ERRORS_READY);
+    // Analyze and validate that a new error is reported.
+    _performPendingAnalysisTasks();
+    _assertValid(a, EXPORT_SOURCE_CLOSURE);
+    _assertValid(b, EXPORT_SOURCE_CLOSURE);
+    _assertValid(c, EXPORT_SOURCE_CLOSURE);
+    _assertValid(d, EXPORT_SOURCE_CLOSURE);
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(c, LIBRARY_ERRORS_READY);
+    _assertValid(d, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_compoundingResults_resolvedTypeNames() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+class B<T> {
+  B(p);
+}
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+export 'a.dart';
+export 'b.dart';
+''');
+    Source d = addSource(
+        '/d.dart',
+        r'''
+import 'c.dart';
+main() {
+  new B<int>(null);
+}
+''');
+    _performPendingAnalysisTasks();
+    // Update a.dart and b.dart
+    //   This should invalidate most results in a.dart and b.dart
+    //
+    //   This should also invalidate "compounding" results in c.dart, such as
+    //   READY_LIBRARY_ELEMENT6, which represent a state of the whole source
+    //   closure, not a result of this single unit or a library.
+    //
+    //   The reason is that although type names (RESOLVED_UNIT5) b.dart will be
+    //   eventually resolved and set into b.dart elements, it may happen
+    //   after we attempted to re-resolve c.dart, which created Member(s), and
+    //   attempts to use elements without types set.
+    context.setContents(
+        a,
+        r'''
+class A2 {}
+''');
+    context.setContents(
+        b,
+        r'''
+class B<T> {
+  B(T p);
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForChangedLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalid(c, READY_LIBRARY_ELEMENT6);
+    _assertInvalid(c, READY_LIBRARY_ELEMENT7);
+    // Analyze and validate that all results are valid.
+    _performPendingAnalysisTasks();
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(c, LIBRARY_ERRORS_READY);
+    _assertValid(d, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_dependenciesWithCycles() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+const A = 1;
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'c.dart';
+const B = C1 + 1;
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+import 'a.dart';
+import 'b.dart';
+const C1 = A + 1;
+const C2 = B + 2;
+''');
+    Source d = addSource(
+        '/d.dart',
+        r'''
+import 'c.dart';
+const D = C2 + 1;
+''');
+    _performPendingAnalysisTasks();
+    // Update "A" constant.
+    // This should invalidate results in all sources.
+    context.setContents(
+        a,
+        r'''
+const A = 2;
+''');
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalid(c, LIBRARY_ERRORS_READY);
+    _assertInvalid(d, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_duplicateField_syntheticAndNot_renameNotSynthetic() {
+    context.analysisOptions =
+        new AnalysisOptionsImpl.from(context.analysisOptions)
+          ..strongMode = true;
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {
+  int foo;
+  int get foo => 1;
+}
+class B extends A {
+  int get foo => 2;
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(a).errors, hasLength(2));
+    // Update a.dart: rename "int foo" to "int bar".
+    // The strong mode "getter cannot override field" error is gone.
+    context.setContents(
+        a,
+        r'''
+class A {
+  int bar;
+  int get foo => 1;
+}
+class B extends A {
+  int get foo => 2;
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(a).errors, isEmpty);
+  }
+
+  void test_sequence_inBodyChange_addRef_deltaChange() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {
+}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+main(A a) {
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(0));
+    // Update b.dart: in-body incremental change - start referencing 'foo'.
+    //   Should update referenced names.
+    context.setContents(
+        b,
+        r'''
+import 'a.dart';
+main(A a) {
+  a.foo;
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(1));
+    // Update a.dart: add A.foo
+    //   b.dart is invalid, because it references 'foo'.
+    context.setContents(
+        a,
+        r'''
+class A {
+  int foo;
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(b, RESOLVED_UNIT4);
+    // No errors after analysis.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(0));
+  }
+
+  void test_sequence_inBodyChange_removeRef_deltaChange() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {
+}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+main(A a) {
+  a.foo;
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(1));
+    // Update b.dart: in-body incremental change - stop referencing 'foo'.
+    //   Should update referenced names.
+    context.setContents(
+        b,
+        r'''
+import 'a.dart';
+main(A a) {
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(b).errors, hasLength(0));
+    // Update a.dart: add A.foo
+    //   b.dart is still valid, because it does references 'foo' anymore.
+    context.setContents(
+        a,
+        r'''
+class A {
+  int foo;
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertValidAllLibraryUnitResults(b);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_middleLimited_thenFirstFull() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+export 'a.dart';
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+import 'b.dart';
+A a;
+''');
+    _performPendingAnalysisTasks();
+    // Update b.dart: limited invalidation.
+    // Results in c.dart are valid, because the change in b.dart does not
+    // affect anything in c.dart.
+    context.setContents(
+        b,
+        r'''
+export 'a.dart';
+class B {}
+''');
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertValid(c, LIBRARY_ERRORS_READY);
+    _assertUnitValid(c, RESOLVED_UNIT4);
+    _assertUnitValid(c, RESOLVED_UNIT5);
+    // Update a.dart: unlimited invalidation.
+    // Results RESOLVED_UNIT4, RESOLVED_UNIT5, and RESOLVED_UNIT6 in c.dart
+    // are invalid, because after unlimited change to a.dart everything
+    // should be invalidated.
+    // This fixes the problem that c.dart was not re-resolving type names.
+    context.setContents(
+        a,
+        r'''
+import 'dart:async';
+class A {}
+''');
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalid(c, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(c, RESOLVED_UNIT4);
+  }
+
   void test_sequence_noChange_thenChange() {
     Source a = addSource(
         '/a.dart',
@@ -3138,8 +4387,8 @@
     _assertValidForChangedLibrary(a);
     _assertInvalid(a, LIBRARY_ERRORS_READY);
     _assertValidForDependentLibrary(b);
-    _assertInvalid(b, LIBRARY_ERRORS_READY);
-    _assertInvalidUnits(b, RESOLVED_UNIT4);
+    _assertValidAllResolution(b);
+    _assertValidAllErrors(b);
     // The a.dart's unit and element are the same.
     {
       LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
@@ -3153,6 +4402,194 @@
     expect(context.getErrors(b).errors, hasLength(0));
   }
 
+  void test_sequence_parts_disableForPart() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+library my_lib;
+part 'b.dart';
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+part of my_lib;
+class A {}
+''');
+    _performPendingAnalysisTasks();
+    // Update b.dart - it is a part, which we don't support.
+    // So, invalidate everything.
+    context.setContents(
+        b,
+        r'''
+part of my_lib;
+class A {}
+class B {}
+''');
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(a, RESOLVED_UNIT2);
+    _assertInvalidUnits(b, RESOLVED_UNIT1);
+  }
+
+  void test_sequence_parts_disableWithPart() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+library my_lib;
+part 'b.dart';
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+part of my_lib;
+class B {}
+''');
+    _performPendingAnalysisTasks();
+    // Update a.dart - it is a library with a part, which we don't support.
+    // So, invalidate everything.
+    context.setContents(
+        a,
+        r'''
+library my_lib;
+part 'b.dart';
+class A {}
+''');
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(a, RESOLVED_UNIT1);
+    _assertInvalidUnits(b, RESOLVED_UNIT1);
+  }
+
+  void test_sequence_reorder_localFunctions() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+f1() {
+  localFunction() {
+    const C = 1;
+  }
+}
+f2() {}
+''');
+    _performPendingAnalysisTasks();
+    // Update a.dart: reorder functions.
+    // This should not fail with FrozenHashCodeException, because identifiers
+    // of local elements should be relative to the enclosing top-level elements.
+    context.setContents(
+        a,
+        r'''
+f2() {}
+f1() {
+  localFunction() {
+    const C = 1;
+  }
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_unitConstants_addRemove() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+const A = 1;
+const B = 2;
+const C = 3;
+foo() {
+  const V1 = 10;
+}
+bar() {
+  const V2 = 20;
+}
+''');
+    _performPendingAnalysisTasks();
+    LibrarySpecificUnit unitA = new LibrarySpecificUnit(a, a);
+    List<ConstantEvaluationTarget> oldConstants =
+        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
+    expect(oldConstants, hasLength(5));
+    ConstVariableElement oldA = _findConstVariable(oldConstants, 'A');
+    ConstVariableElement oldB = _findConstVariable(oldConstants, 'B');
+    ConstVariableElement oldC = _findConstVariable(oldConstants, 'C');
+    ConstVariableElement oldV1 = _findConstVariable(oldConstants, 'V1');
+    ConstVariableElement oldV2 = _findConstVariable(oldConstants, 'V2');
+    expect(context.analysisCache.get(oldA), isNotNull);
+    expect(context.analysisCache.get(oldB), isNotNull);
+    expect(context.analysisCache.get(oldC), isNotNull);
+    expect(context.analysisCache.get(oldV1), isNotNull);
+    // Update and validate new constants.
+    context.setContents(
+        a,
+        r'''
+const A = 1;
+const B = 2;
+const D = 4;
+foo() {
+  const V1 = 10;
+}
+baz() {
+  const V3 = 30;
+}
+''');
+    List<ConstantEvaluationTarget> newConstants =
+        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
+    expect(newConstants, hasLength(5));
+    expect(newConstants, contains(same(oldA)));
+    expect(newConstants, contains(same(oldB)));
+    expect(newConstants, contains(same(oldV1)));
+    ConstVariableElement newD = _findConstVariable(newConstants, 'D');
+    ConstVariableElement newV3 = _findConstVariable(newConstants, 'V3');
+    // Perform analysis, compute constant values.
+    _performPendingAnalysisTasks();
+    // Validate const variable values.
+    expect(context.analysisCache.get(oldA), isNotNull);
+    expect(context.analysisCache.get(oldB), isNotNull);
+    expect(context.analysisCache.get(oldV1), isNotNull);
+    expect(context.analysisCache.get(oldC), isNull);
+    expect(context.analysisCache.get(oldV2), isNull);
+    expect(context.analysisCache.get(newD), isNotNull);
+    expect(context.analysisCache.get(newV3), isNotNull);
+    expect(oldA.evaluationResult.value.toIntValue(), 1);
+    expect(oldB.evaluationResult.value.toIntValue(), 2);
+    expect(newD.evaluationResult.value.toIntValue(), 4);
+    expect(oldV1.evaluationResult.value.toIntValue(), 10);
+    expect(newV3.evaluationResult.value.toIntValue(), 30);
+  }
+
+  void test_sequence_unitConstants_local_insertSpace() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+main() {
+  const C = 1;
+}
+''');
+    _performPendingAnalysisTasks();
+    LibrarySpecificUnit unitA = new LibrarySpecificUnit(a, a);
+    List<ConstantEvaluationTarget> oldConstants =
+        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
+    expect(oldConstants, hasLength(1));
+    ConstVariableElement C = _findConstVariable(oldConstants, 'C');
+    expect(context.analysisCache.get(C), isNotNull);
+    // Insert a space before the name.
+    context.setContents(
+        a,
+        r'''
+main() {
+  const  C = 1;
+}
+''');
+    List<ConstantEvaluationTarget> newConstants =
+        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
+    expect(newConstants, hasLength(1));
+    expect(newConstants, contains(same(C)));
+    // Perform analysis, compute constant values.
+    _performPendingAnalysisTasks();
+    // Validate const variable values.
+    expect(context.analysisCache.get(C), isNotNull);
+    expect(C.evaluationResult.value.toIntValue(), 1);
+  }
+
   void test_sequence_useAnyResolvedUnit() {
     Source a = addSource(
         '/a.dart',
@@ -3408,8 +4845,8 @@
 ''');
     _performPendingAnalysisTasks();
     // Update a.dart: remove A.m, add A.m2.
-    //   b.dart is invalid, because B extends A.
-    //   c.dart is invalid, because 'main' references B.
+    //   b.dart has valid resolution, and invalid errors.
+    //   c.dart is invalid, because 'main' references 'm'.
     context.setContents(
         a,
         r'''
@@ -3421,9 +4858,8 @@
     _assertInvalid(a, LIBRARY_ERRORS_READY);
 
     _assertValidForDependentLibrary(b);
-    _assertInvalidLibraryElements(b, LIBRARY_ELEMENT4);
-    _assertInvalidUnits(b, RESOLVED_UNIT4);
-    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertValidAllResolution(b);
+    _assertInvalidHintsVerifyErrors(b);
 
     _assertValidForDependentLibrary(c);
     _assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
@@ -3471,12 +4907,9 @@
 ''');
     _assertInvalid(a, LIBRARY_ERRORS_READY);
 
-    // TODO(scheglov) In theory b.dart is not affected, because it does not
-    // call A.m, does not override it, etc.
     _assertValidForDependentLibrary(b);
-    _assertInvalidLibraryElements(b, LIBRARY_ELEMENT4);
-    _assertInvalidUnits(b, RESOLVED_UNIT4);
-    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertValidAllResolution(b);
+    _assertInvalidHintsVerifyErrors(b);
 
     _assertValidForDependentLibrary(c);
     _assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
@@ -3492,6 +4925,18 @@
   }
 
   /**
+   * Assert that [VERIFY_ERRORS] and other error results that include it,
+   * are invalid.
+   */
+  void _assertInvalidHintsVerifyErrors(Source unit) {
+    _assertUnitInvalid(unit, HINTS);
+    _assertUnitInvalid(unit, VERIFY_ERRORS);
+    _assertUnitInvalid(unit, LIBRARY_UNIT_ERRORS);
+    _assertInvalid(unit, DART_ERRORS);
+    _assertInvalid(unit, LIBRARY_ERRORS_READY);
+  }
+
+  /**
    * Assert that [LIBRARY_ELEMENT_RESULTS] for [first] and after it are invalid.
    */
   void _assertInvalidLibraryElements(
@@ -3545,17 +4990,40 @@
         reason: '$descriptor in $target');
   }
 
-  void _assertValidAllLibraryUnitResults(Source source, {Source library}) {
-    for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
-      _assertValid(source, result);
+  /**
+   * Assert that all error results for the given [unit] are valid.
+   */
+  void _assertValidAllErrors(Source unit) {
+    for (ListResultDescriptor<AnalysisError> result in ERROR_SOURCE_RESULTS) {
+      _assertValid(unit, result);
     }
+    for (ListResultDescriptor<AnalysisError> result in ERROR_UNIT_RESULTS) {
+      _assertUnitValid(unit, result);
+    }
+  }
+
+  void _assertValidAllLibraryUnitResults(Source source, {Source library}) {
     library ??= source;
+    for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
+      if (result == LIBRARY_ELEMENT4) {
+        continue;
+      }
+      _assertValid(library, result);
+    }
     LibrarySpecificUnit target = new LibrarySpecificUnit(library, source);
     for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
       _assertValid(target, result);
     }
   }
 
+  void _assertValidAllResolution(Source unit) {
+    _assertValidUnits(unit, null);
+    _assertUnitValidTaskResults(unit, ResolveUnitTypeNamesTask.DESCRIPTOR);
+    _assertUnitValidTaskResults(unit, ResolveUnitTask.DESCRIPTOR);
+    _assertValidTaskResults(unit, ResolveLibraryReferencesTask.DESCRIPTOR);
+    _assertValidTaskResults(unit, ResolveLibraryTask.DESCRIPTOR);
+  }
+
   void _assertValidForAnyLibrary(Source source) {
     // Source results.
     _assertValidTaskResults(source, ScanDartTask.DESCRIPTOR);
@@ -3589,6 +5057,25 @@
     }
   }
 
+  void _assertValidUnits(Source unit, ResultDescriptor<CompilationUnit> last,
+      {Source library}) {
+    var target = new LibrarySpecificUnit(library ?? unit, unit);
+    bool foundLast = false;
+    for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
+      if (!foundLast) {
+        _assertValid(target, result);
+      }
+      foundLast = foundLast || result == last;
+    }
+  }
+
+  ConstVariableElement _findConstVariable(
+      List<ConstantEvaluationTarget> constants, String name) {
+    return constants.singleWhere((c) {
+      return c is ConstVariableElement && c.name == name;
+    });
+  }
+
   void _performPendingAnalysisTasks([int maxTasks = 512]) {
     for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) {
       if (i > maxTasks) {
@@ -3596,6 +5083,46 @@
       }
     }
   }
+
+  void _verifyTwoLibrariesAllValid(
+      String firstCodeA, String secondCodeA, String codeB) {
+    Source a = addSource('/a.dart', firstCodeA);
+    Source b = addSource('/b.dart', codeB);
+    _performPendingAnalysisTasks();
+    context.setContents(a, secondCodeA);
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertValidAllResolution(b);
+    _assertValidAllErrors(b);
+  }
+
+  void _verifyTwoLibrariesInvalidatesResolution(
+      String firstCodeA, String secondCodeA, String codeB) {
+    Source a = addSource('/a.dart', firstCodeA);
+    Source b = addSource('/b.dart', codeB);
+    _performPendingAnalysisTasks();
+    context.setContents(a, secondCodeA);
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(b, RESOLVED_UNIT4);
+  }
+
+  void _verifyTwoLibrariesInvalidHintsVerifyErrors(
+      String firstCodeA, String secondCodeA, String codeB) {
+    Source a = addSource('/a.dart', firstCodeA);
+    Source b = addSource('/b.dart', codeB);
+    _performPendingAnalysisTasks();
+    context.setContents(a, secondCodeA);
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertValidAllResolution(b);
+    _assertUnitValid(b, RESOLVE_UNIT_ERRORS);
+    _assertInvalidHintsVerifyErrors(b);
+  }
 }
 
 class _AnalysisContextImplTest_Source_exists_true extends TestSource {
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index 6539e67..91cc635 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -4,6 +4,7 @@
 
 library analyzer.test.src.context.mock_sdk;
 
+import 'package:analyzer/dart/element/element.dart' show LibraryElement;
 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/cache.dart';
@@ -11,10 +12,27 @@
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
+import 'package:analyzer/src/summary/summarize_elements.dart'
+    show PackageBundleAssembler;
+
+const String librariesContent = r'''
+const Map<String, LibraryInfo> libraries = const {
+  "async": const LibraryInfo("async/async.dart"),
+  "collection": const LibraryInfo("collection/collection.dart"),
+  "convert": const LibraryInfo("convert/convert.dart"),
+  "core": const LibraryInfo("core/core.dart"),
+  "html": const LibraryInfo("html/dartium/html_dartium.dart"),
+  "math": const LibraryInfo("math/math.dart"),
+  "_foreign_helper": const LibraryInfo("_internal/js_runtime/lib/foreign_helper.dart"),
+};
+''';
+
+const String sdkRoot = '/sdk';
 
 const _MockSdkLibrary _LIB_ASYNC = const _MockSdkLibrary(
     'dart:async',
-    '/lib/async/async.dart',
+    '$sdkRoot/lib/async/async.dart',
     '''
 library dart.async;
 
@@ -29,7 +47,9 @@
 
   static Future<List/*<T>*/> wait/*<T>*/(
       Iterable<Future/*<T>*/> futures) => null;
-  Future/*<R>*/ then/*<R>*/(/*=R*/ onValue(T value)) => null;
+  Future/*<R>*/ then/*<R>*/(onValue(T value)) => null;
+
+  Future<T> whenComplete(action());
 }
 
 abstract class Completer<T> {
@@ -42,7 +62,7 @@
 }
 ''',
     const <String, String>{
-      '/lib/async/stream.dart': r'''
+      '$sdkRoot/lib/async/stream.dart': r'''
 part of dart.async;
 class Stream<T> {
   Future<T> get first;
@@ -53,7 +73,7 @@
 
 const _MockSdkLibrary _LIB_COLLECTION = const _MockSdkLibrary(
     'dart:collection',
-    '/lib/collection/collection.dart',
+    '$sdkRoot/lib/collection/collection.dart',
     '''
 library dart.collection;
 
@@ -62,7 +82,7 @@
 
 const _MockSdkLibrary _LIB_CONVERT = const _MockSdkLibrary(
     'dart:convert',
-    '/lib/convert/convert.dart',
+    '$sdkRoot/lib/convert/convert.dart',
     '''
 library dart.convert;
 
@@ -74,7 +94,7 @@
 
 const _MockSdkLibrary _LIB_CORE = const _MockSdkLibrary(
     'dart:core',
-    '/lib/core/core.dart',
+    '$sdkRoot/lib/core/core.dart',
     '''
 library dart.core;
 
@@ -194,6 +214,10 @@
 
   /*=R*/ fold/*<R>*/(/*=R*/ initialValue,
       /*=R*/ combine(/*=R*/ previousValue, E element));
+
+  Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element));
+
+  List<E> toList();
 }
 
 class List<E> implements Iterable<E> {
@@ -224,6 +248,9 @@
 
 void print(Object object) {}
 
+const proxy = const _Proxy();
+class _Proxy { const _Proxy(); }
+
 class _Override {
   const _Override();
 }
@@ -232,7 +259,7 @@
 
 const _MockSdkLibrary _LIB_FOREIGN_HELPER = const _MockSdkLibrary(
     'dart:_foreign_helper',
-    '/lib/_foreign_helper/_foreign_helper.dart',
+    '$sdkRoot/lib/_foreign_helper/_foreign_helper.dart',
     '''
 library dart._foreign_helper;
 
@@ -243,7 +270,7 @@
 
 const _MockSdkLibrary _LIB_HTML = const _MockSdkLibrary(
     'dart:html',
-    '/lib/html/dartium/html_dartium.dart',
+    '$sdkRoot/lib/html/dartium/html_dartium.dart',
     '''
 library dart.html;
 class HtmlElement {}
@@ -251,7 +278,7 @@
 
 const _MockSdkLibrary _LIB_MATH = const _MockSdkLibrary(
     'dart:math',
-    '/lib/math/math.dart',
+    '$sdkRoot/lib/math/math.dart',
     '''
 library dart.math;
 
@@ -284,22 +311,21 @@
 
 class MockSdk implements DartSdk {
   static const Map<String, String> FULL_URI_MAP = const {
-    "dart:core": "/lib/core/core.dart",
-    "dart:html": "/lib/html/dartium/html_dartium.dart",
-    "dart:async": "/lib/async/async.dart",
-    "dart:async/stream.dart": "/lib/async/stream.dart",
-    "dart:collection": "/lib/collection/collection.dart",
-    "dart:convert": "/lib/convert/convert.dart",
-    "dart:_foreign_helper": "/lib/_foreign_helper/_foreign_helper.dart",
-    "dart:math": "/lib/math/math.dart"
+    "dart:core": "$sdkRoot/lib/core/core.dart",
+    "dart:html": "$sdkRoot/lib/html/dartium/html_dartium.dart",
+    "dart:async": "$sdkRoot/lib/async/async.dart",
+    "dart:async/stream.dart": "$sdkRoot/lib/async/stream.dart",
+    "dart:collection": "$sdkRoot/lib/collection/collection.dart",
+    "dart:convert": "$sdkRoot/lib/convert/convert.dart",
+    "dart:_foreign_helper": "$sdkRoot/lib/_foreign_helper/_foreign_helper.dart",
+    "dart:math": "$sdkRoot/lib/math/math.dart"
   };
 
   static const Map<String, String> NO_ASYNC_URI_MAP = const {
-    "dart:core": "/lib/core/core.dart",
+    "dart:core": "$sdkRoot/lib/core/core.dart",
   };
 
-  final resource.MemoryResourceProvider provider =
-      new resource.MemoryResourceProvider();
+  final resource.MemoryResourceProvider provider;
 
   final Map<String, String> uriMap;
 
@@ -311,8 +337,14 @@
   @override
   final List<SdkLibrary> sdkLibraries;
 
-  MockSdk({bool dartAsync: true})
-      : sdkLibraries = dartAsync ? _LIBRARIES : [_LIB_CORE],
+  /**
+   * The cached linked bundle of the SDK.
+   */
+  PackageBundle _bundle;
+
+  MockSdk({bool dartAsync: true, resource.ResourceProvider resourceProvider})
+      : provider = resourceProvider ?? new resource.MemoryResourceProvider(),
+        sdkLibraries = dartAsync ? _LIBRARIES : [_LIB_CORE],
         uriMap = dartAsync ? FULL_URI_MAP : NO_ASYNC_URI_MAP {
     for (_MockSdkLibrary library in sdkLibraries) {
       provider.newFile(library.path, library.content);
@@ -320,6 +352,8 @@
         provider.newFile(path, content);
       });
     }
+    provider.newFile(
+        '/_internal/sdk_library_metadata/lib/libraries.dart', librariesContent);
   }
 
   @override
@@ -342,7 +376,7 @@
   @override
   Source fromFileUri(Uri uri) {
     String filePath = uri.path;
-    String libPath = '/lib';
+    String libPath = '$sdkRoot/lib';
     if (!filePath.startsWith("$libPath/")) {
       return null;
     }
@@ -373,6 +407,22 @@
   }
 
   @override
+  PackageBundle getLinkedBundle() {
+    if (_bundle == null) {
+      PackageBundleAssembler assembler = new PackageBundleAssembler();
+      for (SdkLibrary sdkLibrary in sdkLibraries) {
+        String uriStr = sdkLibrary.shortName;
+        Source source = mapDartUri(uriStr);
+        LibraryElement libraryElement = context.computeLibraryElement(source);
+        assembler.serializeLibraryElement(libraryElement);
+      }
+      List<int> bytes = assembler.assemble().toBuffer();
+      _bundle = new PackageBundle.fromBuffer(bytes);
+    }
+    return _bundle;
+  }
+
+  @override
   SdkLibrary getSdkLibrary(String dartUri) {
     // getSdkLibrary() is only used to determine whether a library is internal
     // to the SDK.  The mock SDK doesn't have any internals, so it's safe to
@@ -393,6 +443,19 @@
     // table above.
     return null;
   }
+
+  /**
+   * This method is used to apply patches to [MockSdk].  It may be called only
+   * before analysis, i.e. before the analysis context was created.
+   */
+  void updateUriFile(String uri, String updateContent(String content)) {
+    assert(_analysisContext == null);
+    String path = FULL_URI_MAP[uri];
+    assert(path != null);
+    String content = provider.getFile(path).readAsStringSync();
+    String newContent = updateContent(content);
+    provider.updateFile(path, newContent);
+  }
 }
 
 class _MockSdkLibrary implements SdkLibrary {
diff --git a/pkg/analyzer/test/src/context/test_all.dart b/pkg/analyzer/test/src/context/test_all.dart
index 33c2986..d0f1619 100644
--- a/pkg/analyzer/test/src/context/test_all.dart
+++ b/pkg/analyzer/test/src/context/test_all.dart
@@ -9,7 +9,6 @@
 import '../../utils.dart';
 import 'builder_test.dart' as builder_test;
 import 'cache_test.dart' as cache_test;
-import 'context_factory_test.dart' as context_factory_test;
 import 'context_test.dart' as context_test;
 
 /// Utility for manually running all tests.
@@ -18,7 +17,6 @@
   group('context tests', () {
     builder_test.main();
     cache_test.main();
-    context_factory_test.main();
     context_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 960726e..dd3c4f3 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -30,6 +30,7 @@
   initializeTestEnvironment();
   runReflectiveTests(ConstantValueComputerTest);
   runReflectiveTests(ConstantVisitorTest);
+  runReflectiveTests(StrongConstantValueComputerTest);
 }
 
 /**
@@ -275,7 +276,7 @@
       analysisContext.computeErrors(source);
       expect(unit, isNotNull);
       ConstantValueComputer computer = _makeConstantValueComputer();
-      computer.add(unit, source, source);
+      computer.add(unit);
       computer.computeValues();
       NodeList<CompilationUnitMember> members = unit.declarations;
       expect(members, hasLength(3));
@@ -296,7 +297,7 @@
         analysisContext.resolveCompilationUnit(source, libraryElement);
     expect(unit, isNotNull);
     ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, source, source);
+    computer.add(unit);
     computer.computeValues();
     NodeList<CompilationUnitMember> members = unit.declarations;
     expect(members, hasLength(2));
@@ -331,8 +332,8 @@
         analysisContext.resolveCompilationUnit(partSource, libraryElement);
     expect(partUnit, isNotNull);
     ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(libraryUnit, librarySource, librarySource);
-    computer.add(partUnit, partSource, librarySource);
+    computer.add(libraryUnit);
+    computer.add(partUnit);
     computer.computeValues();
     NodeList<CompilationUnitMember> libraryMembers = libraryUnit.declarations;
     expect(libraryMembers, hasLength(2));
@@ -353,7 +354,7 @@
         analysisContext.resolveCompilationUnit(source, libraryElement);
     expect(unit, isNotNull);
     ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, source, source);
+    computer.add(unit);
     computer.computeValues();
     NodeList<CompilationUnitMember> members = unit.declarations;
     expect(members, hasLength(1));
@@ -370,7 +371,7 @@
         analysisContext.resolveCompilationUnit(source, libraryElement);
     expect(unit, isNotNull);
     ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, source, source);
+    computer.add(unit);
     computer.computeValues();
     TopLevelVariableDeclaration declaration = unit.declarations
         .firstWhere((member) => member is TopLevelVariableDeclaration);
@@ -1200,7 +1201,7 @@
         analysisContext.resolveCompilationUnit(source, element);
     expect(unit, isNotNull);
     ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, source, source);
+    computer.add(unit);
     computer.computeValues();
     assertErrors(source, expectedErrorCodes);
   }
@@ -1380,7 +1381,6 @@
     ConstantEvaluationValidator_ForTest validator =
         new ConstantEvaluationValidator_ForTest(analysisContext2);
     validator.computer = new ConstantValueComputer(
-        analysisContext2,
         analysisContext2.typeProvider,
         analysisContext2.declaredVariables,
         validator,
@@ -1601,3 +1601,11 @@
     return result;
   }
 }
+
+@reflectiveTest
+class StrongConstantValueComputerTest extends ConstantValueComputerTest {
+  void setUp() {
+    super.setUp();
+    resetWithOptions(new AnalysisOptionsImpl()..strongMode = true);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/constant/utilities_test.dart b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
index f4fd958..48443b3 100644
--- a/pkg/analyzer/test/src/dart/constant/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
@@ -183,7 +183,7 @@
   }
 
   List<ConstantEvaluationTarget> _findConstants() {
-    ConstantFinder finder = new ConstantFinder(_context, _source, _source);
+    ConstantFinder finder = new ConstantFinder();
     _node.accept(finder);
     List<ConstantEvaluationTarget> constants = finder.constantsToCompute;
     expect(constants, isNotNull);
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index a6e718d..b8a61fe 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2782,6 +2782,31 @@
     expect(parameterTypes[0], same(typeI));
   }
 
+  void test_getMethod_parameterized_flushCached_whenVersionChanges() {
+    //
+    // 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];
+    // Methods list is cached.
+    MethodElement method = typeAI.methods.single;
+    expect(typeAI.methods.single, same(method));
+    // Methods list is flushed on version change.
+    classA.version++;
+    expect(typeAI.methods.single, isNot(same(method)));
+  }
+
   void test_getMethod_unimplemented() {
     //
     // class A {}
diff --git a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
new file mode 100644
index 0000000..49738ff
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
@@ -0,0 +1,426 @@
+// 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.sdk_test;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../generated/test_support.dart';
+import '../../../reflective_tests.dart';
+import '../../../resource_utils.dart';
+import '../../../source/embedder_test.dart';
+import '../../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(EmbedderSdkTest);
+  runReflectiveTests(FolderBasedDartSdkTest);
+  runReflectiveTests(SdkExtensionFinderTest);
+  runReflectiveTests(SDKLibrariesReaderTest);
+}
+
+@reflectiveTest
+class EmbedderSdkTest extends EmbedderRelatedTest {
+  void test_creation() {
+    EmbedderYamlLocator locator = new EmbedderYamlLocator({
+      'fox': [pathTranslator.getResource('/tmp')]
+    });
+    EmbedderSdk sdk = new EmbedderSdk(resourceProvider, locator.embedderYamls);
+
+    expect(sdk.urlMappings, hasLength(5));
+  }
+
+  void test_fromFileUri() {
+    EmbedderYamlLocator locator = new EmbedderYamlLocator({
+      'fox': [pathTranslator.getResource('/tmp')]
+    });
+    EmbedderSdk sdk = new EmbedderSdk(resourceProvider, locator.embedderYamls);
+
+    expectSource(String posixPath, String dartUri) {
+      Uri uri = Uri.parse(posixToOSFileUri(posixPath));
+      Source source = sdk.fromFileUri(uri);
+      expect(source, isNotNull, reason: posixPath);
+      expect(source.uri.toString(), dartUri);
+      expect(source.fullName, posixToOSPath(posixPath));
+    }
+
+    expectSource('/tmp/slippy.dart', 'dart:fox');
+    expectSource('/tmp/deep/directory/file.dart', 'dart:deep');
+    expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart');
+  }
+
+  void test_getSdkLibrary() {
+    EmbedderYamlLocator locator = new EmbedderYamlLocator({
+      'fox': [pathTranslator.getResource('/tmp')]
+    });
+    EmbedderSdk sdk = new EmbedderSdk(resourceProvider, locator.embedderYamls);
+
+    SdkLibrary lib = sdk.getSdkLibrary('dart:fox');
+    expect(lib, isNotNull);
+    expect(lib.path, posixToOSPath('/tmp/slippy.dart'));
+    expect(lib.shortName, 'dart:fox');
+  }
+
+  void test_mapDartUri() {
+    EmbedderYamlLocator locator = new EmbedderYamlLocator({
+      'fox': [pathTranslator.getResource('/tmp')]
+    });
+    EmbedderSdk sdk = new EmbedderSdk(resourceProvider, locator.embedderYamls);
+
+    void expectSource(String dartUri, String posixPath) {
+      Source source = sdk.mapDartUri(dartUri);
+      expect(source, isNotNull, reason: posixPath);
+      expect(source.uri.toString(), dartUri);
+      expect(source.fullName, posixToOSPath(posixPath));
+    }
+
+    expectSource('dart:core', '/tmp/core.dart');
+    expectSource('dart:fox', '/tmp/slippy.dart');
+    expectSource('dart:deep', '/tmp/deep/directory/file.dart');
+    expectSource('dart:deep/part.dart', '/tmp/deep/directory/part.dart');
+  }
+}
+
+@reflectiveTest
+class FolderBasedDartSdkTest {
+  /**
+   * The resource provider used by these tests.
+   */
+  MemoryResourceProvider resourceProvider;
+
+  void test_addExtensions() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    String uri = 'dart:my.internal';
+    sdk.addExtensions({uri: '/Users/user/dart/my.dart'});
+    expect(sdk.mapDartUri(uri), isNotNull);
+    // The `shortName` property must include the `dart:` prefix.
+    expect(sdk.sdkLibraries, contains(predicate((SdkLibrary library) {
+      return library.shortName == uri;
+    })));
+  }
+
+  void test_analysisOptions_afterContextCreation() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    sdk.context;
+    expect(() {
+      sdk.analysisOptions = new AnalysisOptionsImpl();
+    }, throwsStateError);
+  }
+
+  void test_analysisOptions_beforeContextCreation() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    sdk.analysisOptions = new AnalysisOptionsImpl();
+    sdk.context;
+    // cannot change "analysisOptions" in the context
+    expect(() {
+      sdk.context.analysisOptions = new AnalysisOptionsImpl();
+    }, throwsStateError);
+  }
+
+  void test_creation() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    expect(sdk, isNotNull);
+  }
+
+  void test_fromFile_invalid() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    expect(
+        sdk.fromFileUri(
+            resourceProvider.getFile("/not/in/the/sdk.dart").toUri()),
+        isNull);
+  }
+
+  void test_fromFile_library() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    Source source = sdk.fromFileUri(sdk.libraryDirectory
+        .getChildAssumingFolder("core")
+        .getChildAssumingFile("core.dart")
+        .toUri());
+    expect(source, isNotNull);
+    expect(source.isInSystemLibrary, isTrue);
+    expect(source.uri.toString(), "dart:core");
+  }
+
+  void test_fromFile_library_firstExact() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    Folder dirHtml = sdk.libraryDirectory.getChildAssumingFolder("html");
+    Folder dirDartium = dirHtml.getChildAssumingFolder("dartium");
+    File file = dirDartium.getChildAssumingFile("html_dartium.dart");
+    Source source = sdk.fromFileUri(file.toUri());
+    expect(source, isNotNull);
+    expect(source.isInSystemLibrary, isTrue);
+    expect(source.uri.toString(), "dart:html");
+  }
+
+  void test_fromFile_library_html_common_dart2js() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    Folder dirHtml = sdk.libraryDirectory.getChildAssumingFolder("html");
+    Folder dirCommon = dirHtml.getChildAssumingFolder("html_common");
+    File file = dirCommon.getChildAssumingFile("html_common_dart2js.dart");
+    Source source = sdk.fromFileUri(file.toUri());
+    expect(source, isNotNull);
+    expect(source.isInSystemLibrary, isTrue);
+    expect(source.uri.toString(), "dart:html_common/html_common_dart2js.dart");
+  }
+
+  void test_fromFile_part() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    Source source = sdk.fromFileUri(sdk.libraryDirectory
+        .getChildAssumingFolder("core")
+        .getChildAssumingFile("num.dart")
+        .toUri());
+    expect(source, isNotNull);
+    expect(source.isInSystemLibrary, isTrue);
+    expect(source.uri.toString(), "dart:core/num.dart");
+  }
+
+  void test_getDirectory() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    Folder directory = sdk.directory;
+    expect(directory, isNotNull);
+    expect(directory.exists, isTrue);
+  }
+
+  void test_getDocDirectory() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    Folder directory = sdk.docDirectory;
+    expect(directory, isNotNull);
+  }
+
+  void test_getLibraryDirectory() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    Folder directory = sdk.libraryDirectory;
+    expect(directory, isNotNull);
+    expect(directory.exists, isTrue);
+  }
+
+  void test_getPubExecutable() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    File executable = sdk.pubExecutable;
+    expect(executable, isNotNull);
+    expect(executable.exists, isTrue);
+  }
+
+  void test_getSdkVersion() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    String version = sdk.sdkVersion;
+    expect(version, isNotNull);
+    expect(version.length > 0, isTrue);
+  }
+
+  void test_useSummary_afterContextCreation() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    sdk.context;
+    expect(() {
+      sdk.useSummary = true;
+    }, throwsStateError);
+  }
+
+  void test_useSummary_beforeContextCreation() {
+    FolderBasedDartSdk sdk = _createDartSdk();
+    sdk.useSummary = true;
+    sdk.context;
+  }
+
+  FolderBasedDartSdk _createDartSdk() {
+    resourceProvider = new MemoryResourceProvider();
+    Folder sdkDirectory = resourceProvider.getFolder('/sdk');
+    _createFile(sdkDirectory,
+        ['lib', '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'],
+        content: _librariesFileContent());
+    _createFile(sdkDirectory, ['bin', 'dart']);
+    _createFile(sdkDirectory, ['bin', 'dart2js']);
+    _createFile(sdkDirectory, ['bin', 'pub']);
+    _createFile(sdkDirectory, ['lib', 'async', 'async.dart']);
+    _createFile(sdkDirectory, ['lib', 'core', 'core.dart']);
+    _createFile(sdkDirectory, ['lib', 'core', 'num.dart']);
+    _createFile(sdkDirectory,
+        ['lib', 'html', 'html_common', 'html_common_dart2js.dart']);
+    _createFile(sdkDirectory, ['lib', 'html', 'dartium', 'html_dartium.dart']);
+    _createFile(
+        sdkDirectory, ['bin', (OSUtilities.isWindows() ? 'pub.bat' : 'pub')]);
+    return new FolderBasedDartSdk(resourceProvider, sdkDirectory);
+  }
+
+  void _createFile(Folder directory, List<String> segments,
+      {String content: ''}) {
+    Folder parent = directory;
+    int last = segments.length - 1;
+    for (int i = 0; i < last; i++) {
+      parent = parent.getChildAssumingFolder(segments[i]);
+    }
+    File file = parent.getChildAssumingFile(segments[last]);
+    resourceProvider.newFile(file.path, content);
+  }
+
+  String _librariesFileContent() => '''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+  "async": const LibraryInfo(
+      "async/async.dart",
+      categories: "Client,Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
+
+  "core": const LibraryInfo(
+      "core/core.dart",
+      categories: "Client,Server,Embedded",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
+
+  "html": const LibraryInfo(
+      "html/dartium/html_dartium.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "html/dart2js/html_dart2js.dart"),
+
+  "html_common": const LibraryInfo(
+      "html/html_common/html_common.dart",
+      categories: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "html/html_common/html_common_dart2js.dart",
+      documented: false,
+      implementation: true),
+};
+''';
+}
+
+@reflectiveTest
+class SdkExtensionFinderTest {
+  MemoryResourceProvider resourceProvider;
+
+  void setUp() {
+    resourceProvider = new MemoryResourceProvider();
+    resourceProvider.newFolder('/empty');
+    resourceProvider.newFolder('/tmp');
+    resourceProvider.newFile(
+        '/tmp/_sdkext',
+        r'''
+{
+  "dart:fox": "slippy.dart",
+  "dart:bear": "grizzly.dart",
+  "dart:relative": "../relative.dart",
+  "dart:deep": "deep/directory/file.dart",
+  "fart:loudly": "nomatter.dart"
+}''');
+  }
+
+  test_create_noSdkExtPackageMap() {
+    var resolver = new SdkExtensionFinder({
+      'fox': [resourceProvider.getResource('/empty')]
+    });
+    expect(resolver.urlMappings.length, equals(0));
+  }
+
+  test_create_nullPackageMap() {
+    var resolver = new SdkExtensionFinder(null);
+    expect(resolver.urlMappings.length, equals(0));
+  }
+
+  test_create_sdkExtPackageMap() {
+    var resolver = new SdkExtensionFinder({
+      'fox': [resourceProvider.getResource('/tmp')]
+    });
+    // We have four mappings.
+    Map<String, String> urlMappings = resolver.urlMappings;
+    expect(urlMappings.length, equals(4));
+    // Check that they map to the correct paths.
+    expect(urlMappings['dart:fox'], equals("/tmp/slippy.dart"));
+    expect(urlMappings['dart:bear'], equals("/tmp/grizzly.dart"));
+    expect(urlMappings['dart:relative'], equals("/relative.dart"));
+    expect(urlMappings['dart:deep'], equals("/tmp/deep/directory/file.dart"));
+  }
+}
+
+@reflectiveTest
+class SDKLibrariesReaderTest extends EngineTestCase {
+  /**
+   * The resource provider used by these tests.
+   */
+  MemoryResourceProvider resourceProvider;
+
+  @override
+  void setUp() {
+    resourceProvider = new MemoryResourceProvider();
+  }
+
+  void test_readFrom_dart2js() {
+    LibraryMap libraryMap = new SdkLibrariesReader(true).readFromFile(
+        resourceProvider.getFile("/libs.dart"),
+        r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+  'first' : const LibraryInfo(
+    'first/first.dart',
+    categories: 'Client',
+    documented: true,
+    platforms: VM_PLATFORM,
+    dart2jsPath: 'first/first_dart2js.dart'),
+};''');
+    expect(libraryMap, isNotNull);
+    expect(libraryMap.size(), 1);
+    SdkLibrary first = libraryMap.getLibrary("dart:first");
+    expect(first, isNotNull);
+    expect(first.category, "Client");
+    expect(first.path, "first/first_dart2js.dart");
+    expect(first.shortName, "dart:first");
+    expect(first.isDart2JsLibrary, false);
+    expect(first.isDocumented, true);
+    expect(first.isImplementation, false);
+    expect(first.isVmLibrary, true);
+  }
+
+  void test_readFrom_empty() {
+    LibraryMap libraryMap = new SdkLibrariesReader(false)
+        .readFromFile(resourceProvider.getFile("/libs.dart"), "");
+    expect(libraryMap, isNotNull);
+    expect(libraryMap.size(), 0);
+  }
+
+  void test_readFrom_normal() {
+    LibraryMap libraryMap = new SdkLibrariesReader(false).readFromFile(
+        resourceProvider.getFile("/libs.dart"),
+        r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+  'first' : const LibraryInfo(
+    'first/first.dart',
+    categories: 'Client',
+    documented: true,
+    platforms: VM_PLATFORM),
+
+  'second' : const LibraryInfo(
+    'second/second.dart',
+    categories: 'Server',
+    documented: false,
+    implementation: true,
+    platforms: 0),
+};''');
+    expect(libraryMap, isNotNull);
+    expect(libraryMap.size(), 2);
+    SdkLibrary first = libraryMap.getLibrary("dart:first");
+    expect(first, isNotNull);
+    expect(first.category, "Client");
+    expect(first.path, "first/first.dart");
+    expect(first.shortName, "dart:first");
+    expect(first.isDart2JsLibrary, false);
+    expect(first.isDocumented, true);
+    expect(first.isImplementation, false);
+    expect(first.isVmLibrary, true);
+    SdkLibrary second = libraryMap.getLibrary("dart:second");
+    expect(second, isNotNull);
+    expect(second.category, "Server");
+    expect(second.path, "second/second.dart");
+    expect(second.shortName, "dart:second");
+    expect(second.isDart2JsLibrary, false);
+    expect(second.isDocumented, false);
+    expect(second.isImplementation, true);
+    expect(second.isVmLibrary, false);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/sdk/test_all.dart b/pkg/analyzer/test/src/dart/sdk/test_all.dart
new file mode 100644
index 0000000..8052c9e
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/sdk/test_all.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.
+
+library analyzer.test.src.dart.sdk.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'sdk_test.dart' as sdk;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('sdk tests', () {
+    sdk.main();
+  });
+}
diff --git a/pkg/analyzer/test/src/dart/test_all.dart b/pkg/analyzer/test/src/dart/test_all.dart
index 15a0849..26e34d3 100644
--- a/pkg/analyzer/test/src/dart/test_all.dart
+++ b/pkg/analyzer/test/src/dart/test_all.dart
@@ -10,6 +10,7 @@
 import 'ast/test_all.dart' as ast;
 import 'constant/test_all.dart' as constant;
 import 'element/test_all.dart' as element;
+import 'sdk/test_all.dart' as sdk;
 
 /// Utility for manually running all tests.
 main() {
@@ -18,5 +19,6 @@
     ast.main();
     constant.main();
     element.main();
+    sdk.main();
   });
 }
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
new file mode 100644
index 0000000..28b131e
--- /dev/null
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -0,0 +1,214 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.source.source_resource_test;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+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/source/source_resource.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+import '../context/mock_sdk.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(FileSourceTest);
+}
+
+@reflectiveTest
+class FileSourceTest {
+  MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+
+  void test_equals_false_differentFiles() {
+    File file1 = resourceProvider.getFile("/does/not/exist1.dart");
+    File file2 = resourceProvider.getFile("/does/not/exist2.dart");
+    FileSource source1 = new FileSource(file1);
+    FileSource source2 = new FileSource(file2);
+    expect(source1 == source2, isFalse);
+  }
+
+  void test_equals_false_null() {
+    File file = resourceProvider.getFile("/does/not/exist1.dart");
+    FileSource source1 = new FileSource(file);
+    expect(source1 == null, isFalse);
+  }
+
+  void test_equals_true() {
+    File file1 = resourceProvider.getFile("/does/not/exist.dart");
+    File file2 = resourceProvider.getFile("/does/not/exist.dart");
+    FileSource source1 = new FileSource(file1);
+    FileSource source2 = new FileSource(file2);
+    expect(source1 == source2, isTrue);
+  }
+
+  void test_fileReadMode() {
+    expect(FileSource.fileReadMode('a'), 'a');
+    expect(FileSource.fileReadMode('a\n'), 'a\n');
+    expect(FileSource.fileReadMode('ab'), 'ab');
+    expect(FileSource.fileReadMode('abc'), 'abc');
+    expect(FileSource.fileReadMode('a\nb'), 'a\nb');
+    expect(FileSource.fileReadMode('a\rb'), 'a\rb');
+    expect(FileSource.fileReadMode('a\r\nb'), 'a\r\nb');
+  }
+
+  void test_fileReadMode_changed() {
+    FileSource.fileReadMode = (String s) => s + 'xyz';
+    expect(FileSource.fileReadMode('a'), 'axyz');
+    expect(FileSource.fileReadMode('a\n'), 'a\nxyz');
+    expect(FileSource.fileReadMode('ab'), 'abxyz');
+    expect(FileSource.fileReadMode('abc'), 'abcxyz');
+    FileSource.fileReadMode = (String s) => s;
+  }
+
+  void test_fileReadMode_normalize_eol_always() {
+    FileSource.fileReadMode = PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS;
+    expect(FileSource.fileReadMode('a'), 'a');
+
+    // '\n' -> '\n' as first, last and only character
+    expect(FileSource.fileReadMode('\n'), '\n');
+    expect(FileSource.fileReadMode('a\n'), 'a\n');
+    expect(FileSource.fileReadMode('\na'), '\na');
+
+    // '\r\n' -> '\n' as first, last and only character
+    expect(FileSource.fileReadMode('\r\n'), '\n');
+    expect(FileSource.fileReadMode('a\r\n'), 'a\n');
+    expect(FileSource.fileReadMode('\r\na'), '\na');
+
+    // '\r' -> '\n' as first, last and only character
+    expect(FileSource.fileReadMode('\r'), '\n');
+    expect(FileSource.fileReadMode('a\r'), 'a\n');
+    expect(FileSource.fileReadMode('\ra'), '\na');
+
+    FileSource.fileReadMode = (String s) => s;
+  }
+
+  void test_getEncoding() {
+    SourceFactory factory =
+        new SourceFactory([new ResourceUriResolver(resourceProvider)]);
+    String fullPath = "/does/not/exist.dart";
+    File file = resourceProvider.getFile(fullPath);
+    FileSource source = new FileSource(file);
+    expect(factory.fromEncoding(source.encoding), source);
+  }
+
+  void test_getFullName() {
+    String fullPath = "/does/not/exist.dart";
+    File file = resourceProvider.getFile(fullPath);
+    FileSource source = new FileSource(file);
+    expect(source.fullName, file.path);
+  }
+
+  void test_getShortName() {
+    File file = resourceProvider.getFile("/does/not/exist.dart");
+    FileSource source = new FileSource(file);
+    expect(source.shortName, "exist.dart");
+  }
+
+  void test_hashCode() {
+    File file1 = resourceProvider.getFile("/does/not/exist.dart");
+    File file2 = resourceProvider.getFile("/does/not/exist.dart");
+    FileSource source1 = new FileSource(file1);
+    FileSource source2 = new FileSource(file2);
+    expect(source2.hashCode, source1.hashCode);
+  }
+
+  void test_isInSystemLibrary_contagious() {
+    DartSdk sdk = _createSdk();
+    UriResolver resolver = new DartUriResolver(sdk);
+    SourceFactory factory = new SourceFactory([resolver]);
+    // resolve dart:core
+    Source result =
+        resolver.resolveAbsolute(parseUriWithException("dart:async"));
+    expect(result, isNotNull);
+    expect(result.isInSystemLibrary, isTrue);
+    // system libraries reference only other system libraries
+    Source partSource = factory.resolveUri(result, "stream.dart");
+    expect(partSource, isNotNull);
+    expect(partSource.isInSystemLibrary, isTrue);
+  }
+
+  void test_isInSystemLibrary_false() {
+    File file = resourceProvider.getFile("/does/not/exist.dart");
+    FileSource source = new FileSource(file);
+    expect(source, isNotNull);
+    expect(source.fullName, file.path);
+    expect(source.isInSystemLibrary, isFalse);
+  }
+
+  void test_issue14500() {
+    // see https://code.google.com/p/dart/issues/detail?id=14500
+    FileSource source =
+        new FileSource(resourceProvider.getFile("/some/packages/foo:bar.dart"));
+    expect(source, isNotNull);
+    expect(source.exists(), isFalse);
+  }
+
+  void test_resolveRelative_file_fileName() {
+    if (OSUtilities.isWindows()) {
+      // On Windows, the URI that is produced includes a drive letter,
+      // which I believe is not consistent across all machines that might run
+      // this test.
+      return;
+    }
+    File file = resourceProvider.getFile("/a/b/test.dart");
+    FileSource source = new FileSource(file);
+    expect(source, isNotNull);
+    Uri relative =
+        resolveRelativeUri(source.uri, parseUriWithException("lib.dart"));
+    expect(relative, isNotNull);
+    expect(relative.toString(), "file:///a/b/lib.dart");
+  }
+
+  void test_resolveRelative_file_filePath() {
+    if (OSUtilities.isWindows()) {
+      // On Windows, the URI that is produced includes a drive letter,
+      // which I believe is not consistent across all machines that might run
+      // this test.
+      return;
+    }
+    File file = resourceProvider.getFile("/a/b/test.dart");
+    FileSource source = new FileSource(file);
+    expect(source, isNotNull);
+    Uri relative =
+        resolveRelativeUri(source.uri, parseUriWithException("c/lib.dart"));
+    expect(relative, isNotNull);
+    expect(relative.toString(), "file:///a/b/c/lib.dart");
+  }
+
+  void test_resolveRelative_file_filePathWithParent() {
+    if (OSUtilities.isWindows()) {
+      // On Windows, the URI that is produced includes a drive letter, which I
+      // believe is not consistent across all machines that might run this test.
+      return;
+    }
+    File file = resourceProvider.getFile("/a/b/test.dart");
+    FileSource source = new FileSource(file);
+    expect(source, isNotNull);
+    Uri relative =
+        resolveRelativeUri(source.uri, parseUriWithException("../c/lib.dart"));
+    expect(relative, isNotNull);
+    expect(relative.toString(), "file:///a/c/lib.dart");
+  }
+
+  void test_system() {
+    File file = resourceProvider.getFile("/does/not/exist.dart");
+    FileSource source =
+        new FileSource(file, parseUriWithException("dart:core"));
+    expect(source, isNotNull);
+    expect(source.fullName, file.path);
+    expect(source.isInSystemLibrary, isTrue);
+  }
+
+  DartSdk _createSdk() {
+    return new MockSdk(resourceProvider: resourceProvider);
+  }
+}
diff --git a/pkg/analyzer/test/src/source/test_all.dart b/pkg/analyzer/test/src/source/test_all.dart
new file mode 100644
index 0000000..fea6306
--- /dev/null
+++ b/pkg/analyzer/test/src/source/test_all.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.
+
+library analyzer.test.src.source.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+import 'source_resource_test.dart' as source_resource_test;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('context tests', () {
+    source_resource_test.main();
+  });
+}
diff --git a/pkg/analyzer/test/src/summary/api_signature_test.dart b/pkg/analyzer/test/src/summary/api_signature_test.dart
new file mode 100644
index 0000000..eabb805
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/api_signature_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.
+
+library test.src.summary.api_signature_test;
+
+import 'package:analyzer/src/summary/api_signature.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:convert/convert.dart';
+import 'package:crypto/crypto.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(ApiSignatureTest);
+}
+
+@reflectiveTest
+class ApiSignatureTest {
+  ApiSignature sig = new ApiSignature.unversioned();
+
+  void checkBytes(List<int> bytes) {
+    expect(sig.getBytes_forDebug(), bytes);
+    expect(sig.toHex(), hex.encode(md5.convert(bytes).bytes));
+  }
+
+  String signUnlinkedCombinator(UnlinkedCombinatorBuilder combinator) {
+    ApiSignature sig = new ApiSignature();
+    combinator.collectApiSignature(sig);
+    return sig.toHex();
+  }
+
+  void test_addBool() {
+    sig.addBool(true);
+    sig.addBool(true);
+    sig.addBool(false);
+    sig.addBool(true);
+    sig.addBool(false);
+    sig.addBool(false);
+    sig.addBool(true);
+    sig.addBool(false);
+    checkBytes([1, 1, 0, 1, 0, 0, 1, 0]);
+  }
+
+  void test_addBytes() {
+    // Check that offset works correctly by adding bytes in 2 chunks.
+    sig.addBytes([1, 2, 3, 4, 5]);
+    sig.addBytes([0xff, 0xfe, 0xfd, 0xfc, 0xfb]);
+    checkBytes([1, 2, 3, 4, 5, 0xff, 0xfe, 0xfd, 0xfc, 0xfb]);
+  }
+
+  void test_addDouble() {
+    sig.addDouble(1.0 / 3.0);
+    sig.addDouble(-1.0);
+    checkBytes([85, 85, 85, 85, 85, 85, 213, 63, 0, 0, 0, 0, 0, 0, 240, 191]);
+  }
+
+  void test_addInt() {
+    sig.addInt(1);
+    sig.addInt(1000);
+    sig.addInt(1000000);
+    sig.addInt(1000000000);
+    checkBytes(
+        [1, 0, 0, 0, 0xe8, 3, 0, 0, 0x40, 0x42, 0xf, 0, 0, 0xca, 0x9a, 0x3b]);
+  }
+
+  void test_addString() {
+    sig.addString('abc');
+    sig.addString('\u00f8');
+    checkBytes([3, 0, 0, 0, 0x61, 0x62, 0x63, 2, 0, 0, 0, 0xc3, 0xb8]);
+  }
+
+  void test_excludesInformative() {
+    // Verify that API signatures exclude informative data by checking that two
+    // UnlinkedCombinator instances that differ only in their offset result in
+    // the same signature.
+    UnlinkedCombinatorBuilder combinator1 =
+        new UnlinkedCombinatorBuilder(shows: ['foo'], offset: 1);
+    UnlinkedCombinatorBuilder combinator2 =
+        new UnlinkedCombinatorBuilder(shows: ['foo'], offset: 2);
+    expect(signUnlinkedCombinator(combinator1),
+        signUnlinkedCombinator(combinator2));
+  }
+
+  void test_includesSemantic() {
+    // Verify that API signatures include semantic data by checking that two
+    // UnlinkedCombinator instances that differ only in their "shows" lists
+    // result in different signatures.
+    UnlinkedCombinatorBuilder combinator1 =
+        new UnlinkedCombinatorBuilder(shows: ['foo'], offset: 1);
+    UnlinkedCombinatorBuilder combinator2 =
+        new UnlinkedCombinatorBuilder(shows: ['bar'], offset: 1);
+    expect(signUnlinkedCombinator(combinator1),
+        isNot(signUnlinkedCombinator(combinator2)));
+  }
+
+  void test_manyInts() {
+    // This verifies that the logic to extend the internal buffer works
+    // properly.
+    List<int> expectedResult = [];
+    for (int i = 0; i < 100000; i++) {
+      sig.addInt(i);
+      expectedResult.add(i % 0x100);
+      expectedResult.add((i ~/ 0x100) % 0x100);
+      expectedResult.add((i ~/ 0x10000) % 0x100);
+      expectedResult.add((i ~/ 0x1000000) % 0x100);
+    }
+    checkBytes(expectedResult);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/in_summary_source_test.dart b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
index f45602c..f83d30a 100644
--- a/pkg/analyzer/test/src/summary/in_summary_source_test.dart
+++ b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
@@ -4,6 +4,7 @@
 
 library analyzer.test.src.summary.in_summary_source_test;
 
+import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
@@ -23,35 +24,41 @@
   test_fallbackPath() {
     String fooFallbackPath = absolute('path', 'to', 'foo.dart');
     var sourceFactory = new SourceFactory([
-      new InSummaryPackageUriResolver(new MockSummaryDataStore.fake(
-          {'package:foo/foo.dart': 'foo.sum',},
-          uriToFallbackModePath: {'package:foo/foo.dart': fooFallbackPath}))
+      new InSummaryUriResolver(
+          PhysicalResourceProvider.INSTANCE,
+          new MockSummaryDataStore.fake({
+            'package:foo/foo.dart': 'foo.sum',
+          }, uriToFallbackModePath: {
+            'package:foo/foo.dart': fooFallbackPath
+          }))
     ]);
 
     InSummarySource source = sourceFactory.forUri('package:foo/foo.dart');
-    expect(source, new isInstanceOf<FileBasedSource>());
+    expect(source, isNotNull);
     expect(source.fullName, fooFallbackPath);
   }
 
   test_InSummarySource() {
     var sourceFactory = new SourceFactory([
-      new InSummaryPackageUriResolver(new MockSummaryDataStore.fake({
-        'package:foo/foo.dart': 'foo.sum',
-        'package:foo/src/foo_impl.dart': 'foo.sum',
-        'package:bar/baz.dart': 'bar.sum',
-      }))
+      new InSummaryUriResolver(
+          PhysicalResourceProvider.INSTANCE,
+          new MockSummaryDataStore.fake({
+            'package:foo/foo.dart': 'foo.sum',
+            'package:foo/src/foo_impl.dart': 'foo.sum',
+            'package:bar/baz.dart': 'bar.sum',
+          }))
     ]);
 
     InSummarySource source = sourceFactory.forUri('package:foo/foo.dart');
-    expect(source, isNot(new isInstanceOf<FileBasedSource>()));
+    expect(source, isNotNull);
     expect(source.summaryPath, 'foo.sum');
 
     source = sourceFactory.forUri('package:foo/src/foo_impl.dart');
-    expect(source, isNot(new isInstanceOf<FileBasedSource>()));
+    expect(source, isNotNull);
     expect(source.summaryPath, 'foo.sum');
 
     source = sourceFactory.forUri('package:bar/baz.dart');
-    expect(source, isNot(new isInstanceOf<FileBasedSource>()));
+    expect(source, isNotNull);
     expect(source.summaryPath, 'bar.sum');
   }
 }
diff --git a/pkg/analyzer/test/src/summary/index_unit_test.dart b/pkg/analyzer/test/src/summary/index_unit_test.dart
index 1bf2cf5..f6851c8 100644
--- a/pkg/analyzer/test/src/summary/index_unit_test.dart
+++ b/pkg/analyzer/test/src/summary/index_unit_test.dart
@@ -1134,12 +1134,34 @@
    */
   int _findElementId(Element element) {
     int unitId = _getUnitId(element);
-    ElementInfo info = PackageIndexAssembler.newElementInfo(unitId, element);
+    // Prepare the element that was put into the index.
+    IndexElementInfo info = new IndexElementInfo(element);
+    element = info.element;
+    // Prepare element's name components.
+    int unitMemberId = _getStringId(PackageIndexAssembler.NULL_STRING);
+    int classMemberId = _getStringId(PackageIndexAssembler.NULL_STRING);
+    int parameterId = _getStringId(PackageIndexAssembler.NULL_STRING);
+    for (Element e = element; e != null; e = e.enclosingElement) {
+      if (e.enclosingElement is CompilationUnitElement) {
+        unitMemberId = _getStringId(e.name);
+      }
+    }
+    for (Element e = element; e != null; e = e.enclosingElement) {
+      if (e.enclosingElement is ClassElement) {
+        classMemberId = _getStringId(e.name);
+      }
+    }
+    if (element is ParameterElement) {
+      parameterId = _getStringId(element.name);
+    }
+    // Find the element's id.
     for (int elementId = 0;
         elementId < packageIndex.elementUnits.length;
         elementId++) {
       if (packageIndex.elementUnits[elementId] == unitId &&
-          packageIndex.elementOffsets[elementId] == info.offset &&
+          packageIndex.elementNameUnitMemberIds[elementId] == unitMemberId &&
+          packageIndex.elementNameClassMemberIds[elementId] == classMemberId &&
+          packageIndex.elementNameParameterIds[elementId] == parameterId &&
           packageIndex.elementKinds[elementId] == info.kind) {
         return elementId;
       }
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 674ce9b..b93a39f 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -43,6 +43,60 @@
     return linker.getLibrary(Uri.parse(uri));
   }
 
+  void test_apiSignature_apiChanges() {
+    var bundle0 =
+        createPackageBundle('f(int i) { print(i); }', path: '/test.dart');
+    var bundle1 =
+        createPackageBundle('f(String s) { print(s); }', path: '/test.dart');
+    expect(bundle0.apiSignature, isNotEmpty);
+    expect(bundle1.apiSignature, isNotEmpty);
+    expect(bundle0.apiSignature, isNot(bundle1.apiSignature));
+  }
+
+  void test_apiSignature_localChanges() {
+    var bundle0 = createPackageBundle('f() { print(0); }', path: '/test.dart');
+    var bundle1 = createPackageBundle('f() { print(1); }', path: '/test.dart');
+    expect(bundle0.apiSignature, isNotEmpty);
+    expect(bundle1.apiSignature, isNotEmpty);
+    expect(bundle0.apiSignature, bundle1.apiSignature);
+  }
+
+  void test_apiSignature_orderChange() {
+    // A change to the order in which files are processed should not affect the
+    // API signature.
+    addNamedSource('/a.dart', 'class A {}');
+    var bundle0 = createPackageBundle('class B {}', path: '/b.dart');
+    addNamedSource('/b.dart', 'class B {}');
+    var bundle1 = createPackageBundle('class A {}', path: '/a.dart');
+    expect(bundle0.apiSignature, isNotEmpty);
+    expect(bundle1.apiSignature, isNotEmpty);
+    expect(bundle0.apiSignature, bundle1.apiSignature);
+  }
+
+  void test_apiSignature_unlinkedOnly() {
+    // The API signature of a package bundle should only contain unlinked
+    // information.  In this test, the linked information for bundle2 and
+    // bundle3 refer to class C as existing in different files.  But the
+    // unlinked information for bundle2 and bundle3 should be the same, so their
+    // API signatures should be the same.
+    addNamedSource('/a.dart', 'class C {}');
+    var bundle0 = createPackageBundle('', path: '/b.dart');
+    addNamedSource('/a.dart', '');
+    var bundle1 = createPackageBundle('class C {}', path: '/b.dart');
+    var text = '''
+import 'a.dart';
+import 'b.dart';
+class D extends C {}
+''';
+    addBundle('/bundle0.ds', bundle0);
+    var bundle2 = createPackageBundle(text, path: '/c.dart');
+    addBundle('/bundle1.ds', bundle1);
+    var bundle3 = createPackageBundle(text, path: '/c.dart');
+    expect(bundle2.apiSignature, isNotEmpty);
+    expect(bundle3.apiSignature, isNotEmpty);
+    expect(bundle2.apiSignature, bundle3.apiSignature);
+  }
+
   void test_baseClass_genericWithAccessor() {
     createLinker('''
 class B<T> {
@@ -141,6 +195,33 @@
     // No assertions--just make sure it doesn't crash.
   }
 
+  void test_bundle_refers_to_bundle() {
+    var bundle1 = createPackageBundle(
+        '''
+var x = 0;
+''',
+        path: '/a.dart');
+    addBundle('/a.ds', bundle1);
+    var bundle2 = createPackageBundle(
+        '''
+import "a.dart";
+var y = x;
+''',
+        path: '/b.dart');
+    expect(bundle2.dependencies, hasLength(1));
+    expect(bundle2.dependencies[0].summaryPath, '/a.ds');
+    expect(bundle2.dependencies[0].apiSignature, bundle1.apiSignature);
+    addBundle('/a.ds', bundle1);
+    addBundle('/b.ds', bundle2);
+    createLinker('''
+import "b.dart";
+var z = y;
+''');
+    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
+        'int');
+  }
+
   void test_constCycle_viaLength() {
     createLinker('''
 class C {
@@ -154,6 +235,25 @@
     expect(classC.unnamedConstructor.isCycleFree, false);
   }
 
+  void test_createPackageBundle_withPackageUri() {
+    PackageBundle bundle = createPackageBundle(
+        '''
+class B {
+  void f(int i) {}
+}
+class C extends B {
+  f(i) {} // Inferred param type: int
+}
+''',
+        uri: 'package:foo/bar.dart');
+    UnlinkedExecutable cf = bundle.unlinkedUnits[0].classes[1].executables[0];
+    UnlinkedParam cfi = cf.parameters[0];
+    expect(cfi.inferredTypeSlot, isNot(0));
+    EntityRef typeRef =
+        bundle.linkedLibraries[0].units[0].types[cfi.inferredTypeSlot];
+    expect(bundle.unlinkedUnits[0].references[typeRef.reference].name, 'int');
+  }
+
   void test_getContainedName_nonStaticField() {
     createLinker('class C { var f; }');
     LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
@@ -188,7 +288,7 @@
 var x = () {};
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 var y = x;
@@ -210,7 +310,7 @@
 class E {}
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 var y = C.x;
@@ -323,7 +423,7 @@
 var y = x; // Inferred type: dynamic
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 var z = y; // Inferred type: dynamic
@@ -341,7 +441,7 @@
 }
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 var x = new C().f; // Inferred type: int
@@ -359,7 +459,7 @@
 }
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 class D {
@@ -382,7 +482,7 @@
 }
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 var x = new C().f(0); // Inferred type: int
@@ -403,7 +503,7 @@
 }
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 class D extends C {
@@ -430,7 +530,7 @@
 }
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 var x = new C().f(); // Inferred type: int
@@ -451,7 +551,7 @@
 }
 ''',
         path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 class D extends C {
@@ -468,7 +568,7 @@
   void test_inferredTypeFromOutsideBuildUnit_staticField() {
     var bundle =
         createPackageBundle('class C { static var f = 0; }', path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('import "a.dart"; var x = C.f;', path: '/b.dart');
     expect(
         _getVariable(linker
@@ -481,7 +581,7 @@
 
   void test_inferredTypeFromOutsideBuildUnit_topLevelVariable() {
     var bundle = createPackageBundle('var a = 0;', path: '/a.dart');
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('import "a.dart"; var b = a;', path: '/b.dart');
     expect(
         _getVariable(linker
@@ -652,7 +752,7 @@
         ref.localIndex = 1234;
       }
     }
-    addBundle(bundle);
+    addBundle('/a.ds', bundle);
     createLinker('''
 import 'a.dart';
 var y = x;
diff --git a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
new file mode 100644
index 0000000..07ce00f
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
@@ -0,0 +1,297 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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/context/cache.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/general.dart';
+import 'package:typed_mock/typed_mock.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(ResynthesizerResultProviderTest);
+  runReflectiveTests(SummaryDataStoreTest);
+}
+
+UnlinkedPublicNamespace _namespaceWithParts(List<String> parts) {
+  UnlinkedPublicNamespace namespace = new _UnlinkedPublicNamespaceMock();
+  when(namespace.parts).thenReturn(parts);
+  return namespace;
+}
+
+@reflectiveTest
+class ResynthesizerResultProviderTest {
+  SourceFactory sourceFactory = new _SourceFactoryMock();
+  InternalAnalysisContext context = new _InternalAnalysisContextMock();
+  UniversalCachePartition cachePartition;
+
+  Source source1 = new _SourceMock('package:p1/u1.dart', '/p1/lib/u1.dart');
+  Source source2 = new _SourceMock('package:p1/u2.dart', '/p1/lib/u2.dart');
+  Source source3 = new _SourceMock('package:p2/u1.dart', '/p2/lib/u1.dart');
+  CacheEntry entry1;
+  CacheEntry entry2;
+  CacheEntry entry3;
+
+  PackageBundle bundle = new _PackageBundleMock();
+  UnlinkedUnit unlinkedUnit1 = new _UnlinkedUnitMock();
+  UnlinkedUnit unlinkedUnit2 = new _UnlinkedUnitMock();
+  LinkedLibrary linkedLibrary = new _LinkedLibraryMock();
+
+  SummaryDataStore dataStore = new SummaryDataStore(<String>[]);
+  _TestResynthesizerResultProvider provider;
+
+  void setUp() {
+    cachePartition = new UniversalCachePartition(context);
+    entry1 = new CacheEntry(source1);
+    entry2 = new CacheEntry(source2);
+    entry3 = new CacheEntry(source3);
+    cachePartition.put(entry1);
+    cachePartition.put(entry2);
+    cachePartition.put(entry3);
+
+    when(sourceFactory.resolveUri(anyObject, 'package:p1/u1.dart'))
+        .thenReturn(source1);
+    when(sourceFactory.resolveUri(anyObject, 'package:p1/u2.dart'))
+        .thenReturn(source2);
+    when(context.sourceFactory).thenReturn(sourceFactory);
+
+    when(bundle.unlinkedUnitUris)
+        .thenReturn(<String>['package:p1/u1.dart', 'package:p1/u2.dart']);
+    when(bundle.unlinkedUnits)
+        .thenReturn(<UnlinkedUnit>[unlinkedUnit1, unlinkedUnit2]);
+    when(bundle.linkedLibraryUris).thenReturn(<String>['package:p1/u1.dart']);
+    when(bundle.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary]);
+    dataStore.addBundle('/p1.ds', bundle);
+
+    when(unlinkedUnit1.publicNamespace)
+        .thenReturn(_namespaceWithParts(['package:p1/u2.dart']));
+    when(unlinkedUnit2.publicNamespace).thenReturn(_namespaceWithParts([]));
+
+    provider = new _TestResynthesizerResultProvider(context, dataStore);
+    provider.sourcesWithResults.add(source1);
+    provider.sourcesWithResults.add(source2);
+  }
+
+  test_compute_CONTAINING_LIBRARIES_librarySource() {
+    bool success = provider.compute(entry1, CONTAINING_LIBRARIES);
+    expect(success, isTrue);
+    expect(entry1.getValue(CONTAINING_LIBRARIES), unorderedEquals([source1]));
+  }
+
+  test_compute_CONTAINING_LIBRARIES_partSource() {
+    bool success = provider.compute(entry2, CONTAINING_LIBRARIES);
+    expect(success, isTrue);
+    expect(entry2.getValue(CONTAINING_LIBRARIES), unorderedEquals([source1]));
+  }
+
+  test_compute_LINE_INFO_hasLineStarts() {
+    when(unlinkedUnit1.lineStarts).thenReturn(<int>[10, 20, 30]);
+    bool success = provider.compute(entry1, LINE_INFO);
+    expect(success, isTrue);
+    expect(entry1.getValue(LINE_INFO).lineStarts, <int>[10, 20, 30]);
+  }
+
+  test_compute_LINE_INFO_emptyLineStarts() {
+    when(unlinkedUnit1.lineStarts).thenReturn(<int>[]);
+    bool success = provider.compute(entry1, LINE_INFO);
+    expect(success, isFalse);
+  }
+
+  test_compute_SOURCE_KIND_librarySource() {
+    bool success = provider.compute(entry1, SOURCE_KIND);
+    expect(success, isTrue);
+    expect(entry1.getValue(SOURCE_KIND), SourceKind.LIBRARY);
+  }
+
+  test_compute_SOURCE_KIND_noResults() {
+    bool success = provider.compute(entry3, SOURCE_KIND);
+    expect(success, isFalse);
+    expect(entry3.getState(SOURCE_KIND), CacheState.INVALID);
+  }
+
+  test_compute_SOURCE_KIND_partSource() {
+    bool success = provider.compute(entry2, SOURCE_KIND);
+    expect(success, isTrue);
+    expect(entry2.getValue(SOURCE_KIND), SourceKind.PART);
+  }
+}
+
+@reflectiveTest
+class SummaryDataStoreTest {
+  SummaryDataStore dataStore =
+      new SummaryDataStore(<String>[], recordDependencyInfo: true);
+
+  PackageBundle bundle1 = new _PackageBundleMock();
+  PackageBundle bundle2 = new _PackageBundleMock();
+  UnlinkedUnit unlinkedUnit11 = new _UnlinkedUnitMock();
+  UnlinkedUnit unlinkedUnit12 = new _UnlinkedUnitMock();
+  UnlinkedUnit unlinkedUnit21 = new _UnlinkedUnitMock();
+  LinkedLibrary linkedLibrary1 = new _LinkedLibraryMock();
+  LinkedLibrary linkedLibrary2 = new _LinkedLibraryMock();
+
+  void setUp() {
+    // bundle1
+    when(unlinkedUnit11.publicNamespace)
+        .thenReturn(_namespaceWithParts(['package:p1/u2.dart']));
+    when(unlinkedUnit12.publicNamespace).thenReturn(_namespaceWithParts([]));
+    when(bundle1.unlinkedUnitUris)
+        .thenReturn(<String>['package:p1/u1.dart', 'package:p1/u2.dart']);
+    when(bundle1.unlinkedUnits)
+        .thenReturn(<UnlinkedUnit>[unlinkedUnit11, unlinkedUnit12]);
+    when(bundle1.linkedLibraryUris).thenReturn(<String>['package:p1/u1.dart']);
+    when(bundle1.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary1]);
+    when(bundle1.apiSignature).thenReturn('signature1');
+    dataStore.addBundle('/p1.ds', bundle1);
+    // bundle2
+    when(unlinkedUnit21.publicNamespace).thenReturn(_namespaceWithParts([]));
+    when(bundle2.unlinkedUnitUris).thenReturn(<String>['package:p2/u1.dart']);
+    when(bundle2.unlinkedUnits).thenReturn(<UnlinkedUnit>[unlinkedUnit21]);
+    when(bundle2.linkedLibraryUris).thenReturn(<String>['package:p2/u1.dart']);
+    when(bundle2.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary2]);
+    when(bundle2.apiSignature).thenReturn('signature2');
+    dataStore.addBundle('/p2.ds', bundle2);
+  }
+
+  test_addBundle() {
+    expect(dataStore.bundles, unorderedEquals([bundle1, bundle2]));
+    expect(dataStore.dependencies[0].summaryPath, '/p1.ds');
+    expect(dataStore.dependencies[0].apiSignature, 'signature1');
+    expect(dataStore.dependencies[0].includedPackageNames, ['p1']);
+    expect(dataStore.dependencies[0].includesFileUris, false);
+    expect(dataStore.dependencies[0].includesDartUris, false);
+    expect(dataStore.dependencies[1].summaryPath, '/p2.ds');
+    expect(dataStore.dependencies[1].apiSignature, 'signature2');
+    expect(dataStore.dependencies[1].includedPackageNames, ['p2']);
+    expect(dataStore.dependencies[1].includesFileUris, false);
+    expect(dataStore.dependencies[1].includesDartUris, false);
+    expect(dataStore.uriToSummaryPath,
+        containsPair('package:p1/u1.dart', '/p1.ds'));
+    // unlinkedMap
+    expect(dataStore.unlinkedMap, hasLength(3));
+    expect(dataStore.unlinkedMap,
+        containsPair('package:p1/u1.dart', unlinkedUnit11));
+    expect(dataStore.unlinkedMap,
+        containsPair('package:p1/u2.dart', unlinkedUnit12));
+    expect(dataStore.unlinkedMap,
+        containsPair('package:p2/u1.dart', unlinkedUnit21));
+    // linkedMap
+    expect(dataStore.linkedMap, hasLength(2));
+    expect(dataStore.linkedMap,
+        containsPair('package:p1/u1.dart', linkedLibrary1));
+    expect(dataStore.linkedMap,
+        containsPair('package:p2/u1.dart', linkedLibrary2));
+  }
+
+  test_addBundle_dartUris() {
+    PackageBundle bundle = new _PackageBundleMock();
+    when(bundle.unlinkedUnitUris).thenReturn(<String>['dart:core']);
+    when(bundle.unlinkedUnits).thenReturn(<UnlinkedUnit>[unlinkedUnit11]);
+    when(bundle.linkedLibraryUris).thenReturn(<String>['dart:core']);
+    when(bundle.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary1]);
+    when(bundle.apiSignature).thenReturn('signature');
+    dataStore.addBundle('/p3.ds', bundle);
+    expect(dataStore.dependencies.last.includedPackageNames, []);
+    expect(dataStore.dependencies.last.includesFileUris, false);
+    expect(dataStore.dependencies.last.includesDartUris, true);
+  }
+
+  test_addBundle_fileUris() {
+    PackageBundle bundle = new _PackageBundleMock();
+    when(bundle.unlinkedUnitUris).thenReturn(<String>['file:/foo.dart']);
+    when(bundle.unlinkedUnits).thenReturn(<UnlinkedUnit>[unlinkedUnit11]);
+    when(bundle.linkedLibraryUris).thenReturn(<String>['file:/foo.dart']);
+    when(bundle.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary1]);
+    when(bundle.apiSignature).thenReturn('signature');
+    dataStore.addBundle('/p3.ds', bundle);
+    expect(dataStore.dependencies.last.includedPackageNames, []);
+    expect(dataStore.dependencies.last.includesFileUris, true);
+    expect(dataStore.dependencies.last.includesDartUris, false);
+  }
+
+  test_addBundle_multiProject() {
+    PackageBundle bundle = new _PackageBundleMock();
+    when(bundle.unlinkedUnitUris)
+        .thenReturn(<String>['package:p2/u1.dart', 'package:p1/u1.dart']);
+    when(bundle.unlinkedUnits)
+        .thenReturn(<UnlinkedUnit>[unlinkedUnit21, unlinkedUnit11]);
+    when(bundle.linkedLibraryUris)
+        .thenReturn(<String>['package:p2/u1.dart', 'package:p1/u1.dart']);
+    when(bundle.linkedLibraries)
+        .thenReturn(<LinkedLibrary>[linkedLibrary2, linkedLibrary1]);
+    when(bundle.apiSignature).thenReturn('signature');
+    dataStore.addBundle('/p3.ds', bundle);
+    expect(dataStore.dependencies.last.includedPackageNames, ['p1', 'p2']);
+  }
+
+  test_getContainingLibraryUris_libraryUri() {
+    String partUri = 'package:p1/u1.dart';
+    List<String> uris = dataStore.getContainingLibraryUris(partUri);
+    expect(uris, unorderedEquals([partUri]));
+  }
+
+  test_getContainingLibraryUris_partUri() {
+    String partUri = 'package:p1/u2.dart';
+    List<String> uris = dataStore.getContainingLibraryUris(partUri);
+    expect(uris, unorderedEquals(['package:p1/u1.dart']));
+  }
+
+  test_getContainingLibraryUris_unknownUri() {
+    String partUri = 'package:notInStore/foo.dart';
+    List<String> uris = dataStore.getContainingLibraryUris(partUri);
+    expect(uris, isNull);
+  }
+}
+
+class _InternalAnalysisContextMock extends TypedMock
+    implements InternalAnalysisContext {}
+
+class _LinkedLibraryMock extends TypedMock implements LinkedLibrary {}
+
+class _PackageBundleMock extends TypedMock implements PackageBundle {}
+
+class _SourceFactoryMock extends TypedMock implements SourceFactory {}
+
+class _SourceMock implements Source {
+  final Uri uri;
+  final String fullName;
+
+  _SourceMock(String uriStr, this.fullName) : uri = FastUri.parse(uriStr);
+
+  @override
+  Source get librarySource => null;
+
+  @override
+  Source get source => this;
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => '$uri ($fullName)';
+}
+
+class _TestResynthesizerResultProvider extends ResynthesizerResultProvider {
+  final Set<Source> sourcesWithResults = new Set<Source>();
+
+  _TestResynthesizerResultProvider(
+      InternalAnalysisContext context, SummaryDataStore dataStore)
+      : super(context, dataStore);
+
+  @override
+  bool hasResultsForSource(Source source) {
+    return sourcesWithResults.contains(source);
+  }
+}
+
+class _UnlinkedPublicNamespaceMock extends TypedMock
+    implements UnlinkedPublicNamespace {}
+
+class _UnlinkedUnitMock extends TypedMock implements UnlinkedUnit {}
diff --git a/pkg/analyzer/test/src/summary/pub_summary_test.dart b/pkg/analyzer/test/src/summary/pub_summary_test.dart
new file mode 100644
index 0000000..8475203
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/pub_summary_test.dart
@@ -0,0 +1,1373 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/pub_summary.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:unittest/unittest.dart' hide ERROR;
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+import '../context/abstract_context.dart';
+import '../context/mock_sdk.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(PubSummaryManagerTest);
+}
+
+@reflectiveTest
+class PubSummaryManagerTest extends AbstractContextTest {
+  static const String CACHE = '/home/.pub-cache/hosted/pub.dartlang.org';
+
+  PubSummaryManager manager;
+
+  void setUp() {
+    super.setUp();
+    _createManager();
+  }
+
+  test_computeSdkExtension() async {
+    // Create package files.
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+class A {}
+''');
+    resourceProvider.newFile(
+        '$CACHE/aaa/sdk_ext/extA.dart',
+        '''
+library test.a;
+import 'dart:async';
+part 'src/p1.dart';
+part 'src/p2.dart';
+class ExtA {}
+int V0;
+''');
+    resourceProvider.newFile(
+        '$CACHE/aaa/sdk_ext/src/p1.dart',
+        '''
+part of test.a;
+class ExtAA {}
+double V1;
+''');
+    resourceProvider.newFile(
+        '$CACHE/aaa/sdk_ext/src/p2.dart',
+        '''
+part of test.a;
+class ExtAB {}
+Future V2;
+''');
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/_sdkext',
+        '''
+{
+  "dart:aaa.internal": "../sdk_ext/extA.dart"
+}
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+class B {}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    PackageBundle sdkBundle = sdk.getLinkedBundle();
+    PackageBundle bundle = manager.computeSdkExtension(context, sdkBundle);
+    expect(bundle, isNotNull);
+    expect(bundle.linkedLibraryUris, ['dart:aaa.internal']);
+    expect(bundle.unlinkedUnitUris, [
+      'dart:aaa.internal',
+      'dart:aaa.internal/src/p1.dart',
+      'dart:aaa.internal/src/p2.dart'
+    ]);
+    expect(bundle.unlinkedUnits, hasLength(3));
+    expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['ExtA']);
+    expect(bundle.unlinkedUnits[1].classes.map((c) => c.name), ['ExtAA']);
+    expect(bundle.unlinkedUnits[2].classes.map((c) => c.name), ['ExtAB']);
+    // The library is linked.
+    expect(bundle.linkedLibraries, hasLength(1));
+    LinkedLibrary linkedLibrary = bundle.linkedLibraries[0];
+    // V0 is linked
+    {
+      UnlinkedUnit unlinkedUnit = bundle.unlinkedUnits[0];
+      LinkedUnit linkedUnit = linkedLibrary.units[0];
+      expect(unlinkedUnit.variables, hasLength(1));
+      UnlinkedVariable variable = unlinkedUnit.variables[0];
+      expect(variable.name, 'V0');
+      int typeRef = variable.type.reference;
+      expect(unlinkedUnit.references[typeRef].name, 'int');
+      LinkedReference linkedReference = linkedUnit.references[typeRef];
+      expect(linkedLibrary.dependencies[linkedReference.dependency].uri,
+          'dart:core');
+    }
+    // V1 is linked
+    {
+      UnlinkedUnit unlinkedUnit = bundle.unlinkedUnits[1];
+      LinkedUnit linkedUnit = linkedLibrary.units[1];
+      expect(unlinkedUnit.variables, hasLength(1));
+      UnlinkedVariable variable = unlinkedUnit.variables[0];
+      expect(variable.name, 'V1');
+      int typeRef = variable.type.reference;
+      expect(unlinkedUnit.references[typeRef].name, 'double');
+      LinkedReference linkedReference = linkedUnit.references[typeRef];
+      expect(linkedLibrary.dependencies[linkedReference.dependency].uri,
+          'dart:core');
+    }
+    // V2 is linked
+    {
+      UnlinkedUnit unlinkedUnit = bundle.unlinkedUnits[2];
+      LinkedUnit linkedUnit = linkedLibrary.units[2];
+      expect(unlinkedUnit.variables, hasLength(1));
+      UnlinkedVariable variable = unlinkedUnit.variables[0];
+      expect(variable.name, 'V2');
+      int typeRef = variable.type.reference;
+      expect(unlinkedUnit.references[typeRef].name, 'Future');
+      LinkedReference linkedReference = linkedUnit.references[typeRef];
+      expect(linkedLibrary.dependencies[linkedReference.dependency].uri,
+          'dart:async');
+    }
+  }
+
+  test_computeUnlinkedForFolder() async {
+    // Create package files.
+    resourceProvider.newFile(
+        '/flutter/aaa/lib/a.dart',
+        '''
+class A {}
+''');
+    resourceProvider.newFile(
+        '/flutter/bbb/lib/b.dart',
+        '''
+class B {}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('/flutter/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('/flutter/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    await manager.computeUnlinkedForFolder('aaa', libFolderA);
+    await manager.computeUnlinkedForFolder('bbb', libFolderB);
+
+    // The files must be created.
+    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_NAME);
+    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
+  }
+
+  test_getLinkedBundles_cached() async {
+    String pathA1 = '$CACHE/aaa-1.0.0';
+    String pathA2 = '$CACHE/aaa-2.0.0';
+    resourceProvider.newFile(
+        '$pathA1/lib/a.dart',
+        '''
+class A {}
+int a;
+''');
+    resourceProvider.newFile(
+        '$pathA2/lib/a.dart',
+        '''
+class A2 {}
+int a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:aaa/a.dart';
+A b;
+''');
+    Folder folderA1 = resourceProvider.getFolder(pathA1);
+    Folder folderA2 = resourceProvider.getFolder(pathA2);
+    Folder folderB = resourceProvider.getFolder('$CACHE/bbb');
+
+    // Configure packages resolution.
+    Folder libFolderA1 = resourceProvider.newFolder('$pathA1/lib');
+    Folder libFolderA2 = resourceProvider.newFolder('$pathA2/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA1],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Session 1.
+    // Create linked bundles and store them in files.
+    String linkedHashA;
+    String linkedHashB;
+    {
+      // Ensure unlinked bundles.
+      manager.getUnlinkedBundles(context);
+      await manager.onUnlinkedComplete;
+
+      // Now we should be able to get linked bundles.
+      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+      expect(linkedPackages, hasLength(2));
+
+      // Verify that files with linked bundles were created.
+      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
+      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
+      linkedHashA = packageA.linkedHash;
+      linkedHashB = packageB.linkedHash;
+      _assertFileExists(folderA1, 'linked_spec_$linkedHashA.ds');
+      _assertFileExists(folderB, 'linked_spec_$linkedHashB.ds');
+    }
+
+    // Session 2.
+    // Recreate manager and ask again.
+    {
+      _createManager();
+      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+      expect(linkedPackages, hasLength(2));
+
+      // Verify that linked packages have the same hashes, so they must
+      // be have been read from the previously created files.
+      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
+      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
+      expect(packageA.linkedHash, linkedHashA);
+      expect(packageB.linkedHash, linkedHashB);
+    }
+
+    // Session 2 with different 'aaa' version.
+    // Different linked bundles.
+    {
+      context.sourceFactory = new SourceFactory(<UriResolver>[
+        sdkResolver,
+        resourceResolver,
+        new PackageMapUriResolver(resourceProvider, {
+          'aaa': [libFolderA2],
+          'bbb': [libFolderB],
+        })
+      ]);
+
+      // Ensure unlinked bundles.
+      manager.getUnlinkedBundles(context);
+      await manager.onUnlinkedComplete;
+
+      // Now we should be able to get linked bundles.
+      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+      expect(linkedPackages, hasLength(2));
+
+      // Verify that new files with linked bundles were created.
+      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
+      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
+      expect(packageA.linkedHash, isNot(linkedHashA));
+      expect(packageB.linkedHash, isNot(linkedHashB));
+      _assertFileExists(folderA2, 'linked_spec_${packageA.linkedHash}.ds');
+      _assertFileExists(folderB, 'linked_spec_${packageB.linkedHash}.ds');
+    }
+  }
+
+  test_getLinkedBundles_cached_differentSdk() async {
+    String pathA = '$CACHE/aaa';
+    resourceProvider.newFile(
+        '$pathA/lib/a.dart',
+        '''
+class A {}
+int a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:aaa/a.dart';
+A b;
+''');
+    Folder folderA = resourceProvider.getFolder(pathA);
+    Folder folderB = resourceProvider.getFolder('$CACHE/bbb');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$pathA/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Session 1.
+    // Create linked bundles and store them in files.
+    String linkedHashA;
+    String linkedHashB;
+    {
+      // Ensure unlinked bundles.
+      manager.getUnlinkedBundles(context);
+      await manager.onUnlinkedComplete;
+
+      // Now we should be able to get linked bundles.
+      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+      expect(linkedPackages, hasLength(2));
+
+      // Verify that files with linked bundles were created.
+      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
+      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
+      linkedHashA = packageA.linkedHash;
+      linkedHashB = packageB.linkedHash;
+      _assertFileExists(folderA, 'linked_spec_$linkedHashA.ds');
+      _assertFileExists(folderB, 'linked_spec_$linkedHashB.ds');
+    }
+
+    // Session 2.
+    // Use DartSdk with a different API signature.
+    // Different linked bundles should be created.
+    {
+      MockSdk sdk = new MockSdk();
+      sdk.updateUriFile('dart:math', (String content) {
+        return content + '  class NewMathClass {}';
+      });
+      context.sourceFactory = new SourceFactory(<UriResolver>[
+        new DartUriResolver(sdk),
+        resourceResolver,
+        new PackageMapUriResolver(resourceProvider, {
+          'aaa': [libFolderA],
+          'bbb': [libFolderB],
+        })
+      ]);
+
+      // Ensure unlinked bundles.
+      manager.getUnlinkedBundles(context);
+      await manager.onUnlinkedComplete;
+
+      // Now we should be able to get linked bundles.
+      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+      expect(linkedPackages, hasLength(2));
+
+      // Verify that new files with linked bundles were created.
+      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
+      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
+      expect(packageA.linkedHash, isNot(linkedHashA));
+      expect(packageB.linkedHash, isNot(linkedHashB));
+      _assertFileExists(folderA, 'linked_spec_${packageA.linkedHash}.ds');
+      _assertFileExists(folderB, 'linked_spec_${packageB.linkedHash}.ds');
+    }
+  }
+
+  test_getLinkedBundles_cached_useSdkExtension() async {
+    String pathA1 = '$CACHE/aaa-1.0.0';
+    String pathA2 = '$CACHE/aaa-2.0.0';
+    // aaa-1.0.0
+    resourceProvider.newFile(
+        '$pathA1/lib/a.dart',
+        '''
+class A {}
+int a;
+''');
+    resourceProvider.newFile(
+        '$pathA1/sdk_ext/extA.dart',
+        '''
+class ExtA1 {}
+''');
+    resourceProvider.newFile(
+        '$pathA1/lib/_sdkext',
+        '''
+{
+  "dart:aaa": "../sdk_ext/extA.dart"
+}
+''');
+    // aaa-2.0.0
+    resourceProvider.newFile(
+        '$pathA2/lib/a.dart',
+        '''
+class A {}
+int a;
+''');
+    resourceProvider.newFile(
+        '$pathA2/sdk_ext/extA.dart',
+        '''
+class ExtA2 {}
+''');
+    resourceProvider.newFile(
+        '$pathA2/lib/_sdkext',
+        '''
+{
+  "dart:aaa": "../sdk_ext/extA.dart"
+}
+''');
+    // bbb
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:aaa/a.dart';
+A b;
+''');
+    Folder folderA1 = resourceProvider.getFolder(pathA1);
+    Folder folderA2 = resourceProvider.getFolder(pathA2);
+    Folder folderB = resourceProvider.getFolder('$CACHE/bbb');
+
+    // Configure packages resolution.
+    Folder libFolderA1 = resourceProvider.newFolder('$pathA1/lib');
+    Folder libFolderA2 = resourceProvider.newFolder('$pathA2/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA1],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Session 1.
+    // Create linked bundles and store them in files.
+    String linkedHashA;
+    String linkedHashB;
+    {
+      // Ensure unlinked bundles.
+      manager.getUnlinkedBundles(context);
+      await manager.onUnlinkedComplete;
+
+      // Now we should be able to get linked bundles.
+      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+      expect(linkedPackages, hasLength(2));
+
+      // Verify that files with linked bundles were created.
+      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
+      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
+      linkedHashA = packageA.linkedHash;
+      linkedHashB = packageB.linkedHash;
+      _assertFileExists(folderA1, 'linked_spec_$linkedHashA.ds');
+      _assertFileExists(folderB, 'linked_spec_$linkedHashB.ds');
+    }
+
+    // Session 2.
+    // Use 'aaa-2.0.0', with a different SDK extension.
+    {
+      context.sourceFactory = new SourceFactory(<UriResolver>[
+        sdkResolver,
+        resourceResolver,
+        new PackageMapUriResolver(resourceProvider, {
+          'aaa': [libFolderA2],
+          'bbb': [libFolderB],
+        })
+      ]);
+
+      // Ensure unlinked bundles.
+      manager.getUnlinkedBundles(context);
+      await manager.onUnlinkedComplete;
+
+      // Now we should be able to get linked bundles.
+      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+      expect(linkedPackages, hasLength(2));
+
+      // Verify that new files with linked bundles were created.
+      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
+      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
+      expect(packageA.linkedHash, isNot(linkedHashA));
+      expect(packageB.linkedHash, isNot(linkedHashB));
+      _assertFileExists(folderA2, 'linked_spec_${packageA.linkedHash}.ds');
+      _assertFileExists(folderB, 'linked_spec_${packageB.linkedHash}.ds');
+    }
+  }
+
+  test_getLinkedBundles_hasCycle() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'package:bbb/b.dart';
+class A {}
+int a1;
+B a2;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:ccc/c.dart';
+class B {}
+C b;
+''');
+    resourceProvider.newFile(
+        '$CACHE/ccc/lib/c.dart',
+        '''
+import 'package:aaa/a.dart';
+import 'package:ddd/d.dart';
+class C {}
+A c1;
+D c2;
+''');
+    resourceProvider.newFile(
+        '$CACHE/ddd/lib/d.dart',
+        '''
+class D {}
+String d;
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
+    Folder libFolderD = resourceProvider.newFolder('$CACHE/ddd/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+        'ccc': [libFolderC],
+        'ddd': [libFolderD],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Now we should be able to get linked bundles.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(4));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      expect(linkedPackage.linked.linkedLibraryUris, ['package:aaa/a.dart']);
+      _assertHasLinkedVariable(linkedPackage, 'a1', 'int',
+          expectedTypeNameUri: 'dart:core');
+      _assertHasLinkedVariable(linkedPackage, 'a2', 'B',
+          expectedTypeNameUri: 'package:bbb/b.dart');
+    }
+
+    // package:bbb
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
+      expect(linkedPackage.linked.linkedLibraryUris, ['package:bbb/b.dart']);
+      _assertHasLinkedVariable(linkedPackage, 'b', 'C',
+          expectedTypeNameUri: 'package:ccc/c.dart');
+    }
+
+    // package:ccc
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'ccc');
+      expect(linkedPackage.linked.linkedLibraryUris, ['package:ccc/c.dart']);
+      _assertHasLinkedVariable(linkedPackage, 'c1', 'A',
+          expectedTypeNameUri: 'package:aaa/a.dart');
+      _assertHasLinkedVariable(linkedPackage, 'c2', 'D',
+          expectedTypeNameUri: 'package:ddd/d.dart');
+    }
+
+    // package:ddd
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'ddd');
+      expect(linkedPackage.linked.linkedLibraryUris, ['package:ddd/d.dart']);
+      _assertHasLinkedVariable(linkedPackage, 'd', 'String',
+          expectedTypeNameUri: 'dart:core');
+    }
+  }
+
+  test_getLinkedBundles_missingBundle() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+int a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:ccc/c.dart';
+int b1;
+C b2;
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Try to link.
+    // Both 'aaa' and 'bbb' are linked.
+    // The name 'C' in 'b.dart' is not resolved.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(2));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a', 'int',
+          expectedTypeNameUri: 'dart:core');
+    }
+
+    // package:bbb
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
+      _assertHasLinkedVariable(linkedPackage, 'b1', 'int',
+          expectedTypeNameUri: 'dart:core');
+      _assertHasLinkedVariable(linkedPackage, 'b2', 'C',
+          expectedToBeResolved: false);
+    }
+  }
+
+  test_getLinkedBundles_missingBundle_chained() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'package:bbb/b.dart';
+int a1;
+B a2;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:ccc/c.dart';
+class B {}
+int b1;
+C b2;
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Try to link.
+    // Both 'aaa' and 'bbb' are linked.
+    // The name 'C' in 'b.dart' is not resolved.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(2));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a1', 'int',
+          expectedTypeNameUri: 'dart:core');
+      _assertHasLinkedVariable(linkedPackage, 'a2', 'B',
+          expectedTypeNameUri: 'package:bbb/b.dart');
+    }
+
+    // package:bbb
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
+      _assertHasLinkedVariable(linkedPackage, 'b1', 'int',
+          expectedTypeNameUri: 'dart:core');
+      _assertHasLinkedVariable(linkedPackage, 'b2', 'C',
+          expectedToBeResolved: false);
+    }
+  }
+
+  test_getLinkedBundles_missingLibrary() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'package:bbb/b2.dart';
+int a1;
+B2 a2;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+class B {}
+int b = 42;
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Try to link.
+    // Both 'aaa' and 'bbb' are linked.
+    // The name 'B2' in 'a.dart' is not resolved.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(2));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a1', 'int',
+          expectedTypeNameUri: 'dart:core');
+      _assertHasLinkedVariable(linkedPackage, 'a2', 'B2',
+          expectedToBeResolved: false);
+    }
+
+    // package:bbb
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
+      _assertHasLinkedVariable(linkedPackage, 'b', 'int',
+          expectedTypeNameUri: 'dart:core');
+    }
+  }
+
+  test_getLinkedBundles_missingLibrary_hasCycle() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'package:bbb/b.dart';
+B a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:aaa/a.dart';
+import 'package:ccc/c2.dart';
+class B {}
+int b1;
+C2 b2;
+''');
+    resourceProvider.newFile(
+        '$CACHE/ccc/lib/c.dart',
+        '''
+class C {}
+int c;
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+        'ccc': [libFolderC],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Try to link.
+    // All bundles 'aaa' and 'bbb' and 'ccc' are linked.
+    // The name 'C2' in 'b.dart' is not resolved.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(3));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a', 'B',
+          expectedTypeNameUri: 'package:bbb/b.dart');
+    }
+
+    // package:bbb
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
+      _assertHasLinkedVariable(linkedPackage, 'b1', 'int',
+          expectedTypeNameUri: 'dart:core');
+      _assertHasLinkedVariable(linkedPackage, 'b2', 'C2',
+          expectedToBeResolved: false);
+    }
+
+    // package:ccc
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'ccc');
+      _assertHasLinkedVariable(linkedPackage, 'c', 'int',
+          expectedTypeNameUri: 'dart:core');
+    }
+  }
+
+  test_getLinkedBundles_noCycle() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+class A {}
+int a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'package:aaa/a.dart';
+A b;
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Now we should be able to get linked bundles.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(2));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a', 'int',
+          expectedTypeNameUri: 'dart:core');
+    }
+
+    // package:bbb
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
+      _assertHasLinkedVariable(linkedPackage, 'b', 'A',
+          expectedTypeNameUri: 'package:aaa/a.dart');
+    }
+  }
+
+  test_getLinkedBundles_noCycle_relativeUri() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'src/a2.dart';
+A a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/src/a2.dart',
+        '''
+class A {}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Link.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(1));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a', 'A',
+          expectedTypeNameUri: 'src/a2.dart');
+    }
+  }
+
+  test_getLinkedBundles_noCycle_withExport() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'package:bbb/b.dart';
+C a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+export 'package:ccc/c.dart';
+''');
+    resourceProvider.newFile(
+        '$CACHE/ccc/lib/c.dart',
+        '''
+class C {}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+        'ccc': [libFolderC],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Now we should be able to get linked bundles.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(3));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a', 'C',
+          expectedTypeNameUri: 'package:ccc/c.dart');
+    }
+  }
+
+  test_getLinkedBundles_useSdkExtension() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'dart:bbb';
+ExtB a;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+import 'dart:bbb';
+ExtB b;
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/sdk_ext/extB.dart',
+        '''
+class ExtB {}
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/_sdkext',
+        '''
+{
+  "dart:bbb": "../sdk_ext/extB.dart"
+}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Now we should be able to get linked bundles.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(2));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a', 'ExtB',
+          expectedTypeNameUri: 'dart:bbb');
+    }
+
+    // package:bbb
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
+      _assertHasLinkedVariable(linkedPackage, 'b', 'ExtB',
+          expectedTypeNameUri: 'dart:bbb');
+    }
+  }
+
+  test_getLinkedBundles_wrongScheme() async {
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+import 'xxx:yyy/zzz.dart';
+int a1;
+Z a2;
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+      })
+    ]);
+
+    // Ensure unlinked bundles.
+    manager.getUnlinkedBundles(context);
+    await manager.onUnlinkedComplete;
+
+    // Try to link.
+    // The package 'aaa' is linked.
+    // The name 'Z' in 'a.dart' is not resolved.
+    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+    expect(linkedPackages, hasLength(1));
+
+    // package:aaa
+    {
+      LinkedPubPackage linkedPackage = linkedPackages
+          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
+      _assertHasLinkedVariable(linkedPackage, 'a1', 'int',
+          expectedTypeNameUri: 'dart:core');
+      _assertHasLinkedVariable(linkedPackage, 'a2', 'Z',
+          expectedToBeResolved: false);
+    }
+  }
+
+  test_getPackageName() {
+    String getPackageName(String uriStr) {
+      return PubSummaryManager.getPackageName(uriStr);
+    }
+    expect(getPackageName('package:foo/bar.dart'), 'foo');
+    expect(getPackageName('package:foo/bar/baz.dart'), 'foo');
+    expect(getPackageName('wrong:foo/bar.dart'), isNull);
+    expect(getPackageName('package:foo'), isNull);
+  }
+
+  test_getUnlinkedBundles() async {
+    // Create package files.
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/a.dart',
+        '''
+class A {}
+''');
+    resourceProvider.newFile(
+        '$CACHE/aaa/lib/src/a2.dart',
+        '''
+class A2 {}
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+class B {}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // No unlinked bundles yet.
+    {
+      Map<PubPackage, PackageBundle> bundles =
+          manager.getUnlinkedBundles(context);
+      expect(bundles, isEmpty);
+    }
+
+    // The requested unlinked bundles must be available after the wait.
+    await manager.onUnlinkedComplete;
+    {
+      Map<PubPackage, PackageBundle> bundles =
+          manager.getUnlinkedBundles(context);
+      expect(bundles, hasLength(2));
+      {
+        PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
+        expect(bundle.linkedLibraryUris, isEmpty);
+        expect(bundle.unlinkedUnitUris,
+            ['package:aaa/a.dart', 'package:aaa/src/a2.dart']);
+        expect(bundle.unlinkedUnits, hasLength(2));
+        expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['A']);
+        expect(bundle.unlinkedUnits[1].classes.map((c) => c.name), ['A2']);
+      }
+      {
+        PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb');
+        expect(bundle.linkedLibraryUris, isEmpty);
+        expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']);
+        expect(bundle.unlinkedUnits, hasLength(1));
+        expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']);
+      }
+    }
+
+    // The files must be created.
+    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_NAME);
+    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
+  }
+
+  test_getUnlinkedBundles_notPubCache_dontCreate() async {
+    String aaaPath = '/Users/user/projects/aaa';
+    // Create package files.
+    resourceProvider.newFile(
+        '$aaaPath/lib/a.dart',
+        '''
+class A {}
+''');
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+class B {}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.getFolder('$aaaPath/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // No unlinked bundles initially.
+    {
+      Map<PubPackage, PackageBundle> bundles =
+          manager.getUnlinkedBundles(context);
+      expect(bundles, isEmpty);
+    }
+
+    // Wait for unlinked bundles to be computed.
+    await manager.onUnlinkedComplete;
+    Map<PubPackage, PackageBundle> bundles =
+        manager.getUnlinkedBundles(context);
+    // We have just one bundle - for 'bbb'.
+    expect(bundles, hasLength(1));
+    // We computed the unlinked bundle for 'bbb'.
+    {
+      PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb');
+      expect(bundle.linkedLibraryUris, isEmpty);
+      expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']);
+      expect(bundle.unlinkedUnits, hasLength(1));
+      expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']);
+    }
+
+    // The files must be created.
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
+  }
+
+  test_getUnlinkedBundles_notPubCache_useExisting() async {
+    String aaaPath = '/Users/user/projects/aaa';
+    // Create package files.
+    {
+      File file = resourceProvider.newFile(
+          '$aaaPath/lib/a.dart',
+          '''
+class A {}
+''');
+      PackageBundleAssembler assembler = new PackageBundleAssembler()
+        ..addUnlinkedUnit(
+            file.createSource(FastUri.parse('package:aaa/a.dart')),
+            new UnlinkedUnitBuilder());
+      resourceProvider.newFileWithBytes(
+          '$aaaPath/${PubSummaryManager.UNLINKED_SPEC_NAME}',
+          assembler.assemble().toBuffer());
+    }
+    resourceProvider.newFile(
+        '$CACHE/bbb/lib/b.dart',
+        '''
+class B {}
+''');
+
+    // Configure packages resolution.
+    Folder libFolderA = resourceProvider.getFolder('$aaaPath/lib');
+    Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      sdkResolver,
+      resourceResolver,
+      new PackageMapUriResolver(resourceProvider, {
+        'aaa': [libFolderA],
+        'bbb': [libFolderB],
+      })
+    ]);
+
+    // Request already available unlinked bundles.
+    {
+      Map<PubPackage, PackageBundle> bundles =
+          manager.getUnlinkedBundles(context);
+      expect(bundles, hasLength(1));
+      // We get the unlinked bundle for 'aaa' because it already exists.
+      {
+        PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
+        expect(bundle, isNotNull);
+      }
+    }
+
+    // Wait for unlinked bundles to be computed.
+    await manager.onUnlinkedComplete;
+    Map<PubPackage, PackageBundle> bundles =
+        manager.getUnlinkedBundles(context);
+    expect(bundles, hasLength(2));
+    // We still have the unlinked bundle for 'aaa'.
+    {
+      PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
+      expect(bundle, isNotNull);
+    }
+    // We computed the unlinked bundle for 'bbb'.
+    {
+      PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb');
+      expect(bundle.linkedLibraryUris, isEmpty);
+      expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']);
+      expect(bundle.unlinkedUnits, hasLength(1));
+      expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']);
+    }
+
+    // The files must be created.
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
+    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
+  }
+
+  test_getUnlinkedBundles_nullPackageMap() async {
+    context.sourceFactory =
+        new SourceFactory(<UriResolver>[sdkResolver, resourceResolver]);
+    Map<PubPackage, PackageBundle> bundles =
+        manager.getUnlinkedBundles(context);
+    expect(bundles, isEmpty);
+  }
+
+  test_isPathInPubCache_posix() {
+    expect(
+        PubSummaryManager.isPathInPubCache(pathos.posix,
+            '/home/.pub-cache/hosted/pub.dartlang.org/foo/lib/bar.dart'),
+        isTrue);
+    expect(
+        PubSummaryManager.isPathInPubCache(
+            pathos.posix, '/home/.pub-cache/foo/lib/bar.dart'),
+        isTrue);
+    expect(
+        PubSummaryManager.isPathInPubCache(
+            pathos.posix, '/home/sources/dart/foo/lib/bar.dart'),
+        isFalse);
+  }
+
+  test_isPathInPubCache_windows() {
+    expect(
+        PubSummaryManager.isPathInPubCache(pathos.windows,
+            r'C:\Users\user\Setters\Pub\Cache\hosted\foo\lib\bar.dart'),
+        isTrue);
+    expect(
+        PubSummaryManager.isPathInPubCache(
+            pathos.windows, r'C:\Users\user\Sources\Dart\foo\lib\bar.dart'),
+        isFalse);
+  }
+
+  void _assertFileExists(Folder folder, String fileName) {
+    expect(folder.getChildAssumingFile(fileName).exists, isTrue);
+  }
+
+  void _assertHasLinkedVariable(LinkedPubPackage linkedPackage,
+      String variableName, String expectedTypeName,
+      {bool expectedToBeResolved: true,
+      String expectedTypeNameUri: 'shouldBeSpecifiedIfResolved'}) {
+    PackageBundle unlinked = linkedPackage.unlinked;
+    PackageBundle linked = linkedPackage.linked;
+    expect(unlinked, isNotNull);
+    expect(linked, isNotNull);
+    for (int i = 0; i < unlinked.unlinkedUnitUris.length; i++) {
+      String unlinkedUnitUri = unlinked.unlinkedUnitUris[i];
+      UnlinkedUnit unlinkedUnit = unlinked.unlinkedUnits[i];
+      for (UnlinkedVariable v in unlinkedUnit.variables) {
+        if (v.name == variableName) {
+          int typeNameReference = v.type.reference;
+          expect(unlinkedUnit.references[typeNameReference].name,
+              expectedTypeName);
+          for (int j = 0; j < linked.linkedLibraryUris.length; j++) {
+            String linkedLibraryUri = linked.linkedLibraryUris[j];
+            if (linkedLibraryUri == unlinkedUnitUri) {
+              LinkedLibrary linkedLibrary = linked.linkedLibraries[j];
+              LinkedUnit linkedUnit = linkedLibrary.units.single;
+              int typeNameDependency =
+                  linkedUnit.references[typeNameReference].dependency;
+              if (expectedToBeResolved) {
+                expect(linkedLibrary.dependencies[typeNameDependency].uri,
+                    expectedTypeNameUri);
+              } else {
+                expect(typeNameDependency, isZero);
+              }
+              return;
+            }
+          }
+          fail('Cannot find linked unit for $variableName in $linkedPackage');
+        }
+      }
+    }
+    fail('Cannot find variable $variableName in $linkedPackage');
+  }
+
+  void _createManager() {
+    manager = new PubSummaryManager(resourceProvider, '_.temp');
+  }
+
+  LinkedPubPackage _getLinkedPackage(
+      List<LinkedPubPackage> packages, String name) {
+    return packages
+        .singleWhere((linkedPackage) => linkedPackage.package.name == name);
+  }
+
+  static PackageBundle _getBundleByPackageName(
+      Map<PubPackage, PackageBundle> bundles, String name) {
+    PubPackage package =
+        bundles.keys.singleWhere((package) => package.name == name);
+    return bundles[package];
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 1adaae0..bd2c1fb 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -20,6 +20,7 @@
 import 'package:analyzer/src/summary/summarize_elements.dart'
     show PackageBundleAssembler;
 import 'package:analyzer/task/dart.dart' show PARSED_UNIT;
+import 'package:analyzer/task/general.dart';
 import 'package:unittest/unittest.dart';
 
 import '../../reflective_tests.dart';
@@ -157,6 +158,87 @@
 
   @override
   @failingTest
+  void test_constructors_inferenceFBounded() {
+    super.test_constructors_inferenceFBounded();
+  }
+
+  @override
+  @failingTest
+  void test_constructors_inferFromArguments() {
+    // TODO(jmesserly): does this need to be implemented in AST summaries?
+    // The test might need a change as well to not be based on local variable
+    // types, which don't seem to be available.
+    super.test_constructors_inferFromArguments();
+  }
+
+  @override
+  @failingTest
+  void test_constructors_inferFromArguments_const() {
+    super.test_constructors_inferFromArguments_const();
+  }
+
+  @override
+  @failingTest
+  void test_constructors_inferFromArguments_factory() {
+    super.test_constructors_inferFromArguments_factory();
+  }
+
+  @override
+  @failingTest
+  void test_constructors_inferFromArguments_named() {
+    super.test_constructors_inferFromArguments_named();
+  }
+
+  @override
+  @failingTest
+  void test_constructors_inferFromArguments_namedFactory() {
+    super.test_constructors_inferFromArguments_namedFactory();
+  }
+
+  @override
+  @failingTest
+  void test_constructors_inferFromArguments_redirecting() {
+    super.test_constructors_inferFromArguments_redirecting();
+  }
+
+  @override
+  @failingTest
+  void test_constructors_inferFromArguments_redirectingFactory() {
+    super.test_constructors_inferFromArguments_redirectingFactory();
+  }
+
+  @override
+  @failingTest
+  void test_futureThen() {
+    super.test_futureThen();
+  }
+
+  @override
+  @failingTest
+  void test_futureThen_conditional() {
+    super.test_futureThen_conditional();
+  }
+
+  @override
+  @failingTest
+  void test_futureThen_upwards() {
+    super.test_futureThen_upwards();
+  }
+
+  @override
+  @failingTest
+  void test_futureUnion_asyncConditional() {
+    super.test_futureUnion_asyncConditional();
+  }
+
+  @override
+  @failingTest
+  void test_futureUnion_downwards() {
+    super.test_futureUnion_downwards();
+  }
+
+  @override
+  @failingTest
   void test_genericMethods_inferJSBuiltin() {
     super.test_genericMethods_inferJSBuiltin();
   }
@@ -516,6 +598,12 @@
 
   @override
   @failingTest
+  void test_inferLocalFunctionReturnType() {
+    super.test_inferLocalFunctionReturnType();
+  }
+
+  @override
+  @failingTest
   void test_inferredType_opAssignToProperty_prefixedIdentifier() {
     super.test_inferredType_opAssignToProperty_prefixedIdentifier();
   }
@@ -547,6 +635,78 @@
     expect(unit.topLevelVariables[0].type.toString(), 'int');
   }
 
+  @override
+  @failingTest
+  void test_nullCoalescingOperator() {
+    super.test_nullCoalescingOperator();
+  }
+
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_closureCall() {
+    super.test_unsafeBlockClosureInference_closureCall();
+  }
+
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_constructorCall_implicitTypeParam() {
+    super.test_unsafeBlockClosureInference_constructorCall_implicitTypeParam();
+  }
+
+  @override
+  @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2();
+  }
+
+  @override
+  @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2();
+  }
+
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_functionCall_implicitTypeParam() {
+    super.test_unsafeBlockClosureInference_functionCall_implicitTypeParam();
+  }
+
+  @override
+  @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr();
+  }
+
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_functionCall_noTypeParam_viaExpr() {
+    super.test_unsafeBlockClosureInference_functionCall_noTypeParam_viaExpr();
+  }
+
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_inList_untyped() {
+    super.test_unsafeBlockClosureInference_inList_untyped();
+  }
+
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_inMap_untyped() {
+    super.test_unsafeBlockClosureInference_inMap_untyped();
+  }
+
+  @override
+  @failingTest
+  void test_unsafeBlockClosureInference_methodCall_implicitTypeParam() {
+    super.test_unsafeBlockClosureInference_methodCall_implicitTypeParam();
+  }
+
   LibraryElementImpl _checkSource(
       SummaryResynthesizer resynthesizer, Source source) {
     LibraryElementImpl resynthesized =
@@ -585,7 +745,8 @@
 /**
  * Abstract mixin for serializing ASTs and resynthesizing elements from it.
  */
-abstract class _AstResynthesizeTestMixin {
+abstract class _AstResynthesizeTestMixin
+    implements _AstResynthesizeTestMixinInterface {
   final Set<Source> serializedSources = new Set<Source>();
   final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
   final Map<String, UnlinkedUnitBuilder> uriToUnit =
@@ -614,7 +775,7 @@
       Map<String, LinkedLibrary> sdkLibraries =
           SerializedMockSdk.instance.uriToLinkedLibrary;
       LinkedLibrary linkedLibrary = sdkLibraries[absoluteUri];
-      if (linkedLibrary == null) {
+      if (linkedLibrary == null && !allowMissingFiles) {
         fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
             '  Libraries available: ${sdkLibraries.keys}');
       }
@@ -624,7 +785,7 @@
     UnlinkedUnit getUnit(String absoluteUri) {
       UnlinkedUnit unit = uriToUnit[absoluteUri] ??
           SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri];
-      if (unit == null) {
+      if (unit == null && !allowMissingFiles) {
         fail('Linker unexpectedly requested unit for "$absoluteUri".');
       }
       return unit;
@@ -648,7 +809,8 @@
           ..addAll(unlinkedSummaries),
         new Map<String, LinkedLibrary>()
           ..addAll(SerializedMockSdk.instance.uriToLinkedLibrary)
-          ..addAll(linkedSummaries));
+          ..addAll(linkedSummaries),
+        allowMissingFiles);
   }
 
   UnlinkedUnit _getUnlinkedUnit(Source source) {
@@ -661,6 +823,14 @@
       }
     }
     return uriToUnit.putIfAbsent(uriStr, () {
+      int modificationTime = context.computeResult(source, MODIFICATION_TIME);
+      if (modificationTime < 0) {
+        // Source does not exist.
+        if (!allowMissingFiles) {
+          fail('Unexpectedly tried to get unlinked summary for $source');
+        }
+        return null;
+      }
       CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
       UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
       bundleAssembler.addUnlinkedUnit(source, unlinkedUnit);
@@ -691,14 +861,30 @@
     }
 
     UnlinkedPublicNamespace getImport(String relativeUri) {
-      return getPart(relativeUri).publicNamespace;
+      return getPart(relativeUri)?.publicNamespace;
     }
 
     UnlinkedUnit definingUnit = _getUnlinkedUnit(librarySource);
-    LinkedLibraryBuilder linkedLibrary =
-        prelink(definingUnit, getPart, getImport);
-    linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) {
-      _serializeLibrary(resolveRelativeUri(d.uri));
-    });
+    if (definingUnit != null) {
+      LinkedLibraryBuilder linkedLibrary =
+          prelink(definingUnit, getPart, getImport);
+      linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) {
+        _serializeLibrary(resolveRelativeUri(d.uri));
+      });
+    }
   }
 }
+
+/**
+ * Interface that [_AstResynthesizeTestMixin] requires of classes it's mixed
+ * into.  We can't place the getter below into [_AstResynthesizeTestMixin]
+ * directly, because then it would be overriding a field at the site where the
+ * mixin is instantiated.
+ */
+abstract class _AstResynthesizeTestMixinInterface {
+  /**
+   * A test should return `true` to indicate that a missing file at the time of
+   * summary resynthesis shouldn't trigger an error.
+   */
+  bool get allowMissingFiles;
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_strong_test.dart b/pkg/analyzer/test/src/summary/resynthesize_strong_test.dart
index d337de7..63b8c2c 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_strong_test.dart
@@ -25,4 +25,11 @@
   @override
   AnalysisOptionsImpl createOptions() =>
       super.createOptions()..strongMode = true;
+
+  @override
+  @failingTest
+  test_instantiateToBounds_boundRefersToLaterTypeArgument() {
+    // TODO(paulberry): this is failing due to dartbug.com/27072.
+    super.test_instantiateToBounds_boundRefersToLaterTypeArgument();
+  }
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index 881ad8f..f08366b8 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -49,6 +49,12 @@
    */
   Set<String> variablesWithNotConstInitializers = new Set<String>();
 
+  /**
+   * Tests may set this to `true` to indicate that a missing file at the time of
+   * summary resynthesis shouldn't trigger an error.
+   */
+  bool allowMissingFiles = false;
+
   bool get checkPropagatedTypes => true;
 
   void addLibrary(String uri) {
@@ -107,14 +113,16 @@
     expect(resynthesized.imports.length, original.imports.length,
         reason: 'imports');
     for (int i = 0; i < resynthesized.imports.length; i++) {
-      compareImportElements(resynthesized.imports[i], original.imports[i],
-          'import ${original.imports[i].uri}');
+      ImportElement originalImport = original.imports[i];
+      compareImportElements(
+          resynthesized.imports[i], originalImport, originalImport.toString());
     }
     expect(resynthesized.exports.length, original.exports.length,
         reason: 'exports');
     for (int i = 0; i < resynthesized.exports.length; i++) {
-      compareExportElements(resynthesized.exports[i], original.exports[i],
-          'export ${original.exports[i].uri}');
+      ExportElement originalExport = original.exports[i];
+      compareExportElements(
+          resynthesized.exports[i], originalExport, originalExport.toString());
     }
     expect(resynthesized.nameLength, original.nameLength);
     compareNamespaces(resynthesized.publicNamespace, original.publicNamespace,
@@ -692,18 +700,12 @@
     compareMetadata(resynthesized.metadata, original.metadata, desc);
 
     // Validate modifiers.
-    for (Modifier modifier in Modifier.persistedValues) {
+    for (Modifier modifier in Modifier.values) {
       bool got = _hasModifier(resynthesized, modifier);
       bool want = _hasModifier(original, modifier);
       expect(got, want,
           reason: 'Mismatch in $desc.$modifier: got $got, want $want');
     }
-    for (Modifier modifier in Modifier.transientValues) {
-      bool got = rImpl.hasModifier(modifier);
-      bool want = false;
-      expect(got, false,
-          reason: 'Mismatch in $desc.$modifier: got $got, want $want');
-    }
 
     // Validate members.
     if (oImpl is Member) {
@@ -1170,6 +1172,7 @@
       }
       return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer());
     }
+
     Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{
       library.source.uri.toString(): getLinkedSummaryFor(library)
     };
@@ -1187,7 +1190,7 @@
       });
     }
     return new TestSummaryResynthesizer(
-        null, context, unlinkedSummaries, linkedSummaries);
+        null, context, unlinkedSummaries, linkedSummaries, allowMissingFiles);
   }
 
   ElementImpl getActualElement(Element element, String desc) {
@@ -1400,6 +1403,7 @@
       }
       return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer());
     }
+
     Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{
       library.source.uri.toString(): getLinkedSummaryFor(library)
     };
@@ -1417,7 +1421,7 @@
       });
     }
     return new TestSummaryResynthesizer(
-        null, context, unlinkedSummaries, linkedSummaries);
+        null, context, unlinkedSummaries, linkedSummaries, allowMissingFiles);
   }
 
   /**
@@ -3602,6 +3606,34 @@
 ''');
   }
 
+  test_instantiateToBounds_boundRefersToEarlierTypeArgument() {
+    checkLibrary('''
+class C<S extends num, T extends C<S, T>> {}
+C c;
+''');
+  }
+
+  test_instantiateToBounds_boundRefersToItself() {
+    checkLibrary('''
+class C<T extends C<T>> {}
+C c;
+''');
+  }
+
+  test_instantiateToBounds_boundRefersToLaterTypeArgument() {
+    checkLibrary('''
+class C<T extends C<T, U>, U extends num> {}
+C c;
+''');
+  }
+
+  test_instantiateToBounds_simple() {
+    checkLibrary('''
+class C<T extends num> {}
+C c;
+''');
+  }
+
   test_library() {
     checkLibrary('');
   }
@@ -4471,6 +4503,21 @@
     checkLibrary('f() {} g() {}');
   }
 
+  test_unresolved_export() {
+    allowMissingFiles = true;
+    checkLibrary("export 'foo.dart';", allowErrors: true);
+  }
+
+  test_unresolved_import() {
+    allowMissingFiles = true;
+    checkLibrary("import 'foo.dart';", allowErrors: true);
+  }
+
+  test_unresolved_part() {
+    allowMissingFiles = true;
+    checkLibrary("part 'foo.dart';", allowErrors: true);
+  }
+
   test_unused_type_parameter() {
     checkLibrary('''
 class C<T> {
@@ -4583,6 +4630,7 @@
 class TestSummaryResynthesizer extends SummaryResynthesizer {
   final Map<String, UnlinkedUnit> unlinkedSummaries;
   final Map<String, LinkedLibrary> linkedSummaries;
+  final bool allowMissingFiles;
 
   /**
    * The set of uris for which unlinked summaries have been requested using
@@ -4597,7 +4645,7 @@
   final Set<String> linkedSummariesRequested = new Set<String>();
 
   TestSummaryResynthesizer(SummaryResynthesizer parent, AnalysisContext context,
-      this.unlinkedSummaries, this.linkedSummaries)
+      this.unlinkedSummaries, this.linkedSummaries, this.allowMissingFiles)
       : super(parent, context, context.typeProvider, context.sourceFactory,
             context.analysisOptions.strongMode);
 
@@ -4605,7 +4653,7 @@
   LinkedLibrary getLinkedSummary(String uri) {
     linkedSummariesRequested.add(uri);
     LinkedLibrary serializedLibrary = linkedSummaries[uri];
-    if (serializedLibrary == null) {
+    if (serializedLibrary == null && !allowMissingFiles) {
       fail('Unexpectedly tried to get linked summary for $uri');
     }
     return serializedLibrary;
@@ -4615,7 +4663,7 @@
   UnlinkedUnit getUnlinkedSummary(String uri) {
     unlinkedSummariesRequested.add(uri);
     UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
-    if (serializedUnit == null) {
+    if (serializedUnit == null && !allowMissingFiles) {
       fail('Unexpectedly tried to get unlinked summary for $uri');
     }
     return serializedUnit;
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index 60b30a8..b24daf9 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:unittest/unittest.dart';
@@ -204,7 +205,7 @@
 
   @override
   void serializeLibraryText(String text, {bool allowErrors: false}) {
-    Map<String, UnlinkedUnitBuilder> uriToUnit = this.uriToUnit;
+    Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
     LinkerInputs linkerInputs = createLinkerInputs(text);
     linked = link(linkerInputs.linkedLibraries, linkerInputs.getDependency,
         linkerInputs.getUnit, strongMode)[linkerInputs.testDartUri.toString()];
@@ -287,23 +288,9 @@
  */
 abstract class SummaryLinkerTest {
   /**
-   * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
-   * passed to [addNamedSource].
+   * Information about the files to be linked.
    */
-  Map<String, UnlinkedUnitBuilder> uriToUnit = <String, UnlinkedUnitBuilder>{};
-
-  /**
-   * Map from absolute URI to the [LinkedLibrary] for each compilation unit in a
-   * package bundle passed to [addBundle].
-   */
-  Map<String, LinkedLibrary> _dependentLinkedLibraries =
-      <String, LinkedLibrary>{};
-
-  /**
-   * Map from absolute URI to the [UnlinkedUnit] for each compilation unit in a
-   * package bundle passed to [addBundle].
-   */
-  Map<String, UnlinkedUnit> _dependentUnlinkedUnits = <String, UnlinkedUnit>{};
+  _FilesToLink _filesToLink = new _FilesToLink();
 
   /**
    * A test will set this to `true` if it contains `import`, `export`, or
@@ -315,15 +302,8 @@
    * Add the given package bundle as a dependency so that it may be referenced
    * by the files under test.
    */
-  void addBundle(PackageBundle bundle) {
-    for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
-      _dependentLinkedLibraries[bundle.linkedLibraryUris[i]] =
-          bundle.linkedLibraries[i];
-    }
-    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
-      _dependentUnlinkedUnits[bundle.unlinkedUnitUris[i]] =
-          bundle.unlinkedUnits[i];
-    }
+  void addBundle(String path, PackageBundle bundle) {
+    _filesToLink.summaryDataStore.addBundle(path, bundle);
   }
 
   /**
@@ -333,29 +313,27 @@
   Source addNamedSource(String filePath, String contents) {
     CompilationUnit unit = _parseText(contents);
     UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
-    uriToUnit[absUri(filePath)] = unlinkedUnit;
+    _filesToLink.uriToUnit[absUri(filePath)] = unlinkedUnit;
     // Tests using SummaryLinkerTest don't actually need the returned
     // Source, so we can safely return `null`.
     return null;
   }
 
-  LinkerInputs createLinkerInputs(String text, {String path: '/test.dart'}) {
-    Uri testDartUri = Uri.parse(absUri(path));
+  LinkerInputs createLinkerInputs(String text, {String path: '/test.dart', String uri}) {
+    uri ??= absUri(path);
+    Uri testDartUri = Uri.parse(uri);
     CompilationUnit unit = _parseText(text);
     UnlinkedUnitBuilder unlinkedDefiningUnit = serializeAstUnlinked(unit);
-    uriToUnit[testDartUri.toString()] = unlinkedDefiningUnit;
+    _filesToLink.uriToUnit[testDartUri.toString()] = unlinkedDefiningUnit;
     LinkerInputs linkerInputs = new LinkerInputs(
         allowMissingFiles,
-        uriToUnit,
+        _filesToLink.uriToUnit,
         testDartUri,
         unlinkedDefiningUnit,
-        _dependentLinkedLibraries,
-        _dependentUnlinkedUnits);
-    // Reset uriToUnit, _dependentLinkedLibraries, and _dependentUnlinkedUnits
-    // in case the test needs to start a new package bundle.
-    uriToUnit = <String, UnlinkedUnitBuilder>{};
-    _dependentLinkedLibraries = <String, LinkedLibrary>{};
-    _dependentUnlinkedUnits = <String, UnlinkedUnit>{};
+        _filesToLink.summaryDataStore.linkedMap,
+        _filesToLink.summaryDataStore.unlinkedMap);
+    // Reset _filesToLink in case the test needs to start a new package bundle.
+    _filesToLink = new _FilesToLink();
     return linkerInputs;
   }
 
@@ -366,16 +344,17 @@
    * can be created.
    */
   PackageBundleBuilder createPackageBundle(String text,
-      {String path: '/test.dart'}) {
+      {String path: '/test.dart', String uri}) {
     PackageBundleAssembler assembler = new PackageBundleAssembler();
-    LinkerInputs linkerInputs = createLinkerInputs(text, path: path);
+    assembler.recordDependencies(_filesToLink.summaryDataStore);
+    LinkerInputs linkerInputs = createLinkerInputs(text, path: path, uri: uri);
     Map<String, LinkedLibraryBuilder> linkedLibraries = link(
         linkerInputs.linkedLibraries,
         linkerInputs.getDependency,
         linkerInputs.getUnit,
         true);
     linkedLibraries.forEach(assembler.addLinkedLibrary);
-    linkerInputs._uriToUnit.forEach((String uri, UnlinkedUnitBuilder unit) {
+    linkerInputs._uriToUnit.forEach((String uri, UnlinkedUnit unit) {
       // Note: it doesn't matter what we store for the hash because it isn't
       // used in these tests.
       assembler.addUnlinkedUnitWithHash(uri, unit, 'HASH');
@@ -390,6 +369,27 @@
     Token token = scanner.tokenize();
     Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
     parser.parseGenericMethods = true;
-    return parser.parseCompilationUnit(token);
+    CompilationUnit unit = parser.parseCompilationUnit(token);
+    unit.lineInfo = new LineInfo(scanner.lineStarts);
+    return unit;
   }
 }
+
+/**
+ * [_FilesToLink] stores information about a set of files to be linked together.
+ * This information is grouped into a class to allow it to be reset easily when
+ * [SummaryLinkerTest.createLinkerInputs] is called.
+ */
+class _FilesToLink {
+  /**
+   * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
+   * passed to [addNamedSource].
+   */
+  Map<String, UnlinkedUnitBuilder> uriToUnit = <String, UnlinkedUnitBuilder>{};
+
+  /**
+   * Information about summaries to be included in the link process.
+   */
+  SummaryDataStore summaryDataStore =
+      new SummaryDataStore([], recordDependencyInfo: true);
+}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index a3e2695..09af948 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/src/dart/scanner/scanner.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/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -21,16 +20,17 @@
     as public_namespace;
 import 'package:analyzer/src/summary/summarize_elements.dart'
     as summarize_elements;
+import 'package:path/path.dart' show posix;
 import 'package:unittest/unittest.dart';
 
 import '../context/mock_sdk.dart';
 
 /**
- * Convert [path] to a suitably formatted absolute path URI for the current
- * platform.
+ * Convert the given Posix style file [path] to the corresponding absolute URI.
  */
 String absUri(String path) {
-  return FileUtilities2.createFile(path).toURI().toString();
+  String absolutePath = posix.absolute(path);
+  return posix.toUri(absolutePath).toString();
 }
 
 /**
@@ -1309,6 +1309,35 @@
     expect(cls.interfaces, isEmpty);
   }
 
+  test_unresolved_import() {
+    allowMissingFiles = true;
+    serializeLibraryText("import 'foo.dart';", allowErrors: true);
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].uri, 'foo.dart');
+    // Note: imports[1] is the implicit import of dart:core.
+    expect(unlinkedUnits[0].imports[1].isImplicit, true);
+    expect(linked.importDependencies, hasLength(2));
+    checkDependency(
+        linked.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
+  }
+
+  test_unresolved_export() {
+    allowMissingFiles = true;
+    serializeLibraryText("export 'foo.dart';", allowErrors: true);
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].uri, 'foo.dart');
+    expect(linked.exportDependencies, hasLength(1));
+    checkDependency(
+        linked.exportDependencies[0], absUri('/foo.dart'), 'foo.dart');
+  }
+
+  test_unresolved_part() {
+    allowMissingFiles = true;
+    serializeLibraryText("part 'foo.dart';", allowErrors: true);
+    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts[0], 'foo.dart');
+  }
+
   test_class_no_mixins() {
     UnlinkedClass cls = serializeClassText('class C {}');
     expect(cls.mixins, isEmpty);
@@ -2702,8 +2731,11 @@
 
   test_constExpr_pushInt_max() {
     UnlinkedVariable variable = serializeVariableText('const v = 0xFFFFFFFF;');
-    _assertUnlinkedConst(variable.initializer.bodyExpr,
-        operators: [UnlinkedConstOperation.pushInt,], ints: [0xFFFFFFFF]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+    ], ints: [
+      0xFFFFFFFF
+    ]);
   }
 
   test_constExpr_pushInt_negative() {
@@ -2726,15 +2758,26 @@
 
   test_constExpr_pushLongInt_min2() {
     UnlinkedVariable variable = serializeVariableText('const v = 0x100000000;');
-    _assertUnlinkedConst(variable.initializer.bodyExpr,
-        operators: [UnlinkedConstOperation.pushLongInt], ints: [2, 1, 0,]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedConstOperation.pushLongInt
+    ], ints: [
+      2,
+      1,
+      0,
+    ]);
   }
 
   test_constExpr_pushLongInt_min3() {
     UnlinkedVariable variable =
         serializeVariableText('const v = 0x10000000000000000;');
-    _assertUnlinkedConst(variable.initializer.bodyExpr,
-        operators: [UnlinkedConstOperation.pushLongInt], ints: [3, 1, 0, 0,]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+      UnlinkedConstOperation.pushLongInt
+    ], ints: [
+      3,
+      1,
+      0,
+      0,
+    ]);
   }
 
   test_constExpr_pushNull() {
@@ -8659,6 +8702,17 @@
         expectedTargetUnit: 2);
   }
 
+  test_lineStarts() {
+    String text = '''
+int foo;
+class Test {}
+
+int bar;'''
+        .replaceAll('\r\n', '\n');
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].lineStarts, [0, 9, 23, 24]);
+  }
+
   test_linked_reference_reuse() {
     if (skipFullyLinkedData) {
       return;
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index 2f9202b..d669d0e 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -7,13 +7,16 @@
 import 'package:unittest/unittest.dart';
 
 import '../../utils.dart';
+import 'api_signature_test.dart' as api_signature_test;
 import 'flat_buffers_test.dart' as flat_buffers_test;
 import 'in_summary_source_test.dart' as in_summary_source_test;
 import 'incremental_cache_test.dart' as incremental_cache_test;
 import 'index_unit_test.dart' as index_unit_test;
 import 'linker_test.dart' as linker_test;
 import 'name_filter_test.dart' as name_filter_test;
+import 'package_bundle_reader_test.dart' as package_bundle_reader_test;
 import 'prelinker_test.dart' as prelinker_test;
+import 'pub_summary_test.dart' as pub_summary_test;
 import 'resynthesize_ast_test.dart' as resynthesize_ast_test;
 import 'resynthesize_strong_test.dart' as resynthesize_strong_test;
 import 'resynthesize_test.dart' as resynthesize_test;
@@ -26,13 +29,16 @@
 main() {
   initializeTestEnvironment();
   group('summary tests', () {
+    api_signature_test.main();
     flat_buffers_test.main();
     in_summary_source_test.main();
     incremental_cache_test.main();
     index_unit_test.main();
     linker_test.main();
     name_filter_test.main();
+    package_bundle_reader_test.main();
     prelinker_test.main();
+    pub_summary_test.main();
     resynthesize_ast_test.main();
     resynthesize_strong_test.main();
     resynthesize_test.main();
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 25a6bef..c01223c 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -772,11 +772,10 @@
 part of lib;
 '''
     });
-    expect(outputs, hasLength(4));
+    expect(outputs, hasLength(3));
     // simple outputs
     expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty);
     expect(outputs[IS_LAUNCHABLE], isFalse);
-    expect(outputs[REFERENCED_NAMES], isNotNull);
     // LibraryElement output
     expect(libraryElement, isNotNull);
     expect(libraryElement.entryPoint, isNull);
@@ -1557,113 +1556,143 @@
 
   void test_library_cycle_incremental() {
     enableStrongMode();
-    Source lib1Source = newSource(
-        '/my_lib1.dart',
+    Source a = newSource(
+        '/a.dart',
         '''
-library my_lib1;
+library a;
 ''');
-    Source lib2Source = newSource(
-        '/my_lib2.dart',
+    Source b = newSource(
+        '/b.dart',
         '''
-library my_lib2;
-import 'my_lib1.dart';
+library b;
+import 'a.dart';
 ''');
-    Source lib3Source = newSource(
-        '/my_lib3.dart',
+    Source c = newSource(
+        '/c.dart',
         '''
-library my_lib3;
-import 'my_lib2.dart';
+library c;
+import 'b.dart';
 ''');
 
-    computeResult(lib1Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
-    computeResult(lib2Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
-    computeResult(lib3Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
+    _assertLibraryCycle(a, [a]);
+    _assertLibraryCycle(b, [b]);
+    _assertLibraryCycle(c, [c]);
 
-    // create a cycle
+    // Create a cycle.
     context.setContents(
-        lib1Source,
+        a,
         '''
-library my_lib1;
-import 'my_lib3.dart';
+library a;
+import 'c.dart';
 ''');
-    _expectInvalid(lib1Source);
-    _expectInvalid(lib2Source);
-    _expectInvalid(lib3Source);
+    _expectInvalid(a);
+    _expectInvalid(b);
+    _expectInvalid(c);
 
-    computeResult(lib1Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(3));
-    computeResult(lib2Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(3));
-    computeResult(lib3Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(3));
+    _assertLibraryCycle(a, [a, b, c]);
+    _assertLibraryCycle(b, [a, b, c]);
+    _assertLibraryCycle(c, [a, b, c]);
 
-    // break the cycle again
+    // Break the cycle again.
     context.setContents(
-        lib1Source,
+        a,
         '''
-library my_lib1;
+library a;
 ''');
-    _expectInvalid(lib1Source);
-    _expectInvalid(lib2Source);
-    _expectInvalid(lib3Source);
+    _expectInvalid(a);
+    _expectInvalid(b);
+    _expectInvalid(c);
 
-    computeResult(lib1Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
-    computeResult(lib2Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
-    computeResult(lib3Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
+    _assertLibraryCycle(a, [a]);
+    _assertLibraryCycle(b, [b]);
+    _assertLibraryCycle(c, [c]);
   }
 
   void test_library_cycle_incremental_partial() {
     enableStrongMode();
-    Source lib1Source = newSource(
-        '/my_lib1.dart',
-        '''
-library my_lib1;
+    Source a = newSource(
+        '/a.dart',
+        r'''
+library a;
 ''');
-    Source lib2Source = newSource(
-        '/my_lib2.dart',
-        '''
-library my_lib2;
-import 'my_lib1.dart';
+    Source b = newSource(
+        '/b.dart',
+        r'''
+library b;
+import 'a.dart';
 ''');
-    Source lib3Source = newSource(
-        '/my_lib3.dart',
-        '''
-library my_lib3;
-import 'my_lib2.dart';
+    Source c = newSource(
+        '/c.dart',
+        r'''
+library c;
+import 'b.dart';
 ''');
 
-    computeResult(lib1Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
-    computeResult(lib2Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(1));
-    // lib3 is not reachable, so we have not yet computed its library
-    // cycles
+    _assertLibraryCycle(a, [a]);
+    _assertLibraryCycle(b, [b]);
+    // 'c' is not reachable, so we have not yet computed its library cycles.
 
-    // complete the cycle, via lib3
+    // Complete the cycle, via 'c'.
     context.setContents(
-        lib1Source,
-        '''
-library my_lib1;
-import 'my_lib3.dart';
+        a,
+        r'''
+library a;
+import 'c.dart';
 ''');
-    _expectInvalid(lib1Source);
-    _expectInvalid(lib2Source);
-    _expectInvalid(lib3Source);
+    _expectInvalid(a);
+    _expectInvalid(b);
+    _expectInvalid(c);
 
-    // Ensure that invalidation correctly invalidated everything reachable
-    // through lib3
-    computeResult(lib1Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(3));
-    computeResult(lib2Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(3));
-    computeResult(lib3Source, LIBRARY_CYCLE);
-    expect(outputs[LIBRARY_CYCLE], hasLength(3));
+    // Ensure that everything reachable through 'c' was invalidated,
+    // and recomputed to include all three sources.
+    _assertLibraryCycle(a, [a, b, c]);
+    _assertLibraryCycle(b, [a, b, c]);
+    _assertLibraryCycle(c, [a, b, c]);
+  }
+
+  void test_library_cycle_incremental_partial2() {
+    enableStrongMode();
+    Source a = newSource(
+        '/a.dart',
+        r'''
+library a;
+import 'b.dart';
+''');
+    Source b = newSource(
+        '/b.dart',
+        r'''
+library b;
+import 'a.dart';
+''');
+    Source c = newSource(
+        '/c.dart',
+        r'''
+library c;
+import 'b.dart';
+''');
+
+    _assertLibraryCycle(a, [a, b]);
+    _assertLibraryCycle(b, [a, b]);
+    _assertLibraryCycle(c, [c]);
+
+    // Include 'c' into the cycle.
+    context.setContents(
+        a,
+        r'''
+library a;
+import 'b.dart';
+import 'c.dart';
+''');
+    _expectInvalid(a);
+    _expectInvalid(b);
+    _expectInvalid(c);
+
+    // Start processing with 'b', so that when we resolve 'b' directives,
+    // and invalidate library cycles, the 'a' directives are not resolved yet,
+    // so we don't know that the cycle must include 'c'.
+    _assertLibraryCycle(b, [a, b, c]);
+    _assertLibraryCycle(a, [a, b, c]);
+    _assertLibraryCycle(c, [a, b, c]);
   }
 
   void test_library_cycle_linear() {
@@ -1975,6 +2004,12 @@
     expect(dep5, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
   }
 
+  void _assertLibraryCycle(Source source, List<Source> expected) {
+    computeResult(source, LIBRARY_CYCLE);
+    List<LibraryElement> cycle = outputs[LIBRARY_CYCLE] as List<LibraryElement>;
+    expect(cycle.map((e) => e.source), unorderedEquals(expected));
+  }
+
   void _expectInvalid(Source librarySource) {
     CacheEntry entry = context.getCacheEntry(librarySource);
     expect(entry.getState(LIBRARY_CYCLE), CacheState.INVALID);
@@ -2964,6 +2999,26 @@
     InterfaceType intType = context.typeProvider.intType;
     expect(expression.staticType, intType);
   }
+
+  test_staticModeHints_forStaticVariableInference() {
+    context.analysisOptions =
+        new AnalysisOptionsImpl.from(context.analysisOptions)
+          ..strongModeHints = true;
+    Source source = newSource(
+        '/test.dart',
+        r'''
+var V = [42];
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, RESOLVED_UNIT9);
+    expect(outputs[RESOLVED_UNIT9], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+    // An INFERRED_TYPE_LITERAL error should be generated.
+    List<AnalysisError> errors = outputs[
+        STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT] as List<AnalysisError>;
+    expect(errors, hasLength(1));
+    expect(errors[0].errorCode, StrongModeCode.INFERRED_TYPE_LITERAL);
+  }
 }
 
 @reflectiveTest
@@ -3185,7 +3240,7 @@
     _performParseTask(r'''
 part of lib;
 class B {}''');
-    expect(outputs, hasLength(10));
+    expect(outputs, hasLength(11));
     expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
     _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
@@ -3193,9 +3248,10 @@
     expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
     expect(outputs[PARSE_ERRORS], hasLength(0));
     expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[REFERENCED_NAMES], isNotNull);
+    expect(outputs[REFERENCED_SOURCES], hasLength(2));
     expect(outputs[SOURCE_KIND], SourceKind.PART);
     expect(outputs[UNITS], hasLength(1));
-    expect(outputs[REFERENCED_SOURCES], hasLength(2));
   }
 
   test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
@@ -3220,7 +3276,7 @@
 
   test_perform_doesNotExist() {
     _performParseTask(null);
-    expect(outputs, hasLength(10));
+    expect(outputs, hasLength(11));
     expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
     _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
@@ -3228,9 +3284,10 @@
     expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
     expect(outputs[PARSE_ERRORS], hasLength(0));
     expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[REFERENCED_NAMES], isNotNull);
+    expect(outputs[REFERENCED_SOURCES], hasLength(2));
     expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
     expect(outputs[UNITS], hasLength(1));
-    expect(outputs[REFERENCED_SOURCES], hasLength(2));
   }
 
   test_perform_enableAsync_false() {
@@ -3240,7 +3297,7 @@
     _performParseTask(r'''
 import 'dart:async';
 class B {void foo() async {}}''');
-    expect(outputs, hasLength(10));
+    expect(outputs, hasLength(11));
     expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
     _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
@@ -3248,16 +3305,17 @@
     expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
     expect(outputs[PARSE_ERRORS], hasLength(1));
     expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[REFERENCED_NAMES], isNotNull);
+    expect(outputs[REFERENCED_SOURCES], hasLength(3));
     expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
     expect(outputs[UNITS], hasLength(1));
-    expect(outputs[REFERENCED_SOURCES], hasLength(3));
   }
 
   test_perform_enableAsync_true() {
     _performParseTask(r'''
 import 'dart:async';
 class B {void foo() async {}}''');
-    expect(outputs, hasLength(10));
+    expect(outputs, hasLength(11));
     expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
     _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
@@ -3265,9 +3323,10 @@
     expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
     expect(outputs[PARSE_ERRORS], hasLength(0));
     expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[REFERENCED_NAMES], isNotNull);
+    expect(outputs[REFERENCED_SOURCES], hasLength(3));
     expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
     expect(outputs[UNITS], hasLength(1));
-    expect(outputs[REFERENCED_SOURCES], hasLength(3));
   }
 
   test_perform_flushTokenStream() {
@@ -3285,7 +3344,7 @@
 export '${a}lib3.dart';
 part 'part.dart';
 class A {}''');
-    expect(outputs, hasLength(10));
+    expect(outputs, hasLength(11));
     expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
     _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
@@ -3293,9 +3352,10 @@
     expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
     expect(outputs[PARSE_ERRORS], hasLength(2));
     expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[REFERENCED_NAMES], isNotNull);
+    expect(outputs[REFERENCED_SOURCES], hasLength(4));
     expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
     expect(outputs[UNITS], hasLength(2));
-    expect(outputs[REFERENCED_SOURCES], hasLength(4));
   }
 
   test_perform_library() {
@@ -3305,7 +3365,7 @@
 export 'lib3.dart';
 part 'part.dart';
 class A {''');
-    expect(outputs, hasLength(10));
+    expect(outputs, hasLength(11));
     expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(1));
     _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
@@ -3313,9 +3373,10 @@
     expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
     expect(outputs[PARSE_ERRORS], hasLength(1));
     expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[REFERENCED_NAMES], isNotNull);
+    expect(outputs[REFERENCED_SOURCES], hasLength(5));
     expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
     expect(outputs[UNITS], hasLength(2));
-    expect(outputs[REFERENCED_SOURCES], hasLength(5));
   }
 
   test_perform_library_selfReferenceAsPart() {
@@ -3330,7 +3391,7 @@
     _performParseTask(r'''
 part of lib;
 class B {}''');
-    expect(outputs, hasLength(10));
+    expect(outputs, hasLength(11));
     expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
     _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
@@ -3338,9 +3399,10 @@
     expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
     expect(outputs[PARSE_ERRORS], hasLength(0));
     expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[REFERENCED_NAMES], isNotNull);
+    expect(outputs[REFERENCED_SOURCES], hasLength(2));
     expect(outputs[SOURCE_KIND], SourceKind.PART);
     expect(outputs[UNITS], hasLength(1));
-    expect(outputs[REFERENCED_SOURCES], hasLength(2));
   }
 
   void _performParseTask(String content) {
@@ -3502,6 +3564,7 @@
       SimpleIdentifier reference = statement.expression;
       expect(reference.staticElement, isResolved ? isNotNull : isNull);
     }
+
     //
     // The reference to 'A' in 'f1' should not be resolved.
     //
@@ -3689,6 +3752,22 @@
     expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
   }
 
+  test_class_extendedUsedUnnamedConstructorNames() {
+    ReferencedNames info = _computeReferencedNames('''
+class U1 extends A {
+  U1() : super();
+}
+class U2 extends p.B {
+  U2() : super();
+}
+class U3 extends p.C {
+  U3() : super.named();
+}
+''');
+    expect(
+        info.extendedUsedUnnamedConstructorNames, unorderedEquals(['A', 'B']));
+  }
+
   test_class_field() {
     ReferencedNames info = _computeReferencedNames('''
 class U {
@@ -4106,7 +4185,7 @@
 
   ReferencedNames _computeReferencedNames(String code) {
     Source source = newSource('/test.dart', code);
-    computeResult(source, REFERENCED_NAMES, matcher: isBuildLibraryElementTask);
+    computeResult(source, REFERENCED_NAMES, matcher: isParseDartTask);
     return outputs[REFERENCED_NAMES];
   }
 }
@@ -5624,7 +5703,21 @@
     ]);
   }
 
-  test_perform_directiveError() {
+  test_perform_directiveError_generated() {
+    Source source = newSource(
+        '/test.dart',
+        '''
+import 'generated-file.g.dart';
+''');
+    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
+    // validate
+    _fillErrorListener(VERIFY_ERRORS);
+    errorListener.assertErrorsWithCodes(
+        <ErrorCode>[CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED]);
+  }
+
+  test_perform_directiveError_nonGenerated() {
     Source source = newSource(
         '/test.dart',
         '''
@@ -5727,6 +5820,7 @@
           matcher: matcher);
       return outputs[result];
     }
+
     return sources.map(compute).toList();
   }
 
@@ -5737,6 +5831,7 @@
       computeResult(source, result, matcher: matcher);
       return outputs;
     }
+
     return sources.map(compute).toList();
   }
 
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 da36f87..79f3071 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -106,6 +106,21 @@
     expect_unknownSourceQueue([source4, source1]);
   }
 
+  /**
+   * When we perform limited invalidation, we keep [SOURCE_KIND] valid. So, we
+   * don't need to put such sources into [DartWorkManager.unknownSourceQueue],
+   * and remove from [DartWorkManager.librarySourceQueue].
+   */
+  void test_applyChange_change_hasSourceKind() {
+    entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
+    manager.librarySourceQueue.addAll([source1, source2]);
+    manager.unknownSourceQueue.addAll([source3]);
+    // change source1
+    manager.applyChange([], [source1, source2], []);
+    expect_librarySourceQueue([source1]);
+    expect_unknownSourceQueue([source2, source3]);
+  }
+
   void test_applyChange_remove() {
     manager.librarySourceQueue.addAll([source1, source3]);
     manager.unknownSourceQueue.addAll([source4]);
@@ -314,6 +329,7 @@
   }
 
   void test_getLibrariesContainingPart() {
+    when(context.aboutToComputeResult(anyObject, anyObject)).thenReturn(false);
     Source part1 = new TestSource('part1.dart');
     Source part2 = new TestSource('part2.dart');
     Source part3 = new TestSource('part3.dart');
@@ -331,6 +347,33 @@
     expect(manager.getLibrariesContainingPart(part3), isEmpty);
   }
 
+  void test_getLibrariesContainingPart_askResultProvider() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    // configure AnalysisContext mock
+    when(context.aboutToComputeResult(anyObject, CONTAINING_LIBRARIES))
+        .thenInvoke((CacheEntry entry, ResultDescriptor result) {
+      if (entry.target == part1) {
+        entry.setValue(result, <Source>[library1, library2], []);
+        return true;
+      }
+      if (entry.target == part2) {
+        entry.setValue(result, <Source>[library2], []);
+        return true;
+      }
+      return false;
+    });
+    // getLibrariesContainingPart
+    expect(manager.getLibrariesContainingPart(part1),
+        unorderedEquals([library1, library2]));
+    expect(
+        manager.getLibrariesContainingPart(part2), unorderedEquals([library2]));
+    expect(manager.getLibrariesContainingPart(part3), isEmpty);
+  }
+
   void test_getLibrariesContainingPart_inSDK() {
     Source part = new _SourceMock('part.dart');
     when(part.isInSystemLibrary).thenReturn(true);
@@ -749,6 +792,11 @@
     expect(manager.libraryPartsMap, isEmpty);
   }
 
+  void test_unitIncrementallyResolved() {
+    manager.unitIncrementallyResolved(source1, source2);
+    expect_librarySourceQueue([source1]);
+  }
+
   CacheEntry _getOrCreateEntry(Source source, [bool explicit = true]) {
     CacheEntry entry = cache.get(source);
     if (entry == null) {
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 8d495af..56f174e 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -41,6 +42,38 @@
     return newCode.substring(node.offset, node.end);
   }
 
+  test_classDelta_annotation_add() {
+    var helper = new _ClassDeltaHelper('A');
+    _buildOldUnit(r'''
+class A {}
+''');
+    helper.initOld(oldUnit);
+    expect(helper.element.metadata, isEmpty);
+    _buildNewUnit(r'''
+@deprecated
+class A {}
+''');
+    helper.initNew(newUnit, unitDelta);
+    expect(helper.delta.hasAnnotationChanges, isTrue);
+    expect(helper.element.metadata, hasLength(1));
+  }
+
+  test_classDelta_annotation_remove() {
+    var helper = new _ClassDeltaHelper('A');
+    _buildOldUnit(r'''
+@deprecated
+class A {}
+''');
+    helper.initOld(oldUnit);
+    expect(helper.element.metadata, hasLength(1));
+    _buildNewUnit(r'''
+class A {}
+''');
+    helper.initNew(newUnit, unitDelta);
+    expect(helper.delta.hasAnnotationChanges, isTrue);
+    expect(helper.element.metadata, isEmpty);
+  }
+
   test_classDelta_constructor_0to1() {
     var helper = new _ClassDeltaHelper('A');
     _buildOldUnit(r'''
@@ -66,6 +99,7 @@
     ClassElement classElement = helper.element;
     expect(classElement.constructors, unorderedEquals([newConstructorElement]));
     // verify delta
+    expect(helper.delta.hasUnnamedConstructorChange, isTrue);
     expect(helper.delta.addedConstructors,
         unorderedEquals([newConstructorElement]));
     expect(helper.delta.removedConstructors,
@@ -99,7 +133,9 @@
       expect(constructors[0].isSynthetic, isTrue);
     }
     // verify delta
-    expect(helper.delta.addedConstructors, unorderedEquals([]));
+    expect(helper.delta.hasUnnamedConstructorChange, isTrue);
+    expect(helper.delta.addedConstructors,
+        unorderedEquals([classElement.unnamedConstructor]));
     expect(helper.delta.removedConstructors, unorderedEquals([oldElementA]));
     expect(helper.delta.addedAccessors, isEmpty);
     expect(helper.delta.removedAccessors, isEmpty);
@@ -107,6 +143,66 @@
     expect(helper.delta.removedMethods, isEmpty);
   }
 
+  test_classDelta_constructor_1to1_unnamed_addParameter() {
+    var helper = new _ClassDeltaHelper('A');
+    _buildOldUnit(r'''
+class A {
+  A();
+}
+''');
+    helper.initOld(oldUnit);
+    ConstructorElement oldConstructor = helper.element.unnamedConstructor;
+    _buildNewUnit(r'''
+class A {
+  A(int p);
+}
+''');
+    helper.initNew(newUnit, unitDelta);
+    ClassElement classElement = helper.element;
+    ConstructorElement newConstructor = classElement.unnamedConstructor;
+    expect(classElement.constructors, [newConstructor]);
+    // verify delta
+    expect(helper.delta.hasUnnamedConstructorChange, isTrue);
+    expect(helper.delta.addedConstructors, unorderedEquals([newConstructor]));
+    expect(helper.delta.removedConstructors, unorderedEquals([oldConstructor]));
+    expect(helper.delta.addedAccessors, isEmpty);
+    expect(helper.delta.removedAccessors, isEmpty);
+    expect(helper.delta.addedMethods, isEmpty);
+    expect(helper.delta.removedMethods, isEmpty);
+  }
+
+  test_classDelta_constructor_1to1_unnamed_removeParameter() {
+    var helper = new _ClassDeltaHelper('A');
+    _buildOldUnit(r'''
+class A {
+  final int a;
+  final int b;
+  A(this.a, this.b);
+}
+''');
+    helper.initOld(oldUnit);
+    ConstructorElement oldConstructor = helper.element.unnamedConstructor;
+    _buildNewUnit(r'''
+class A {
+  final int a;
+  final int b;
+  A(this.a);
+}
+''');
+    helper.initNew(newUnit, unitDelta);
+    ClassElement classElement = helper.element;
+    ConstructorElement newConstructor = classElement.unnamedConstructor;
+    expect(classElement.constructors, [newConstructor]);
+    // verify delta
+    expect(helper.delta.hasUnnamedConstructorChange, isTrue);
+    expect(helper.delta.addedConstructors, unorderedEquals([newConstructor]));
+    expect(helper.delta.removedConstructors, unorderedEquals([oldConstructor]));
+    expect(helper.delta.addedAccessors, isEmpty);
+    expect(helper.delta.removedAccessors, isEmpty);
+    expect(helper.delta.addedMethods, isEmpty);
+    expect(helper.delta.removedMethods, isEmpty);
+  }
+
   test_classDelta_constructor_1to2() {
     var helper = new _ClassDeltaHelper('A');
     _buildOldUnit(r'''
@@ -161,6 +257,7 @@
 }
 ''');
     helper.initNew(newUnit, unitDelta);
+    expect(helper.delta.hasUnnamedConstructorChange, isFalse);
     // nodes
     ClassMember nodeB = helper.newMembers[0];
     expect(nodeB, same(helper.oldMembers[1]));
@@ -373,6 +470,7 @@
     FieldElement newFieldElementB = newFieldsB[0].name.staticElement;
     expect(newFieldElementB.name, 'bbb');
     // verify delta
+    expect(helper.delta.hasAnnotationChanges, isFalse);
     expect(helper.delta.addedConstructors, isEmpty);
     expect(helper.delta.removedConstructors, isEmpty);
     expect(helper.delta.addedAccessors,
@@ -415,6 +513,56 @@
     expect(helper.delta.removedMethods, isEmpty);
   }
 
+  test_classDelta_field_syntheticAndNot_renameNonSynthetic() {
+    var helper = new _ClassDeltaHelper('A');
+    _buildOldUnit(r'''
+class A {
+  int foo;
+  int get foo => 1;
+}
+''');
+    helper.initOld(oldUnit);
+    FieldDeclaration oldFieldDeclNode = helper.oldMembers[0];
+    VariableDeclaration oldFieldNode = oldFieldDeclNode.fields.variables.single;
+    FieldElement oldFieldElement = oldFieldNode.name.staticElement;
+    _buildNewUnit(r'''
+class A {
+  int _foo;
+  int get foo => 1;
+}
+''');
+    helper.initNew(newUnit, unitDelta);
+    // nodes
+    FieldDeclaration newFieldDeclNode = helper.newMembers[0];
+    VariableDeclaration newFieldNode = newFieldDeclNode.fields.variables.single;
+    MethodDeclaration getterNode = helper.newMembers[1];
+    expect(getterNode, same(helper.oldMembers[1]));
+    // elements
+    FieldElement newFieldElement = newFieldNode.name.staticElement;
+    PropertyAccessorElement getterElement = getterNode.element;
+    expect(newFieldElement.name, '_foo');
+    expect(
+        helper.element.fields,
+        unorderedMatches(
+            [same(newFieldElement), same(getterElement.variable)]));
+    expect(
+        helper.element.accessors,
+        unorderedMatches([
+          same(newFieldElement.getter),
+          same(newFieldElement.setter),
+          same(getterElement)
+        ]));
+    // verify delta
+    expect(helper.delta.addedConstructors, isEmpty);
+    expect(helper.delta.removedConstructors, isEmpty);
+    expect(helper.delta.addedAccessors,
+        unorderedEquals([newFieldElement.getter, newFieldElement.setter]));
+    expect(helper.delta.removedAccessors,
+        [oldFieldElement.getter, oldFieldElement.setter]);
+    expect(helper.delta.addedMethods, isEmpty);
+    expect(helper.delta.removedMethods, isEmpty);
+  }
+
   test_classDelta_getter_add() {
     var helper = new _ClassDeltaHelper('A');
     _buildOldUnit(r'''
@@ -685,6 +833,26 @@
     expect(helper.delta.removedMethods, unorderedEquals([oldElementA]));
   }
 
+  test_classDelta_null_abstractKeyword_add() {
+    _verifyNoClassDeltaForTheLast(
+        r'''
+class A {}
+''',
+        r'''
+abstract class A {}
+''');
+  }
+
+  test_classDelta_null_abstractKeyword_remove() {
+    _verifyNoClassDeltaForTheLast(
+        r'''
+abstract class A {}
+''',
+        r'''
+class A {}
+''');
+  }
+
   test_classDelta_null_extendsClause_add() {
     _verifyNoClassDeltaForTheLast(
         r'''
@@ -980,6 +1148,27 @@
     }
   }
 
+  test_directives_library_updateOffset() {
+    _buildOldUnit(r'''
+#!/bin/sh
+library my_lib;
+class A {}
+''');
+    LibraryDirective libraryDirective = oldUnit.directives.single;
+    // Set the LibraryElement and check that its nameOffset is correct.
+    libraryDirective.element =
+        new LibraryElementImpl.forNode(context, libraryDirective.name);
+    expect(libraryDirective.element.nameOffset, libraryDirective.name.offset);
+    // Update and check again that the nameOffset is correct.
+    _buildNewUnit(r'''
+#!/bin/sh
+
+library my_lib;
+class A {}
+''');
+    expect(libraryDirective.element.nameOffset, libraryDirective.name.offset);
+  }
+
   test_directives_remove() {
     _buildOldUnit(r'''
 library test;
@@ -1052,6 +1241,35 @@
     expect(unitDelta.hasDirectiveChange, isFalse);
   }
 
+  test_directives_sameImportPrefix_sameOrder() {
+    _buildOldUnit(r'''
+import 'test1.dart' as m;
+import 'test2.dart' as m;
+''');
+    List<Directive> oldDirectives = oldUnit.directives.toList();
+    ImportDirective import1 = oldDirectives[0];
+    ImportDirective import2 = oldDirectives[1];
+    ImportElementImpl importElement1 = new ImportElementImpl(import1.offset);
+    ImportElementImpl importElement2 = new ImportElementImpl(import2.offset);
+    PrefixElement prefixElement = new PrefixElementImpl.forNode(import1.prefix);
+    importElement1.prefix = prefixElement;
+    importElement2.prefix = prefixElement;
+    import1.element = importElement1;
+    import2.element = importElement2;
+    import1.prefix.staticElement = prefixElement;
+    import2.prefix.staticElement = prefixElement;
+    _buildNewUnit(r'''
+import 'test1.dart' as m;
+import 'test2.dart' as m;
+class A {}
+''');
+    int expectedPrefixOffset = 23;
+    expect(import1.prefix.staticElement.nameOffset, expectedPrefixOffset);
+    expect(import2.prefix.staticElement.nameOffset, expectedPrefixOffset);
+    expect(importElement1.prefix.nameOffset, expectedPrefixOffset);
+    expect(importElement2.prefix.nameOffset, expectedPrefixOffset);
+  }
+
   test_directives_sameOrder_insertSpaces() {
     _buildOldUnit(r'''
 library test;
@@ -1366,6 +1584,14 @@
     expect(elementB, isNotNull);
     expect(elementA.name, 'A');
     expect(elementB.name, 'B');
+    expect(elementA.fields.map((f) => f.name),
+        unorderedEquals(['index', 'values', 'A1', 'A2']));
+    expect(elementA.accessors.map((a) => a.name),
+        unorderedEquals(['index', 'values', 'A1', 'A2']));
+    expect(elementB.fields.map((f) => f.name),
+        unorderedEquals(['index', 'values', 'B1', 'B2']));
+    expect(elementB.accessors.map((a) => a.name),
+        unorderedEquals(['index', 'values', 'B1', 'B2']));
     // unit.types
     expect(unitElement.enums, unorderedEquals([elementA, elementB]));
     // verify delta
@@ -1565,6 +1791,18 @@
 ''');
   }
 
+  test_update_annotation_add() {
+    _buildOldUnit(r'''
+const myAnnotation = const Object();
+foo() {}
+''');
+    _buildNewUnit(r'''
+const myAnnotation = const Object();
+@myAnnotation
+foo() {}
+''');
+  }
+
   test_update_beforeClassWithDelta_nameOffset() {
     _buildOldUnit(r'''
 class A {}
@@ -1634,6 +1872,39 @@
 ''');
   }
 
+  test_update_commentReference_multipleCommentTokens() {
+    _buildOldUnit(r'''
+class A {
+  /// C1 [C2]
+  /// C3 [C4]
+  /// C5 [C6]
+  void m() {}
+}
+''');
+    _buildNewUnit(r'''
+class A {
+  int field;
+
+  /// C1 [C2]
+  /// C3 [C4]
+  /// C5 [C6]
+  void m() {}
+}
+''');
+  }
+
+  test_update_commentReference_new() {
+    _buildOldUnit(r'''
+/// Comment reference with new [new A].
+class A {}
+''');
+    _buildNewUnit(r'''
+class B {}
+/// Comment reference with new [new A].
+class A {}
+''');
+  }
+
   test_update_commentReference_notClosed() {
     _buildOldUnit(r'''
 /// [c)
@@ -1646,6 +1917,48 @@
 ''');
   }
 
+  test_update_element_implicitAccessors_classField() {
+    _buildOldUnit(r'''
+// 0
+class A {
+  var F = 0;
+}
+''');
+    _materializeLazyElements(unitElement);
+    _buildNewUnit(r'''
+// 012
+class A {
+  var F = 0;
+}
+''');
+  }
+
+  test_update_element_implicitAccessors_topLevelVariable() {
+    _buildOldUnit(r'''
+var A = 0;
+var B = 1;
+''');
+    _materializeLazyElements(unitElement);
+    _buildNewUnit(r'''
+var B = 1;
+''');
+  }
+
+  test_update_parseError_diffPlus_removeOne() {
+    _buildOldUnit(r'''
+class C {
+  + /// comment
+  + String field;
+}
+''');
+    _buildNewUnit(r'''
+class C {
+  + /// comment
+   String field;
+}
+''');
+  }
+
   test_update_rewrittenConstructorName() {
     _buildOldUnit(r'''
 class A {
@@ -1715,6 +2028,10 @@
     expect(unitElement, isNotNull);
   }
 
+  void _materializeLazyElements(CompilationUnitElement unitElement) {
+    unitElement.accept(new _MaterializeLazyElementsVisitor());
+  }
+
   void _verifyNoClassDeltaForTheLast(String oldCode, String newCode) {
     _buildOldUnit(oldCode);
     List<CompilationUnitMember> oldMembers = oldUnit.declarations.toList();
@@ -1733,6 +2050,8 @@
  * Compares tokens and ASTs, and built elements of declared identifiers.
  */
 class _BuiltElementsValidator extends AstComparator {
+  final Set visited = new Set.identity();
+
   @override
   bool isEqualNodes(AstNode expected, AstNode actual) {
     // Elements of nodes which are children of ClassDeclaration(s) must be
@@ -1761,6 +2080,16 @@
           actual.getAncestor((n) => n is ClassDeclaration);
       expect(element.enclosingElement, same(classNode.element));
     }
+    // ElementAnnotationImpl must use the enclosing CompilationUnitElement.
+    if (actual is Annotation) {
+      AstNode parent = actual.parent;
+      if (parent is Declaration) {
+        ElementAnnotationImpl actualElement = actual.elementAnnotation;
+        CompilationUnitElement enclosingUnitElement =
+            parent.element.getAncestor((a) => a is CompilationUnitElement);
+        expect(actualElement.compilationUnit, same(enclosingUnitElement));
+      }
+    }
     // Identifiers like 'a.b' in 'new a.b()' might be rewritten if resolver
     // sees that 'a' is actually a class name, so 'b' is a constructor name.
     //
@@ -1784,13 +2113,17 @@
         expect(actual.inDeclarationContext(), isTrue);
         Element expectedElement = expected.staticElement;
         Element actualElement = actual.staticElement;
-        _verifyElement(expectedElement, actualElement, 'staticElement');
+        _verifyElement(
+            expectedElement, actualElement, 'staticElement ($expectedElement)');
       }
     }
     return true;
   }
 
   void _verifyElement(Element expected, Element actual, String desc) {
+    if (!visited.add(expected)) {
+      return;
+    }
     if (expected == null && actual == null) {
       return;
     }
@@ -1801,6 +2134,7 @@
     // Compare properties.
     _verifyEqual('$desc name', expected.name, actual.name);
     _verifyEqual('$desc nameOffset', expected.nameOffset, actual.nameOffset);
+    _verifyEqual('$desc isSynthetic', expected.isSynthetic, actual.isSynthetic);
     if (expected is ElementImpl && actual is ElementImpl) {
       _verifyEqual('$desc codeOffset', expected.codeOffset, actual.codeOffset);
       _verifyEqual('$desc codeLength', expected.codeLength, actual.codeLength);
@@ -1820,6 +2154,29 @@
             '${expectedEnclosing.name}.$desc');
       }
     }
+    // Compare implicit accessors.
+    if (expected is PropertyInducingElement &&
+        actual is PropertyInducingElement &&
+        !expected.isSynthetic) {
+      _verifyElement(expected.getter, actual.getter, '$desc getter');
+      _verifyElement(expected.setter, actual.setter, '$desc setter');
+    }
+    // Compare implicit properties.
+    if (expected is PropertyAccessorElement &&
+        actual is PropertyAccessorElement &&
+        !expected.isSynthetic) {
+      _verifyElement(expected.variable, actual.variable, '$desc variable');
+    }
+    // Compare parameters.
+    if (expected is ExecutableElement && actual is ExecutableElement) {
+      List<ParameterElement> actualParameters = actual.parameters;
+      List<ParameterElement> expectedParameters = expected.parameters;
+      expect(actualParameters, hasLength(expectedParameters.length));
+      for (int i = 0; i < expectedParameters.length; i++) {
+        _verifyElement(
+            expectedParameters[i], actualParameters[i], '$desc parameters[$i]');
+      }
+    }
   }
 
   void _verifyEqual(String name, expected, actual) {
@@ -1833,13 +2190,15 @@
   final String name;
 
   ClassElementDelta delta;
-  ClassElement element;
+  ClassElementImpl element;
+  int oldVersion;
   List<ClassMember> oldMembers;
   List<ClassMember> newMembers;
 
   _ClassDeltaHelper(this.name);
 
   void initNew(CompilationUnit newUnit, CompilationUnitElementDelta unitDelta) {
+    expect(element.version, isNot(oldVersion));
     ClassDeclaration newClass = _findClassNode(newUnit, name);
     expect(newClass, isNotNull);
     newMembers = newClass.members.toList();
@@ -1851,6 +2210,7 @@
     ClassDeclaration oldClass = _findClassNode(oldUnit, name);
     expect(oldClass, isNotNull);
     element = oldClass.element;
+    oldVersion = element.version;
     oldMembers = oldClass.members.toList();
   }
 
@@ -1858,3 +2218,11 @@
       unit.declarations.singleWhere((unitMember) =>
           unitMember is ClassDeclaration && unitMember.name.name == name);
 }
+
+class _MaterializeLazyElementsVisitor extends GeneralizingElementVisitor {
+  @override
+  visitExecutableElement(ExecutableElement element) {
+    element.parameters;
+    super.visitExecutableElement(element);
+  }
+}
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index f65c3fb..a0cbca8 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/analyzer.dart';
 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/source.dart';
 import 'package:analyzer/src/task/options.dart';
@@ -128,6 +129,18 @@
     expect(unusedLocal.severity, ErrorSeverity.ERROR);
   }
 
+  test_configure_excludes() {
+    configureContext('''
+analyzer:
+  exclude:
+    - foo/bar.dart
+    - 'test/**'
+''');
+
+    List<String> excludes = context.getConfigurationData(CONTEXT_EXCLUDES);
+    expect(excludes, unorderedEquals(['foo/bar.dart', 'test/**']));
+  }
+
   test_configure_strong_mode() {
     configureContext('''
 analyzer:
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 0b1a115..d2a0bd5 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -113,6 +113,15 @@
 ''');
   }
 
+  void test_callMethodOnFunctions() {
+    checkFile(r'''
+void f(int x) => print(x);
+main() {
+  f.call(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
+}
+    ''');
+  }
+
   void test_castsInConditions() {
     checkFile('''
 main() {
@@ -264,7 +273,7 @@
 test() {
   int x = 0;
   x += 5;
-  /*error:STATIC_TYPE_ERROR*/x += 3.14;
+  /*error:STATIC_TYPE_ERROR*/x += /*error:INVALID_ASSIGNMENT*/3.14;
 
   double y = 0.0;
   y += 5;
@@ -690,14 +699,14 @@
 
 foo1() async => x;
 Future foo2() async => x;
-Future<int> foo3() async => /*info:DYNAMIC_CAST*/x;
+Future<int> foo3() async => x;
 Future<int> foo4() async => new Future<int>.value(/*info:DYNAMIC_CAST*/x);
 Future<int> foo5() async =>
     /*error:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
 
 bar1() async { return x; }
 Future bar2() async { return x; }
-Future<int> bar3() async { return /*info:DYNAMIC_CAST*/x; }
+Future<int> bar3() async { return x; }
 Future<int> bar4() async { return new Future<int>.value(/*info:DYNAMIC_CAST*/x); }
 Future<int> bar5() async {
   return /*error:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
@@ -713,7 +722,7 @@
   String d = /*error:INVALID_ASSIGNMENT*/await z;
 }
 
-Future<bool> get issue_264 async {
+Future<bool> get issue_ddc_264 async {
   await 42;
   if (new Random().nextBool()) {
     return true;
@@ -721,6 +730,11 @@
     return new Future<bool>.value(false);
   }
 }
+
+
+Future<String> issue_sdk_26404() async {
+  return (1 > 0) ? new Future<String>.value('hello') : "world";
+}
 ''');
   }
 
@@ -793,13 +807,13 @@
     Left f;
     f = /*error:STATIC_TYPE_ERROR*/top;
     f = left;
-    f = /*error:STATIC_TYPE_ERROR*/right;
+    f = /*error:INVALID_ASSIGNMENT*/right;
     f = bot;
   }
   {
     Right f;
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:INVALID_ASSIGNMENT*/left;
     f = right;
     f = bot;
   }
@@ -839,13 +853,13 @@
     Left f;
     f = /*warning:DOWN_CAST_COMPOSITE*/top;
     f = left;
-    f = /*warning:DOWN_CAST_COMPOSITE*/right;
+    f = /*error:INVALID_ASSIGNMENT*/right;
     f = bot;
   }
   {
     Right f;
     f = /*warning:DOWN_CAST_COMPOSITE*/top;
-    f = /*warning:DOWN_CAST_COMPOSITE*/left;
+    f = /*error:INVALID_ASSIGNMENT*/left;
     f = right;
     f = bot;
   }
@@ -926,14 +940,14 @@
     f = topTop;
     f = aa;
     f = aTop;
-    f = /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA;
+    f = /*error:INVALID_ASSIGNMENT*/botA;
     f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
     apply/*<ATop>*/(
         topA,
         topTop,
         aa,
         aTop,
-        /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                     );
     apply/*<ATop>*/(
@@ -941,31 +955,31 @@
         (dynamic x) => (x as Object),
         (A x) => x,
         (A x) => null,
-        /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                     );
   }
   {
     BotA f;
     f = topA;
-    f = /*error:STATIC_TYPE_ERROR*/topTop;
+    f = /*error:INVALID_ASSIGNMENT*/topTop;
     f = aa;
-    f = /*error:STATIC_TYPE_ERROR*/aTop;
+    f = /*error:INVALID_ASSIGNMENT*/aTop;
     f = botA;
     f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
     apply/*<BotA>*/(
         topA,
-        /*error:STATIC_TYPE_ERROR*/topTop,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
         aa,
-        /*error:STATIC_TYPE_ERROR*/aTop,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/aTop,
         botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                     );
     apply/*<BotA>*/(
         (dynamic x) => new A(),
-        /*error:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(dynamic x) => (x as Object),
         (A x) => x,
-        /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object),
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(A x) => (/*info:UNNECESSARY_CAST*/x as Object),
         botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                     );
@@ -973,14 +987,14 @@
   {
     AA f;
     f = topA;
-    f = /*error:STATIC_TYPE_ERROR*/topTop;
+    f = /*error:INVALID_ASSIGNMENT*/topTop;
     f = aa;
     f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
     f = /*warning:DOWN_CAST_COMPOSITE*/botA;
     f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
     apply/*<AA>*/(
         topA,
-        /*error:STATIC_TYPE_ERROR*/topTop,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
         aa,
         /*error:STATIC_TYPE_ERROR*/aTop, // known function
         /*warning:DOWN_CAST_COMPOSITE*/botA,
@@ -988,9 +1002,9 @@
                   );
     apply/*<AA>*/(
         (dynamic x) => new A(),
-        /*error:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(dynamic x) => (x as Object),
         (A x) => x,
-        /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+        /*error:STATIC_TYPE_ERROR*/(A x) => (/*info:UNNECESSARY_CAST*/x as Object), // known function
         /*warning:DOWN_CAST_COMPOSITE*/botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                   );
@@ -999,24 +1013,24 @@
     TopTop f;
     f = topA;
     f = topTop;
-    f = /*error:STATIC_TYPE_ERROR*/aa;
+    f = /*error:INVALID_ASSIGNMENT*/aa;
     f = /*error:STATIC_TYPE_ERROR*/aTop; // known function
-    f = /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA;
+    f = /*error:INVALID_ASSIGNMENT*/botA;
     f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
     apply/*<TopTop>*/(
         topA,
         topTop,
-        /*error:STATIC_TYPE_ERROR*/aa,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/aa,
         /*error:STATIC_TYPE_ERROR*/aTop, // known function
-        /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                       );
     apply/*<TopTop>*/(
         (dynamic x) => new A(),
         (dynamic x) => (x as Object),
-        /*error:STATIC_TYPE_ERROR*/(A x) => x,
-        /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
-        /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/botA,
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(A x) => x,
+        /*error:STATIC_TYPE_ERROR*/(A x) => (/*info:UNNECESSARY_CAST*/x as Object), // known function
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                       );
   }
@@ -1040,7 +1054,7 @@
         (dynamic x) => new A(),
         /*error:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object), // known function
         /*error:STATIC_TYPE_ERROR*/(A x) => x, // known function
-        /*error:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+        /*error:STATIC_TYPE_ERROR*/(A x) => (/*info:UNNECESSARY_CAST*/x as Object), // known function
         /*warning:DOWN_CAST_COMPOSITE*/botA,
         /*warning:DOWN_CAST_COMPOSITE*/botTop
                     );
@@ -1127,16 +1141,16 @@
     f = bot;
   }
   {
-    Function2<B, B> f;
+    Function2<B, B> f; // left
     f = /*error:STATIC_TYPE_ERROR*/top;
     f = left;
-    f = /*error:STATIC_TYPE_ERROR*/right;
+    f = /*error:INVALID_ASSIGNMENT*/right;
     f = bot;
   }
   {
-    Function2<A, A> f;
+    Function2<A, A> f; // right
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:INVALID_ASSIGNMENT*/left;
     f = right;
     f = bot;
   }
@@ -1172,12 +1186,12 @@
 
     left = /*warning:DOWN_CAST_COMPOSITE*/top;
     left = left;
-    left = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
+    left = /*error:INVALID_ASSIGNMENT*/right;
     left = bot;
 
-    right = /*warning:DOWN_CAST_COMPOSITE*/top;
-    right = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
-    right = right;
+    right = /*info:INVALID_ASSIGNMENT,warning:DOWN_CAST_COMPOSITE*/top;
+    right = /*error:INVALID_ASSIGNMENT*/left;
+    right = /*info:INVALID_ASSIGNMENT*/right;
     right = bot;
 
     bot = /*warning:DOWN_CAST_COMPOSITE*/top;
@@ -1217,13 +1231,13 @@
     Function2<AToB, AToB> f; // Left
     f = /*error:STATIC_TYPE_ERROR*/top;
     f = left;
-    f = /*error:STATIC_TYPE_ERROR*/right;
+    f = /*error:INVALID_ASSIGNMENT*/right;
     f = bot;
   }
   {
     Function2<BToA, BToA> f; // Right
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:INVALID_ASSIGNMENT*/left;
     f = right;
     f = bot;
   }
@@ -1232,7 +1246,7 @@
     f = bot;
     f = /*error:STATIC_TYPE_ERROR*/left;
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:STATIC_TYPE_ERROR*/right;
   }
 }
 ''');
@@ -1266,13 +1280,13 @@
     Function2<AToB, AToB> f; // Left
     f = /*error:STATIC_TYPE_ERROR*/top;
     f = left;
-    f = /*error:STATIC_TYPE_ERROR*/right;
+    f = /*error:INVALID_ASSIGNMENT*/right;
     f = bot;
   }
   {
     Function2<BToA, BToA> f; // Right
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:INVALID_ASSIGNMENT*/left;
     f = right;
     f = bot;
   }
@@ -1281,7 +1295,7 @@
     f = bot;
     f = /*error:STATIC_TYPE_ERROR*/left;
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:STATIC_TYPE_ERROR*/right;
   }
 }
 ''');
@@ -1315,13 +1329,13 @@
     Function2<AToB, AToB> f; // Left
     f = /*error:STATIC_TYPE_ERROR*/top;
     f = left;
-    f = /*error:STATIC_TYPE_ERROR*/right;
+    f = /*error:INVALID_ASSIGNMENT*/right;
     f = bot;
   }
   {
     Function2<BToA, BToA> f; // Right
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:INVALID_ASSIGNMENT*/left;
     f = right;
     f = bot;
   }
@@ -1330,7 +1344,7 @@
     f = bot;
     f = /*error:STATIC_TYPE_ERROR*/left;
     f = /*error:STATIC_TYPE_ERROR*/top;
-    f = /*error:STATIC_TYPE_ERROR*/left;
+    f = /*error:STATIC_TYPE_ERROR*/right;
   }
 }
 ''');
@@ -1358,12 +1372,12 @@
     left = /*warning:DOWN_CAST_COMPOSITE*/top;
     left = left;
     left =
-        /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/right;
+        /*error:INVALID_ASSIGNMENT*/right;
     left = bot;
 
     right = /*warning:DOWN_CAST_COMPOSITE*/top;
     right =
-        /*warning:DOWN_CAST_COMPOSITE should be error:STATIC_TYPE_ERROR*/left;
+        /*error:INVALID_ASSIGNMENT*/left;
     right = right;
     right = bot;
 
@@ -1403,13 +1417,13 @@
     Function2<B, B> f;
     f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
     f = c.left;
-    f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
+    f = /*error:INVALID_ASSIGNMENT*/c.right;
     f = c.bot;
   }
   {
     Function2<A, A> f;
     f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
-    f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
+    f = /*error:INVALID_ASSIGNMENT*/c.left;
     f = c.right;
     f = c.bot;
   }
@@ -1461,13 +1475,13 @@
     Left f;
     f = /*warning:DOWN_CAST_COMPOSITE*/top;
     f = left;
-    f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
+    f = /*error:INVALID_ASSIGNMENT*/right;
     f = bot;
   }
   {
     Right f;
     f = /*warning:DOWN_CAST_COMPOSITE*/top;
-    f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
+    f = /*error:INVALID_ASSIGNMENT*/left;
     f = right;
     f = bot;
   }
@@ -1618,18 +1632,18 @@
      f = new A();
      f = /*error:INVALID_ASSIGNMENT*/new B();
      f = i2i;
-     f = /*error:STATIC_TYPE_ERROR*/n2n;
-     f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
-     f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
+     f = /*error:INVALID_ASSIGNMENT*/n2n;
+     f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/i2i as Object;
+     f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/n2n as Function;
    }
    {
      N2N f;
      f = /*error:INVALID_ASSIGNMENT*/new A();
      f = new B();
-     f = /*error:STATIC_TYPE_ERROR*/i2i;
+     f = /*error:INVALID_ASSIGNMENT*/i2i;
      f = n2n;
-     f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
-     f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
+     f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/i2i as Object;
+     f = /*info:UNNECESSARY_CAST,warning:DOWN_CAST_COMPOSITE*/n2n as Function;
    }
    {
      A f;
@@ -1637,8 +1651,8 @@
      f = /*error:INVALID_ASSIGNMENT*/new B();
      f = /*error:INVALID_ASSIGNMENT*/i2i;
      f = /*error:INVALID_ASSIGNMENT*/n2n;
-     f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
-     f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
+     f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
+     f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/n2n as Function;
    }
    {
      B f;
@@ -1646,8 +1660,8 @@
      f = new B();
      f = /*error:INVALID_ASSIGNMENT*/i2i;
      f = /*error:INVALID_ASSIGNMENT*/n2n;
-     f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
-     f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
+     f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
+     f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/n2n as Function;
    }
    {
      Function f;
@@ -1655,8 +1669,8 @@
      f = new B();
      f = i2i;
      f = n2n;
-     f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
-     f = (n2n as Function);
+     f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
+     f = /*info:UNNECESSARY_CAST*/n2n as Function;
    }
 }
 ''');
@@ -1688,13 +1702,13 @@
     Function2<B, B> f;
     f = /*error:STATIC_TYPE_ERROR*/C.top;
     f = C.left;
-    f = /*error:STATIC_TYPE_ERROR*/C.right;
+    f = /*error:INVALID_ASSIGNMENT*/C.right;
     f = C.bot;
   }
   {
     Function2<A, A> f;
     f = /*error:STATIC_TYPE_ERROR*/C.top;
-    f = /*error:STATIC_TYPE_ERROR*/C.left;
+    f = /*error:INVALID_ASSIGNMENT*/C.left;
     f = C.right;
     f = C.bot;
   }
@@ -1748,7 +1762,7 @@
     checkFile('''
 typedef num Num2Num(num x);
 void main() {
-  Num2Num g = /*info:INFERRED_TYPE_CLOSURE,error:STATIC_TYPE_ERROR*/(int x) { return x; };
+  Num2Num g = /*info:INFERRED_TYPE_CLOSURE,error:INVALID_ASSIGNMENT*/(int x) { return x; };
   print(g(42));
 }
 ''');
@@ -1917,6 +1931,23 @@
     check(implicitCasts: false);
   }
 
+  void test_implicitCasts_genericMethods() {
+    addFile('var x = <String>[].map((x) => "");');
+    check(implicitCasts: false);
+  }
+
+  void test_implicitCasts_numericOps() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26912
+    addFile(r'''
+void f() {
+  int x = 0;
+  int y = 0;
+  x += y;
+}
+    ''');
+    check(implicitCasts: false);
+  }
+
   void test_implicitDynamic_field() {
     addFile(r'''
 class C {
@@ -1957,7 +1988,7 @@
 
   /*error:IMPLICIT_DYNAMIC_INVOKE*/(/*<T>*/(/*=T*/ t) => t)(d);
   (/*<T>*/(/*=T*/ t) => t)(42);
-  (/*<T>*/() => null as dynamic/*=T*/)/*<int>*/();
+  (/*<T>*/() => /*info:UNNECESSARY_CAST*/null as dynamic/*=T*/)/*<int>*/();
 }
     ''');
     check(implicitDynamic: false);
@@ -2142,6 +2173,58 @@
     check(implicitDynamic: false);
   }
 
+  void test_constantGenericTypeArg_infer() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26141
+    checkFile('''
+abstract class Equality<Q> {}
+abstract class EqualityBase<R> implements Equality<R> {
+  final C<R> c = /*info:INFERRED_TYPE_ALLOCATION*/const C();
+  const EqualityBase();
+}
+class DefaultEquality<S> extends EqualityBase<S> {
+  const DefaultEquality();
+}
+class SetEquality<T> implements Equality<T> {
+  final Equality<T> field = const DefaultEquality();
+  const SetEquality([Equality<T> inner = const DefaultEquality()]);
+}
+class C<Q> {
+  final List<Q> list = /*info:INFERRED_TYPE_LITERAL*/const [];
+  final Map<Q, Iterable<Q>> m =  /*info:INFERRED_TYPE_LITERAL*/const {};
+  const C();
+}
+main() {
+  const SetEquality<String>();
+}
+    ''');
+  }
+
+  void test_constantGenericTypeArg_explict() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26141
+    checkFile('''
+abstract class Equality<R> {}
+abstract class EqualityBase<R> implements Equality<R> {
+  final C<R> c = const C<R>();
+  const EqualityBase();
+}
+class DefaultEquality<S> extends EqualityBase<S> {
+  const DefaultEquality();
+}
+class SetEquality<T> implements Equality<T> {
+  final Equality<T> field = const DefaultEquality<T>();
+  const SetEquality([Equality<T> inner = const DefaultEquality<T>()]);
+}
+class C<Q> {
+  final List<Q> list = const <Q>[];
+  final Map<Q, Iterable<Q>> m =  const <Q, Iterable<Q>>{};
+  const C();
+}
+main() {
+  const SetEquality<String>();
+}
+    ''');
+  }
+
   void test_invalidOverrides_baseClassOverrideToChildInterface() {
     checkFile('''
 class A {}
@@ -2472,19 +2555,19 @@
 
   // For as, the validity of checks is deferred to runtime.
   Function f;
-  f = foo as I2I;
-  f = foo as D2I;
-  f = foo as I2D;
-  f = foo as D2D;
+  f = /*info:UNNECESSARY_CAST*/foo as I2I;
+  f = /*info:UNNECESSARY_CAST*/foo as D2I;
+  f = /*info:UNNECESSARY_CAST*/foo as I2D;
+  f = /*info:UNNECESSARY_CAST*/foo as D2D;
 
-  f = bar as II2I;
-  f = bar as DI2I;
-  f = bar as ID2I;
-  f = bar as II2D;
-  f = bar as DD2I;
-  f = bar as DI2D;
-  f = bar as ID2D;
-  f = bar as DD2D;
+  f = /*info:UNNECESSARY_CAST*/bar as II2I;
+  f = /*info:UNNECESSARY_CAST*/bar as DI2I;
+  f = /*info:UNNECESSARY_CAST*/bar as ID2I;
+  f = /*info:UNNECESSARY_CAST*/bar as II2D;
+  f = /*info:UNNECESSARY_CAST*/bar as DD2I;
+  f = /*info:UNNECESSARY_CAST*/bar as DI2D;
+  f = /*info:UNNECESSARY_CAST*/bar as ID2D;
+  f = /*info:UNNECESSARY_CAST*/bar as DD2D;
 }
 ''');
   }
@@ -2538,6 +2621,20 @@
 ''');
   }
 
+  void test_leastUpperBounds_fuzzyArrows() {
+    checkFile(r'''
+typedef String TakesA<T>(T item);
+
+void main() {
+  TakesA<int> f;
+  TakesA<dynamic> g;
+  TakesA<String> h;
+  g = h;
+  f = /*warning:DOWN_CAST_COMPOSITE*/f ?? g;
+}
+''');
+  }
+
   void test_loadLibrary() {
     addFile('''library lib1;''', name: '/lib1.dart');
     checkFile(r'''
@@ -2599,6 +2696,18 @@
 ''');
   }
 
+  void test_methodTearoffStrictArrow() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26393
+    checkFile(r'''
+class A {
+  void foo(dynamic x) {}
+  void test(void f(int x)) {
+    test(foo);
+  }
+}
+    ''');
+  }
+
   void test_mixinOverrideOfGrandInterface_interfaceOfAbstractSuperclass() {
     checkFile('''
 class A {}
@@ -2877,6 +2986,46 @@
 ''');
   }
 
+  void test_nullCoalescingStrictArrow() {
+    checkFile(r'''
+bool _alwaysTrue(x) => true;
+typedef bool TakesA<T>(T t);
+class C<T> {
+  TakesA<T> g;
+  C(TakesA<T> f)
+    : g = f ?? _alwaysTrue;
+  C.a() : g = _alwaysTrue;
+}
+    ''');
+  }
+
+  void test_optionalParams() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26155
+    checkFile(r'''
+void takesF(void f(int x)) {
+  takesF(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/([x]) { bool z = x.isEven; });
+  takesF(/*info:INFERRED_TYPE_CLOSURE*/(y) { bool z = y.isEven; });
+}
+    ''');
+  }
+
+  void test_overrideNarrowsType() {
+    addFile(r'''
+class A {}
+class B extends A {}
+
+abstract class C {
+  m(A a);
+  n(B b);
+}
+abstract class D extends C {
+  /*error:INVALID_METHOD_OVERRIDE*/m(/*error:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B b);
+  n(A a);
+}
+    ''');
+    check(implicitCasts: false);
+  }
+
   void test_privateOverride() {
     addFile(
         '''
@@ -2914,6 +3063,44 @@
 ''');
   }
 
+  void test_proxy() {
+    checkFile(r'''
+@proxy class C {}
+@proxy class D {
+  var f;
+  m() => null;
+  operator -() => null;
+  operator +(int other) => null;
+  operator [](int index) => null;
+  call() => null;
+}
+@proxy class F implements Function { noSuchMethod(i) => 42; }
+
+
+m() {
+  D d = new D();
+  d.m();
+  d.m;
+  d.f;
+  -d;
+  d + 7;
+  d[7];
+  d();
+
+  C c = new C();
+  /*info:DYNAMIC_INVOKE*/c.m();
+  /*info:DYNAMIC_INVOKE*/c.m;
+  /*info:DYNAMIC_INVOKE*/-c;
+  /*info:DYNAMIC_INVOKE*/c + 7;
+  /*info:DYNAMIC_INVOKE*/c[7];
+  /*error:INVOCATION_OF_NON_FUNCTION,info:DYNAMIC_INVOKE*/c();
+
+  F f = new F();
+  /*info:DYNAMIC_INVOKE*/f();
+}
+    ''');
+  }
+
   void test_redirectingConstructor() {
     checkFile('''
 class A {
@@ -2966,7 +3153,7 @@
     lOfOs = new L<Object>(); // Reset type propagation.
   }
   {
-    lOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
+    lOfAs = /*error:INVALID_ASSIGNMENT*/mOfDs;
     lOfAs = /*error:INVALID_ASSIGNMENT*/mOfOs;
     lOfAs = mOfAs;
     lOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
@@ -2980,7 +3167,7 @@
     mOfDs = mOfAs;
     mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
     mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
-    mOfDs = /*warning:DOWN_CAST_COMPOSITE*/lOfAs;
+    mOfDs = /*error:INVALID_ASSIGNMENT*/lOfAs;
     mOfDs = new M(); // Reset type propagation.
   }
   {
@@ -3248,7 +3435,9 @@
                 bool isValidKey(potentialKey)])
     : _comparator = /*warning:DOWN_CAST_COMPOSITE*/(compare == null) ? Comparable.compare : compare,
       _validKey = (isValidKey != null) ? isValidKey : ((v) => true) {
-    _Predicate<Object> v = (isValidKey != null)
+
+    // NOTE: this is a down cast because isValidKey has fuzzy arrow type.
+    _Predicate<Object> v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
         ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
 
     v = (isValidKey != null)
@@ -3332,6 +3521,29 @@
 ''');
   }
 
+  void test_typePromotionFromTypeParameter() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26965
+    checkFile(r'''
+void f/*<T>*/(/*=T*/ object) {
+  if (object is String) print(object.substring(1));
+}
+void g/*<T extends num>*/(/*=T*/ object) {
+  if (object is int) print(object.isEven);
+  if (object is String) print(/*info:DYNAMIC_INVOKE*/object.substring(1));
+}
+class Clonable<T> {}
+class SubClonable<T> extends Clonable<T> {
+  T m(T t) => t;
+}
+void h/*<T extends Clonable<T>>*/(/*=T*/ object) {
+  if (/*info:NON_GROUND_TYPE_CHECK_INFO*/object is SubClonable/*<T>*/) {
+    // Note we need to cast back to T, because promotion lost that type info.
+    print(object.m(object as dynamic/*=T*/));
+  }
+}
+''');
+  }
+
   void test_typeSubtyping_assigningClass() {
     checkFile('''
 class A {}
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 0446efa..5405293 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -62,7 +62,7 @@
     var mainUnit = checkFile(r'''
 import 'dart:async';
 import 'dart:math' show Random;
-var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+var f = /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() async {
   if (new Random().nextBool()) {
     return new Future<int>.value(1);
   } else {
@@ -101,7 +101,7 @@
     var mainUnit = checkFile(r'''
 import 'dart:async';
 import 'dart:math' show Random;
-var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+var f = /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() async {
   if (new Random().nextBool()) {
     return 1;
   } else {
@@ -140,7 +140,7 @@
     var mainUnit = checkFile(r'''
 import 'dart:async';
 import 'dart:math' show Random;
-var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+var f = /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() async {
   if (new Random().nextBool()) {
     return new Future<int>.value(1);
   } else {
@@ -175,7 +175,7 @@
   void test_blockBodiedLambdas_asyncStar_topLevel() {
     var mainUnit = checkFile(r'''
   import 'dart:async';
-var f = /*info:INFERRED_TYPE_CLOSURE*/() async* {
+var f = /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() async* {
   yield 1;
   Stream<double> s;
   yield* s;
@@ -198,7 +198,7 @@
   void test_blockBodiedLambdas_basic_topLevel() {
     checkFile(r'''
 List<int> o;
-var y = o.map(/*info:INFERRED_TYPE_CLOSURE*/(x) { return x + 1; });
+var y = o.map(/*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/(x) { return x + 1; });
 Iterable<int> z = y;
 ''');
   }
@@ -223,7 +223,7 @@
   void test_blockBodiedLambdas_doesNotInferBottom_async_topLevel() {
     var mainUnit = checkFile(r'''
 import 'dart:async';
-var f = () async { return null; };
+var f = /*warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() async { return null; };
 ''');
     var f = mainUnit.topLevelVariables[0];
     expect(f.type.toString(), '() → Future<dynamic>');
@@ -249,7 +249,7 @@
   void test_blockBodiedLambdas_doesNotInferBottom_asyncStar_topLevel() {
     var mainUnit = checkFile(r'''
 import 'dart:async';
-var f = () async* { yield null; };
+var f = /*warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() async* { yield null; };
 ''');
     var f = mainUnit.topLevelVariables[0];
     expect(f.type.toString(), '() → Stream<dynamic>');
@@ -304,7 +304,7 @@
 
   void test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel() {
     var mainUnit = checkFile(r'''
-var f = () sync* { yield null; };
+var f = /*warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() sync* { yield null; };
 ''');
     var f = mainUnit.topLevelVariables[0];
     expect(f.type.toString(), '() → Iterable<dynamic>');
@@ -357,7 +357,7 @@
     checkFile(r'''
 import 'dart:math' show Random;
 List<num> o;
-var y = o.map(/*info:INFERRED_TYPE_CLOSURE*/(x) {
+var y = o.map(/*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/(x) {
   if (new Random().nextBool()) {
     return x.toInt() + 1;
   } else {
@@ -388,7 +388,7 @@
   void test_blockBodiedLambdas_nestedLambdas_topLevel() {
     // Original feature request: https://github.com/dart-lang/sdk/issues/25487
     var mainUnit = checkFile(r'''
-var f = /*info:INFERRED_TYPE_CLOSURE*/() {
+var f = /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
   return /*info:INFERRED_TYPE_CLOSURE*/(int x) { return 2.0 * x; };
 };
 ''');
@@ -440,7 +440,7 @@
 
   void test_blockBodiedLambdas_syncStar_topLevel() {
     var mainUnit = checkFile(r'''
-var f = /*info:INFERRED_TYPE_CLOSURE*/() sync* {
+var f = /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() sync* {
   yield 1;
   yield* /*info:INFERRED_TYPE_LITERAL*/[3, 4.0];
 };
@@ -588,6 +588,209 @@
 ''');
   }
 
+  void test_constructors_downwardsWithConstraint() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26431
+    checkFile(r'''
+class Foo<T extends Iterable> {}
+void main() {
+  Foo<List> foo = /*info:INFERRED_TYPE_ALLOCATION*/new Foo();
+}
+    ''');
+  }
+
+  void test_constructors_inferenceFBounded() {
+    // Regression for https://github.com/dart-lang/sdk/issues/26990
+    var unit = checkFile('''
+class Clonable<T> {}
+
+class Pair<T extends Clonable<T>, U extends Clonable<U>> {
+  T t;
+  U u;
+  Pair(this.t, this.u);
+  Pair._();
+  Pair<U, T> get reversed => /*info:INFERRED_TYPE_ALLOCATION*/new Pair(u, t);
+}
+final x = /*info:INFERRED_TYPE_ALLOCATION*/new Pair._();
+    ''');
+    var x = unit.topLevelVariables[0];
+    expect(x.type.toString(), 'Pair<Clonable<dynamic>, Clonable<dynamic>>');
+  }
+
+  void test_constructors_inferFromArguments() {
+    var unit = checkFile('''
+class C<T> {
+  T t;
+  C(this.t);
+}
+
+var x = /*info:INFERRED_TYPE_ALLOCATION*/new C(42);
+
+// Don't infer if we had a context type.
+num y;
+C<int> c_int = /*info:INFERRED_TYPE_ALLOCATION*/new C(/*info:DOWN_CAST_IMPLICIT*/y);
+
+// These hints are not reported because we resolve with a null error listener.
+C<num> c_num = /*pass should be info:INFERRED_TYPE_ALLOCATION*/new C(123);
+C<num> c_num2 = (/*pass should be info:INFERRED_TYPE_ALLOCATION*/new C(456))
+    ..t = /*error:INVALID_ASSIGNMENT*/1.0;
+
+// Down't infer from explicit dynamic.
+var c_dynamic = new C<dynamic>(42);
+
+main() {
+  x.t = /*error:INVALID_ASSIGNMENT*/'hello';
+}
+''');
+    var vars = unit.topLevelVariables;
+    expect(vars[0].type.toString(), 'C<int>');
+    expect(vars.firstWhere((e) => e.name == 'c_int').type.toString(), 'C<int>');
+    expect(vars.firstWhere((e) => e.name == 'c_num').type.toString(), 'C<num>');
+    expect(vars.firstWhere((e) => e.name == 'c_dynamic').type.toString(),
+        'C<dynamic>');
+  }
+
+  void test_constructors_inferFromArguments_const() {
+    var unit = checkFile('''
+class C<T> {
+  final T t;
+  const C(this.t);
+}
+
+var x = /*info:INFERRED_TYPE_ALLOCATION*/const C(42);
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+  }
+
+  void test_constructors_inferFromArguments_constWithUpperBound() {
+    // Regression for https://github.com/dart-lang/sdk/issues/26993
+    checkFile('''
+class C<T extends num> {
+  final T x;
+  const C(this.x);
+}
+class D<T extends num> {
+  const D();
+}
+void f() {
+  const c = /*info:INFERRED_TYPE_ALLOCATION*/const C(0);
+  const D<int> d = /*info:INFERRED_TYPE_ALLOCATION*/const D();
+}
+    ''');
+  }
+
+  void test_constructors_inferFromArguments_factory() {
+    var unit = checkFile('''
+class C<T> {
+  T t;
+
+  C._();
+
+  factory C(T t) {
+    var x = new C<T>._();
+    x.t = t;
+    return x;
+  }
+}
+
+var x = /*info:INFERRED_TYPE_ALLOCATION*/new C(42);
+
+main() {
+  x.t = /*error:INVALID_ASSIGNMENT*/'hello';
+}
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+  }
+
+  void test_constructors_inferFromArguments_named() {
+    var unit = checkFile('''
+class C<T> {
+  T t;
+  C.named(List<T> t);
+}
+
+var x = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(<int>[]);
+
+main() {
+  x.t = /*error:INVALID_ASSIGNMENT*/'hello';
+}
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+  }
+
+  void test_constructors_inferFromArguments_namedFactory() {
+    var unit = checkFile('''
+class C<T> {
+  T t;
+  C();
+
+  factory C.named(T t) {
+    var x = new C<T>();
+    x.t = t;
+    return x;
+  }
+}
+
+var x = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(42);
+
+main() {
+  x.t = /*error:INVALID_ASSIGNMENT*/'hello';
+}
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+  }
+
+  void test_constructors_inferFromArguments_redirecting() {
+    var unit = checkFile('''
+class C<T> {
+  T t;
+  C(this.t);
+  C.named(List<T> t) : this(t[0]);
+}
+
+var x = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(<int>[42]);
+
+main() {
+  x.t = /*error:INVALID_ASSIGNMENT*/'hello';
+}
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+  }
+
+  void test_constructors_inferFromArguments_redirectingFactory() {
+    var unit = checkFile('''
+abstract class C<T> {
+  T get t;
+  void set t(T x);
+
+  factory C(T t) = CImpl<T>;
+}
+
+class CImpl<T> implements C<T> {
+  T t;
+  CImpl(this.t);
+}
+
+var x = /*info:INFERRED_TYPE_ALLOCATION*/new C(42);
+
+main() {
+  x.t = /*error:INVALID_ASSIGNMENT*/'hello';
+}
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+  }
+
+  void test_constructors_reverseTypeParameters() {
+    // Regression for https://github.com/dart-lang/sdk/issues/26990
+    checkFile('''
+class Pair<T, U> {
+  T t;
+  U u;
+  Pair(this.t, this.u);
+  Pair<U, T> get reversed => /*info:INFERRED_TYPE_ALLOCATION*/new Pair(u, t);
+}
+    ''');
+  }
+
   void test_doNotInferOverriddenFieldsThatExplicitlySayDynamic_infer() {
     checkFile('''
 class A {
@@ -697,7 +900,7 @@
 import 'dart:async';
 Future test() async {
   dynamic d;
-  List<int> l0 = /*warning:DOWN_CAST_COMPOSITE should be pass*/await /*pass should be info:INFERRED_TYPE_LITERAL*/[d];
+  List<int> l0 = await /*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d];
   List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d]);
 }
 ''');
@@ -1034,8 +1237,8 @@
     A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/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 = /*error:STATIC_TYPE_ERROR*/new B<String, dynamic>("hello", 3);
-    A<int, String> a5 = /*error:STATIC_TYPE_ERROR*/new B<dynamic, dynamic>.named("hello", 3);
+    A<int, String> a4 = /*error:INVALID_ASSIGNMENT*/new B<String, dynamic>("hello", 3);
+    A<int, String> a5 = /*error:INVALID_ASSIGNMENT*/new B<dynamic, dynamic>.named("hello", 3);
   }
   {
     A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new B(
@@ -1050,8 +1253,8 @@
     A<int, int> a1 = /*info:INFERRED_TYPE_ALLOCATION*/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 = /*error:STATIC_TYPE_ERROR*/new C<dynamic>(3);
-    A<int, int> a5 = /*error:STATIC_TYPE_ERROR*/new C<dynamic>.named(3);
+    A<int, int> a4 = /*error:INVALID_ASSIGNMENT*/new C<dynamic>(3);
+    A<int, int> a5 = /*error:INVALID_ASSIGNMENT*/new C<dynamic>.named(3);
   }
   {
     A<int, int> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new C(
@@ -1064,8 +1267,8 @@
     A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/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 = /*error:STATIC_TYPE_ERROR*/new D<num, dynamic>("hello");
-    A<int, String> a5 = /*error:STATIC_TYPE_ERROR*/new D<dynamic, dynamic>.named("hello");
+    A<int, String> a4 = /*error:INVALID_ASSIGNMENT*/new D<num, dynamic>("hello");
+    A<int, String> a5 = /*error:INVALID_ASSIGNMENT*/new D<dynamic, dynamic>.named("hello");
   }
   {
     A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new D(
@@ -1073,8 +1276,8 @@
     A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new D.named(
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
   }
-  { // Currently we only allow variable constraints.  Test that we reject.
-    A<C<int>, String> a0 = /*error:STATIC_TYPE_ERROR*/new E("hello");
+  {
+    A<C<int>, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new E("hello");
   }
   { // Check named and optional arguments
     A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello",
@@ -1317,11 +1520,202 @@
   }
 
   void test_futureThen() {
-    checkFile('''
+    String build({String declared, String downwards, String upwards}) => '''
 import 'dart:async';
-Future f;
-Future<int> t1 = f.then((_) => new Future<int>.value(42));
-''');
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
+  MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+  $declared f;
+  $downwards<int> t1 = f.then((_) async => await new $upwards<int>.value(3));
+  $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async {
+     return await new $upwards<int>.value(3);});
+  $downwards<int> t3 = f.then((_) async => 3);
+  $downwards<int> t4 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async {
+    return 3;});
+  $downwards<int> t5 = f.then((_) => new $upwards<int>.value(3));
+  $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) {return new $upwards<int>.value(3);});
+  $downwards<int> t7 = f.then((_) async => new $upwards<int>.value(3));
+  $downwards<int> t8 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async {
+    return new $upwards<int>.value(3);});
+}
+''';
+
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future"));
+    checkFile(build(
+        declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+  }
+
+  void test_futureThen_conditional() {
+    String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
+  MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+  $declared<bool> f;
+  $downwards<int> t1 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+      (x) async => x ? 2 : await new $upwards<int>.value(3));
+  $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) async { // TODO(leafp): Why the duplicate here?
+    return await x ? 2 : new $upwards<int>.value(3);});
+  $downwards<int> t5 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+      (x) => x ? 2 : new $upwards<int>.value(3));
+  $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/
+      (x) {return x ? 2 : new $upwards<int>.value(3);});
+}
+''';
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future"));
+    checkFile(build(
+        declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+  }
+
+  void test_futureThen_downwardsMethodTarget() {
+    // Not working yet, see: https://github.com/dart-lang/sdk/issues/27114
+    checkFile(r'''
+import 'dart:async';
+main() {
+  Future<int> f;
+  Future<List<int>> b = /*info:ASSIGNMENT_CAST should be pass*/f
+      .then(/*info:INFERRED_TYPE_CLOSURE*/(x) => [])
+      .whenComplete(/*pass should be info:INFERRED_TYPE_LITERAL*/() {});
+  b = f.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/[]);
+}
+    ''');
+  }
+
+  void test_futureThen_upwards() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/27088.
+    String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
+  MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
+}
+
+void main() {
+  var f = foo().then((_) => 2.3);
+  $downwards<int> f2 = /*error:INVALID_ASSIGNMENT*/f;
+
+  // The unnecessary cast is to illustrate that we inferred <double> for
+  // the generic type args, even though we had a return type context.
+  $downwards<num> f3 = /*info:UNNECESSARY_CAST*/foo().then(
+      (_) => 2.3) as $upwards<double>;
+}
+$declared foo() => new $declared<int>.value(1);
+    ''';
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(build(
+        declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+  }
+
+  void test_futureThen_upwardsFromBlock() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/27113.
+    checkFile(r'''
+import 'dart:async';
+main() {
+  Future<int> base;
+  var f = base.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) { return x == 0; });
+  var g = base.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => x == 0);
+  Future<bool> b = f;
+  b = g;
+}
+    ''');
+  }
+
+  void test_futureUnion_asyncConditional() {
+    String build({String declared, String downwards, String upwards}) => '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value(T x) {}
+  dynamic noSuchMethod(invocation);
+  MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
+}
+
+$downwards<int> g1(bool x) async {
+  return x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42); }
+$downwards<int> g2(bool x) async =>
+  x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42);
+$downwards<int> g3(bool x) async {
+  var y = x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42);
+  return y;
+}
+    ''';
+    checkFile(build(downwards: "Future", upwards: "Future"));
+    checkFile(build(downwards: "Future", upwards: "MyFuture"));
+  }
+
+  void test_futureUnion_downwards() {
+    String build({String declared, String downwards, String upwards}) {
+      // TODO(leafp): The use of matchTypes in visitInstanceCreationExpression
+      // in the resolver visitor isn't powerful enough to catch this for the
+      // subclass.  See the TODO there.
+      var allocInfo =
+          (upwards == "Future") ? "/*info:INFERRED_TYPE_ALLOCATION*/" : "";
+      return '''
+import 'dart:async';
+class MyFuture<T> implements Future<T> {
+  MyFuture() {}
+  MyFuture.value([T x]) {}
+  dynamic noSuchMethod(invocation);
+  MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null;
+}
+
+$declared f;
+// Instantiates Future<int>
+$downwards<int> t1 = f.then((_) =>
+   ${allocInfo}new $upwards.value(
+     /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'));
+
+// Instantiates List<int>
+$downwards<List<int>> t2 = f.then((_) => /*info:INFERRED_TYPE_LITERAL*/[3]);
+$downwards<List<int>> g2() async { return /*info:INFERRED_TYPE_LITERAL*/[3]; }
+$downwards<List<int>> g3() async {
+  return /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(
+      /*info:INFERRED_TYPE_LITERAL*/[3]); }
+''';
+    }
+
+    ;
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "Future"));
+    checkFile(
+        build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
   }
 
   void test_genericMethods_basicDownwardInference() {
@@ -1444,7 +1838,7 @@
   /*=T*/ g/*<T>*/(/*=T*/ x) => x;
 }
 main() {
-  int y = /*info:DYNAMIC_CAST*/(new D() as C).m(42);
+  int y = /*info:DYNAMIC_CAST*/(/*info:UNNECESSARY_CAST*/new D() as C).m(42);
   print(y);
 }
   ''');
@@ -1512,11 +1906,11 @@
 takeIIO(math.max);
 takeDDO(math.max);
 
-takeOOI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeIDI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeDID(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeOON(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeOOO(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOOI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeIDI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeDID(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOON(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+takeOOO(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
 
 // Also test SimpleIdentifier
 takeIII(min);
@@ -1529,11 +1923,11 @@
 takeIIO(min);
 takeDDO(min);
 
-takeOOI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeIDI(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeDID(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeOON(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeOOO(/*error:STATIC_TYPE_ERROR,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOOI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeIDI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeDID(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOON(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+takeOOO(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
 
 // Also PropertyAccess
 takeIII(new C().m);
@@ -1555,14 +1949,14 @@
 //
 // That's legal because we're loosening parameter types.
 //
-takeOON(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-takeOOO(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeOON(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeOOO(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
 
 // Note: this is a warning because a downcast of a method tear-off could work
 // in "normal" Dart, due to bivariance.
-takeOOI(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-takeIDI(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-takeDID(/*warning:DOWN_CAST_COMPOSITE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeOOI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeIDI(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+takeDID(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
 }
 
 void takeIII(int fn(int a, int b)) {}
@@ -2077,8 +2471,8 @@
                         // conected component.
 var g = -3;
 var h = new A() + 3;
-var i = /*error:UNDEFINED_OPERATOR*/- new A();
-var j = null as B;
+var i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/- new A();
+var j = /*info:UNNECESSARY_CAST*/null as B;
 
 test1() {
   a = /*error:INVALID_ASSIGNMENT*/"hi";
@@ -2315,6 +2709,42 @@
   ''');
   }
 
+  void test_inferLocalFunctionReturnType() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26414
+    var unit = checkFile(r'''
+main() {
+  f0() => 42;
+  f1() async => 42;
+
+  f2 /*info:INFERRED_TYPE_CLOSURE*/() { return 42; }
+  f3 /*info:INFERRED_TYPE_CLOSURE*/() async { return 42; }
+  f4 /*info:INFERRED_TYPE_CLOSURE*/() sync* { yield 42; }
+  f5 /*info:INFERRED_TYPE_CLOSURE*/() async* { yield 42; }
+
+  num f6() => 42;
+
+  f7() => f7();
+  f8() => /*error:REFERENCED_BEFORE_DECLARATION*/f9();
+  f9() => f5();
+}
+''');
+    var fns = unit.functions[0].functions;
+    expect(fns[0].type.toString(), '() → int');
+    expect(fns[1].type.toString(), '() → Future<int>');
+
+    expect(fns[2].type.toString(), '() → int');
+    expect(fns[3].type.toString(), '() → Future<int>');
+    expect(fns[4].type.toString(), '() → Iterable<int>');
+    expect(fns[5].type.toString(), '() → Stream<int>');
+
+    expect(fns[6].type.toString(), '() → num');
+
+    // Recursive cases: these infer in declaration order.
+    expect(fns[7].type.toString(), '() → dynamic');
+    expect(fns[8].type.toString(), '() → dynamic');
+    expect(fns[9].type.toString(), '() → Stream<int>');
+  }
+
   void test_inferred_nonstatic_field_depends_on_static_field_complex() {
     var mainUnit = checkFile('''
 class C {
@@ -2697,6 +3127,18 @@
     expect(f.type.toString(), '(bool) → int');
   }
 
+  void test_inferReturnOfStatementLambda() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26139
+    checkFile(r'''
+List<String> strings() {
+  var stuff = [].expand(/*info:INFERRED_TYPE_CLOSURE*/(i) {
+    return <String>[];
+  });
+  return stuff.toList();
+}
+    ''');
+  }
+
   void test_inferStaticsTransitively() {
     addFile(
         '''
@@ -3423,6 +3865,23 @@
 ''');
   }
 
+  void test_nullCoalescingOperator() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26552
+    checkFile(r'''
+List<int> x;
+var y = x ?? /*info:INFERRED_TYPE_LITERAL*/[];
+List<int> z = y;
+    ''');
+    // Don't do anything if we already have a context type.
+    var unit = checkFile(r'''
+List<int> x;
+List<num> y = x ?? /*info:INFERRED_TYPE_LITERAL*/[];
+    ''');
+
+    expect(unit.topLevelVariables[1].initializer.returnType.toString(),
+        'List<num>');
+  }
+
   void test_nullLiteralShouldNotInferAsBottom() {
     // Regression test for https://github.com/dart-lang/dev_compiler/issues/47
     checkFile(r'''
@@ -3711,6 +4170,297 @@
     // No type should be inferred for a because there is a circular reference
     // between a and c.
   }
+
+  void test_unsafeBlockClosureInference_closureCall() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/26962
+    var mainUnit = checkFile('''
+var v = ((x) => 1.0)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'double');
+  }
+
+  void test_unsafeBlockClosureInference_constructorCall_explicitDynamicParam() {
+    var mainUnit = checkFile('''
+class C<T> {
+  C(T x());
+}
+var v = new C<dynamic>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'C<dynamic>');
+  }
+
+  void test_unsafeBlockClosureInference_constructorCall_explicitTypeParam() {
+    var mainUnit = checkFile('''
+class C<T> {
+  C(T x());
+}
+var v = new C<int>(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'C<int>');
+  }
+
+  void test_unsafeBlockClosureInference_constructorCall_implicitTypeParam() {
+    var mainUnit = checkFile('''
+class C<T> {
+  C(T x());
+}
+var v = /*info:INFERRED_TYPE_ALLOCATION*/new C(
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'C<int>');
+  }
+
+  void test_unsafeBlockClosureInference_constructorCall_noTypeParam() {
+    var mainUnit = checkFile('''
+class C {
+  C(x());
+}
+var v = new C(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'C');
+  }
+
+  void test_unsafeBlockClosureInference_functionCall_explicitDynamicParam() {
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = f/*<dynamic>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1() {
+    // Note: (f/*<dynamic>*/) is nort properly resulting in an instantiated
+    // function type due to dartbug.com/25824.
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = (f/*<dynamic>*/)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2() {
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = (f)/*<dynamic>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  void test_unsafeBlockClosureInference_functionCall_explicitTypeParam() {
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = f/*<int>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  @failingTest
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1() {
+    // TODO(paulberry): for some reason (f/*<int>) is nort properly resulting
+    // in an instantiated function type.
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = (f/*<int>*/)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2() {
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = (f)/*<int>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void test_unsafeBlockClosureInference_functionCall_implicitTypeParam() {
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = f(
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void
+      test_unsafeBlockClosureInference_functionCall_implicitTypeParam_viaExpr() {
+    var mainUnit = checkFile('''
+dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+var v = (f)(
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void test_unsafeBlockClosureInference_functionCall_noTypeParam() {
+    var mainUnit = checkFile('''
+double f(x) => 1.0;
+var v = f(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'double');
+  }
+
+  void test_unsafeBlockClosureInference_functionCall_noTypeParam_viaExpr() {
+    var mainUnit = checkFile('''
+double f(x) => 1.0;
+var v = (f)(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'double');
+  }
+
+  void test_unsafeBlockClosureInference_inList_dynamic() {
+    var mainUnit = checkFile('''
+var v = <dynamic>[/*info:INFERRED_TYPE_CLOSURE*/() { return 1; }];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  void test_unsafeBlockClosureInference_inList_typed() {
+    var mainUnit = checkFile('''
+typedef int F();
+var v = <F>[/*info:INFERRED_TYPE_CLOSURE*/() { return 1; }];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<() → int>');
+  }
+
+  void test_unsafeBlockClosureInference_inList_untyped() {
+    var mainUnit = checkFile('''
+var v = /*info:INFERRED_TYPE_LITERAL*/[
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  }];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<() → int>');
+  }
+
+  void test_unsafeBlockClosureInference_inMap_dynamic() {
+    var mainUnit = checkFile('''
+var v = <int, dynamic>{1: /*info:INFERRED_TYPE_CLOSURE*/() { return 1; }};
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'Map<int, dynamic>');
+  }
+
+  void test_unsafeBlockClosureInference_inMap_typed() {
+    var mainUnit = checkFile('''
+typedef int F();
+var v = <int, F>{1: /*info:INFERRED_TYPE_CLOSURE*/() { return 1; }};
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'Map<int, () → int>');
+  }
+
+  void test_unsafeBlockClosureInference_inMap_untyped() {
+    var mainUnit = checkFile('''
+var v = /*info:INFERRED_TYPE_LITERAL*/{
+  1: /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  }};
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'Map<int, () → int>');
+  }
+
+  void test_unsafeBlockClosureInference_methodCall_explicitDynamicParam() {
+    var mainUnit = checkFile('''
+class C {
+  dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+}
+var v = new C().f/*<dynamic>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<dynamic>');
+  }
+
+  void test_unsafeBlockClosureInference_methodCall_explicitTypeParam() {
+    var mainUnit = checkFile('''
+class C {
+  dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+}
+var v = new C().f/*<int>*/(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void test_unsafeBlockClosureInference_methodCall_implicitTypeParam() {
+    var mainUnit = checkFile('''
+class C {
+  dynamic /*=List<T>*/ f/*<T>*/(dynamic/*=T*/ g()) => <T>[g()];
+}
+var v = new C().f(
+  /*info:INFERRED_TYPE_CLOSURE,warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() {
+    return 1;
+  });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'List<int>');
+  }
+
+  void test_unsafeBlockClosureInference_methodCall_noTypeParam() {
+    var mainUnit = checkFile('''
+class C {
+  double f(x) => 1.0;
+}
+var v = new C().f(/*info:INFERRED_TYPE_CLOSURE*/() { return 1; });
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.name, 'v');
+    expect(v.type.toString(), 'double');
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/task/strong/non_null_checker_test.dart b/pkg/analyzer/test/src/task/strong/non_null_checker_test.dart
new file mode 100644
index 0000000..e5fa7c6
--- /dev/null
+++ b/pkg/analyzer/test/src/task/strong/non_null_checker_test.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// These tests are for an experimental feature that treats Dart primitive types
+// (int, bool, double, etc.) as non-nullable. This file is not evidence for an
+// intention to officially support non-nullable primitives in Dart (or general
+// NNBD, for that matter) so don't get too crazy about it.
+
+library analyzer.test.src.task.non_null_primitives.checker_test;
+
+import '../../../reflective_tests.dart';
+import '../strong/strong_test_helper.dart';
+
+void main() {
+  initStrongModeTests();
+  runReflectiveTests(NonNullCheckerTest);
+}
+
+@reflectiveTest
+class NonNullCheckerTest {
+  // Tests simple usage of ints as iterators for a loop. Not directly related to
+  // non-nullability, but if it is implemented this should be more efficient,
+  // since languages.length will not be null-checked on every iteration.
+  void test_forLoop() {
+    checkFile('''
+class MyList {
+  int length;
+  MyList() {
+    length = 6;
+  }
+  String operator [](int i) {
+    return <String>["Dart", "Java", "JS", "C", "C++", "C#"][i];
+  }
+}
+
+main() {
+  var languages = new MyList();
+  for (int i = 0; i < languages.length; ++i) {
+    print(languages[i]);
+  }
+}
+''');
+  }
+
+  void test_nullableTypes() {
+    // By default x can be set to null.
+    checkFile('int x = null;');
+  }
+
+  void test_initialize_nonnullable_with_null() {
+    addFile('int x = /*error:INVALID_ASSIGNMENT*/null;');
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+
+  void test_initialize_nonnullable_with_valid_value() {
+    addFile('int x = 0;');
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+
+  void test_assign_null_to_nonnullable() {
+    addFile('''
+int x = 0;
+
+main() {
+  x = 1;
+  x = /*error:INVALID_ASSIGNMENT*/null;
+}
+''');
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+
+  void test_uninitialized_nonnullable_local_variable() {
+    // Ideally, we will do flow analysis and throw an error only if a variable
+    // is used before it has been initialized.
+    addFile('main() { int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x; }');
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+
+  void test_uninitialized_nonnullable_top_level_variable_declaration() {
+    // If `int`s are non-nullable, then this code should throw an error.
+    addFile('int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;');
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+
+  void test_uninitialized_nonnullable_field_declaration() {
+    addFile('''
+void foo() {}
+
+class A {
+  // Ideally, we should allow x to be init in the constructor, but that requires
+  // too much complication in the checker, so for now we throw a static error at
+  // the declaration site.
+  int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;
+
+  A();
+}
+''');
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+
+  void test_prefer_final_to_non_nullable_error() {
+    addFile('main() { final int /*error:FINAL_NOT_INITIALIZED*/x; }');
+    addFile('final int /*error:FINAL_NOT_INITIALIZED*/x;');
+    addFile('''
+void foo() {}
+
+class A {
+  final int x;
+
+  /*warning:FINAL_NOT_INITIALIZED_CONSTRUCTOR_1*/A();
+}
+''');
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+
+  // Default example from NNBD document.
+  final String defaultNnbdExample = '''
+class Point {
+  final int x, y;
+  Point(this.x, this.y);
+  Point operator +(Point other) => new Point(x + other.x, y + other.y);
+  String toString() => "x: \$x, y: \$y";
+}
+
+void main() {
+  Point p1 = new Point(0, 0);
+  Point p2 = new Point(10, 10);
+  print("p1 + p2 = \${p1 + p2}");
+}
+''';
+
+  final String defaultNnbdExampleMod1 = '''
+class Point {
+  final int x, y;
+  Point(this.x, this.y);
+  Point operator +(Point other) => new Point(x + other.x, y + other.y);
+  String toString() => "x: \$x, y: \$y";
+}
+
+void main() {
+  Point p1 = new Point(0, 0);
+  Point p2 = new Point(10, /*boom*/null); // Change here.
+  print("p1 + p2 = \${p1 + p2}");
+}
+''';
+
+  final String defaultNnbdExampleMod2 = '''
+class Point {
+  final int x, y;
+  Point(this.x, this.y);
+  Point operator +(Point other) => new Point(x + other.x, y + other.y);
+  String toString() => "x: \$x, y: \$y";
+}
+
+void main() {
+  bool f = false; // Necessary, because dead code is otherwise detected.
+  Point p1 = new Point(0, 0);
+  Point p2 = new Point(10, /*boom*/f ? 10 : null); // Change here.
+  print("p1 + p2 = \${p1 + p2}");
+}
+''';
+
+  void test_nullable_fields() {
+    addFile(defaultNnbdExample);
+    // `null` can be passed as an argument to `Point` in default mode.
+    addFile(defaultNnbdExampleMod1);
+    // A nullable expression can be passed as an argument to `Point` in default
+    // mode.
+    addFile(defaultNnbdExampleMod2);
+    check();
+  }
+
+  void test_nonnullable_fields() {
+    addFile(defaultNnbdExample);
+    // `null` can be passed as an argument to `Point` in default mode.
+    addFile(_withError(defaultNnbdExampleMod1, "error:INVALID_ASSIGNMENT"));
+    // A nullable expression can be passed as an argument to `Point` in default
+    // mode.
+    addFile(_withError(defaultNnbdExampleMod2, "error:INVALID_ASSIGNMENT"));
+    check(nonnullableTypes: <String>['dart:core,int']);
+  }
+}
+
+String _withError(String file, String error) {
+  return ("" + file).replaceFirst("boom", error);
+}
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 82829eb..5b9f89a 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -54,7 +54,10 @@
 /// the file text.
 ///
 /// Returns the main resolved library. This can be used for further checks.
-CompilationUnit check({bool implicitCasts: true, bool implicitDynamic: true}) {
+CompilationUnit check(
+    {bool implicitCasts: true,
+    bool implicitDynamic: true,
+    List<String> nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES}) {
   _checkCalled = true;
 
   expect(files.getFile('/main.dart').exists, true,
@@ -68,8 +71,9 @@
   options.strongModeHints = true;
   options.implicitCasts = implicitCasts;
   options.implicitDynamic = implicitDynamic;
+  options.nonnullableTypes = nonnullableTypes;
   var mockSdk = new MockSdk();
-  mockSdk.context.analysisOptions.strongMode = true;
+  (mockSdk.context.analysisOptions as AnalysisOptionsImpl).strongMode = true;
   context.sourceFactory =
       new SourceFactory([new DartUriResolver(mockSdk), uriResolver]);
 
@@ -97,7 +101,6 @@
           // TODO(jmesserly): these are usually intentional dynamic calls.
           e.errorCode.name != 'UNDEFINED_METHOD' &&
           // We don't care about any of these:
-          e.errorCode != HintCode.UNNECESSARY_CAST &&
           e.errorCode != HintCode.UNUSED_ELEMENT &&
           e.errorCode != HintCode.UNUSED_FIELD &&
           e.errorCode != HintCode.UNUSED_IMPORT &&
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index c92adfa..94cbace 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -10,6 +10,7 @@
 import 'context/test_all.dart' as context;
 import 'dart/test_all.dart' as dart;
 import 'plugin/plugin_config_test.dart' as plugin;
+import 'source/test_all.dart' as source;
 import 'summary/test_all.dart' as summary;
 import 'task/test_all.dart' as task;
 import 'util/test_all.dart' as util;
@@ -21,6 +22,7 @@
     context.main();
     dart.main();
     plugin.main();
+    source.main();
     summary.main();
     task.main();
     util.main();
diff --git a/pkg/analyzer/test/stress/for_git_repository.dart b/pkg/analyzer/test/stress/for_git_repository.dart
new file mode 100644
index 0000000..2ee3929
--- /dev/null
+++ b/pkg/analyzer/test/stress/for_git_repository.dart
@@ -0,0 +1,637 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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.stress.limited_invalidation;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/file_system/file_system.dart' as fs;
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+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/utilities_collection.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/general.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+main() {
+  new StressTest().run();
+}
+
+void _failTypeMismatch(Object actual, Object expected, {String reason}) {
+  String message = 'Actual $actual is ${actual.runtimeType}, '
+      'but expected $expected is ${expected.runtimeType}';
+  if (reason != null) {
+    message += ' $reason';
+  }
+  fail(message);
+}
+
+void _logPrint(String message) {
+  DateTime time = new DateTime.now();
+  print('$time: $message');
+}
+
+class FileInfo {
+  final String path;
+  final int modification;
+
+  FileInfo(this.path, this.modification);
+}
+
+class FolderDiff {
+  final List<String> added;
+  final List<String> changed;
+  final List<String> removed;
+
+  FolderDiff(this.added, this.changed, this.removed);
+
+  bool get isEmpty => added.isEmpty && changed.isEmpty && removed.isEmpty;
+  bool get isNotEmpty => !isEmpty;
+
+  @override
+  String toString() {
+    return '[added=$added, changed=$changed, removed=$removed]';
+  }
+}
+
+class FolderInfo {
+  final String path;
+  final List<FileInfo> files = <FileInfo>[];
+
+  FolderInfo(this.path) {
+    List<FileSystemEntity> entities =
+        new Directory(path).listSync(recursive: true);
+    for (FileSystemEntity entity in entities) {
+      if (entity is File) {
+        String path = entity.path;
+        if (path.contains('packages') || path.contains('.pub')) {
+          continue;
+        }
+        if (path.endsWith('.dart')) {
+          files.add(new FileInfo(
+              path, entity.lastModifiedSync().millisecondsSinceEpoch));
+        }
+      }
+    }
+  }
+
+  FolderDiff diff(FolderInfo oldFolder) {
+    Map<String, FileInfo> toMap(FolderInfo folder) {
+      Map<String, FileInfo> map = <String, FileInfo>{};
+      folder.files.forEach((file) {
+        map[file.path] = file;
+      });
+      return map;
+    }
+
+    Map<String, FileInfo> newFiles = toMap(this);
+    Map<String, FileInfo> oldFiles = toMap(oldFolder);
+    Set<String> addedPaths = newFiles.keys.toSet()..removeAll(oldFiles.keys);
+    Set<String> removedPaths = oldFiles.keys.toSet()..removeAll(newFiles.keys);
+    List<String> changedPaths = <String>[];
+    newFiles.forEach((path, newFile) {
+      FileInfo oldFile = oldFiles[path];
+      if (oldFile != null && oldFile.modification != newFile.modification) {
+        changedPaths.add(path);
+      }
+    });
+    return new FolderDiff(
+        addedPaths.toList(), changedPaths, removedPaths.toList());
+  }
+}
+
+class GitException {
+  final String message;
+  final String stdout;
+  final String stderr;
+
+  GitException(this.message)
+      : stdout = null,
+        stderr = null;
+
+  GitException.forProcessResult(this.message, ProcessResult processResult)
+      : stdout = processResult.stdout,
+        stderr = processResult.stderr;
+
+  @override
+  String toString() => '$message\n$stdout\n$stderr\n';
+}
+
+class GitRepository {
+  final String path;
+
+  GitRepository(this.path);
+
+  Future checkout(String hash) async {
+    // TODO(scheglov) use for updating only some files
+    if (hash.endsWith('hash')) {
+      List<String> filePaths = <String>[
+        '/Users/user/full/path/one.dart',
+        '/Users/user/full/path/two.dart',
+      ];
+      for (var filePath in filePaths) {
+        await Process.run('git', <String>['checkout', '-f', hash, filePath],
+            workingDirectory: path);
+      }
+      return;
+    }
+    ProcessResult processResult = await Process
+        .run('git', <String>['checkout', '-f', hash], workingDirectory: path);
+    _throwIfNotSuccess(processResult);
+  }
+
+  Future<List<GitRevision>> getRevisions({String after}) async {
+    List<String> args = <String>['log', '--format=%ct %H %s'];
+    if (after != null) {
+      args.add('--after=$after');
+    }
+    ProcessResult processResult =
+        await Process.run('git', args, workingDirectory: path);
+    _throwIfNotSuccess(processResult);
+    String output = processResult.stdout;
+    List<String> logLines = output.split('\n');
+    List<GitRevision> revisions = <GitRevision>[];
+    for (String logLine in logLines) {
+      int index1 = logLine.indexOf(' ');
+      if (index1 != -1) {
+        int index2 = logLine.indexOf(' ', index1 + 1);
+        if (index2 != -1) {
+          int timestamp = int.parse(logLine.substring(0, index1));
+          String hash = logLine.substring(index1 + 1, index2);
+          String message = logLine.substring(index2).trim();
+          revisions.add(new GitRevision(timestamp, hash, message));
+        }
+      }
+    }
+    return revisions;
+  }
+
+  void removeIndexLock() {
+    File file = new File('$path/.git/index.lock');
+    if (file.existsSync()) {
+      file.deleteSync();
+    }
+  }
+
+  Future resetHard() async {
+    ProcessResult processResult = await Process
+        .run('git', <String>['reset', '--hard'], workingDirectory: path);
+    _throwIfNotSuccess(processResult);
+  }
+
+  void _throwIfNotSuccess(ProcessResult processResult) {
+    if (processResult.exitCode != 0) {
+      throw new GitException.forProcessResult(
+          'Unable to run "git log".', processResult);
+    }
+  }
+}
+
+class GitRevision {
+  final int timestamp;
+  final String hash;
+  final String message;
+
+  GitRevision(this.timestamp, this.hash, this.message);
+
+  @override
+  String toString() {
+    DateTime dateTime =
+        new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000, isUtc: true)
+            .toLocal();
+    return '$dateTime|$hash|$message|';
+  }
+}
+
+class StressTest {
+  String repoPath = '/Users/scheglov/tmp/limited-invalidation/path';
+  String folderPath = '/Users/scheglov/tmp/limited-invalidation/path';
+//  String repoPath = '/Users/scheglov/tmp/limited-invalidation/async';
+//  String folderPath = '/Users/scheglov/tmp/limited-invalidation/async';
+//  String repoPath = '/Users/scheglov/tmp/limited-invalidation/sdk';
+//  String folderPath = '/Users/scheglov/tmp/limited-invalidation/sdk/pkg/analyzer';
+
+  fs.ResourceProvider resourceProvider;
+  path.Context pathContext;
+  DartSdkManager sdkManager;
+  ContentCache contentCache;
+
+  AnalysisContextImpl expectedContext;
+  AnalysisContextImpl actualContext;
+
+  Set<Element> currentRevisionValidatedElements = new Set<Element>();
+
+  void createContexts() {
+    assert(expectedContext == null);
+    assert(actualContext == null);
+    resourceProvider = PhysicalResourceProvider.INSTANCE;
+    pathContext = resourceProvider.pathContext;
+    fs.Folder sdkDirectory =
+        FolderBasedDartSdk.defaultSdkDirectory(resourceProvider);
+    sdkManager = new DartSdkManager(sdkDirectory.path, false,
+        (_) => new FolderBasedDartSdk(resourceProvider, sdkDirectory));
+    contentCache = new ContentCache();
+    ContextBuilder builder =
+        new ContextBuilder(resourceProvider, sdkManager, contentCache);
+    builder.defaultOptions = new AnalysisOptionsImpl();
+    expectedContext = builder.buildContext(folderPath);
+    actualContext = builder.buildContext(folderPath);
+    expectedContext.analysisOptions =
+        new AnalysisOptionsImpl.from(expectedContext.analysisOptions)
+          ..incremental = true;
+    actualContext.analysisOptions =
+        new AnalysisOptionsImpl.from(actualContext.analysisOptions)
+          ..incremental = true
+          ..finerGrainedInvalidation = true;
+    print('Created contexts');
+  }
+
+  run() async {
+    GitRepository repository = new GitRepository(repoPath);
+
+    // Recover.
+    repository.removeIndexLock();
+    await repository.resetHard();
+
+    await repository.checkout('master');
+    List<GitRevision> revisions =
+        await repository.getRevisions(after: '2016-01-01');
+    revisions = revisions.reversed.toList();
+    // TODO(scheglov) Use to compare two revisions.
+//    List<GitRevision> revisions = [
+//      new GitRevision(0, '99517a162cbabf3d3afbdb566df3fe2b18cd4877', 'aaa'),
+//      new GitRevision(0, '2ef00b0c3d0182b5e4ea5ca55fd00b9d038ae40d', 'bbb'),
+//    ];
+    FolderInfo oldFolder = null;
+    for (GitRevision revision in revisions) {
+      print(revision);
+      await repository.checkout(revision.hash);
+
+      // Run "pub get".
+      if (!new File('$folderPath/pubspec.yaml').existsSync()) {
+        continue;
+      }
+      {
+        ProcessResult processResult = await Process.run(
+            '/Users/scheglov/Applications/dart-sdk/bin/pub', <String>['get'],
+            workingDirectory: folderPath);
+        if (processResult.exitCode != 0) {
+          _logPrint('Pub get failed.');
+          _logPrint(processResult.stdout);
+          _logPrint(processResult.stderr);
+          continue;
+        }
+        _logPrint('\tpub get OK');
+      }
+      FolderInfo newFolder = new FolderInfo(folderPath);
+
+      if (expectedContext == null) {
+        createContexts();
+        _applyChanges(
+            newFolder.files.map((file) => file.path).toList(), [], []);
+        _analyzeContexts();
+      }
+
+      if (oldFolder != null) {
+        FolderDiff diff = newFolder.diff(oldFolder);
+        print('    $diff');
+        if (diff.isNotEmpty) {
+          _applyChanges(diff.added, diff.changed, diff.removed);
+          _analyzeContexts();
+        }
+      }
+      oldFolder = newFolder;
+      print('\n');
+      print('\n');
+    }
+  }
+
+  /**
+   * Perform analysis tasks up to 512 times and assert that it was enough.
+   */
+  void _analyzeAll_assertFinished(AnalysisContext context,
+      [int maxIterations = 1000000]) {
+    for (int i = 0; i < maxIterations; i++) {
+      List<ChangeNotice> notice = context.performAnalysisTask().changeNotices;
+      if (notice == null) {
+        return;
+      }
+    }
+    throw new StateError(
+        "performAnalysisTask failed to terminate after analyzing all sources");
+  }
+
+  void _analyzeContexts() {
+    {
+      Stopwatch sw = new Stopwatch()..start();
+      _analyzeAll_assertFinished(expectedContext);
+      print('    analyze(expected):    ${sw.elapsedMilliseconds}');
+    }
+    {
+      Stopwatch sw = new Stopwatch()..start();
+      _analyzeAll_assertFinished(actualContext);
+      print('    analyze(actual): ${sw.elapsedMilliseconds}');
+    }
+    _validateContexts();
+  }
+
+  void _applyChanges(
+      List<String> added, List<String> changed, List<String> removed) {
+    ChangeSet changeSet = new ChangeSet();
+    added.map(_pathToSource).forEach(changeSet.addedSource);
+    removed.map(_pathToSource).forEach(changeSet.removedSource);
+    changed.map(_pathToSource).forEach(changeSet.changedSource);
+    changed.forEach((path) => new File(path).readAsStringSync());
+    {
+      Stopwatch sw = new Stopwatch()..start();
+      expectedContext.applyChanges(changeSet);
+      print('    apply(expected):    ${sw.elapsedMilliseconds}');
+    }
+    {
+      Stopwatch sw = new Stopwatch()..start();
+      actualContext.applyChanges(changeSet);
+      print('    apply(actual): ${sw.elapsedMilliseconds}');
+    }
+  }
+
+  Source _pathToSource(String path) {
+    fs.File file = resourceProvider.getFile(path);
+    return _createSourceInContext(expectedContext, file);
+  }
+
+  void _validateContexts() {
+    currentRevisionValidatedElements.clear();
+    MapIterator<AnalysisTarget, CacheEntry> iterator =
+        expectedContext.privateAnalysisCachePartition.iterator();
+    while (iterator.moveNext()) {
+      AnalysisTarget target = iterator.key;
+      CacheEntry entry = iterator.value;
+      if (target is NonExistingSource) {
+        continue;
+      }
+      _validateEntry(target, entry);
+    }
+  }
+
+  void _validateElements(
+      Element actualValue, Element expectedValue, Set visited) {
+    if (actualValue == null && expectedValue == null) {
+      return;
+    }
+    if (!currentRevisionValidatedElements.add(expectedValue)) {
+      return;
+    }
+    if (!visited.add(expectedValue)) {
+      return;
+    }
+    List<Element> sortElements(List<Element> elements) {
+      elements = elements.toList();
+      elements.sort((a, b) {
+        if (a.nameOffset != b.nameOffset) {
+          return a.nameOffset - b.nameOffset;
+        }
+        return a.name.compareTo(b.name);
+      });
+      return elements;
+    }
+
+    void validateSortedElements(
+        List<Element> actualElements, List<Element> expectedElements) {
+      expect(actualElements, hasLength(expectedElements.length));
+      actualElements = sortElements(actualElements);
+      expectedElements = sortElements(expectedElements);
+      for (int i = 0; i < expectedElements.length; i++) {
+        _validateElements(actualElements[i], expectedElements[i], visited);
+      }
+    }
+
+    expect(actualValue?.runtimeType, expectedValue?.runtimeType);
+    expect(actualValue.nameOffset, expectedValue.nameOffset);
+    expect(actualValue.name, expectedValue.name);
+    if (expectedValue is ClassElement) {
+      var actualElement = actualValue as ClassElement;
+      validateSortedElements(actualElement.accessors, expectedValue.accessors);
+      validateSortedElements(
+          actualElement.constructors, expectedValue.constructors);
+      validateSortedElements(actualElement.fields, expectedValue.fields);
+      validateSortedElements(actualElement.methods, expectedValue.methods);
+    }
+    if (expectedValue is CompilationUnitElement) {
+      var actualElement = actualValue as CompilationUnitElement;
+      validateSortedElements(actualElement.accessors, expectedValue.accessors);
+      validateSortedElements(actualElement.functions, expectedValue.functions);
+      validateSortedElements(actualElement.types, expectedValue.types);
+      validateSortedElements(
+          actualElement.functionTypeAliases, expectedValue.functionTypeAliases);
+      validateSortedElements(
+          actualElement.topLevelVariables, expectedValue.topLevelVariables);
+    }
+    if (expectedValue is ExecutableElement) {
+      var actualElement = actualValue as ExecutableElement;
+      validateSortedElements(
+          actualElement.parameters, expectedValue.parameters);
+      _validateTypes(
+          actualElement.returnType, expectedValue.returnType, visited);
+    }
+  }
+
+  void _validateEntry(AnalysisTarget target, CacheEntry expectedEntry) {
+    CacheEntry actualEntry =
+        actualContext.privateAnalysisCachePartition.get(target);
+    if (actualEntry == null) {
+      return;
+    }
+    print('  (${target.runtimeType})  $target');
+    for (ResultDescriptor result in expectedEntry.nonInvalidResults) {
+      var expectedData = expectedEntry.getResultDataOrNull(result);
+      var actualData = actualEntry.getResultDataOrNull(result);
+      if (expectedData?.state == CacheState.INVALID) {
+        expectedData = null;
+      }
+      if (actualData?.state == CacheState.INVALID) {
+        actualData = null;
+      }
+      if (actualData == null) {
+        if (result != CONTENT &&
+            result != LIBRARY_ELEMENT4 &&
+            result != LIBRARY_ELEMENT5 &&
+            result != READY_LIBRARY_ELEMENT6 &&
+            result != READY_LIBRARY_ELEMENT7) {
+          Source targetSource = target.source;
+          if (targetSource != null &&
+              targetSource.fullName.startsWith(folderPath)) {
+            fail('No ResultData $result for $target');
+          }
+        }
+        continue;
+      }
+      Object expectedValue = expectedData.value;
+      Object actualValue = actualData.value;
+      print('    $result  ${expectedValue?.runtimeType}');
+      _validateResult(target, result, actualValue, expectedValue);
+    }
+  }
+
+  void _validatePairs(AnalysisTarget target, ResultDescriptor result,
+      List actualList, List expectedList) {
+    if (expectedList == null) {
+      expect(actualList, isNull);
+      return;
+    }
+    expect(actualList, isNotNull);
+    expect(actualList, hasLength(expectedList.length));
+    for (int i = 0; i < expectedList.length; i++) {
+      Object expected = expectedList[i];
+      Object actual = actualList[i];
+      _validateResult(target, result, actual, expected);
+    }
+  }
+
+  void _validateResult(AnalysisTarget target, ResultDescriptor result,
+      Object actualValue, Object expectedValue) {
+    if (expectedValue is bool) {
+      expect(actualValue, expectedValue, reason: '$result of $target');
+    }
+    if (expectedValue is CompilationUnit) {
+      expect(actualValue, new isInstanceOf<CompilationUnit>());
+      new _AstValidator().isEqualNodes(expectedValue, actualValue);
+    }
+    if (expectedValue is Element) {
+      expect(actualValue, new isInstanceOf<Element>());
+      _validateElements(actualValue, expectedValue, new Set.identity());
+    }
+    if (expectedValue is List) {
+      if (actualValue is List) {
+        _validatePairs(target, result, actualValue, expectedValue);
+      } else {
+        _failTypeMismatch(actualValue, expectedValue);
+      }
+    }
+    if (expectedValue is AnalysisError) {
+      if (actualValue is AnalysisError) {
+        expect(actualValue.source, expectedValue.source);
+        expect(actualValue.offset, expectedValue.offset);
+        expect(actualValue.message, expectedValue.message);
+      } else {
+        _failTypeMismatch(actualValue, expectedValue);
+      }
+    }
+  }
+
+  void _validateTypes(DartType actualType, DartType expectedType, Set visited) {
+    if (!visited.add(expectedType)) {
+      return;
+    }
+    expect(actualType?.runtimeType, expectedType?.runtimeType);
+    _validateElements(actualType.element, expectedType.element, visited);
+  }
+
+  /**
+   * Create and return a source representing the given [file] within the given
+   * [context].
+   */
+  static Source _createSourceInContext(AnalysisContext context, fs.File file) {
+    Source source = file.createSource();
+    if (context == null) {
+      return source;
+    }
+    Uri uri = context.sourceFactory.restoreUri(source);
+    return file.createSource(uri);
+  }
+}
+
+/**
+ * Compares tokens and ASTs, and built elements of declared identifiers.
+ */
+class _AstValidator extends AstComparator {
+  @override
+  bool isEqualNodes(AstNode expected, AstNode actual) {
+    // TODO(scheglov) skip comments for now
+    // [ElementBuilder.visitFunctionExpression] in resolver_test.dart
+    // Going from c4493869ca19ef9ba6bd35d3d42e1209eb3b7e63
+    // to         3977c9f2274df35df6332a65af9973fd6517bc12
+    // With files:
+    //  '/Users/scheglov/tmp/limited-invalidation/sdk/pkg/analyzer/lib/src/generated/resolver.dart',
+    //  '/Users/scheglov/tmp/limited-invalidation/sdk/pkg/analyzer/lib/src/dart/element/builder.dart',
+    //  '/Users/scheglov/tmp/limited-invalidation/sdk/pkg/analyzer/test/generated/resolver_test.dart',
+    if (expected is CommentReference) {
+      return true;
+    }
+    // Compare nodes.
+    bool result = super.isEqualNodes(expected, actual);
+    if (!result) {
+      fail('|$actual| != expected |$expected|');
+    }
+    // Verify that identifiers have equal elements and types.
+    if (expected is SimpleIdentifier && actual is SimpleIdentifier) {
+      _verifyElements(actual.staticElement, expected.staticElement,
+          '$expected staticElement');
+      _verifyElements(actual.propagatedElement, expected.propagatedElement,
+          '$expected staticElement');
+      _verifyTypes(
+          actual.staticType, expected.staticType, '$expected staticType');
+      _verifyTypes(actual.propagatedType, expected.propagatedType,
+          '$expected propagatedType');
+      _verifyElements(actual.staticParameterElement,
+          expected.staticParameterElement, '$expected staticParameterElement');
+      _verifyElements(
+          actual.propagatedParameterElement,
+          expected.propagatedParameterElement,
+          '$expected propagatedParameterElement');
+    }
+    return true;
+  }
+
+  void _verifyElements(Element actual, Element expected, String desc) {
+    if (expected == null && actual == null) {
+      return;
+    }
+    if (expected is MultiplyDefinedElement &&
+        actual is MultiplyDefinedElement) {
+      return;
+    }
+    while (expected is Member) {
+      if (actual is Member) {
+        actual = (actual as Member).baseElement;
+        expected = (expected as Member).baseElement;
+      } else {
+        _failTypeMismatch(actual, expected, reason: desc);
+      }
+    }
+    expect(actual, equals(expected), reason: desc);
+  }
+
+  void _verifyTypes(DartType actual, DartType expected, String desc) {
+    _verifyElements(actual?.element, expected?.element, '$desc element');
+    if (expected is InterfaceType) {
+      if (actual is InterfaceType) {
+        List<DartType> actualArguments = actual.typeArguments;
+        List<DartType> expectedArguments = expected.typeArguments;
+        expect(
+            actualArguments,
+            pairwiseCompare(expectedArguments, (a, b) {
+              _verifyTypes(a, b, '$desc typeArguments');
+              return true;
+            }, 'elements'));
+      } else {
+        _failTypeMismatch(actual, expected);
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index bf6d8b5..8a6645d 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -1,6 +1,7 @@
 import 'dart:io';
 
-import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/summary/flat_buffers.dart' as fb;
 import 'package:analyzer/src/summary/summary_file_builder.dart';
 
@@ -98,7 +99,9 @@
       return null;
     }
   } else {
-    sdkPath = DirectoryBasedDartSdk.defaultSdkDirectory.getAbsolutePath();
+    sdkPath = FolderBasedDartSdk
+        .defaultSdkDirectory(PhysicalResourceProvider.INSTANCE)
+        .path;
   }
 
   //
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 869b38d..124a6b8 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -451,6 +451,7 @@
     out("import 'flat_buffers.dart' as fb;");
     out("import 'idl.dart' as idl;");
     out("import 'dart:convert' as convert;");
+    out("import 'api_signature.dart' as api_sig;");
     out();
     for (idlModel.EnumDeclaration enm in _idl.enums.values) {
       _generateEnumReader(enm);
@@ -618,6 +619,44 @@
         });
         out('}');
       }
+      // Generate collectApiSignature().
+      {
+        out();
+        out('/**');
+        out(' * Accumulate non-[informative] data into [signature].');
+        out(' */');
+        out('void collectApiSignature(api_sig.ApiSignature signature) {');
+        indent(() {
+          List<idlModel.FieldDeclaration> sortedFields = cls.fields.toList()
+            ..sort((idlModel.FieldDeclaration a, idlModel.FieldDeclaration b) =>
+                a.id.compareTo(b.id));
+          for (idlModel.FieldDeclaration field in sortedFields) {
+            if (field.isInformative) {
+              continue;
+            }
+            String ref = 'this._${field.name}';
+            if (field.type.isList) {
+              out('if ($ref == null) {');
+              indent(() {
+                out('signature.addInt(0);');
+              });
+              out('} else {');
+              indent(() {
+                out('signature.addInt($ref.length);');
+                out('for (var x in $ref) {');
+                indent(() {
+                  _generateSignatureCall(field.type.typeName, 'x', false);
+                });
+                out('}');
+              });
+              out('}');
+            } else {
+              _generateSignatureCall(field.type.typeName, ref, true);
+            }
+          }
+        });
+        out('}');
+      }
       // Generate finish.
       if (cls.isTopLevel) {
         out();
@@ -820,7 +859,8 @@
         } else {
           out('$returnType get $fieldName {');
           indent(() {
-            String readExpr = '$readCode.vTableGet(_bc, _bcOffset, $index, $def)';
+            String readExpr =
+                '$readCode.vTableGet(_bc, _bcOffset, $index, $def)';
             out('_$fieldName ??= $readExpr;');
             out('return _$fieldName;');
           });
@@ -918,6 +958,56 @@
   }
 
   /**
+   * Generate a call to the appropriate method of [ApiSignature] for the type
+   * [typeName], using the data named by [ref].  If [couldBeNull] is `true`,
+   * generate code to handle the possibility that [ref] is `null` (substituting
+   * in the appropriate default value).
+   */
+  void _generateSignatureCall(String typeName, String ref, bool couldBeNull) {
+    if (_idl.enums.containsKey(typeName)) {
+      if (couldBeNull) {
+        out('signature.addInt($ref == null ? 0 : $ref.index);');
+      } else {
+        out('signature.addInt($ref.index);');
+      }
+    } else if (_idl.classes.containsKey(typeName)) {
+      if (couldBeNull) {
+        out('signature.addBool($ref != null);');
+      }
+      out('$ref?.collectApiSignature(signature);');
+    } else {
+      switch (typeName) {
+        case 'String':
+          if (couldBeNull) {
+            ref += " ?? ''";
+          }
+          out("signature.addString($ref);");
+          break;
+        case 'int':
+          if (couldBeNull) {
+            ref += ' ?? 0';
+          }
+          out('signature.addInt($ref);');
+          break;
+        case 'bool':
+          if (couldBeNull) {
+            ref += ' == true';
+          }
+          out('signature.addBool($ref);');
+          break;
+        case 'double':
+          if (couldBeNull) {
+            ref += ' ?? 0.0';
+          }
+          out('signature.addDouble($ref);');
+          break;
+        default:
+          throw "Don't know how to generate signature call for $typeName";
+      }
+    }
+  }
+
+  /**
    * Return the documentation text of the given [node], or `null` if the [node]
    * does not have a comment.  Each line is `\n` separated.
    */
diff --git a/pkg/analyzer/tool/summary/idl_model.dart b/pkg/analyzer/tool/summary/idl_model.dart
index 18b981c..375dcb2 100644
--- a/pkg/analyzer/tool/summary/idl_model.dart
+++ b/pkg/analyzer/tool/summary/idl_model.dart
@@ -123,6 +123,9 @@
   final bool isList;
 
   FieldType(this.typeName, this.isList);
+
+  @override
+  String toString() => isList ? 'List<$typeName>' : typeName;
 }
 
 /**
diff --git a/pkg/analyzer/tool/summary/inspect.dart b/pkg/analyzer/tool/summary/inspect.dart
index eb0093d..c5adc30 100644
--- a/pkg/analyzer/tool/summary/inspect.dart
+++ b/pkg/analyzer/tool/summary/inspect.dart
@@ -2,10 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:convert';
 import 'dart:io';
+import 'dart:mirrors';
 
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/base.dart';
+import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/inspect.dart';
 import 'package:args/args.dart';
 
 main(List<String> args) {
@@ -22,3 +26,433 @@
   SummaryInspector inspector = new SummaryInspector(argResults['raw']);
   print(inspector.dumpPackageBundle(bundle).join('\n'));
 }
+
+const int MAX_LINE_LENGTH = 80;
+
+/**
+ * Cache used to speed up [isEnum].
+ */
+Map<Type, bool> _isEnumCache = <Type, bool>{};
+
+/**
+ * Determine if the given [obj] has an enumerated type.
+ */
+bool isEnum(Object obj) {
+  return _isEnumCache.putIfAbsent(
+      obj.runtimeType, () => reflect(obj).type.isEnum);
+}
+
+/**
+ * Decoded reprensentation of a part of a summary that occupies multiple lines
+ * of output.
+ */
+class BrokenEntity implements DecodedEntity {
+  final String opener;
+  final Map<String, DecodedEntity> parts;
+  final String closer;
+
+  BrokenEntity(this.opener, this.parts, this.closer);
+
+  @override
+  List<String> getLines() {
+    List<String> result = <String>[opener];
+    bool first = true;
+    for (String key in parts.keys) {
+      if (first) {
+        first = false;
+      } else {
+        result[result.length - 1] += ',';
+      }
+      List<String> subResult = parts[key].getLines();
+      subResult[0] = '$key: ${subResult[0]}';
+      result.addAll(subResult.map((String s) => '  $s'));
+    }
+    result.add(closer);
+    return result;
+  }
+}
+
+/**
+ * Decoded representation of a part of a summary.
+ */
+abstract class DecodedEntity {
+  /**
+   * Create a representation of a part of the summary that consists of a group
+   * of entities (represented by [parts]) contained between [opener] and
+   * [closer].
+   *
+   * If [forceKeys] is `true`, the keys in [parts] will always be shown.  If
+   * [forceKeys] is `false`, they keys will only be shown if the output is
+   * broken into multiple lines.
+   */
+  factory DecodedEntity.group(String opener, Map<String, DecodedEntity> parts,
+      String closer, bool forceKeys) {
+    // Attempt to format the entity in a single line; if not bail out and
+    // construct a _BrokenEntity.
+    DecodedEntity bailout() => new BrokenEntity(opener, parts, closer);
+    String short = opener;
+    bool first = true;
+    for (String key in parts.keys) {
+      if (first) {
+        first = false;
+      } else {
+        short += ', ';
+      }
+      DecodedEntity value = parts[key];
+      if (forceKeys) {
+        short += '$key: ';
+      }
+      if (value is UnbrokenEntity) {
+        short += value._s;
+      } else {
+        return bailout();
+      }
+      if (short.length > MAX_LINE_LENGTH) {
+        return bailout();
+      }
+    }
+    return new DecodedEntity.short(short + closer);
+  }
+
+  /**
+   * Create a representation of a part of the summary that is represented by a
+   * single unbroken string.
+   */
+  factory DecodedEntity.short(String s) = UnbrokenEntity;
+
+  /**
+   * Format this entity into a sequence of strings (one per output line).
+   */
+  List<String> getLines();
+}
+
+/**
+ * Wrapper around a [LinkedLibrary] and its constituent [UnlinkedUnit]s.
+ */
+class LibraryWrapper {
+  final LinkedLibrary _linked;
+  final List<UnlinkedUnit> _unlinked;
+
+  LibraryWrapper(this._linked, this._unlinked);
+}
+
+/**
+ * Wrapper around a [LinkedReference] and its corresponding [UnlinkedReference].
+ */
+class ReferenceWrapper {
+  final LinkedReference _linked;
+  final UnlinkedReference _unlinked;
+
+  ReferenceWrapper(this._linked, this._unlinked);
+
+  String get name {
+    if (_linked != null && _linked.name.isNotEmpty) {
+      return _linked.name;
+    } else if (_unlinked != null && _unlinked.name.isNotEmpty) {
+      return _unlinked.name;
+    } else {
+      return '???';
+    }
+  }
+}
+
+/**
+ * Instances of [SummaryInspector] are capable of traversing a summary and
+ * converting it to semi-human-readable output.
+ */
+class SummaryInspector {
+  /**
+   * The dependencies of the library currently being visited.
+   */
+  List<LinkedDependency> _dependencies;
+
+  /**
+   * The references of the unit currently being visited.
+   */
+  List<ReferenceWrapper> _references;
+
+  /**
+   * Indicates whether summary inspection should operate in "raw" mode.  In this
+   * mode, the structure of the summary file is not altered for easier
+   * readability; everything is output in exactly the form in which it appears
+   * in the file.
+   */
+  final bool raw;
+
+  SummaryInspector(this.raw);
+
+  /**
+   * Decode the object [obj], which was reached by examining [key] inside
+   * another object.
+   */
+  DecodedEntity decode(Object obj, String key) {
+    if (!raw && obj is PackageBundle) {
+      return decodePackageBundle(obj);
+    }
+    if (obj is LibraryWrapper) {
+      return decodeLibrary(obj);
+    }
+    if (obj is UnitWrapper) {
+      return decodeUnit(obj);
+    }
+    if (obj is ReferenceWrapper) {
+      return decodeReference(obj);
+    }
+    if (obj is DecodedEntity) {
+      return obj;
+    }
+    if (obj is SummaryClass) {
+      Map<String, Object> map = obj.toMap();
+      return decodeMap(map);
+    } else if (obj is List) {
+      Map<String, DecodedEntity> parts = <String, DecodedEntity>{};
+      for (int i = 0; i < obj.length; i++) {
+        parts[i.toString()] = decode(obj[i], key);
+      }
+      return new DecodedEntity.group('[', parts, ']', false);
+    } else if (obj is String) {
+      return new DecodedEntity.short(JSON.encode(obj));
+    } else if (isEnum(obj)) {
+      return new DecodedEntity.short(obj.toString().split('.')[1]);
+    } else if (obj is int &&
+        key == 'dependency' &&
+        _dependencies != null &&
+        obj < _dependencies.length) {
+      return new DecodedEntity.short('$obj (${_dependencies[obj].uri})');
+    } else if (obj is int &&
+        key == 'reference' &&
+        _references != null &&
+        obj < _references.length) {
+      return new DecodedEntity.short('$obj (${_references[obj].name})');
+    } else {
+      return new DecodedEntity.short(obj.toString());
+    }
+  }
+
+  /**
+   * Decode the given [LibraryWrapper].
+   */
+  DecodedEntity decodeLibrary(LibraryWrapper obj) {
+    try {
+      LinkedLibrary linked = obj._linked;
+      List<UnlinkedUnit> unlinked = obj._unlinked;
+      _dependencies = linked.dependencies;
+      Map<String, Object> result = linked.toMap();
+      result.remove('units');
+      result['defining compilation unit'] =
+          new UnitWrapper(linked.units[0], unlinked[0]);
+      for (int i = 1; i < linked.units.length; i++) {
+        String partUri = unlinked[0].publicNamespace.parts[i - 1];
+        result['part ${JSON.encode(partUri)}'] =
+            new UnitWrapper(linked.units[i], unlinked[i]);
+      }
+      return decodeMap(result);
+    } finally {
+      _dependencies = null;
+    }
+  }
+
+  /**
+   * Decode the given [map].
+   */
+  DecodedEntity decodeMap(Map<String, Object> map) {
+    Map<String, DecodedEntity> parts = <String, DecodedEntity>{};
+    map = reorderMap(map);
+    map.forEach((String key, Object value) {
+      if (value is String && value.isEmpty) {
+        return;
+      }
+      if (isEnum(value) && (value as dynamic).index == 0) {
+        return;
+      }
+      if (value is int && value == 0) {
+        return;
+      }
+      if (value is bool && value == false) {
+        return;
+      }
+      if (value == null) {
+        return;
+      }
+      if (value is List) {
+        if (value.isEmpty) {
+          return;
+        }
+        DecodedEntity entity = decode(value, key);
+        if (entity is BrokenEntity) {
+          for (int i = 0; i < value.length; i++) {
+            parts['$key[$i]'] = decode(value[i], key);
+          }
+          return;
+        } else {
+          parts[key] = entity;
+        }
+      }
+      parts[key] = decode(value, key);
+    });
+    return new DecodedEntity.group('{', parts, '}', true);
+  }
+
+  /**
+   * Decode the given [PackageBundle].
+   */
+  DecodedEntity decodePackageBundle(PackageBundle bundle) {
+    Map<String, UnlinkedUnit> units = <String, UnlinkedUnit>{};
+    Set<String> seenUnits = new Set<String>();
+    for (int i = 0; i < bundle.unlinkedUnits.length; i++) {
+      units[bundle.unlinkedUnitUris[i]] = bundle.unlinkedUnits[i];
+    }
+    Map<String, Object> restOfMap = bundle.toMap();
+    Map<String, Object> result = <String, Object>{};
+    result['version'] = new DecodedEntity.short(
+        '${bundle.majorVersion}.${bundle.minorVersion}');
+    restOfMap.remove('majorVersion');
+    restOfMap.remove('minorVersion');
+    result['linkedLibraryUris'] = restOfMap['linkedLibraryUris'];
+    result['unlinkedUnitUris'] = restOfMap['unlinkedUnitUris'];
+    for (int i = 0; i < bundle.linkedLibraries.length; i++) {
+      String libraryUriString = bundle.linkedLibraryUris[i];
+      Uri libraryUri = Uri.parse(libraryUriString);
+      UnlinkedUnit unlinkedDefiningUnit = units[libraryUriString];
+      seenUnits.add(libraryUriString);
+      List<UnlinkedUnit> libraryUnits = <UnlinkedUnit>[unlinkedDefiningUnit];
+      LinkedLibrary linkedLibrary = bundle.linkedLibraries[i];
+      for (int j = 1; j < linkedLibrary.units.length; j++) {
+        String partUriString = resolveRelativeUri(libraryUri,
+                Uri.parse(unlinkedDefiningUnit.publicNamespace.parts[j - 1]))
+            .toString();
+        libraryUnits.add(units[partUriString]);
+        seenUnits.add(partUriString);
+      }
+      result['library ${JSON.encode(libraryUriString)}'] =
+          new LibraryWrapper(linkedLibrary, libraryUnits);
+    }
+    for (String uriString in units.keys) {
+      if (seenUnits.contains(uriString)) {
+        continue;
+      }
+      result['orphan unit ${JSON.encode(uriString)}'] =
+          new UnitWrapper(null, units[uriString]);
+    }
+    restOfMap.remove('linkedLibraries');
+    restOfMap.remove('linkedLibraryUris');
+    restOfMap.remove('unlinkedUnits');
+    restOfMap.remove('unlinkedUnitUris');
+    result.addAll(restOfMap);
+    return decodeMap(result);
+  }
+
+  /**
+   * Decode the given [ReferenceWrapper].
+   */
+  DecodedEntity decodeReference(ReferenceWrapper obj) {
+    Map<String, Object> result = obj._unlinked != null
+        ? obj._unlinked.toMap()
+        : <String, Object>{'linkedOnly': true};
+    if (obj._linked != null) {
+      mergeMaps(result, obj._linked.toMap());
+    }
+    return decodeMap(result);
+  }
+
+  /**
+   * Decode the given [UnitWrapper].
+   */
+  DecodedEntity decodeUnit(UnitWrapper obj) {
+    try {
+      LinkedUnit linked = obj._linked;
+      UnlinkedUnit unlinked = obj._unlinked ?? new UnlinkedUnitBuilder();
+      Map<String, Object> unlinkedMap = unlinked.toMap();
+      Map<String, Object> linkedMap =
+          linked != null ? linked.toMap() : <String, Object>{};
+      Map<String, Object> result = <String, Object>{};
+      List<ReferenceWrapper> references = <ReferenceWrapper>[];
+      int numReferences = linked != null
+          ? linked.references.length
+          : unlinked.references.length;
+      for (int i = 0; i < numReferences; i++) {
+        references.add(new ReferenceWrapper(
+            linked != null ? linked.references[i] : null,
+            i < unlinked.references.length ? unlinked.references[i] : null));
+      }
+      result['references'] = references;
+      _references = references;
+      unlinkedMap.remove('references');
+      linkedMap.remove('references');
+      linkedMap.forEach((String key, Object value) {
+        result['linked $key'] = value;
+      });
+      unlinkedMap.forEach((String key, Object value) {
+        result[key] = value;
+      });
+      return decodeMap(result);
+    } finally {
+      _references = null;
+    }
+  }
+
+  /**
+   * Decode the given [PackageBundle] and dump it to a list of strings.
+   */
+  List<String> dumpPackageBundle(PackageBundle bundle) {
+    DecodedEntity decoded = decode(bundle, 'PackageBundle');
+    return decoded.getLines();
+  }
+
+  /**
+   * Merge the contents of [other] into [result], discarding empty entries.
+   */
+  void mergeMaps(Map<String, Object> result, Map<String, Object> other) {
+    other.forEach((String key, Object value) {
+      if (value is String && value.isEmpty) {
+        return;
+      }
+      if (result.containsKey(key)) {
+        Object oldValue = result[key];
+        if (oldValue is String && oldValue.isEmpty) {
+          result[key] = value;
+        } else {
+          throw new Exception(
+              'Duplicate values for $key: $oldValue and $value');
+        }
+      } else {
+        result[key] = value;
+      }
+    });
+  }
+
+  /**
+   * Reorder [map] for more intuitive display.
+   */
+  Map<String, Object> reorderMap(Map<String, Object> map) {
+    Map<String, Object> result = <String, Object>{};
+    if (map.containsKey('name')) {
+      result['name'] = map['name'];
+    }
+    result.addAll(map);
+    return result;
+  }
+}
+
+/**
+ * Decoded reprensentation of a part of a summary that occupies a single line of
+ * output.
+ */
+class UnbrokenEntity implements DecodedEntity {
+  final String _s;
+
+  UnbrokenEntity(this._s);
+
+  @override
+  List<String> getLines() => <String>[_s];
+}
+
+/**
+ * Wrapper around a [LinkedUnit] and its corresponding [UnlinkedUnit].
+ */
+class UnitWrapper {
+  final LinkedUnit _linked;
+  final UnlinkedUnit _unlinked;
+
+  UnitWrapper(this._linked, this._unlinked);
+}
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index fc88511..0caa453 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -26,11 +26,11 @@
 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/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/constant.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/generated/source_io.dart';
 import 'package:path/path.dart' as path;
@@ -150,7 +150,8 @@
     }
     List<String> lines = <String>[];
     resourceProvider = PhysicalResourceProvider.INSTANCE;
-    DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
+    DartSdk sdk = new FolderBasedDartSdk(resourceProvider,
+        FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
     context = AnalysisEngine.instance.createAnalysisContext();
     String packageRootPath;
     if (Platform.packageRoot != null) {
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 11040b1..7cf3d9d 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -25,7 +25,6 @@
   BuildLibraryElementTask -> BUILD_LIBRARY_ERRORS
   BuildLibraryElementTask -> IS_LAUNCHABLE
   BuildLibraryElementTask -> LIBRARY_ELEMENT1
-  BuildLibraryElementTask -> REFERENCED_NAMES
   BuildPublicNamespaceTask -> LIBRARY_ELEMENT3
   BuildSourceExportClosureTask -> EXPORT_SOURCE_CLOSURE
   BuildTypeProviderTask -> TYPE_PROVIDER
@@ -91,6 +90,7 @@
   EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
   EXPORTED_LIBRARIES [shape=box]
   EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
+  EXPORT_SOURCE_CLOSURE -> ResolveTopLevelUnitTypeBoundsTask
   EXPORT_SOURCE_CLOSURE [shape=box]
   EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
   EvaluateUnitConstantsTask -> RESOLVED_UNIT13
@@ -122,8 +122,10 @@
   InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
   InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
   InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
+  InferStaticVariableTypeTask -> STATIC_VARIABLE_RESOLUTION_ERRORS
   InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
   InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
+  InferStaticVariableTypesInUnitTask -> STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
   LIBRARY_CYCLE [shape=box]
   LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
   LIBRARY_CYCLE_DEPENDENCIES -> InferStaticVariableTypeTask
@@ -187,6 +189,7 @@
   LibraryErrorsReadyTask -> LIBRARY_ERRORS_READY
   LibraryUnitErrorsTask -> LIBRARY_UNIT_ERRORS
   MODIFICATION_TIME -> BuildDirectiveElementsTask
+  MODIFICATION_TIME -> BuildLibraryElementTask
   MODIFICATION_TIME -> ParseDartTask
   MODIFICATION_TIME -> ScanDartTask
   MODIFICATION_TIME -> VerifyUnitTask
@@ -211,6 +214,7 @@
   ParseDartTask -> LIBRARY_SPECIFIC_UNITS
   ParseDartTask -> PARSED_UNIT
   ParseDartTask -> PARSE_ERRORS
+  ParseDartTask -> REFERENCED_NAMES
   ParseDartTask -> REFERENCED_SOURCES
   ParseDartTask -> SOURCE_KIND
   ParseDartTask -> UNITS
@@ -321,6 +325,10 @@
   SCAN_ERRORS [shape=box]
   SOURCE_KIND -> BuildDirectiveElementsTask
   SOURCE_KIND [shape=box]
+  STATIC_VARIABLE_RESOLUTION_ERRORS -> InferStaticVariableTypesInUnitTask
+  STATIC_VARIABLE_RESOLUTION_ERRORS [shape=box]
+  STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT -> LibraryUnitErrorsTask
+  STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT [shape=box]
   STRONG_MODE_ERRORS -> LibraryUnitErrorsTask
   STRONG_MODE_ERRORS [shape=box]
   ScanDartTask -> IGNORE_INFO
diff --git a/pkg/analyzer_cli/.analysis_options b/pkg/analyzer_cli/.analysis_options
index 78831a9..dc60267 100644
--- a/pkg/analyzer_cli/.analysis_options
+++ b/pkg/analyzer_cli/.analysis_options
@@ -1,3 +1,4 @@
 analyzer:
+  strong-mode: true
   exclude:
     - 'test/data'
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index f79e401..b69669d 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -10,12 +10,11 @@
 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.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/generated/source_io.dart';
 import 'package:analyzer/src/summary/format.dart';
@@ -39,23 +38,26 @@
   final StringBuffer errorBuffer = new StringBuffer();
   final StringBuffer outBuffer = new StringBuffer();
 
+  final ResourceProvider resourceProvider;
   final String dartSdkPath;
 
-  AnalyzerWorkerLoop(SyncWorkerConnection connection, {this.dartSdkPath})
+  AnalyzerWorkerLoop(this.resourceProvider, SyncWorkerConnection connection,
+      {this.dartSdkPath})
       : super(connection: connection);
 
-  factory AnalyzerWorkerLoop.std(
+  factory AnalyzerWorkerLoop.std(ResourceProvider resourceProvider,
       {io.Stdin stdinStream, io.Stdout stdoutStream, String dartSdkPath}) {
     SyncWorkerConnection connection = new StdSyncWorkerConnection(
         stdinStream: stdinStream, stdoutStream: stdoutStream);
-    return new AnalyzerWorkerLoop(connection, dartSdkPath: dartSdkPath);
+    return new AnalyzerWorkerLoop(resourceProvider, connection,
+        dartSdkPath: dartSdkPath);
   }
 
   /**
    * Performs analysis with given [options].
    */
   void analyze(CommandLineOptions options) {
-    new BuildMode(options, new AnalysisStats()).analyze();
+    new BuildMode(resourceProvider, options, new AnalysisStats()).analyze();
     AnalysisEngine.instance.clearCaches();
   }
 
@@ -69,7 +71,7 @@
     try {
       // Add in the dart-sdk argument if `dartSdkPath` is not null, otherwise it
       // will try to find the currently installed sdk.
-      var arguments = new List.from(request.arguments);
+      var arguments = new List<String>.from(request.arguments);
       if (dartSdkPath != null &&
           !arguments.any((arg) => arg.startsWith('--dart-sdk'))) {
         arguments.add('--dart-sdk=$dartSdkPath');
@@ -123,10 +125,10 @@
  * Analyzer used when the "--build-mode" option is supplied.
  */
 class BuildMode {
+  final ResourceProvider resourceProvider;
   final CommandLineOptions options;
   final AnalysisStats stats;
 
-  final ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
   SummaryDataStore summaryDataStore;
   InternalAnalysisContext context;
   Map<Uri, JavaFile> uriToFileMap;
@@ -135,8 +137,13 @@
   PackageBundleAssembler assembler;
   final Set<Source> processedSources = new Set<Source>();
   final Map<Uri, UnlinkedUnit> uriToUnit = <Uri, UnlinkedUnit>{};
+  PackageBundle sdkBundle;
 
-  BuildMode(this.options, this.stats);
+  BuildMode(this.resourceProvider, this.options, this.stats);
+
+  bool get _shouldOutputSummary =>
+      options.buildSummaryOutput != null ||
+      options.buildSummaryOutputSemantic != null;
 
   /**
    * Perform package analysis according to the given [options].
@@ -186,8 +193,7 @@
     assembler = new PackageBundleAssembler(
         excludeHashes: options.buildSummaryExcludeInformative &&
             options.buildSummaryOutputSemantic == null);
-    if (options.buildSummaryOutput != null ||
-        options.buildSummaryOutputSemantic != null) {
+    if (_shouldOutputSummary) {
       if (options.buildSummaryOnlyAst && !options.buildSummaryFallback) {
         _serializeAstBasedSummary(explicitSources);
       } else {
@@ -206,21 +212,26 @@
           }
         }
       }
+      if (!options.buildSummaryOnlyAst) {
+        // In non-AST mode, the SDK bundle wasn't added to the summaryDataStore
+        // because it is automatically loaded during analysis.  However we still
+        // want the SDK bundle to be noted as a dependency, so add it now.
+        summaryDataStore.addBundle(null, sdkBundle);
+      }
       // Write the whole package bundle.
-      PackageBundleBuilder sdkBundle = assembler.assemble();
+      assembler.recordDependencies(summaryDataStore);
+      PackageBundleBuilder bundle = assembler.assemble();
       if (options.buildSummaryExcludeInformative) {
-        sdkBundle.flushInformative();
+        bundle.flushInformative();
       }
       if (options.buildSummaryOutput != null) {
         io.File file = new io.File(options.buildSummaryOutput);
-        file.writeAsBytesSync(sdkBundle.toBuffer(),
-            mode: io.FileMode.WRITE_ONLY);
+        file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
       }
       if (options.buildSummaryOutputSemantic != null) {
-        sdkBundle.flushInformative();
+        bundle.flushInformative();
         io.File file = new io.File(options.buildSummaryOutputSemantic);
-        file.writeAsBytesSync(sdkBundle.toBuffer(),
-            mode: io.FileMode.WRITE_ONLY);
+        file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
       }
     }
 
@@ -252,23 +263,23 @@
 
   void _createContext() {
     // Read the summaries.
-    summaryDataStore = new SummaryDataStore(options.buildSummaryInputs);
+    summaryDataStore = new SummaryDataStore(options.buildSummaryInputs,
+        recordDependencyInfo: _shouldOutputSummary);
 
     DartSdk sdk;
-    PackageBundle sdkBundle;
     if (options.dartSdkSummaryPath != null) {
       SummaryBasedDartSdk summarySdk = new SummaryBasedDartSdk(
           options.dartSdkSummaryPath, options.strongMode);
       sdk = summarySdk;
       sdkBundle = summarySdk.bundle;
     } else {
-      DirectoryBasedDartSdk directorySdk =
-          new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath));
-      directorySdk.analysisOptions =
+      FolderBasedDartSdk dartSdk = new FolderBasedDartSdk(resourceProvider,
+          resourceProvider.getFolder(options.dartSdkPath), options.strongMode);
+      dartSdk.analysisOptions =
           Driver.createAnalysisOptionsForCommandLineOptions(options);
-      directorySdk.useSummary = !options.buildSummaryOnlyAst;
-      sdk = directorySdk;
-      sdkBundle = directorySdk.getSummarySdkBundle(options.strongMode);
+      dartSdk.useSummary = !options.buildSummaryOnlyAst;
+      sdk = dartSdk;
+      sdkBundle = dartSdk.getSummarySdkBundle(options.strongMode);
     }
 
     // In AST mode include SDK bundle to avoid parsing SDK sources.
@@ -285,7 +296,7 @@
     ]);
 
     // Set context options.
-    Driver.setAnalysisContextOptions(context, options,
+    Driver.setAnalysisContextOptions(resourceProvider, context, options,
         (AnalysisOptionsImpl contextOptions) {
       if (options.buildSummaryOnlyDiet) {
         contextOptions.analyzeFunctionBodies = false;
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 44cc1d1..68c9b25 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -13,11 +13,12 @@
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/plugin/resolver_provider.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/pub_package_map_provider.dart';
 import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -25,7 +26,6 @@
 import 'package:analyzer/src/generated/java_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/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart'
@@ -94,6 +94,12 @@
   /// SDK instance.
   DartSdk sdk;
 
+  /**
+   * The resource provider used to access the file system.
+   */
+  file_system.ResourceProvider resourceProvider =
+      PhysicalResourceProvider.INSTANCE;
+
   /// Collected analysis statistics.
   final AnalysisStats stats = new AnalysisStats();
 
@@ -245,9 +251,11 @@
   ErrorSeverity _buildModeAnalyze(CommandLineOptions options) {
     return _analyzeAllTag.makeCurrentWhile(() {
       if (options.buildModePersistentWorker) {
-        new AnalyzerWorkerLoop.std(dartSdkPath: options.dartSdkPath).run();
+        new AnalyzerWorkerLoop.std(resourceProvider,
+                dartSdkPath: options.dartSdkPath)
+            .run();
       } else {
-        return new BuildMode(options, stats).analyze();
+        return new BuildMode(resourceProvider, options, stats).analyze();
       }
     });
   }
@@ -338,8 +346,7 @@
       Map<file_system.Folder, YamlMap> embedderMap, _PackageInfo packageInfo) {
     // Create a custom package resolver if one has been specified.
     if (packageResolverProvider != null) {
-      file_system.Folder folder =
-          PhysicalResourceProvider.INSTANCE.getResource('.');
+      file_system.Folder folder = resourceProvider.getResource('.');
       UriResolver resolver = packageResolverProvider(folder);
       if (resolver != null) {
         UriResolver sdkResolver = new DartUriResolver(sdk);
@@ -348,7 +355,7 @@
         List<UriResolver> resolvers = <UriResolver>[
           sdkResolver,
           resolver,
-          new file_system.ResourceUriResolver(PhysicalResourceProvider.INSTANCE)
+          new file_system.ResourceUriResolver(resourceProvider)
         ];
         return new SourceFactory(resolvers);
       }
@@ -364,9 +371,8 @@
       if (packageInfo.packageMap == null) {
         // Fall back to pub list-package-dirs.
         PubPackageMapProvider pubPackageMapProvider =
-            new PubPackageMapProvider(PhysicalResourceProvider.INSTANCE, sdk);
-        file_system.Resource cwd =
-            PhysicalResourceProvider.INSTANCE.getResource('.');
+            new PubPackageMapProvider(resourceProvider, sdk);
+        file_system.Resource cwd = resourceProvider.getResource('.');
         PackageMapInfo packageMapInfo =
             pubPackageMapProvider.computePackageMap(cwd);
         Map<String, List<file_system.Folder>> packageMap =
@@ -376,8 +382,8 @@
         // 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);
+          packageUriResolver =
+              new PackageMapUriResolver(resourceProvider, packageMap);
         }
       }
     }
@@ -388,7 +394,7 @@
     // 'dart:' URIs come first.
 
     // Setup embedding.
-    EmbedderSdk embedderSdk = new EmbedderSdk(embedderMap);
+    EmbedderSdk embedderSdk = new EmbedderSdk(resourceProvider, embedderMap);
     if (embedderSdk.libraryMap.size() == 0) {
       // The embedder uri resolver has no mappings. Use the default Dart SDK
       // uri resolver.
@@ -410,8 +416,7 @@
     }
 
     // Finally files.
-    resolvers.add(
-        new file_system.ResourceUriResolver(PhysicalResourceProvider.INSTANCE));
+    resolvers.add(new file_system.ResourceUriResolver(resourceProvider));
 
     return new SourceFactory(resolvers, packageInfo.packages);
   }
@@ -475,7 +480,7 @@
 
     AnalyzeFunctionBodiesPredicate dietParsingPolicy =
         _chooseDietParsingPolicy(options);
-    setAnalysisContextOptions(_context, options,
+    setAnalysisContextOptions(resourceProvider, _context, options,
         (AnalysisOptionsImpl contextOptions) {
       contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy;
     });
@@ -523,7 +528,7 @@
   _PackageInfo _findPackages(CommandLineOptions options) {
     if (packageResolverProvider != null) {
       // The resolver provider will do all the work later.
-      return null;
+      return new _PackageInfo(null, null);
     }
 
     Packages packages;
@@ -546,8 +551,7 @@
       packageMap = _PackageRootPackageMapBuilder
           .buildPackageMap(options.packageRootPath);
     } else {
-      file_system.Resource cwd =
-          PhysicalResourceProvider.INSTANCE.getResource('.');
+      file_system.Resource cwd = resourceProvider.getResource('.');
       // Look for .packages.
       packages = _discoverPackagespec(new Uri.directory(cwd.path));
       packageMap = _getPackageMap(packages);
@@ -564,9 +568,7 @@
     Map<String, List<file_system.Folder>> folderMap =
         new Map<String, List<file_system.Folder>>();
     packages.asMap().forEach((String packagePath, Uri uri) {
-      folderMap[packagePath] = [
-        PhysicalResourceProvider.INSTANCE.getFolder(path.fromUri(uri))
-      ];
+      folderMap[packagePath] = [resourceProvider.getFolder(path.fromUri(uri))];
     });
     return folderMap;
   }
@@ -622,17 +624,17 @@
             options.dartSdkSummaryPath, options.strongMode);
       } else {
         String dartSdkPath = options.dartSdkPath;
-        DirectoryBasedDartSdk directorySdk = new DirectoryBasedDartSdk(
-            new JavaFile(dartSdkPath), options.strongMode);
-        directorySdk.useSummary = useSummaries &&
+        FolderBasedDartSdk dartSdk = new FolderBasedDartSdk(resourceProvider,
+            resourceProvider.getFolder(dartSdkPath), options.strongMode);
+        dartSdk.useSummary = useSummaries &&
             options.sourceFiles.every((String sourcePath) {
               sourcePath = path.absolute(sourcePath);
               sourcePath = path.normalize(sourcePath);
               return !path.isWithin(dartSdkPath, sourcePath);
             });
 
-        directorySdk.analysisOptions = context.analysisOptions;
-        sdk = directorySdk;
+        dartSdk.analysisOptions = context.analysisOptions;
+        sdk = dartSdk;
       }
     }
   }
@@ -648,10 +650,13 @@
     contextOptions.generateSdkErrors = options.showSdkWarnings;
     contextOptions.lint = options.lints;
     contextOptions.strongMode = options.strongMode;
+    contextOptions.implicitCasts = options.implicitCasts;
+    contextOptions.implicitDynamic = options.implicitDynamic;
     return contextOptions;
   }
 
   static void setAnalysisContextOptions(
+      file_system.ResourceProvider resourceProvider,
       AnalysisContext context,
       CommandLineOptions options,
       void configureContextOptions(AnalysisOptionsImpl contextOptions)) {
@@ -676,7 +681,7 @@
     context.analysisOptions = contextOptions;
 
     // Process analysis options file (and notify all interested parties).
-    _processAnalysisOptions(context, options);
+    _processAnalysisOptions(resourceProvider, context, options);
   }
 
   /// Perform a deep comparison of two string maps.
@@ -692,21 +697,23 @@
     return true;
   }
 
-  static file_system.File _getOptionsFile(CommandLineOptions options) {
+  static file_system.File _getOptionsFile(
+      file_system.ResourceProvider resourceProvider,
+      CommandLineOptions options) {
     file_system.File file;
     String filePath = options.analysisOptionsFile;
     if (filePath != null) {
-      file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+      file = resourceProvider.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);
+      file = resourceProvider.getFile(filePath);
       if (!file.exists) {
         filePath = AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
-        file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+        file = resourceProvider.getFile(filePath);
       }
     }
     return file;
@@ -717,8 +724,10 @@
       path.normalize(new File(sourcePath).absolute.path);
 
   static void _processAnalysisOptions(
-      AnalysisContext context, CommandLineOptions options) {
-    file_system.File file = _getOptionsFile(options);
+      file_system.ResourceProvider resourceProvider,
+      AnalysisContext context,
+      CommandLineOptions options) {
+    file_system.File file = _getOptionsFile(resourceProvider, options);
     List<OptionsProcessor> optionsProcessors =
         AnalysisEngine.instance.optionsPlugin.optionsProcessors;
     try {
@@ -770,15 +779,12 @@
         exitCode = batchResult.ordinal;
       }
       // Prepare arguments.
-      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');
-      }
+      var lineArgs = line.split(new RegExp('\\s+'));
+      var args = new List<String>();
+      args.addAll(sharedArgs);
+      args.addAll(lineArgs);
+      args.remove('-b');
+      args.remove('--batch');
       // Analyze single set of arguments.
       try {
         totalTests++;
diff --git a/pkg/analyzer_cli/lib/src/incremental_analyzer.dart b/pkg/analyzer_cli/lib/src/incremental_analyzer.dart
index d57327a..d7e9084 100644
--- a/pkg/analyzer_cli/lib/src/incremental_analyzer.dart
+++ b/pkg/analyzer_cli/lib/src/incremental_analyzer.dart
@@ -10,10 +10,10 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
 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/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/incremental_cache.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
@@ -35,7 +35,7 @@
   // If supported implementations, configure for incremental analysis.
   if (cachePath != null &&
       context is InternalAnalysisContext &&
-      sdk is DirectoryBasedDartSdk) {
+      sdk is FolderBasedDartSdk) {
     context.typeProvider = sdk.context.typeProvider;
     // Set the result provide from the cache.
     CacheStorage storage = new FolderCacheStorage(
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 3706464..2ad8bc4 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -150,6 +150,12 @@
   /// Whether to use strong static checking.
   final bool strongMode;
 
+  /// Whether implicit casts are enabled (in strong mode)
+  final bool implicitCasts;
+
+  /// Whether implicit dynamic is enabled (mainly for strong mode users)
+  final bool implicitDynamic;
+
   /// Whether to treat lints as fatal
   final bool lintsAreFatal;
 
@@ -160,7 +166,7 @@
         buildMode = args['build-mode'],
         buildModePersistentWorker = args['persistent_worker'],
         buildSummaryFallback = args['build-summary-fallback'],
-        buildSummaryInputs = args['build-summary-input'],
+        buildSummaryInputs = args['build-summary-input'] as List<String>,
         buildSummaryOnly = args['build-summary-only'],
         buildSummaryOnlyAst = args['build-summary-only-ast'],
         buildSummaryOnlyDiet = args['build-summary-only-diet'],
@@ -197,6 +203,8 @@
         sourceFiles = args.rest,
         warningsAreFatal = args['fatal-warnings'],
         strongMode = args['strong'],
+        implicitCasts = !args['no-implicit-casts'],
+        implicitDynamic = !args['no-implicit-dynamic'],
         lintsAreFatal = args['fatal-lints'];
 
   /// Parse [args] into [CommandLineOptions] describing the specified
@@ -478,7 +486,13 @@
           negatable: false,
           hide: true)
       ..addFlag('strong',
-          help: 'Enable strong static checks (https://goo.gl/DqcBsw)');
+          help: 'Enable strong static checks (https://goo.gl/DqcBsw)')
+      ..addFlag('no-implicit-casts',
+          negatable: false,
+          help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40)')
+      ..addFlag('no-implicit-dynamic',
+          negatable: false,
+          help: 'Disable implicit dynamic (https://goo.gl/m0UgXD)');
 
     try {
       // TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 4e45320..a19fecb 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -11,7 +11,7 @@
   bazel_worker: ^0.1.0
   cli_util: ^0.0.1
   linter: ^0.1.16
-  package_config: ^0.1.5
+  package_config: '>=0.1.5 <2.0.0'
   plugin: '>=0.1.0 <0.3.0'
   protobuf: ^0.5.0
   yaml: ^2.1.2
diff --git a/pkg/analyzer_cli/test/build_mode_test.dart b/pkg/analyzer_cli/test/build_mode_test.dart
index 9c88a0f..5e16d95 100644
--- a/pkg/analyzer_cli/test/build_mode_test.dart
+++ b/pkg/analyzer_cli/test/build_mode_test.dart
@@ -4,6 +4,7 @@
 
 library analyzer_cli.test.built_mode;
 
+import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer_cli/src/build_mode.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/options.dart';
@@ -17,6 +18,25 @@
   defineReflectiveTests(WorkerLoopTest);
 }
 
+typedef void _TestWorkerLoopAnalyze(CommandLineOptions options);
+
+/**
+ * [AnalyzerWorkerLoop] for testing.
+ */
+class TestAnalyzerWorkerLoop extends AnalyzerWorkerLoop {
+  final _TestWorkerLoopAnalyze _analyze;
+
+  TestAnalyzerWorkerLoop(SyncWorkerConnection connection, [this._analyze])
+      : super(new MemoryResourceProvider(), connection);
+
+  @override
+  void analyze(CommandLineOptions options) {
+    if (_analyze != null) {
+      _analyze(options);
+    }
+  }
+}
+
 @reflectiveTest
 class WorkerLoopTest {
   final TestStdinSync stdinStream = new TestStdinSync();
@@ -30,16 +50,6 @@
 
   void setUp() {}
 
-  List<int> _serializeProto(GeneratedMessage message) {
-    var buffer = message.writeToBuffer();
-
-    var writer = new CodedBufferWriter();
-    writer.writeInt32NoTag(buffer.length);
-    writer.writeRawBytes(buffer);
-
-    return writer.toBuffer();
-  }
-
   test_run() {
     var request = new WorkRequest();
     request.arguments.addAll([
@@ -119,23 +129,14 @@
     stdinStream.close();
     new TestAnalyzerWorkerLoop(connection).run();
   }
-}
 
-typedef void _TestWorkerLoopAnalyze(CommandLineOptions options);
+  List<int> _serializeProto(GeneratedMessage message) {
+    var buffer = message.writeToBuffer();
 
-/**
- * [AnalyzerWorkerLoop] for testing.
- */
-class TestAnalyzerWorkerLoop extends AnalyzerWorkerLoop {
-  final _TestWorkerLoopAnalyze _analyze;
+    var writer = new CodedBufferWriter();
+    writer.writeInt32NoTag(buffer.length);
+    writer.writeRawBytes(buffer);
 
-  TestAnalyzerWorkerLoop(SyncWorkerConnection connection, [this._analyze])
-      : super(connection);
-
-  @override
-  void analyze(CommandLineOptions options) {
-    if (_analyze != null) {
-      _analyze(options);
-    }
+    return writer.toBuffer();
   }
 }
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index e549603..58b5c1a 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -518,7 +518,7 @@
 }
 
 class TestProcessor extends OptionsProcessor {
-  Map<String, YamlNode> options;
+  Map<String, Object> options;
   Exception exception;
 
   @override
@@ -527,8 +527,7 @@
   }
 
   @override
-  void optionsProcessed(
-      AnalysisContext context, Map<String, YamlNode> options) {
+  void optionsProcessed(AnalysisContext context, Map<String, Object> options) {
     this.options = options;
   }
 }
diff --git a/pkg/analyzer_cli/test/embedder_test.dart b/pkg/analyzer_cli/test/embedder_test.dart
index 5a57c2d..93bbaf5 100644
--- a/pkg/analyzer_cli/test/embedder_test.dart
+++ b/pkg/analyzer_cli/test/embedder_test.dart
@@ -4,7 +4,8 @@
 
 import 'dart:io';
 
-import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
 import 'package:path/path.dart' as path;
 import 'package:unittest/unittest.dart';
@@ -52,8 +53,9 @@
         path.join(testDir, 'embedder_yaml_user.dart')
       ]);
 
-      DirectoryBasedDartSdk sdk = driver.sdk;
-      expect(sdk.useSummary, false);
+      DartSdk sdk = driver.sdk;
+      expect(sdk, new isInstanceOf<FolderBasedDartSdk>());
+      expect((sdk as FolderBasedDartSdk).useSummary, isFalse);
     }));
   });
 }
diff --git a/pkg/analyzer_cli/test/sdk_ext_test.dart b/pkg/analyzer_cli/test/sdk_ext_test.dart
index 1376d46..3eb5c62 100644
--- a/pkg/analyzer_cli/test/sdk_ext_test.dart
+++ b/pkg/analyzer_cli/test/sdk_ext_test.dart
@@ -7,7 +7,8 @@
 
 import 'dart:io';
 
-import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
 import 'package:analyzer_cli/src/options.dart';
 import 'package:path/path.dart' as path;
@@ -46,8 +47,9 @@
           path.join(testDir, 'sdk_ext_user.dart')
         ]);
 
-      DirectoryBasedDartSdk sdk = driver.sdk;
-      expect(sdk.useSummary, isFalse);
+      DartSdk sdk = driver.sdk;
+      expect(sdk, new isInstanceOf<FolderBasedDartSdk>());
+      expect((sdk as FolderBasedDartSdk).useSummary, isFalse);
 
       expect(exitCode, 0);
     });
diff --git a/pkg/compiler/bin/resolver.dart b/pkg/compiler/bin/resolver.dart
index aa70e4d..d5b56da 100644
--- a/pkg/compiler/bin/resolver.dart
+++ b/pkg/compiler/bin/resolver.dart
@@ -6,12 +6,11 @@
 
 import 'package:args/args.dart';
 import 'package:compiler/src/apiimpl.dart';
-import 'package:compiler/src/dart2js.dart';
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/null_compiler_output.dart';
-import 'package:compiler/src/source_file_provider.dart';
 import 'package:compiler/src/options.dart';
 import 'package:compiler/src/serialization/json_serializer.dart';
+import 'package:compiler/src/source_file_provider.dart';
 import 'package:package_config/discovery.dart';
 
 main(var argv) async {
@@ -19,6 +18,8 @@
   parser.addOption('deps', abbr: 'd', allowMultiple: true);
   parser.addOption('out', abbr: 'o');
   parser.addOption('library-root', abbr: 'l');
+  parser.addOption('packages', abbr: 'p');
+  parser.addOption('bazel-paths', abbr: 'I', allowMultiple: true);
   var args = parser.parse(argv);
 
   var resolutionInputs = args['deps']
@@ -28,18 +29,32 @@
   var libraryRoot = root == null
       ? Platform.script.resolve('../../../sdk/')
       : currentDirectory.resolve(nativeToUriPath(root));
+
   var options = new CompilerOptions(
       libraryRoot: libraryRoot,
+      packageConfig: args['packages'] == null
+          ? null
+          : currentDirectory.resolve(args['packages']),
       resolveOnly: true,
       resolutionInputs: resolutionInputs,
       packagesDiscoveryProvider: findPackages);
-  var inputProvider = new CompilerSourceFileProvider();
-  var outputProvider = const NullCompilerOutput();
-  var diagnostics = new FormattingDiagnosticHandler(inputProvider);
 
+  var bazelSearchPaths = args['bazel-paths'];
+  var inputProvider = bazelSearchPaths != null
+      ? new BazelInputProvider(bazelSearchPaths)
+      : new CompilerSourceFileProvider();
+
+  var outputProvider = const NullCompilerOutput();
+  var diagnostics = new FormattingDiagnosticHandler(inputProvider)
+    ..enableColors = true;
   var compiler =
       new CompilerImpl(inputProvider, outputProvider, diagnostics, options);
 
+  if (args.rest.isEmpty) {
+    print('missing input files');
+    exit(1);
+  }
+
   var inputs = args.rest
       .map((uri) => currentDirectory.resolve(nativeToUriPath(uri)))
       .toList();
diff --git a/pkg/compiler/lib/compiler.dart b/pkg/compiler/lib/compiler.dart
index 11e99b3..e030673 100644
--- a/pkg/compiler/lib/compiler.dart
+++ b/pkg/compiler/lib/compiler.dart
@@ -5,10 +5,12 @@
 library compiler;
 
 import 'dart:async';
+
 import 'package:package_config/packages.dart';
+
 import 'compiler_new.dart' as new_api;
-import 'src/options.dart' show CompilerOptions;
 import 'src/old_to_new_api.dart';
+import 'src/options.dart' show CompilerOptions;
 
 // Unless explicitly allowed, passing [:null:] for any argument to the
 // methods of library will result in an Error being thrown.
diff --git a/pkg/compiler/lib/compiler_new.dart b/pkg/compiler/lib/compiler_new.dart
index 51de3810..5ba94cb 100644
--- a/pkg/compiler/lib/compiler_new.dart
+++ b/pkg/compiler/lib/compiler_new.dart
@@ -8,10 +8,11 @@
 library compiler_new;
 
 import 'dart:async';
+
+import 'compiler.dart' show Diagnostic;
 import 'src/apiimpl.dart';
 import 'src/options.dart' show CompilerOptions;
 
-import 'compiler.dart' show Diagnostic;
 export 'compiler.dart' show Diagnostic, PackagesDiscoveryProvider;
 
 // Unless explicitly allowed, passing `null` for any argument to the
@@ -39,9 +40,9 @@
 /// files, source map files, dump info files, etc.
 abstract class CompilerOutput {
   /// Returns an [EventSink] that will serve as compiler output for the given
-  ///  component.
+  /// component.
   ///
-  ///  Components are identified by [name] and [extension]. By convention,
+  /// Components are identified by [name] and [extension]. By convention,
   /// the empty string [:"":] will represent the main script
   /// (corresponding to the script parameter of [compile]) even if the
   /// main script is a library. For libraries that are compiled
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 98d931a..3bddb9b 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -5,7 +5,6 @@
 library leg_apiimpl;
 
 import 'dart:async';
-import 'dart:convert';
 
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart' as pkgs;
@@ -16,7 +15,6 @@
 import '../compiler_new.dart' as api;
 import 'common/tasks.dart' show GenericTask, Measurer;
 import 'common.dart';
-import 'common/backend_api.dart' show Backend;
 import 'compiler.dart';
 import 'diagnostics/messages.dart' show Message;
 import 'elements/elements.dart' as elements;
@@ -26,7 +24,6 @@
 import 'platform_configuration.dart' as platform_configuration;
 import 'resolved_uri_translator.dart';
 import 'script.dart';
-import 'serialization/system.dart';
 
 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the
 /// sources.
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index b0f01b8..7b71e69 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -4,23 +4,23 @@
 
 library closureToClassMapper;
 
-import 'common.dart';
 import 'common/names.dart' show Identifiers;
 import 'common/resolution.dart' show ParsingContext, Resolution;
 import 'common/tasks.dart' show CompilerTask;
+import 'common.dart';
 import 'compiler.dart' show Compiler;
 import 'constants/expressions.dart';
 import 'dart_types.dart';
 import 'elements/elements.dart';
 import 'elements/modelx.dart'
-    show BaseFunctionElementX, ClassElementX, ElementX, LocalFunctionElementX;
+    show BaseFunctionElementX, ClassElementX, ElementX;
 import 'elements/visitor.dart' show ElementVisitor;
 import 'js_backend/js_backend.dart' show JavaScriptBackend;
 import 'resolution/tree_elements.dart' show TreeElements;
 import 'tokens/token.dart' show Token;
 import 'tree/tree.dart';
-import 'util/util.dart';
 import 'universe/universe.dart' show Universe;
+import 'util/util.dart';
 
 class ClosureTask extends CompilerTask {
   Map<Node, ClosureClassMap> closureMappingCache;
@@ -255,6 +255,9 @@
   final String name;
   final ExecutableElement executableContext;
 
+  final int hashCode = _nextHashCode = (_nextHashCode + 10007).toUnsigned(30);
+  static int _nextHashCode = 0;
+
   BoxLocal(this.name, this.executableContext);
 
   String toString() => 'BoxLocal($name)';
@@ -326,7 +329,7 @@
 /// A local variable used encode the direct (uncaptured) references to [this].
 class ThisLocal extends Local {
   final ExecutableElement executableContext;
-  final hashCode = ++ElementX.elementHashCode;
+  final hashCode = ElementX.newHashCode();
 
   ThisLocal(this.executableContext);
 
@@ -1125,7 +1128,7 @@
   visitFunctionExpression(FunctionExpression node) {
     Element element = elements[node];
 
-    if (element.isParameter) {
+    if (element.isRegularParameter) {
       // TODO(ahe): This is a hack. This method should *not* call
       // visitChildren.
       return node.name.accept(this);
diff --git a/pkg/compiler/lib/src/code_organization.md b/pkg/compiler/lib/src/code_organization.md
new file mode 100644
index 0000000..8fea527
--- /dev/null
+++ b/pkg/compiler/lib/src/code_organization.md
@@ -0,0 +1,26 @@
+[comment]: WIP - code is being refactored...
+
+##General code organization of this pacakge
+
+  lib/src/
+    |- ...
+    |- universe/  - how we represent the closed-world semantics of a program.
+
+[comment]: TODO fill in the rest
+
+
+##Details
+
+### Universe
+[comment]: TODO rename universe => world
+[comment]: TODO consider merging feature.dart and use.dart
+
+How we represent the closed-world semantics of a program.
+
+universe/
+ |- feature.dart - Features that may be used in the program. Using a feature
+ |                 pulls in special code that the compiler needs to support it.
+ |- use.dart     - Describes a use of an element (a method, a class) and how it
+ |                 is used by the program.
+
+
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index bf08051..52c7cf3 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -44,7 +44,6 @@
   static const String trustJSInteropTypeAnnotations =
       '--experimental-trust-js-interop-type-annotations';
   static const String useContentSecurityPolicy = '--csp';
-  static const String useCpsIr = '--use-cps-ir';
   static const String useNewSourceInfo = '--use-new-source-info';
   static const String verbose = '--verbose';
   static const String version = '--version';
@@ -74,4 +73,5 @@
 
   // Experimental options.
   static const String resolutionInput = '--resolution-input=.+';
+  static const String bazelPaths = '--bazel-paths=.+';
 }
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index c4c9020..5582734 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -17,15 +17,8 @@
 import '../constants/values.dart' show ConstantValue;
 import '../dart_types.dart' show DartType, InterfaceType;
 import '../elements/elements.dart'
-    show
-        ClassElement,
-        Element,
-        FunctionElement,
-        LibraryElement,
-        MetadataAnnotation,
-        MethodElement;
-import '../enqueue.dart'
-    show Enqueuer, EnqueueTask, CodegenEnqueuer, ResolutionEnqueuer;
+    show ClassElement, Element, FunctionElement, LibraryElement;
+import '../enqueue.dart' show Enqueuer, EnqueueTask, 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;
@@ -36,8 +29,7 @@
     show checkNativeAnnotation, checkJsInteropAnnotation;
 import '../serialization/serialization.dart'
     show DeserializerPlugin, SerializerPlugin;
-import '../tree/tree.dart' show Node, Send;
-import '../universe/call_structure.dart' show CallStructure;
+import '../tree/tree.dart' show Node;
 import '../universe/world_impact.dart' show ImpactStrategy, WorldImpact;
 import 'codegen.dart' show CodegenWorkItem;
 import 'registry.dart' show Registry;
@@ -52,9 +44,6 @@
   /// Returns true if the backend supports reflection.
   bool get supportsReflection;
 
-  /// Returns true if the backend supports reflection.
-  bool get supportsAsyncAwait;
-
   /// The [ConstantSystem] used to interpret compile-time constants for this
   /// backend.
   ConstantSystem get constantSystem;
@@ -229,14 +218,6 @@
 
   bool isInterceptorClass(ClassElement element) => false;
 
-  /// Returns `true` if [element] is a foreign element, that is, that the
-  /// backend has specialized handling for the element.
-  bool isForeign(Element element) => false;
-
-  /// Returns `true` if [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;
@@ -247,10 +228,6 @@
     return native.maybeEnableNative(compiler, library);
   }
 
-  /// Processes [element] for resolution and returns the [MethodElement] that
-  /// defines the implementation of [element].
-  MethodElement resolveExternalFunction(MethodElement element) => element;
-
   @override
   bool isTargetSpecificLibrary(LibraryElement library) {
     // TODO(johnniwinther): Remove this when patching is only done by the
@@ -375,12 +352,6 @@
   void registerAsyncMarker(
       FunctionElement element, Enqueuer enqueuer, Registry registry) {}
 
-  /// Called when resolving a call to a foreign function. If a non-null value
-  /// is returned, this is stored as native data for [node] in the resolved
-  /// AST.
-  dynamic resolveForeignCall(Send node, Element element,
-      CallStructure callStructure, ForeignResolver resolver) {}
-
   /// Returns the location of the patch-file associated with [libraryName]
   /// resolved from [plaformConfigUri].
   ///
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 8a26860..cee2fcb 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -4,7 +4,6 @@
 
 library dart2js.common.codegen;
 
-import '../closure.dart' show SynthesizedCallMethodElementX;
 import '../common.dart';
 import '../compiler.dart' show Compiler;
 import '../constants/values.dart' show ConstantValue;
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 515aa68..42f7b32 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -5,29 +5,38 @@
 library dart2js.common.resolution;
 
 import '../common.dart';
+import '../compile_time_constants.dart';
 import '../compiler.dart' show Compiler;
 import '../constants/expressions.dart' show ConstantExpression;
+import '../constants/values.dart' show ConstantValue;
 import '../core_types.dart' show CoreClasses, CoreTypes;
-import '../dart_types.dart' show DartType, InterfaceType, Types;
+import '../dart_types.dart' show DartType, Types;
 import '../elements/elements.dart'
     show
         AstElement,
         ClassElement,
+        ConstructorElement,
         Element,
         ExecutableElement,
         FunctionElement,
         FunctionSignature,
         LibraryElement,
         MetadataAnnotation,
+        MethodElement,
         ResolvedAst,
         TypedefElement;
 import '../enqueue.dart' show ResolutionEnqueuer;
-import '../options.dart' show ParserOptions;
+import '../id_generator.dart';
+import '../mirrors_used.dart';
+import '../options.dart' show CompilerOptions, ParserOptions;
 import '../parser/element_listener.dart' show ScannerOptions;
 import '../parser/parser_task.dart';
 import '../patch_parser.dart';
-import '../tree/tree.dart' show TypeAnnotation;
+import '../resolution/resolution.dart';
+import '../tree/tree.dart' show Send, TypeAnnotation;
+import '../universe/call_structure.dart' show CallStructure;
 import '../universe/world_impact.dart' show WorldImpact;
+import '../universe/feature.dart';
 import 'backend_api.dart';
 import 'work.dart' show ItemCompilationContext, WorkItem;
 
@@ -55,139 +64,12 @@
   Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[];
   Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[];
   Iterable<String> get constSymbolNames => const <String>[];
-  Iterable<ConstantExpression> get constantLiterals {
-    return const <ConstantExpression>[];
-  }
+  Iterable<ConstantExpression> get constantLiterals =>
+      const <ConstantExpression>[];
 
   Iterable<dynamic> get nativeData => const <dynamic>[];
 }
 
-/// A language feature seen during resolution.
-// TODO(johnniwinther): Should mirror usage be part of this?
-enum Feature {
-  /// Invocation of a generative construction on an abstract class.
-  ABSTRACT_CLASS_INSTANTIATION,
-
-  /// An assert statement with no message.
-  ASSERT,
-
-  /// An assert statement with a message.
-  ASSERT_WITH_MESSAGE,
-
-  /// A method with an `async` body modifier.
-  ASYNC,
-
-  /// An asynchronous for in statement like `await for (var e in i) {}`.
-  ASYNC_FOR_IN,
-
-  /// A method with an `async*` body modifier.
-  ASYNC_STAR,
-
-  /// A catch statement.
-  CATCH_STATEMENT,
-
-  /// A compile time error.
-  COMPILE_TIME_ERROR,
-
-  /// A fall through in a switch case.
-  FALL_THROUGH_ERROR,
-
-  /// A ++/-- operation.
-  INC_DEC_OPERATION,
-
-  /// A field whose initialization is not a constant.
-  LAZY_FIELD,
-
-  /// A catch clause with a variable for the stack trace.
-  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,
-
-  /// A redirection to the `Symbol` constructor.
-  SYMBOL_CONSTRUCTOR,
-
-  /// An synchronous for in statement, like `for (var e in i) {}`.
-  SYNC_FOR_IN,
-
-  /// A method with a `sync*` body modifier.
-  SYNC_STAR,
-
-  /// A throw expression.
-  THROW_EXPRESSION,
-
-  /// An implicit throw of a `NoSuchMethodError`, like calling an unresolved
-  /// static method.
-  THROW_NO_SUCH_METHOD,
-
-  /// An implicit throw of a runtime error, like
-  THROW_RUNTIME_ERROR,
-
-  /// The need for a type variable bound check, like instantiation of a generic
-  /// type whose type variable have non-trivial bounds.
-  TYPE_VARIABLE_BOUNDS_CHECK,
-}
-
-/// A use of a map literal seen during resolution.
-class MapLiteralUse {
-  final InterfaceType type;
-  final bool isConstant;
-  final bool isEmpty;
-
-  MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
-
-  int get hashCode {
-    return type.hashCode * 13 +
-        isConstant.hashCode * 17 +
-        isEmpty.hashCode * 19;
-  }
-
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! MapLiteralUse) return false;
-    return type == other.type &&
-        isConstant == other.isConstant &&
-        isEmpty == other.isEmpty;
-  }
-
-  String toString() {
-    return 'MapLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)';
-  }
-}
-
-/// A use of a list literal seen during resolution.
-class ListLiteralUse {
-  final InterfaceType type;
-  final bool isConstant;
-  final bool isEmpty;
-
-  ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
-
-  int get hashCode {
-    return type.hashCode * 13 +
-        isConstant.hashCode * 17 +
-        isEmpty.hashCode * 19;
-  }
-
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! ListLiteralUse) return false;
-    return type == other.type &&
-        isConstant == other.isConstant &&
-        isEmpty == other.isEmpty;
-  }
-
-  String toString() {
-    return 'ListLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)';
-  }
-}
 
 /// Interface for the accessing the front-end analysis.
 // TODO(johnniwinther): Find a better name for this.
@@ -206,6 +88,32 @@
   /// Resolve target specific information for [element] and register it with
   /// [registry].
   void resolveNativeElement(Element element, NativeRegistry registry) {}
+
+  /// Processes [element] for resolution and returns the [MethodElement] that
+  /// defines the implementation of [element].
+  MethodElement resolveExternalFunction(MethodElement element) => element;
+
+  /// Called when resolving a call to a foreign function. If a non-null value
+  /// is returned, this is stored as native data for [node] in the resolved
+  /// AST.
+  dynamic resolveForeignCall(Send node, Element element,
+      CallStructure callStructure, ForeignResolver resolver) {
+    return null;
+  }
+
+  /// Returns the default superclass for the given [element] in this target.
+  ClassElement defaultSuperclass(ClassElement element);
+
+  /// 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 a foreign element, that is, that the
+  /// backend has specialized handling for the element.
+  bool isForeign(Element element) => false;
+
+  /// Returns `true` if this target supports async/await.
+  bool get supportsAsyncAwait => true;
 }
 
 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
@@ -216,6 +124,24 @@
   CoreTypes get coreTypes;
   Types get types;
   Target get target;
+  ResolverTask get resolver;
+  ResolutionEnqueuer get enqueuer;
+  CompilerOptions get options;
+  IdGenerator get idGenerator;
+  ConstantEnvironment get constants;
+  MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask;
+
+  // TODO(het): Move all elements into common/elements.dart
+  LibraryElement get coreLibrary;
+  FunctionElement get identicalFunction;
+  ClassElement get mirrorSystemClass;
+  FunctionElement get mirrorSystemGetNameFunction;
+  ConstructorElement get mirrorsUsedConstructor;
+  ConstructorElement get symbolConstructor;
+
+  // TODO(het): This is only referenced in a test...
+  /// The constant for the [proxy] variable defined in dart:core.
+  ConstantValue get proxyConstant;
 
   /// If set to `true` resolution caches will not be cleared. Use this only for
   /// testing.
@@ -237,6 +163,14 @@
   /// Resolve [element] if it has not already been resolved.
   void ensureResolved(Element element);
 
+  /// Called whenever a class has been resolved.
+  void onClassResolved(ClassElement element);
+
+  /// Registers that [element] has a compile time error.
+  ///
+  /// The error itself is given in [message].
+  void registerCompileTimeError(Element element, DiagnosticMessage message);
+
   ResolutionWorkItem createWorkItem(
       Element element, ItemCompilationContext compilationContext);
 
@@ -274,6 +208,10 @@
   void emptyCache();
 
   void forgetElement(Element element);
+
+  /// Returns `true` if [value] is the top-level [proxy] annotation from the
+  /// core library.
+  bool isProxyConstant(ConstantValue value);
 }
 
 /// A container of commonly used dependencies for tasks that involve parsing.
diff --git a/pkg/compiler/lib/src/common/tasks.dart b/pkg/compiler/lib/src/common/tasks.dart
index f1d3426..2c5d62c 100644
--- a/pkg/compiler/lib/src/common/tasks.dart
+++ b/pkg/compiler/lib/src/common/tasks.dart
@@ -20,6 +20,11 @@
 
   int asyncCount = 0;
 
+  // Each task has a fixed, lazily computed, ZoneSpecification and zoneValues
+  // for [_measureZoned].
+  ZoneSpecification _zoneSpecification;
+  Map _zoneValues;
+
   CompilerTask(Measurer measurer)
       : measurer = measurer,
         _watch = measurer.enableTaskMeasurements ? new Stopwatch() : null;
@@ -97,49 +102,49 @@
     // The current zone is already measuring `this` task.
     if (Zone.current[measurer] == this) return action();
 
-    /// Run [f] in [zone]. Running must be delegated to [parent] to ensure that
-    /// various state is set up correctly (in particular that `Zone.current`
-    /// has the right value). Since [_measureZoned] can be called recursively
-    /// (synchronously), some of the measuring zones we create will be parents
-    /// of other measuring zones, but we still need to call through the parent
-    /// chain. Consequently, we use a zone value keyed by [measurer] to see if
-    /// we should measure or not when delegating.
-    run(Zone self, ZoneDelegate parent, Zone zone, f()) {
-      if (zone[measurer] != this) return parent.run(zone, f);
-      CompilerTask previous = _start();
-      try {
-        return parent.run(zone, f);
-      } finally {
-        _stop(previous);
-      }
-    }
-
-    /// Same as [run] except that [f] takes one argument, [arg].
-    runUnary(Zone self, ZoneDelegate parent, Zone zone, f(arg), arg) {
-      if (zone[measurer] != this) return parent.runUnary(zone, f, arg);
-      CompilerTask previous = _start();
-      try {
-        return parent.runUnary(zone, f, arg);
-      } finally {
-        _stop(previous);
-      }
-    }
-
-    /// Same as [run] except that [f] takes two arguments ([a1] and [a2]).
-    runBinary(Zone self, ZoneDelegate parent, Zone zone, f(a1, a2), a1, a2) {
-      if (zone[measurer] != this) return parent.runBinary(zone, f, a1, a2);
-      CompilerTask previous = _start();
-      try {
-        return parent.runBinary(zone, f, a1, a2);
-      } finally {
-        _stop(previous);
-      }
-    }
-
     return runZoned(action,
-        zoneValues: {measurer: this},
-        zoneSpecification: new ZoneSpecification(
-            run: run, runUnary: runUnary, runBinary: runBinary));
+        zoneValues: _zoneValues ??= {measurer: this},
+        zoneSpecification: _zoneSpecification ??= new ZoneSpecification(
+            run: _run, runUnary: _runUnary, runBinary: _runBinary));
+  }
+
+  /// Run [f] in [zone]. Running must be delegated to [parent] to ensure that
+  /// various state is set up correctly (in particular that `Zone.current`
+  /// has the right value). Since [_measureZoned] can be called recursively
+  /// (synchronously), some of the measuring zones we create will be parents
+  /// of other measuring zones, but we still need to call through the parent
+  /// chain. Consequently, we use a zone value keyed by [measurer] to see if
+  /// we should measure or not when delegating.
+  _run(Zone self, ZoneDelegate parent, Zone zone, f()) {
+    if (zone[measurer] != this) return parent.run(zone, f);
+    CompilerTask previous = _start();
+    try {
+      return parent.run(zone, f);
+    } finally {
+      _stop(previous);
+    }
+  }
+
+  /// Same as [run] except that [f] takes one argument, [arg].
+  _runUnary(Zone self, ZoneDelegate parent, Zone zone, f(arg), arg) {
+    if (zone[measurer] != this) return parent.runUnary(zone, f, arg);
+    CompilerTask previous = _start();
+    try {
+      return parent.runUnary(zone, f, arg);
+    } finally {
+      _stop(previous);
+    }
+  }
+
+  /// Same as [run] except that [f] takes two arguments ([a1] and [a2]).
+  _runBinary(Zone self, ZoneDelegate parent, Zone zone, f(a1, a2), a1, a2) {
+    if (zone[measurer] != this) return parent.runBinary(zone, f, a1, a2);
+    CompilerTask previous = _start();
+    try {
+      return parent.runBinary(zone, f, a1, a2);
+    } finally {
+      _stop(previous);
+    }
   }
 
   /// Asynchronous version of [measure]. Use this when action returns a future
@@ -211,6 +216,9 @@
   /// Whether measurement of tasks is enabled.
   final bool enableTaskMeasurements;
 
+  static int _hashCodeGenerator = 197;
+  final int hashCode = _hashCodeGenerator++;
+
   Measurer({this.enableTaskMeasurements: false});
 
   /// The currently running task, that is, the task whose [Stopwatch] is
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 1c066ed..bda354e2 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -4,9 +4,9 @@
 
 library dart2js.compile_time_constant_evaluator;
 
-import 'common.dart';
 import 'common/resolution.dart' show Resolution;
 import 'common/tasks.dart' show CompilerTask, Measurer;
+import 'common.dart';
 import 'compiler.dart' show Compiler;
 import 'constant_system_dart.dart';
 import 'constants/constant_system.dart';
@@ -16,13 +16,12 @@
 import 'core_types.dart' show CoreTypes;
 import 'dart_types.dart';
 import 'elements/elements.dart';
-import 'elements/modelx.dart'
-    show FieldElementX, FunctionElementX, ConstantVariableMixin;
-import 'resolution/tree_elements.dart' show TreeElements;
+import 'elements/modelx.dart' show ConstantVariableMixin;
 import 'resolution/operators.dart';
+import 'resolution/tree_elements.dart' show TreeElements;
 import 'tree/tree.dart';
-import 'util/util.dart' show Link;
 import 'universe/call_structure.dart' show CallStructure;
+import 'util/util.dart' show Link;
 
 /// A [ConstantEnvironment] provides access for constants compiled for variable
 /// initializers.
@@ -861,6 +860,7 @@
       return new AstConstant.fromDefaultValue(
           element, constant, handler.getConstantValue(constant));
     }
+
     target.computeType(resolution);
 
     FunctionSignature signature = target.functionSignature;
@@ -965,6 +965,16 @@
     if (constructor.isFromEnvironmentConstructor) {
       return createFromEnvironmentConstant(node, constructedType, constructor,
           callStructure, normalizedArguments, concreteArguments);
+    } else if (compiler.serialization.isDeserialized(constructor)) {
+      ConstructedConstantExpression expression =
+          new ConstructedConstantExpression(type, constructor, callStructure,
+              concreteArguments.map((c) => c.expression).toList());
+      return new AstConstant(
+          context,
+          node,
+          expression,
+          expression.evaluate(
+              new _CompilerEnvironment(compiler), constantSystem));
     } else {
       return makeConstructedConstant(
           compiler,
@@ -1089,7 +1099,7 @@
       List<AstConstant> concreteArguments,
       List<AstConstant> normalizedArguments) {
     if (target.isRedirectingFactory) {
-      // This happens is case of cyclic redirection.
+      // This happens in case of cyclic redirection.
       assert(invariant(node, compiler.compilationFailed,
           message: "makeConstructedConstant can only be called with the "
               "effective target: $constructor"));
@@ -1163,8 +1173,11 @@
    *
    * Invariant: [constructor] must be an implementation element.
    */
-  ConstructorEvaluator(InterfaceType this.constructedType,
-      FunctionElement constructor, ConstantCompiler handler, Compiler compiler)
+  ConstructorEvaluator(
+      InterfaceType this.constructedType,
+      ConstructorElement constructor,
+      ConstantCompiler handler,
+      Compiler compiler)
       : this.constructor = constructor,
         this.definitions = new Map<Element, AstConstant>(),
         this.fieldValues = new Map<Element, AstConstant>(),
@@ -1175,6 +1188,9 @@
   }
 
   @override
+  Element get context => resolvedAst.element;
+
+  @override
   TreeElements get elements => resolvedAst.elements;
 
   AstConstant visitSend(Send send) {
@@ -1234,18 +1250,33 @@
     });
   }
 
-  void evaluateSuperOrRedirectSend(
-      List<AstConstant> compiledArguments, FunctionElement targetConstructor) {
-    ConstructorEvaluator evaluator = new ConstructorEvaluator(
-        constructedType.asInstanceOf(targetConstructor.enclosingClass),
-        targetConstructor,
-        handler,
-        compiler);
-    evaluator.evaluateConstructorFieldValues(compiledArguments);
-    // Copy over the fieldValues from the super/redirect-constructor.
-    // No need to go through [updateFieldValue] because the
-    // assignments have already been checked in checked mode.
-    evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
+  void evaluateSuperOrRedirectSend(List<AstConstant> compiledArguments,
+      CallStructure callStructure, ConstructorElement targetConstructor) {
+    InterfaceType type =
+        constructedType.asInstanceOf(targetConstructor.enclosingClass);
+    if (compiler.serialization.isDeserialized(targetConstructor)) {
+      List<ConstantExpression> arguments =
+          compiledArguments.map((c) => c.expression).toList();
+      ConstructedConstantExpression expression =
+          new ConstructedConstantExpression(
+              type, targetConstructor, callStructure, arguments);
+
+      Map<FieldElement, ConstantExpression> fields =
+          expression.computeInstanceFields();
+      fields.forEach((FieldElement field, ConstantExpression expression) {
+        ConstantValue value = expression.evaluate(
+            new _CompilerEnvironment(compiler), constantSystem);
+        fieldValues[field] = new AstConstant(context, null, expression, value);
+      });
+    } else {
+      ConstructorEvaluator evaluator =
+          new ConstructorEvaluator(type, targetConstructor, handler, compiler);
+      evaluator.evaluateConstructorFieldValues(compiledArguments);
+      // Copy over the fieldValues from the super/redirect-constructor.
+      // No need to go through [updateFieldValue] because the
+      // assignments have already been checked in checked mode.
+      evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
+    }
   }
 
   /**
@@ -1262,7 +1293,9 @@
       FunctionElement target = constructor.definingConstructor.implementation;
       CallStructure.addForwardingElementArgumentsToList(constructor,
           compiledArguments, target, compileArgument, compileConstant);
-      evaluateSuperOrRedirectSend(compiledArguments, target);
+      CallStructure callStructure =
+          new CallStructure.fromSignature(target.functionSignature);
+      evaluateSuperOrRedirectSend(compiledArguments, callStructure, target);
       return;
     }
     FunctionExpression functionNode = resolvedAst.node;
@@ -1280,14 +1313,14 @@
           Send call = link.head;
           FunctionElement target = elements[call];
           if (!target.isMalformed) {
+            CallStructure callStructure =
+                elements.getSelector(call).callStructure;
             List<AstConstant> compiledArguments =
                 evaluateArgumentsToConstructor(
-                    call,
-                    elements.getSelector(call).callStructure,
-                    call.arguments,
-                    target,
+                    call, callStructure, call.arguments, target,
                     compileArgument: evaluateConstant);
-            evaluateSuperOrRedirectSend(compiledArguments, target);
+            evaluateSuperOrRedirectSend(
+                compiledArguments, callStructure, target);
           }
           foundSuperOrRedirect = true;
         } else {
@@ -1315,12 +1348,14 @@
         // If we do not find a default constructor, an error was reported
         // already and compilation will fail anyway. So just ignore that case.
         if (targetConstructor != null) {
+          CallStructure callStructure = CallStructure.NO_ARGS;
           List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
               functionNode,
-              CallStructure.NO_ARGS,
+              callStructure,
               const Link<Node>(),
               targetConstructor);
-          evaluateSuperOrRedirectSend(compiledArguments, targetConstructor);
+          evaluateSuperOrRedirectSend(
+              compiledArguments, callStructure, targetConstructor);
         }
       }
     }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index d567bba..cf4e215 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -27,7 +27,6 @@
 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 DartType, DynamicType, InterfaceType, Types;
 import 'deferred_load.dart' show DeferredLoadTask;
 import 'diagnostics/code_location.dart';
@@ -166,9 +165,6 @@
 
   ClassElement typedDataClass;
 
-  /// The constant for the [proxy] variable defined in dart:core.
-  ConstantValue proxyConstant;
-
   // TODO(johnniwinther): Move this to the JavaScriptBackend.
   /// The class for patch annotation defined in dart:_js_helper.
   ClassElement patchAnnotationClass;
@@ -203,8 +199,6 @@
   // Initialized when dart:mirrors is loaded.
   ClassElement deferredLibraryClass;
 
-  /// Document class from dart:mirrors.
-  ClassElement documentClass;
   Element identicalFunction;
   Element loadLibraryFunction;
   Element functionApplyMethod;
@@ -305,19 +299,13 @@
 
     if (makeBackend != null) {
       backend = makeBackend(this);
-    } else if (options.emitJavaScript) {
+    } else {
       js_backend.JavaScriptBackend jsBackend = new js_backend.JavaScriptBackend(
           this,
           generateSourceMap: options.generateSourceMap,
           useStartupEmitter: options.useStartupEmitter,
           useNewSourceInfo: options.useNewSourceInfo);
       backend = jsBackend;
-    } else {
-      backend = new dart_backend.DartBackend(this, options.strips,
-          multiFile: options.dart2dartMultiFile);
-      if (options.dumpInfo) {
-        throw new ArgumentError('--dump-info is not supported for dart2dart.');
-      }
     }
 
     if (options.dumpInfo && options.useStartupEmitter) {
@@ -332,7 +320,8 @@
       serialization = new SerializationTask(this),
       libraryLoader = new LibraryLoaderTask(
           resolvedUriTranslator,
-          new _ScriptLoader(this),
+          options.compileOnly
+              ? new _NoScriptLoader(this) : new _ScriptLoader(this),
           new _ElementScanner(scanner),
           serialization,
           this,
@@ -373,7 +362,8 @@
   ///
   /// Override this to mock the resolver for testing.
   ResolverTask createResolverTask() {
-    return new ResolverTask(this, backend.constantCompilerTask);
+    return new ResolverTask(
+        resolution, backend.constantCompilerTask, world, measurer);
   }
 
   Universe get resolverWorld => enqueuer.resolution.universe;
@@ -386,6 +376,8 @@
   bool get disableTypeInference =>
       options.disableTypeInference || compilationFailed;
 
+  // TODO(het): remove this from here. Either inline at all use sites or add it
+  // to Reporter.
   void unimplemented(Spannable spannable, String methodName) {
     reporter.internalError(spannable, "$methodName not implemented.");
   }
@@ -570,28 +562,9 @@
       coreClasses.functionClass.ensureResolved(resolution);
       functionApplyMethod =
           coreClasses.functionClass.lookupLocalMember('apply');
-
-      if (options.preserveComments) {
-        return libraryLoader
-            .loadLibrary(Uris.dart_mirrors)
-            .then((LibraryElement libraryElement) {
-          documentClass = libraryElement.find('Comment');
-        });
-      }
     }).then((_) => backend.onLibrariesLoaded(loadedLibraries));
   }
 
-  bool isProxyConstant(ConstantValue value) {
-    FieldElement field = coreLibrary.find('proxy');
-    if (field == null) return false;
-    if (!resolution.hasBeenResolved(field)) return false;
-    if (proxyConstant == null) {
-      proxyConstant = constants
-          .getConstantValue(resolver.constantCompiler.compileConstant(field));
-    }
-    return proxyConstant == value;
-  }
-
   Element findRequiredElement(LibraryElement library, String name) {
     var element = library.find(name);
     if (element == null) {
@@ -626,6 +599,7 @@
       }
       return result;
     }
+
     _coreTypes.objectClass = lookupCoreClass('Object');
     _coreTypes.boolClass = lookupCoreClass('bool');
     _coreTypes.numClass = lookupCoreClass('num');
@@ -851,7 +825,7 @@
           }
         }
 
-        if (options.resolveOnly) {
+        if (options.resolveOnly && !compilationFailed) {
           reporter.log('Serializing to ${options.resolutionOutput}');
           serialization
               .serializeToSink(userOutputProvider.createEventSink('', 'data'),
@@ -919,6 +893,7 @@
     void enqueueAll(Element element) {
       fullyEnqueueTopLevelElement(element, world);
     }
+
     library.implementation.forEachLocalMember(enqueueAll);
     library.imports.forEach((ImportElement import) {
       if (import.isDeferred) {
@@ -1129,7 +1104,7 @@
     if (markCompilationAsFailed(message, kind)) {
       compilationFailed = true;
     }
-    registerCompiletimeError(currentElement, message);
+    registerCompileTimeError(currentElement, message);
   }
 
   /**
@@ -1174,6 +1149,7 @@
         }
       }
     }
+
     libraryLoader.libraries.forEach((LibraryElement library) {
       // TODO(ahe): Implement better heuristics to discover entry points of
       // packages and use that to discover unused implementation details in
@@ -1272,7 +1248,7 @@
   }
 
   /// Associate [element] with a compile-time error [message].
-  void registerCompiletimeError(Element element, DiagnosticMessage message) {
+  void registerCompileTimeError(Element element, DiagnosticMessage message) {
     // The information is only needed if [generateCodeWithCompileTimeErrors].
     if (options.generateCodeWithCompileTimeErrors) {
       if (element == null) {
@@ -1553,7 +1529,7 @@
       } else {
         errorElement = currentElement;
       }
-      compiler.registerCompiletimeError(errorElement, message);
+      compiler.registerCompileTimeError(errorElement, message);
       compiler.fatalDiagnosticReported(message, infos, kind);
     }
   }
@@ -1906,6 +1882,48 @@
   Target get target => compiler.backend;
 
   @override
+  ResolverTask get resolver => compiler.resolver;
+
+  @override
+  ResolutionEnqueuer get enqueuer => compiler.enqueuer.resolution;
+
+  @override
+  CompilerOptions get options => compiler.options;
+
+  @override
+  IdGenerator get idGenerator => compiler.idGenerator;
+
+  @override
+  ConstantEnvironment get constants => compiler.constants;
+
+  @override
+  MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask =>
+      compiler.mirrorUsageAnalyzerTask;
+
+  @override
+  LibraryElement get coreLibrary => compiler.coreLibrary;
+
+  @override
+  FunctionElement get identicalFunction => compiler.identicalFunction;
+
+  @override
+  ClassElement get mirrorSystemClass => compiler.mirrorSystemClass;
+
+  @override
+  FunctionElement get mirrorSystemGetNameFunction =>
+      compiler.mirrorSystemGetNameFunction;
+
+  @override
+  ConstructorElement get mirrorsUsedConstructor =>
+      compiler.mirrorsUsedConstructor;
+
+  @override
+  ConstructorElement get symbolConstructor => compiler.symbolConstructor;
+
+  @override
+  ConstantValue proxyConstant;
+
+  @override
   void registerClass(ClassElement cls) {
     compiler.world.registerClass(cls);
   }
@@ -1944,6 +1962,14 @@
   }
 
   @override
+  void onClassResolved(ClassElement element) =>
+      compiler.onClassResolved(element);
+
+  @override
+  void registerCompileTimeError(Element element, DiagnosticMessage message) =>
+      compiler.registerCompileTimeError(element, message);
+
+  @override
   bool hasResolvedAst(ExecutableElement element) {
     assert(invariant(element, element.isDeclaration,
         message: "Element $element must be the declaration."));
@@ -1960,6 +1986,9 @@
         message: "Element $element must be the declaration."));
     assert(invariant(element, hasResolvedAst(element),
         message: "ResolvedAst not available for $element."));
+    if (compiler.serialization.isDeserialized(element)) {
+      return compiler.serialization.getResolvedAst(element);
+    }
     return element.resolvedAst;
   }
 
@@ -2084,6 +2113,18 @@
     _worldImpactCache.remove(element);
     _resolutionImpactCache.remove(element);
   }
+
+  @override
+  bool isProxyConstant(ConstantValue value) {
+    FieldElement field = coreLibrary.find('proxy');
+    if (field == null) return false;
+    if (!hasBeenResolved(field)) return false;
+    if (proxyConstant == null) {
+      proxyConstant = constants
+          .getConstantValue(resolver.constantCompiler.compileConstant(field));
+    }
+    return proxyConstant == value;
+  }
 }
 
 class GlobalDependencyRegistry extends EagerRegistry {
@@ -2118,6 +2159,18 @@
       compiler.readScript(uri, spannable);
 }
 
+/// [ScriptLoader] used to ensure that scripts are not loaded accidentally
+/// through the [LibraryLoader] when `CompilerOptions.compileOnly` is `true`.
+class _NoScriptLoader implements ScriptLoader {
+  Compiler compiler;
+  _NoScriptLoader(this.compiler);
+
+  Future<Script> readScript(Uri uri, [Spannable spannable]) {
+    compiler.reporter.internalError(spannable,
+        "Script loading of '$uri' is not enabled.");
+  }
+}
+
 class _ElementScanner implements ElementScanner {
   ScannerTask scanner;
   _ElementScanner(this.scanner);
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index a19e003..c42ca74 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -8,7 +8,7 @@
 import 'constants/constant_system.dart';
 import 'constants/values.dart';
 import 'dart_types.dart';
-import 'tree/tree.dart' show DartString;
+import 'tree/dartstring.dart' show DartString;
 
 const DART_CONSTANT_SYSTEM = const DartConstantSystem();
 
diff --git a/pkg/compiler/lib/src/constants/constant_constructors.dart b/pkg/compiler/lib/src/constants/constant_constructors.dart
index 4628f28..996f8b1 100644
--- a/pkg/compiler/lib/src/constants/constant_constructors.dart
+++ b/pkg/compiler/lib/src/constants/constant_constructors.dart
@@ -16,7 +16,6 @@
 import '../resolution/tree_elements.dart' show TreeElements;
 import '../tree/tree.dart';
 import '../universe/call_structure.dart' show CallStructure;
-
 import 'constructors.dart';
 import 'expressions.dart';
 
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index e278612..1a0da6a 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -4,10 +4,10 @@
 
 library dart2js.constant_system;
 
-import '../dart_types.dart';
 import '../compiler.dart' show Compiler;
+import '../dart_types.dart';
 import '../resolution/operators.dart';
-import '../tree/tree.dart' show DartString;
+import '../tree/dartstring.dart' show DartString;
 import 'values.dart';
 
 abstract class Operation {
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 922ae06..6fc55de 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -16,7 +16,7 @@
         PrefixElement,
         VariableElement;
 import '../resolution/operators.dart';
-import '../tree/tree.dart' show DartString;
+import '../tree/dartstring.dart' show DartString;
 import '../universe/call_structure.dart' show CallStructure;
 import 'evaluation.dart';
 import 'values.dart';
@@ -101,12 +101,7 @@
 
   int _computeHashCode();
 
-  int get hashCode {
-    if (_hashCode == null) {
-      _hashCode = _computeHashCode();
-    }
-    return _hashCode;
-  }
+  int get hashCode => _hashCode ??= _computeHashCode();
 
   bool _equals(ConstantExpression other);
 
@@ -138,7 +133,7 @@
   /// if it contains positional or named references, used to define constant
   /// constructors.
   // TODO(johnniwinther): Maybe make this final if we use it outside assertions.
-  bool get isPotential => true;
+  bool get isPotential => false;
 }
 
 /// A synthetic constant used to recover from errors.
@@ -200,9 +195,6 @@
   ConstantExpressionKind get kind => ConstantExpressionKind.SYNTHETIC;
 
   @override
-  bool get isPotential => false;
-
-  @override
   bool get isImplicit => false;
 }
 
@@ -482,11 +474,15 @@
   @override
   ConstantValue evaluate(
       Environment environment, ConstantSystem constantSystem) {
-    return constantSystem.createMap(
-        environment.compiler,
-        type,
-        keys.map((k) => k.evaluate(environment, constantSystem)).toList(),
-        values.map((v) => v.evaluate(environment, constantSystem)).toList());
+    Map<ConstantValue, ConstantValue> valueMap =
+        <ConstantValue, ConstantValue>{};
+    for (int index = 0; index < keys.length; index++) {
+      ConstantValue key = keys[index].evaluate(environment, constantSystem);
+      ConstantValue value = values[index].evaluate(environment, constantSystem);
+      valueMap[key] = value;
+    }
+    return constantSystem.createMap(environment.compiler, type,
+        valueMap.keys.toList(), valueMap.values.toList());
   }
 
   ConstantExpression apply(NormalizedArguments arguments) {
@@ -654,7 +650,7 @@
     for (ConstantExpression expression in expressions) {
       ConstantValue value = expression.evaluate(environment, constantSystem);
       DartString valueString;
-      if (value.isNum || value.isBool) {
+      if (value.isNum || value.isBool || value.isNull) {
         PrimitiveConstantValue primitive = value;
         valueString =
             new DartString.literal(primitive.primitiveValue.toString());
@@ -1271,9 +1267,7 @@
   }
 
   @override
-  bool get isPotential {
-    return true;
-  }
+  bool get isPotential => true;
 }
 
 /// A reference to a named parameter.
@@ -1312,9 +1306,7 @@
   }
 
   @override
-  bool get isPotential {
-    return true;
-  }
+  bool get isPotential => true;
 }
 
 abstract class FromEnvironmentConstantExpression extends ConstantExpression {
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 62749bf..cba4e69 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -9,9 +9,26 @@
 import '../dart_types.dart';
 import '../elements/elements.dart'
     show FieldElement, FunctionElement, PrefixElement;
-import '../tree/tree.dart' hide unparse;
+import '../tree/dartstring.dart';
 import '../util/util.dart' show Hashing;
 
+enum ConstantValueKind {
+  FUNCTION,
+  NULL,
+  INT,
+  DOUBLE,
+  BOOL,
+  STRING,
+  LIST,
+  MAP,
+  CONSTRUCTED,
+  TYPE,
+  INTERCEPTOR,
+  SYNTHETIC,
+  DEFERRED,
+  NON_CONSTANT,
+}
+
 abstract class ConstantValueVisitor<R, A> {
   const ConstantValueVisitor();
 
@@ -84,6 +101,8 @@
   /// Returns a structured representation of this constant suited for debugging.
   String toStructuredText();
 
+  ConstantValueKind get kind;
+
   String toString() {
     assertDebugMode("Use ConstantValue.toDartText() or "
         "ConstantValue.toStructuredText() "
@@ -118,6 +137,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitFunction(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.FUNCTION;
+
   String toDartText() {
     if (element.isStatic) {
       return '${element.enclosingClass.name}.${element.name}';
@@ -177,6 +198,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitNull(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.NULL;
+
   String toStructuredText() => 'NullConstant';
 }
 
@@ -258,6 +281,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitInt(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.INT;
+
   String toStructuredText() => 'IntConstant(${toDartText()})';
 }
 
@@ -320,6 +345,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitDouble(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.DOUBLE;
+
   String toStructuredText() => 'DoubleConstant(${toDartText()})';
 }
 
@@ -338,6 +365,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitBool(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.BOOL;
+
   String toStructuredText() => 'BoolConstant(${toDartText()})';
 }
 
@@ -414,6 +443,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitString(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.STRING;
+
   // TODO(johnniwinther): Ensure correct escaping.
   String toDartText() => '"${primitiveValue.slowToString()}"';
 
@@ -457,6 +488,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitType(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.TYPE;
+
   String toDartText() => '$representedType';
 
   String toStructuredText() => 'TypeConstant(${representedType})';
@@ -492,6 +525,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitList(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.LIST;
+
   String toDartText() {
     StringBuffer sb = new StringBuffer();
     _unparseTypeArguments(sb);
@@ -567,6 +602,8 @@
 
   accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg);
 
+  ConstantValueKind get kind => ConstantValueKind.MAP;
+
   String toDartText() {
     StringBuffer sb = new StringBuffer();
     _unparseTypeArguments(sb);
@@ -621,6 +658,8 @@
 
   DartType getType(CoreTypes types) => const DynamicType();
 
+  ConstantValueKind get kind => ConstantValueKind.INTERCEPTOR;
+
   String toDartText() {
     return 'interceptor($dispatchedType)';
   }
@@ -632,9 +671,9 @@
 
 class SyntheticConstantValue extends ConstantValue {
   final payload;
-  final kind;
+  final valueKind;
 
-  SyntheticConstantValue(this.kind, this.payload);
+  SyntheticConstantValue(this.valueKind, this.payload);
 
   bool get isDummy => true;
 
@@ -642,7 +681,7 @@
     return other is SyntheticConstantValue && payload == other.payload;
   }
 
-  get hashCode => payload.hashCode * 17 + kind.hashCode;
+  get hashCode => payload.hashCode * 17 + valueKind.hashCode;
 
   List<ConstantValue> getDependencies() => const <ConstantValue>[];
 
@@ -652,9 +691,11 @@
 
   DartType getType(CoreTypes types) => const DynamicType();
 
-  String toDartText() => 'synthetic($kind, $payload)';
+  ConstantValueKind get kind => ConstantValueKind.SYNTHETIC;
 
-  String toStructuredText() => 'SyntheticConstant($kind, $payload)';
+  String toDartText() => 'synthetic($valueKind, $payload)';
+
+  String toStructuredText() => 'SyntheticConstant($valueKind, $payload)';
 }
 
 class ConstructedConstantValue extends ObjectConstantValue {
@@ -693,6 +734,8 @@
     return visitor.visitConstructed(this, arg);
   }
 
+  ConstantValueKind get kind => ConstantValueKind.CONSTRUCTED;
+
   String toDartText() {
     StringBuffer sb = new StringBuffer();
     sb.write(type.name);
@@ -752,6 +795,8 @@
 
   DartType getType(CoreTypes types) => referenced.getType(types);
 
+  ConstantValueKind get kind => ConstantValueKind.DEFERRED;
+
   String toDartText() => 'deferred(${referenced.toDartText()})';
 
   String toStructuredText() {
@@ -776,6 +821,8 @@
   @override
   DartType getType(CoreTypes types) => const DynamicType();
 
+  ConstantValueKind get kind => ConstantValueKind.NON_CONSTANT;
+
   @override
   String toStructuredText() => 'NonConstant';
 
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
deleted file mode 100644
index 5bdfc6c..0000000
--- a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
+++ /dev/null
@@ -1,128 +0,0 @@
-library dart2js.cps_ir.backward_null_check_remover;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.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 [ReceiverCheck] 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 [ReceiverCheck]
-/// 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 an operand of [prim] that throws if null is passed into it.
-  Primitive getNullCheckedOperand(Primitive prim) {
-    if (prim is ReceiverCheck) 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.receiver;
-    }
-    if (prim is ForeignCode) {
-      return prim.isNullGuardOnNullFirstArgument() ? prim.argument(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 ReceiverCheck && prim.isNullCheck) {
-      Primitive value = prim.value;
-      LetPrim let = prim.parent;
-      prim
-        ..replaceUsesWith(value)
-        ..destroy();
-      let.remove();
-    } else if (prim is GetLength || prim is GetField || prim is GetIndex) {
-      if (prim.hasNoRefinedUses) {
-        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);
-    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];
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
deleted file mode 100644
index b4ca8e1..0000000
--- a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
+++ /dev/null
@@ -1,710 +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.bounds_checker;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart' show Pass;
-import 'octagon.dart';
-import '../constants/values.dart';
-import 'cps_fragment.dart';
-import 'type_mask_system.dart';
-import '../types/types.dart';
-import '../world.dart';
-import 'loop_effects.dart';
-import 'effects.dart';
-
-/// Eliminates bounds checks when they can be proven safe.
-///
-/// In general, this pass will try to eliminate any branch with arithmetic
-/// in the condition, i.e. `x < y`, `x <= y`, `x == y` etc.
-///
-/// The analysis uses an [Octagon] abstract domain. Unlike traditional octagon
-/// analyzers, we do not use a closed matrix representation, but just maintain
-/// a bucket of constraints.  Constraints can therefore be added and removed
-/// on-the-fly without significant overhead.
-///
-/// We never copy the constraint system.  While traversing the IR, the
-/// constraint system is mutated to take into account the knowledge that is
-/// valid for the current location.  Constraints are added when entering a
-/// branch, for instance, and removed again after the branch has been processed.
-///
-/// 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 two-pass scheme is suboptimal compared to a least fixed-point
-/// computation, but does not require repeated iteration.  Repeated iteration
-/// would be expensive, since we cannot perform a sparse analysis with our
-/// mutable octagon representation.
-class BoundsChecker extends TrampolineRecursiveVisitor implements Pass {
-  String get passName => 'Bounds checker';
-
-  static const int MAX_UINT32 = (1 << 32) - 1;
-
-  /// All integers of this magnitude or less are representable as JS numbers.
-  static const int MAX_SAFE_INT = (1 << 53) - 1;
-
-  /// Marker to indicate that a continuation should get a unique effect number.
-  static const int NEW_EFFECT = -1;
-
-  final TypeMaskSystem types;
-  final World world;
-
-  /// Fields for the constraint system and its variables.
-  final Octagon octagon = new Octagon();
-  final Map<Primitive, SignedVariable> valueOf = {};
-  final Map<Primitive, Map<int, SignedVariable>> lengthOf = {};
-
-  /// Fields for the two-pass handling of loops.
-  final Map<Parameter, Monotonicity> monotonicity = <Parameter, Monotonicity>{};
-  bool isStrongLoopPass;
-  bool foundLoop = false;
-
-  /// Fields for tracking side effects.
-  ///
-  /// 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;
-
-  BoundsChecker(this.types, this.world);
-
-  void rewrite(FunctionDefinition node) {
-    loopEffects = new LoopSideEffects(node, world);
-    isStrongLoopPass = false;
-    visit(node);
-    if (foundLoop) {
-      isStrongLoopPass = true;
-      effectNumberAt.clear();
-      visit(node);
-    }
-  }
-
-  // ------------- VARIABLES -----------------
-
-  int makeNewEffect() => ++effectNumberCounter;
-
-  bool isInt(Primitive prim) {
-    return types.isDefinitelyInt(prim.type);
-  }
-
-  bool isUInt32(Primitive prim) {
-    return types.isDefinitelyUint32(prim.type);
-  }
-
-  bool isNonNegativeInt(Primitive prim) {
-    return types.isDefinitelyNonNegativeInt(prim.type);
-  }
-
-  /// Get a constraint variable representing the numeric value of [number].
-  SignedVariable getValue(Primitive number) {
-    number = number.effectiveDefinition;
-    int min, max;
-    if (isUInt32(number)) {
-      min = 0;
-      max = MAX_UINT32;
-    } else if (isNonNegativeInt(number)) {
-      min = 0;
-    }
-    return valueOf.putIfAbsent(number, () => octagon.makeVariable(min, max));
-  }
-
-  /// Get a constraint variable representing the length of [indexableObject] at
-  /// program locations with the given [effectNumber].
-  SignedVariable getLength(Primitive indexableObject, int effectNumber) {
-    indexableObject = indexableObject.effectiveDefinition;
-    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(effectNumber, () {
-      int length = types.getContainerLength(type);
-      if (length != null) {
-        return octagon.makeVariable(length, length);
-      } else {
-        return octagon.makeVariable(0, MAX_UINT32);
-      }
-    });
-  }
-
-  // ------------- CONSTRAINT HELPERS -----------------
-
-  /// Puts the given constraint "in scope" by adding it to the octagon, and
-  /// pushing a stack action that will remove it again.
-  void applyConstraint(SignedVariable v1, SignedVariable v2, int k) {
-    Constraint constraint = new Constraint(v1, v2, k);
-    octagon.pushConstraint(constraint);
-    pushAction(() => octagon.popConstraint(constraint));
-  }
-
-  /// Return true if we can prove that `v1 + v2 <= k`.
-  bool testConstraint(SignedVariable v1, SignedVariable v2, int k) {
-    // Add the negated constraint and check for solvability.
-    // !(v1 + v2 <= k)   <==>   -v1 - v2 <= -k-1
-    Constraint constraint = new Constraint(v1.negated, v2.negated, -k - 1);
-    octagon.pushConstraint(constraint);
-    bool answer = octagon.isUnsolvable;
-    octagon.popConstraint(constraint);
-    return answer;
-  }
-
-  void makeLessThanOrEqual(SignedVariable v1, SignedVariable v2) {
-    // v1 <= v2   <==>   v1 - v2 <= 0
-    applyConstraint(v1, v2.negated, 0);
-  }
-
-  void makeLessThan(SignedVariable v1, SignedVariable v2) {
-    // v1 < v2   <==>   v1 - v2 <= -1
-    applyConstraint(v1, v2.negated, -1);
-  }
-
-  void makeGreaterThanOrEqual(SignedVariable v1, SignedVariable v2) {
-    // v1 >= v2   <==>   v2 - v1 <= 0
-    applyConstraint(v2, v1.negated, 0);
-  }
-
-  void makeGreaterThan(SignedVariable v1, SignedVariable v2) {
-    // v1 > v2   <==>    v2 - v1 <= -1
-    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
-    //   -v1 - v1 <= -2k
-    applyConstraint(v1, v1, 2 * k);
-    applyConstraint(v1.negated, v1.negated, -2 * k);
-  }
-
-  /// Make `v1 = v2 + k`.
-  void makeExactSum(SignedVariable v1, SignedVariable v2, int k) {
-    applyConstraint(v1, v2.negated, k);
-    applyConstraint(v1.negated, v2, -k);
-  }
-
-  /// Make `v1 = v2 [+] k` where [+] represents floating-point addition.
-  void makeFloatingPointSum(SignedVariable v1, SignedVariable v2, int k) {
-    if (isDefinitelyLessThanOrEqualToConstant(v2, MAX_SAFE_INT - k) &&
-        isDefinitelyGreaterThanOrEqualToConstant(v2, -MAX_SAFE_INT + k)) {
-      // The result is known to be in the 53-bit range, so no rounding occurs.
-      makeExactSum(v1, v2, k);
-    } else {
-      // A rounding error may occur, so the result may not be exactly v2 + k.
-      // We can still add monotonicity constraints:
-      //   adding a positive number cannot return a lesser number
-      //   adding a negative number cannot return a greater number
-      if (k >= 0) {
-        // v1 >= v2   <==>   v2 - v1 <= 0   <==>   -v1 + v2 <= 0
-        applyConstraint(v1.negated, v2, 0);
-      } else {
-        // v1 <= v2   <==>   v1 - v2 <= 0
-        applyConstraint(v1, v2.negated, 0);
-      }
-    }
-  }
-
-  void makeEqual(SignedVariable v1, SignedVariable v2) {
-    // We model this using the constraints:
-    //    v1 <= v2   <==>   v1 - v2 <= 0
-    //    v1 >= v2   <==>   v2 - v1 <= 0
-    applyConstraint(v1, v2.negated, 0);
-    applyConstraint(v2, v1.negated, 0);
-  }
-
-  void makeNotEqual(SignedVariable v1, SignedVariable v2) {
-    // The octagon cannot represent non-equality, but we can sharpen a weak
-    // inequality to a sharp one. If v1 and v2 are already known to be equal,
-    // this will create a contradiction and eliminate a dead branch.
-    // This is necessary for eliminating concurrent modification checks.
-    if (isDefinitelyLessThanOrEqualTo(v1, v2)) {
-      makeLessThan(v1, v2);
-    } else if (isDefinitelyGreaterThanOrEqualTo(v1, v2)) {
-      makeGreaterThan(v1, v2);
-    }
-  }
-
-  /// Return true if we can prove that `v1 <= v2`.
-  bool isDefinitelyLessThanOrEqualTo(SignedVariable v1, SignedVariable v2) {
-    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);
-  }
-
-  bool isDefinitelyLessThanOrEqualToConstant(SignedVariable v1, int value) {
-    // v1 <= value   <==>   v1 + v1 <= 2 * value
-    return testConstraint(v1, v1, 2 * value);
-  }
-
-  bool isDefinitelyGreaterThanOrEqualToConstant(SignedVariable v1, int value) {
-    // v1 >= value   <==>   -v1 - v1 <= -2 * value
-    return testConstraint(v1.negated, v1.negated, -2 * value);
-  }
-
-  // ------------- TAIL EXPRESSIONS -----------------
-
-  @override
-  void visitBranch(Branch node) {
-    Primitive condition = node.condition;
-    Continuation trueCont = node.trueContinuation;
-    Continuation falseCont = node.falseContinuation;
-    effectNumberAt[trueCont] = currentEffectNumber;
-    effectNumberAt[falseCont] = currentEffectNumber;
-    pushAction(() {
-      // If the branching condition is known statically, either or both of the
-      // branch continuations will be replaced by Unreachable. Clean up the
-      // branch afterwards.
-      if (trueCont.body is Unreachable && falseCont.body is Unreachable) {
-        destroyAndReplace(node, new Unreachable());
-      } else if (trueCont.body is Unreachable) {
-        destroyAndReplace(
-            node, new InvokeContinuation(falseCont, <Parameter>[]));
-      } else if (falseCont.body is Unreachable) {
-        destroyAndReplace(
-            node, new InvokeContinuation(trueCont, <Parameter>[]));
-      }
-    });
-    void pushTrue(makeConstraint()) {
-      pushAction(() {
-        makeConstraint();
-        push(trueCont);
-      });
-    }
-    void pushFalse(makeConstraint()) {
-      pushAction(() {
-        makeConstraint();
-        push(falseCont);
-      });
-    }
-    if (condition is ApplyBuiltinOperator &&
-        condition.argumentRefs.length == 2 &&
-        isInt(condition.argument(0)) &&
-        isInt(condition.argument(1))) {
-      SignedVariable v1 = getValue(condition.argument(0));
-      SignedVariable v2 = getValue(condition.argument(1));
-      switch (condition.operator) {
-        case BuiltinOperator.NumLe:
-          pushTrue(() => makeLessThanOrEqual(v1, v2));
-          pushFalse(() => makeGreaterThan(v1, v2));
-          return;
-        case BuiltinOperator.NumLt:
-          pushTrue(() => makeLessThan(v1, v2));
-          pushFalse(() => makeGreaterThanOrEqual(v1, v2));
-          return;
-        case BuiltinOperator.NumGe:
-          pushTrue(() => makeGreaterThanOrEqual(v1, v2));
-          pushFalse(() => makeLessThan(v1, v2));
-          return;
-        case BuiltinOperator.NumGt:
-          pushTrue(() => makeGreaterThan(v1, v2));
-          pushFalse(() => makeLessThanOrEqual(v1, v2));
-          return;
-        case BuiltinOperator.StrictEq:
-          pushTrue(() => makeEqual(v1, v2));
-          pushFalse(() => makeNotEqual(v1, v2));
-          return;
-        case BuiltinOperator.StrictNeq:
-          pushTrue(() => makeNotEqual(v1, v2));
-          pushFalse(() => makeEqual(v1, v2));
-          return;
-        default:
-      }
-    }
-
-    push(trueCont);
-    push(falseCont);
-  }
-
-  @override
-  void visitConstant(Constant node) {
-    // TODO(asgerf): It might be faster to inline the constant in the
-    //               constraints that reference it.
-    if (node.value.isInt) {
-      IntConstantValue constant = node.value;
-      makeConstant(getValue(node), constant.primitiveValue);
-    }
-  }
-
-  @override
-  void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    if (!isInt(node)) return;
-    if (node.argumentRefs.length == 1) {
-      applyUnaryOperator(node);
-    } else if (node.argumentRefs.length == 2) {
-      applyBinaryOperator(node);
-    }
-  }
-
-  void applyBinaryOperator(ApplyBuiltinOperator node) {
-    Primitive left = node.argument(0);
-    Primitive right = node.argument(1);
-    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.argument(0);
-    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
-  void visitGetLength(GetLength node) {
-    valueOf[node] = getLength(node.object, currentEffectNumber);
-  }
-
-  @override
-  void visitBoundsCheck(BoundsCheck node) {
-    if (node.checks == BoundsCheck.NONE) return;
-    assert(node.indexRef != null); // Because there is at least one check.
-    SignedVariable length =
-        node.lengthRef == null ? null : getValue(node.length);
-    SignedVariable index = getValue(node.index);
-    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.lengthRef != null) {
-      node
-        ..lengthRef.unlink()
-        ..lengthRef = 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
-        ..indexRef.unlink()
-        ..indexRef = null;
-    }
-  }
-
-  void analyzeLoopEntry(InvokeContinuation node) {
-    foundLoop = true;
-    Continuation cont = node.continuation;
-    if (isStrongLoopPass) {
-      for (int i = 0; i < node.argumentRefs.length; ++i) {
-        Parameter param = cont.parameters[i];
-        if (!isInt(param)) continue;
-        Primitive initialValue = node.argument(i);
-        SignedVariable initialVariable = getValue(initialValue);
-        Monotonicity mono = monotonicity[param];
-        if (mono == null) {
-          // Value never changes. This is extremely uncommon.
-          param.replaceUsesWith(initialValue);
-        } else if (mono == Monotonicity.Increasing) {
-          makeGreaterThanOrEqual(getValue(param), initialVariable);
-        } else if (mono == Monotonicity.Decreasing) {
-          makeLessThanOrEqual(getValue(param), initialVariable);
-        }
-      }
-    }
-    if (loopEffects.changesIndexableLength(cont)) {
-      currentEffectNumber = effectNumberAt[cont] = makeNewEffect();
-    }
-    push(cont);
-  }
-
-  void analyzeLoopContinue(InvokeContinuation node) {
-    Continuation cont = node.continuation;
-
-    // During the strong loop phase, there is no need to compute monotonicity,
-    // and we already put bounds on the loop variables when we went into the
-    // loop.
-    if (isStrongLoopPass) return;
-
-    // For each loop parameter, try to prove that the new value is definitely
-    // less/greater than its old value. When we fail to prove this, update the
-    // monotonicity flag accordingly.
-    for (int i = 0; i < node.argumentRefs.length; ++i) {
-      Parameter param = cont.parameters[i];
-      if (!isInt(param)) continue;
-      SignedVariable arg = getValue(node.argument(i));
-      SignedVariable paramVar = getValue(param);
-      if (!isDefinitelyLessThanOrEqualTo(arg, paramVar)) {
-        // We couldn't prove that the value does not increase, so assume
-        // henceforth that it might be increasing.
-        markMonotonicity(cont.parameters[i], Monotonicity.Increasing);
-      }
-      if (!isDefinitelyGreaterThanOrEqualTo(arg, paramVar)) {
-        // We couldn't prove that the value does not decrease, so assume
-        // henceforth that it might be decreasing.
-        markMonotonicity(cont.parameters[i], Monotonicity.Decreasing);
-      }
-    }
-  }
-
-  void markMonotonicity(Parameter param, Monotonicity mono) {
-    Monotonicity current = monotonicity[param];
-    if (current == null) {
-      monotonicity[param] = mono;
-    } else if (current != mono) {
-      monotonicity[param] = Monotonicity.NotMonotone;
-    }
-  }
-
-  @override
-  void visitInvokeContinuation(InvokeContinuation node) {
-    Continuation cont = node.continuation;
-    if (node.isRecursive) {
-      analyzeLoopContinue(node);
-    } else if (cont.isRecursive) {
-      analyzeLoopEntry(node);
-    } else {
-      int effect = effectNumberAt[cont];
-      if (effect == null) {
-        effectNumberAt[cont] = currentEffectNumber;
-      } else if (effect != currentEffectNumber && effect != NEW_EFFECT) {
-        effectNumberAt[cont] = NEW_EFFECT;
-      }
-      // TODO(asgerf): Compute join for parameters to increase precision?
-    }
-  }
-
-  // ---------------- PRIMITIVES --------------------
-
-  @override
-  Expression traverseLetPrim(LetPrim node) {
-    visit(node.primitive);
-    // visitApplyBuiltinMethod updates the effect number.
-    if (node.primitive is! ApplyBuiltinMethod) {
-      if (node.primitive.effects & Effects.changesIndexableLength != 0) {
-        currentEffectNumber = makeNewEffect();
-      }
-    }
-    return node.body;
-  }
-
-  @override
-  void visitInvokeMethod(InvokeMethod node) {
-    if (node.selector.isGetter && node.selector.name == 'length') {
-      // If the receiver type is not known to be indexable, the length call
-      // was not rewritten to GetLength.  But if we can prove that the call only
-      // succeeds for indexables, we can trust that it returns the length.
-      TypeMask successType =
-          types.receiverTypeFor(node.selector, node.receiver.type);
-      if (types.isDefinitelyIndexable(successType)) {
-        valueOf[node] = getLength(node.receiver, currentEffectNumber);
-      }
-    }
-  }
-
-  @override
-  void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    Primitive receiver = node.receiver;
-    int effectBefore = currentEffectNumber;
-    currentEffectNumber = makeNewEffect();
-    int effectAfter = currentEffectNumber;
-    SignedVariable lengthBefore = getLength(receiver, effectBefore);
-    SignedVariable lengthAfter = getLength(receiver, effectAfter);
-    switch (node.method) {
-      case BuiltinMethod.Push:
-        // after = before + count
-        int count = node.argumentRefs.length;
-        makeExactSum(lengthAfter, lengthBefore, count);
-        break;
-
-      case BuiltinMethod.Pop:
-        // after = before - 1
-        makeExactSum(lengthAfter, lengthBefore, -1);
-        break;
-
-      case BuiltinMethod.SetLength:
-        makeEqual(lengthAfter, getValue(node.argument(0)));
-        break;
-    }
-  }
-
-  @override
-  void visitLiteralList(LiteralList node) {
-    makeConstant(getLength(node, currentEffectNumber), node.valueRefs.length);
-  }
-
-  // ---------------- INTERIOR EXPRESSIONS --------------------
-
-  @override
-  Expression traverseContinuation(Continuation cont) {
-    if (octagon.isUnsolvable) {
-      destroyAndReplace(cont.body, new Unreachable());
-    } else {
-      int effect = effectNumberAt[cont];
-      if (effect != null) {
-        currentEffectNumber = effect == NEW_EFFECT ? makeNewEffect() : effect;
-      }
-    }
-    return cont.body;
-  }
-
-  @override
-  Expression traverseLetCont(LetCont node) {
-    // Join continuations should be pushed at declaration-site, so all their
-    // call sites are seen before they are analyzed.
-    // Other continuations are pushed at the use site.
-    for (Continuation cont in node.continuations) {
-      if (cont.hasAtLeastOneUse &&
-          !cont.isRecursive &&
-          cont.firstRef.parent is InvokeContinuation) {
-        push(cont);
-      }
-    }
-    return node.body;
-  }
-}
-
-/// Lattice representing the known (weak) monotonicity of a loop variable.
-///
-/// The lattice bottom is represented by `null` and represents the case where
-/// the loop variable never changes value during the loop.
-enum Monotonicity { NotMonotone, Increasing, Decreasing, }
diff --git a/pkg/compiler/lib/src/cps_ir/builtin_operator.dart b/pkg/compiler/lib/src/cps_ir/builtin_operator.dart
deleted file mode 100644
index 7c5e45c..0000000
--- a/pkg/compiler/lib/src/cps_ir/builtin_operator.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 builtin_operator;
-// This is shared by the CPS and Tree IRs.
-// Both cps_ir_nodes and tree_ir_nodes import and re-export this file.
-
-import 'effects.dart';
-
-/// An operator supported natively in the CPS and Tree IRs using the
-/// `ApplyBuiltinOperator` instructions.
-///
-/// These operators are pure in the sense that they cannot throw, diverge,
-/// have observable side-effects, return new objects, nor depend on any
-/// mutable state.
-///
-/// Most operators place restrictions on the values that may be given as
-/// argument; their behaviour is unspecified if those requirements are violated.
-///
-/// In all cases, the word "null" refers to the Dart null object, corresponding
-/// to both JS null and JS undefined.
-///
-/// Some operators, notably [IsFloor] and [IsInteger], take "repeated"
-/// arguments to reflect the number of times the given value is referenced
-/// by the generated code. The tree IR needs to know the number of references
-/// to safely propagate assignments.
-enum BuiltinOperator {
-  /// The numeric binary operators must take two numbers as argument.
-  /// The bitwise operators coerce the result to an unsigned integer, but
-  /// otherwise these all behave like the corresponding JS operator.
-  NumAdd,
-  NumSubtract,
-  NumMultiply,
-  NumDivide,
-  NumAnd,
-  NumOr,
-  NumXor,
-  NumShl,
-  NumLt,
-  NumLe,
-  NumGt,
-  NumGe,
-
-  /// NumShr behaves like JS '>>>' but is valid only when the left is in the
-  /// uint32 range and the right in the range [0, 31].
-  NumShr,
-
-  /// NumRemainder corresponds to JavaScript's `a % b`, and Dart's
-  /// `a.remainder(b)`, except at zero, since JavaScript `1 % 0` is `NaN`.
-  /// Dart's modulo (`%`) is the same as remainder only when if both arguments
-  /// are non-negative.
-  NumRemainder,
-
-  /// Corresponds to `a ~/ b` when b is non-zero and the result fits in a signed
-  /// 32 bit value.
-  ///
-  /// 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.
-  ///
-  /// 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.
-  ///
-  /// Compiled as a static method call.
-  Identical,
-
-  /// Like [Identical], except at most one argument may be null.
-  ///
-  /// Compiles to `===`.
-  StrictEq,
-
-  /// Negated version of [StrictEq]. Introduced by [LogicalRewriter] in Tree IR.
-  StrictNeq,
-
-  /// Returns true if the two arguments are both null or are the same string,
-  /// boolean, or number, and that number is not NaN, or one argument is +0
-  /// and the other is -0.
-  ///
-  /// One of the following must hold:
-  /// - At least one argument is null.
-  /// - Arguments are both strings, or both booleans, or both numbers.
-  ///
-  /// Compiles to `==`.
-  LooseEq,
-
-  /// Negated version of [LooseEq]. Introduced by [LogicalRewriter] in Tree IR.
-  LooseNeq,
-
-  /// Returns true if the argument is false, +0. -0, NaN, the empty string,
-  /// or null.
-  ///
-  /// Compiles to `!`.
-  IsFalsy,
-
-  /// Returns true if the argument is a number.
-  ///
-  /// Compiles to `typeof x === 'number'`
-  IsNumber,
-
-  /// Returns true if the argument is not a number.
-  ///
-  /// Compiles to `typeof x !== 'number'`.
-  IsNotNumber,
-
-  /// Returns true if the argument is an integer, false if it is a double or
-  /// null, and unspecified if it is anything else.
-  ///
-  /// The argument must be repeated 2 times.
-  ///
-  /// Compiles to `Math.floor(x) === x`
-  IsFloor,
-
-  /// Returns true if the argument is an integer.
-  ///
-  /// The argument must be repeated 3 times.
-  ///
-  /// Compiles to `typeof x === 'number' && Math.floor(x) === x`
-  IsInteger,
-
-  /// Returns true if the argument is not an integer.
-  ///
-  /// The argument must be repeated 3 times.
-  ///
-  /// Compiles to `typeof x !== 'number' || Math.floor(x) !== x`
-  IsNotInteger,
-
-  /// Returns true if `x` is an unsigned 32-bit integer.
-  ///
-  /// The argument must be repeated 2 times.
-  ///
-  /// Compiles to `x >>> 0 === x`
-  IsUnsigned32BitInteger,
-
-  /// Returns false if `x` is an unsigned 32-bit integer.
-  ///
-  /// The argument must be repeated 2 times.
-  ///
-  /// Compiles to `x >>> 0 !== x`
-  IsNotUnsigned32BitInteger,
-
-  /// Returns true if the argument is a fixed length Array.
-  ///
-  /// Uses one argument.
-  ///
-  /// Precondition: Argument is a JavaScript Array.
-  IsFixedLengthJSArray,
-
-  // TODO(sra): Remove this and replace with IsFalsy(IsFixedLengthJSArray(x)).
-  IsExtendableJSArray,
-
-  /// Returns true if the argument is an unmodifiable Array.
-  ///
-  /// Uses one argument.
-  ///
-  /// Precondition: Argument is a JavaScript Array.
-  IsUnmodifiableJSArray,
-
-  // TODO(sra): Remove this and replace with IsFalsy(IsUnmodifiableArray(x)).
-  IsModifiableJSArray,
-}
-
-/// 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 an array.
-  ///
-  /// 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 an array.
-  ///
-  /// Takes no arguments.
-  ///
-  /// Compiles to `object.pop()`.
-  Pop,
-
-  /// Sets the length of the array.
-  ///
-  /// Compiles to `object.length = x1`.
-  SetLength,
-}
-
-/// 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;
-  }
-}
-
-int getEffectsOfBuiltinMethod(BuiltinMethod method) {
-  switch (method) {
-    case BuiltinMethod.Push:
-      return Effects.changesIndexableContent | Effects.changesIndexableLength;
-    case BuiltinMethod.Pop:
-      return Effects.dependsOnIndexableContent |
-          Effects.dependsOnIndexableLength |
-          Effects.changesIndexableLength;
-    case BuiltinMethod.SetLength:
-      return Effects.changesIndexableLength;
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
deleted file mode 100644
index 4e22d0e..0000000
--- a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
+++ /dev/null
@@ -1,374 +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.cps_fragment;
-
-import 'cps_ir_nodes.dart';
-import '../constants/values.dart';
-import '../universe/selector.dart' show Selector;
-import '../types/types.dart' show TypeMask;
-import '../io/source_information.dart';
-import '../elements/elements.dart';
-
-/// Builds a CPS fragment that can be plugged into another CPS term.
-///
-/// A CPS fragment contains a CPS term, possibly with a "hole" in it denoting
-/// where to insert new IR nodes. We say a fragment is "open" if it has such
-/// a hole. Otherwise, the fragment is "closed" and cannot be extended further.
-///
-/// This class is designed for building non-trivial CPS terms in a readable and
-/// non-error prone manner. It is not designed to manipulate existing IR nodes,
-/// nor is it intended to shield the user from every complexity in the IR.
-///
-/// EXAMPLES:
-///
-/// Call `cont` with `obj.field + 1` as argument:
-///
-///   CpsFragment cps = new CpsFragment();
-///   var fieldValue = cps.letPrim(new GetField(obj, field));
-///   var plusOne = cps.applyBuiltin(BuiltinOperator.NumAdd,
-///                                  [fieldValue, cps.makeOne()]);
-///   cps.invokeContinuation(cont, [plusOne]);
-///
-/// If `condition` is true then invoke `cont1`, else `cont2`.
-///
-///   cps.ifTruthy(condition).invokeContinuation(cont1, []);
-///   cps.invokeContinuation(cont2, []);
-///
-/// If `condition` is true then invoke `cont` with a bound primitive:
-///
-///   CpsFragment branch = cps.ifTruthy(condition);
-///   branch.invokeContinuation(cont, [branch.letPrim(arg)]);
-///
-/// Loop and call a method until it returns false:
-///
-///   Continuation loop = cps.beginLoop();
-///   var result = cps.invokeMethod(receiver, selector, ...);
-///   cps.ifFalsy(result).invokeContinuation(exit, []);
-///   cps.continueLoop(loop);
-///
-class CpsFragment {
-  /// The root of the IR built using this fragment.
-  Expression root;
-
-  /// Node whose body is the hole in this CPS fragment. May be null.
-  InteriorNode context;
-
-  /// Source information to attach to every IR node created in the fragment.
-  SourceInformation sourceInformation;
-
-  CpsFragment([this.sourceInformation, this.context]);
-
-  bool get isOpen => root == null || context != null;
-  bool get isClosed => !isOpen;
-  bool get isEmpty => root == null;
-
-  /// Asserts that the fragment is non-empty and closed and returns the IR that
-  /// was built.
-  Expression get result {
-    assert(!isEmpty);
-    assert(isClosed);
-    return root;
-  }
-
-  /// Put the given expression into the fragment's hole.
-  ///
-  /// Afterwards the fragment is closed and cannot be extended until a new
-  /// [context] is set.
-  void put(Expression node) {
-    assert(root == null || context != null); // We must put the node somewhere.
-    if (root == null) {
-      root = node;
-    }
-    if (context != null) {
-      context.body = node;
-      node.parent = context;
-    }
-    context = null;
-  }
-
-  /// Bind a primitive. Returns the same primitive for convenience.
-  Primitive letPrim(Primitive prim) {
-    assert(prim != null);
-    LetPrim let = new LetPrim(prim);
-    put(let);
-    context = let;
-    return prim;
-  }
-
-  /// Bind a constant value.
-  Primitive makeConstant(ConstantValue constant) {
-    return letPrim(new Constant(constant));
-  }
-
-  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());
-
-  /// Invoke a built-in operator.
-  Primitive applyBuiltin(BuiltinOperator op, List<Primitive> args) {
-    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,
-      {bool receiverIsNotNull: false}) {
-    ApplyBuiltinMethod apply =
-        new ApplyBuiltinMethod(method, receiver, arguments, sourceInformation);
-    return letPrim(apply);
-  }
-
-  /// Inserts an invocation and returns a primitive holding the returned value.
-  Primitive invokeMethod(Primitive receiver, Selector selector, TypeMask mask,
-      List<Primitive> arguments,
-      {Primitive interceptor, CallingConvention callingConvention}) {
-    InvokeMethod invoke = new InvokeMethod(receiver, selector, mask, arguments,
-        sourceInformation: sourceInformation,
-        callingConvention: callingConvention,
-        interceptor: interceptor);
-    return letPrim(invoke);
-  }
-
-  /// 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.
-  ///
-  /// This closes the fragment; no more nodes may be added.
-  void invokeStaticThrower(FunctionElement target, List<Primitive> arguments) {
-    invokeStatic(target, arguments);
-    put(new Unreachable());
-  }
-
-  /// Invoke a non-recursive continuation.
-  ///
-  /// This closes the fragment; no more nodes may be inserted.
-  void invokeContinuation(Continuation cont, [List<Primitive> arguments]) {
-    if (arguments == null) arguments = <Primitive>[];
-    put(new InvokeContinuation(cont, arguments));
-  }
-
-  /// Build a loop with the given loop variables and initial values.
-  /// Call [continueLoop] with the returned continuation to iterate the loop.
-  ///
-  /// The loop body becomes the new hole.
-  Continuation beginLoop(
-      [List<Parameter> loopVars, List<Primitive> initialValues]) {
-    if (initialValues == null) {
-      assert(loopVars == null);
-      loopVars = <Parameter>[];
-      initialValues = <Primitive>[];
-    }
-    Continuation cont = new Continuation(loopVars);
-    put(new LetCont(cont, new InvokeContinuation(cont, initialValues)));
-    context = cont;
-    return cont;
-  }
-
-  /// Continue a loop started by [beginLoop].
-  ///
-  /// This closes the fragment; no more nodes may be inserted.
-  void continueLoop(Continuation cont, [List<Primitive> updatedLoopVariables]) {
-    put(new InvokeContinuation(cont, updatedLoopVariables, isRecursive: true));
-  }
-
-  /// Branch on [condition].
-  ///
-  /// Returns a new fragment for the 'then' branch, or the 'else' branch
-  /// if [negate] is true.
-  ///
-  /// 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(condition, trueCont, falseCont, sourceInformation,
-            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) => branch(condition, negate: true);
-
-  /// Create a new empty continuation and bind it here.
-  ///
-  /// Convenient for making a join point where multiple branches
-  /// meet later.
-  ///
-  /// The LetCont body becomes the new hole.
-  ///
-  /// Example use:
-  ///
-  ///   Continuation fail = cps.letCont();
-  ///
-  ///   // Fail if something
-  ///   cps.ifTrue(<condition>)
-  ///      ..invokeMethod(<method>)
-  ///      ..invokeContinuation(fail);
-  ///
-  ///   // Fail if something else
-  ///   cps.ifTrue(<anotherCondition>)
-  ///      ..invokeMethod(<anotherMethod>)
-  ///      ..invokeContinuation(fail);
-  ///
-  ///   // Build the fail branch
-  ///   cps.insideContinuation(fail)
-  ///      ..invokeStaticThrower(...);
-  ///
-  ///   // Go to the happy branch
-  ///   cps.invokeContinuation(cont..)
-  ///
-  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;
-  }
-
-  /// Inlines [target] at the current position, substituting the provided
-  /// arguments.
-  ///
-  /// Returns a primitive containing the function's return value.
-  ///
-  /// The new hole is 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 receiver, List<Primitive> arguments,
-      {Entity hint, Primitive interceptor}) {
-    if (interceptor != null) {
-      target.interceptorParameter.replaceUsesWith(interceptor);
-    }
-    if (receiver != null) {
-      target.receiverParameter.replaceUsesWith(receiver);
-    }
-    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.
-  ///
-  /// Does not change the state of this CPS fragment.
-  ///
-  /// Useful for building the body of a continuation created using [letCont].
-  CpsFragment insideContinuation(Continuation cont) {
-    return new CpsFragment(sourceInformation, cont);
-  }
-
-  /// Puts the given fragment into this one.
-  ///
-  /// If [other] was an open fragment, its hole becomes the new hole
-  /// in this fragment.
-  ///
-  /// [other] is reset to an empty fragment after this.
-  void append(CpsFragment other) {
-    if (other.root == null) return;
-    put(other.root);
-    context = other.context;
-    other.context = null;
-    other.root = null;
-  }
-
-  /// Reads the value of the given mutable variable.
-  Primitive getMutable(MutableVariable variable) {
-    return letPrim(new GetMutable(variable));
-  }
-
-  /// Sets the value of the given mutable variable.
-  void setMutable(MutableVariable variable, Primitive value) {
-    letPrim(new SetMutable(variable, value));
-  }
-
-  /// Declare a new mutable variable.
-  void letMutable(MutableVariable variable, Primitive initialValue) {
-    LetMutable let = new LetMutable(variable, initialValue);
-    put(let);
-    context = let;
-  }
-
-  void insertBelow(InteriorNode node) {
-    assert(isOpen);
-    if (isEmpty) return;
-    Expression child = node.body;
-    node.body = root;
-    root.parent = node;
-    context.body = child;
-    child.parent = context;
-    root = context = null;
-  }
-
-  void insertAbove(InteriorExpression node) {
-    insertBelow(node.parent);
-  }
-}
-
-/// Removes [node], unlinking all its references and replaces it with [newNode].
-void destroyAndReplace(Expression node, Expression newNode) {
-  InteriorNode parent = node.parent;
-  RemovalVisitor.remove(node);
-  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
deleted file mode 100644
index 3e1f9bf..0000000
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ /dev/null
@@ -1,2927 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.ir_builder;
-
-import '../closure.dart' as closure;
-import '../common.dart';
-import '../common/names.dart' show Selectors;
-import '../compile_time_constants.dart' show BackendConstantEnvironment;
-import '../constants/constant_system.dart';
-import '../constants/values.dart' show ConstantValue;
-import '../dart_types.dart';
-import '../elements/elements.dart';
-import '../io/source_information.dart';
-import '../js/js.dart' as js
-    show
-        js,
-        objectLiteral,
-        Expression,
-        LiteralStatement,
-        Template,
-        InterpolatedExpression,
-        isIdentityTemplate;
-import '../native/native.dart' show NativeBehavior;
-import '../tree/tree.dart' as ast;
-import '../types/types.dart' show TypeMask;
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector, SelectorKind;
-import 'cps_ir_builder_task.dart' show GlobalProgramInformation;
-import 'cps_ir_nodes.dart' as ir;
-
-/// A mapping from variable elements to their compile-time values.
-///
-/// Map elements denoted by parameters and local variables to the
-/// [ir.Primitive] that is their value.  Parameters and locals are
-/// assigned indexes which can be used to refer to them.
-class Environment {
-  /// A map from locals to their environment index.
-  final Map<Local, int> variable2index;
-
-  /// A reverse map from environment indexes to the variable.
-  final List<Local> index2variable;
-
-  /// A map from environment indexes to their value.
-  final List<ir.Primitive> index2value;
-
-  Environment.empty()
-      : variable2index = <Local, int>{},
-        index2variable = <Local>[],
-        index2value = <ir.Primitive>[];
-
-  /// Construct an environment that is a copy of another one.
-  ///
-  /// The mapping from elements to indexes is shared, not copied.
-  Environment.from(Environment other)
-      : variable2index = other.variable2index,
-        index2variable = new List<Local>.from(other.index2variable),
-        index2value = new List<ir.Primitive>.from(other.index2value);
-
-  /// Construct an environment that is shaped like another one but with a
-  /// fresh parameter for each variable.
-  ///
-  /// The mapping from elements to indexes is shared, not copied.
-  Environment.fresh(Environment other)
-      : variable2index = other.variable2index,
-        index2variable = new List<Local>.from(other.index2variable),
-        index2value = other.index2variable.map((Local local) {
-          return new ir.Parameter(local);
-        }).toList();
-
-  get length => index2variable.length;
-
-  ir.Primitive operator [](int index) => index2value[index];
-
-  void extend(Local element, ir.Primitive value) {
-    // Assert that the name is not already in the environment.  `null` is used
-    // as the name of anonymous variables.
-    assert(!variable2index.containsKey(element));
-    if (element != null) variable2index[element] = index2variable.length;
-    index2variable.add(element);
-    index2value.add(value);
-  }
-
-  /// Drop [count] values from the environment.
-  ///
-  /// Return the previous last value in the environment for convenience.
-  ir.Primitive discard(int count) {
-    assert(count > 0);
-    assert(count <= index2variable.length);
-    ir.Primitive value = index2value.last;
-    // The map from variables to their index are shared, so we cannot remove
-    // the mapping in `variable2index`.
-    index2variable.length -= count;
-    index2value.length -= count;
-    return value;
-  }
-
-  ir.Primitive lookup(Local element) {
-    assert(invariant(element, variable2index.containsKey(element),
-        message: "Unknown variable: $element."));
-    return index2value[variable2index[element]];
-  }
-
-  void update(Local element, ir.Primitive value) {
-    index2value[variable2index[element]] = value;
-  }
-
-  /// Verify that the variable2index and index2variable maps agree up to the
-  /// index [length] exclusive.
-  bool sameDomain(int length, Environment other) {
-    assert(this.length >= length);
-    assert(other.length >= length);
-    for (int i = 0; i < length; ++i) {
-      // An index maps to the same variable in both environments.
-      Local variable = index2variable[i];
-      if (variable != other.index2variable[i]) return false;
-
-      // A named variable maps to the same index in both environments.
-      if (variable != null) {
-        int index = variable2index[variable];
-        if (index == null || index != other.variable2index[variable]) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-
-  bool contains(Local local) => variable2index.containsKey(local);
-}
-
-/// The abstract base class of objects that emit jumps to a continuation and
-/// give a handle to the continuation and its environment.
-abstract class JumpCollector {
-  final JumpTarget target;
-
-  ir.Continuation _continuation = null;
-  final Environment _continuationEnvironment;
-
-  final List<Iterable<LocalVariableElement>> _boxedTryVariables =
-      <Iterable<LocalVariableElement>>[];
-
-  /// Construct a collector for a given environment and optionally a target.
-  ///
-  /// The environment is the one in effect at the point where the jump's
-  /// continuation will be bound.  Continuations can take an extra argument
-  /// (see [addJump]).
-  JumpCollector(
-      this._continuationEnvironment, this.target, bool hasExtraArgument) {
-    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;
-
-  /// Construct a collector for collecting goto jumps.
-  ///
-  /// There is no continuation or environment at the destination.
-  JumpCollector.goto(this.target) : _continuationEnvironment = null;
-
-  /// True if the collector has not recorded any jumps to its continuation.
-  bool get isEmpty;
-
-  /// The continuation encapsulated by this collector.
-  ir.Continuation get continuation;
-
-  /// The compile-time environment to be used for translating code in the body
-  /// of the continuation.
-  Environment get environment;
-
-  /// Emit a jump to the continuation for a given [IrBuilder].
-  ///
-  /// Jumps can take a single extra argument.  This is used to pass return
-  /// 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, SourceInformation sourceInformation]);
-
-  /// Add a set of variables that were boxed on entry to a try block.
-  ///
-  /// All jumps from a try block to targets outside have to unbox the
-  /// variables that were boxed on entry before invoking the target
-  /// continuation.  Call this function before translating a try block and
-  /// call [leaveTry] after translating it.
-  void enterTry(Iterable<LocalVariableElement> boxedOnEntry) {
-    // The boxed variables are maintained as a stack to make leaving easy.
-    _boxedTryVariables.add(boxedOnEntry);
-  }
-
-  /// Remove the most recently added set of variables boxed on entry to a try
-  /// block.
-  ///
-  /// Call [enterTry] before translating a try block and call this function
-  /// after translating it.
-  void leaveTry() {
-    _boxedTryVariables.removeLast();
-  }
-
-  void _buildTryExit(IrBuilder builder) {
-    for (Iterable<LocalVariableElement> boxedOnEntry in _boxedTryVariables) {
-      for (LocalVariableElement variable in boxedOnEntry) {
-        assert(builder.isInMutableVariable(variable));
-        ir.Primitive value = builder.buildLocalGet(variable);
-        builder.environment.update(variable, value);
-      }
-    }
-  }
-
-  /// True if a jump inserted now will escape from a try block.
-  ///
-  /// Concretely, this is true when [enterTry] has been called without
-  /// its corresponding [leaveTry] call.
-  bool get isEscapingTry => _boxedTryVariables.isNotEmpty;
-}
-
-/// A class to collect 'forward' jumps.
-///
-/// A forward jump to a continuation in the sense of the CPS translation is
-/// a jump where the jump is emitted before any code in the body of the
-/// continuation is translated.  They have the property that continuation
-/// parameters and the environment for the translation of the body can be
-/// determined based on the invocations, before translating the body.  A
-/// [ForwardJumpCollector] can encapsulate a continuation where all the
-/// jumps are forward ones.
-///
-/// Examples of forward jumps in the translation are join points of
-/// if-then-else and breaks from loops.
-///
-/// The implementation strategy is that the collector collects invocation
-/// sites and the environments at those sites.  Then it constructs a
-/// continuation 'on demand' after all the jumps are seen.  It determines
-/// continuation parameters, the environment for the translation of code in
-/// the continuation body, and the arguments at the invocation site only
-/// after all the jumps to the continuation are seen.
-class ForwardJumpCollector extends JumpCollector {
-  final List<ir.InvokeContinuation> _invocations = <ir.InvokeContinuation>[];
-  final List<Environment> _invocationEnvironments = <Environment>[];
-
-  /// Construct a collector with a given base environment.
-  ///
-  /// The base environment is the one in scope at the site that the
-  /// continuation represented by this collector will be bound.  The
-  /// environment is copied by the collector.  Subsequent mutation of the
-  /// original environment will not affect the collector.
-  ForwardJumpCollector(Environment environment,
-      {JumpTarget target, bool hasExtraArgument: false})
-      : super(new Environment.from(environment), target, hasExtraArgument);
-
-  bool get isEmpty => _invocations.isEmpty;
-
-  ir.Continuation get continuation {
-    if (_continuation == null) _setContinuation();
-    return _continuation;
-  }
-
-  Environment get environment {
-    if (_continuation == null) _setContinuation();
-    return _continuationEnvironment;
-  }
-
-  void addJump(IrBuilder builder,
-      [ir.Primitive value, SourceInformation sourceInformation]) {
-    assert(_continuation == null);
-    _buildTryExit(builder);
-    ir.InvokeContinuation invoke =
-        new ir.InvokeContinuation.uninitialized(isEscapingTry: isEscapingTry);
-    builder.add(invoke);
-    _invocations.add(invoke);
-    // Truncate the environment at the invocation site so it only includes
-    // values that will be continuation arguments.  If an extra value is passed
-    // it will already be included in the continuation environment, but it is
-    // not present in the invocation environment.
-    int delta = builder.environment.length - _continuationEnvironment.length;
-    if (value != null) ++delta;
-    if (delta > 0) builder.environment.discard(delta);
-    if (value != null) builder.environment.extend(null, value);
-    _invocationEnvironments.add(builder.environment);
-    builder._current = null;
-    // TODO(kmillikin): Can we set builder.environment to null to make it
-    // less likely to mutate it?
-  }
-
-  void _setContinuation() {
-    assert(_continuation == null);
-    // We have seen all invocations of this continuation, and recorded the
-    // environment in effect at each invocation site.
-
-    // Compute the union of the assigned variables reaching the continuation.
-    //
-    // There is a continuation parameter for each environment variable
-    // that has a different value (from the environment in scope at the
-    // continuation binding) on some path.  `_environment` is initially a copy
-    // of the environment in scope at the continuation binding.  Compute the
-    // continuation parameters and add them to `_environment` so it will become
-    // the one in scope for the continuation body.
-    List<ir.Parameter> parameters = <ir.Parameter>[];
-    if (_invocationEnvironments.isNotEmpty) {
-      int length = _continuationEnvironment.length;
-      for (int varIndex = 0; varIndex < length; ++varIndex) {
-        for (Environment invocationEnvironment in _invocationEnvironments) {
-          assert(invocationEnvironment.sameDomain(
-              length, _continuationEnvironment));
-          if (invocationEnvironment[varIndex] !=
-              _continuationEnvironment[varIndex]) {
-            ir.Parameter parameter = new ir.Parameter(
-                _continuationEnvironment.index2variable[varIndex]);
-            _continuationEnvironment.index2value[varIndex] = parameter;
-            parameters.add(parameter);
-            break;
-          }
-        }
-      }
-    }
-    _continuation = new ir.Continuation(parameters);
-
-    // Compute the intersection of the parameters with the environments at
-    // each continuation invocation.  Initialize the invocations.
-    for (int jumpIndex = 0; jumpIndex < _invocations.length; ++jumpIndex) {
-      Environment invocationEnvironment = _invocationEnvironments[jumpIndex];
-      List<ir.Reference> arguments = <ir.Reference>[];
-      int varIndex = 0;
-      for (ir.Parameter parameter in parameters) {
-        varIndex =
-            _continuationEnvironment.index2value.indexOf(parameter, varIndex);
-        arguments.add(new ir.Reference(invocationEnvironment[varIndex]));
-      }
-      ir.InvokeContinuation invocation = _invocations[jumpIndex];
-      invocation.continuationRef = new ir.Reference(_continuation);
-      invocation.argumentRefs = arguments;
-    }
-  }
-}
-
-/// A class to collect 'backward' jumps.
-///
-/// A backward jump to a continuation in the sense of the CPS translation is
-/// a jump where some code in the body of the continuation is translated
-/// before the jump is emitted.  They have the property that the
-/// continuation parameters and the environment for the translation of the
-/// body must be determined before emitting all the invocations.  A
-/// [BackwardJumpCollector] can ecapsulate a continuation where some jumps
-/// are backward ones.
-///
-/// Examples of backward jumps in the translation are the recursive
-/// invocations of loop continuations.
-///
-/// The implementation strategy is that the collector inserts a continuation
-/// parameter for each variable in scope at the entry to the continuation,
-/// before emitting any jump to the continuation.  When a jump is added, it
-/// is given an argument for each continuation parameter.
-class BackwardJumpCollector extends JumpCollector {
-  /// Construct a collector with a given base environment.
-  ///
-  /// The base environment is the one in scope at the site that the
-  /// continuation represented by this collector will be bound.  The
-  /// translation of the continuation body will use an environment with the
-  /// same shape, but with fresh continuation parameters for each variable.
-  BackwardJumpCollector(Environment environment,
-      {JumpTarget target, bool hasExtraArgument: false})
-      : super(new Environment.fresh(environment), target, hasExtraArgument) {
-    List<ir.Parameter> parameters =
-        new List<ir.Parameter>.from(_continuationEnvironment.index2value);
-    _continuation = new ir.Continuation(parameters, isRecursive: true);
-  }
-
-  bool isEmpty = true;
-
-  ir.Continuation get continuation => _continuation;
-  Environment get environment => _continuationEnvironment;
-
-  void addJump(IrBuilder builder,
-      [ir.Primitive value, SourceInformation sourceInformation]) {
-    assert(_continuation.parameters.length <= builder.environment.length);
-    isEmpty = false;
-    _buildTryExit(builder);
-    // Truncate the environment at the invocation site so it only includes
-    // values that will be continuation arguments.  If an extra value is passed
-    // it will already be included in the continuation environment, but it is
-    // not present in the invocation environment.
-    int delta = builder.environment.length - _continuationEnvironment.length;
-    if (value != null) ++delta;
-    if (delta > 0) builder.environment.discard(delta);
-    if (value != null) builder.environment.extend(null, value);
-    builder.add(new ir.InvokeContinuation(
-        _continuation, builder.environment.index2value,
-        isRecursive: true, isEscapingTry: isEscapingTry));
-    builder._current = null;
-  }
-}
-
-/// 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;
-  }
-}
-
-/// Collect 'goto' jumps, continue to a labeled case from within a switch.
-///
-/// These jumps are unrestricted within the switch.  They can be forward or
-/// backward.  They are implemented by assigning to a state variable.
-class GotoJumpCollector extends JumpCollector {
-  bool isEmpty = true;
-  final ir.Continuation continuation = null;
-  final Environment environment = null;
-
-  int _stateVariableIndex;
-  int _stateValue;
-  JumpCollector _breakJoin;
-
-  GotoJumpCollector(JumpTarget target, this._stateVariableIndex,
-      this._stateValue, this._breakJoin)
-      : super.goto(target);
-
-  void addJump(IrBuilder builder,
-      [ir.Primitive value, SourceInformation sourceInformation]) {
-    isEmpty = false;
-    ir.Primitive constant = builder.buildIntegerConstant(_stateValue);
-    builder.environment.index2value[_stateVariableIndex] = constant;
-    builder.jumpTo(_breakJoin);
-  }
-}
-
-/// Function for building a node in the context of the current builder.
-typedef ir.Node BuildFunction(node);
-
-/// Function for building nodes in the context of the provided [builder].
-typedef ir.Node SubbuildFunction(IrBuilder builder);
-
-/// Mixin that provides encapsulated access to nested builders.
-abstract class IrBuilderMixin<N> {
-  IrBuilder _irBuilder;
-
-  /// Execute [f] with [builder] as the current builder.
-  withBuilder(IrBuilder builder, f()) {
-    assert(builder != null);
-    IrBuilder prev = _irBuilder;
-    _irBuilder = builder;
-    var result = f();
-    _irBuilder = prev;
-    return result;
-  }
-
-  /// The current builder.
-  IrBuilder get irBuilder {
-    assert(_irBuilder != null);
-    return _irBuilder;
-  }
-
-  /// Visits the [node].
-  ir.Primitive visit(N node);
-
-  /// Builds and returns the [ir.Node] for [node] or returns `null` if
-  /// [node] is `null`.
-  ir.Node build(N node) => node != null ? visit(node) : null;
-
-  /// Returns a closure that takes an [IrBuilder] and builds [node] in its
-  /// context using [build].
-  SubbuildFunction subbuild(N node) {
-    return (IrBuilder builder) => withBuilder(builder, () => build(node));
-  }
-
-  /// Returns a closure that takes an [IrBuilder] and runs [f] in its context.
-  SubbuildFunction nested(f()) {
-    return (IrBuilder builder) => withBuilder(builder, f);
-  }
-
-  /// Returns a closure that takes an [IrBuilder] and builds the sequence of
-  /// [nodes] in its context using [build].
-  // TODO(johnniwinther): Type [nodes] as `Iterable<N>` when `NodeList` uses
-  // `List` instead of `Link`.
-  SubbuildFunction subbuildSequence(/*Iterable<N>*/ nodes) {
-    return (IrBuilder builder) {
-      return withBuilder(builder, () => builder.buildSequence(nodes, build));
-    };
-  }
-}
-
-/// Shared state between delimited IrBuilders within the same function.
-class IrBuilderSharedState {
-  final GlobalProgramInformation program;
-
-  final BackendConstantEnvironment constants;
-
-  ConstantSystem get constantSystem => constants.constantSystem;
-
-  /// A stack of collectors for breaks.
-  List<JumpCollector> breakCollectors = <JumpCollector>[];
-
-  /// A stack of collectors for continues.
-  List<JumpCollector> continueCollectors = <JumpCollector>[];
-
-  final ExecutableElement currentElement;
-
-  final ir.Continuation returnContinuation = new ir.Continuation.retrn();
-
-  /// The target of a return from the function.
-  ///
-  /// 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;
-
-  /// Parameter holding the internal value of 'this' passed to the function.
-  ///
-  /// For nested functions, this is *not* captured receiver, but the function
-  /// object itself.
-  ir.Parameter thisParameter;
-
-  /// If non-null, this refers to the receiver (`this`) in the enclosing method.
-  ir.Primitive enclosingThis;
-
-  final List<ir.Parameter> functionParameters = <ir.Parameter>[];
-
-  /// Maps boxed locals to their location. These locals are not part of
-  /// the environment.
-  final Map<Local, ClosureLocation> boxedVariables = {};
-
-  IrBuilderSharedState(this.program, this.constants, this.currentElement) {
-    returnCollector = new ReturnJumpCollector(returnContinuation);
-  }
-}
-
-class ThisParameterLocal implements Local {
-  final ExecutableElement executableContext;
-  ThisParameterLocal(this.executableContext);
-  String get name => 'this';
-  toString() => 'ThisParameterLocal($executableContext)';
-}
-
-/// The IR builder maintains an environment and an IR fragment.
-///
-/// The IR fragment is an expression with a hole in it. The hole represents
-/// the focus where new expressions can be added. The fragment is implemented
-/// by [root] which is the root of the expression and [_current] which is the
-/// expression that immediately contains the hole. Not all expressions have a
-/// hole (e.g., invocations, which always occur in tail position, do not have a
-/// hole). Expressions with a hole have a plug method.
-///
-/// The environment maintains the reaching definition of each local variable,
-/// including some synthetic locals such as [TypeVariableLocal].
-///
-/// Internally, IR builders also maintains a [JumpCollector] stack and tracks
-/// which variables are currently boxed or held in a mutable local variable.
-class IrBuilder {
-  final List<ir.Parameter> _parameters = <ir.Parameter>[];
-
-  final IrBuilderSharedState state;
-
-  /// A map from variable indexes to their values.
-  ///
-  /// [BoxLocal]s map to their box. [LocalElement]s that are boxed are not
-  /// in the map; look up their [BoxLocal] instead.
-  Environment environment;
-
-  /// A map from mutable local variables to their [ir.MutableVariable]s.
-  ///
-  /// Mutable variables are treated as boxed.  Writes to them are observable
-  /// side effects.
-  Map<Local, ir.MutableVariable> mutableVariables;
-
-  ir.Expression root = null;
-  ir.Expression _current = null;
-
-  GlobalProgramInformation get program => state.program;
-
-  IrBuilder(GlobalProgramInformation program,
-      BackendConstantEnvironment constants, ExecutableElement currentElement)
-      : state = new IrBuilderSharedState(program, constants, currentElement),
-        environment = new Environment.empty(),
-        mutableVariables = <Local, ir.MutableVariable>{};
-
-  IrBuilder._internal(this.state, this.environment, this.mutableVariables);
-
-  /// Construct a delimited visitor for visiting a subtree.
-  ///
-  /// Build a subterm that is not (yet) connected to the CPS term.  The
-  /// delimited visitor has its own has its own context for building an IR
-  /// expression, so the built expression is not plugged into the parent's
-  /// context.  It has its own compile-time environment mapping local
-  /// variables to their values.  If an optional environment argument is
-  /// supplied, it is used as the builder's initial environment.  Otherwise
-  /// the environment is initially a copy of the parent builder's environment.
-  IrBuilder makeDelimitedBuilder([Environment env = null]) {
-    return new IrBuilder._internal(
-        state,
-        env != null ? env : new Environment.from(environment),
-        mutableVariables);
-  }
-
-  /// True if [local] should currently be accessed from a [ir.MutableVariable].
-  bool isInMutableVariable(Local local) {
-    return mutableVariables.containsKey(local);
-  }
-
-  /// Creates a [ir.MutableVariable] for the given local.
-  void makeMutableVariable(Local local) {
-    mutableVariables[local] = new ir.MutableVariable(local);
-  }
-
-  /// Remove an [ir.MutableVariable] for a local.
-  ///
-  /// Subsequent access to the local will be direct rather than through the
-  /// mutable variable.
-  void removeMutableVariable(Local local) {
-    mutableVariables.remove(local);
-  }
-
-  /// Gets the [MutableVariable] containing the value of [local].
-  ir.MutableVariable getMutableVariable(Local local) {
-    return mutableVariables[local];
-  }
-
-  bool get isOpen => root == null || _current != null;
-
-  List<ir.Primitive> buildFunctionHeader(Iterable<Local> parameters,
-      {ClosureScope closureScope, ClosureEnvironment env}) {
-    _createThisParameter();
-    _enterClosureEnvironment(env);
-    _enterScope(closureScope);
-    parameters.forEach(_createFunctionParameter);
-    return _parameters;
-  }
-
-  /// Creates a parameter for [local] and adds it to the current environment.
-  ir.Parameter _createLocalParameter(Local local) {
-    ir.Parameter parameter = new ir.Parameter(local);
-    _parameters.add(parameter);
-    environment.extend(local, parameter);
-    return parameter;
-  }
-
-  /// Plug an expression into the 'hole' in the context being accumulated.  The
-  /// empty context (just a hole) is represented by root (and current) being
-  /// null.  Since the hole in the current context is filled by this function,
-  /// the new hole must be in the newly added expression---which becomes the
-  /// new value of current.
-  void add(ir.Expression expr) {
-    assert(isOpen);
-    if (root == null) {
-      root = _current = expr;
-    } else {
-      _current = _current.plug(expr);
-    }
-  }
-
-  /// Create and add a new [LetPrim] for [primitive].
-  ir.Primitive addPrimitive(ir.Primitive primitive) {
-    add(new ir.LetPrim(primitive));
-    return primitive;
-  }
-
-  ir.Primitive buildInvokeStatic(Element element, Selector selector,
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    assert(!element.isLocal);
-    assert(!element.isInstanceMember);
-    assert(isOpen);
-    if (program.isJsInterop(element)) {
-      return buildInvokeJsInteropMember(element, arguments, sourceInformation);
-    }
-    return addPrimitive(
-        new ir.InvokeStatic(element, selector, arguments, sourceInformation));
-  }
-
-  ir.Primitive _buildInvokeSuper(Element target, Selector selector,
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    assert(target.isInstanceMember);
-    assert(isOpen);
-    return addPrimitive(new ir.InvokeMethodDirectly(
-        buildThis(), target, selector, arguments, sourceInformation));
-  }
-
-  ir.Primitive _buildInvokeDynamic(
-      ir.Primitive receiver,
-      Selector selector,
-      TypeMask mask,
-      List<ir.Primitive> arguments,
-      SourceInformation sourceInformation) {
-    assert(isOpen);
-    return addPrimitive(new ir.InvokeMethod(receiver, selector, mask, arguments,
-        sourceInformation: sourceInformation));
-  }
-
-  ir.Primitive _buildInvokeCall(
-      ir.Primitive target,
-      CallStructure callStructure,
-      TypeMask mask,
-      List<ir.Definition> arguments,
-      SourceInformation sourceInformation) {
-    Selector selector = callStructure.callSelector;
-    return _buildInvokeDynamic(
-        target, selector, mask, arguments, sourceInformation);
-  }
-
-  ir.Primitive buildStaticNoSuchMethod(Selector selector,
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    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],
-        sourceInformation);
-  }
-
-  /// Create a [ir.Constant] from [value] and add it to the CPS term.
-  ir.Constant buildConstant(ConstantValue value,
-      {SourceInformation sourceInformation}) {
-    assert(isOpen);
-    return addPrimitive(
-        new ir.Constant(value, sourceInformation: sourceInformation));
-  }
-
-  /// Create an integer constant and add it to the CPS term.
-  ir.Constant buildIntegerConstant(int value) {
-    return buildConstant(state.constantSystem.createInt(value));
-  }
-
-  /// Create a double constant and add it to the CPS term.
-  ir.Constant buildDoubleConstant(double value) {
-    return buildConstant(state.constantSystem.createDouble(value));
-  }
-
-  /// Create a Boolean constant and add it to the CPS term.
-  ir.Constant buildBooleanConstant(bool value) {
-    return buildConstant(state.constantSystem.createBool(value));
-  }
-
-  /// Create a null constant and add it to the CPS term.
-  ir.Constant buildNullConstant() {
-    return buildConstant(state.constantSystem.createNull());
-  }
-
-  /// Create a string constant and add it to the CPS term.
-  ir.Constant buildStringConstant(String value) {
-    return buildConstant(
-        state.constantSystem.createString(new ast.DartString.literal(value)));
-  }
-
-  /// Create a string constant and add it to the CPS term.
-  ir.Constant buildDartStringConstant(ast.DartString value) {
-    return buildConstant(state.constantSystem.createString(value));
-  }
-
-  /// Creates a non-constant list literal of the provided [type] and with the
-  /// provided [values].
-  ir.Primitive buildListLiteral(
-      InterfaceType type, Iterable<ir.Primitive> values,
-      {TypeMask allocationSiteType}) {
-    assert(isOpen);
-    return addPrimitive(new ir.LiteralList(type, values.toList(),
-        allocationSiteType: allocationSiteType));
-  }
-
-  /// Creates a conditional expression with the provided [condition] where the
-  /// then and else expression are created through the [buildThenExpression]
-  /// and [buildElseExpression] functions, respectively.
-  ir.Primitive buildConditional(
-      ir.Primitive condition,
-      ir.Primitive buildThenExpression(IrBuilder builder),
-      ir.Primitive buildElseExpression(IrBuilder builder),
-      SourceInformation sourceInformation) {
-    assert(isOpen);
-
-    // The then and else expressions are delimited.
-    IrBuilder thenBuilder = makeDelimitedBuilder();
-    IrBuilder elseBuilder = makeDelimitedBuilder();
-    ir.Primitive thenValue = buildThenExpression(thenBuilder);
-    ir.Primitive elseValue = buildElseExpression(elseBuilder);
-
-    // Treat the values of the subexpressions as named values in the
-    // environment, so they will be treated as arguments to the join-point
-    // continuation.  We know the environments are the right size because
-    // expressions cannot introduce variable bindings.
-    assert(environment.length == thenBuilder.environment.length);
-    assert(environment.length == elseBuilder.environment.length);
-    JumpCollector join =
-        new ForwardJumpCollector(environment, hasExtraArgument: true);
-    thenBuilder.jumpTo(join, thenValue);
-    elseBuilder.jumpTo(join, elseValue);
-
-    // Build the term
-    //   let cont join(x, ..., result) = [] in
-    //   let cont then() = [[thenPart]]; join(v, ...)
-    //        and else() = [[elsePart]]; join(v, ...)
-    //   in
-    //     if condition (then, else)
-    ir.Continuation thenContinuation = new ir.Continuation([]);
-    ir.Continuation elseContinuation = new ir.Continuation([]);
-    thenContinuation.body = thenBuilder.root;
-    elseContinuation.body = elseBuilder.root;
-    add(new ir.LetCont(
-        join.continuation,
-        new ir.LetCont.two(
-            thenContinuation,
-            elseContinuation,
-            new ir.Branch.strict(condition, thenContinuation, elseContinuation,
-                sourceInformation))));
-    environment = join.environment;
-    return environment.discard(1);
-  }
-
-  /**
-   * Add an explicit `return null` for functions that don't have a return
-   * statement on each branch. This includes functions with an empty body,
-   * such as `foo(){ }`.
-   */
-  void _ensureReturn() {
-    if (!isOpen) return;
-    ir.Constant constant = buildNullConstant();
-    add(new ir.InvokeContinuation(state.returnContinuation, [constant]));
-    _current = null;
-  }
-
-  /// Create a [ir.FunctionDefinition] using [root] as the body.
-  ///
-  /// The protocol for building a function is:
-  /// 1. Call [buildFunctionHeader].
-  /// 2. Call `buildXXX` methods to build the body.
-  /// 3. Call [makeFunctionDefinition] to finish.
-  ir.FunctionDefinition makeFunctionDefinition(
-      SourceInformation sourceInformation) {
-    _ensureReturn();
-    return new ir.FunctionDefinition(state.currentElement, state.thisParameter,
-        state.functionParameters, state.returnContinuation, root,
-        sourceInformation: sourceInformation);
-  }
-
-  /// Create a invocation of the [method] on the super class where the call
-  /// structure is defined [callStructure] and the argument values are defined
-  /// by [arguments].
-  ir.Primitive buildSuperMethodInvocation(
-      MethodElement method,
-      CallStructure callStructure,
-      List<ir.Primitive> arguments,
-      SourceInformation sourceInformation) {
-    // TODO(johnniwinther): This shouldn't be necessary.
-    SelectorKind kind = Elements.isOperatorName(method.name)
-        ? SelectorKind.OPERATOR
-        : SelectorKind.CALL;
-    Selector selector = new Selector(kind, method.memberName, callStructure);
-    return _buildInvokeSuper(method, selector, arguments, sourceInformation);
-  }
-
-  /// Create a read access of the [method] on the super class, i.e. a
-  /// closurization of [method].
-  ir.Primitive buildSuperMethodGet(
-      MethodElement method, SourceInformation sourceInformation) {
-    // TODO(johnniwinther): This should have its own ir node.
-    return _buildInvokeSuper(method, new Selector.getter(method.memberName),
-        const <ir.Primitive>[], sourceInformation);
-  }
-
-  /// Create a getter invocation of the [getter] on the super class.
-  ir.Primitive buildSuperGetterGet(
-      MethodElement getter, SourceInformation sourceInformation) {
-    // TODO(johnniwinther): This should have its own ir node.
-    return _buildInvokeSuper(getter, new Selector.getter(getter.memberName),
-        const <ir.Primitive>[], sourceInformation);
-  }
-
-  /// Create an setter invocation of the [setter] on the super class with
-  /// [value].
-  ir.Primitive buildSuperSetterSet(MethodElement setter, ir.Primitive value,
-      SourceInformation sourceInformation) {
-    // TODO(johnniwinther): This should have its own ir node.
-    _buildInvokeSuper(setter, new Selector.setter(setter.memberName),
-        <ir.Primitive>[value], sourceInformation);
-    return value;
-  }
-
-  /// Create an invocation of the index [method] on the super class with
-  /// the provided [index].
-  ir.Primitive buildSuperIndex(MethodElement method, ir.Primitive index,
-      SourceInformation sourceInformation) {
-    return _buildInvokeSuper(
-        method, new Selector.index(), <ir.Primitive>[index], sourceInformation);
-  }
-
-  /// Create an invocation of the index set [method] on the super class with
-  /// the provided [index] and [value].
-  ir.Primitive buildSuperIndexSet(MethodElement method, ir.Primitive index,
-      ir.Primitive value, SourceInformation sourceInformation) {
-    _buildInvokeSuper(method, new Selector.indexSet(),
-        <ir.Primitive>[index, value], sourceInformation);
-    return value;
-  }
-
-  /// Create a dynamic invocation on [receiver] where the method name and
-  /// argument structure are defined by [selector] and the argument values are
-  /// defined by [arguments].
-  ir.Primitive buildDynamicInvocation(
-      ir.Primitive receiver,
-      Selector selector,
-      TypeMask mask,
-      List<ir.Primitive> arguments,
-      SourceInformation sourceInformation) {
-    return _buildInvokeDynamic(
-        receiver, selector, mask, arguments, sourceInformation);
-  }
-
-  /// Create a dynamic getter invocation on [receiver] where the getter name is
-  /// defined by [selector].
-  ir.Primitive buildDynamicGet(ir.Primitive receiver, Selector selector,
-      TypeMask mask, SourceInformation sourceInformation) {
-    assert(selector.isGetter);
-    FieldElement field = program.locateSingleField(selector, mask);
-    if (field != null) {
-      // If the world says this resolves to a unique field, then it MUST be
-      // treated as a field access, since the getter might not be emitted.
-      return buildFieldGet(receiver, field, sourceInformation);
-    } else {
-      return _buildInvokeDynamic(
-          receiver, selector, mask, const <ir.Primitive>[], sourceInformation);
-    }
-  }
-
-  /// Create a dynamic setter invocation on [receiver] where the setter name and
-  /// argument are defined by [selector] and [value], respectively.
-  ir.Primitive buildDynamicSet(ir.Primitive receiver, Selector selector,
-      TypeMask mask, ir.Primitive value, SourceInformation sourceInformation) {
-    assert(selector.isSetter);
-    FieldElement field = program.locateSingleField(selector, mask);
-    if (field != null) {
-      // If the world says this resolves to a unique field, then it MUST be
-      // treated as a field access, since the setter might not be emitted.
-      buildFieldSet(receiver, field, value, sourceInformation);
-    } else {
-      _buildInvokeDynamic(
-          receiver, selector, mask, <ir.Primitive>[value], sourceInformation);
-    }
-    return value;
-  }
-
-  /// Create a dynamic index set invocation on [receiver] with the provided
-  /// [index] and [value].
-  ir.Primitive buildDynamicIndexSet(
-      ir.Primitive receiver,
-      TypeMask mask,
-      ir.Primitive index,
-      ir.Primitive value,
-      SourceInformation sourceInformation) {
-    _buildInvokeDynamic(receiver, new Selector.indexSet(), mask,
-        <ir.Primitive>[index, value], sourceInformation);
-    return value;
-  }
-
-  /// Create an invocation of the local [function] where argument structure is
-  /// defined by [callStructure] and the argument values are defined by
-  /// [arguments].
-  ir.Primitive buildLocalFunctionInvocation(
-      LocalFunctionElement function,
-      CallStructure callStructure,
-      List<ir.Primitive> arguments,
-      SourceInformation sourceInformation) {
-    // TODO(johnniwinther): Maybe this should have its own ir node.
-    return buildCallInvocation(
-        buildLocalGet(function), callStructure, arguments, sourceInformation);
-  }
-
-  /// Create a static invocation of [function].
-  ///
-  /// The arguments are not named and their values are defined by [arguments].
-  ir.Primitive buildStaticFunctionInvocation(MethodElement function,
-      List<ir.Primitive> arguments, SourceInformation 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(
-        getter, selector, const <ir.Primitive>[], sourceInformation);
-  }
-
-  /// Create a write access to the static [field] with the [value].
-  ir.Primitive buildStaticFieldSet(FieldElement field, ir.Primitive value,
-      SourceInformation sourceInformation) {
-    addPrimitive(new ir.SetStatic(field, value, sourceInformation));
-    return value;
-  }
-
-  /// Create a setter invocation of the static [setter] with the [value].
-  ir.Primitive buildStaticSetterSet(MethodElement setter, ir.Primitive value,
-      SourceInformation sourceInformation) {
-    Selector selector = new Selector.setter(setter.memberName);
-    buildInvokeStatic(
-        setter, selector, <ir.Primitive>[value], sourceInformation);
-    return value;
-  }
-
-  /// Create an erroneous invocation where argument structure is defined by
-  /// [selector] and the argument values are defined by [arguments].
-  // TODO(johnniwinther): Make this more fine-grained.
-  ir.Primitive buildErroneousInvocation(Element element, Selector selector,
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    // TODO(johnniwinther): This should have its own ir node.
-    return buildInvokeStatic(element, selector, arguments, sourceInformation);
-  }
-
-  /// Concatenate string values.  The arguments must be strings.
-  ir.Primitive buildStringConcatenation(
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    assert(isOpen);
-    return addPrimitive(new ir.ApplyBuiltinOperator(
-        ir.BuiltinOperator.StringConcatenate, arguments, sourceInformation));
-  }
-
-  /// Create an invocation of the `call` method of [functionExpression], where
-  /// the structure of arguments are given by [callStructure].
-  // TODO(johnniwinther): This should take a [TypeMask].
-  ir.Primitive buildCallInvocation(
-      ir.Primitive functionExpression,
-      CallStructure callStructure,
-      List<ir.Definition> arguments,
-      SourceInformation sourceInformation) {
-    return _buildInvokeCall(
-        functionExpression, callStructure, null, arguments, sourceInformation);
-  }
-
-  /// Creates an if-then-else statement with the provided [condition] where the
-  /// then and else branches are created through the [buildThenPart] and
-  /// [buildElsePart] functions, respectively.
-  ///
-  /// An if-then statement is created if [buildElsePart] is a no-op.
-  // TODO(johnniwinther): Unify implementation with [buildConditional] and
-  // [_buildLogicalOperator].
-  void buildIf(
-      ir.Primitive condition,
-      void buildThenPart(IrBuilder builder),
-      void buildElsePart(IrBuilder builder),
-      SourceInformation sourceInformation) {
-    assert(isOpen);
-
-    // The then and else parts are delimited.
-    IrBuilder thenBuilder = makeDelimitedBuilder();
-    IrBuilder elseBuilder = makeDelimitedBuilder();
-    buildThenPart(thenBuilder);
-    buildElsePart(elseBuilder);
-
-    // Build the term
-    // (Result =) let cont then() = [[thenPart]]
-    //                 and else() = [[elsePart]]
-    //            in
-    //              if condition (then, else)
-    ir.Continuation thenContinuation = new ir.Continuation([]);
-    ir.Continuation elseContinuation = new ir.Continuation([]);
-    // If exactly one of the then and else continuation bodies is open (i.e.,
-    // the other one has an exit on all paths), then Continuation.plug expects
-    // that continuation to be listed first.  Arbitrarily use [then, else]
-    // order otherwise.
-    List<ir.Continuation> arms = !thenBuilder.isOpen && elseBuilder.isOpen
-        ? <ir.Continuation>[elseContinuation, thenContinuation]
-        : <ir.Continuation>[thenContinuation, elseContinuation];
-
-    ir.Expression result = new ir.LetCont.many(
-        arms,
-        new ir.Branch.strict(
-            condition, thenContinuation, elseContinuation, sourceInformation));
-
-    JumpCollector join; // Null if there is no join.
-    if (thenBuilder.isOpen && elseBuilder.isOpen) {
-      // There is a join-point continuation.  Build the term
-      // 'let cont join(x, ...) = [] in Result' and plug invocations of the
-      // join-point continuation into the then and else continuations.
-      join = new ForwardJumpCollector(environment);
-      thenBuilder.jumpTo(join);
-      elseBuilder.jumpTo(join);
-      result = new ir.LetCont(join.continuation, result);
-    }
-
-    // The then or else term root could be null, but not both.  If there is
-    // a join then an InvokeContinuation was just added to both of them.  If
-    // there is no join, then at least one of them is closed and thus has a
-    // non-null root by the definition of the predicate isClosed.  In the
-    // case that one of them is null, it must be the only one that is open
-    // and thus contains the new hole in the context.  This case is handled
-    // after the branch is plugged into the current hole.
-    thenContinuation.body = thenBuilder.root;
-    elseContinuation.body = elseBuilder.root;
-
-    add(result);
-    if (join == null) {
-      // At least one subexpression is closed.
-      if (thenBuilder.isOpen) {
-        if (thenBuilder.root != null) _current = thenBuilder._current;
-        environment = thenBuilder.environment;
-      } else if (elseBuilder.isOpen) {
-        if (elseBuilder.root != null) _current = elseBuilder._current;
-        environment = elseBuilder.environment;
-      } else {
-        _current = null;
-      }
-    } else {
-      environment = join.environment;
-    }
-  }
-
-  void jumpTo(JumpCollector collector,
-      [ir.Primitive value, SourceInformation sourceInformation]) {
-    collector.addJump(this, value, sourceInformation);
-  }
-
-  void addRecursiveContinuation(BackwardJumpCollector collector) {
-    assert(environment.length == collector.environment.length);
-    add(new ir.LetCont(
-        collector.continuation,
-        new ir.InvokeContinuation(
-            collector.continuation, environment.index2value)));
-    environment = collector.environment;
-  }
-
-  /// Creates a for loop in which the initializer, condition, body, update are
-  /// created by [buildInitializer], [buildCondition], [buildBody] and
-  /// [buildUpdate], respectively.
-  ///
-  /// The jump [target] is used to identify which `break` and `continue`
-  /// statements that have this `for` statement as their target.
-  ///
-  /// The [closureScope] identifies variables that should be boxed in this loop.
-  /// This includes variables declared inside the body of the loop as well as
-  /// in the for-loop initializer.
-  ///
-  /// [loopVariables] is the list of variables declared in the for-loop
-  /// initializer.
-  void buildFor(
-      {SubbuildFunction buildInitializer,
-      SubbuildFunction buildCondition,
-      SourceInformation conditionSourceInformation,
-      SubbuildFunction buildBody,
-      SubbuildFunction buildUpdate,
-      JumpTarget target,
-      ClosureScope closureScope,
-      List<LocalElement> loopVariables}) {
-    assert(isOpen);
-
-    // For loops use four named continuations: the entry to the condition,
-    // the entry to the body, the loop exit, and the loop successor (break).
-    // The CPS translation of
-    // [[for (initializer; condition; update) body; successor]] is:
-    //
-    // _enterForLoopInitializer();
-    // [[initializer]];
-    // let cont loop(x, ...) =
-    //     let prim cond = [[condition]] in
-    //     let cont break(x, ...) = [[successor]] in
-    //     let cont exit() = break(v, ...) in
-    //     let cont body() =
-    //         _enterForLoopBody();
-    //         let cont continue(x, ...) =
-    //             _enterForLoopUpdate();
-    //             [[update]];
-    //             loop(v, ...) in
-    //         [[body]];
-    //         continue(v, ...) in
-    //     branch cond (body, exit) in
-    // loop(v, ...)
-    //
-    // If there are no breaks in the body, the break continuation is inlined
-    // in the exit continuation (i.e., the translation of the successor
-    // statement occurs in the exit continuation).  If there is only one
-    // invocation of the continue continuation (i.e., no continues in the
-    // body), the continue continuation is inlined in the body.
-    _enterForLoopInitializer(closureScope, loopVariables);
-    buildInitializer(this);
-
-    JumpCollector loop = new BackwardJumpCollector(environment);
-    addRecursiveContinuation(loop);
-
-    ir.Primitive condition = buildCondition(this);
-    if (condition == null) {
-      // If the condition is empty then the body is entered unconditionally.
-      condition = buildBooleanConstant(true);
-    }
-    JumpCollector breakCollector =
-        new ForwardJumpCollector(environment, target: target);
-
-    // Use a pair of builders for the body, one for the entry code if any
-    // and one for the body itself.  We only decide whether to insert a
-    // continue continuation until after translating the body and there is no
-    // way to insert such a continuation between the entry code and the body
-    // if they are translated together.
-    IrBuilder outerBodyBuilder = makeDelimitedBuilder();
-    outerBodyBuilder._enterForLoopBody(closureScope, loopVariables);
-    JumpCollector continueCollector =
-        new ForwardJumpCollector(outerBodyBuilder.environment, target: target);
-
-    IrBuilder innerBodyBuilder = outerBodyBuilder.makeDelimitedBuilder();
-    state.breakCollectors.add(breakCollector);
-    state.continueCollectors.add(continueCollector);
-    buildBody(innerBodyBuilder);
-    assert(state.breakCollectors.last == breakCollector);
-    assert(state.continueCollectors.last == continueCollector);
-    state.breakCollectors.removeLast();
-    state.continueCollectors.removeLast();
-
-    // The binding of the continue continuation should occur as late as
-    // possible, that is, at the nearest common ancestor of all the continue
-    // sites in the body.  However, that is difficult to compute here, so it
-    // is instead placed just outside the translation of the loop body.  In
-    // the case where there are no continues in the body, the updates are
-    // translated immediately after the body.
-    bool hasContinues = !continueCollector.isEmpty;
-    IrBuilder updateBuilder;
-    if (hasContinues) {
-      if (innerBodyBuilder.isOpen) innerBodyBuilder.jumpTo(continueCollector);
-      updateBuilder = makeDelimitedBuilder(continueCollector.environment);
-    } else {
-      updateBuilder = innerBodyBuilder;
-    }
-    updateBuilder._enterForLoopUpdate(closureScope, loopVariables);
-    buildUpdate(updateBuilder);
-    if (updateBuilder.isOpen) updateBuilder.jumpTo(loop);
-    // Connect the inner and outer body builders.  This is done only after
-    // it is guaranteed that the updateBuilder has a non-empty term.
-    if (hasContinues) {
-      outerBodyBuilder.add(new ir.LetCont(
-          continueCollector.continuation, innerBodyBuilder.root));
-      continueCollector.continuation.body = updateBuilder.root;
-    } else {
-      outerBodyBuilder.add(innerBodyBuilder.root);
-    }
-
-    // Create loop exit and body entry continuations and a branch to them.
-    ir.Continuation exitContinuation = new ir.Continuation([]);
-    ir.Continuation bodyContinuation = new ir.Continuation([]);
-    bodyContinuation.body = outerBodyBuilder.root;
-    // Note the order of continuations: the first one is the one that will
-    // be filled by LetCont.plug.
-    ir.LetCont branch = new ir.LetCont.two(
-        exitContinuation,
-        bodyContinuation,
-        new ir.Branch.strict(condition, bodyContinuation, exitContinuation,
-            conditionSourceInformation));
-    // If there are breaks in the body, then there must be a join-point
-    // continuation for the normal exit and the breaks.  Otherwise, the
-    // successor is translated in the hole in the exit continuation.
-    bool hasBreaks = !breakCollector.isEmpty;
-    ir.LetCont letBreak;
-    if (hasBreaks) {
-      IrBuilder exitBuilder = makeDelimitedBuilder();
-      exitBuilder.jumpTo(breakCollector);
-      exitContinuation.body = exitBuilder.root;
-      letBreak = new ir.LetCont(breakCollector.continuation, branch);
-      add(letBreak);
-      environment = breakCollector.environment;
-    } else {
-      add(branch);
-    }
-  }
-
-  /// Creates a for-in loop, `for (v in e) b`.
-  ///
-  /// [buildExpression] creates the expression, `e`. The variable, `v`, can
-  /// take one of three forms:
-  ///     1) `v` can be declared within the for-in statement, like in
-  ///        `for (var v in e)`, in which case, [buildVariableDeclaration]
-  ///        creates its declaration and [variableElement] is the element for
-  ///        the declared variable,
-  ///     2) `v` is predeclared statically known variable, that is top-level,
-  ///        static, or local variable, in which case [variableElement] is the
-  ///        variable element, and [variableSelector] defines its write access,
-  ///     3) `v` is an instance variable in which case [variableSelector]
-  ///        defines its write access.
-  /// [buildBody] creates the body, `b`, of the loop. The jump [target] is used
-  /// to identify which `break` and `continue` statements that have this for-in
-  /// statement as their target.
-  void buildForIn(
-      {SubbuildFunction buildExpression,
-      SubbuildFunction buildVariableDeclaration,
-      Element variableElement,
-      Selector variableSelector,
-      TypeMask variableMask,
-      SourceInformation variableSetSourceInformation,
-      TypeMask currentMask,
-      SourceInformation currentSourceInformation,
-      TypeMask iteratorMask,
-      SourceInformation iteratorSourceInformation,
-      TypeMask moveNextMask,
-      SourceInformation moveNextSourceInformation,
-      SubbuildFunction buildBody,
-      JumpTarget target,
-      ClosureScope closureScope,
-      SourceInformation conditionSourceInformation}) {
-    // The for-in loop
-    //
-    // for (a in e) s;
-    //
-    // Is compiled analogously to:
-    //
-    // it = e.iterator;
-    // while (it.moveNext()) {
-    //   var a = it.current;
-    //   s;
-    // }
-
-    // Fill the current hole with:
-    // let prim expressionReceiver = [[e]] in
-    // let cont iteratorInvoked(iterator) =
-    //     [ ]
-    // in expressionReceiver.iterator () iteratorInvoked
-    ir.Primitive expressionReceiver = buildExpression(this);
-    List<ir.Primitive> emptyArguments = <ir.Primitive>[];
-    ir.Primitive iterator = addPrimitive(new ir.InvokeMethod(
-        expressionReceiver, Selectors.iterator, iteratorMask, emptyArguments));
-
-    // Fill with:
-    // let cont loop(x, ...) =
-    //     let cont moveNextInvoked(condition) =
-    //         [ ]
-    //     in iterator.moveNext () moveNextInvoked
-    // in loop(v, ...)
-    JumpCollector loop = new BackwardJumpCollector(environment, target: target);
-    addRecursiveContinuation(loop);
-    ir.Primitive condition = addPrimitive(new ir.InvokeMethod(
-        iterator, Selectors.moveNext, moveNextMask, emptyArguments));
-
-    // As a delimited term, build:
-    // <<BODY>> =
-    //   _enterScope();
-    //   [[variableDeclaration]]
-    //   let cont currentInvoked(currentValue) =
-    //       [[a = currentValue]];
-    //       [ ]
-    //   in iterator.current () currentInvoked
-    IrBuilder bodyBuilder = makeDelimitedBuilder();
-    bodyBuilder._enterScope(closureScope);
-    if (buildVariableDeclaration != null) {
-      buildVariableDeclaration(bodyBuilder);
-    }
-    ir.Primitive currentValue = bodyBuilder.addPrimitive(new ir.InvokeMethod(
-        iterator, Selectors.current, currentMask, emptyArguments,
-        sourceInformation: currentSourceInformation));
-    // TODO(johnniwinther): Extract this as a provided strategy.
-    if (Elements.isLocal(variableElement)) {
-      bodyBuilder.buildLocalVariableSet(
-          variableElement, currentValue, variableSetSourceInformation);
-    } 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 comparison below.  It can be the case that an element isError
-      // and isMalformed.
-      if (Elements.isError(variableElement)) {
-        bodyBuilder.buildStaticNoSuchMethod(
-            selector, value, variableSetSourceInformation);
-      } else {
-        bodyBuilder.buildErroneousInvocation(
-            variableElement, selector, value, variableSetSourceInformation);
-      }
-    } else if (Elements.isStaticOrTopLevel(variableElement)) {
-      if (variableElement.isField) {
-        bodyBuilder.addPrimitive(new ir.SetStatic(
-            variableElement, currentValue, variableSetSourceInformation));
-      } else {
-        bodyBuilder.buildStaticSetterSet(
-            variableElement, currentValue, variableSetSourceInformation);
-      }
-    } else {
-      ir.Primitive receiver = bodyBuilder.buildThis();
-      assert(receiver != null);
-      bodyBuilder.buildDynamicSet(receiver, variableSelector, variableMask,
-          currentValue, variableSetSourceInformation);
-    }
-
-    // Translate the body in the hole in the delimited term above, and add
-    // a jump to the loop if control flow is live after the body.
-    JumpCollector breakCollector =
-        new ForwardJumpCollector(environment, target: target);
-    state.breakCollectors.add(breakCollector);
-    state.continueCollectors.add(loop);
-    buildBody(bodyBuilder);
-    assert(state.breakCollectors.last == breakCollector);
-    assert(state.continueCollectors.last == loop);
-    state.breakCollectors.removeLast();
-    state.continueCollectors.removeLast();
-    if (bodyBuilder.isOpen) bodyBuilder.jumpTo(loop);
-
-    // Create body entry and loop exit continuations and a branch to them.
-    //
-    // let cont exit() = [ ]
-    //      and body() = <<BODY>>
-    // in branch condition (body, exit)
-    ir.Continuation exitContinuation = new ir.Continuation([]);
-    ir.Continuation bodyContinuation = new ir.Continuation([]);
-    bodyContinuation.body = bodyBuilder.root;
-    // Note the order of continuations: the first one is the one that will
-    // be filled by LetCont.plug.
-    ir.LetCont branch = new ir.LetCont.two(
-        exitContinuation,
-        bodyContinuation,
-        new ir.Branch.strict(condition, bodyContinuation, exitContinuation,
-            conditionSourceInformation));
-    // If there are breaks in the body, then there must be a join-point
-    // continuation for the normal exit and the breaks.  Otherwise, the
-    // successor is translated in the hole in the exit continuation.
-    bool hasBreaks = !breakCollector.isEmpty;
-    ir.LetCont letBreak;
-    if (hasBreaks) {
-      IrBuilder exitBuilder = makeDelimitedBuilder();
-      exitBuilder.jumpTo(breakCollector);
-      exitContinuation.body = exitBuilder.root;
-      letBreak = new ir.LetCont(breakCollector.continuation, branch);
-      add(letBreak);
-      environment = breakCollector.environment;
-    } else {
-      add(branch);
-    }
-  }
-
-  /// Creates a while loop in which the condition and body are created by
-  /// [buildCondition] and [buildBody], respectively.
-  ///
-  /// The jump [target] is used to identify which `break` and `continue`
-  /// statements that have this `while` statement as their target.
-  void buildWhile(
-      {SubbuildFunction buildCondition,
-      SubbuildFunction buildBody,
-      JumpTarget target,
-      ClosureScope closureScope,
-      SourceInformation sourceInformation}) {
-    assert(isOpen);
-    // While loops use four named continuations: the entry to the body, the
-    // loop exit, the loop back edge (continue), and the loop exit (break).
-    // The CPS translation of [[while (condition) body; successor]] is:
-    //
-    // let cont continue(x, ...) =
-    //     let prim cond = [[condition]] in
-    //     let cont break(x, ...) = [[successor]] in
-    //     let cont exit() = break(v, ...)
-    //          and body() =
-    //                _enterScope();
-    //                [[body]];
-    //                continue(v, ...)
-    //     in branch cond (body, exit)
-    // in continue(v, ...)
-    //
-    // If there are no breaks in the body, the break continuation is inlined
-    // in the exit continuation (i.e., the translation of the successor
-    // statement occurs in the exit continuation).
-    JumpCollector loop = new BackwardJumpCollector(environment, target: target);
-    addRecursiveContinuation(loop);
-
-    ir.Primitive condition = buildCondition(this);
-
-    JumpCollector breakCollector =
-        new ForwardJumpCollector(environment, target: target);
-
-    IrBuilder bodyBuilder = makeDelimitedBuilder();
-    bodyBuilder._enterScope(closureScope);
-    state.breakCollectors.add(breakCollector);
-    state.continueCollectors.add(loop);
-    buildBody(bodyBuilder);
-    assert(state.breakCollectors.last == breakCollector);
-    assert(state.continueCollectors.last == loop);
-    state.breakCollectors.removeLast();
-    state.continueCollectors.removeLast();
-    if (bodyBuilder.isOpen) bodyBuilder.jumpTo(loop);
-
-    // Create body entry and loop exit continuations and a branch to them.
-    ir.Continuation exitContinuation = new ir.Continuation([]);
-    ir.Continuation bodyContinuation = new ir.Continuation([]);
-    bodyContinuation.body = bodyBuilder.root;
-    // Note the order of continuations: the first one is the one that will
-    // be filled by LetCont.plug.
-    ir.LetCont branch = new ir.LetCont.two(
-        exitContinuation,
-        bodyContinuation,
-        new ir.Branch.strict(
-            condition, bodyContinuation, exitContinuation, sourceInformation));
-    // If there are breaks in the body, then there must be a join-point
-    // continuation for the normal exit and the breaks.  Otherwise, the
-    // successor is translated in the hole in the exit continuation.
-    bool hasBreaks = !breakCollector.isEmpty;
-    ir.LetCont letBreak;
-    if (hasBreaks) {
-      IrBuilder exitBuilder = makeDelimitedBuilder();
-      exitBuilder.jumpTo(breakCollector);
-      exitContinuation.body = exitBuilder.root;
-      letBreak = new ir.LetCont(breakCollector.continuation, branch);
-      add(letBreak);
-      environment = breakCollector.environment;
-    } else {
-      add(branch);
-    }
-  }
-
-  /// Creates a do-while loop.
-  ///
-  /// The body and condition are created by [buildBody] and [buildCondition].
-  /// The jump target [target] is the target of `break` and `continue`
-  /// statements in the body that have the loop as their target.
-  /// [closureScope] contains all the variables declared in the loop (but not
-  /// declared in some inner closure scope).
-  void buildDoWhile(
-      {SubbuildFunction buildBody,
-      SubbuildFunction buildCondition,
-      JumpTarget target,
-      ClosureScope closureScope,
-      SourceInformation sourceInformation}) {
-    assert(isOpen);
-    // The CPS translation of [[do body; while (condition); successor]] is:
-    //
-    // let cont break(x, ...) = [[successor]] in
-    // let cont rec loop(x, ...) =
-    //   let cont continue(x, ...) =
-    //     let prim cond = [[condition]] in
-    //       let cont exit() = break(v, ...)
-    //            and repeat() = loop(v, ...)
-    //       in branch cond (repeat, exit)
-    //   in [[body]]; continue(v, ...)
-    // in loop(v, ...)
-    IrBuilder loopBuilder = makeDelimitedBuilder();
-    JumpCollector loop =
-        new BackwardJumpCollector(loopBuilder.environment, target: target);
-    loopBuilder.addRecursiveContinuation(loop);
-
-    // Translate the body.
-    JumpCollector breakCollector =
-        new ForwardJumpCollector(environment, target: target);
-    JumpCollector continueCollector =
-        new ForwardJumpCollector(loopBuilder.environment, target: target);
-    IrBuilder bodyBuilder = loopBuilder.makeDelimitedBuilder();
-    bodyBuilder._enterScope(closureScope);
-    state.breakCollectors.add(breakCollector);
-    state.continueCollectors.add(continueCollector);
-    buildBody(bodyBuilder);
-    assert(state.breakCollectors.last == breakCollector);
-    assert(state.continueCollectors.last == continueCollector);
-    state.breakCollectors.removeLast();
-    state.continueCollectors.removeLast();
-    if (bodyBuilder.isOpen) bodyBuilder.jumpTo(continueCollector);
-
-    // Construct the body of the continue continuation (i.e., the condition).
-    // <Continue> =
-    // let prim cond = [[condition]] in
-    //   let cont exit() = break(v, ...)
-    //        and repeat() = loop(v, ...)
-    //   in branch cond (repeat, exit)
-    IrBuilder continueBuilder = loopBuilder.makeDelimitedBuilder();
-    continueBuilder.environment = continueCollector.environment;
-    ir.Primitive condition = buildCondition(continueBuilder);
-
-    ir.Continuation exitContinuation = new ir.Continuation([]);
-    IrBuilder exitBuilder = continueBuilder.makeDelimitedBuilder();
-    exitBuilder.jumpTo(breakCollector);
-    exitContinuation.body = exitBuilder.root;
-    ir.Continuation repeatContinuation = new ir.Continuation([]);
-    IrBuilder repeatBuilder = continueBuilder.makeDelimitedBuilder();
-    repeatBuilder.jumpTo(loop);
-    repeatContinuation.body = repeatBuilder.root;
-
-    continueBuilder.add(new ir.LetCont.two(
-        exitContinuation,
-        repeatContinuation,
-        new ir.Branch.strict(condition, repeatContinuation, exitContinuation,
-            sourceInformation)));
-    continueCollector.continuation.body = continueBuilder.root;
-
-    // Construct the loop continuation (i.e., the body and condition).
-    // <Loop> =
-    // let cont continue(x, ...) =
-    //   <Continue>
-    // in [[body]]; continue(v, ...)
-    loopBuilder
-        .add(new ir.LetCont(continueCollector.continuation, bodyBuilder.root));
-
-    // And tie it all together.
-    add(new ir.LetCont(breakCollector.continuation, loopBuilder.root));
-    environment = breakCollector.environment;
-  }
-
-  void buildSimpleSwitch(JumpCollector join, List<SwitchCaseInfo> cases,
-      SubbuildFunction buildDefaultBody) {
-    IrBuilder casesBuilder = makeDelimitedBuilder();
-    for (SwitchCaseInfo caseInfo in cases) {
-      ir.Primitive condition = caseInfo.buildCondition(casesBuilder);
-      IrBuilder thenBuilder = makeDelimitedBuilder();
-      caseInfo.buildBody(thenBuilder);
-      ir.Continuation thenContinuation = new ir.Continuation([]);
-      thenContinuation.body = thenBuilder.root;
-      ir.Continuation elseContinuation = new ir.Continuation([]);
-      // A LetCont.two term has a hole as the body of the first listed
-      // continuation, to be plugged by the translation.  Therefore put the
-      // else continuation first.
-      casesBuilder.add(new ir.LetCont.two(
-          elseContinuation,
-          thenContinuation,
-          new ir.Branch.strict(condition, thenContinuation, elseContinuation,
-              caseInfo.sourceInformation)));
-    }
-
-    if (buildDefaultBody == null) {
-      casesBuilder.jumpTo(join);
-    } else {
-      buildDefaultBody(casesBuilder);
-    }
-
-    if (!join.isEmpty) {
-      add(new ir.LetCont(join.continuation, casesBuilder.root));
-      environment = join.environment;
-    } else if (casesBuilder.root != null) {
-      add(casesBuilder.root);
-      _current = casesBuilder._current;
-      environment = casesBuilder.environment;
-    } else {
-      // The translation of the cases did not emit any code.
-    }
-  }
-
-  /// Utility function to translate try/catch into the IR.
-  ///
-  /// The translation treats try/finally and try/catch/finally as if they
-  /// were macro-expanded into try/catch.  This utility function generates
-  /// that try/catch.  The function is parameterized over a list of variables
-  /// that should be boxed on entry to the try, and over functions to emit
-  /// code for entering the try, building the try body, leaving the try body,
-  /// building the catch body, and leaving the entire try/catch.
-  ///
-  /// Please see the function's implementation for where these functions are
-  /// called.
-  void _helpBuildTryCatch(
-      TryStatementInfo variables,
-      void enterTry(IrBuilder builder),
-      SubbuildFunction buildTryBlock,
-      void leaveTry(IrBuilder builder),
-      List<ir.Parameter> buildCatch(IrBuilder builder, JumpCollector join),
-      void leaveTryCatch(
-          IrBuilder builder, JumpCollector join, ir.Expression body)) {
-    JumpCollector join = new ForwardJumpCollector(environment);
-    IrBuilder tryCatchBuilder = makeDelimitedBuilder();
-
-    // Variables treated as mutable in a try are not mutable outside of it.
-    // Work with a copy of the outer builder's mutable variables.
-    tryCatchBuilder.mutableVariables =
-        new Map<Local, ir.MutableVariable>.from(mutableVariables);
-    for (LocalVariableElement variable in variables.boxedOnEntry) {
-      assert(!tryCatchBuilder.isInMutableVariable(variable));
-      ir.Primitive value = tryCatchBuilder.buildLocalGet(variable);
-      tryCatchBuilder.makeMutableVariable(variable);
-      tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
-    }
-
-    IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder();
-    enterTry(tryBuilder);
-    buildTryBlock(tryBuilder);
-    if (tryBuilder.isOpen) {
-      join.enterTry(variables.boxedOnEntry);
-      tryBuilder.jumpTo(join);
-      join.leaveTry();
-    }
-    leaveTry(tryBuilder);
-
-    IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
-    for (LocalVariableElement variable in variables.boxedOnEntry) {
-      assert(catchBuilder.isInMutableVariable(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);
-      catchBuilder.environment.update(variable, value);
-    }
-
-    List<ir.Parameter> catchParameters = buildCatch(catchBuilder, join);
-    ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
-    catchContinuation.body = catchBuilder.root;
-    tryCatchBuilder.add(new ir.LetHandler(catchContinuation, tryBuilder.root));
-
-    leaveTryCatch(this, join, tryCatchBuilder.root);
-  }
-
-  /// Translates a try/catch.
-  ///
-  /// [variables] provides information on local variables declared and boxed
-  /// within the try body.
-  /// [buildTryBlock] builds the try block.
-  /// [catchClauseInfos] provides access to the catch type, exception variable,
-  /// and stack trace variable, and a function for building the catch block.
-  void buildTryCatch(TryStatementInfo variables, SubbuildFunction buildTryBlock,
-      List<CatchClauseInfo> catchClauseInfos) {
-    assert(isOpen);
-    // Catch handlers are in scope for their body.  The CPS translation of
-    // [[try tryBlock catch (ex, st) catchBlock; successor]] is:
-    //
-    // let cont join(v0, v1, ...) = [[successor]] in
-    //   let mutable m0 = x0 in
-    //     let mutable m1 = x1 in
-    //       ...
-    //       let handler catch_(ex, st) =
-    //         let prim p0 = GetMutable(m0) in
-    //           let prim p1 = GetMutable(m1) in
-    //             ...
-    //             [[catchBlock]]
-    //             join(p0, p1, ...)
-    //       in
-    //         [[tryBlock]]
-    //         let prim p0' = GetMutable(m0) in
-    //           let prim p1' = GetMutable(m1) in
-    //             ...
-    //             join(p0', p1', ...)
-    //
-    // In other words, both the try and catch block are in the scope of the
-    // join-point continuation, and they are both in the scope of a sequence
-    // of mutable bindings for the variables assigned in the try.  The join-
-    // point continuation is not in the scope of these mutable bindings.
-    // The tryBlock is in the scope of a binding for the catch handler.  Each
-    // instruction (specifically, each call) in the tryBlock is in the dynamic
-    // scope of the handler.  The mutable bindings are dereferenced at the end
-    // of the try block and at the beginning of the catch block, so the
-    // variables are unboxed in the catch block and at the join point.
-
-    void enterTry(IrBuilder builder) {
-      // On entry to try of try/catch, update the builder's state to reflect the
-      // variables that have been boxed.
-      void interceptJump(JumpCollector collector) {
-        collector.enterTry(variables.boxedOnEntry);
-      }
-      builder.state.breakCollectors.forEach(interceptJump);
-      builder.state.continueCollectors.forEach(interceptJump);
-      interceptJump(builder.state.returnCollector);
-    }
-
-    void leaveTry(IrBuilder builder) {
-      // On exit from try of try/catch, update the builder's state to reflect
-      // the variables that are no longer boxed.
-      void restoreJump(JumpCollector collector) {
-        collector.leaveTry();
-      }
-      builder.state.breakCollectors.forEach(restoreJump);
-      builder.state.continueCollectors.forEach(restoreJump);
-      restoreJump(builder.state.returnCollector);
-    }
-
-    List<ir.Parameter> buildCatch(IrBuilder builder, JumpCollector join) {
-      // Translate the catch clauses.  Multiple clauses are translated as if
-      // they were explicitly cascaded if/else type tests.
-
-      // Handlers are always translated as having both exception and stack trace
-      // parameters.  Multiple clauses do not have to use the same names for
-      // them.  Choose the first of each as the name hint for the respective
-      // handler parameter.
-      ir.Parameter exceptionParameter =
-          new ir.Parameter(catchClauseInfos.first.exceptionVariable);
-      LocalVariableElement traceVariable;
-      CatchClauseInfo catchAll;
-      for (int i = 0; i < catchClauseInfos.length; ++i) {
-        CatchClauseInfo info = catchClauseInfos[i];
-        if (info.type == null) {
-          catchAll = info;
-          catchClauseInfos.length = i;
-          break;
-        }
-        if (traceVariable == null) {
-          traceVariable = info.stackTraceVariable;
-        }
-      }
-      ir.Parameter traceParameter = new ir.Parameter(traceVariable);
-
-      ir.Expression buildCatchClause(CatchClauseInfo clause) {
-        IrBuilder clauseBuilder = builder.makeDelimitedBuilder();
-        if (clause.exceptionVariable != null) {
-          clauseBuilder.declareLocalVariable(clause.exceptionVariable,
-              initialValue: exceptionParameter);
-        }
-        if (clause.stackTraceVariable != null) {
-          clauseBuilder.declareLocalVariable(clause.stackTraceVariable,
-              initialValue: traceParameter);
-        }
-        clause.buildCatchBlock(clauseBuilder);
-        if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join);
-        return clauseBuilder.root;
-      }
-
-      // Expand multiple catch clauses into an explicit if/then/else.  Iterate
-      // them in reverse so the current block becomes the next else block.
-      ir.Expression catchBody =
-          (catchAll == null) ? new ir.Rethrow() : buildCatchClause(catchAll);
-      for (CatchClauseInfo clause in catchClauseInfos.reversed) {
-        ir.Continuation thenContinuation = new ir.Continuation([]);
-        ir.Continuation elseContinuation = new ir.Continuation([]);
-        thenContinuation.body = buildCatchClause(clause);
-        elseContinuation.body = catchBody;
-
-        // Build the type test guarding this clause. We can share the
-        // environment with the nested builder because this part cannot mutate
-        // it.
-        IrBuilder checkBuilder = builder.makeDelimitedBuilder(environment);
-        ir.Primitive typeMatches = checkBuilder.buildTypeOperator(
-            exceptionParameter, clause.type, clause.sourceInformation,
-            isTypeTest: true);
-        checkBuilder.add(new ir.LetCont.two(
-            thenContinuation,
-            elseContinuation,
-            new ir.Branch.strict(typeMatches, thenContinuation,
-                elseContinuation, clause.sourceInformation)));
-        catchBody = checkBuilder.root;
-      }
-      builder.add(catchBody);
-
-      return <ir.Parameter>[exceptionParameter, traceParameter];
-    }
-
-    void leaveTryCatch(
-        IrBuilder builder, JumpCollector join, ir.Expression body) {
-      // Add the binding for the join-point continuation and continue the
-      // translation in its body.
-      builder.add(new ir.LetCont(join.continuation, body));
-      builder.environment = join.environment;
-    }
-
-    _helpBuildTryCatch(variables, enterTry, buildTryBlock, leaveTry, buildCatch,
-        leaveTryCatch);
-  }
-
-  /// Translates a try/finally.
-  ///
-  /// [variables] provides information on local variables declared and boxed
-  /// within the try body.
-  /// [buildTryBlock] builds the try block.
-  /// [buildFinallyBlock] builds the finally block.
-  void buildTryFinally(TryStatementInfo variables,
-      SubbuildFunction buildTryBlock, SubbuildFunction buildFinallyBlock) {
-    assert(isOpen);
-    // Try/finally is implemented in terms of try/catch and by duplicating the
-    // code for finally at all exits.  The encoding is:
-    //
-    // try tryBlock finally finallyBlock
-    // ==>
-    // try tryBlock catch (ex, st) { finallyBlock; rethrow } finallyBlock
-    //
-    // Where in tryBlock, all of the break, continue, and return exits are
-    // translated as jumps to continuations (bound outside the catch handler)
-    // that include the finally code followed by a break, continue, or
-    // return respectively.
-
-    List<JumpCollector> savedBreaks, newBreaks, savedContinues, newContinues;
-    JumpCollector savedReturn, newReturn;
-    void enterTry(IrBuilder builder) {
-      // On entry to the try of try/finally, update the builder's state to
-      // relfect the variables that have been boxed.  Then intercept all break,
-      // continue, and return jumps out of the try so that they can go to
-      // continuations that include the finally code.
-      JumpCollector interceptJump(JumpCollector collector) {
-        JumpCollector result =
-            new ForwardJumpCollector(environment, target: collector.target);
-        result.enterTry(variables.boxedOnEntry);
-        return result;
-      }
-      savedBreaks = builder.state.breakCollectors;
-      savedContinues = builder.state.continueCollectors;
-      savedReturn = builder.state.returnCollector;
-
-      builder.state.breakCollectors =
-          newBreaks = savedBreaks.map(interceptJump).toList();
-      builder.state.continueCollectors =
-          newContinues = savedContinues.map(interceptJump).toList();
-      builder.state.returnCollector = newReturn =
-          new ForwardJumpCollector(environment, hasExtraArgument: true)
-            ..enterTry(variables.boxedOnEntry);
-    }
-
-    void leaveTry(IrBuilder builder) {
-      // On exit from the try of try/finally, update the builder's state to
-      // reflect the variables that are no longer boxed and restore the
-      // original, unintercepted break, continue, and return targets.
-      void restoreJump(JumpCollector collector) {
-        collector.leaveTry();
-      }
-      newBreaks.forEach(restoreJump);
-      newContinues.forEach(restoreJump);
-      newReturn.leaveTry();
-      builder.state.breakCollectors = savedBreaks;
-      builder.state.continueCollectors = savedContinues;
-      builder.state.returnCollector = savedReturn;
-    }
-
-    List<ir.Parameter> buildCatch(IrBuilder builder, JumpCollector join) {
-      // The catch block of the try/catch used for try/finally is the finally
-      // code followed by a rethrow.
-      buildFinallyBlock(builder);
-      if (builder.isOpen) {
-        builder.add(new ir.Rethrow());
-        builder._current = null;
-      }
-      return <ir.Parameter>[new ir.Parameter(null), new ir.Parameter(null)];
-    }
-
-    void leaveTryCatch(
-        IrBuilder builder, JumpCollector join, ir.Expression body) {
-      // Build a list of continuations for jumps from the try block and
-      // duplicate the finally code before jumping to the actual target.
-      List<ir.Continuation> exits = <ir.Continuation>[join.continuation];
-      void addJump(
-          JumpCollector newCollector, JumpCollector originalCollector) {
-        if (newCollector.isEmpty) return;
-        IrBuilder builder = makeDelimitedBuilder(newCollector.environment);
-        buildFinallyBlock(builder);
-        if (builder.isOpen) builder.jumpTo(originalCollector);
-        newCollector.continuation.body = builder.root;
-        exits.add(newCollector.continuation);
-      }
-      for (int i = 0; i < newBreaks.length; ++i) {
-        addJump(newBreaks[i], savedBreaks[i]);
-      }
-      for (int i = 0; i < newContinues.length; ++i) {
-        addJump(newContinues[i], savedContinues[i]);
-      }
-      if (!newReturn.isEmpty) {
-        IrBuilder builder = makeDelimitedBuilder(newReturn.environment);
-        ir.Primitive value = builder.environment.discard(1);
-        buildFinallyBlock(builder);
-        if (builder.isOpen) builder.buildReturn(value: value);
-        newReturn.continuation.body = builder.root;
-        exits.add(newReturn.continuation);
-      }
-      builder.add(new ir.LetCont.many(exits, body));
-      builder.environment = join.environment;
-      buildFinallyBlock(builder);
-    }
-
-    _helpBuildTryCatch(variables, enterTry, buildTryBlock, leaveTry, buildCatch,
-        leaveTryCatch);
-  }
-
-  /// Create a return statement `return value;` or `return;` if [value] is
-  /// null.
-  void buildReturn({ir.Primitive value, SourceInformation sourceInformation}) {
-    // Build(Return(e), C) = C'[InvokeContinuation(return, x)]
-    //   where (C', x) = Build(e, C)
-    //
-    // Return without a subexpression is translated as if it were return null.
-    assert(isOpen);
-    if (value == null) {
-      value = buildNullConstant();
-    }
-    jumpTo(state.returnCollector, value, sourceInformation);
-  }
-
-  /// Generate the body for a native function [function] that is annotated with
-  /// an implementation in JavaScript (provided as string in [javaScriptCode]).
-  void buildNativeFunctionBody(FunctionElement function, String javaScriptCode,
-      SourceInformation sourceInformation) {
-    NativeBehavior behavior = new NativeBehavior();
-    behavior.sideEffects.setAllSideEffects();
-    // Generate a [ForeignCode] statement from the given native code.
-    buildForeignCode(
-        js.js
-            .statementTemplateYielding(new js.LiteralStatement(javaScriptCode)),
-        <ir.Primitive>[],
-        behavior,
-        sourceInformation);
-  }
-
-  /// Generate the body for a native function that redirects to a native
-  /// JavaScript function, getter, or setter.
-  ///
-  /// Generates a call to the real target, which is given by [functions]'s
-  /// `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 sourceInformation) {
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    NativeBehavior behavior = new NativeBehavior();
-    behavior.sideEffects.setAllSideEffects();
-    program.addNativeMethod(function);
-    // Construct the access of the target element.
-    String code = function.isInstanceMember ? '#.$name' : name;
-    if (function.isInstanceMember) {
-      arguments.add(state.thisParameter);
-    }
-    // Collect all parameters of the function and templates for them to be
-    // inserted into the JavaScript code.
-    List<String> argumentTemplates = <String>[];
-    function.functionSignature.forEachParameter((ParameterElement parameter) {
-      ir.Primitive input = environment.lookup(parameter);
-      DartType type = program.unaliasType(parameter.type);
-      if (type is FunctionType) {
-        // The parameter type is a function type either directly or through
-        // typedef(s).
-        ir.Constant arity = buildIntegerConstant(type.computeArity());
-        input = buildStaticFunctionInvocation(program.closureConverter,
-            <ir.Primitive>[input, arity], sourceInformation);
-      }
-      arguments.add(input);
-      argumentTemplates.add('#');
-    });
-    // Construct the application of parameters for functions and setters.
-    if (function.kind == ElementKind.FUNCTION) {
-      code = "$code(${argumentTemplates.join(', ')})";
-    } else if (function.kind == ElementKind.SETTER) {
-      code = "$code = ${argumentTemplates.single}";
-    } else {
-      assert(argumentTemplates.isEmpty);
-      assert(function.kind == ElementKind.GETTER);
-    }
-    // Generate the [ForeignCode] expression and a return statement to return
-    // its value.
-    ir.Primitive value = buildForeignCode(
-        js.js.uncachedExpressionTemplate(code),
-        arguments,
-        behavior,
-        sourceInformation,
-        type: program.getTypeMaskForNativeFunction(function));
-    buildReturn(value: value, sourceInformation: sourceInformation);
-  }
-
-  static _isNotNull(ir.Primitive value) =>
-      !(value is ir.Constant && value.value.isNull);
-
-  /// Builds a call to a resolved js-interop element.
-  ir.Primitive buildInvokeJsInteropMember(FunctionElement element,
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    program.addNativeMethod(element);
-    String target = program.getJsInteropTargetPath(element);
-    // Strip off trailing arguments that were not specified.
-    // TODO(jacobr,sigmund): assert that the trailing arguments are all null.
-    // TODO(jacobr): rewrite named arguments to an object literal matching
-    // the factory constructor case.
-    var inputs = arguments.where(_isNotNull).toList();
-
-    var behavior = new NativeBehavior()..sideEffects.setAllSideEffects();
-    DartType type = element.isConstructor
-        ? element.enclosingClass.thisType
-        : element.type.returnType;
-    // Native behavior effects here are similar to native/behavior.dart.
-    // The return type is dynamic if we don't trust js-interop type
-    // declarations.
-    behavior.typesReturned.add(
-        program.trustJSInteropTypeAnnotations ? type : const DynamicType());
-
-    // The allocation effects include the declared type if it is native (which
-    // includes js interop types).
-    if (type.element != null && program.isNative(type.element)) {
-      behavior.typesInstantiated.add(type);
-    }
-
-    // It also includes any other JS interop type if we don't trust the
-    // annotation or if is declared too broad.
-    if (!program.trustJSInteropTypeAnnotations ||
-        type.isObject ||
-        type.isDynamic) {
-      behavior.typesInstantiated.add(program.jsJavascriptObjectType);
-    }
-
-    String code;
-    if (element.isGetter) {
-      code = target;
-    } else if (element.isSetter) {
-      code = "$target = #";
-    } else {
-      var args = new List.filled(inputs.length, '#').join(',');
-      code = element.isConstructor ? "new $target($args)" : "$target($args)";
-    }
-    return buildForeignCode(
-        js.js.parseForeignJS(code), inputs, behavior, sourceInformation);
-    // TODO(sigmund): should we record the source-information here?
-  }
-
-  /// Builds an object literal that results from invoking a factory constructor
-  /// of a js-interop anonymous type.
-  ir.Primitive buildJsInteropObjectLiteral(ConstructorElement constructor,
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    assert(program.isJsInteropAnonymous(constructor));
-    program.addNativeMethod(constructor);
-    FunctionSignature params = constructor.functionSignature;
-    int i = 0;
-    var filteredArguments = <ir.Primitive>[];
-    var entries = new Map<String, js.Expression>();
-    params.orderedForEachParameter((ParameterElement parameter) {
-      // TODO(jacobr): throw if parameter names do not match names of property
-      // names in the class.
-      assert(parameter.isNamed);
-      ir.Primitive argument = arguments[i++];
-      if (_isNotNull(argument)) {
-        filteredArguments.add(argument);
-        entries[parameter.name] =
-            new js.InterpolatedExpression(filteredArguments.length - 1);
-      }
-    });
-    var code = new js.Template(null, js.objectLiteral(entries));
-    var behavior = new NativeBehavior();
-    if (program.trustJSInteropTypeAnnotations) {
-      behavior.typesReturned.add(constructor.enclosingClass.thisType);
-    }
-
-    return buildForeignCode(
-        code, filteredArguments, behavior, sourceInformation);
-  }
-
-  /// Create a blocks of [statements] by applying [build] to all reachable
-  /// statements. The first statement is assumed to be reachable.
-  // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses
-  // `List` instead of `Link`.
-  void buildBlock(var statements, BuildFunction build) {
-    // Build(Block(stamements), C) = C'
-    //   where C' = statements.fold(Build, C)
-    assert(isOpen);
-    return buildSequence(statements, build);
-  }
-
-  /// Creates a sequence of [nodes] by applying [build] to all reachable nodes.
-  ///
-  /// The first node in the sequence does not need to be reachable.
-  // TODO(johnniwinther): Type [nodes] as `Iterable` when `NodeList` uses
-  // `List` instead of `Link`.
-  void buildSequence(var nodes, BuildFunction build) {
-    for (var node in nodes) {
-      if (!isOpen) return;
-      build(node);
-    }
-  }
-
-  /// Creates a labeled statement
-  void buildLabeledStatement({SubbuildFunction buildBody, JumpTarget target}) {
-    JumpCollector join = new ForwardJumpCollector(environment, target: target);
-    IrBuilder innerBuilder = makeDelimitedBuilder();
-    innerBuilder.state.breakCollectors.add(join);
-    buildBody(innerBuilder);
-    innerBuilder.state.breakCollectors.removeLast();
-    bool hasBreaks = !join.isEmpty;
-    if (hasBreaks) {
-      if (innerBuilder.isOpen) innerBuilder.jumpTo(join);
-      add(new ir.LetCont(join.continuation, innerBuilder.root));
-      environment = join.environment;
-    } else if (innerBuilder.root != null) {
-      add(innerBuilder.root);
-      _current = innerBuilder._current;
-      environment = innerBuilder.environment;
-    } else {
-      // The translation of the body did not emit any CPS term.
-    }
-  }
-
-  // Build(BreakStatement L, C) = C[InvokeContinuation(...)]
-  //
-  // The continuation and arguments are filled in later after translating
-  // the body containing the break.
-  bool buildBreak(JumpTarget target) {
-    return buildJumpInternal(target, state.breakCollectors);
-  }
-
-  // Build(ContinueStatement L, C) = C[InvokeContinuation(...)]
-  //
-  // The continuation and arguments are filled in later after translating
-  // the body containing the continue.
-  bool buildContinue(JumpTarget target) {
-    return buildJumpInternal(target, state.continueCollectors);
-  }
-
-  bool buildJumpInternal(
-      JumpTarget target, Iterable<JumpCollector> collectors) {
-    assert(isOpen);
-    for (JumpCollector collector in collectors) {
-      if (target == collector.target) {
-        jumpTo(collector);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  void buildThrow(ir.Primitive value) {
-    assert(isOpen);
-    add(new ir.Throw(value));
-    _current = null;
-  }
-
-  ir.Primitive buildNonTailThrow(ir.Primitive value) {
-    assert(isOpen);
-    ir.Parameter param = new ir.Parameter(null);
-    ir.Continuation cont = new ir.Continuation(<ir.Parameter>[param]);
-    add(new ir.LetCont(cont, new ir.Throw(value)));
-    return param;
-  }
-
-  void buildRethrow() {
-    assert(isOpen);
-    add(new ir.Rethrow());
-    _current = null;
-  }
-
-  /// Create a negation of [condition].
-  ir.Primitive buildNegation(
-      ir.Primitive condition, SourceInformation sourceInformation) {
-    // ! e is translated as e ? false : true
-
-    // Add a continuation parameter for the result of the expression.
-    ir.Parameter resultParameter = new ir.Parameter(null);
-
-    ir.Continuation joinContinuation = new ir.Continuation([resultParameter]);
-    ir.Continuation thenContinuation = new ir.Continuation([]);
-    ir.Continuation elseContinuation = new ir.Continuation([]);
-
-    ir.Constant makeBoolConstant(bool value) {
-      return new ir.Constant(state.constantSystem.createBool(value));
-    }
-
-    ir.Constant trueConstant = makeBoolConstant(true);
-    ir.Constant falseConstant = makeBoolConstant(false);
-
-    thenContinuation.body = new ir.LetPrim(falseConstant)
-      ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant]));
-    elseContinuation.body = new ir.LetPrim(trueConstant)
-      ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant]));
-
-    add(new ir.LetCont(
-        joinContinuation,
-        new ir.LetCont.two(
-            thenContinuation,
-            elseContinuation,
-            new ir.Branch.strict(condition, thenContinuation, elseContinuation,
-                sourceInformation))));
-    return resultParameter;
-  }
-
-  /// Create a lazy and/or expression. [leftValue] is the value of the left
-  /// operand and [buildRightValue] is called to process the value of the right
-  /// operand in the context of its own [IrBuilder].
-  ir.Primitive buildLogicalOperator(
-      ir.Primitive leftValue,
-      ir.Primitive buildRightValue(IrBuilder builder),
-      SourceInformation sourceInformation,
-      {bool isLazyOr: false}) {
-    // e0 && e1 is translated as if e0 ? (e1 == true) : false.
-    // e0 || e1 is translated as if e0 ? true : (e1 == true).
-    // The translation must convert both e0 and e1 to booleans and handle
-    // local variable assignments in e1.
-    IrBuilder rightBuilder = makeDelimitedBuilder();
-    ir.Primitive rightValue = buildRightValue(rightBuilder);
-    // A dummy empty target for the branch on the left subexpression branch.
-    // This enables using the same infrastructure for join-point continuations
-    // as in visitIf and visitConditional.  It will hold a definition of the
-    // appropriate constant and an invocation of the join-point continuation.
-    IrBuilder emptyBuilder = makeDelimitedBuilder();
-    // Dummy empty targets for right true and right false.  They hold
-    // definitions of the appropriate constant and an invocation of the
-    // join-point continuation.
-    IrBuilder rightTrueBuilder = rightBuilder.makeDelimitedBuilder();
-    IrBuilder rightFalseBuilder = rightBuilder.makeDelimitedBuilder();
-
-    // If we don't evaluate the right subexpression, the value of the whole
-    // expression is this constant.
-    ir.Constant leftBool = emptyBuilder.buildBooleanConstant(isLazyOr);
-    // If we do evaluate the right subexpression, the value of the expression
-    // is a true or false constant.
-    ir.Constant rightTrue = rightTrueBuilder.buildBooleanConstant(true);
-    ir.Constant rightFalse = rightFalseBuilder.buildBooleanConstant(false);
-
-    // Result values are passed as continuation arguments, which are
-    // constructed based on environments.  These assertions are a sanity check.
-    assert(environment.length == emptyBuilder.environment.length);
-    assert(environment.length == rightTrueBuilder.environment.length);
-    assert(environment.length == rightFalseBuilder.environment.length);
-
-    // Wire up two continuations for the left subexpression, two continuations
-    // for the right subexpression, and a three-way join continuation.
-    JumpCollector join =
-        new ForwardJumpCollector(environment, hasExtraArgument: true);
-    emptyBuilder.jumpTo(join, leftBool);
-    rightTrueBuilder.jumpTo(join, rightTrue);
-    rightFalseBuilder.jumpTo(join, rightFalse);
-    ir.Continuation leftTrueContinuation = new ir.Continuation([]);
-    ir.Continuation leftFalseContinuation = new ir.Continuation([]);
-    ir.Continuation rightTrueContinuation = new ir.Continuation([]);
-    ir.Continuation rightFalseContinuation = new ir.Continuation([]);
-    rightTrueContinuation.body = rightTrueBuilder.root;
-    rightFalseContinuation.body = rightFalseBuilder.root;
-    // The right subexpression has two continuations.
-    rightBuilder.add(new ir.LetCont.two(
-        rightTrueContinuation,
-        rightFalseContinuation,
-        new ir.Branch.strict(rightValue, rightTrueContinuation,
-            rightFalseContinuation, sourceInformation)));
-    // Depending on the operator, the left subexpression's continuations are
-    // either the right subexpression or an invocation of the join-point
-    // continuation.
-    if (isLazyOr) {
-      leftTrueContinuation.body = emptyBuilder.root;
-      leftFalseContinuation.body = rightBuilder.root;
-    } else {
-      leftTrueContinuation.body = rightBuilder.root;
-      leftFalseContinuation.body = emptyBuilder.root;
-    }
-
-    add(new ir.LetCont(
-        join.continuation,
-        new ir.LetCont.two(
-            leftTrueContinuation,
-            leftFalseContinuation,
-            new ir.Branch.strict(leftValue, leftTrueContinuation,
-                leftFalseContinuation, sourceInformation))));
-    environment = join.environment;
-    return environment.discard(1);
-  }
-
-  ir.Primitive buildIdentical(ir.Primitive x, ir.Primitive y,
-      {SourceInformation sourceInformation}) {
-    return addPrimitive(new ir.ApplyBuiltinOperator(
-        ir.BuiltinOperator.Identical, <ir.Primitive>[x, y], sourceInformation));
-  }
-
-  /// Called when entering a nested function with free variables.
-  ///
-  /// The free variables must subsequently be accessible using [buildLocalGet]
-  /// and [buildLocalSet].
-  void _enterClosureEnvironment(ClosureEnvironment env) {
-    if (env == null) return;
-
-    // Obtain a reference to the function object (this).
-    ir.Parameter thisPrim = state.thisParameter;
-
-    // Obtain access to the free variables.
-    env.freeVariables.forEach((Local local, ClosureLocation location) {
-      if (location.isBox) {
-        // Boxed variables are loaded from their box on-demand.
-        state.boxedVariables[local] = location;
-      } else {
-        // Unboxed variables are loaded from the function object immediately.
-        // This includes BoxLocals which are themselves unboxed variables.
-        environment.extend(
-            local, addPrimitive(new ir.GetField(thisPrim, location.field)));
-      }
-    });
-
-    // If the function captures a reference to the receiver from the
-    // enclosing method, remember which primitive refers to the receiver object.
-    if (env.thisLocal != null && env.freeVariables.containsKey(env.thisLocal)) {
-      state.enclosingThis = environment.lookup(env.thisLocal);
-    }
-
-    // If the function has a self-reference, use the value of `this`.
-    if (env.selfReference != null) {
-      environment.extend(env.selfReference, thisPrim);
-    }
-  }
-
-  /// Creates a box for [scope.box] and binds the captured variables to
-  /// that box.
-  ///
-  /// The captured variables can subsequently be manipulated with
-  /// [declareLocalVariable], [buildLocalGet], and [buildLocalSet].
-  void enterScope(ClosureScope scope) => _enterScope(scope);
-
-  /// Called when entering a function body or loop body.
-  ///
-  /// This is not called for for-loops, which instead use the methods
-  /// [_enterForLoopInitializer], [_enterForLoopBody], and [_enterForLoopUpdate]
-  /// due to their special scoping rules.
-  ///
-  /// The boxed variables declared in this scope must subsequently be available
-  /// using [buildLocalGet], [buildLocalSet], etc.
-  void _enterScope(ClosureScope scope) {
-    if (scope == null) return;
-    ir.CreateBox boxPrim = addPrimitive(new ir.CreateBox());
-    environment.extend(scope.box, boxPrim);
-    boxPrim.useElementAsHint(scope.box);
-    scope.capturedVariables.forEach((Local local, ClosureLocation location) {
-      assert(!state.boxedVariables.containsKey(local));
-      if (location.isBox) {
-        state.boxedVariables[local] = location;
-      }
-    });
-  }
-
-  /// Add the given function parameter to the IR, and bind it in the environment
-  /// or put it in its box, if necessary.
-  void _createFunctionParameter(Local parameterElement) {
-    ir.Parameter parameter = new ir.Parameter(parameterElement);
-    _parameters.add(parameter);
-    state.functionParameters.add(parameter);
-    ClosureLocation location = state.boxedVariables[parameterElement];
-    if (location != null) {
-      addPrimitive(new ir.SetField(
-          environment.lookup(location.box), location.field, parameter));
-    } else {
-      environment.extend(parameterElement, parameter);
-    }
-  }
-
-  void _createThisParameter() {
-    assert(state.thisParameter == null);
-    if (Elements.isStaticOrTopLevel(state.currentElement)) return;
-    if (state.currentElement.isLocal) return;
-    state.thisParameter =
-        new ir.Parameter(new ThisParameterLocal(state.currentElement));
-  }
-
-  void declareLocalVariable(LocalElement variableElement,
-      {ir.Primitive initialValue}) {
-    assert(isOpen);
-    if (initialValue == null) {
-      initialValue = buildNullConstant();
-    }
-    ClosureLocation location = state.boxedVariables[variableElement];
-    if (location != null) {
-      addPrimitive(new ir.SetField(
-          environment.lookup(location.box), location.field, initialValue));
-    } else if (isInMutableVariable(variableElement)) {
-      add(new ir.LetMutable(getMutableVariable(variableElement), initialValue));
-    } else {
-      initialValue.useElementAsHint(variableElement);
-      environment.extend(variableElement, initialValue);
-    }
-  }
-
-  /// Add [functionElement] to the environment with provided [definition].
-  void declareLocalFunction(
-      LocalFunctionElement functionElement,
-      closure.ClosureClassElement classElement,
-      SourceInformation sourceInformation) {
-    ir.Primitive closure =
-        buildFunctionExpression(classElement, sourceInformation);
-    declareLocalVariable(functionElement, initialValue: closure);
-  }
-
-  ir.Primitive buildFunctionExpression(closure.ClosureClassElement classElement,
-      SourceInformation sourceInformation) {
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    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 closure.ThisLocal) {
-        value = buildThis();
-      } else if (field.local is closure.TypeVariableLocal) {
-        closure.TypeVariableLocal variable = field.local;
-        value = buildTypeVariableAccess(variable.typeVariable);
-      } else {
-        value = environment.lookup(field.local);
-      }
-      arguments.add(value);
-    }
-    return addPrimitive(new ir.CreateInstance(
-        classElement, arguments, null, sourceInformation));
-  }
-
-  /// Create a read access of [local] function, variable, or parameter.
-  // TODO(johnniwinther): Make [sourceInformation] mandatory.
-  ir.Primitive buildLocalGet(LocalElement local,
-      {SourceInformation sourceInformation}) {
-    assert(isOpen);
-    ClosureLocation location = state.boxedVariables[local];
-    if (location != null) {
-      ir.Primitive result = new ir.GetField(
-          environment.lookup(location.box), location.field,
-          sourceInformation: sourceInformation);
-      result.useElementAsHint(local);
-      return addPrimitive(result);
-    } else if (isInMutableVariable(local)) {
-      return addPrimitive(new ir.GetMutable(getMutableVariable(local),
-          sourceInformation: sourceInformation));
-    } else {
-      return environment.lookup(local);
-    }
-  }
-
-  /// Create a write access to [local] variable or parameter with the provided
-  /// [value].
-  ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value,
-      SourceInformation sourceInformation) {
-    assert(isOpen);
-    ClosureLocation location = state.boxedVariables[local];
-    if (location != null) {
-      addPrimitive(new ir.SetField(
-          environment.lookup(location.box), location.field, value,
-          sourceInformation: sourceInformation));
-    } else if (isInMutableVariable(local)) {
-      addPrimitive(new ir.SetMutable(getMutableVariable(local), value,
-          sourceInformation: sourceInformation));
-    } else {
-      value.useElementAsHint(local);
-      environment.update(local, value);
-    }
-    return value;
-  }
-
-  /// Called before building the initializer of a for-loop.
-  ///
-  /// The loop variables will subsequently be declared using
-  /// [declareLocalVariable].
-  void _enterForLoopInitializer(
-      ClosureScope scope, List<LocalElement> loopVariables) {
-    if (scope == null) return;
-    // If there are no boxed loop variables, don't create the box here, let
-    // it be created inside the body instead.
-    if (scope.boxedLoopVariables.isEmpty) return;
-    _enterScope(scope);
-  }
-
-  /// Called before building the body of a for-loop.
-  void _enterForLoopBody(ClosureScope scope, List<LocalElement> loopVariables) {
-    if (scope == null) return;
-    // If there are boxed loop variables, the box has already been created
-    // at the initializer.
-    if (!scope.boxedLoopVariables.isEmpty) return;
-    _enterScope(scope);
-  }
-
-  /// Called before building the update of a for-loop.
-  void _enterForLoopUpdate(
-      ClosureScope scope, List<LocalElement> loopVariables) {
-    if (scope == null) return;
-    // If there are no boxed loop variables, then the box is created inside the
-    // body, so there is no need to explicitly renew it.
-    if (scope.boxedLoopVariables.isEmpty) return;
-    ir.Primitive box = environment.lookup(scope.box);
-    ir.Primitive newBox = addPrimitive(new ir.CreateBox());
-    newBox.useElementAsHint(scope.box);
-    for (VariableElement loopVar in scope.boxedLoopVariables) {
-      ClosureLocation location = scope.capturedVariables[loopVar];
-      ir.Primitive value = addPrimitive(new ir.GetField(box, location.field));
-      addPrimitive(new ir.SetField(newBox, location.field, value));
-    }
-    environment.update(scope.box, newBox);
-  }
-
-  /// Creates an access to the receiver from the current (or enclosing) method.
-  ///
-  /// If inside a closure class, [buildThis] will redirect access through
-  /// closure fields in order to access the receiver from the enclosing method.
-  ir.Primitive buildThis() {
-    if (state.enclosingThis != null) return state.enclosingThis;
-    assert(state.thisParameter != null);
-    return state.thisParameter;
-  }
-
-  ir.Primitive buildFieldGet(ir.Primitive receiver, FieldElement target,
-      SourceInformation sourceInformation) {
-    return addPrimitive(new ir.GetField(receiver, target,
-        sourceInformation: sourceInformation,
-        isFinal: program.fieldNeverChanges(target)));
-  }
-
-  void buildFieldSet(ir.Primitive receiver, FieldElement target,
-      ir.Primitive value, SourceInformation sourceInformation) {
-    addPrimitive(new ir.SetField(receiver, target, value,
-        sourceInformation: sourceInformation));
-  }
-
-  ir.Primitive buildSuperFieldGet(
-      FieldElement target, SourceInformation sourceInformation) {
-    return addPrimitive(new ir.GetField(buildThis(), target,
-        sourceInformation: sourceInformation));
-  }
-
-  ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value,
-      SourceInformation sourceInformation) {
-    addPrimitive(new ir.SetField(buildThis(), target, value,
-        sourceInformation: sourceInformation));
-    return value;
-  }
-
-  /// Loads parameters to a constructor body into the environment.
-  ///
-  /// The header for a constructor body differs from other functions in that
-  /// some parameters are already boxed, and the box is passed as an argument
-  /// instead of being created in the header.
-  void buildConstructorBodyHeader(
-      Iterable<Local> parameters, ClosureScope closureScope) {
-    _createThisParameter();
-    for (Local param in parameters) {
-      ir.Parameter parameter = _createLocalParameter(param);
-      state.functionParameters.add(parameter);
-    }
-    if (closureScope != null) {
-      state.boxedVariables.addAll(closureScope.capturedVariables);
-    }
-  }
-
-  /// Create a constructor invocation of [element] on [type] where the
-  /// constructor name and argument structure are defined by [callStructure] and
-  /// the argument values are defined by [arguments].
-  ir.Primitive buildConstructorInvocation(
-      ConstructorElement element,
-      CallStructure callStructure,
-      DartType type,
-      List<ir.Primitive> arguments,
-      SourceInformation sourceInformation,
-      {TypeMask allocationSiteType}) {
-    assert(isOpen);
-    Selector selector =
-        new Selector(SelectorKind.CALL, element.memberName, callStructure);
-    ClassElement cls = element.enclosingClass;
-    if (program.isJsInterop(element)) {
-      if (program.isJsInteropAnonymous(element)) {
-        return buildJsInteropObjectLiteral(
-            element, arguments, sourceInformation);
-      }
-      return buildInvokeJsInteropMember(element, arguments, sourceInformation);
-    }
-    if (program.requiresRuntimeTypesFor(cls)) {
-      InterfaceType interface = type;
-      Iterable<ir.Primitive> typeArguments =
-          interface.typeArguments.map((DartType argument) {
-        return type.treatAsRaw
-            ? buildNullConstant()
-            : buildTypeExpression(argument);
-      });
-      arguments = new List<ir.Primitive>.from(arguments)..addAll(typeArguments);
-    }
-    return addPrimitive(new ir.InvokeConstructor(
-        type, element, selector, arguments, sourceInformation,
-        allocationSiteType: allocationSiteType));
-  }
-
-  ir.Primitive buildTypeExpression(DartType type) {
-    type = program.unaliasType(type);
-    if (type is TypeVariableType) {
-      return buildTypeVariableAccess(type);
-    } else if (type is InterfaceType || type is FunctionType) {
-      List<ir.Primitive> arguments = <ir.Primitive>[];
-      type.forEachTypeVariable((TypeVariableType variable) {
-        ir.Primitive value = buildTypeVariableAccess(variable);
-        arguments.add(value);
-      });
-      return addPrimitive(new ir.TypeExpression(
-          ir.TypeExpressionKind.COMPLETE, type, arguments));
-    } else if (type.treatAsDynamic) {
-      return buildNullConstant();
-    } else {
-      // TypedefType can reach here, and possibly other things.
-      throw 'unimplemented translation of type expression $type (${type.kind})';
-    }
-  }
-
-  /// Obtains the internal type representation of the type held in [variable].
-  ///
-  /// The value of [variable] is taken from the current receiver object, or
-  /// if we are currently building a constructor field initializer, from the
-  /// corresponding type argument (field initializers are evaluated before the
-  /// receiver object is created).
-  ir.Primitive buildTypeVariableAccess(TypeVariableType variable,
-      {SourceInformation sourceInformation}) {
-    // 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 closure.TypeVariableLocal(variable, state.currentElement);
-    if (environment.contains(local)) {
-      return environment.lookup(local);
-    }
-
-    // If the type variable is not in a local, read its value from the
-    // receiver object.
-    ir.Primitive target = buildThis();
-    return addPrimitive(
-        new ir.ReadTypeVariable(variable, target, sourceInformation));
-  }
-
-  /// Make the given type variable accessible through the local environment
-  /// with the value of [binding].
-  void declareTypeVariable(TypeVariableType variable, DartType binding) {
-    environment.extend(
-        new closure.TypeVariableLocal(variable, state.currentElement),
-        buildTypeExpression(binding));
-  }
-
-  /// Reifies the value of [variable] on the current receiver object.
-  ir.Primitive buildReifyTypeVariable(
-      TypeVariableType variable, SourceInformation sourceInformation) {
-    ir.Primitive typeArgument =
-        buildTypeVariableAccess(variable, sourceInformation: sourceInformation);
-    return addPrimitive(
-        new ir.ReifyRuntimeType(typeArgument, sourceInformation));
-  }
-
-  ir.Primitive buildInvocationMirror(
-      Selector selector, List<ir.Primitive> arguments) {
-    return addPrimitive(new ir.CreateInvocationMirror(selector, arguments));
-  }
-
-  ir.Primitive buildForeignCode(
-      js.Template codeTemplate,
-      List<ir.Primitive> arguments,
-      NativeBehavior behavior,
-      SourceInformation sourceInformation,
-      {Element dependency,
-      TypeMask type}) {
-    assert(behavior != null);
-    if (type == null) {
-      type = program.getTypeMaskForForeign(behavior);
-    }
-    if (js.isIdentityTemplate(codeTemplate) && !program.isArrayType(type)) {
-      // JS expression is just a refinement.
-      // Do not do this for arrays - those are special because array types can
-      // change after creation.  The input and output must therefore be modeled
-      // as distinct values.
-      return addPrimitive(new ir.Refinement(arguments.single, type));
-    }
-    ir.Primitive result = addPrimitive(new ir.ForeignCode(
-        codeTemplate, type, arguments, behavior, sourceInformation,
-        dependency: dependency));
-    if (!codeTemplate.isExpression) {
-      // Close the term if this is a "throw" expression or native body.
-      add(new ir.Unreachable());
-      _current = null;
-    }
-    return result;
-  }
-
-  /// Creates a type test or type cast of [value] against [type].
-  ir.Primitive buildTypeOperator(
-      ir.Primitive value, DartType type, SourceInformation sourceInformation,
-      {bool isTypeTest}) {
-    assert(isOpen);
-    assert(isTypeTest != null);
-
-    type = program.unaliasType(type);
-
-    if (type.isMalformed) {
-      String message;
-      if (type is MalformedType) {
-        ErroneousElement element = type.element;
-        message = element.message;
-      } else {
-        assert(type is MethodTypeVariableType);
-        message = "Method type variables are not reified, "
-            "so they cannot be tested dynamically";
-      }
-      ir.Primitive irMessage = buildStringConstant(message);
-      return buildStaticFunctionInvocation(program.throwTypeErrorHelper,
-          <ir.Primitive>[irMessage], sourceInformation);
-    }
-
-    List<ir.Primitive> typeArguments = const <ir.Primitive>[];
-    if (type is GenericType && type.typeArguments.isNotEmpty) {
-      typeArguments = type.typeArguments.map(buildTypeExpression).toList();
-    } else if (type is TypeVariableType) {
-      typeArguments = <ir.Primitive>[buildTypeVariableAccess(type)];
-    } else if (type is FunctionType) {
-      typeArguments = <ir.Primitive>[buildTypeExpression(type)];
-    }
-
-    if (isTypeTest) {
-      // For type tests, we must treat specially the rare cases where `null`
-      // satisfies the test (which otherwise never satisfies a type test).
-      // This is not an optimization: the TypeOperator assumes that `null`
-      // cannot satisfy the type test unless the type is a type variable.
-      if (type.isObject || type.isDynamic) {
-        // `x is Object` and `x is dynamic` are always true, even if x is null.
-        return buildBooleanConstant(true);
-      }
-      if (type is InterfaceType && type.element == program.nullClass) {
-        // `x is Null` is true if and only if x is null.
-        return _buildCheckNull(value, sourceInformation);
-      }
-      return addPrimitive(new ir.TypeTest(value, type, typeArguments));
-    } else {
-      if (type.isObject || type.isDynamic) {
-        // `x as Object` and `x as dynamic` are the same as `x`.
-        return value;
-      }
-      return addPrimitive(new ir.TypeCast(value, type, typeArguments));
-    }
-  }
-
-  /// Create an if-null expression. This is equivalent to a conditional
-  /// expression whose result is either [value] if [value] is not null, or
-  /// `right` if [value] is null. Only when [value] is null, [buildRight] is
-  /// evaluated to produce the `right` value.
-  ir.Primitive buildIfNull(
-      ir.Primitive value,
-      ir.Primitive buildRight(IrBuilder builder),
-      SourceInformation sourceInformation) {
-    ir.Primitive condition = _buildCheckNull(value, sourceInformation);
-    return buildConditional(
-        condition, buildRight, (_) => value, sourceInformation);
-  }
-
-  /// Create a conditional send. This is equivalent to a conditional expression
-  /// that checks if [receiver] is null, if so, it returns null, otherwise it
-  /// evaluates the [buildSend] expression.
-  ir.Primitive buildIfNotNullSend(
-      ir.Primitive receiver,
-      ir.Primitive buildSend(IrBuilder builder),
-      SourceInformation sourceInformation) {
-    ir.Primitive condition = _buildCheckNull(receiver, sourceInformation);
-    return buildConditional(
-        condition, (_) => receiver, buildSend, sourceInformation);
-  }
-
-  /// Creates a type test checking whether [value] is null.
-  ir.Primitive _buildCheckNull(
-      ir.Primitive value, SourceInformation sourceInformation) {
-    assert(isOpen);
-    return buildIdentical(value, buildNullConstant(),
-        sourceInformation: sourceInformation);
-  }
-}
-
-/// Location of a variable relative to a given closure.
-class ClosureLocation {
-  /// If not `null`, this location is [box].[field].
-  /// 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 closure.BoxLocal box;
-
-  /// The field in which the variable is stored.
-  final Entity field;
-
-  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.
-///
-/// A [ClosureScope] may exist for each function and for each loop.
-/// Generally, one may pass `null` to the [IrBuilder] instead of a
-/// [ClosureScope] when a given scope has no boxed variables.
-class ClosureScope {
-  /// This box is now in scope and [capturedVariables] may use it.
-  final closure.BoxLocal box;
-
-  /// Maps [LocalElement]s to their location.
-  final Map<Local, ClosureLocation> capturedVariables;
-
-  /// If this is the scope of a for-loop, [boxedLoopVariables] is the list
-  /// of boxed variables that are declared in the initializer.
-  final List<VariableElement> 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
-/// to access variables from the enclosing scope.
-class ClosureEnvironment {
-  /// References to this local should be treated as recursive self-reference.
-  /// (This is *not* in [freeVariables]).
-  final LocalFunctionElement selfReference;
-
-  /// If non-null, [thisLocal] has an entry in [freeVariables] describing where
-  /// to find the captured value of `this`.
-  final closure.ThisLocal thisLocal;
-
-  /// Maps [LocalElement]s, [BoxLocal]s and [ThisLocal] to their location.
-  final Map<Local, ClosureLocation> 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 {
-  final Set<LocalVariableElement> declared = new Set<LocalVariableElement>();
-  final Set<LocalVariableElement> boxedOnEntry =
-      new Set<LocalVariableElement>();
-}
-
-class CatchClauseInfo {
-  final DartType type;
-  final LocalVariableElement exceptionVariable;
-  final LocalVariableElement stackTraceVariable;
-  final SubbuildFunction buildCatchBlock;
-  final SourceInformation sourceInformation;
-
-  CatchClauseInfo(
-      {this.type,
-      this.exceptionVariable,
-      this.stackTraceVariable,
-      this.buildCatchBlock,
-      this.sourceInformation});
-}
-
-class SwitchCaseInfo {
-  final SubbuildFunction buildCondition;
-  final SubbuildFunction buildBody;
-  final SourceInformation sourceInformation;
-
-  SwitchCaseInfo(this.buildCondition, this.buildBody, this.sourceInformation);
-}
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
deleted file mode 100644
index 28cc94a..0000000
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ /dev/null
@@ -1,4033 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.ir_builder_task;
-
-import 'package:js_runtime/shared/embedded_names.dart'
-    show JsBuiltin, JsGetName;
-
-import '../closure.dart' as closure;
-import '../common.dart';
-import '../common/names.dart' show Identifiers, Names, Selectors;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../constants/expressions.dart';
-import '../constants/values.dart' show ConstantValue;
-import '../constants/values.dart';
-import '../dart_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart' show ConstructorBodyElementX;
-import '../io/source_information.dart';
-import '../js/js.dart' as js show js, Template, Expression, Name;
-import '../js_backend/backend_helpers.dart' show BackendHelpers;
-import '../js_backend/js_backend.dart'
-    show JavaScriptBackend, SyntheticConstantKind;
-import '../native/native.dart' show NativeBehavior, HasCapturedPlaceholders;
-import '../resolution/operators.dart' as op;
-import '../resolution/semantic_visitor.dart';
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../ssa/types.dart' show TypeMaskFactory;
-import '../tree/tree.dart' as ast;
-import '../types/types.dart' show TypeMask;
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import '../util/util.dart';
-import 'cps_ir_builder.dart';
-import 'cps_ir_nodes.dart' as ir;
-import 'type_mask_system.dart' show TypeMaskSystem;
-// TODO(karlklose): remove.
-
-typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode);
-
-class ExplicitReceiverParameter implements Local {
-  final ExecutableElement executableContext;
-
-  ExplicitReceiverParameter(this.executableContext);
-
-  String get name => 'receiver';
-  String toString() => 'ExplicitReceiverParameter($executableContext)';
-}
-
-/// This task provides the interface to build IR nodes from [ast.Node]s, which
-/// is used from the [CpsFunctionCompiler] to generate code.
-///
-/// This class is mainly there to correctly measure how long building the IR
-/// takes.
-class IrBuilderTask extends CompilerTask {
-  final SourceInformationStrategy sourceInformationStrategy;
-  final Compiler compiler;
-
-  String bailoutMessage = null;
-
-  /// If not null, this function will be called with for each
-  /// [ir.FunctionDefinition] node that has been built.
-  IrBuilderCallback builderCallback;
-
-  IrBuilderTask(Compiler compiler, this.sourceInformationStrategy,
-      [this.builderCallback])
-      : compiler = compiler,
-        super(compiler.measurer);
-
-  String get name => 'CPS builder';
-
-  ir.FunctionDefinition buildNode(
-      AstElement element, TypeMaskSystem typeMaskSystem) {
-    return measure(() {
-      bailoutMessage = null;
-
-      ResolvedAst resolvedAst = element.resolvedAst;
-      element = element.implementation;
-      return compiler.reporter.withCurrentElement(element, () {
-        SourceInformationBuilder sourceInformationBuilder =
-            sourceInformationStrategy.createBuilderForContext(resolvedAst);
-
-        IrBuilderVisitor builder = new IrBuilderVisitor(
-            resolvedAst, compiler, sourceInformationBuilder, typeMaskSystem);
-        ir.FunctionDefinition irNode = builder.buildExecutable(element);
-        if (irNode == null) {
-          bailoutMessage = builder.bailoutMessage;
-        } else if (builderCallback != null) {
-          builderCallback(element, irNode);
-        }
-        return irNode;
-      });
-    });
-  }
-}
-
-/// Translates the frontend AST of a method to its CPS IR.
-///
-/// The visitor has an [IrBuilder] which contains an IR fragment to build upon
-/// and the current reaching definition of local variables.
-///
-/// Visiting a statement or expression extends the IR builder's fragment.
-/// For expressions, the primitive holding the resulting value is returned.
-/// For statements, `null` is returned.
-// TODO(johnniwinther): Implement [SemanticDeclVisitor].
-class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
-    with
-        IrBuilderMixin<ast.Node>,
-        SemanticSendResolvedMixin<ir.Primitive, dynamic>,
-        ErrorBulkMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfNewMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic>,
-        BaseImplementationOfSuperIndexSetIfNullMixin<ir.Primitive, dynamic>
-    implements SemanticSendVisitor<ir.Primitive, dynamic> {
-  final ResolvedAst resolvedAst;
-  final Compiler compiler;
-  final SourceInformationBuilder sourceInformationBuilder;
-  final TypeMaskSystem typeMaskSystem;
-
-  /// A map from try statements in the source to analysis information about
-  /// them.
-  ///
-  /// The analysis information includes the set of variables that must be
-  /// copied into [ir.MutableVariable]s on entry to the try and copied out on
-  /// exit.
-  Map<ast.Node, TryStatementInfo> tryStatements = null;
-
-  // In SSA terms, join-point continuation parameters are the phis and the
-  // continuation invocation arguments are the corresponding phi inputs.  To
-  // support name introduction and renaming for source level variables, we use
-  // nested (delimited) visitors for constructing subparts of the IR that will
-  // need renaming.  Each source variable is assigned an index.
-  //
-  // Each nested visitor maintains a list of free variable uses in the body.
-  // These are implemented as a list of parameters, each with their own use
-  // list of references.  When the delimited subexpression is plugged into the
-  // surrounding context, the free occurrences can be captured or become free
-  // occurrences in the next outer delimited subexpression.
-  //
-  // Each nested visitor maintains a list that maps indexes of variables
-  // assigned in the delimited subexpression to their reaching definition ---
-  // that is, the definition in effect at the hole in 'current'.  These are
-  // used to determine if a join-point continuation needs to be passed
-  // arguments, and what the arguments are.
-
-  /// Construct a top-level visitor.
-  IrBuilderVisitor(this.resolvedAst, this.compiler,
-      this.sourceInformationBuilder, this.typeMaskSystem);
-
-  TreeElements get elements => resolvedAst.elements;
-
-  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);
-
-  SemanticSendVisitor get sendVisitor => this;
-
-  /// 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].
-  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.
-  ///
-  /// 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.resolvedAst);
-    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;
-    ResolvedAst resolvedAst = constructor.resolvedAst;
-    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(resolvedAst, constructor);
-      classElement.addBackendMember(bodyElement);
-
-      if (constructor.isPatch) {
-        // Create origin body element for patched constructors.
-        ConstructorBodyElementX patch = bodyElement;
-        ConstructorBodyElementX origin =
-            new ConstructorBodyElementX(resolvedAst, 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>[];
-      if (constructor.isGenerativeConstructor &&
-          backend.isNativeOrExtendsNative(classElement)) {
-        parameters.add(new ExplicitReceiverParameter(constructor));
-      }
-      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.
-      ir.Primitive typeInformation;
-      if (requiresTypeInformation) {
-        typeInformation = new ir.TypeExpression(
-            ir.TypeExpressionKind.INSTANCE,
-            classElement.thisType,
-            irParameters.sublist(firstTypeArgumentParameterIndex));
-        irBuilder.add(new ir.LetPrim(typeInformation));
-      } else {
-        typeInformation = null;
-      }
-
-      // -- 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>[];
-      List<FieldElement> fields = <FieldElement>[];
-      classElement.forEachInstanceField((ClassElement c, FieldElement field) {
-        ir.Primitive value = fieldValues[field];
-        if (value != null) {
-          fields.add(field);
-          instanceArguments.add(value);
-        } else {
-          assert(backend.isNativeOrExtendsNative(c));
-          // Native fields are initialized elsewhere.
-        }
-      }, includeSuperAndInjectedMembers: true);
-
-      ir.Primitive instance;
-      if (constructor.isGenerativeConstructor &&
-          backend.isNativeOrExtendsNative(classElement)) {
-        instance = irParameters.first;
-        instance.type =
-            new TypeMask.exact(classElement, typeMaskSystem.classWorld);
-        irBuilder.addPrimitive(new ir.ReceiverCheck.nullCheck(
-            instance, Selectors.toString_, null));
-        for (int i = 0; i < fields.length; i++) {
-          irBuilder.addPrimitive(
-              new ir.SetField(instance, fields[i], instanceArguments[i]));
-        }
-      } else {
-        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(
-          sourceInformationBuilder.buildVariableDeclaration());
-    });
-  }
-
-  /// 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) {
-    ResolvedAst resolvedAst = context.resolvedAst;
-    return new IrBuilderVisitor(resolvedAst, compiler,
-        sourceInformationBuilder.forContext(resolvedAst), 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.declaration == resolvedAst.element);
-    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.declaration == resolvedAst.element);
-    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.resolvedAst);
-
-    // 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(
-          sourceInformationBuilder.buildVariableDeclaration());
-    });
-  }
-
-  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.resolvedAst);
-    TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
-    tryStatements = variables.tryStatements;
-    IrBuilder builder = getBuilderFor(element);
-    return withBuilder(
-        builder, () => _makeFunctionBody(builder, element, node));
-  }
-
-  ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) {
-    if (!backend.constants.lazyStatics.contains(element)) {
-      return null; // Nothing to do.
-    }
-    closureClassMap = compiler.closureToClassMapper
-        .computeClosureToClassMapping(element.resolvedAst);
-    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(
-          sourceInformationBuilder.buildVariableDeclaration());
-    });
-  }
-
-  /// 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 ||
-        // TODO(sigmund): JS doesn't support default values, so this should be
-        // reported as an error earlier (Issue #25759).
-        backend.isJsInterop(parameter.functionDeclaration)) {
-      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) {
-    target = target.implementation;
-    FunctionSignature signature = target.functionSignature;
-    if (!signature.optionalParametersAreNamed &&
-        signature.parameterCount == arguments.length) {
-      return callStructure;
-    }
-
-    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.
-  ///
-  /// 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) {
-    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,
-          sourceInformation: src,
-          isFinal: compiler.world.fieldNeverChanges(field)));
-    } else {
-      return irBuilder.addPrimitive(new ir.GetStatic(field,
-          sourceInformation: src,
-          isFinal: compiler.world.fieldNeverChanges(field)));
-    }
-  }
-
-  ir.FunctionDefinition _makeFunctionBody(
-      IrBuilder builder, FunctionElement element, ast.FunctionExpression node) {
-    FunctionSignature signature = element.functionSignature;
-    List<Local> parameters = <Local>[];
-    signature.orderedForEachParameter(
-        (LocalParameterElement e) => parameters.add(e));
-
-    bool requiresRuntimeTypes = false;
-    if (element.isFactoryConstructor) {
-      requiresRuntimeTypes =
-          builder.program.requiresRuntimeTypesFor(element.enclosingElement);
-      if (requiresRuntimeTypes) {
-        // Type arguments are passed in as extra parameters.
-        for (DartType typeVariable in element.enclosingClass.typeVariables) {
-          parameters.add(new closure.TypeVariableLocal(typeVariable, element));
-        }
-      }
-    }
-
-    irBuilder.buildFunctionHeader(parameters,
-        closureScope: getClosureScopeForNode(node),
-        env: getClosureEnvironment());
-
-    if (element == helpers.jsArrayTypedConstructor) {
-      // Generate a body for JSArray<E>.typed(allocation):
-      //
-      //    t1 = setRuntimeTypeInfo(allocation, TypeExpression($E));
-      //    return Refinement(t1, <JSArray>);
-      //
-      assert(parameters.length == 1 || parameters.length == 2);
-      ir.Primitive allocation = irBuilder.buildLocalGet(parameters[0]);
-
-      // Only call setRuntimeTypeInfo if JSArray requires the type parameter.
-      if (requiresRuntimeTypes) {
-        assert(parameters.length == 2);
-        closure.TypeVariableLocal typeParameter = parameters[1];
-        ir.Primitive typeArgument =
-            irBuilder.buildTypeVariableAccess(typeParameter.typeVariable);
-
-        ir.Primitive typeInformation = irBuilder.addPrimitive(
-            new ir.TypeExpression(ir.TypeExpressionKind.INSTANCE,
-                element.enclosingClass.thisType, <ir.Primitive>[typeArgument]));
-
-        MethodElement helper = helpers.setRuntimeTypeInfo;
-        CallStructure callStructure = CallStructure.TWO_ARGS;
-        Selector selector = new Selector.call(helper.memberName, callStructure);
-        allocation = irBuilder.buildInvokeStatic(
-            helper,
-            selector,
-            <ir.Primitive>[allocation, typeInformation],
-            sourceInformationBuilder.buildGeneric(node));
-      }
-
-      ir.Primitive refinement = irBuilder.addPrimitive(
-          new ir.Refinement(allocation, typeMaskSystem.arrayType));
-
-      irBuilder.buildReturn(
-          value: refinement,
-          sourceInformation:
-              sourceInformationBuilder.buildImplicitReturn(element));
-    } else {
-      visit(node.body);
-    }
-    return irBuilder.makeFunctionDefinition(
-        sourceInformationBuilder.buildVariableDeclaration());
-  }
-
-  /// 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) {
-    irBuilder.buildBlock(node.statements.nodes, build);
-  }
-
-  ir.Primitive visitBreakStatement(ast.BreakStatement node) {
-    if (!irBuilder.buildBreak(elements.getTargetOf(node))) {
-      reporter.internalError(node, "'break' target not found");
-    }
-    return null;
-  }
-
-  ir.Primitive visitContinueStatement(ast.ContinueStatement node) {
-    if (!irBuilder.buildContinue(elements.getTargetOf(node))) {
-      reporter.internalError(node, "'continue' target not found");
-    }
-    return null;
-  }
-
-  // Build(EmptyStatement, C) = C
-  ir.Primitive visitEmptyStatement(ast.EmptyStatement node) {
-    assert(irBuilder.isOpen);
-    return null;
-  }
-
-  // Build(ExpressionStatement(e), C) = C'
-  //   where (C', _) = Build(e, C)
-  ir.Primitive visitExpressionStatement(ast.ExpressionStatement node) {
-    assert(irBuilder.isOpen);
-    if (node.expression is ast.Throw) {
-      // Throw expressions that occur as statements are translated differently
-      // from ones that occur as subexpressions.  This is achieved by peeking
-      // at statement-level expressions here.
-      irBuilder.buildThrow(visit(node.expression));
-    } else {
-      visit(node.expression);
-    }
-    return null;
-  }
-
-  ir.Primitive visitRethrow(ast.Rethrow node) {
-    assert(irBuilder.isOpen);
-    irBuilder.buildRethrow();
-    return null;
-  }
-
-  /// Construct a method that executes the forwarding call to the target
-  /// 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 [handleConstructorInvoke]).
-  visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
-    ConstructorElement targetConstructor =
-        elements.getRedirectingTargetConstructor(node).implementation;
-    ConstructorElement redirectingConstructor =
-        irBuilder.state.currentElement.implementation;
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    FunctionSignature redirectingSignature =
-        redirectingConstructor.functionSignature;
-    List<String> namedParameters = <String>[];
-    redirectingSignature.forEachParameter((ParameterElement parameter) {
-      arguments.add(irBuilder.environment.lookup(parameter));
-      if (parameter.isNamed) {
-        namedParameters.add(parameter.name);
-      }
-    });
-    ClassElement cls = redirectingConstructor.enclosingClass;
-    InterfaceType targetType =
-        redirectingConstructor.computeEffectiveTargetType(cls.thisType);
-    CallStructure callStructure =
-        new CallStructure(redirectingSignature.parameterCount, namedParameters);
-    callStructure =
-        normalizeStaticArguments(callStructure, targetConstructor, arguments);
-    ir.Primitive instance = irBuilder.buildConstructorInvocation(
-        targetConstructor,
-        callStructure,
-        targetType,
-        arguments,
-        sourceInformationBuilder.buildNew(node));
-    irBuilder.buildReturn(
-        value: instance,
-        sourceInformation: sourceInformationBuilder.buildReturn(node));
-  }
-
-  visitFor(ast.For node) {
-    List<LocalElement> loopVariables = <LocalElement>[];
-    if (node.initializer is ast.VariableDefinitions) {
-      ast.VariableDefinitions definitions = node.initializer;
-      for (ast.Node node in definitions.definitions.nodes) {
-        LocalElement loopVariable = elements[node];
-        loopVariables.add(loopVariable);
-      }
-    }
-
-    JumpTarget target = elements.getTargetDefinition(node);
-    irBuilder.buildFor(
-        buildInitializer: subbuild(node.initializer),
-        buildCondition: subbuild(node.condition),
-        buildBody: subbuild(node.body),
-        buildUpdate: subbuildSequence(node.update),
-        closureScope: getClosureScopeForNode(node),
-        loopVariables: loopVariables,
-        target: target);
-  }
-
-  visitIf(ast.If node) {
-    irBuilder.buildIf(build(node.condition), subbuild(node.thenPart),
-        subbuild(node.elsePart), sourceInformationBuilder.buildIf(node));
-  }
-
-  visitLabeledStatement(ast.LabeledStatement node) {
-    ast.Statement body = node.statement;
-    if (body is ast.Loop) {
-      visit(body);
-    } else {
-      JumpTarget target = elements.getTargetDefinition(body);
-      irBuilder.buildLabeledStatement(
-          buildBody: subbuild(body), target: target);
-    }
-  }
-
-  visitDoWhile(ast.DoWhile node) {
-    irBuilder.buildDoWhile(
-        buildBody: subbuild(node.body),
-        buildCondition: subbuild(node.condition),
-        target: elements.getTargetDefinition(node),
-        closureScope: getClosureScopeForNode(node));
-  }
-
-  visitWhile(ast.While node) {
-    irBuilder.buildWhile(
-        buildCondition: subbuild(node.condition),
-        buildBody: subbuild(node.body),
-        target: elements.getTargetDefinition(node),
-        closureScope: getClosureScopeForNode(node));
-  }
-
-  visitAsyncForIn(ast.AsyncForIn node) {
-    // Translate await for into a loop over a StreamIterator.  The source
-    // statement:
-    //
-    // await for (<decl> in <stream>) <body>
-    //
-    // is translated as if it were:
-    //
-    // var iterator = new StreamIterator(<stream>);
-    // try {
-    //   while (await iterator.hasNext()) {
-    //     <decl> = await iterator.current;
-    //     <body>
-    //   }
-    // } finally {
-    //   await iterator.cancel();
-    // }
-    ir.Primitive stream = visit(node.expression);
-    ir.Primitive dummyTypeArgument = irBuilder.buildNullConstant();
-    ConstructorElement constructor = helpers.streamIteratorConstructor;
-    ir.Primitive iterator = irBuilder.addPrimitive(new ir.InvokeConstructor(
-        constructor.enclosingClass.thisType,
-        constructor,
-        new Selector.callConstructor(constructor.memberName, 1),
-        <ir.Primitive>[stream, dummyTypeArgument],
-        sourceInformationBuilder.buildGeneric(node)));
-
-    buildTryBody(IrBuilder builder) {
-      ir.Node buildLoopCondition(IrBuilder builder) {
-        ir.Primitive moveNext = builder.buildDynamicInvocation(
-            iterator,
-            Selectors.moveNext,
-            elements.getMoveNextTypeMask(node),
-            <ir.Primitive>[],
-            sourceInformationBuilder.buildForInMoveNext(node));
-        return builder.addPrimitive(new ir.Await(moveNext));
-      }
-
-      ir.Node buildLoopBody(IrBuilder builder) {
-        return withBuilder(builder, () {
-          ir.Primitive current = irBuilder.buildDynamicInvocation(
-              iterator,
-              Selectors.current,
-              elements.getCurrentTypeMask(node),
-              <ir.Primitive>[],
-              sourceInformationBuilder.buildForInCurrent(node));
-          Element variable = elements.getForInVariable(node);
-          SourceInformation sourceInformation =
-              sourceInformationBuilder.buildForInSet(node);
-          if (Elements.isLocal(variable)) {
-            if (node.declaredIdentifier.asVariableDefinitions() != null) {
-              irBuilder.declareLocalVariable(variable);
-            }
-            irBuilder.buildLocalVariableSet(
-                variable, current, sourceInformation);
-          } else if (Elements.isError(variable) ||
-              Elements.isMalformed(variable)) {
-            Selector selector =
-                new Selector.setter(new Name(variable.name, variable.library));
-            List<ir.Primitive> args = <ir.Primitive>[current];
-            // Note the comparison below.  It can be the case that an element
-            // isError and isMalformed.
-            if (Elements.isError(variable)) {
-              irBuilder.buildStaticNoSuchMethod(
-                  selector, args, sourceInformation);
-            } else {
-              irBuilder.buildErroneousInvocation(
-                  variable, selector, args, sourceInformation);
-            }
-          } else if (Elements.isStaticOrTopLevel(variable)) {
-            if (variable.isField) {
-              irBuilder.addPrimitive(new ir.SetStatic(variable, current));
-            } else {
-              irBuilder.buildStaticSetterSet(
-                  variable, current, sourceInformation);
-            }
-          } else {
-            ir.Primitive receiver = irBuilder.buildThis();
-            ast.Node identifier = node.declaredIdentifier;
-            irBuilder.buildDynamicSet(
-                receiver,
-                elements.getSelector(identifier),
-                elements.getTypeMask(identifier),
-                current,
-                sourceInformation);
-          }
-          visit(node.body);
-        });
-      }
-
-      builder.buildWhile(
-          buildCondition: buildLoopCondition,
-          buildBody: buildLoopBody,
-          target: elements.getTargetDefinition(node),
-          closureScope: getClosureScopeForNode(node));
-    }
-
-    ir.Node buildFinallyBody(IrBuilder builder) {
-      ir.Primitive cancellation = builder.buildDynamicInvocation(
-          iterator,
-          Selectors.cancel,
-          backend.dynamicType,
-          <ir.Primitive>[],
-          sourceInformationBuilder.buildGeneric(node));
-      return builder.addPrimitive(new ir.Await(cancellation));
-    }
-
-    irBuilder.buildTryFinally(
-        new TryStatementInfo(), buildTryBody, buildFinallyBody);
-  }
-
-  visitAwait(ast.Await node) {
-    assert(irBuilder.isOpen);
-    ir.Primitive value = visit(node.expression);
-    return irBuilder.addPrimitive(new ir.Await(value));
-  }
-
-  visitYield(ast.Yield node) {
-    assert(irBuilder.isOpen);
-    ir.Primitive value = visit(node.expression);
-    return irBuilder.addPrimitive(new ir.Yield(value, node.hasStar));
-  }
-
-  visitSyncForIn(ast.SyncForIn node) {
-    // [node.declaredIdentifier] can be either an [ast.VariableDefinitions]
-    // (defining a new local variable) or a send designating some existing
-    // variable.
-    ast.Node identifier = node.declaredIdentifier;
-    ast.VariableDefinitions variableDeclaration =
-        identifier.asVariableDefinitions();
-    Element variableElement = elements.getForInVariable(node);
-    Selector selector = elements.getSelector(identifier);
-
-    irBuilder.buildForIn(
-        buildExpression: subbuild(node.expression),
-        buildVariableDeclaration: subbuild(variableDeclaration),
-        variableElement: variableElement,
-        variableSelector: selector,
-        variableMask: elements.getTypeMask(identifier),
-        variableSetSourceInformation:
-            sourceInformationBuilder.buildForInSet(node),
-        currentMask: elements.getCurrentTypeMask(node),
-        currentSourceInformation:
-            sourceInformationBuilder.buildForInCurrent(node),
-        moveNextMask: elements.getMoveNextTypeMask(node),
-        moveNextSourceInformation:
-            sourceInformationBuilder.buildForInMoveNext(node),
-        iteratorMask: elements.getIteratorTypeMask(node),
-        iteratorSourceInformation:
-            sourceInformationBuilder.buildForInIterator(node),
-        buildBody: subbuild(node.body),
-        target: elements.getTargetDefinition(node),
-        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.options.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) {
-      Element element = elements[definition];
-      ir.Primitive initialValue;
-      // Definitions are either SendSets if there is an initializer, or
-      // Identifiers if there is no initializer.
-      if (definition is ast.SendSet) {
-        assert(!definition.arguments.isEmpty);
-        assert(definition.arguments.tail.isEmpty);
-        initialValue = visit(definition.arguments.head);
-        initialValue = checkTypeVsElement(initialValue, element);
-      } else {
-        assert(definition is ast.Identifier);
-      }
-      irBuilder.declareLocalVariable(element, initialValue: initialValue);
-    }
-    return null;
-  }
-
-  static final RegExp nativeRedirectionRegExp =
-      new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$');
-
-  // Build(Return(e), C) = C'[InvokeContinuation(return, x)]
-  //   where (C', x) = Build(e, C)
-  //
-  // Return without a subexpression is translated as if it were return null.
-  visitReturn(ast.Return node) {
-    assert(irBuilder.isOpen);
-    SourceInformation source = sourceInformationBuilder.buildReturn(node);
-    if (node.beginToken.value == 'native') {
-      FunctionElement function = irBuilder.state.currentElement;
-      assert(backend.isNative(function));
-      ast.Node nativeBody = node.expression;
-      if (nativeBody != null) {
-        ast.LiteralString jsCode = nativeBody.asLiteralString();
-        String javaScriptCode = jsCode.dartString.slowToString();
-        assert(invariant(
-            nativeBody, !nativeRedirectionRegExp.hasMatch(javaScriptCode),
-            message: "Deprecated syntax, use @JSName('name') instead."));
-        assert(invariant(
-            nativeBody, function.functionSignature.parameterCount == 0,
-            message: 'native "..." syntax is restricted to '
-                'functions with zero parameters.'));
-        irBuilder.buildNativeFunctionBody(function, javaScriptCode,
-            sourceInformationBuilder.buildForeignCode(node));
-      } else {
-        String name = backend.nativeData.getFixedBackendName(function);
-        irBuilder.buildRedirectingNativeFunctionBody(function, name, source);
-      }
-    } else {
-      irBuilder.buildReturn(
-          value: build(node.expression), sourceInformation: source);
-    }
-  }
-
-  visitSwitchStatement(ast.SwitchStatement node) {
-    // Dart switch cases can be labeled and be the target of continue from
-    // within the switch.  Such cases are 'recursive'.  If there are any
-    // recursive cases, we implement the switch using a pair of switches with
-    // the second one switching over a state variable in a loop.  The first
-    // switch contains the non-recursive cases, and the second switch contains
-    // the recursive ones.
-    //
-    // For example, for the Dart switch:
-    //
-    // switch (E) {
-    //   case 0:
-    //     BODY0;
-    //     break;
-    //   LABEL0: case 1:
-    //     BODY1;
-    //     break;
-    //   case 2:
-    //     BODY2;
-    //     continue LABEL1;
-    //   LABEL1: case 3:
-    //     BODY3;
-    //     continue LABEL0;
-    //   default:
-    //     BODY4;
-    // }
-    //
-    // We translate it as if it were the JavaScript:
-    //
-    // var state = -1;
-    // switch (E) {
-    //   case 0:
-    //     BODY0;
-    //     break;
-    //   case 1:
-    //     state = 0;  // Recursive, label ID = 0.
-    //     break;
-    //   case 2:
-    //     BODY2;
-    //     state = 1;  // Continue to label ID = 1.
-    //     break;
-    //   case 3:
-    //     state = 1;  // Recursive, label ID = 1.
-    //     break;
-    //   default:
-    //     BODY4;
-    // }
-    // L: while (state != -1) {
-    //   case 0:
-    //     BODY1;
-    //     break L;  // Break from switch becomes break from loop.
-    //   case 1:
-    //     BODY2;
-    //     state = 0;  // Continue to label ID = 0.
-    //     break;
-    // }
-    assert(irBuilder.isOpen);
-    // Preprocess: compute a list of cases that are the target of continue.
-    // These are the so-called 'recursive' cases.
-    List<JumpTarget> continueTargets = <JumpTarget>[];
-    List<ast.Node> switchCases = node.cases.nodes.toList();
-    for (ast.SwitchCase switchCase in switchCases) {
-      for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-        if (labelOrCase is ast.Label) {
-          LabelDefinition definition = elements.getLabelDefinition(labelOrCase);
-          if (definition != null && definition.isContinueTarget) {
-            continueTargets.add(definition.target);
-          }
-        }
-      }
-    }
-
-    // If any cases are continue targets, use an anonymous local value to
-    // implement a state machine.  The initial value is -1.
-    ir.Primitive initial;
-    int stateIndex;
-    if (continueTargets.isNotEmpty) {
-      initial = irBuilder.buildIntegerConstant(-1);
-      stateIndex = irBuilder.environment.length;
-      irBuilder.environment.extend(null, initial);
-    }
-
-    // Use a simple switch for the non-recursive cases.  A break will go to the
-    // join-point after the switch.  A continue to a labeled case will assign
-    // to the state variable and go to the join-point.
-    ir.Primitive value = visit(node.expression);
-    JumpCollector join = new ForwardJumpCollector(irBuilder.environment,
-        target: elements.getTargetDefinition(node));
-    irBuilder.state.breakCollectors.add(join);
-    for (int i = 0; i < continueTargets.length; ++i) {
-      // The state value is i, the case's position in the list of recursive
-      // cases.
-      irBuilder.state.continueCollectors
-          .add(new GotoJumpCollector(continueTargets[i], stateIndex, i, join));
-    }
-
-    // For each non-default case use a pair of functions, one to translate the
-    // condition and one to translate the body.  For the default case use a
-    // function to translate the body.  Use continueTargetIterator as a pointer
-    // to the next recursive case.
-    Iterator<JumpTarget> continueTargetIterator = continueTargets.iterator;
-    continueTargetIterator.moveNext();
-    List<SwitchCaseInfo> cases = <SwitchCaseInfo>[];
-    SubbuildFunction buildDefaultBody;
-    for (ast.SwitchCase switchCase in switchCases) {
-      JumpTarget nextContinueTarget = continueTargetIterator.current;
-      if (switchCase.isDefaultCase) {
-        if (nextContinueTarget != null &&
-            switchCase == nextContinueTarget.statement) {
-          // In this simple switch, recursive cases are as if they immediately
-          // continued to themselves.
-          buildDefaultBody = nested(() {
-            irBuilder.buildContinue(nextContinueTarget);
-          });
-          continueTargetIterator.moveNext();
-        } else {
-          // Non-recursive cases consist of the translation of the body.
-          // For the default case, there is implicitly a break if control
-          // flow reaches the end.
-          buildDefaultBody = nested(() {
-            irBuilder.buildSequence(switchCase.statements, visit);
-            if (irBuilder.isOpen) irBuilder.jumpTo(join);
-          });
-        }
-        continue;
-      }
-
-      ir.Primitive buildCondition(IrBuilder builder) {
-        // There can be multiple cases sharing the same body, because empty
-        // cases are allowed to fall through to the next one.  Each case is
-        // a comparison, build a short-circuited disjunction of all of them.
-        return withBuilder(builder, () {
-          ir.Primitive condition;
-          for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-            if (labelOrCase is ast.CaseMatch) {
-              ir.Primitive buildComparison() {
-                ir.Primitive constant =
-                    translateConstant(labelOrCase.expression);
-                return irBuilder.buildIdentical(value, constant);
-              }
-
-              if (condition == null) {
-                condition = buildComparison();
-              } else {
-                condition = irBuilder.buildLogicalOperator(
-                    condition,
-                    nested(buildComparison),
-                    sourceInformationBuilder.buildSwitchCase(switchCase),
-                    isLazyOr: true);
-              }
-            }
-          }
-          return condition;
-        });
-      }
-
-      SubbuildFunction buildBody;
-      if (nextContinueTarget != null &&
-          switchCase == nextContinueTarget.statement) {
-        // Recursive cases are as if they immediately continued to themselves.
-        buildBody = nested(() {
-          irBuilder.buildContinue(nextContinueTarget);
-        });
-        continueTargetIterator.moveNext();
-      } else {
-        // Non-recursive cases consist of the translation of the body.  It is a
-        // runtime error if control-flow reaches the end of the body of any but
-        // the last case.
-        buildBody = (IrBuilder builder) {
-          withBuilder(builder, () {
-            irBuilder.buildSequence(switchCase.statements, visit);
-            if (irBuilder.isOpen) {
-              if (switchCase == switchCases.last) {
-                irBuilder.jumpTo(join);
-              } else {
-                Element error = helpers.fallThroughError;
-                ir.Primitive exception = irBuilder.buildInvokeStatic(
-                    error,
-                    new Selector.fromElement(error),
-                    <ir.Primitive>[],
-                    sourceInformationBuilder.buildGeneric(node));
-                irBuilder.buildThrow(exception);
-              }
-            }
-          });
-          return null;
-        };
-      }
-
-      cases.add(new SwitchCaseInfo(buildCondition, buildBody,
-          sourceInformationBuilder.buildSwitchCase(switchCase)));
-    }
-
-    irBuilder.buildSimpleSwitch(join, cases, buildDefaultBody);
-    irBuilder.state.breakCollectors.removeLast();
-    irBuilder.state.continueCollectors.length -= continueTargets.length;
-    if (continueTargets.isEmpty) return;
-
-    // If there were recursive cases build a while loop whose body is a
-    // switch containing (only) the recursive cases.  The condition is
-    // 'state != initialValue' so the loop is not taken when the state variable
-    // has not been assigned.
-    //
-    // 'loop' is the join-point of the exits from the inner switch which will
-    // perform another iteration of the loop.  'exit' is the join-point of the
-    // breaks from the switch, outside the loop.
-    JumpCollector loop = new ForwardJumpCollector(irBuilder.environment);
-    JumpCollector exit = new ForwardJumpCollector(irBuilder.environment,
-        target: elements.getTargetDefinition(node));
-    irBuilder.state.breakCollectors.add(exit);
-    for (int i = 0; i < continueTargets.length; ++i) {
-      irBuilder.state.continueCollectors
-          .add(new GotoJumpCollector(continueTargets[i], stateIndex, i, loop));
-    }
-    cases.clear();
-    for (int i = 0; i < continueTargets.length; ++i) {
-      // The conditions compare to the recursive case index.
-      ir.Primitive buildCondition(IrBuilder builder) {
-        ir.Primitive constant = builder.buildIntegerConstant(i);
-        return builder.buildIdentical(
-            builder.environment.index2value[stateIndex], constant);
-      }
-
-      ir.Primitive buildBody(IrBuilder builder) {
-        withBuilder(builder, () {
-          ast.SwitchCase switchCase = continueTargets[i].statement;
-          irBuilder.buildSequence(switchCase.statements, visit);
-          if (irBuilder.isOpen) {
-            if (switchCase == switchCases.last) {
-              irBuilder.jumpTo(exit);
-            } else {
-              Element error = helpers.fallThroughError;
-              ir.Primitive exception = irBuilder.buildInvokeStatic(
-                  error,
-                  new Selector.fromElement(error),
-                  <ir.Primitive>[],
-                  sourceInformationBuilder.buildGeneric(node));
-              irBuilder.buildThrow(exception);
-            }
-          }
-        });
-        return null;
-      }
-
-      cases.add(new SwitchCaseInfo(buildCondition, buildBody,
-          sourceInformationBuilder.buildSwitch(node)));
-    }
-
-    // A loop with a simple switch in the body.
-    IrBuilder whileBuilder = irBuilder.makeDelimitedBuilder();
-    whileBuilder.buildWhile(buildCondition: (IrBuilder builder) {
-      ir.Primitive condition = builder.buildIdentical(
-          builder.environment.index2value[stateIndex], initial);
-      return builder.buildNegation(
-          condition, sourceInformationBuilder.buildSwitch(node));
-    }, buildBody: (IrBuilder builder) {
-      builder.buildSimpleSwitch(loop, cases, null);
-    });
-    // Jump to the exit continuation.  This jump is the body of the loop exit
-    // continuation, so the loop exit continuation can be eta-reduced.  The
-    // jump is here for simplicity because `buildWhile` does not expose the
-    // loop's exit continuation directly and has already emitted all jumps
-    // to it anyway.
-    whileBuilder.jumpTo(exit);
-    irBuilder.add(new ir.LetCont(exit.continuation, whileBuilder.root));
-    irBuilder.environment = exit.environment;
-    irBuilder.environment.discard(1); // Discard the state variable.
-    irBuilder.state.breakCollectors.removeLast();
-    irBuilder.state.continueCollectors.length -= continueTargets.length;
-  }
-
-  visitTryStatement(ast.TryStatement node) {
-    List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
-    for (ast.CatchBlock catchClause in node.catchBlocks.nodes) {
-      LocalVariableElement exceptionVariable;
-      if (catchClause.exception != null) {
-        exceptionVariable = elements[catchClause.exception];
-      }
-      LocalVariableElement stackTraceVariable;
-      if (catchClause.trace != null) {
-        stackTraceVariable = elements[catchClause.trace];
-      }
-      DartType type;
-      if (catchClause.onKeyword != null) {
-        type = elements.getType(catchClause.type);
-      }
-      catchClauseInfos.add(new CatchClauseInfo(
-          type: type,
-          exceptionVariable: exceptionVariable,
-          stackTraceVariable: stackTraceVariable,
-          buildCatchBlock: subbuild(catchClause.block),
-          sourceInformation: sourceInformationBuilder.buildCatch(catchClause)));
-    }
-
-    assert(!node.catchBlocks.isEmpty || node.finallyBlock != null);
-    if (!node.catchBlocks.isEmpty && node.finallyBlock != null) {
-      // Try/catch/finally is encoded in terms of try/catch and try/finally:
-      //
-      // try tryBlock catch (ex, st) catchBlock finally finallyBlock
-      // ==>
-      // try { try tryBlock catch (ex, st) catchBlock } finally finallyBlock
-      irBuilder.buildTryFinally(tryStatements[node.finallyBlock],
-          (IrBuilder inner) {
-        inner.buildTryCatch(tryStatements[node.catchBlocks],
-            subbuild(node.tryBlock), catchClauseInfos);
-      }, subbuild(node.finallyBlock));
-    } else if (!node.catchBlocks.isEmpty) {
-      irBuilder.buildTryCatch(tryStatements[node.catchBlocks],
-          subbuild(node.tryBlock), catchClauseInfos);
-    } else {
-      irBuilder.buildTryFinally(tryStatements[node.finallyBlock],
-          subbuild(node.tryBlock), subbuild(node.finallyBlock));
-    }
-  }
-
-  // ## Expressions ##
-  ir.Primitive visitConditional(ast.Conditional node) {
-    return irBuilder.buildConditional(
-        build(node.condition),
-        subbuild(node.thenExpression),
-        subbuild(node.elseExpression),
-        sourceInformationBuilder.buildIf(node));
-  }
-
-  // For all simple literals:
-  // Build(Literal(c), C) = C[let val x = Constant(c) in [], x]
-  ir.Primitive visitLiteralBool(ast.LiteralBool node) {
-    assert(irBuilder.isOpen);
-    return irBuilder.buildBooleanConstant(node.value);
-  }
-
-  ir.Primitive visitLiteralDouble(ast.LiteralDouble node) {
-    assert(irBuilder.isOpen);
-    return irBuilder.buildDoubleConstant(node.value);
-  }
-
-  ir.Primitive visitLiteralInt(ast.LiteralInt node) {
-    assert(irBuilder.isOpen);
-    return irBuilder.buildIntegerConstant(node.value);
-  }
-
-  ir.Primitive visitLiteralNull(ast.LiteralNull node) {
-    assert(irBuilder.isOpen);
-    return irBuilder.buildNullConstant();
-  }
-
-  ir.Primitive visitLiteralString(ast.LiteralString node) {
-    assert(irBuilder.isOpen);
-    return irBuilder.buildDartStringConstant(node.dartString);
-  }
-
-  ConstantValue getConstantForNode(ast.Node node) {
-    return irBuilder.state.constants.getConstantValueForNode(node, elements);
-  }
-
-  ConstantValue getConstantForVariable(VariableElement element) {
-    ConstantExpression constant = element.constant;
-    if (constant != null) {
-      return irBuilder.state.constants.getConstantValue(constant);
-    }
-    return null;
-  }
-
-  ir.Primitive buildConstantExpression(
-      ConstantExpression expression, SourceInformation sourceInformation) {
-    return irBuilder.buildConstant(
-        irBuilder.state.constants.getConstantValue(expression),
-        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);
-    TypeMask allocationSiteType = getAllocationSiteType(node);
-    // TODO(sra): In checked mode, the elements must be checked as though
-    // operator[]= is called.
-    ir.Primitive list = irBuilder.buildListLiteral(type, values,
-        allocationSiteType: allocationSiteType);
-    if (type.treatAsRaw) return list;
-    // Call JSArray<E>.typed(allocation) to install the reified type.
-    ConstructorElement constructor = helpers.jsArrayTypedConstructor;
-    ir.Primitive tagged = irBuilder.buildConstructorInvocation(
-        constructor.effectiveTarget,
-        CallStructure.ONE_ARG,
-        constructor.computeEffectiveTargetType(type),
-        <ir.Primitive>[list],
-        sourceInformationBuilder.buildNew(node));
-
-    if (allocationSiteType == null) return tagged;
-
-    return irBuilder
-        .addPrimitive(new ir.Refinement(tagged, allocationSiteType));
-  }
-
-  ir.Primitive visitLiteralMap(ast.LiteralMap node) {
-    assert(irBuilder.isOpen);
-    if (node.isConst) {
-      return translateConstant(node);
-    }
-
-    InterfaceType type = elements.getType(node);
-
-    if (node.entries.nodes.isEmpty) {
-      if (type.treatAsRaw) {
-        return irBuilder.buildStaticFunctionInvocation(
-            helpers.mapLiteralUntypedEmptyMaker,
-            <ir.Primitive>[],
-            sourceInformationBuilder.buildNew(node));
-      } else {
-        ConstructorElement constructor = helpers.mapLiteralConstructorEmpty;
-        return irBuilder.buildConstructorInvocation(
-            constructor.effectiveTarget,
-            CallStructure.NO_ARGS,
-            constructor.computeEffectiveTargetType(type),
-            <ir.Primitive>[],
-            sourceInformationBuilder.buildNew(node));
-      }
-    }
-
-    List<ir.Primitive> keysAndValues = <ir.Primitive>[];
-    for (ast.LiteralMapEntry entry in node.entries.nodes.toList()) {
-      keysAndValues.add(visit(entry.key));
-      keysAndValues.add(visit(entry.value));
-    }
-    ir.Primitive keysAndValuesList =
-        irBuilder.buildListLiteral(null, keysAndValues);
-
-    if (type.treatAsRaw) {
-      return irBuilder.buildStaticFunctionInvocation(
-          helpers.mapLiteralUntypedMaker,
-          <ir.Primitive>[keysAndValuesList],
-          sourceInformationBuilder.buildNew(node));
-    } else {
-      ConstructorElement constructor = helpers.mapLiteralConstructor;
-      return irBuilder.buildConstructorInvocation(
-          constructor.effectiveTarget,
-          CallStructure.ONE_ARG,
-          constructor.computeEffectiveTargetType(type),
-          <ir.Primitive>[keysAndValuesList],
-          sourceInformationBuilder.buildNew(node));
-    }
-  }
-
-  ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
-    assert(irBuilder.isOpen);
-    return translateConstant(node);
-  }
-
-  ir.Primitive visitParenthesizedExpression(ast.ParenthesizedExpression node) {
-    assert(irBuilder.isOpen);
-    return visit(node.expression);
-  }
-
-  // Stores the result of visiting a CascadeReceiver, so we can return it from
-  // its enclosing Cascade.
-  ir.Primitive _currentCascadeReceiver;
-
-  ir.Primitive visitCascadeReceiver(ast.CascadeReceiver node) {
-    assert(irBuilder.isOpen);
-    return _currentCascadeReceiver = visit(node.expression);
-  }
-
-  ir.Primitive visitCascade(ast.Cascade node) {
-    assert(irBuilder.isOpen);
-    var oldCascadeReceiver = _currentCascadeReceiver;
-    // Throw away the result of visiting the expression.
-    // Instead we return the result of visiting the CascadeReceiver.
-    visit(node.expression);
-    ir.Primitive receiver = _currentCascadeReceiver;
-    _currentCascadeReceiver = oldCascadeReceiver;
-    return receiver;
-  }
-
-  @override
-  ir.Primitive visitAssert(ast.Assert node) {
-    assert(irBuilder.isOpen);
-    if (compiler.options.enableUserAssertions) {
-      return giveup(node, 'assert in checked mode not implemented');
-    } else {
-      // The call to assert and its argument expression must be ignored
-      // in production mode.
-      // Assertions can only occur in expression statements, so no value needs
-      // to be returned.
-      return null;
-    }
-  }
-
-  // ## Sends ##
-  @override
-  void previsitDeferredAccess(ast.Send node, PrefixElement prefix, _) {
-    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);
-  }
-
-  ir.Primitive visitNamedArgument(ast.NamedArgument node) {
-    assert(irBuilder.isOpen);
-    return visit(node.expression);
-  }
-
-  @override
-  ir.Primitive visitExpressionInvoke(ast.Send node, ast.Node expression,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    ir.Primitive receiver = visit(expression);
-    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
-    callStructure = normalizeDynamicArguments(callStructure, arguments);
-    return irBuilder.buildCallInvocation(receiver, callStructure, arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  /// Returns `true` if [node] is a super call.
-  // TODO(johnniwinther): Remove the need for this.
-  bool isSuperCall(ast.Send node) {
-    return node != null && node.receiver != null && node.receiver.isSuper();
-  }
-
-  @override
-  ir.Primitive handleConstantGet(
-      ast.Node node, ConstantExpression constant, _) {
-    return buildConstantExpression(
-        constant, sourceInformationBuilder.buildGet(node));
-  }
-
-  /// If [node] is null, returns this.
-  /// Otherwise visits [node] and returns the result.
-  ir.Primitive translateReceiver(ast.Expression node) {
-    return node != null ? visit(node) : irBuilder.buildThis();
-  }
-
-  @override
-  ir.Primitive handleDynamicGet(
-      ast.Send node, ast.Node receiver, Name name, _) {
-    return irBuilder.buildDynamicGet(
-        translateReceiver(receiver),
-        new Selector.getter(name),
-        elements.getTypeMask(node),
-        sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitIfNotNullDynamicPropertyGet(
-      ast.Send node, ast.Node receiver, Name name, _) {
-    ir.Primitive target = visit(receiver);
-    return irBuilder.buildIfNotNullSend(
-        target,
-        nested(() => irBuilder.buildDynamicGet(
-            target,
-            new Selector.getter(name),
-            elements.getTypeMask(node),
-            sourceInformationBuilder.buildGet(node))),
-        sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  ir.Primitive visitDynamicTypeLiteralGet(
-      ast.Send node, ConstantExpression constant, _) {
-    return buildConstantExpression(
-        constant, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitLocalVariableGet(
-      ast.Send node, LocalVariableElement element, _) {
-    return element.isConst
-        ? irBuilder.buildConstant(getConstantForVariable(element),
-            sourceInformation: sourceInformationBuilder.buildGet(node))
-        : irBuilder.buildLocalGet(element);
-  }
-
-  ir.Primitive handleLocalGet(ast.Send node, LocalElement element, _) {
-    return irBuilder.buildLocalGet(element);
-  }
-
-  @override
-  ir.Primitive handleStaticFunctionGet(
-      ast.Send node, MethodElement function, _) {
-    return irBuilder.addPrimitive(new ir.GetStatic(function, isFinal: true));
-  }
-
-  @override
-  ir.Primitive handleStaticGetterGet(ast.Send node, FunctionElement getter, _) {
-    return buildStaticGetterGet(
-        getter, node, sourceInformationBuilder.buildGet(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) {
-    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);
-    } else {
-      return irBuilder.buildStaticGetterGet(getter, sourceInformation);
-    }
-  }
-
-  @override
-  ir.Primitive visitSuperFieldGet(ast.Send node, FieldElement field, _) {
-    return irBuilder.buildSuperFieldGet(
-        field, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitSuperGetterGet(ast.Send node, FunctionElement getter, _) {
-    return irBuilder.buildSuperGetterGet(
-        getter, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitSuperMethodGet(ast.Send node, MethodElement method, _) {
-    return irBuilder.buildSuperMethodGet(
-        method, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperGet(ast.Send node, Element element, _) {
-    return buildSuperNoSuchMethod(
-        elements.getSelector(node),
-        elements.getTypeMask(node),
-        [],
-        sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperSet(
-      ast.Send node, Element element, ast.Node rhs, _) {
-    return buildSuperNoSuchMethod(
-        elements.getSelector(node),
-        elements.getTypeMask(node),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitThisGet(ast.Identifier node, _) {
-    if (irBuilder.state.thisParameter == null) {
-      // TODO(asgerf,johnniwinther): Should be in a visitInvalidThis method.
-      // 'this' in static context. Just translate to null.
-      assert(compiler.compilationFailed);
-      return irBuilder.buildNullConstant();
-    }
-    return irBuilder.buildThis();
-  }
-
-  ir.Primitive translateTypeVariableTypeLiteral(
-      TypeVariableElement element, SourceInformation sourceInformation) {
-    return irBuilder.buildReifyTypeVariable(element.type, sourceInformation);
-  }
-
-  @override
-  ir.Primitive visitTypeVariableTypeLiteralGet(
-      ast.Send node, TypeVariableElement element, _) {
-    return translateTypeVariableTypeLiteral(
-        element, sourceInformationBuilder.buildGet(node));
-  }
-
-  ir.Primitive translateLogicalOperator(ast.Expression left,
-      ast.Expression right, SourceInformation sourceInformation,
-      {bool isLazyOr}) {
-    ir.Primitive leftValue = visit(left);
-
-    ir.Primitive buildRightValue(IrBuilder rightBuilder) {
-      return withBuilder(rightBuilder, () => visit(right));
-    }
-
-    return irBuilder.buildLogicalOperator(
-        leftValue, buildRightValue, sourceInformation,
-        isLazyOr: isLazyOr);
-  }
-
-  @override
-  ir.Primitive visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
-    return irBuilder.buildIfNull(
-        build(left), subbuild(right), sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  ir.Primitive visitLogicalAnd(
-      ast.Send node, ast.Node left, ast.Node right, _) {
-    return translateLogicalOperator(
-        left, right, sourceInformationBuilder.buildIf(node),
-        isLazyOr: false);
-  }
-
-  @override
-  ir.Primitive visitLogicalOr(ast.Send node, ast.Node left, ast.Node right, _) {
-    return translateLogicalOperator(
-        left, right, sourceInformationBuilder.buildIf(node),
-        isLazyOr: true);
-  }
-
-  @override
-  ir.Primitive visitAs(ast.Send node, ast.Node expression, DartType type, _) {
-    ir.Primitive receiver = visit(expression);
-    return irBuilder.buildTypeOperator(
-        receiver, type, sourceInformationBuilder.buildAs(node),
-        isTypeTest: false);
-  }
-
-  @override
-  ir.Primitive visitIs(ast.Send node, ast.Node expression, DartType type, _) {
-    ir.Primitive value = visit(expression);
-    return irBuilder.buildTypeOperator(
-        value, type, sourceInformationBuilder.buildIs(node),
-        isTypeTest: true);
-  }
-
-  @override
-  ir.Primitive visitIsNot(
-      ast.Send node, ast.Node expression, DartType type, _) {
-    ir.Primitive value = visit(expression);
-    ir.Primitive check = irBuilder.buildTypeOperator(
-        value, type, sourceInformationBuilder.buildIs(node),
-        isTypeTest: true);
-    return irBuilder.buildNegation(
-        check, sourceInformationBuilder.buildIf(node));
-  }
-
-  ir.Primitive translateBinary(ast.Send node, ast.Node left,
-      op.BinaryOperator operator, ast.Node right) {
-    ir.Primitive receiver = visit(left);
-    Selector selector = new Selector.binaryOperator(operator.selectorName);
-    List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
-    CallStructure callStructure =
-        normalizeDynamicArguments(selector.callStructure, arguments);
-    return irBuilder.buildDynamicInvocation(
-        receiver,
-        new Selector(selector.kind, selector.memberName, callStructure),
-        elements.getTypeMask(node),
-        arguments,
-        sourceInformationBuilder.buildCall(node, node.selector));
-  }
-
-  @override
-  ir.Primitive visitBinary(ast.Send node, ast.Node left,
-      op.BinaryOperator operator, ast.Node right, _) {
-    return translateBinary(node, left, operator, right);
-  }
-
-  @override
-  ir.Primitive visitIndex(ast.Send node, ast.Node receiver, ast.Node index, _) {
-    ir.Primitive target = visit(receiver);
-    Selector selector = new Selector.index();
-    List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
-    CallStructure callStructure =
-        normalizeDynamicArguments(selector.callStructure, arguments);
-    return irBuilder.buildDynamicInvocation(
-        target,
-        new Selector(selector.kind, selector.memberName, callStructure),
-        elements.getTypeMask(node),
-        arguments,
-        sourceInformationBuilder.buildCall(receiver, node.selector));
-  }
-
-  ir.Primitive translateSuperBinary(
-      FunctionElement function,
-      op.BinaryOperator operator,
-      ast.Node argument,
-      SourceInformation sourceInformation) {
-    List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)];
-    return irBuilder.buildSuperMethodInvocation(
-        function, CallStructure.ONE_ARG, arguments, sourceInformation);
-  }
-
-  @override
-  ir.Primitive visitSuperBinary(ast.Send node, FunctionElement function,
-      op.BinaryOperator operator, ast.Node argument, _) {
-    return translateSuperBinary(function, operator, argument,
-        sourceInformationBuilder.buildBinary(node));
-  }
-
-  @override
-  ir.Primitive visitSuperIndex(
-      ast.Send node, FunctionElement function, ast.Node index, _) {
-    return irBuilder.buildSuperIndex(
-        function, visit(index), sourceInformationBuilder.buildIndex(node));
-  }
-
-  @override
-  ir.Primitive visitEquals(ast.Send node, ast.Node left, ast.Node right, _) {
-    return translateBinary(node, left, op.BinaryOperator.EQ, right);
-  }
-
-  @override
-  ir.Primitive visitSuperEquals(
-      ast.Send node, FunctionElement function, ast.Node argument, _) {
-    return translateSuperBinary(function, op.BinaryOperator.EQ, argument,
-        sourceInformationBuilder.buildBinary(node));
-  }
-
-  @override
-  ir.Primitive visitNot(ast.Send node, ast.Node expression, _) {
-    return irBuilder.buildNegation(
-        visit(expression), sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  ir.Primitive visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) {
-    return irBuilder.buildNegation(
-        translateBinary(node, left, op.BinaryOperator.NOT_EQ, right),
-        sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  ir.Primitive visitSuperNotEquals(
-      ast.Send node, FunctionElement function, ast.Node argument, _) {
-    return irBuilder.buildNegation(
-        translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument,
-            sourceInformationBuilder.buildBinary(node)),
-        sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  ir.Primitive visitUnary(
-      ast.Send node, op.UnaryOperator operator, ast.Node expression, _) {
-    // TODO(johnniwinther): Clean up the creation of selectors.
-    Selector selector = operator.selector;
-    ir.Primitive receiver = translateReceiver(expression);
-    return irBuilder.buildDynamicInvocation(
-        receiver,
-        selector,
-        elements.getTypeMask(node),
-        const [],
-        sourceInformationBuilder.buildCall(expression, node));
-  }
-
-  @override
-  ir.Primitive visitSuperUnary(
-      ast.Send node, op.UnaryOperator operator, FunctionElement function, _) {
-    return irBuilder.buildSuperMethodInvocation(function, CallStructure.NO_ARGS,
-        const [], sourceInformationBuilder.buildCall(node, node));
-  }
-
-  // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
-  // semantic correlation between arguments and invocation.
-  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.
-  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 argumentsNode,
-      CallStructure callStructure,
-      SourceInformation sourceInformation) {
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildCallInvocation(
-        target, callStructure, arguments, sourceInformation);
-  }
-
-  @override
-  ir.Primitive handleConstantInvoke(ast.Send node, ConstantExpression constant,
-      ast.NodeList arguments, CallStructure callStructure, _) {
-    ir.Primitive target = buildConstantExpression(
-        constant, sourceInformationBuilder.buildGet(node));
-    return translateCallInvoke(target, arguments, callStructure,
-        sourceInformationBuilder.buildCall(node, arguments));
-  }
-
-  @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);
-    if (constructor.isGenerativeConstructor &&
-        backend.isNativeOrExtendsNative(constructor.enclosingClass)) {
-      arguments.insert(0, irBuilder.buildNullConstant());
-    }
-    // Use default values from the effective target, not the immediate target.
-    ConstructorElement target;
-    if (constructor == compiler.symbolConstructor) {
-      // The Symbol constructor should perform validation of its argument
-      // which is not expressible as a Dart const constructor.  Instead, the
-      // libraries contain a dummy const constructor implementation that
-      // doesn't perform validation and the compiler compiles a call to
-      // (non-const) Symbol.validated when it sees new Symbol(...).
-      target = helpers.symbolValidatedConstructor;
-    } else {
-      target = constructor.implementation;
-    }
-    while (target.isRedirectingFactory && !target.isCyclicRedirection) {
-      target = target.effectiveTarget.implementation;
-    }
-
-    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);
-    }
-    ConstructorElement constructorImplementation = constructor.implementation;
-    return irBuilder.buildConstructorInvocation(
-        target,
-        callStructure,
-        constructorImplementation.computeEffectiveTargetType(type),
-        arguments,
-        sourceInformationBuilder.buildNew(node),
-        allocationSiteType: allocationSiteType);
-  }
-
-  @override
-  ir.Primitive handleDynamicInvoke(ast.Send node, ast.Node receiver,
-      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(
-        target,
-        new Selector(selector.kind, selector.memberName, callStructure),
-        elements.getTypeMask(node),
-        arguments,
-        sourceInformationBuilder.buildCall(node, node.selector));
-  }
-
-  @override
-  ir.Primitive visitIfNotNullDynamicPropertyInvoke(ast.Send node,
-      ast.Node receiver, ast.NodeList argumentsNode, Selector selector, _) {
-    ir.Primitive target = visit(receiver);
-    return irBuilder.buildIfNotNullSend(target, 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,
-          sourceInformationBuilder.buildCall(node, node.selector));
-    }), sourceInformationBuilder.buildIf(node));
-  }
-
-  ir.Primitive handleLocalInvoke(ast.Send node, LocalElement element,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    ir.Primitive function = irBuilder.buildLocalGet(element);
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildCallInvocation(function, callStructure, arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
-  ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
-    return buildStaticFieldGet(field, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive handleStaticFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    SourceInformation src = sourceInformationBuilder.buildGet(node);
-    ir.Primitive target = buildStaticFieldGet(field, src);
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildCallInvocation(target, callStructure, arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
-  ir.Primitive handleStaticFunctionInvoke(ast.Send node, MethodElement function,
-      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(
-      ast.Send node,
-      MethodElement function,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        elements.getSelector(node),
-        arguments.nodes.mapToList(visit),
-        sourceInformationBuilder.buildCall(node, node.selector));
-  }
-
-  @override
-  ir.Primitive handleStaticGetterInvoke(ast.Send node, FunctionElement getter,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    ir.Primitive target = buildStaticGetterGet(
-        getter, node, sourceInformationBuilder.buildGet(node));
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildCallInvocation(target, callStructure, arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
-  ir.Primitive visitSuperFieldInvoke(ast.Send node, FieldElement field,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    ir.Primitive target = irBuilder.buildSuperFieldGet(
-        field, sourceInformationBuilder.buildGet(node));
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildCallInvocation(target, callStructure, arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
-  ir.Primitive visitSuperGetterInvoke(ast.Send node, FunctionElement getter,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    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, arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
-  ir.Primitive visitSuperMethodInvoke(ast.Send node, MethodElement method,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure = translateStaticArguments(
-        argumentsNode, method, callStructure, arguments);
-    return irBuilder.buildSuperMethodInvocation(method, callStructure,
-        arguments, sourceInformationBuilder.buildCall(node, node.selector));
-  }
-
-  @override
-  ir.Primitive visitSuperMethodIncompatibleInvoke(
-      ast.Send node,
-      MethodElement method,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    List<ir.Primitive> normalizedArguments = <ir.Primitive>[];
-    CallStructure normalizedCallStructure = translateDynamicArguments(
-        arguments, callStructure, normalizedArguments);
-    return buildSuperNoSuchMethod(
-        new Selector.call(method.memberName, normalizedCallStructure),
-        elements.getTypeMask(node),
-        normalizedArguments,
-        sourceInformationBuilder.buildCall(node, arguments));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperInvoke(ast.Send node, Element element,
-      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 buildSuperNoSuchMethod(
-        new Selector.call(elements.getSelector(node).memberName, callStructure),
-        elements.getTypeMask(node),
-        arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
-  ir.Primitive visitThisInvoke(
-      ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
-    return translateCallInvoke(irBuilder.buildThis(), arguments, callStructure,
-        sourceInformationBuilder.buildCall(node, arguments));
-  }
-
-  @override
-  ir.Primitive visitTypeVariableTypeLiteralInvoke(
-      ast.Send node,
-      TypeVariableElement element,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    return translateCallInvoke(
-        translateTypeVariableTypeLiteral(
-            element, sourceInformationBuilder.buildGet(node)),
-        arguments,
-        callStructure,
-        sourceInformationBuilder.buildCall(node, arguments));
-  }
-
-  @override
-  ir.Primitive visitIndexSet(
-      ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
-    return irBuilder.buildDynamicIndexSet(
-        visit(receiver),
-        elements.getTypeMask(node),
-        visit(index),
-        visit(rhs),
-        sourceInformationBuilder.buildIndexSet(node));
-  }
-
-  @override
-  ir.Primitive visitSuperIndexSet(ast.SendSet node, FunctionElement function,
-      ast.Node index, ast.Node rhs, _) {
-    return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs),
-        sourceInformationBuilder.buildIndexSet(node));
-  }
-
-  ir.Primitive translateIfNull(ast.SendSet node, 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.
-    return irBuilder.buildIfNull(value, nested(() {
-      ir.Primitive newValue = build(rhs);
-      setValue(newValue);
-      return newValue;
-    }), sourceInformationBuilder.buildIf(node));
-  }
-
-  ir.Primitive translateCompounds(ast.SendSet node, ir.Primitive getValue(),
-      CompoundRhs rhs, void setValue(ir.Primitive value)) {
-    ir.Primitive value = getValue();
-    op.BinaryOperator operator = rhs.operator;
-    assert(operator.kind != op.BinaryOperatorKind.IF_NULL);
-
-    Selector operatorSelector =
-        new Selector.binaryOperator(operator.selectorName);
-    ir.Primitive rhsValue;
-    if (rhs.kind == CompoundKind.ASSIGNMENT) {
-      rhsValue = visit(rhs.rhs);
-    } else {
-      rhsValue = irBuilder.buildIntegerConstant(1);
-    }
-    List<ir.Primitive> arguments = <ir.Primitive>[rhsValue];
-    CallStructure callStructure =
-        normalizeDynamicArguments(operatorSelector.callStructure, arguments);
-    TypeMask operatorTypeMask =
-        elements.getOperatorTypeMaskInComplexSendSet(node);
-    SourceInformation operatorSourceInformation =
-        sourceInformationBuilder.buildCall(node, node.assignmentOperator);
-    ir.Primitive result = irBuilder.buildDynamicInvocation(
-        value,
-        new Selector(
-            operatorSelector.kind, operatorSelector.memberName, callStructure),
-        operatorTypeMask,
-        arguments,
-        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 value = getValue();
-    // Unlike other compound operators if-null conditionally will not do the
-    // assignment operation.
-    return irBuilder.buildIfNull(value, nested(() {
-      ir.Primitive newValue = build(rhs);
-      setValue(newValue);
-      return newValue;
-    }), sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  ir.Primitive handleSuperIndexSetIfNull(
-      ast.SendSet node,
-      Element indexFunction,
-      Element indexSetFunction,
-      ast.Node index,
-      ast.Node rhs,
-      arg,
-      {bool isGetterValid,
-      bool isSetterValid}) {
-    return translateSetIfNull(
-        node,
-        () {
-          if (isGetterValid) {
-            return irBuilder.buildSuperMethodGet(
-                indexFunction, sourceInformationBuilder.buildIndex(node));
-          } else {
-            return buildSuperNoSuchGetter(
-                indexFunction,
-                elements.getGetterTypeMaskInComplexSendSet(node),
-                sourceInformationBuilder.buildIndex(node));
-          }
-        },
-        rhs,
-        (ir.Primitive result) {
-          if (isSetterValid) {
-            return irBuilder.buildSuperMethodGet(
-                indexSetFunction, sourceInformationBuilder.buildIndexSet(node));
-          } else {
-            return buildSuperNoSuchSetter(
-                indexSetFunction,
-                elements.getTypeMask(node),
-                result,
-                sourceInformationBuilder.buildIndexSet(node));
-          }
-        });
-  }
-
-  @override
-  ir.Primitive visitIndexSetIfNull(
-      ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, arg) {
-    ir.Primitive target = visit(receiver);
-    ir.Primitive indexValue = visit(index);
-    return translateSetIfNull(
-        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,
-              sourceInformationBuilder.buildCall(receiver, node));
-        },
-        rhs,
-        (ir.Primitive result) {
-          irBuilder.buildDynamicIndexSet(target, elements.getTypeMask(node),
-              indexValue, result, sourceInformationBuilder.buildIndexSet(node));
-        });
-  }
-
-  @override
-  ir.Primitive handleDynamicSet(
-      ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) {
-    return irBuilder.buildDynamicSet(
-        translateReceiver(receiver),
-        new Selector.setter(name),
-        elements.getTypeMask(node),
-        visit(rhs),
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitIfNotNullDynamicPropertySet(
-      ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) {
-    ir.Primitive target = visit(receiver);
-    return irBuilder.buildIfNotNullSend(
-        target,
-        nested(() => irBuilder.buildDynamicSet(
-            target,
-            new Selector.setter(name),
-            elements.getTypeMask(node),
-            visit(rhs),
-            sourceInformationBuilder.buildAssignment(node))),
-        sourceInformationBuilder.buildIf(node));
-  }
-
-  @override
-  ir.Primitive handleLocalSet(
-      ast.SendSet node, LocalElement element, ast.Node rhs, _) {
-    ir.Primitive value = visit(rhs);
-    value = checkTypeVsElement(value, element);
-    return irBuilder.buildLocalVariableSet(
-        element, value, sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive handleStaticFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    ir.Primitive value = visit(rhs);
-    irBuilder.addPrimitive(new ir.SetStatic(
-        field, value, sourceInformationBuilder.buildAssignment(node)));
-    return value;
-  }
-
-  @override
-  ir.Primitive visitSuperFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    return irBuilder.buildSuperFieldSet(
-        field, visit(rhs), sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitSuperSetterSet(
-      ast.SendSet node, FunctionElement setter, ast.Node rhs, _) {
-    return irBuilder.buildSuperSetterSet(
-        setter, visit(rhs), sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperIndexSet(
-      ast.Send node, Element element, ast.Node index, ast.Node rhs, arg) {
-    return giveup(node, 'visitUnresolvedSuperIndexSet');
-  }
-
-  @override
-  ir.Primitive handleStaticSetterSet(
-      ast.SendSet node, FunctionElement setter, ast.Node rhs, _) {
-    return irBuilder.buildStaticSetterSet(
-        setter, visit(rhs), sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive handleTypeLiteralConstantCompounds(
-      ast.SendSet node, ConstantExpression constant, CompoundRhs rhs, arg) {
-    SourceInformation src = sourceInformationBuilder.buildGet(node);
-    return translateCompounds(
-        node,
-        () {
-          return buildConstantExpression(constant, src);
-        },
-        rhs,
-        (ir.Primitive value) {
-          // The binary operator will throw before this.
-        });
-  }
-
-  @override
-  ir.Primitive handleTypeLiteralConstantSetIfNulls(
-      ast.SendSet node, ConstantExpression constant, ast.Node rhs, _) {
-    // The type literal is never `null`.
-    return buildConstantExpression(
-        constant, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive handleDynamicCompounds(
-      ast.SendSet node, ast.Node receiver, Name name, CompoundRhs rhs, arg) {
-    ir.Primitive target = translateReceiver(receiver);
-    ir.Primitive helper() {
-      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,
-                sourceInformationBuilder.buildAssignment(node));
-          });
-    }
-    return node.isConditional
-        ? irBuilder.buildIfNotNullSend(
-            target, nested(helper), sourceInformationBuilder.buildIf(node))
-        : helper();
-  }
-
-  @override
-  ir.Primitive handleDynamicSetIfNulls(
-      ast.Send node, ast.Node receiver, Name name, ast.Node rhs, _) {
-    ir.Primitive target = translateReceiver(receiver);
-    ir.Primitive helper() {
-      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,
-                sourceInformationBuilder.buildAssignment(node));
-          });
-    }
-    return node.isConditional
-        ? irBuilder.buildIfNotNullSend(
-            target, nested(helper), sourceInformationBuilder.buildIf(node))
-        : helper();
-  }
-
-  ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value,
-      SourceInformation sourceInformation) {
-    Selector selector = new Selector.setter(
-        new Name(local.name, local.library, isSetter: true));
-    return irBuilder.buildStaticNoSuchMethod(
-        selector, [value], sourceInformation);
-  }
-
-  @override
-  ir.Primitive handleLocalCompounds(
-      ast.SendSet node, LocalElement local, CompoundRhs rhs, arg,
-      {bool isSetterValid}) {
-    return translateCompounds(
-        node,
-        () {
-          return irBuilder.buildLocalGet(local);
-        },
-        rhs,
-        (ir.Primitive result) {
-          if (isSetterValid) {
-            irBuilder.buildLocalVariableSet(
-                local, result, sourceInformationBuilder.buildAssignment(node));
-          } else {
-            Selector selector = new Selector.setter(
-                new Name(local.name, local.library, isSetter: true));
-            irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result],
-                sourceInformationBuilder.buildAssignment(node));
-          }
-        });
-  }
-
-  @override
-  ir.Primitive handleLocalSetIfNulls(
-      ast.SendSet node, LocalElement local, ast.Node rhs, _,
-      {bool isSetterValid}) {
-    return translateSetIfNull(
-        node,
-        () {
-          return irBuilder.buildLocalGet(local,
-              sourceInformation: sourceInformationBuilder.buildGet(node));
-        },
-        rhs,
-        (ir.Primitive result) {
-          SourceInformation sourceInformation =
-              sourceInformationBuilder.buildAssignment(node);
-          if (isSetterValid) {
-            irBuilder.buildLocalVariableSet(local, result, sourceInformation);
-          } else {
-            Selector selector = new Selector.setter(
-                new Name(local.name, local.library, isSetter: true));
-            irBuilder.buildStaticNoSuchMethod(
-                selector, <ir.Primitive>[result], sourceInformation);
-          }
-        });
-  }
-
-  @override
-  ir.Primitive handleStaticCompounds(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      CompoundRhs rhs,
-      arg) {
-    return translateCompounds(
-        node,
-        () {
-          SourceInformation sourceInformation =
-              sourceInformationBuilder.buildGet(node);
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return buildStaticFieldGet(getter, sourceInformation);
-            case CompoundGetter.GETTER:
-              return buildStaticGetterGet(getter, node, sourceInformation);
-            case CompoundGetter.METHOD:
-              return irBuilder.addPrimitive(new ir.GetStatic(getter,
-                  sourceInformation: sourceInformation, isFinal: true));
-            case CompoundGetter.UNRESOLVED:
-              return irBuilder.buildStaticNoSuchMethod(
-                  new Selector.getter(new Name(getter.name, getter.library)),
-                  <ir.Primitive>[],
-                  sourceInformation);
-          }
-        },
-        rhs,
-        (ir.Primitive result) {
-          SourceInformation sourceInformation =
-              sourceInformationBuilder.buildAssignment(node);
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              irBuilder.addPrimitive(
-                  new ir.SetStatic(setter, result, sourceInformation));
-              return;
-            case CompoundSetter.SETTER:
-              irBuilder.buildStaticSetterSet(setter, result, sourceInformation);
-              return;
-            case CompoundSetter.INVALID:
-              irBuilder.buildStaticNoSuchMethod(
-                  new Selector.setter(new Name(setter.name, setter.library)),
-                  <ir.Primitive>[result],
-                  sourceInformation);
-              return;
-          }
-        });
-  }
-
-  @override
-  ir.Primitive handleStaticSetIfNulls(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      ast.Node rhs,
-      _) {
-    return translateSetIfNull(
-        node,
-        () {
-          SourceInformation sourceInformation =
-              sourceInformationBuilder.buildGet(node);
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return buildStaticFieldGet(getter, sourceInformation);
-            case CompoundGetter.GETTER:
-              return buildStaticGetterGet(getter, node, sourceInformation);
-            case CompoundGetter.METHOD:
-              return irBuilder.addPrimitive(new ir.GetStatic(getter,
-                  sourceInformation: sourceInformation, isFinal: true));
-            case CompoundGetter.UNRESOLVED:
-              return irBuilder.buildStaticNoSuchMethod(
-                  new Selector.getter(new Name(getter.name, getter.library)),
-                  <ir.Primitive>[],
-                  sourceInformation);
-          }
-        },
-        rhs,
-        (ir.Primitive result) {
-          SourceInformation sourceInformation =
-              sourceInformationBuilder.buildAssignment(node);
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              irBuilder.addPrimitive(
-                  new ir.SetStatic(setter, result, sourceInformation));
-              return;
-            case CompoundSetter.SETTER:
-              irBuilder.buildStaticSetterSet(setter, result, sourceInformation);
-              return;
-            case CompoundSetter.INVALID:
-              irBuilder.buildStaticNoSuchMethod(
-                  new Selector.setter(new Name(setter.name, setter.library)),
-                  <ir.Primitive>[result],
-                  sourceInformation);
-              return;
-          }
-        });
-  }
-
-  ir.Primitive buildSuperNoSuchGetter(
-      Element element, TypeMask mask, SourceInformation sourceInformation) {
-    return buildSuperNoSuchMethod(
-        new Selector.getter(new Name(element.name, element.library)),
-        mask,
-        const <ir.Primitive>[],
-        sourceInformation);
-  }
-
-  ir.Primitive buildSuperNoSuchSetter(Element element, TypeMask mask,
-      ir.Primitive value, SourceInformation sourceInformation) {
-    return buildSuperNoSuchMethod(
-        new Selector.setter(new Name(element.name, element.library)),
-        mask,
-        <ir.Primitive>[value],
-        sourceInformation);
-  }
-
-  @override
-  ir.Primitive handleSuperCompounds(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      CompoundRhs rhs,
-      arg) {
-    return translateCompounds(
-        node,
-        () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return irBuilder.buildSuperFieldGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.GETTER:
-              return irBuilder.buildSuperGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildSuperMethodGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.UNRESOLVED:
-              return buildSuperNoSuchGetter(
-                  getter,
-                  elements.getGetterTypeMaskInComplexSendSet(node),
-                  sourceInformationBuilder.buildGet(node));
-          }
-        },
-        rhs,
-        (ir.Primitive result) {
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              irBuilder.buildSuperFieldSet(setter, result,
-                  sourceInformationBuilder.buildAssignment(node));
-              return;
-            case CompoundSetter.SETTER:
-              irBuilder.buildSuperSetterSet(setter, result,
-                  sourceInformationBuilder.buildAssignment(node));
-              return;
-            case CompoundSetter.INVALID:
-              buildSuperNoSuchSetter(setter, elements.getTypeMask(node), result,
-                  sourceInformationBuilder.buildAssignment(node));
-              return;
-          }
-        });
-  }
-
-  @override
-  ir.Primitive handleSuperSetIfNulls(
-      ast.SendSet node,
-      Element getter,
-      CompoundGetter getterKind,
-      Element setter,
-      CompoundSetter setterKind,
-      ast.Node rhs,
-      _) {
-    return translateSetIfNull(
-        node,
-        () {
-          switch (getterKind) {
-            case CompoundGetter.FIELD:
-              return irBuilder.buildSuperFieldGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.GETTER:
-              return irBuilder.buildSuperGetterGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.METHOD:
-              return irBuilder.buildSuperMethodGet(
-                  getter, sourceInformationBuilder.buildGet(node));
-            case CompoundGetter.UNRESOLVED:
-              return buildSuperNoSuchGetter(
-                  getter,
-                  elements.getGetterTypeMaskInComplexSendSet(node),
-                  sourceInformationBuilder.buildGet(node));
-          }
-        },
-        rhs,
-        (ir.Primitive result) {
-          switch (setterKind) {
-            case CompoundSetter.FIELD:
-              irBuilder.buildSuperFieldSet(setter, result,
-                  sourceInformationBuilder.buildAssignment(node));
-              return;
-            case CompoundSetter.SETTER:
-              irBuilder.buildSuperSetterSet(setter, result,
-                  sourceInformationBuilder.buildAssignment(node));
-              return;
-            case CompoundSetter.INVALID:
-              buildSuperNoSuchSetter(setter, elements.getTypeMask(node), result,
-                  sourceInformationBuilder.buildAssignment(node));
-              return;
-          }
-        });
-  }
-
-  @override
-  ir.Primitive handleTypeVariableTypeLiteralCompounds(ast.SendSet node,
-      TypeVariableElement typeVariable, CompoundRhs rhs, arg) {
-    return translateCompounds(
-        node,
-        () {
-          return irBuilder.buildReifyTypeVariable(
-              typeVariable.type, sourceInformationBuilder.buildGet(node));
-        },
-        rhs,
-        (ir.Primitive value) {
-          // The binary operator will throw before this.
-        });
-  }
-
-  @override
-  ir.Primitive visitTypeVariableTypeLiteralSetIfNull(
-      ast.Send node, TypeVariableElement element, ast.Node rhs, _) {
-    // The type variable is never `null`.
-    return translateTypeVariableTypeLiteral(
-        element, sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive handleIndexCompounds(ast.SendSet node, ast.Node receiver,
-      ast.Node index, CompoundRhs rhs, arg) {
-    ir.Primitive target = visit(receiver);
-    ir.Primitive indexValue = visit(index);
-    return translateCompounds(
-        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,
-              sourceInformationBuilder.buildCall(receiver, node));
-        },
-        rhs,
-        (ir.Primitive result) {
-          irBuilder.buildDynamicIndexSet(target, elements.getTypeMask(node),
-              indexValue, result, sourceInformationBuilder.buildIndexSet(node));
-        });
-  }
-
-  @override
-  ir.Primitive handleSuperIndexCompounds(
-      ast.SendSet node,
-      Element indexFunction,
-      Element indexSetFunction,
-      ast.Node index,
-      CompoundRhs rhs,
-      arg,
-      {bool isGetterValid,
-      bool isSetterValid}) {
-    ir.Primitive indexValue = visit(index);
-    return translateCompounds(
-        node,
-        () {
-          if (isGetterValid) {
-            return irBuilder.buildSuperIndex(indexFunction, indexValue,
-                sourceInformationBuilder.buildIndex(node));
-          } else {
-            return buildSuperNoSuchMethod(
-                new Selector.index(),
-                elements.getGetterTypeMaskInComplexSendSet(node),
-                <ir.Primitive>[indexValue],
-                sourceInformationBuilder.buildIndex(node));
-          }
-        },
-        rhs,
-        (ir.Primitive result) {
-          if (isSetterValid) {
-            irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result,
-                sourceInformationBuilder.buildIndexSet(node));
-          } else {
-            buildSuperNoSuchMethod(
-                new Selector.indexSet(),
-                elements.getTypeMask(node),
-                <ir.Primitive>[indexValue, result],
-                sourceInformationBuilder.buildIndexSet(node));
-          }
-        });
-  }
-
-  /// 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! EnumConstantElement ||
-          element.enclosingClass != enumClass) {
-        internalError(node, 'expected a JsBuiltin enum value');
-      }
-      EnumConstantElement enumConstant = element;
-      int index = enumConstant.index;
-      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 = elements.getNativeData(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, sourceInformationBuilder.buildForeignCode(node));
-
-      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,
-            sourceInformationBuilder.buildForeignCode(node),
-            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,
-            sourceInformationBuilder.buildForeignCode(node));
-
-      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,
-            sourceInformationBuilder.buildForeignCode(node));
-
-      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.options.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, sourceInformationBuilder.buildForeignCode(node));
-
-      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.DEPENDS_OTHER,
-            sourceInformationBuilder.buildForeignCode(node));
-
-      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.CHANGES_OTHER,
-            sourceInformationBuilder.buildForeignCode(node));
-
-      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>[],
-              sourceInformationBuilder.buildForeignCode(node));
-        }
-        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]
-  /// (after stringify conversion).
-  void buildStringParts(ast.Node node, List<ir.Primitive> accumulator) {
-    if (node is ast.StringJuxtaposition) {
-      buildStringParts(node.first, accumulator);
-      buildStringParts(node.second, accumulator);
-    } else if (node is ast.StringInterpolation) {
-      buildStringParts(node.string, accumulator);
-      for (ast.StringInterpolationPart part in node.parts) {
-        buildStringParts(part.expression, accumulator);
-        buildStringParts(part.string, accumulator);
-      }
-    } else if (node is ast.LiteralString) {
-      // Empty strings often occur at the end of a string interpolation,
-      // do not bother to include them.
-      if (!node.dartString.isEmpty) {
-        accumulator.add(irBuilder.buildDartStringConstant(node.dartString));
-      }
-    } else if (node is ast.ParenthesizedExpression) {
-      buildStringParts(node.expression, accumulator);
-    } else {
-      ir.Primitive value = visit(node);
-      accumulator.add(irBuilder.buildStaticFunctionInvocation(
-          helpers.stringInterpolationHelper,
-          <ir.Primitive>[value],
-          sourceInformationBuilder.buildStringInterpolation(node)));
-    }
-  }
-
-  ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) {
-    assert(irBuilder.isOpen);
-    List<ir.Primitive> parts = <ir.Primitive>[];
-    buildStringParts(node, parts);
-    return irBuilder.buildStringConcatenation(
-        parts, sourceInformationBuilder.buildStringInterpolation(node));
-  }
-
-  ir.Primitive visitStringInterpolation(ast.StringInterpolation node) {
-    assert(irBuilder.isOpen);
-    List<ir.Primitive> parts = <ir.Primitive>[];
-    buildStringParts(node, parts);
-    return irBuilder.buildStringConcatenation(
-        parts, sourceInformationBuilder.buildStringInterpolation(node));
-  }
-
-  ir.Primitive translateConstant(ast.Node node) {
-    assert(irBuilder.isOpen);
-    return irBuilder.buildConstant(getConstantForNode(node),
-        sourceInformation: sourceInformationBuilder.buildGet(node));
-  }
-
-  ir.Primitive visitThrow(ast.Throw node) {
-    assert(irBuilder.isOpen);
-    // This function is not called for throw expressions occurring as
-    // statements.
-    return irBuilder.buildNonTailThrow(visit(node.expression));
-  }
-
-  ir.Primitive buildSuperNoSuchMethod(Selector selector, TypeMask mask,
-      List<ir.Primitive> arguments, SourceInformation sourceInformation) {
-    ClassElement cls = elements.analyzedElement.enclosingClass;
-    MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
-    if (!Selectors.noSuchMethod_.signatureApplies(element)) {
-      element = compiler.coreClasses.objectClass
-          .lookupMember(Identifiers.noSuchMethod_);
-    }
-    return irBuilder.buildSuperMethodInvocation(
-        element,
-        Selectors.noSuchMethod_.callStructure,
-        [irBuilder.buildInvocationMirror(selector, arguments)],
-        sourceInformation);
-  }
-
-  @override
-  ir.Primitive visitUnresolvedCompound(ast.Send node, Element element,
-      op.AssignmentOperator operator, ast.Node rhs, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.getter(new Name(element.name, element.library)),
-        [],
-        sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedClassConstructorInvoke(
-      ast.NewExpression node,
-      Element element,
-      DartType type,
-      ast.NodeList arguments,
-      Selector selector,
-      _) {
-    // If the class is missing it's a runtime error.
-    ir.Primitive message =
-        irBuilder.buildStringConstant("Unresolved class: '${element.name}'");
-    return irBuilder.buildStaticFunctionInvocation(helpers.throwRuntimeError,
-        <ir.Primitive>[message], sourceInformationBuilder.buildNew(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedConstructorInvoke(
-      ast.NewExpression node,
-      Element constructor,
-      DartType type,
-      ast.NodeList argumentsNode,
-      Selector selector,
-      _) {
-    // If the class is there but the constructor is missing, it's an NSM error.
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    CallStructure callStructure = translateDynamicArguments(
-        argumentsNode, selector.callStructure, arguments);
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector(selector.kind, selector.memberName, callStructure),
-        arguments,
-        sourceInformationBuilder.buildNew(node));
-  }
-
-  @override
-  ir.Primitive visitConstructorIncompatibleInvoke(
-      ast.NewExpression node,
-      ConstructorElement constructor,
-      DartType type,
-      ast.NodeList argumentsNode,
-      CallStructure callStructure,
-      _) {
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.call(constructor.memberName, callStructure),
-        arguments,
-        sourceInformationBuilder.buildNew(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedGet(ast.Send node, Element element, _) {
-    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), [],
-        sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedInvoke(ast.Send node, Element element,
-      ast.NodeList arguments, Selector selector, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        elements.getSelector(node),
-        arguments.nodes.mapToList(visit),
-        sourceInformationBuilder.buildCall(node, node.selector));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedRedirectingFactoryConstructorInvoke(
-      ast.NewExpression node,
-      ConstructorElement constructor,
-      InterfaceType type,
-      ast.NodeList argumentsNode,
-      CallStructure callStructure,
-      _) {
-    String nameString = Elements.reconstructConstructorName(constructor);
-    Name name = new Name(nameString, constructor.library);
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.call(name, callStructure),
-        arguments,
-        sourceInformationBuilder.buildNew(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSet(
-      ast.Send node, Element element, ast.Node rhs, _) {
-    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
-        [visit(rhs)], sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperIndex(
-      ast.Send node, Element function, ast.Node index, _) {
-    // Assume the index getter is missing.
-    return buildSuperNoSuchMethod(
-        new Selector.index(),
-        elements.getTypeMask(node),
-        [visit(index)],
-        sourceInformationBuilder.buildIndex(node));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperBinary(ast.Send node, Element element,
-      op.BinaryOperator operator, ast.Node argument, _) {
-    return buildSuperNoSuchMethod(
-        elements.getSelector(node),
-        elements.getTypeMask(node),
-        [visit(argument)],
-        sourceInformationBuilder.buildCall(node, node.selector));
-  }
-
-  @override
-  ir.Primitive visitUnresolvedSuperUnary(
-      ast.Send node, op.UnaryOperator operator, Element element, _) {
-    return buildSuperNoSuchMethod(
-        elements.getSelector(node),
-        elements.getTypeMask(node),
-        [],
-        sourceInformationBuilder.buildCall(node, node.selector));
-  }
-
-  @override
-  ir.Primitive bulkHandleNode(ast.Node node, String message, _) {
-    return giveup(node, "Unhandled node: ${message.replaceAll('#', '$node')}");
-  }
-
-  @override
-  ir.Primitive bulkHandleError(ast.Node node, ErroneousElement error, _) {
-    return irBuilder.buildNullConstant();
-  }
-
-  @override
-  ir.Primitive visitClassTypeLiteralSet(
-      ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
-    InterfaceType type = constant.type;
-    ClassElement element = type.element;
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(element.memberName),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitTypedefTypeLiteralSet(
-      ast.SendSet node, TypeConstantExpression constant, ast.Node rhs, _) {
-    TypedefType type = constant.type;
-    TypedefElement element = type.element;
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(element.memberName),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitTypeVariableTypeLiteralSet(
-      ast.SendSet node, TypeVariableElement element, ast.Node rhs, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(element.memberName),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitDynamicTypeLiteralSet(
-      ast.SendSet node, ConstantExpression constant, ast.Node rhs, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(Names.dynamic_),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitAbstractClassConstructorInvoke(
-      ast.NewExpression node,
-      ConstructorElement element,
-      InterfaceType type,
-      ast.NodeList arguments,
-      CallStructure callStructure,
-      _) {
-    for (ast.Node argument in arguments) visit(argument);
-    ir.Primitive name =
-        irBuilder.buildStringConstant(element.enclosingClass.name);
-    return irBuilder.buildStaticFunctionInvocation(
-        helpers.throwAbstractClassInstantiationError,
-        <ir.Primitive>[name],
-        sourceInformationBuilder.buildNew(node));
-  }
-
-  @override
-  ir.Primitive handleFinalStaticFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    // TODO(asgerf): Include class name somehow for static class members?
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(field.memberName),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitFinalSuperFieldSet(
-      ast.SendSet node, FieldElement field, ast.Node rhs, _) {
-    return buildSuperNoSuchMethod(
-        new Selector.setter(field.memberName),
-        elements.getTypeMask(node),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive handleImmutableLocalSet(
-      ast.SendSet node, LocalElement local, ast.Node rhs, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(new Name(local.name, local.library)),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive handleStaticFunctionSet(
-      ast.Send node, MethodElement function, ast.Node rhs, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(function.memberName),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive handleStaticGetterSet(
-      ast.SendSet node, GetterElement getter, ast.Node rhs, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.setter(getter.memberName),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive handleStaticSetterGet(ast.Send node, SetterElement setter, _) {
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.getter(setter.memberName),
-        [],
-        sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive handleStaticSetterInvoke(ast.Send node, SetterElement setter,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    // Translate as a method call.
-    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
-    return irBuilder.buildStaticNoSuchMethod(
-        new Selector.call(setter.memberName, callStructure),
-        arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  @override
-  ir.Primitive visitSuperGetterSet(
-      ast.SendSet node, GetterElement getter, ast.Node rhs, _) {
-    return buildSuperNoSuchMethod(
-        new Selector.setter(getter.memberName),
-        elements.getTypeMask(node),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitSuperMethodSet(
-      ast.Send node, MethodElement method, ast.Node rhs, _) {
-    return buildSuperNoSuchMethod(
-        new Selector.setter(method.memberName),
-        elements.getTypeMask(node),
-        [visit(rhs)],
-        sourceInformationBuilder.buildAssignment(node));
-  }
-
-  @override
-  ir.Primitive visitSuperSetterGet(ast.Send node, SetterElement setter, _) {
-    return buildSuperNoSuchMethod(
-        new Selector.getter(setter.memberName),
-        elements.getTypeMask(node),
-        [],
-        sourceInformationBuilder.buildGet(node));
-  }
-
-  @override
-  ir.Primitive visitSuperSetterInvoke(ast.Send node, SetterElement setter,
-      ast.NodeList argumentsNode, CallStructure callStructure, _) {
-    List<ir.Primitive> arguments = <ir.Primitive>[];
-    callStructure =
-        translateDynamicArguments(argumentsNode, callStructure, arguments);
-    return buildSuperNoSuchMethod(
-        new Selector.call(setter.memberName, callStructure),
-        elements.getTypeMask(node),
-        arguments,
-        sourceInformationBuilder.buildCall(node, argumentsNode));
-  }
-
-  ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
-    try {
-      return action();
-    } catch (e) {
-      if (e == ABORT_IRNODE_BUILDER) {
-        return null;
-      }
-      rethrow;
-    }
-  }
-
-  internalError(ast.Node node, String message) {
-    reporter.internalError(node, message);
-  }
-
-  @override
-  visitNode(ast.Node node) {
-    giveup(node, "Unhandled node");
-  }
-
-  dynamic giveup(ast.Node node, [String reason]) {
-    bailoutMessage = '($node): $reason';
-    throw ABORT_IRNODE_BUILDER;
-  }
-}
-
-final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
-
-/// Determines which local variables should be boxed in a mutable variable
-/// inside a given try block.
-class TryBoxedVariables extends ast.Visitor {
-  final TreeElements elements;
-  TryBoxedVariables(this.elements);
-
-  FunctionElement currentFunction;
-  bool insideInitializer = false;
-  Set<Local> capturedVariables = new Set<Local>();
-
-  /// A map containing variables boxed inside try blocks.
-  ///
-  /// The map is keyed by the [NodeList] of catch clauses for try/catch and
-  /// by the finally block for try/finally.  try/catch/finally is treated
-  /// as a try/catch nested in the try block of a try/finally.
-  Map<ast.Node, TryStatementInfo> tryStatements =
-      <ast.Node, TryStatementInfo>{};
-
-  List<TryStatementInfo> tryNestingStack = <TryStatementInfo>[];
-  bool get inTryStatement => tryNestingStack.isNotEmpty;
-
-  String bailoutMessage = null;
-
-  giveup(ast.Node node, [String reason]) {
-    bailoutMessage = '($node): $reason';
-    throw ABORT_IRNODE_BUILDER;
-  }
-
-  void markAsCaptured(Local local) {
-    capturedVariables.add(local);
-  }
-
-  analyze(ast.Node node) {
-    visit(node);
-    // Variables that are captured by a closure are boxed for their entire
-    // lifetime, so they never need to be boxed on entry to a try block.
-    // They are not filtered out before this because we cannot identify all
-    // of them in the same pass (they may be captured by a closure after the
-    // try statement).
-    for (TryStatementInfo info in tryStatements.values) {
-      info.boxedOnEntry.removeAll(capturedVariables);
-    }
-  }
-
-  visit(ast.Node node) => node.accept(this);
-
-  visitNode(ast.Node node) {
-    node.visitChildren(this);
-  }
-
-  void handleSend(ast.Send node) {
-    Element element = elements[node];
-    if (Elements.isLocal(element) &&
-        !element.isConst &&
-        element.enclosingElement != currentFunction) {
-      LocalElement local = element;
-      markAsCaptured(local);
-    }
-  }
-
-  visitSend(ast.Send node) {
-    handleSend(node);
-    node.visitChildren(this);
-  }
-
-  visitSendSet(ast.SendSet node) {
-    handleSend(node);
-    Element element = elements[node];
-    if (Elements.isLocal(element)) {
-      LocalElement local = element;
-      if (insideInitializer &&
-          (local.isParameter || local.isInitializingFormal) &&
-          local.enclosingElement == currentFunction) {
-        assert(local.enclosingElement.isConstructor);
-        // Initializers in an initializer-list can communicate via parameters.
-        // If a parameter is stored in an initializer list we box it.
-        // TODO(sigurdm): Fix this.
-        // Though these variables do not outlive the activation of the
-        // function, they still need to be boxed.  As a simplification, we
-        // treat them as if they are captured by a closure (i.e., they do
-        // outlive the activation of the function).
-        markAsCaptured(local);
-      } else if (inTryStatement) {
-        assert(local.isParameter ||
-            local.isVariable ||
-            local.isInitializingFormal);
-        // Search for the position of the try block containing the variable
-        // declaration, or -1 if it is declared outside the outermost try.
-        int i = tryNestingStack.length - 1;
-        while (i >= 0 && !tryNestingStack[i].declared.contains(local)) {
-          --i;
-        }
-        // If there is a next inner try, then the variable should be boxed on
-        // entry to it.
-        if (i + 1 < tryNestingStack.length) {
-          tryNestingStack[i + 1].boxedOnEntry.add(local);
-        }
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  visitFunctionExpression(ast.FunctionExpression node) {
-    FunctionElement savedFunction = currentFunction;
-    currentFunction = elements[node];
-
-    if (currentFunction.asyncMarker != AsyncMarker.SYNC &&
-        currentFunction.asyncMarker != AsyncMarker.SYNC_STAR &&
-        currentFunction.asyncMarker != AsyncMarker.ASYNC) {
-      giveup(node, "cannot handle async* functions");
-    }
-
-    if (node.initializers != null) {
-      visit(node.initializers);
-    }
-    visit(node.body);
-    currentFunction = savedFunction;
-  }
-
-  visitTryStatement(ast.TryStatement node) {
-    // Try/catch/finally is treated as two simpler constructs: try/catch and
-    // try/finally.  The encoding is:
-    //
-    // try S0 catch (ex, st) S1 finally S2
-    // ==>
-    // try { try S0 catch (ex, st) S1 } finally S2
-    //
-    // The analysis associates variables assigned in S0 with the catch clauses
-    // and variables assigned in S0 and S1 with the finally block.
-    TryStatementInfo enterTryFor(ast.Node node) {
-      TryStatementInfo info = new TryStatementInfo();
-      tryStatements[node] = info;
-      tryNestingStack.add(info);
-      return info;
-    }
-    void leaveTryFor(TryStatementInfo info) {
-      assert(tryNestingStack.last == info);
-      tryNestingStack.removeLast();
-    }
-    bool hasCatch = !node.catchBlocks.isEmpty;
-    bool hasFinally = node.finallyBlock != null;
-    TryStatementInfo catchInfo, finallyInfo;
-    // There is a nesting stack of try blocks, so the outer try/finally block
-    // is added first.
-    if (hasFinally) finallyInfo = enterTryFor(node.finallyBlock);
-    if (hasCatch) catchInfo = enterTryFor(node.catchBlocks);
-    visit(node.tryBlock);
-
-    if (hasCatch) {
-      leaveTryFor(catchInfo);
-      visit(node.catchBlocks);
-    }
-    if (hasFinally) {
-      leaveTryFor(finallyInfo);
-      visit(node.finallyBlock);
-    }
-  }
-
-  visitVariableDefinitions(ast.VariableDefinitions node) {
-    if (inTryStatement) {
-      for (ast.Node definition in node.definitions.nodes) {
-        LocalVariableElement local = elements[definition];
-        assert(local != null);
-        // In the closure conversion pass we check for isInitializingFormal,
-        // but I'm not sure it can arise.
-        assert(!local.isInitializingFormal);
-        tryNestingStack.last.declared.add(local);
-      }
-    }
-    node.visitChildren(this);
-  }
-}
-
-/// The [IrBuilder]s view on the information about the program that has been
-/// computed in resolution and and type interence.
-class GlobalProgramInformation {
-  final Compiler _compiler;
-  JavaScriptBackend get _backend => _compiler.backend;
-
-  GlobalProgramInformation(this._compiler);
-
-  /// Returns [true], if the analysis could not determine that the type
-  /// arguments for the class [cls] are never used in the program.
-  bool requiresRuntimeTypesFor(ClassElement cls) {
-    return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
-  }
-
-  FunctionElement get throwTypeErrorHelper => _backend.helpers.throwTypeError;
-  Element get throwNoSuchMethod => _backend.helpers.throwNoSuchMethod;
-
-  ClassElement get nullClass => _compiler.coreClasses.nullClass;
-
-  DartType unaliasType(DartType type) => type.unaliased;
-
-  TypeMask getTypeMaskForForeign(NativeBehavior behavior) {
-    if (behavior == null) {
-      return _backend.dynamicType;
-    }
-    return TypeMaskFactory.fromNativeBehavior(behavior, _compiler);
-  }
-
-  bool isArrayType(TypeMask type) {
-    return type.satisfies(_backend.helpers.jsArrayClass, _compiler.world);
-  }
-
-  TypeMask getTypeMaskForNativeFunction(FunctionElement function) {
-    return _compiler.typesTask.getGuaranteedReturnTypeOfElement(function);
-  }
-
-  FieldElement locateSingleField(Selector selector, TypeMask type) {
-    return _compiler.world.locateSingleField(selector, type);
-  }
-
-  bool fieldNeverChanges(FieldElement field) {
-    return _compiler.world.fieldNeverChanges(field);
-  }
-
-  Element get closureConverter {
-    return _backend.helpers.closureConverter;
-  }
-
-  void addNativeMethod(FunctionElement function) {
-    _backend.emitter.nativeEmitter.nativeMethods.add(function);
-  }
-
-  bool get trustJSInteropTypeAnnotations =>
-      _compiler.options.trustJSInteropTypeAnnotations;
-
-  bool isNative(ClassElement element) => _backend.isNative(element);
-
-  bool isJsInterop(FunctionElement element) => _backend.isJsInterop(element);
-
-  bool isJsInteropAnonymous(FunctionElement element) =>
-      _backend.jsInteropAnalysis.hasAnonymousAnnotation(element.contextClass);
-
-  String getJsInteropTargetPath(FunctionElement element) {
-    return '${_backend.namer.fixedBackendPath(element)}.'
-        '${_backend.nativeData.getFixedBackendName(element)}';
-  }
-
-  DartType get jsJavascriptObjectType =>
-      _backend.helpers.jsJavaScriptObjectClass.thisType;
-}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
deleted file mode 100644
index cee7a1e..0000000
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
+++ /dev/null
@@ -1,276 +0,0 @@
-library dart2js.cps_ir_integrity;
-
-import 'cps_ir_nodes.dart';
-import 'cps_ir_nodes_sexpr.dart';
-import '../tracer.dart' as tracer;
-
-/// Dump S-expressions on error if the tracer is enabled.
-///
-/// Technically this has nothing to do with the tracer, but if you want one
-/// 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.
-///
-/// The following integrity checks are performed:
-///
-/// - References are in scope of their definitions.
-/// - Recursive Continuations and InvokeContinuations are marked as recursive.
-/// - InvokeContinuations have the same arity as their target.
-/// - Reference chains are valid doubly-linked lists.
-/// - Reference chains contain exactly the references that are in the IR.
-/// - Each definition object occurs only once in the IR (no redeclaring).
-/// - Each reference object occurs only once in the IR (no sharing).
-///
-class CheckCpsIntegrity extends TrampolineRecursiveVisitor {
-  FunctionDefinition topLevelNode;
-  final Map<Definition, ScopeType> inScope = <Definition, ScopeType>{};
-  final List<Definition> definitions = [];
-  String previousPass;
-
-  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;
-      }
-    }
-  }
-
-  void enterScope(Iterable<Definition> definitions) {
-    for (Definition def in definitions) {
-      inScope[def] = ScopeType.InScope;
-    }
-    pushAction(() {
-      for (Definition def in definitions) {
-        inScope[def] = ScopeType.NotInScope;
-      }
-    });
-  }
-
-  void enterContinuation(Continuation cont) {
-    inScope[cont] = ScopeType.InDefinition;
-    pushAction(() {
-      inScope[cont] = ScopeType.NotInScope;
-    });
-  }
-
-  void check(FunctionDefinition node, String previousPass) {
-    // [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.
-    definitions.forEach(checkReferenceChain);
-  }
-
-  @override
-  Expression traverseLetCont(LetCont node) {
-    node.continuations.forEach(handleDeclaration);
-    node.continuations.forEach(push);
-
-    // Put all continuations in scope when visiting the body.
-    enterScope(node.continuations);
-
-    return node.body;
-  }
-
-  @override
-  Expression traverseLetPrim(LetPrim node) {
-    handleDeclaration(node.primitive);
-
-    // Process references in the primitive.
-    visit(node.primitive);
-
-    // Put the primitive in scope when visiting the body.
-    enterScope([node.primitive]);
-
-    return node.body;
-  }
-
-  @override
-  Expression traverseLetMutable(LetMutable node) {
-    handleDeclaration(node.variable);
-    processReference(node.valueRef);
-
-    // Put the primitive in scope when visiting the body.
-    enterScope([node.variable]);
-
-    return node.body;
-  }
-
-  @override
-  Expression traverseContinuation(Continuation cont) {
-    if (cont.isReturnContinuation) {
-      error('Non-return continuation missing body', cont);
-    }
-    cont.parameters.forEach(handleDeclaration);
-    enterScope(cont.parameters);
-    // Put every continuation in scope at its own body. The isRecursive
-    // flag is checked explicitly using [insideContinuations].
-    enterScope([cont]);
-    enterContinuation(cont);
-    return cont.body;
-  }
-
-  @override
-  visitFunctionDefinition(FunctionDefinition node) {
-    if (node.interceptorParameter != null) {
-      handleDeclaration(node.interceptorParameter);
-      enterScope([node.interceptorParameter]);
-    }
-    if (node.receiverParameter != null) {
-      handleDeclaration(node.receiverParameter);
-      enterScope([node.receiverParameter]);
-    }
-    node.parameters.forEach(handleDeclaration);
-    enterScope(node.parameters);
-    handleDeclaration(node.returnContinuation);
-    enterScope([node.returnContinuation]);
-    if (!node.returnContinuation.isReturnContinuation) {
-      error('Return continuation with a body', node);
-    }
-    visit(node.body);
-  }
-
-  @override
-  processReference(Reference ref) {
-    Definition def = ref.definition;
-    if (inScope[def] == ScopeType.NotInScope) {
-      error('Referenced out of scope: $def', ref);
-    }
-    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;
-    if (node.isRecursive && inScope[target] == ScopeType.InScope) {
-      error('Non-recursive InvokeContinuation marked as recursive', node);
-    }
-    if (!node.isRecursive && inScope[target] == ScopeType.InDefinition) {
-      error('Recursive InvokeContinuation marked as non-recursive', node);
-    }
-    if (node.isRecursive && !target.isRecursive) {
-      error('Recursive Continuation was not marked as recursive', node);
-    }
-    if (node.argumentRefs.length != target.parameters.length) {
-      error('Arity mismatch in InvokeContinuation', node);
-    }
-  }
-
-  @override
-  processInvokeMethod(InvokeMethod node) {
-    if (node.callingConvention == CallingConvention.Intercepted) {
-      if (node.interceptorRef == null) {
-        error('No interceptor on intercepted call', node);
-      }
-    } else {
-      if (node.interceptorRef != null) {
-        error('Interceptor on call with ${node.callingConvention}', node);
-      }
-    }
-  }
-
-  void checkReferenceChain(Definition def) {
-    Reference previous = null;
-    for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
-      if (ref.previous != ref) {
-        // Reference was not seen during IR traversal, so it is orphaned.
-        error('Orphaned reference in reference chain for $def', def);
-      }
-      // Repair the .previous link that was used for marking.
-      ref.previous = previous;
-      previous = ref;
-    }
-  }
-
-  error(String message, node) {
-    String sexpr;
-    if (ENABLE_DUMP) {
-      try {
-        Decorator decorator = (n, String s) => n == node ? '**$s**' : s;
-        sexpr = new SExpressionStringifier(decorator).visit(topLevelNode);
-        sexpr = 'SExpr dump (offending node marked with **):\n\n$sexpr';
-      } catch (e) {
-        sexpr = '(Exception thrown by SExpressionStringifier: $e)';
-      }
-    } else {
-      sexpr = '(Set DUMP_IR flag to enable SExpr dump)';
-    }
-    throw 'CPS integrity violation\n'
-        'After \'$previousPass\' on ${topLevelNode.element}\n'
-        '$message\n\n'
-        '$sexpr\n';
-  }
-}
-
-/// Traverses the CPS term and checks that node.parent is correctly set
-/// for each visited node.
-class ParentChecker extends DeepRecursiveVisitor {
-  static void checkParents(Node node, CheckCpsIntegrity main) {
-    ParentChecker visitor = new ParentChecker._make(main);
-    visitor._worklist.add(node);
-    visitor.trampoline();
-  }
-
-  ParentChecker._make(this.main);
-
-  Node _parent;
-  final List<Node> _worklist = <Node>[];
-  final CheckCpsIntegrity main;
-
-  void trampoline() {
-    while (_worklist.isNotEmpty) {
-      _parent = _worklist.removeLast();
-      _parent.accept(this);
-    }
-  }
-
-  error(String message, node) => main.error(message, node);
-
-  @override
-  visit(Node node) {
-    _worklist.add(node);
-    if (node.parent != _parent) {
-      error('Parent pointer on $node is ${node.parent} but should be $_parent',
-          node);
-    }
-  }
-
-  @override
-  processReference(Reference node) {
-    if (node.parent != _parent) {
-      error('Parent pointer on $node is ${node.parent} but should be $_parent',
-          node);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
deleted file mode 100644
index 7ba13c8..0000000
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ /dev/null
@@ -1,3123 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library dart2js.ir_nodes;
-
-import 'dart:collection';
-import 'cps_fragment.dart' show CpsFragment;
-import 'cps_ir_nodes_sexpr.dart';
-import '../constants/values.dart' as values;
-import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
-import '../elements/elements.dart';
-import '../io/source_information.dart' show SourceInformation;
-import '../types/types.dart' show TypeMask;
-import '../universe/selector.dart' show Selector;
-
-import 'builtin_operator.dart';
-export 'builtin_operator.dart';
-
-import 'effects.dart';
-
-// 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, isNullGuardOnFirstArgument;
-import '../native/native.dart' as native show NativeBehavior;
-
-abstract class Node {
-  /// A pointer to the parent node. Is null until set by optimization passes.
-  Node parent;
-
-  /// Workaround for a slow Object.hashCode in the VM.
-  static int _usedHashCodes = 0;
-  final int hashCode = ++_usedHashCodes;
-
-  Node() {
-    setParentPointers();
-  }
-
-  accept(Visitor visitor);
-
-  /// Updates the [parent] of the immediate children to refer to this node.
-  ///
-  /// All constructors call this method to initialize parent pointers.
-  void setParentPointers();
-
-  /// Returns the SExpression for the subtree rooted at this node.
-  ///
-  /// [annotations] maps strings to nodes and/or nodes to values that will be
-  /// converted to strings. Each binding causes the annotation to appear on the
-  /// given node.
-  ///
-  /// For example, the following could be used to diagnose a problem with nodes
-  /// not appearing in an environment map:
-  ///
-  ///     if (environment[node] == null)
-  ///       root.debugPrint({
-  ///         'currentNode': node,
-  ///         'caller': someContinuation
-  ///       });
-  ///       throw 'Node was not in environment';
-  ///     }
-  ///
-  /// If two strings map to the same node, it will be given both annotations.
-  ///
-  /// Avoid using nodes as keys if there is a chance that two keys are the
-  /// same node.
-  String debugString([Map annotations = const {}]) {
-    return new SExpressionStringifier()
-        .withAnnotations(annotations)
-        .withTypes()
-        .visit(this);
-  }
-
-  /// Prints the result of [debugString].
-  void debugPrint([Map annotations = const {}]) {
-    print(debugString(annotations));
-  }
-}
-
-/// Expressions can be evaluated, and may diverge, throw, and/or have
-/// side-effects.
-///
-/// Evaluation continues by stepping into a sub-expression, invoking a
-/// continuation, or throwing an exception.
-///
-/// Expressions do not a return value. Expressions that produce values should
-/// invoke a [Continuation] with the result as argument. Alternatively, values
-/// that can be obtained without side-effects, divergence, or throwing
-/// exceptions can be built using a [LetPrim].
-///
-/// All subclasses implement exactly one of [CallExpression],
-/// [InteriorExpression], or [TailExpression].
-abstract class Expression extends Node {
-  InteriorNode get parent; // Only InteriorNodes may contain expressions.
-
-  Expression plug(Expression expr) => throw 'impossible';
-
-  /// The next expression in the basic block.
-  ///
-  /// 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
-/// `body` member. A typical usage is when removing a node from the CPS graph:
-///
-///     Node child          = node.body;
-///     InteriorNode parent = node.parent;
-///
-///     child.parent = parent;
-///     parent.body  = child;
-abstract class InteriorNode extends Node {
-  Expression get body;
-  void set body(Expression body);
-
-  accept(BlockVisitor visitor);
-}
-
-/// The base class of things that variables can refer to: primitives,
-/// continuations, function and continuation parameters, etc.
-abstract class Definition<T extends Definition<T>> extends Node {
-  // The head of a linked-list of occurrences, in no particular order.
-  Reference<T> firstRef;
-
-  bool get hasAtMostOneUse => firstRef == null || firstRef.next == null;
-  bool get hasExactlyOneUse => firstRef != null && firstRef.next == null;
-  bool get hasNoUses => firstRef == null;
-  bool get hasAtLeastOneUse => firstRef != null;
-  bool get hasMultipleUses => !hasAtMostOneUse;
-
-  void replaceUsesWith(Definition<T> newDefinition) {
-    if (newDefinition == this) return;
-    if (hasNoUses) return;
-    Reference<T> previous, current = firstRef;
-    do {
-      current.definition = newDefinition;
-      previous = current;
-      current = current.next;
-    } while (current != null);
-    previous.next = newDefinition.firstRef;
-    if (newDefinition.firstRef != null) {
-      newDefinition.firstRef.previous = previous;
-    }
-    newDefinition.firstRef = firstRef;
-    firstRef = null;
-  }
-}
-
-/// Operands to invocations and primitives are always variables.  They point to
-/// their definition and are doubly-linked into a list of occurrences.
-class Reference<T extends Definition<T>> {
-  T definition;
-  Reference<T> previous;
-  Reference<T> next;
-
-  /// A pointer to the parent node. Is null until set by optimization passes.
-  Node parent;
-
-  Reference(this.definition) {
-    next = definition.firstRef;
-    if (next != null) next.previous = this;
-    definition.firstRef = this;
-  }
-
-  /// Unlinks this reference from the list of occurrences.
-  void unlink() {
-    if (previous == null) {
-      assert(definition.firstRef == this);
-      definition.firstRef = next;
-    } else {
-      previous.next = next;
-    }
-    if (next != null) next.previous = previous;
-  }
-
-  /// Changes the definition referenced by this object and updates
-  /// the reference chains accordingly.
-  void changeTo(Definition<T> newDefinition) {
-    unlink();
-    previous = null;
-    definition = newDefinition;
-    next = definition.firstRef;
-    if (next != null) next.previous = this;
-    definition.firstRef = this;
-  }
-}
-
-class EffectiveUseIterator extends Iterator<Reference<Primitive>> {
-  Reference<Primitive> current;
-  Reference<Primitive> next;
-  final List<Refinement> stack = <Refinement>[];
-
-  EffectiveUseIterator(Primitive prim) : next = prim.firstRef;
-
-  bool moveNext() {
-    Reference<Primitive> ref = next;
-    while (true) {
-      if (ref == null) {
-        if (stack.isNotEmpty) {
-          ref = stack.removeLast().firstRef;
-        } else {
-          current = null;
-          return false;
-        }
-      } else if (ref.parent is Refinement) {
-        stack.add(ref.parent);
-        ref = ref.next;
-      } else {
-        current = ref;
-        next = current.next;
-        return true;
-      }
-    }
-  }
-}
-
-class RefinedUseIterable extends IterableBase<Reference<Primitive>> {
-  Primitive primitive;
-  RefinedUseIterable(this.primitive);
-  EffectiveUseIterator get iterator => new EffectiveUseIterator(primitive);
-}
-
-/// A named value.
-///
-/// The identity of the [Primitive] object is the name of the value.
-/// The subclass describes how to compute the value.
-///
-/// All primitives except [Parameter] must be bound by a [LetPrim].
-abstract class Primitive extends Variable<Primitive> {
-  Primitive() : super(null);
-
-  /// Returns a bitmask with the non-local side effects and dependencies of
-  /// this primitive, as defined by [Effects].
-  int get effects => Effects.none;
-
-  /// 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).
-  ///
-  /// False must be returned for primitives that may throw, diverge, or have
-  /// observable side-effects.
-  bool get isSafeForElimination;
-
-  /// True if time-of-evaluation is irrelevant for the given primitive,
-  /// assuming its inputs are the same values.
-  bool get isSafeForReordering;
-
-  /// The source information associated with this primitive.
-  // TODO(johnniwinther): Require source information for all primitives.
-  SourceInformation get sourceInformation => null;
-
-  /// If this is a [Refinement], [BoundsCheck] or [ReceiverCheck] 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;
-
-  /// Like [effectiveDefinition] but only unfolds [Refinement] nodes.
-  Primitive get unrefined => this;
-
-  /// True if the two primitives are (refinements of) the same value.
-  bool sameValue(Primitive other) {
-    return effectiveDefinition == other.effectiveDefinition;
-  }
-
-  /// Iterates all non-refinement uses of the primitive and all uses of
-  /// a [Refinement] of this primitive (transitively).
-  ///
-  /// Notes regarding concurrent modification:
-  /// - The current reference may safely be unlinked.
-  /// - Yet unvisited references may not be unlinked.
-  /// - References to this primitive created during iteration will not be seen.
-  /// - References to a refinement of this primitive may not be created during
-  ///   iteration.
-  RefinedUseIterable get refinedUses => new RefinedUseIterable(this);
-
-  bool get hasMultipleRefinedUses {
-    Iterator it = refinedUses.iterator;
-    return it.moveNext() && it.moveNext();
-  }
-
-  bool get hasNoRefinedUses {
-    return refinedUses.isEmpty;
-  }
-
-  /// Unlinks all references contained in this node.
-  void destroy() {
-    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();
-  }
-}
-
-/// Continuations are normally bound by 'let cont'.  A continuation with one
-/// parameter and no body is used to represent a function's return continuation.
-/// The return continuation is bound by the function, not by 'let cont'.
-class Continuation extends Definition<Continuation> implements InteriorNode {
-  final List<Parameter> parameters;
-  Expression body = null;
-
-  // A continuation is recursive if it has any recursive invocations.
-  bool isRecursive;
-
-  /// True if this is the return continuation.  The return continuation is bound
-  /// by [FunctionDefinition].
-  bool get isReturnContinuation => body == null;
-
-  /// True if this is a branch continuation.  Branch continuations are bound
-  /// by [LetCont] and can only have one use.
-  bool get isBranchContinuation => firstRef?.parent is Branch;
-
-  /// True if this is the exception handler bound by a [LetHandler].
-  bool get isHandlerContinuation => parent is LetHandler;
-
-  /// True if this is a non-return continuation that can be targeted by
-  /// [InvokeContinuation].
-  bool get isJoinContinuation {
-    return body != null &&
-        parent is! LetHandler &&
-        (firstRef == null || firstRef.parent is InvokeContinuation);
-  }
-
-  Continuation(this.parameters, {this.isRecursive: false});
-
-  Continuation.retrn()
-      : parameters = <Parameter>[new Parameter(null)],
-        isRecursive = false;
-
-  accept(BlockVisitor visitor) => visitor.visitContinuation(this);
-
-  void setParentPointers() {
-    _setParentsOnNodes(parameters, this);
-    if (body != null) body.parent = this;
-  }
-}
-
-/// Common interface for [Primitive] and [MutableVariable].
-abstract class Variable<T extends Variable<T>> extends Definition<T> {
-  /// Type of value held in the variable.
-  ///
-  /// 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> {
-  MutableVariable(Entity hint) : super(hint);
-
-  accept(Visitor v) => v.visitMutableVariable(this);
-
-  void setParentPointers() {}
-}
-
-/// A function definition, consisting of parameters and a body.
-///
-/// There is an explicit parameter for the `this` argument, and a return
-/// continuation to invoke when returning from the function.
-class FunctionDefinition extends InteriorNode {
-  final ExecutableElement element;
-  Parameter interceptorParameter;
-  final Parameter receiverParameter;
-  final List<Parameter> parameters;
-  final Continuation returnContinuation;
-  final SourceInformation sourceInformation;
-  Expression body;
-
-  FunctionDefinition(this.element, this.receiverParameter, this.parameters,
-      this.returnContinuation, this.body,
-      {this.interceptorParameter, this.sourceInformation});
-
-  accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this);
-
-  void setParentPointers() {
-    if (interceptorParameter != null) interceptorParameter.parent = this;
-    if (receiverParameter != null) receiverParameter.parent = this;
-    _setParentsOnNodes(parameters, this);
-    returnContinuation.parent = this;
-    if (body != null) body.parent = this;
-  }
-}
-
-// ----------------------------------------------------------------------------
-//                            PRIMITIVES
-// ----------------------------------------------------------------------------
-
-class Parameter extends Primitive {
-  Parameter(Entity hint) {
-    super.hint = hint;
-  }
-
-  accept(Visitor visitor) => visitor.visitParameter(this);
-
-  String toString() => 'Parameter(${hint == null ? null : hint.name})';
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {}
-}
-
-/// A primitive that is generally not safe for elimination, but may be marked
-/// as safe by type propagation
-abstract class UnsafePrimitive extends Primitive {
-  int effects = Effects.all;
-  bool isSafeForElimination = false;
-  bool isSafeForReordering = false;
-}
-
-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 interceptorRef => null;
-  Primitive get interceptor => interceptorRef?.definition;
-
-  Reference<Primitive> get receiverRef => null;
-  Primitive get receiver => receiverRef?.definition;
-
-  List<Reference<Primitive>> get argumentRefs;
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-
-  CallingConvention get callingConvention => CallingConvention.Normal;
-
-  SourceInformation get sourceInformation;
-}
-
-/// Invoke a static function.
-///
-/// All optional arguments declared by [target] are passed in explicitly, and
-/// occur at the end of [arguments] list, in normalized order.
-///
-/// Discussion:
-/// All information in the [selector] is technically redundant; it will likely
-/// be removed.
-class InvokeStatic extends InvocationPrimitive {
-  final FunctionElement target;
-  final Selector selector;
-  final List<Reference<Primitive>> argumentRefs;
-  final SourceInformation sourceInformation;
-
-  InvokeStatic(this.target, this.selector, List<Primitive> args,
-      [this.sourceInformation])
-      : argumentRefs = _referenceList(args);
-
-  InvokeStatic.byReference(this.target, this.selector, this.argumentRefs,
-      [this.sourceInformation]);
-
-  accept(Visitor visitor) => visitor.visitInvokeStatic(this);
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    _setParentsOnList(argumentRefs, this);
-  }
-}
-
-/// Invoke a method on an object.
-///
-/// This includes getters, setters, operators, and index getter/setters.
-///
-/// Tearing off a method is treated like a getter invocation (getters and
-/// tear-offs cannot be distinguished at compile-time).
-///
-/// 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 InvocationPrimitive {
-  Reference<Primitive> interceptorRef;
-  Reference<Primitive> receiverRef;
-  Selector selector;
-  TypeMask mask;
-  final List<Reference<Primitive>> argumentRefs;
-  final SourceInformation sourceInformation;
-  CallingConvention _callingConvention;
-
-  CallingConvention get callingConvention => _callingConvention;
-
-  InvokeMethod(
-      Primitive receiver, this.selector, this.mask, List<Primitive> arguments,
-      {this.sourceInformation,
-      CallingConvention callingConvention,
-      Primitive interceptor})
-      : this.receiverRef = new Reference<Primitive>(receiver),
-        this.argumentRefs = _referenceList(arguments),
-        this.interceptorRef = _optionalReference(interceptor),
-        this._callingConvention = callingConvention ??
-            (interceptor != null
-                ? CallingConvention.Intercepted
-                : CallingConvention.Normal);
-
-  accept(Visitor visitor) => visitor.visitInvokeMethod(this);
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    interceptorRef?.parent = this;
-    receiverRef.parent = this;
-    _setParentsOnList(argumentRefs, this);
-  }
-
-  void makeIntercepted(Primitive interceptor) {
-    interceptorRef?.unlink();
-    interceptorRef = new Reference<Primitive>(interceptor)..parent = this;
-    _callingConvention = CallingConvention.Intercepted;
-  }
-
-  void makeOneShotIntercepted() {
-    interceptorRef?.unlink();
-    interceptorRef = null;
-    _callingConvention = CallingConvention.OneShotIntercepted;
-  }
-
-  void makeDummyIntercepted() {
-    interceptorRef?.unlink();
-    interceptorRef = null;
-    _callingConvention = CallingConvention.DummyIntercepted;
-  }
-}
-
-/// Invoke [target] on [receiver], bypassing dispatch and override semantics.
-///
-/// That is, if [receiver] is an instance of a class that overrides [target]
-/// with a different implementation, the overriding implementation is bypassed
-/// and [target]'s implementation is invoked.
-///
-/// As with [InvokeMethod], this can be used to invoke a method, operator,
-/// getter, setter, or index getter/setter.
-///
-/// If it is known that [target] does not use its receiver argument, then
-/// [receiver] may refer to a null constant primitive. This happens for direct
-/// invocations to intercepted methods, where the effective receiver is instead
-/// passed as a formal parameter.
-///
-/// TODO(sra): Review. A direct call to a method that is mixed into a native
-/// class will still require an explicit argument.
-///
-/// All optional arguments declared by [target] are passed in explicitly, and
-/// occur at the end of [arguments] list, in normalized order.
-class InvokeMethodDirectly extends InvocationPrimitive {
-  Reference<Primitive> interceptorRef;
-  Reference<Primitive> receiverRef;
-  final FunctionElement target;
-  final Selector selector;
-  final List<Reference<Primitive>> argumentRefs;
-  final SourceInformation sourceInformation;
-
-  InvokeMethodDirectly(Primitive receiver, this.target, this.selector,
-      List<Primitive> arguments, this.sourceInformation,
-      {Primitive interceptor})
-      : this.receiverRef = new Reference<Primitive>(receiver),
-        this.argumentRefs = _referenceList(arguments),
-        this.interceptorRef = _optionalReference(interceptor);
-
-  accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this);
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    interceptorRef?.parent = this;
-    receiverRef.parent = this;
-    _setParentsOnList(argumentRefs, this);
-  }
-
-  bool get isConstructorBodyCall => target is ConstructorBodyElement;
-  bool get isTearOff => selector.isGetter && !target.isGetter;
-
-  void makeIntercepted(Primitive interceptor) {
-    interceptorRef?.unlink();
-    interceptorRef = new Reference<Primitive>(interceptor)..parent = this;
-  }
-}
-
-/// Non-const call to a constructor.
-///
-/// The [target] may be a generative constructor (forwarding or normal)
-/// or a non-redirecting factory.
-///
-/// All optional arguments declared by [target] are passed in explicitly, and
-/// occur in the [arguments] list, in normalized order.
-///
-/// Last in the [arguments] list, after the mandatory and optional arguments,
-/// the internal representation of each type argument occurs, unless it could
-/// be determined at build-time that the constructed class has no need for its
-/// runtime type information.
-///
-/// Note that [InvokeConstructor] does it itself allocate an object.
-/// The invoked constructor will do that using [CreateInstance].
-class InvokeConstructor extends InvocationPrimitive {
-  final DartType dartType;
-  final ConstructorElement target;
-  final List<Reference<Primitive>> argumentRefs;
-  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, this.sourceInformation,
-      {this.allocationSiteType})
-      : argumentRefs = _referenceList(args);
-
-  accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    _setParentsOnList(argumentRefs, this);
-  }
-}
-
-/// An alias for [value] in a context where the value is known to satisfy
-/// [type].
-///
-/// Refinement nodes are inserted before the type propagator pass and removed
-/// afterwards, so as not to complicate passes that don't reason about types,
-/// but need to reason about value references being identical (i.e. referring
-/// to the same primitive).
-class Refinement extends Primitive {
-  Reference<Primitive> value;
-  final TypeMask refineType;
-
-  Refinement(Primitive value, this.refineType)
-      : value = new Reference<Primitive>(value);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => false;
-  bool get isSafeForReordering => false;
-
-  accept(Visitor visitor) => visitor.visitRefinement(this);
-
-  Primitive get effectiveDefinition => value.definition.effectiveDefinition;
-
-  Primitive get unrefined => value.definition.unrefined;
-
-  void setParentPointers() {
-    value.parent = this;
-  }
-}
-
-/// Checks that [index] is a valid index on a given indexable [object].
-///
-/// In the simplest form, compiles to the following:
-///
-///     if (index < 0 || index >= object.length)
-///         ThrowIndexOutOfRangeException(object, index);
-///
-/// In the general form, any of the following conditions can be checked:
-///
-///  Lower bound: `index >= 0`
-///  Upper bound: `index < object.length`
-///  Emptiness:   `object.length !== 0`
-///  Integerness: `index >>> 0 === index`
-///
-/// [index] must be an integer unless integerness is checked, 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> objectRef;
-  Reference<Primitive> indexRef;
-  Reference<Primitive> lengthRef;
-  int checks;
-  final SourceInformation sourceInformation;
-
-  Primitive get object => objectRef.definition;
-  Primitive get index => indexRef?.definition;
-  Primitive get length => lengthRef?.definition;
-
-  /// 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;
-
-  /// If true, check that `index` is an integer.
-  bool get hasIntegerCheck => checks & INTEGER != 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 INTEGER = 1 << 3; // Check if index is an int.
-  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.objectRef = new Reference<Primitive>(object),
-        this.indexRef = new Reference<Primitive>(index),
-        this.lengthRef = _optionalReference(length);
-
-  BoundsCheck.noCheck(Primitive object, [this.sourceInformation])
-      : this.objectRef = new Reference<Primitive>(object),
-        this.checks = NONE;
-
-  accept(Visitor visitor) => visitor.visitBoundsCheck(this);
-
-  void setParentPointers() {
-    objectRef.parent = this;
-    if (indexRef != null) {
-      indexRef.parent = this;
-    }
-    if (lengthRef != null) {
-      lengthRef.parent = this;
-    }
-  }
-
-  String get checkString {
-    if (hasNoChecks) return 'no-check';
-    return [
-      hasUpperBoundCheck ? 'upper' : null,
-      hasLowerBoundCheck ? 'lower' : null,
-      hasEmptinessCheck ? 'emptiness' : null,
-      hasIntegerCheck ? 'integer' : null,
-      'check'
-    ].where((x) => x != null).join('-');
-  }
-
-  bool get isSafeForElimination => checks == NONE;
-  bool get isSafeForReordering => false;
-  bool get hasValue => true; // Can be referenced to restrict code motion.
-
-  Primitive get effectiveDefinition => object.effectiveDefinition;
-}
-
-/// Throw a [NoSuchMethodError] if [value] cannot respond to [selector].
-///
-/// Returns [value] so this can be used to restrict code motion.
-///
-/// The check can take one of three forms:
-///
-///     value.toString;
-///     value.selectorName;
-///     value.selectorName();    (should only be used if check always fails)
-///
-/// The first two forms are used when it is known that only null fails the
-/// check.  Additionally, the check may be guarded by a [condition], allowing
-/// for three more forms:
-///
-///     if (condition) value.toString;          (this form is valid but unused)
-///     if (condition) value.selectorName;
-///     if (condition) value.selectorName();
-///
-/// The condition must be true if and only if the check should fail. It should
-/// ideally be of a form understood by JS engines, e.g. a `typeof` test.
-///
-/// If [useSelector] is false, the first form instead becomes `value.toString;`.
-/// This form is faster when the value is non-null and the accessed property has
-/// been removed by tree shaking.
-///
-/// [selector] may not be one of the selectors implemented by the null object.
-class ReceiverCheck extends Primitive {
-  final Reference<Primitive> valueRef;
-  final Selector selector;
-  final SourceInformation sourceInformation;
-  final Reference<Primitive> conditionRef;
-  final int _flags;
-
-  Primitive get value => valueRef.definition;
-  Primitive get condition => conditionRef?.definition;
-
-  static const int _USE_SELECTOR = 1 << 0;
-  static const int _NULL_CHECK = 1 << 1;
-
-  /// True if the selector name should be used in the check; otherwise
-  /// `toString` will be used.
-  bool get useSelector => _flags & _USE_SELECTOR != 0;
-
-  /// True if null is the only possible input that cannot respond to [selector].
-  bool get isNullCheck => _flags & _NULL_CHECK != 0;
-
-  /// Constructor for creating checks in arbitrary configurations.
-  ///
-  /// Consider using one of the named constructors instead.
-  ///
-  /// [useSelector] and [isNullCheck] are mandatory named arguments.
-  ReceiverCheck(Primitive value, this.selector, this.sourceInformation,
-      {Primitive condition, bool useSelector, bool isNullCheck})
-      : valueRef = new Reference<Primitive>(value),
-        conditionRef = _optionalReference(condition),
-        _flags =
-            (useSelector ? _USE_SELECTOR : 0) | (isNullCheck ? _NULL_CHECK : 0);
-
-  /// Simplified constructor for building null checks.
-  ///
-  /// Null must be the only possible input value that does not respond to
-  /// [selector].
-  ReceiverCheck.nullCheck(
-      Primitive value, Selector selector, SourceInformation sourceInformation,
-      {Primitive condition})
-      : this(value, selector, sourceInformation,
-            condition: condition,
-            useSelector: condition != null,
-            isNullCheck: true);
-
-  /// Simplified constructor for building the general check of form:
-  ///
-  ///     if (condition) value.selectorName();
-  ///
-  ReceiverCheck.generalCheck(Primitive value, Selector selector,
-      SourceInformation sourceInformation, Primitive condition)
-      : this(value, selector, sourceInformation,
-            condition: condition, useSelector: true, isNullCheck: false);
-
-  bool get isSafeForElimination => false;
-  bool get isSafeForReordering => false;
-  bool get hasValue => true;
-
-  accept(Visitor visitor) => visitor.visitReceiverCheck(this);
-
-  void setParentPointers() {
-    valueRef.parent = this;
-    if (conditionRef != null) {
-      conditionRef.parent = this;
-    }
-  }
-
-  Primitive get effectiveDefinition => value.effectiveDefinition;
-
-  String get nullCheckString => isNullCheck ? 'null-check' : 'general-check';
-  String get useSelectorString => useSelector ? 'use-selector' : 'no-selector';
-  String get flagString => '$nullCheckString $useSelectorString';
-}
-
-/// An "is" type test.
-///
-/// 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
-/// to simplify code generation for type tests.
-class TypeTest extends Primitive {
-  Reference<Primitive> valueRef;
-  final DartType dartType;
-
-  /// If [dartType] is an [InterfaceType], this holds the internal
-  /// representation of the type arguments to [dartType]. Since these may
-  /// reference type variables from the enclosing class, they are not constant.
-  ///
-  /// If [dartType] is a [TypeVariableType], this is a singleton list with the
-  /// internal representation of the type held in that type variable.
-  ///
-  /// If [dartType] is a [FunctionType], this is a singleton list with the
-  /// internal representation of that type,
-  ///
-  /// Otherwise the list is empty.
-  final List<Reference<Primitive>> typeArgumentRefs;
-
-  Primitive get value => valueRef.definition;
-  Primitive typeArgument(int n) => typeArgumentRefs[n].definition;
-  Iterable<Primitive> get typeArguments => _dereferenceList(typeArgumentRefs);
-
-  TypeTest(Primitive value, this.dartType, List<Primitive> typeArguments)
-      : this.valueRef = new Reference<Primitive>(value),
-        this.typeArgumentRefs = _referenceList(typeArguments);
-
-  accept(Visitor visitor) => visitor.visitTypeTest(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    valueRef.parent = this;
-    _setParentsOnList(typeArgumentRefs, this);
-  }
-}
-
-/// An "is" type test for a raw type, performed by testing a flag property.
-///
-/// Returns `true` if [interceptor] is for [dartType].
-class TypeTestViaFlag extends Primitive {
-  Reference<Primitive> interceptorRef;
-  final DartType dartType;
-
-  Primitive get interceptor => interceptorRef.definition;
-
-  TypeTestViaFlag(Primitive interceptor, this.dartType)
-      : this.interceptorRef = new Reference<Primitive>(interceptor);
-
-  accept(Visitor visitor) => visitor.visitTypeTestViaFlag(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    interceptorRef.parent = this;
-  }
-}
-
-/// An "as" type cast.
-///
-/// If [value] is `null` or is an instance of [type], [continuation] is invoked
-/// with [value] as argument. Otherwise, a [CastError] is thrown.
-///
-/// Discussion:
-/// The parameter to [continuation] is redundant since it will always equal
-/// [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 UnsafePrimitive {
-  Reference<Primitive> valueRef;
-  final DartType dartType;
-
-  /// See the corresponding field on [TypeTest].
-  final List<Reference<Primitive>> typeArgumentRefs;
-
-  Primitive get value => valueRef.definition;
-  Primitive typeArgument(int n) => typeArgumentRefs[n].definition;
-  Iterable<Primitive> get typeArguments => _dereferenceList(typeArgumentRefs);
-
-  TypeCast(Primitive value, this.dartType, List<Primitive> typeArguments)
-      : this.valueRef = new Reference<Primitive>(value),
-        this.typeArgumentRefs = _referenceList(typeArguments);
-
-  accept(Visitor visitor) => visitor.visitTypeCast(this);
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    valueRef.parent = this;
-    _setParentsOnList(typeArgumentRefs, this);
-  }
-}
-
-/// Apply a built-in operator.
-///
-/// It must be known that the arguments have the proper types.
-class ApplyBuiltinOperator extends Primitive {
-  BuiltinOperator operator;
-  List<Reference<Primitive>> argumentRefs;
-  final SourceInformation sourceInformation;
-
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-
-  ApplyBuiltinOperator(
-      this.operator, List<Primitive> arguments, this.sourceInformation)
-      : this.argumentRefs = _referenceList(arguments);
-
-  accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    _setParentsOnList(argumentRefs, this);
-  }
-}
-
-/// Apply a built-in method.
-///
-/// It must be known that the arguments have the proper types.
-class ApplyBuiltinMethod extends Primitive {
-  BuiltinMethod method;
-  Reference<Primitive> receiverRef;
-  List<Reference<Primitive>> argumentRefs;
-  final SourceInformation sourceInformation;
-
-  Primitive get receiver => receiverRef.definition;
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-
-  ApplyBuiltinMethod(this.method, Primitive receiver, List<Primitive> arguments,
-      this.sourceInformation)
-      : this.receiverRef = new Reference<Primitive>(receiver),
-        this.argumentRefs = _referenceList(arguments);
-
-  accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => false;
-  bool get isSafeForReordering => false;
-
-  void setParentPointers() {
-    receiverRef.parent = this;
-    _setParentsOnList(argumentRefs, this);
-  }
-
-  int get effects => getEffectsOfBuiltinMethod(method);
-}
-
-/// Gets the value from a [MutableVariable].
-///
-/// [MutableVariable]s can be seen as ref cells that are not first-class
-/// values.  A [LetPrim] with a [GetMutable] can then be seen as:
-///
-///   let prim p = ![variable] in [body]
-///
-class GetMutable extends Primitive {
-  final Reference<MutableVariable> variableRef;
-  final SourceInformation sourceInformation;
-
-  MutableVariable get variable => variableRef.definition;
-
-  GetMutable(MutableVariable variable, {this.sourceInformation})
-      : this.variableRef = new Reference<MutableVariable>(variable);
-
-  accept(Visitor visitor) => visitor.visitGetMutable(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => false;
-
-  void setParentPointers() {
-    variableRef.parent = this;
-  }
-}
-
-/// Assign a [MutableVariable].
-///
-/// [MutableVariable]s can be seen as ref cells that are not first-class
-/// values.  This can be seen as a dereferencing assignment:
-///
-///   { [variable] := [value]; [body] }
-class SetMutable extends Primitive {
-  final Reference<MutableVariable> variableRef;
-  final Reference<Primitive> valueRef;
-  final SourceInformation sourceInformation;
-
-  MutableVariable get variable => variableRef.definition;
-  Primitive get value => valueRef.definition;
-
-  SetMutable(MutableVariable variable, Primitive value,
-      {this.sourceInformation})
-      : this.variableRef = new Reference<MutableVariable>(variable),
-        this.valueRef = new Reference<Primitive>(value);
-
-  accept(Visitor visitor) => visitor.visitSetMutable(this);
-
-  bool get hasValue => false;
-  bool get isSafeForElimination => false;
-  bool get isSafeForReordering => false;
-
-  void setParentPointers() {
-    variableRef.parent = this;
-    valueRef.parent = this;
-  }
-}
-
-/// Directly reads from a field on a given object.
-///
-/// The [object] must either be `null` or an object that has [field].
-class GetField extends Primitive {
-  final Reference<Primitive> objectRef;
-  FieldElement field;
-  final SourceInformation sourceInformation;
-
-  /// True if the field never changes value.
-  final bool isFinal;
-
-  /// True if the object is known not to be null.
-  // TODO(asgerf): This is a placeholder until we agree on how to track
-  //               side effects.
-  bool objectIsNotNull = false;
-
-  Primitive get object => objectRef.definition;
-
-  GetField(Primitive object, this.field,
-      {this.sourceInformation, this.isFinal: false})
-      : this.objectRef = new Reference<Primitive>(object);
-
-  accept(Visitor visitor) => visitor.visitGetField(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => objectIsNotNull;
-  bool get isSafeForReordering => false;
-
-  toString() => 'GetField($field)';
-
-  void setParentPointers() {
-    objectRef.parent = this;
-  }
-
-  int get effects => isFinal ? 0 : Effects.dependsOnInstanceField;
-}
-
-/// Directly assigns to a field on a given object.
-class SetField extends Primitive {
-  final Reference<Primitive> objectRef;
-  FieldElement field;
-  final Reference<Primitive> valueRef;
-  final SourceInformation sourceInformation;
-
-  Primitive get object => objectRef.definition;
-  Primitive get value => valueRef.definition;
-
-  SetField(Primitive object, this.field, Primitive value,
-      {this.sourceInformation})
-      : this.objectRef = new Reference<Primitive>(object),
-        this.valueRef = new Reference<Primitive>(value);
-
-  accept(Visitor visitor) => visitor.visitSetField(this);
-
-  bool get hasValue => false;
-  bool get isSafeForElimination => false;
-  bool get isSafeForReordering => false;
-
-  void setParentPointers() {
-    objectRef.parent = this;
-    valueRef.parent = this;
-  }
-
-  int get effects => Effects.changesInstanceField;
-}
-
-/// Get the length of a string or native list.
-class GetLength extends Primitive {
-  final Reference<Primitive> objectRef;
-
-  /// True if the length of the given object can never change.
-  bool isFinal;
-
-  /// True if the object is known not to be null.
-  bool objectIsNotNull = false;
-
-  Primitive get object => objectRef.definition;
-
-  GetLength(Primitive object, {this.isFinal: false})
-      : this.objectRef = new Reference<Primitive>(object);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => objectIsNotNull;
-  bool get isSafeForReordering => false;
-
-  accept(Visitor v) => v.visitGetLength(this);
-
-  void setParentPointers() {
-    objectRef.parent = this;
-  }
-
-  int get effects => isFinal ? 0 : Effects.dependsOnIndexableLength;
-}
-
-/// Read an entry from an indexable object.
-///
-/// [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> objectRef;
-  final Reference<Primitive> indexRef;
-
-  /// True if the object is known not to be null.
-  bool objectIsNotNull = false;
-
-  Primitive get object => objectRef.definition;
-  Primitive get index => indexRef.definition;
-
-  GetIndex(Primitive object, Primitive index)
-      : this.objectRef = new Reference<Primitive>(object),
-        this.indexRef = new Reference<Primitive>(index);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => objectIsNotNull;
-  bool get isSafeForReordering => false;
-
-  accept(Visitor v) => v.visitGetIndex(this);
-
-  void setParentPointers() {
-    objectRef.parent = this;
-    indexRef.parent = this;
-  }
-
-  int get effects => Effects.dependsOnIndexableContent;
-}
-
-/// Set an entry on a native list.
-///
-/// [object] must be null or a native list, and [index] must be an integer
-/// within the bounds of the indexable object.
-///
-/// [SetIndex] may not be used to alter the length of a JS array.
-///
-/// The primitive itself has no value and may not be referenced.
-class SetIndex extends Primitive {
-  final Reference<Primitive> objectRef;
-  final Reference<Primitive> indexRef;
-  final Reference<Primitive> valueRef;
-
-  Primitive get object => objectRef.definition;
-  Primitive get index => indexRef.definition;
-  Primitive get value => valueRef.definition;
-
-  SetIndex(Primitive object, Primitive index, Primitive value)
-      : this.objectRef = new Reference<Primitive>(object),
-        this.indexRef = new Reference<Primitive>(index),
-        this.valueRef = new Reference<Primitive>(value);
-
-  bool get hasValue => false;
-  bool get isSafeForElimination => false;
-  bool get isSafeForReordering => false;
-
-  accept(Visitor v) => v.visitSetIndex(this);
-
-  void setParentPointers() {
-    objectRef.parent = this;
-    indexRef.parent = this;
-    valueRef.parent = this;
-  }
-
-  int get effects => Effects.changesIndexableContent;
-}
-
-/// Reads the value of a static field or tears off a static method.
-///
-/// 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;
-
-  /// True if the field never changes value.
-  final bool isFinal;
-
-  /// 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> witnessRef;
-
-  Primitive get witness => witnessRef.definition;
-
-  GetStatic(this.element, {this.isFinal: false, 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})
-      : witnessRef = _optionalReference(witness),
-        isFinal = false;
-
-  accept(Visitor visitor) => visitor.visitGetStatic(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => isFinal;
-
-  void setParentPointers() {
-    if (witnessRef != null) {
-      witnessRef.parent = this;
-    }
-  }
-
-  int get effects => isFinal ? 0 : Effects.dependsOnStaticField;
-}
-
-/// Sets the value of a static field.
-class SetStatic extends Primitive {
-  final FieldElement element;
-  final Reference<Primitive> valueRef;
-  final SourceInformation sourceInformation;
-
-  Primitive get value => valueRef.definition;
-
-  SetStatic(this.element, Primitive value, [this.sourceInformation])
-      : this.valueRef = new Reference<Primitive>(value);
-
-  accept(Visitor visitor) => visitor.visitSetStatic(this);
-
-  bool get hasValue => false;
-  bool get isSafeForElimination => false;
-  bool get isSafeForReordering => false;
-
-  void setParentPointers() {
-    valueRef.parent = this;
-  }
-
-  int get effects => Effects.changesStaticField;
-}
-
-/// Reads the value of a lazily initialized static field.
-///
-/// If the field has not yet been initialized, its initializer is evaluated
-/// and assigned to the field.
-class GetLazyStatic extends UnsafePrimitive {
-  final FieldElement element;
-  final SourceInformation sourceInformation;
-
-  /// True if the field never changes value.
-  final bool isFinal;
-
-  GetLazyStatic(this.element, {this.isFinal: false, this.sourceInformation});
-
-  accept(Visitor visitor) => visitor.visitGetLazyStatic(this);
-
-  bool get hasValue => true;
-
-  void setParentPointers() {}
-
-  // TODO(asgerf): Track side effects of lazy field initializers.
-  int get effects => Effects.all;
-}
-
-/// 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;
-
-  void setParentPointers() {}
-}
-
-/// Creates an instance of a class and initializes its fields and runtime type
-/// information.
-class CreateInstance extends Primitive {
-  final ClassElement classElement;
-
-  /// Initial values for the fields on the class.
-  /// The order corresponds to the order of fields on the class.
-  final List<Reference<Primitive>> argumentRefs;
-
-  /// The runtime type information structure which contains the type arguments.
-  ///
-  /// May be `null` to indicate that no type information is needed because the
-  /// compiler determined that the type information for instances of this class
-  /// is not needed at runtime.
-  Reference<Primitive> typeInformationRef;
-
-  final SourceInformation sourceInformation;
-
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-  Primitive get typeInformation => typeInformationRef?.definition;
-
-  CreateInstance(this.classElement, List<Primitive> arguments,
-      Primitive typeInformation, this.sourceInformation)
-      : this.argumentRefs = _referenceList(arguments),
-        this.typeInformationRef = _optionalReference(typeInformation);
-
-  accept(Visitor visitor) => visitor.visitCreateInstance(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  toString() => 'CreateInstance($classElement)';
-
-  void setParentPointers() {
-    _setParentsOnList(argumentRefs, this);
-    if (typeInformationRef != null) typeInformationRef.parent = this;
-  }
-}
-
-/// 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> inputRef;
-  final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
-  final SourceInformation sourceInformation;
-
-  Primitive get input => inputRef.definition;
-
-  Interceptor(Primitive input, this.sourceInformation)
-      : this.inputRef = new Reference<Primitive>(input);
-
-  accept(Visitor visitor) => visitor.visitInterceptor(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    inputRef.parent = this;
-  }
-}
-
-/// Create an instance of [Invocation] for use in a call to `noSuchMethod`.
-class CreateInvocationMirror extends Primitive {
-  final Selector selector;
-  final List<Reference<Primitive>> argumentRefs;
-
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-
-  CreateInvocationMirror(this.selector, List<Primitive> arguments)
-      : this.argumentRefs = _referenceList(arguments);
-
-  accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    _setParentsOnList(argumentRefs, this);
-  }
-}
-
-class ForeignCode extends UnsafePrimitive {
-  final js.Template codeTemplate;
-  final TypeMask storedType;
-  final List<Reference<Primitive>> argumentRefs;
-  final native.NativeBehavior nativeBehavior;
-  final SourceInformation sourceInformation;
-  final FunctionElement dependency;
-
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-
-  ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments,
-      this.nativeBehavior, this.sourceInformation,
-      {this.dependency})
-      : this.argumentRefs = _referenceList(arguments) {
-    effects = Effects.from(nativeBehavior.sideEffects);
-  }
-
-  accept(Visitor visitor) => visitor.visitForeignCode(this);
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    _setParentsOnList(argumentRefs, this);
-  }
-
-  bool isNullGuardOnNullFirstArgument() {
-    if (argumentRefs.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);
-  }
-}
-
-class Constant extends Primitive {
-  final values.ConstantValue value;
-  final SourceInformation sourceInformation;
-
-  Constant(this.value, {this.sourceInformation}) {
-    assert(value != null);
-  }
-
-  accept(Visitor visitor) => visitor.visitConstant(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {}
-}
-
-class LiteralList extends Primitive {
-  /// The List type being created; this is not the type argument.
-  final InterfaceType dartType;
-  final List<Reference<Primitive>> valueRefs;
-
-  /// If non-null, this is an allocation site-specific type for the list
-  /// created here.
-  TypeMask allocationSiteType;
-
-  Primitive value(int n) => valueRefs[n].definition;
-  Iterable<Primitive> get values => _dereferenceList(valueRefs);
-
-  LiteralList(this.dartType, List<Primitive> values, {this.allocationSiteType})
-      : this.valueRefs = _referenceList(values);
-
-  accept(Visitor visitor) => visitor.visitLiteralList(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    _setParentsOnList(valueRefs, this);
-  }
-}
-
-/// Converts the internal representation of a type to a Dart object of type
-/// [Type].
-class ReifyRuntimeType extends Primitive {
-  /// Reference to the internal representation of a type (as produced, for
-  /// example, by [ReadTypeVariable]).
-  final Reference<Primitive> valueRef;
-
-  final SourceInformation sourceInformation;
-
-  Primitive get value => valueRef.definition;
-
-  ReifyRuntimeType(Primitive value, this.sourceInformation)
-      : this.valueRef = new Reference<Primitive>(value);
-
-  @override
-  accept(Visitor visitor) => visitor.visitReifyRuntimeType(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    valueRef.parent = this;
-  }
-}
-
-/// Read the value the type variable [variable] from the target object.
-///
-/// The resulting value is an internal representation (and not neccessarily a
-/// Dart object), and must be reified by [ReifyRuntimeType], if it should be
-/// used as a Dart value.
-class ReadTypeVariable extends Primitive {
-  final TypeVariableType variable;
-  final Reference<Primitive> targetRef;
-  final SourceInformation sourceInformation;
-
-  Primitive get target => targetRef.definition;
-
-  ReadTypeVariable(this.variable, Primitive target, this.sourceInformation)
-      : this.targetRef = new Reference<Primitive>(target);
-
-  @override
-  accept(Visitor visitor) => visitor.visitReadTypeVariable(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    targetRef.parent = this;
-  }
-}
-
-enum TypeExpressionKind { COMPLETE, INSTANCE }
-
-/// Constructs a representation of a closed or ground-term type (that is, a type
-/// without type variables).
-///
-/// There are two forms:
-///
-/// - COMPLETE: A complete form that is self contained, used for the values of
-///   type parameters and non-raw is-checks.
-///
-/// - INSTANCE: A headless flat form for representing the sequence of values of
-///   the type parameters of an instance of a generic type.
-///
-/// The COMPLETE form value is constructed from [dartType] by replacing the type
-/// variables with consecutive values from [arguments], in the order generated
-/// by [DartType.forEachTypeVariable].  The type variables in [dartType] are
-/// treated as 'holes' in the term, which means that it must be ensured at
-/// construction, that duplicate occurences of a type variable in [dartType]
-/// are assigned the same value.
-///
-/// The INSTANCE form is constructed as a list of [arguments]. This is the same
-/// as the COMPLETE form for the 'thisType', except the root term's type is
-/// missing; this is implicit as the raw type of instance.  The [dartType] of
-/// the INSTANCE form must be the thisType of some class.
-///
-/// While we would like to remove the constrains on the INSTANCE form, we can
-/// get by with a tree of TypeExpressions.  Consider:
-///
-///     class Foo<T> {
-///       ... new Set<List<T>>()
-///     }
-///     class Set<E1> {
-///       factory Set() => new _LinkedHashSet<E1>();
-///     }
-///     class List<E2> { ... }
-///     class _LinkedHashSet<E3> { ... }
-///
-/// After inlining the factory constructor for `Set<E1>`, the CreateInstance
-/// should have type `_LinkedHashSet<List<T>>` and the TypeExpression should be
-/// a tree:
-///
-///    CreateInstance(dartType: _LinkedHashSet<List<T>>,
-///        [], // No arguments
-///        TypeExpression(INSTANCE,
-///            dartType: _LinkedHashSet<E3>, // _LinkedHashSet's thisType
-///            TypeExpression(COMPLETE,  // E3 = List<T>
-///                dartType: List<E2>,
-///                ReadTypeVariable(this, T)))) // E2 = T
-//
-// TODO(sra): The INSTANCE form requires the actual instance for full
-// interpretation. I want to move to a representation where the INSTANCE form is
-// also a complete form (possibly the same).
-class TypeExpression extends Primitive {
-  final TypeExpressionKind kind;
-  final DartType dartType;
-  final List<Reference<Primitive>> argumentRefs;
-
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-
-  TypeExpression(this.kind, this.dartType, List<Primitive> arguments)
-      : this.argumentRefs = _referenceList(arguments) {
-    assert(kind == TypeExpressionKind.INSTANCE
-        ? dartType == (dartType.element as ClassElement).thisType
-        : true);
-  }
-
-  @override
-  accept(Visitor visitor) {
-    return visitor.visitTypeExpression(this);
-  }
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    _setParentsOnList(argumentRefs, this);
-  }
-
-  String get kindAsString {
-    switch (kind) {
-      case TypeExpressionKind.COMPLETE:
-        return 'COMPLETE';
-      case TypeExpressionKind.INSTANCE:
-        return 'INSTANCE';
-    }
-  }
-}
-
-class Await extends UnsafePrimitive {
-  final Reference<Primitive> inputRef;
-
-  Primitive get input => inputRef.definition;
-
-  Await(Primitive input) : this.inputRef = new Reference<Primitive>(input);
-
-  @override
-  accept(Visitor visitor) {
-    return visitor.visitAwait(this);
-  }
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    inputRef.parent = this;
-  }
-}
-
-class Yield extends UnsafePrimitive {
-  final Reference<Primitive> inputRef;
-  final bool hasStar;
-
-  Primitive get input => inputRef.definition;
-
-  Yield(Primitive input, this.hasStar)
-      : this.inputRef = new Reference<Primitive>(input);
-
-  @override
-  accept(Visitor visitor) {
-    return visitor.visitYield(this);
-  }
-
-  bool get hasValue => true;
-
-  void setParentPointers() {
-    inputRef.parent = this;
-  }
-}
-
-// ---------------------------------------------------------------------------
-//                            EXPRESSIONS
-// ---------------------------------------------------------------------------
-
-/// An expression that creates new bindings and continues evaluation in
-/// a subexpression.
-///
-/// The interior expressions are [LetPrim], [LetCont], [LetHandler], and
-/// [LetMutable].
-abstract class InteriorExpression extends Expression implements InteriorNode {
-  Expression get next => body;
-
-  /// Removes this expression from its current position in the IR.
-  ///
-  /// The node can be re-inserted elsewhere or remain orphaned.
-  ///
-  /// If orphaned, the caller is responsible for unlinking all references in
-  /// the orphaned node. Use [Reference.unlink] or [Primitive.destroy] for this.
-  void remove() {
-    assert(parent != null);
-    assert(parent.body == this);
-    assert(body.parent == this);
-    parent.body = body;
-    body.parent = parent;
-    parent = null;
-    body = null;
-  }
-
-  /// Inserts this above [node].
-  ///
-  /// This node must be orphaned first.
-  void insertAbove(Expression node) {
-    insertBelow(node.parent);
-  }
-
-  /// Inserts this below [node].
-  ///
-  /// This node must be orphaned first.
-  void insertBelow(InteriorNode newParent) {
-    assert(parent == null);
-    assert(body == null);
-    Expression child = newParent.body;
-    newParent.body = this;
-    this.body = child;
-    child.parent = this;
-    this.parent = newParent;
-  }
-}
-
-/// An expression without a continuation or a subexpression body.
-///
-/// These break straight-line control flow and can be thought of as ending a
-/// basic block.
-abstract class TailExpression extends Expression {
-  Expression get next => null;
-}
-
-/// Evaluates a primitive and binds it to variable: `let val x = V in E`.
-///
-/// The bound value is in scope in the body.
-///
-/// During one-pass construction a LetPrim with an empty body is used to
-/// represent the one-hole context `let val x = V in []`.
-class LetPrim extends InteriorExpression {
-  Primitive primitive;
-  Expression body;
-
-  LetPrim(this.primitive, [this.body = null]);
-
-  Expression plug(Expression expr) {
-    assert(body == null);
-    return body = expr;
-  }
-
-  accept(BlockVisitor visitor) => visitor.visitLetPrim(this);
-
-  void setParentPointers() {
-    primitive.parent = this;
-    if (body != null) body.parent = this;
-  }
-}
-
-/// Binding continuations.
-///
-/// let cont k0(v0 ...) = E0
-///          k1(v1 ...) = E1
-///          ...
-///   in E
-///
-/// The bound continuations are in scope in the body and the continuation
-/// parameters are in scope in the respective continuation bodies.
-///
-/// During one-pass construction a LetCont whose first continuation has an empty
-/// body is used to represent the one-hole context
-/// `let cont ... k(v) = [] ... in E`.
-class LetCont extends InteriorExpression {
-  List<Continuation> continuations;
-  Expression body;
-
-  LetCont(Continuation continuation, this.body)
-      : continuations = <Continuation>[continuation];
-
-  LetCont.two(Continuation first, Continuation second, this.body)
-      : continuations = <Continuation>[first, second];
-
-  LetCont.many(this.continuations, this.body);
-
-  Expression plug(Expression expr) {
-    assert(continuations != null &&
-        continuations.isNotEmpty &&
-        continuations.first.body == null);
-    return continuations.first.body = expr;
-  }
-
-  accept(BlockVisitor visitor) => visitor.visitLetCont(this);
-
-  void setParentPointers() {
-    _setParentsOnNodes(continuations, this);
-    if (body != null) body.parent = this;
-  }
-}
-
-// Binding an exception handler.
-//
-// let handler h(v0, v1) = E0 in E1
-//
-// The handler is a two-argument (exception, stack trace) continuation which
-// is implicitly the error continuation of all the code in its body E1.
-// [LetHandler] differs from a [LetCont] binding in that it (1) has the
-// runtime semantics of pushing/popping a handler from the dynamic exception
-// handler stack and (2) it does not have any explicit invocations.
-class LetHandler extends InteriorExpression {
-  Continuation handler;
-  Expression body;
-
-  LetHandler(this.handler, this.body);
-
-  accept(BlockVisitor visitor) => visitor.visitLetHandler(this);
-
-  void setParentPointers() {
-    handler.parent = this;
-    if (body != null) body.parent = this;
-  }
-}
-
-/// Binding mutable variables.
-///
-/// let mutable v = P in E
-///
-/// [MutableVariable]s can be seen as ref cells that are not first-class
-/// values.  They are therefore not [Primitive]s and not bound by [LetPrim]
-/// to prevent unrestricted use of references to them.  During one-pass
-/// construction, a [LetMutable] with an empty body is use to represent the
-/// one-hole context 'let mutable v = P in []'.
-class LetMutable extends InteriorExpression {
-  final MutableVariable variable;
-  final Reference<Primitive> valueRef;
-  Expression body;
-
-  Primitive get value => valueRef.definition;
-
-  LetMutable(this.variable, Primitive value)
-      : this.valueRef = new Reference<Primitive>(value);
-
-  Expression plug(Expression expr) {
-    return body = expr;
-  }
-
-  accept(BlockVisitor visitor) => visitor.visitLetMutable(this);
-
-  void setParentPointers() {
-    variable.parent = this;
-    valueRef.parent = this;
-    if (body != null) body.parent = this;
-  }
-}
-
-/// Throw a value.
-///
-/// Throw is an expression, i.e., it always occurs in tail position with
-/// respect to a body or expression.
-class Throw extends TailExpression {
-  Reference<Primitive> valueRef;
-
-  Primitive get value => valueRef.definition;
-
-  Throw(Primitive value) : valueRef = new Reference<Primitive>(value);
-
-  accept(BlockVisitor visitor) => visitor.visitThrow(this);
-
-  void setParentPointers() {
-    valueRef.parent = this;
-  }
-}
-
-/// Rethrow
-///
-/// Rethrow can only occur inside a continuation bound by [LetHandler].  It
-/// implicitly throws the exception parameter of the enclosing handler with
-/// the same stack trace as the enclosing handler.
-class Rethrow extends TailExpression {
-  accept(BlockVisitor visitor) => visitor.visitRethrow(this);
-  void setParentPointers() {}
-}
-
-/// An expression that is known to be unreachable.
-///
-/// 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(BlockVisitor visitor) => visitor.visitUnreachable(this);
-  void setParentPointers() {}
-}
-
-/// Invoke a continuation in tail position.
-class InvokeContinuation extends TailExpression {
-  Reference<Continuation> continuationRef;
-  List<Reference<Primitive>> argumentRefs;
-  SourceInformation sourceInformation;
-
-  Continuation get continuation => continuationRef.definition;
-  Primitive argument(int n) => argumentRefs[n].definition;
-  Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
-
-  // An invocation of a continuation is recursive if it occurs in the body of
-  // the continuation itself.
-  bool isRecursive;
-
-  /// True if this invocation escapes from the body of a [LetHandler]
-  /// (i.e. a try block). Notably, such an invocation cannot be inlined.
-  bool isEscapingTry;
-
-  InvokeContinuation(Continuation cont, List<Primitive> args,
-      {this.isRecursive: false,
-      this.isEscapingTry: false,
-      this.sourceInformation})
-      : continuationRef = new Reference<Continuation>(cont),
-        argumentRefs = _referenceList(args) {
-    assert(cont.parameters == null || cont.parameters.length == args.length);
-    if (isRecursive) cont.isRecursive = true;
-  }
-
-  /// A continuation invocation whose target and arguments will be filled
-  /// in later.
-  ///
-  /// Used as a placeholder for a jump whose target is not yet created
-  /// (e.g., in the translation of break and continue).
-  InvokeContinuation.uninitialized(
-      {this.isRecursive: false, this.isEscapingTry: false})
-      : continuationRef = null,
-        argumentRefs = null,
-        sourceInformation = null;
-
-  accept(BlockVisitor visitor) => visitor.visitInvokeContinuation(this);
-
-  void setParentPointers() {
-    if (continuationRef != null) continuationRef.parent = this;
-    if (argumentRefs != null) _setParentsOnList(argumentRefs, this);
-  }
-}
-
-/// Choose between a pair of continuations based on a condition value.
-///
-/// The two continuations must not declare any parameters.
-class Branch extends TailExpression {
-  final Reference<Primitive> conditionRef;
-  final Reference<Continuation> trueContinuationRef;
-  final Reference<Continuation> falseContinuationRef;
-  final SourceInformation sourceInformation;
-
-  Primitive get condition => conditionRef.definition;
-  Continuation get trueContinuation => trueContinuationRef.definition;
-  Continuation get falseContinuation => falseContinuationRef.definition;
-
-  /// If true, only the value `true` satisfies the condition. Otherwise, any
-  /// truthy value satisfies the check.
-  ///
-  /// Non-strict checks are preferable when the condition is known to be a
-  /// boolean.
-  bool isStrictCheck;
-
-  Branch(Primitive condition, Continuation trueCont, Continuation falseCont,
-      this.sourceInformation,
-      {bool strict})
-      : this.conditionRef = new Reference<Primitive>(condition),
-        trueContinuationRef = new Reference<Continuation>(trueCont),
-        falseContinuationRef = new Reference<Continuation>(falseCont),
-        isStrictCheck = strict {
-    assert(strict != null);
-  }
-
-  Branch.strict(Primitive condition, Continuation trueCont,
-      Continuation falseCont, SourceInformation sourceInformation)
-      : this(condition, trueCont, falseCont, sourceInformation, strict: true);
-
-  Branch.loose(Primitive condition, Continuation trueCont,
-      Continuation falseCont, SourceInformation sourceInformation)
-      : this(condition, trueCont, falseCont, sourceInformation, strict: false);
-
-  accept(BlockVisitor visitor) => visitor.visitBranch(this);
-
-  void setParentPointers() {
-    conditionRef.parent = this;
-    trueContinuationRef.parent = this;
-    falseContinuationRef.parent = this;
-  }
-}
-
-// ----------------------------------------------------------------------------
-//                            UTILITY STUFF
-// ----------------------------------------------------------------------------
-
-Reference<Primitive> _optionalReference(Primitive definition) {
-  return definition == null ? null : new Reference<Primitive>(definition);
-}
-
-List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
-  return definitions.map((e) => new Reference<Primitive>(e)).toList();
-}
-
-Iterable<Primitive> _dereferenceList(List<Reference<Primitive>> references) {
-  return references.map((ref) => ref.definition);
-}
-
-void _setParentsOnNodes(List<Node> nodes, Node parent) {
-  for (Node node in nodes) {
-    node.parent = parent;
-  }
-}
-
-void _setParentsOnList(List<Reference> nodes, Node parent) {
-  for (Reference node in nodes) {
-    node.parent = parent;
-  }
-}
-
-// ----------------------------------------------------------------------------
-//                                 VISITORS
-// ----------------------------------------------------------------------------
-
-/// 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.
-  ///
-  /// Traversal continues at the original success for the current node, so:
-  /// - The current node can safely be removed.
-  /// - Nodes inserted immediately below the current node will not be seen.
-  /// - The body of the current node should not be moved/removed, as traversal
-  ///   would otherwise continue into an orphaned or relocated node.
-  static void traverseInPreOrder(FunctionDefinition root, BlockVisitor v) {
-    List<Continuation> stack = <Continuation>[];
-    void walkBlock(InteriorNode block) {
-      v.visit(block);
-      Expression node = block.body;
-      while (node != null) {
-        if (node is LetCont) {
-          stack.addAll(node.continuations);
-        } else if (node is LetHandler) {
-          stack.add(node.handler);
-        }
-        Expression next = node.next;
-        v.visit(node);
-        node = next;
-      }
-    }
-    walkBlock(root);
-    while (stack.isNotEmpty) {
-      walkBlock(stack.removeLast());
-    }
-  }
-}
-
-abstract class Visitor<T> implements BlockVisitor<T> {
-  const Visitor();
-
-  T visit(Node node);
-
-  // Definitions.
-  T visitInvokeStatic(InvokeStatic node);
-  T visitInvokeMethod(InvokeMethod node);
-  T visitInvokeMethodDirectly(InvokeMethodDirectly node);
-  T visitInvokeConstructor(InvokeConstructor node);
-  T visitTypeCast(TypeCast node);
-  T visitSetMutable(SetMutable node);
-  T visitSetStatic(SetStatic node);
-  T visitSetField(SetField node);
-  T visitGetLazyStatic(GetLazyStatic node);
-  T visitAwait(Await node);
-  T visitYield(Yield node);
-  T visitLiteralList(LiteralList node);
-  T visitConstant(Constant node);
-  T visitGetMutable(GetMutable node);
-  T visitParameter(Parameter node);
-  T visitMutableVariable(MutableVariable node);
-  T visitGetStatic(GetStatic node);
-  T visitInterceptor(Interceptor node);
-  T visitCreateInstance(CreateInstance node);
-  T visitGetField(GetField node);
-  T visitCreateBox(CreateBox node);
-  T visitReifyRuntimeType(ReifyRuntimeType node);
-  T visitReadTypeVariable(ReadTypeVariable node);
-  T visitTypeExpression(TypeExpression node);
-  T visitCreateInvocationMirror(CreateInvocationMirror node);
-  T visitTypeTest(TypeTest node);
-  T visitTypeTestViaFlag(TypeTestViaFlag node);
-  T visitApplyBuiltinOperator(ApplyBuiltinOperator node);
-  T visitApplyBuiltinMethod(ApplyBuiltinMethod node);
-  T visitGetLength(GetLength node);
-  T visitGetIndex(GetIndex node);
-  T visitSetIndex(SetIndex node);
-  T visitRefinement(Refinement node);
-  T visitBoundsCheck(BoundsCheck node);
-  T visitReceiverCheck(ReceiverCheck node);
-  T visitForeignCode(ForeignCode node);
-}
-
-/// Recursively visits all children of a CPS term.
-///
-/// The user of the class is responsible for avoiding stack overflows from
-/// deep recursion, e.g. by overriding methods to cut off recursion at certain
-/// points.
-///
-/// All recursive invocations occur through the [visit] method, which the
-/// subclass may override as a generic way to control the visitor without
-/// overriding all visitor methods.
-///
-/// The `process*` methods are called in pre-order for every node visited.
-/// These can be overridden without disrupting the visitor traversal.
-class DeepRecursiveVisitor implements Visitor {
-  const DeepRecursiveVisitor();
-
-  visit(Node node) => node.accept(this);
-
-  processReference(Reference ref) {}
-
-  processFunctionDefinition(FunctionDefinition node) {}
-  visitFunctionDefinition(FunctionDefinition node) {
-    processFunctionDefinition(node);
-    if (node.interceptorParameter != null) visit(node.interceptorParameter);
-    if (node.receiverParameter != null) visit(node.receiverParameter);
-    node.parameters.forEach(visit);
-    visit(node.body);
-  }
-
-  processContinuation(Continuation node) {}
-  visitContinuation(Continuation node) {
-    processContinuation(node);
-    node.parameters.forEach(visit);
-    if (node.body != null) visit(node.body);
-  }
-
-  // Expressions.
-  processLetPrim(LetPrim node) {}
-  visitLetPrim(LetPrim node) {
-    processLetPrim(node);
-    visit(node.primitive);
-    visit(node.body);
-  }
-
-  processLetCont(LetCont node) {}
-  visitLetCont(LetCont node) {
-    processLetCont(node);
-    node.continuations.forEach(visit);
-    visit(node.body);
-  }
-
-  processLetHandler(LetHandler node) {}
-  visitLetHandler(LetHandler node) {
-    processLetHandler(node);
-    visit(node.handler);
-    visit(node.body);
-  }
-
-  processLetMutable(LetMutable node) {}
-  visitLetMutable(LetMutable node) {
-    processLetMutable(node);
-    visit(node.variable);
-    processReference(node.valueRef);
-    visit(node.body);
-  }
-
-  processInvokeStatic(InvokeStatic node) {}
-  visitInvokeStatic(InvokeStatic node) {
-    processInvokeStatic(node);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processInvokeContinuation(InvokeContinuation node) {}
-  visitInvokeContinuation(InvokeContinuation node) {
-    processInvokeContinuation(node);
-    processReference(node.continuationRef);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processInvokeMethod(InvokeMethod node) {}
-  visitInvokeMethod(InvokeMethod node) {
-    processInvokeMethod(node);
-    if (node.interceptorRef != null) {
-      processReference(node.interceptorRef);
-    }
-    processReference(node.receiverRef);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processInvokeMethodDirectly(InvokeMethodDirectly node) {}
-  visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    processInvokeMethodDirectly(node);
-    if (node.interceptorRef != null) {
-      processReference(node.interceptorRef);
-    }
-    processReference(node.receiverRef);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processInvokeConstructor(InvokeConstructor node) {}
-  visitInvokeConstructor(InvokeConstructor node) {
-    processInvokeConstructor(node);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processThrow(Throw node) {}
-  visitThrow(Throw node) {
-    processThrow(node);
-    processReference(node.valueRef);
-  }
-
-  processRethrow(Rethrow node) {}
-  visitRethrow(Rethrow node) {
-    processRethrow(node);
-  }
-
-  processBranch(Branch node) {}
-  visitBranch(Branch node) {
-    processBranch(node);
-    processReference(node.trueContinuationRef);
-    processReference(node.falseContinuationRef);
-    processReference(node.conditionRef);
-  }
-
-  processTypeCast(TypeCast node) {}
-  visitTypeCast(TypeCast node) {
-    processTypeCast(node);
-    processReference(node.valueRef);
-    node.typeArgumentRefs.forEach(processReference);
-  }
-
-  processTypeTest(TypeTest node) {}
-  visitTypeTest(TypeTest node) {
-    processTypeTest(node);
-    processReference(node.valueRef);
-    node.typeArgumentRefs.forEach(processReference);
-  }
-
-  processTypeTestViaFlag(TypeTestViaFlag node) {}
-  visitTypeTestViaFlag(TypeTestViaFlag node) {
-    processTypeTestViaFlag(node);
-    processReference(node.interceptorRef);
-  }
-
-  processSetMutable(SetMutable node) {}
-  visitSetMutable(SetMutable node) {
-    processSetMutable(node);
-    processReference(node.variableRef);
-    processReference(node.valueRef);
-  }
-
-  processGetLazyStatic(GetLazyStatic node) {}
-  visitGetLazyStatic(GetLazyStatic node) {
-    processGetLazyStatic(node);
-  }
-
-  processLiteralList(LiteralList node) {}
-  visitLiteralList(LiteralList node) {
-    processLiteralList(node);
-    node.valueRefs.forEach(processReference);
-  }
-
-  processConstant(Constant node) {}
-  visitConstant(Constant node) {
-    processConstant(node);
-  }
-
-  processMutableVariable(node) {}
-  visitMutableVariable(MutableVariable node) {
-    processMutableVariable(node);
-  }
-
-  processGetMutable(GetMutable node) {}
-  visitGetMutable(GetMutable node) {
-    processGetMutable(node);
-    processReference(node.variableRef);
-  }
-
-  processParameter(Parameter node) {}
-  visitParameter(Parameter node) {
-    processParameter(node);
-  }
-
-  processInterceptor(Interceptor node) {}
-  visitInterceptor(Interceptor node) {
-    processInterceptor(node);
-    processReference(node.inputRef);
-  }
-
-  processCreateInstance(CreateInstance node) {}
-  visitCreateInstance(CreateInstance node) {
-    processCreateInstance(node);
-    node.argumentRefs.forEach(processReference);
-    if (node.typeInformationRef != null) {
-      processReference(node.typeInformationRef);
-    }
-  }
-
-  processSetField(SetField node) {}
-  visitSetField(SetField node) {
-    processSetField(node);
-    processReference(node.objectRef);
-    processReference(node.valueRef);
-  }
-
-  processGetField(GetField node) {}
-  visitGetField(GetField node) {
-    processGetField(node);
-    processReference(node.objectRef);
-  }
-
-  processGetStatic(GetStatic node) {}
-  visitGetStatic(GetStatic node) {
-    processGetStatic(node);
-    if (node.witnessRef != null) {
-      processReference(node.witnessRef);
-    }
-  }
-
-  processSetStatic(SetStatic node) {}
-  visitSetStatic(SetStatic node) {
-    processSetStatic(node);
-    processReference(node.valueRef);
-  }
-
-  processCreateBox(CreateBox node) {}
-  visitCreateBox(CreateBox node) {
-    processCreateBox(node);
-  }
-
-  processReifyRuntimeType(ReifyRuntimeType node) {}
-  visitReifyRuntimeType(ReifyRuntimeType node) {
-    processReifyRuntimeType(node);
-    processReference(node.valueRef);
-  }
-
-  processReadTypeVariable(ReadTypeVariable node) {}
-  visitReadTypeVariable(ReadTypeVariable node) {
-    processReadTypeVariable(node);
-    processReference(node.targetRef);
-  }
-
-  processTypeExpression(TypeExpression node) {}
-  visitTypeExpression(TypeExpression node) {
-    processTypeExpression(node);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processCreateInvocationMirror(CreateInvocationMirror node) {}
-  visitCreateInvocationMirror(CreateInvocationMirror node) {
-    processCreateInvocationMirror(node);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processApplyBuiltinOperator(ApplyBuiltinOperator node) {}
-  visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    processApplyBuiltinOperator(node);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processApplyBuiltinMethod(ApplyBuiltinMethod node) {}
-  visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    processApplyBuiltinMethod(node);
-    processReference(node.receiverRef);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processForeignCode(ForeignCode node) {}
-  visitForeignCode(ForeignCode node) {
-    processForeignCode(node);
-    node.argumentRefs.forEach(processReference);
-  }
-
-  processUnreachable(Unreachable node) {}
-  visitUnreachable(Unreachable node) {
-    processUnreachable(node);
-  }
-
-  processAwait(Await node) {}
-  visitAwait(Await node) {
-    processAwait(node);
-    processReference(node.inputRef);
-  }
-
-  processYield(Yield node) {}
-  visitYield(Yield node) {
-    processYield(node);
-    processReference(node.inputRef);
-  }
-
-  processGetLength(GetLength node) {}
-  visitGetLength(GetLength node) {
-    processGetLength(node);
-    processReference(node.objectRef);
-  }
-
-  processGetIndex(GetIndex node) {}
-  visitGetIndex(GetIndex node) {
-    processGetIndex(node);
-    processReference(node.objectRef);
-    processReference(node.indexRef);
-  }
-
-  processSetIndex(SetIndex node) {}
-  visitSetIndex(SetIndex node) {
-    processSetIndex(node);
-    processReference(node.objectRef);
-    processReference(node.indexRef);
-    processReference(node.valueRef);
-  }
-
-  processRefinement(Refinement node) {}
-  visitRefinement(Refinement node) {
-    processRefinement(node);
-    processReference(node.value);
-  }
-
-  processBoundsCheck(BoundsCheck node) {}
-  visitBoundsCheck(BoundsCheck node) {
-    processBoundsCheck(node);
-    processReference(node.objectRef);
-    if (node.indexRef != null) {
-      processReference(node.indexRef);
-    }
-    if (node.lengthRef != null) {
-      processReference(node.lengthRef);
-    }
-  }
-
-  processNullCheck(ReceiverCheck node) {}
-  visitReceiverCheck(ReceiverCheck node) {
-    processNullCheck(node);
-    processReference(node.valueRef);
-    if (node.conditionRef != null) {
-      processReference(node.conditionRef);
-    }
-  }
-}
-
-typedef void StackAction();
-
-/// Calls `process*` for all nodes in a tree.
-/// For simple usage, only override the `process*` methods.
-///
-/// To avoid deep recursion, this class uses an "action stack" containing
-/// callbacks to be invoked after the processing of some term has finished.
-///
-/// To avoid excessive overhead from the action stack, basic blocks of
-/// interior nodes are iterated in a loop without using the action stack.
-///
-/// The iteration order can be controlled by overriding the `traverse*`
-/// methods for [LetCont], [LetPrim], [LetMutable], [LetHandler] and
-/// [Continuation].
-///
-/// The `traverse*` methods return the expression to visit next, and may
-/// push other subterms onto the stack using [push] or [pushAction] to visit
-/// them later. Actions pushed onto the stack will be executed after the body
-/// has been processed (and the stack actions it pushed have been executed).
-///
-/// By default, the `traverse` methods visit all non-recursive subterms,
-/// push all bound continuations on the stack, and return the body of the term.
-///
-/// Subclasses should not override the `visit` methods for the nodes that have
-/// a `traverse` method.
-class TrampolineRecursiveVisitor extends DeepRecursiveVisitor {
-  List<StackAction> _stack = <StackAction>[];
-
-  void pushAction(StackAction callback) {
-    _stack.add(callback);
-  }
-
-  void push(Continuation cont) {
-    _stack.add(() {
-      if (cont.isReturnContinuation) {
-        traverseContinuation(cont);
-      } else {
-        _processBlock(traverseContinuation(cont));
-      }
-    });
-  }
-
-  visitFunctionDefinition(FunctionDefinition node) {
-    processFunctionDefinition(node);
-    if (node.interceptorParameter != null) visit(node.interceptorParameter);
-    if (node.receiverParameter != null) visit(node.receiverParameter);
-    node.parameters.forEach(visit);
-    visit(node.body);
-  }
-
-  visitContinuation(Continuation cont) {
-    if (cont.isReturnContinuation) {
-      traverseContinuation(cont);
-    } else {
-      int initialHeight = _stack.length;
-      Expression body = traverseContinuation(cont);
-      _trampoline(body, initialHeight: initialHeight);
-    }
-  }
-
-  visitLetPrim(LetPrim node) => _trampoline(node);
-  visitLetCont(LetCont node) => _trampoline(node);
-  visitLetHandler(LetHandler node) => _trampoline(node);
-  visitLetMutable(LetMutable node) => _trampoline(node);
-
-  Expression traverseContinuation(Continuation cont) {
-    processContinuation(cont);
-    cont.parameters.forEach(visitParameter);
-    return cont.body;
-  }
-
-  Expression traverseLetCont(LetCont node) {
-    processLetCont(node);
-    node.continuations.forEach(push);
-    return node.body;
-  }
-
-  Expression traverseLetHandler(LetHandler node) {
-    processLetHandler(node);
-    push(node.handler);
-    return node.body;
-  }
-
-  Expression traverseLetPrim(LetPrim node) {
-    processLetPrim(node);
-    visit(node.primitive);
-    return node.body;
-  }
-
-  Expression traverseLetMutable(LetMutable node) {
-    processLetMutable(node);
-    visit(node.variable);
-    processReference(node.valueRef);
-    return node.body;
-  }
-
-  void _trampoline(Expression node, {int initialHeight}) {
-    initialHeight = initialHeight ?? _stack.length;
-    _processBlock(node);
-    while (_stack.length > initialHeight) {
-      StackAction callback = _stack.removeLast();
-      callback();
-    }
-  }
-
-  _processBlock(Expression node) {
-    while (node is InteriorExpression) {
-      if (node is LetCont) {
-        node = traverseLetCont(node);
-      } else if (node is LetHandler) {
-        node = traverseLetHandler(node);
-      } else if (node is LetPrim) {
-        node = traverseLetPrim(node);
-      } else {
-        node = traverseLetMutable(node);
-      }
-    }
-    visit(node);
-  }
-}
-
-/// Visit a just-deleted subterm and unlink all [Reference]s in it.
-class RemovalVisitor extends TrampolineRecursiveVisitor {
-  processReference(Reference reference) {
-    reference.unlink();
-  }
-
-  static void remove(Node node) {
-    (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];
-
-  /// Get the copy of a [Reference]'s definition from the map.
-  Definition getCopyOrNull(Reference reference) =>
-      reference == null ? null : getCopy(reference);
-
-  /// 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.argumentRefs), node.sourceInformation);
-  }
-
-  Definition visitInvokeMethod(InvokeMethod node) {
-    return new InvokeMethod(getCopy(node.receiverRef), node.selector, node.mask,
-        getList(node.argumentRefs),
-        sourceInformation: node.sourceInformation,
-        callingConvention: node.callingConvention,
-        interceptor: getCopyOrNull(node.interceptorRef));
-  }
-
-  Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    return new InvokeMethodDirectly(getCopy(node.receiverRef), node.target,
-        node.selector, getList(node.argumentRefs), node.sourceInformation,
-        interceptor: getCopyOrNull(node.interceptorRef));
-  }
-
-  Definition visitInvokeConstructor(InvokeConstructor node) {
-    return new InvokeConstructor(
-        node.dartType,
-        node.target,
-        node.selector,
-        getList(node.argumentRefs),
-        node.sourceInformation)..allocationSiteType = node.allocationSiteType;
-  }
-
-  Definition visitTypeCast(TypeCast node) {
-    return new TypeCast(
-        getCopy(node.valueRef), node.dartType, getList(node.typeArgumentRefs));
-  }
-
-  Definition visitSetMutable(SetMutable node) {
-    return new SetMutable(getCopy(node.variableRef), getCopy(node.valueRef),
-        sourceInformation: node.sourceInformation);
-  }
-
-  Definition visitSetStatic(SetStatic node) {
-    return new SetStatic(
-        node.element, getCopy(node.valueRef), node.sourceInformation);
-  }
-
-  Definition visitSetField(SetField node) {
-    return new SetField(
-        getCopy(node.objectRef), node.field, getCopy(node.valueRef),
-        sourceInformation: node.sourceInformation);
-  }
-
-  Definition visitGetLazyStatic(GetLazyStatic node) {
-    return new GetLazyStatic(node.element,
-        isFinal: node.isFinal, sourceInformation: node.sourceInformation);
-  }
-
-  Definition visitAwait(Await node) {
-    return new Await(getCopy(node.inputRef));
-  }
-
-  Definition visitYield(Yield node) {
-    return new Yield(getCopy(node.inputRef), node.hasStar);
-  }
-
-  Definition visitLiteralList(LiteralList node) {
-    return new LiteralList(node.dartType, getList(node.valueRefs))
-      ..allocationSiteType = node.allocationSiteType;
-  }
-
-  Definition visitConstant(Constant node) {
-    return new Constant(node.value, sourceInformation: node.sourceInformation);
-  }
-
-  Definition visitGetMutable(GetMutable node) {
-    return new GetMutable(getCopy(node.variableRef),
-        sourceInformation: node.sourceInformation);
-  }
-
-  Definition visitParameter(Parameter node) {
-    return new Parameter(node.hint);
-  }
-
-  Definition visitMutableVariable(MutableVariable node) {
-    return new MutableVariable(node.hint);
-  }
-
-  Definition visitGetStatic(GetStatic node) {
-    if (node.witnessRef != null) {
-      return new GetStatic.witnessed(node.element, getCopy(node.witnessRef),
-          sourceInformation: node.sourceInformation);
-    } else {
-      return new GetStatic(node.element,
-          isFinal: node.isFinal, sourceInformation: node.sourceInformation);
-    }
-  }
-
-  Definition visitInterceptor(Interceptor node) {
-    return new Interceptor(getCopy(node.inputRef), node.sourceInformation)
-      ..interceptedClasses.addAll(node.interceptedClasses);
-  }
-
-  Definition visitCreateInstance(CreateInstance node) {
-    return new CreateInstance(node.classElement, getList(node.argumentRefs),
-        getCopyOrNull(node.typeInformationRef), node.sourceInformation);
-  }
-
-  Definition visitGetField(GetField node) {
-    return new GetField(getCopy(node.objectRef), node.field,
-        isFinal: node.isFinal);
-  }
-
-  Definition visitCreateBox(CreateBox node) {
-    return new CreateBox();
-  }
-
-  Definition visitReifyRuntimeType(ReifyRuntimeType node) {
-    return new ReifyRuntimeType(getCopy(node.valueRef), node.sourceInformation);
-  }
-
-  Definition visitReadTypeVariable(ReadTypeVariable node) {
-    return new ReadTypeVariable(
-        node.variable, getCopy(node.targetRef), node.sourceInformation);
-  }
-
-  Definition visitTypeExpression(TypeExpression node) {
-    return new TypeExpression(
-        node.kind, node.dartType, getList(node.argumentRefs));
-  }
-
-  Definition visitCreateInvocationMirror(CreateInvocationMirror node) {
-    return new CreateInvocationMirror(
-        node.selector, getList(node.argumentRefs));
-  }
-
-  Definition visitTypeTest(TypeTest node) {
-    return new TypeTest(
-        getCopy(node.valueRef), node.dartType, getList(node.typeArgumentRefs));
-  }
-
-  Definition visitTypeTestViaFlag(TypeTestViaFlag node) {
-    return new TypeTestViaFlag(getCopy(node.interceptorRef), node.dartType);
-  }
-
-  Definition visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    return new ApplyBuiltinOperator(
-        node.operator, getList(node.argumentRefs), node.sourceInformation);
-  }
-
-  Definition visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    return new ApplyBuiltinMethod(node.method, getCopy(node.receiverRef),
-        getList(node.argumentRefs), node.sourceInformation);
-  }
-
-  Definition visitGetLength(GetLength node) {
-    return new GetLength(getCopy(node.objectRef), isFinal: node.isFinal);
-  }
-
-  Definition visitGetIndex(GetIndex node) {
-    return new GetIndex(getCopy(node.objectRef), getCopy(node.indexRef));
-  }
-
-  Definition visitSetIndex(SetIndex node) {
-    return new SetIndex(getCopy(node.objectRef), getCopy(node.indexRef),
-        getCopy(node.valueRef));
-  }
-
-  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.objectRef), node.sourceInformation);
-    } else {
-      return new BoundsCheck(getCopy(node.objectRef), getCopy(node.indexRef),
-          getCopyOrNull(node.lengthRef), node.checks, node.sourceInformation);
-    }
-  }
-
-  Definition visitReceiverCheck(ReceiverCheck node) {
-    return new ReceiverCheck(
-        getCopy(node.valueRef), node.selector, node.sourceInformation,
-        condition: getCopyOrNull(node.conditionRef),
-        useSelector: node.useSelector,
-        isNullCheck: node.isNullCheck);
-  }
-
-  Definition visitForeignCode(ForeignCode node) {
-    return new ForeignCode(node.codeTemplate, node.storedType,
-        getList(node.argumentRefs), node.nativeBehavior, node.sourceInformation,
-        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;
-      body.parent = interior;
-    }
-    _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);
-      Continuation contCopy = _copies[cont];
-      contCopy.body = _first;
-      _first.parent = contCopy;
-      _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.receiverParameter == null
-        ? null
-        : _definitions.copy(node.receiverParameter);
-    Parameter interceptorParameter = node.interceptorParameter == null
-        ? null
-        : _definitions.copy(node.interceptorParameter);
-    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,
-        interceptorParameter: interceptorParameter,
-        sourceInformation: node.sourceInformation);
-    _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.valueRef)));
-    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], _definitions.getList(node.argumentRefs),
-        isRecursive: node.isRecursive,
-        isEscapingTry: node.isEscapingTry,
-        sourceInformation: node.sourceInformation));
-  }
-
-  visitThrow(Throw node) {
-    plug(new Throw(_definitions.getCopy(node.valueRef)));
-  }
-
-  visitRethrow(Rethrow node) {
-    plug(new Rethrow());
-  }
-
-  visitBranch(Branch node) {
-    plug(new Branch.loose(
-        _definitions.getCopy(node.conditionRef),
-        _copies[node.trueContinuation],
-        _copies[node.falseContinuation],
-        node.sourceInformation)..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
deleted file mode 100644
index d788549..0000000
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ /dev/null
@@ -1,574 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.ir_nodes_sexpr;
-
-import '../constants/values.dart';
-import '../util/util.dart';
-import 'cps_ir_nodes.dart';
-import '../universe/call_structure.dart' show CallStructure;
-
-/// A [Decorator] is a function used by [SExpressionStringifier] to augment the
-/// output produced for a node or reference.  It can be provided to the
-/// constructor.
-typedef String Decorator(node, String s);
-
-/// Generate a Lisp-like S-expression representation of an IR node as a string.
-class SExpressionStringifier extends Indentation implements Visitor<String> {
-  final _Namer namer = new _Namer();
-
-  String newValueName(Primitive node) => namer.nameValue(node);
-  String newContinuationName(Continuation node) => namer.nameContinuation(node);
-  Decorator decorator;
-
-  SExpressionStringifier([this.decorator]) {
-    if (this.decorator == null) {
-      this.decorator = (node, String s) => s;
-    }
-  }
-
-  /// Create a stringifier with an extra layer of decoration.
-  SExpressionStringifier withDecorator(Decorator subDecorator) {
-    return new SExpressionStringifier((node, String s) {
-      return subDecorator(node, decorator(node, s));
-    });
-  }
-
-  /// Create a stringifier that displays type information.
-  SExpressionStringifier withTypes() => withDecorator(typeDecorator);
-
-  /// Creates a stringifier that adds annotations from a map;
-  /// see [Node.debugString].
-  SExpressionStringifier withAnnotations(Map annotations) {
-    return withDecorator(decoratorFromMap(annotations));
-  }
-
-  static Decorator decoratorFromMap(Map annotations) {
-    Map<Node, String> nodeMap = {};
-    for (var key in annotations.keys) {
-      if (key is Node) {
-        nodeMap[key] = '${annotations[key]}';
-      } else {
-        String text = key;
-        Node node = annotations[key];
-        if (nodeMap.containsKey(node)) {
-          // In case two annotations belong to the same node,
-          // put both annotations on that node.
-          nodeMap[node] += ' $text';
-        } else {
-          nodeMap[node] = text;
-        }
-      }
-    }
-    return (node, string) {
-      String text = nodeMap[node];
-      if (text != null) return '***$string*** $text';
-      return string;
-    };
-  }
-
-  static String typeDecorator(node, String string) {
-    return node is Variable ? '$string:${node.type}' : string;
-  }
-
-  String access(Reference<Definition> r) {
-    if (r == null) return '**** NULL ****';
-    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);
-  }
-
-  String visitMutableVariable(MutableVariable node) {
-    return namer.nameMutableVariable(node);
-  }
-
-  /// 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);
-  }
-
-  String formatOptionalParameter(Parameter parameter) {
-    return parameter == null ? '()' : '(${visit(parameter)})';
-  }
-
-  String visitFunctionDefinition(FunctionDefinition node) {
-    String name = node.element.name;
-    String interceptorParameter =
-        formatOptionalParameter(node.interceptorParameter);
-    String thisParameter = formatOptionalParameter(node.receiverParameter);
-    String parameters = node.parameters.map(visit).join(' ');
-    namer.setReturnContinuation(node.returnContinuation);
-    String body = indentBlock(() => visit(node.body));
-    return '$indentation'
-        '(FunctionDefinition $name $interceptorParameter $thisParameter '
-        '($parameters) return\n'
-        '$body)';
-  }
-
-  String visitLetPrim(LetPrim node) {
-    String name = newValueName(node.primitive);
-    String value = visit(node.primitive);
-    String bindings = '($name $value)';
-    String skip = ' ' * '(LetPrim ('.length;
-    while (node.body is LetPrim) {
-      node = node.body;
-      name = newValueName(node.primitive);
-      value = visit(node.primitive);
-      String binding = decorator(node, '($name $value)');
-      bindings += '\n${indentation}$skip$binding';
-    }
-    String body = indentBlock(() => visit(node.body));
-    return '$indentation(LetPrim ($bindings)\n$body)';
-  }
-
-  bool isBranchTarget(Continuation cont) {
-    return cont.hasExactlyOneUse && cont.firstRef.parent is Branch;
-  }
-
-  String visitLetCont(LetCont node) {
-    String conts;
-    bool first = true;
-    String skip = ' ' * '(LetCont ('.length;
-    for (Continuation continuation in node.continuations) {
-      // Branch continuations will be printed at their use site.
-      if (isBranchTarget(continuation)) continue;
-      if (first) {
-        first = false;
-        conts = visit(continuation);
-      } else {
-        // Each subsequent line is indented additional spaces to align it
-        // with the previous continuation.
-        conts += '\n${indentation}$skip${visit(continuation)}';
-      }
-    }
-    // If there were no continuations printed, just print the body.
-    if (first) return visit(node.body);
-
-    String body = indentBlock(() => visit(node.body));
-    return '$indentation(LetCont ($conts)\n$body)';
-  }
-
-  String visitLetHandler(LetHandler node) {
-    // There are no explicit references to the handler, so we leave it
-    // anonymous in the printed representation.
-    String parameters = node.handler.parameters
-        .map((p) => '${decorator(p, newValueName(p))}')
-        .join(' ');
-    String handlerBody =
-        indentBlock(() => indentBlock(() => visit(node.handler.body)));
-    String body = indentBlock(() => visit(node.body));
-    return '$indentation(LetHandler (($parameters)\n$handlerBody)\n$body)';
-  }
-
-  String visitLetMutable(LetMutable node) {
-    String name = visit(node.variable);
-    String value = access(node.valueRef);
-    String body = indentBlock(() => visit(node.body));
-    return '$indentation(LetMutable ($name $value)\n$body)';
-  }
-
-  String formatArguments(
-      CallStructure call, List<Reference<Primitive>> arguments,
-      [CallingConvention callingConvention = CallingConvention.Normal]) {
-    int positionalArgumentCount = call.positionalArgumentCount;
-    List<String> args =
-        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 args =
-        formatArguments(node.selector.callStructure, node.argumentRefs);
-    return '(InvokeStatic $name $args)';
-  }
-
-  String visitInvokeMethod(InvokeMethod node) {
-    String name = node.selector.name;
-    String interceptor = optionalAccess(node.interceptorRef);
-    String receiver = access(node.receiverRef);
-    String arguments = formatArguments(
-        node.selector.callStructure, node.argumentRefs, node.callingConvention);
-    return '(InvokeMethod $interceptor $receiver $name $arguments)';
-  }
-
-  String visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    String interceptor = optionalAccess(node.interceptorRef);
-    String receiver = access(node.receiverRef);
-    String name = node.selector.name;
-    String arguments = formatArguments(
-        node.selector.callStructure, node.argumentRefs, node.callingConvention);
-    return '(InvokeMethodDirectly $interceptor $receiver $name $arguments)';
-  }
-
-  String visitInvokeConstructor(InvokeConstructor node) {
-    // 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.
-    String name = node.dartType != null
-        ? node.dartType.toString()
-        : node.target.enclosingClass.name;
-    if (!node.target.name.isEmpty) {
-      name = '${name}.${node.target.name}';
-    }
-    String args =
-        formatArguments(node.selector.callStructure, node.argumentRefs);
-    return '(InvokeConstructor $name $args)';
-  }
-
-  String visitInvokeContinuation(InvokeContinuation node) {
-    String name = access(node.continuationRef);
-    if (node.isRecursive) name = 'rec $name';
-    String args = node.argumentRefs == null
-        ? '**** NULL ****'
-        : node.argumentRefs.map(access).join(' ');
-    String escaping = node.isEscapingTry ? ' escape' : '';
-    return '$indentation(InvokeContinuation $name ($args)$escaping)';
-  }
-
-  String visitThrow(Throw node) {
-    String value = access(node.valueRef);
-    return '$indentation(Throw $value)';
-  }
-
-  String visitRethrow(Rethrow node) {
-    return '$indentation(Rethrow)';
-  }
-
-  String visitBranch(Branch node) {
-    String condition = access(node.conditionRef);
-    assert(isBranchTarget(node.trueContinuation));
-    assert(isBranchTarget(node.falseContinuation));
-    String trueCont = indentBlock(() => visit(node.trueContinuation));
-    String falseCont = indentBlock(() => visit(node.falseContinuation));
-    String strict = node.isStrictCheck ? 'Strict' : 'NonStrict';
-    return '$indentation(Branch $strict $condition\n$trueCont\n$falseCont)';
-  }
-
-  String visitUnreachable(Unreachable node) {
-    return '$indentation(Unreachable)';
-  }
-
-  String visitConstant(Constant node) {
-    String value = node.value.accept(new ConstantStringifier(), null);
-    return '(Constant $value)';
-  }
-
-  String visitContinuation(Continuation node) {
-    if (isBranchTarget(node)) {
-      assert(node.parameters.isEmpty);
-      assert(!node.isRecursive);
-      return indentBlock(() => visit(node.body));
-    }
-    String name = newContinuationName(node);
-    if (node.isRecursive) name = 'rec $name';
-    // TODO(karlklose): this should be changed to `.map(visit).join(' ')`
-    // and should recurse to [visit].  Currently we can't do that, because
-    // the unstringifier_test produces [LetConts] with dummy arguments on
-    // them.
-    String parameters = node.parameters
-        .map((p) => '${decorator(p, newValueName(p))}')
-        .join(' ');
-    String body = indentBlock(() => indentBlock(() => visit(node.body)));
-    return '($name ($parameters)\n$body)';
-  }
-
-  String visitGetMutable(GetMutable node) {
-    return '(GetMutable ${access(node.variableRef)})';
-  }
-
-  String visitSetMutable(SetMutable node) {
-    String value = access(node.valueRef);
-    return '(SetMutable ${access(node.variableRef)} $value)';
-  }
-
-  String visitTypeCast(TypeCast node) {
-    String value = access(node.valueRef);
-    String typeArguments = node.typeArgumentRefs.map(access).join(' ');
-    return '(TypeCast $value ${node.dartType} ($typeArguments))';
-  }
-
-  String visitTypeTest(TypeTest node) {
-    String value = access(node.valueRef);
-    String typeArguments = node.typeArgumentRefs.map(access).join(' ');
-    return '(TypeTest $value ${node.dartType} ($typeArguments))';
-  }
-
-  String visitTypeTestViaFlag(TypeTestViaFlag node) {
-    String interceptor = access(node.interceptorRef);
-    return '(TypeTestViaFlag $interceptor ${node.dartType})';
-  }
-
-  String visitLiteralList(LiteralList node) {
-    String values = node.valueRefs.map(access).join(' ');
-    return '(LiteralList ($values))';
-  }
-
-  String visitSetField(SetField node) {
-    String object = access(node.objectRef);
-    String field = node.field.name;
-    String value = access(node.valueRef);
-    return '(SetField $object $field $value)';
-  }
-
-  String visitGetField(GetField node) {
-    String object = access(node.objectRef);
-    String field = node.field.name;
-    return '(GetField $object $field)';
-  }
-
-  String visitGetStatic(GetStatic node) {
-    String element = node.element.name;
-    return '(GetStatic $element)';
-  }
-
-  String visitSetStatic(SetStatic node) {
-    String element = node.element.name;
-    String value = access(node.valueRef);
-    return '(SetStatic $element $value)';
-  }
-
-  String visitGetLazyStatic(GetLazyStatic node) {
-    String element = node.element.name;
-    return '(GetLazyStatic $element)';
-  }
-
-  String visitCreateBox(CreateBox node) {
-    return '(CreateBox)';
-  }
-
-  String visitCreateInstance(CreateInstance node) {
-    String className = node.classElement.name;
-    String arguments = node.argumentRefs.map(access).join(' ');
-    String typeInformation = optionalAccess(node.typeInformationRef);
-    return '(CreateInstance $className ($arguments) ($typeInformation))';
-  }
-
-  String visitInterceptor(Interceptor node) {
-    return '(Interceptor ${access(node.inputRef)})';
-  }
-
-  String visitReifyRuntimeType(ReifyRuntimeType node) {
-    return '(ReifyRuntimeType ${access(node.valueRef)})';
-  }
-
-  String visitReadTypeVariable(ReadTypeVariable node) {
-    return '(ReadTypeVariable ${access(node.targetRef)}.${node.variable})';
-  }
-
-  String visitTypeExpression(TypeExpression node) {
-    String args = node.argumentRefs.map(access).join(' ');
-    return '(TypeExpression ${node.kindAsString} ${node.dartType} ($args))';
-  }
-
-  String visitCreateInvocationMirror(CreateInvocationMirror node) {
-    String selector = node.selector.name;
-    String args = node.argumentRefs.map(access).join(' ');
-    return '(CreateInvocationMirror $selector ($args))';
-  }
-
-  String visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    String operator = node.operator.toString();
-    String args = node.argumentRefs.map(access).join(' ');
-    return '(ApplyBuiltinOperator $operator ($args))';
-  }
-
-  String visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    String method = node.method.toString();
-    String receiver = access(node.receiverRef);
-    String args = node.argumentRefs.map(access).join(' ');
-    return '(ApplyBuiltinMethod $method $receiver ($args))';
-  }
-
-  String visitForeignCode(ForeignCode node) {
-    String arguments = node.argumentRefs.map(access).join(' ');
-    return '(JS "${node.codeTemplate.source}" ($arguments))';
-  }
-
-  String visitGetLength(GetLength node) {
-    String object = access(node.objectRef);
-    return '(GetLength $object)';
-  }
-
-  String visitGetIndex(GetIndex node) {
-    String object = access(node.objectRef);
-    String index = access(node.indexRef);
-    return '(GetIndex $object $index)';
-  }
-
-  String visitSetIndex(SetIndex node) {
-    String object = access(node.objectRef);
-    String index = access(node.indexRef);
-    String value = access(node.valueRef);
-    return '(SetIndex $object $index $value)';
-  }
-
-  @override
-  String visitAwait(Await node) {
-    String value = access(node.inputRef);
-    return '(Await $value)';
-  }
-
-  @override
-  String visitYield(Yield node) {
-    String value = access(node.inputRef);
-    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.objectRef);
-    String index = optionalAccess(node.indexRef);
-    String length = optionalAccess(node.lengthRef);
-    return '(BoundsCheck $object $index $length ${node.checkString})';
-  }
-
-  String visitReceiverCheck(ReceiverCheck node) {
-    String value = access(node.valueRef);
-    String condition = optionalAccess(node.conditionRef);
-    return '(ReceiverCheck $value ${node.selector} $condition '
-        '${node.flagString}))';
-  }
-}
-
-class ConstantStringifier extends ConstantValueVisitor<String, Null> {
-  // Some of these methods are unimplemented because we haven't had a need
-  // to print such constants.  When printing is implemented, the corresponding
-  // parsing support should be added to SExpressionUnstringifier.parseConstant
-  // in the dart2js tests (currently in the file
-  // tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart).
-
-  String _failWith(ConstantValue constant) {
-    throw 'Stringification not supported for ${constant.toStructuredText()}';
-  }
-
-  String visitFunction(FunctionConstantValue constant, _) {
-    return '(Function "${constant.toDartText()}")';
-  }
-
-  String visitNull(NullConstantValue constant, _) {
-    return '(Null)';
-  }
-
-  String visitNonConstant(NonConstantValue constant, _) {
-    return '(NonConstant)';
-  }
-
-  String visitInt(IntConstantValue constant, _) {
-    return '(Int ${constant.toDartText()})';
-  }
-
-  String visitDouble(DoubleConstantValue constant, _) {
-    return '(Double ${constant.toDartText()})';
-  }
-
-  String visitBool(BoolConstantValue constant, _) {
-    return '(Bool ${constant.toDartText()})';
-  }
-
-  String visitString(StringConstantValue constant, _) {
-    return '(String ${constant.toDartText()})';
-  }
-
-  String visitList(ListConstantValue constant, _) {
-    String entries =
-        constant.entries.map((entry) => entry.accept(this, _)).join(' ');
-    return '(List $entries)';
-  }
-
-  String visitMap(MapConstantValue constant, _) {
-    List<String> elements = <String>[];
-    for (int i = 0; i < constant.keys.length; ++i) {
-      ConstantValue key = constant.keys[i];
-      ConstantValue value = constant.values[i];
-      elements.add('(${key.accept(this, _)} . ${value.accept(this, _)})');
-    }
-    return '(Map (${elements.join(' ')}))';
-  }
-
-  String visitConstructed(ConstructedConstantValue constant, _) {
-    return '(Constructed "${constant.toDartText()}")';
-  }
-
-  String visitType(TypeConstantValue constant, _) {
-    return '(Type "${constant.representedType}")';
-  }
-
-  String visitInterceptor(InterceptorConstantValue constant, _) {
-    return '(Interceptor "${constant.toDartText()}")';
-  }
-
-  String visitSynthetic(SyntheticConstantValue constant, _) {
-    return '(Synthetic "${constant.toDartText()}")';
-  }
-
-  String visitDeferred(DeferredConstantValue constant, _) {
-    return _failWith(constant);
-  }
-}
-
-class _Namer {
-  final Map<Node, String> _names = <Node, String>{};
-  int _valueCounter = 0;
-  int _continuationCounter = 0;
-
-  // TODO(sra): Make the methods not assert and print something indicating an
-  // error, so printer can be used to inspect broken terms.
-
-  String nameParameter(Parameter parameter) {
-    assert(!_names.containsKey(parameter));
-    String name =
-        parameter.hint != null ? parameter.hint.name : nameValue(parameter);
-    return _names[parameter] = name;
-  }
-
-  String nameMutableVariable(MutableVariable variable) {
-    assert(!_names.containsKey(variable));
-    return _names[variable] = variable.hint.name;
-  }
-
-  String nameContinuation(Continuation node) {
-    assert(!_names.containsKey(node));
-    return _names[node] = 'k${_continuationCounter++}';
-  }
-
-  String nameValue(Primitive node) {
-    assert(!_names.containsKey(node));
-    return _names[node] = 'v${_valueCounter++}';
-  }
-
-  void setReturnContinuation(Continuation node) {
-    assert(!_names.containsKey(node) || _names[node] == 'return');
-    _names[node] = 'return';
-  }
-
-  String getName(Node node) {
-    if (!_names.containsKey(node)) return 'MISSING_NAME';
-    return _names[node];
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
deleted file mode 100644
index f70c586..0000000
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ /dev/null
@@ -1,683 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.ir_tracer;
-
-import 'dart:async' show EventSink;
-import 'cps_ir_nodes.dart' as cps_ir;
-import '../tracer.dart';
-
-/**
- * If true, show LetCont expressions in output.
- */
-const bool IR_TRACE_LET_CONT = false;
-
-class IRTracer extends TracerUtil implements cps_ir.Visitor {
-  EventSink<String> output;
-
-  IRTracer(this.output);
-
-  visit(cps_ir.Node node) => node.accept(this);
-
-  void traceGraph(String name, cps_ir.FunctionDefinition node) {
-    tag("cfg", () {
-      printProperty("name", name);
-
-      names = new Names();
-      BlockCollector builder = new BlockCollector(names);
-      builder.visit(node);
-
-      for (Block block in builder.entries) {
-        printBlock(block, entryPoint: node);
-      }
-      for (Block block in builder.cont2block.values) {
-        printBlock(block);
-      }
-      names = null;
-    });
-  }
-
-  // Temporary field used during tree walk
-  Names names;
-
-  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
-    unexpectedNode(node);
-  }
-
-  // Bodies and initializers are not visited.  They contain continuations which
-  // are found by a BlockCollector, then those continuations are processed by
-  // this visitor.
-  unexpectedNode(cps_ir.Node node) {
-    throw 'The IR tracer reached an unexpected IR instruction: $node';
-  }
-
-  int countUses(cps_ir.Definition definition) {
-    int count = 0;
-    cps_ir.Reference ref = definition.firstRef;
-    while (ref != null) {
-      ++count;
-      ref = ref.next;
-    }
-    return count;
-  }
-
-  /// If [entryPoint] is given, this block is an entry point.
-  printBlock(Block block, {cps_ir.FunctionDefinition entryPoint}) {
-    tag("block", () {
-      printProperty("name", block.name);
-      printProperty("from_bci", -1);
-      printProperty("to_bci", -1);
-      printProperty("predecessors", block.pred.map((n) => n.name));
-      printProperty("successors", block.succ.map((n) => n.name));
-      printEmptyProperty("xhandlers");
-      printEmptyProperty("flags");
-      tag("states", () {
-        tag("locals", () {
-          printProperty("size", 0);
-          printProperty("method", "None");
-        });
-      });
-      tag("HIR", () {
-        String formatParameter(cps_ir.Parameter param) {
-          return '${names.name(param)} ${param.type}';
-        }
-        if (entryPoint != null) {
-          String thisParam = entryPoint.receiverParameter != null
-              ? formatParameter(entryPoint.receiverParameter)
-              : 'no receiver';
-          String interceptorParam = entryPoint.interceptorParameter != null
-              ? formatParameter(entryPoint.interceptorParameter)
-              : 'no interceptor';
-          String params = entryPoint.parameters.map(formatParameter).join(', ');
-          printStmt('x0', 'Entry ($interceptorParam) ($thisParam) ($params)');
-        }
-        String params = block.parameters.map(formatParameter).join(', ');
-        printStmt('x0', 'Parameters ($params)');
-        visit(block.body);
-      });
-    });
-  }
-
-  void printStmt(String resultVar, String contents) {
-    int bci = 0;
-    int uses = 0;
-    addIndent();
-    add("$bci $uses $resultVar $contents <|@\n");
-  }
-
-  visitLetPrim(cps_ir.LetPrim node) {
-    String id = names.name(node.primitive);
-    String primitive = visit(node.primitive);
-    printStmt(id, "LetPrim $id = $primitive [type=${node.primitive.type}]");
-    visit(node.body);
-  }
-
-  visitLetCont(cps_ir.LetCont node) {
-    if (IR_TRACE_LET_CONT) {
-      String dummy = names.name(node);
-
-      String nameContinuation(cps_ir.Continuation cont) {
-        String name = names.name(cont);
-        return cont.isRecursive ? '$name*' : name;
-      }
-
-      String ids = node.continuations.map(nameContinuation).join(', ');
-      printStmt(dummy, "LetCont $ids");
-    }
-    visit(node.body);
-  }
-
-  visitLetHandler(cps_ir.LetHandler node) {
-    if (IR_TRACE_LET_CONT) {
-      String dummy = names.name(node);
-      String id = names.name(node.handler);
-      printStmt(dummy, "LetHandler $id = <$id>");
-    }
-    visit(node.body);
-  }
-
-  visitLetMutable(cps_ir.LetMutable node) {
-    String id = names.name(node.variable);
-    printStmt(id, "LetMutable $id = ${formatReference(node.valueRef)}");
-    visit(node.body);
-  }
-
-  visitInvokeStatic(cps_ir.InvokeStatic node) {
-    String callName = node.selector.name;
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    return "InvokeStatic $callName ($args)";
-  }
-
-  visitInvokeMethod(cps_ir.InvokeMethod node) {
-    String receiver = formatReference(node.receiverRef);
-    String callName = node.selector.name;
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    return "InvokeMethod $receiver $callName ($args)";
-  }
-
-  visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
-    String receiver = formatReference(node.receiverRef);
-    String callName = node.selector.name;
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    return "InvokeMethodDirectly $receiver $callName ($args)";
-  }
-
-  visitInvokeConstructor(cps_ir.InvokeConstructor node) {
-    String className = node.target.enclosingClass.name;
-    String callName;
-    if (node.target.name.isEmpty) {
-      callName = '${className}';
-    } else {
-      callName = '${className}.${node.target.name}';
-    }
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    return "InvokeConstructor $callName ($args)";
-  }
-
-  visitThrow(cps_ir.Throw node) {
-    String dummy = names.name(node);
-    String value = formatReference(node.valueRef);
-    printStmt(dummy, "Throw $value");
-  }
-
-  visitRethrow(cps_ir.Rethrow node) {
-    String dummy = names.name(node);
-    printStmt(dummy, "Rethrow");
-  }
-
-  visitUnreachable(cps_ir.Unreachable node) {
-    String dummy = names.name(node);
-    printStmt(dummy, 'Unreachable');
-  }
-
-  visitLiteralList(cps_ir.LiteralList node) {
-    String values = node.valueRefs.map(formatReference).join(', ');
-    return "LiteralList ($values)";
-  }
-
-  visitTypeCast(cps_ir.TypeCast node) {
-    String value = formatReference(node.valueRef);
-    String args = node.typeArgumentRefs.map(formatReference).join(', ');
-    return "TypeCast ($value ${node.dartType} ($args))";
-  }
-
-  visitInvokeContinuation(cps_ir.InvokeContinuation node) {
-    String dummy = names.name(node);
-    String kont = formatReference(node.continuationRef);
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    printStmt(dummy, "InvokeContinuation $kont ($args)");
-  }
-
-  visitBranch(cps_ir.Branch node) {
-    String dummy = names.name(node);
-    String condition = formatReference(node.conditionRef);
-    String trueCont = formatReference(node.trueContinuationRef);
-    String falseCont = formatReference(node.falseContinuationRef);
-    String strict = node.isStrictCheck ? "Strict" : "NonStrict";
-    printStmt(dummy, "Branch $condition ($trueCont, $falseCont) $strict");
-  }
-
-  visitAwait(cps_ir.Await node) {
-    String value = formatReference(node.inputRef);
-    return 'Await $value';
-  }
-
-  visitYield(cps_ir.Yield node) {
-    String name = node.hasStar ? 'YieldStar' : 'Yield';
-    String value = formatReference(node.inputRef);
-    return '$name $value';
-  }
-
-  visitSetMutable(cps_ir.SetMutable node) {
-    String variable = names.name(node.variable);
-    String value = formatReference(node.valueRef);
-    return 'SetMutable $variable := $value';
-  }
-
-  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
-    } else {
-      return names.name(ref.definition);
-    }
-  }
-
-  visitConstant(cps_ir.Constant node) {
-    return "Constant ${node.value.toStructuredText()}";
-  }
-
-  visitParameter(cps_ir.Parameter node) {
-    return "Parameter ${names.name(node)}";
-  }
-
-  visitMutableVariable(cps_ir.MutableVariable node) {
-    return "MutableVariable ${names.name(node)}";
-  }
-
-  visitContinuation(cps_ir.Continuation node) {
-    return "Continuation ${names.name(node)}";
-  }
-
-  visitSetField(cps_ir.SetField node) {
-    String object = formatReference(node.objectRef);
-    String field = node.field.name;
-    String value = formatReference(node.valueRef);
-    return 'SetField $object.$field = $value';
-  }
-
-  visitGetField(cps_ir.GetField node) {
-    String object = formatReference(node.objectRef);
-    String field = node.field.name;
-    String finalFlag = node.isFinal ? 'final' : 'non-final';
-    return 'GetField $object.$field $finalFlag';
-  }
-
-  visitGetStatic(cps_ir.GetStatic node) {
-    String element = node.element.name;
-    String finalFlag = node.isFinal ? 'final' : 'non-final';
-    return 'GetStatic $element $finalFlag';
-  }
-
-  visitSetStatic(cps_ir.SetStatic node) {
-    String element = node.element.name;
-    String value = formatReference(node.valueRef);
-    return 'SetStatic $element = $value';
-  }
-
-  visitGetLazyStatic(cps_ir.GetLazyStatic node) {
-    String element = node.element.name;
-    String finalFlag = node.isFinal ? 'final' : 'non-final';
-    return "GetLazyStatic $element $finalFlag";
-  }
-
-  visitCreateBox(cps_ir.CreateBox node) {
-    return 'CreateBox';
-  }
-
-  visitCreateInstance(cps_ir.CreateInstance node) {
-    String className = node.classElement.name;
-    String arguments = node.argumentRefs.map(formatReference).join(', ');
-    String typeInformation = formatReference(node.typeInformationRef);
-    return 'CreateInstance $className ($arguments) <$typeInformation>';
-  }
-
-  visitInterceptor(cps_ir.Interceptor node) {
-    return 'Interceptor(${formatReference(node.inputRef)}, '
-        '${node.interceptedClasses})';
-  }
-
-  visitGetMutable(cps_ir.GetMutable node) {
-    String variable = names.name(node.variable);
-    return 'GetMutable $variable';
-  }
-
-  visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
-    return "ReadTypeVariable ${node.variable.element} "
-        "${formatReference(node.targetRef)}";
-  }
-
-  visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
-    return "ReifyRuntimeType ${formatReference(node.valueRef)}";
-  }
-
-  visitTypeExpression(cps_ir.TypeExpression node) {
-    return "TypeExpression ${node.kindAsString} ${node.dartType}"
-        "${node.argumentRefs.map(formatReference).join(', ')}";
-  }
-
-  visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    return "CreateInvocationMirror(${node.selector.name}, $args)";
-  }
-
-  visitTypeTest(cps_ir.TypeTest node) {
-    String value = formatReference(node.valueRef);
-    String args = node.typeArgumentRefs.map(formatReference).join(', ');
-    return "TypeTest ($value ${node.dartType} ($args))";
-  }
-
-  visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
-    String interceptor = formatReference(node.interceptorRef);
-    return "TypeTestViaFlag ($interceptor ${node.dartType})";
-  }
-
-  visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
-    String operator = node.operator.toString();
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    return 'ApplyBuiltinOperator $operator ($args)';
-  }
-
-  visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
-    String method = node.method.toString();
-    String receiver = formatReference(node.receiverRef);
-    String args = node.argumentRefs.map(formatReference).join(', ');
-    return 'ApplyBuiltinMethod $method $receiver ($args)';
-  }
-
-  visitForeignCode(cps_ir.ForeignCode node) {
-    String id = names.name(node);
-    String arguments = node.argumentRefs.map(formatReference).join(', ');
-    printStmt(
-        id, "ForeignCode ${node.type} ${node.codeTemplate.source} $arguments");
-  }
-
-  visitGetLength(cps_ir.GetLength node) {
-    String object = formatReference(node.objectRef);
-    String finalFlag = node.isFinal ? 'final' : 'non-final';
-    return 'GetLength $object $finalFlag';
-  }
-
-  visitGetIndex(cps_ir.GetIndex node) {
-    String object = formatReference(node.objectRef);
-    String index = formatReference(node.indexRef);
-    return 'GetIndex $object $index';
-  }
-
-  visitSetIndex(cps_ir.SetIndex node) {
-    String object = formatReference(node.objectRef);
-    String index = formatReference(node.indexRef);
-    String value = formatReference(node.valueRef);
-    return 'SetIndex $object $index $value';
-  }
-
-  visitRefinement(cps_ir.Refinement node) {
-    String value = formatReference(node.value);
-    return 'Refinement $value ${node.refineType}';
-  }
-
-  visitBoundsCheck(cps_ir.BoundsCheck node) {
-    String object = formatReference(node.objectRef);
-    String index =
-        node.indexRef == null ? 'no-index' : formatReference(node.indexRef);
-    String length =
-        node.lengthRef == null ? 'no-length' : formatReference(node.lengthRef);
-    return 'BoundsCheck $object $index $length ${node.checkString}';
-  }
-
-  visitReceiverCheck(cps_ir.ReceiverCheck node) {
-    String value = formatReference(node.valueRef);
-    String condition = formatReference(node.conditionRef);
-    return 'ReceiverCheck $value $condition ${node.selector} '
-        '${node.flagString}';
-  }
-}
-
-/**
- * Invents (and remembers) names for Continuations, Parameters, etc.
- * The names must match the conventions used by IR Hydra, e.g.
- * Continuations and Functions must have names of form B### since they
- * are visualized as basic blocks.
- */
-class Names {
-  final Map<Object, String> names = {};
-  final Map<String, int> counters = {'r': 0, 'B': 0, 'v': 0, 'x': 0, 'c': 0};
-
-  String prefix(x) {
-    if (x is cps_ir.Parameter) return 'r';
-    if (x is cps_ir.Continuation || x is cps_ir.FunctionDefinition) return 'B';
-    if (x is cps_ir.Primitive) return 'v';
-    if (x is cps_ir.MutableVariable) return 'c';
-    return 'x';
-  }
-
-  String name(x) {
-    String nam = names[x];
-    if (nam == null) {
-      String pref = prefix(x);
-      int id = counters[pref]++;
-      nam = names[x] = '${pref}${id}';
-    }
-    return nam;
-  }
-}
-
-/**
- * A vertex in the graph visualization, used in place of basic blocks.
- */
-class Block {
-  String name;
-  final List<cps_ir.Parameter> parameters;
-  final cps_ir.Expression body;
-  final List<Block> succ = <Block>[];
-  final List<Block> pred = <Block>[];
-
-  Block(this.name, this.parameters, this.body);
-
-  void addEdgeTo(Block successor) {
-    succ.add(successor);
-    successor.pred.add(this);
-  }
-}
-
-class BlockCollector implements cps_ir.Visitor {
-  final Map<cps_ir.Continuation, Block> cont2block =
-      <cps_ir.Continuation, Block>{};
-  final Set<Block> entries = new Set<Block>();
-  Block currentBlock;
-
-  Names names;
-  BlockCollector(this.names);
-
-  Block getBlock(cps_ir.Continuation c) {
-    Block block = cont2block[c];
-    if (block == null) {
-      block = new Block(names.name(c), c.parameters, c.body);
-      cont2block[c] = block;
-    }
-    return block;
-  }
-
-  visit(cps_ir.Node node) => node.accept(this);
-
-  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
-    currentBlock = new Block(names.name(node), [], node.body);
-    entries.add(currentBlock);
-    visit(node.body);
-  }
-
-  visitLetPrim(cps_ir.LetPrim exp) {
-    visit(exp.body);
-  }
-
-  visitLetCont(cps_ir.LetCont exp) {
-    exp.continuations.forEach(visit);
-    visit(exp.body);
-  }
-
-  visitLetHandler(cps_ir.LetHandler exp) {
-    visit(exp.handler);
-    visit(exp.body);
-  }
-
-  visitLetMutable(cps_ir.LetMutable exp) {
-    visit(exp.body);
-  }
-
-  void addEdgeToContinuation(cps_ir.Reference continuation) {
-    cps_ir.Definition target = continuation.definition;
-    if (target is cps_ir.Continuation && !target.isReturnContinuation) {
-      currentBlock.addEdgeTo(getBlock(target));
-    }
-  }
-
-  visitInvokeContinuation(cps_ir.InvokeContinuation exp) {
-    addEdgeToContinuation(exp.continuationRef);
-  }
-
-  visitInvokeStatic(cps_ir.InvokeStatic node) {
-    unexpectedNode(node);
-  }
-
-  visitInvokeMethod(cps_ir.InvokeMethod node) {
-    unexpectedNode(node);
-  }
-
-  visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
-    unexpectedNode(node);
-  }
-
-  visitInvokeConstructor(cps_ir.InvokeConstructor node) {
-    unexpectedNode(node);
-  }
-
-  visitThrow(cps_ir.Throw exp) {}
-
-  visitRethrow(cps_ir.Rethrow exp) {}
-
-  visitUnreachable(cps_ir.Unreachable node) {}
-
-  visitGetLazyStatic(cps_ir.GetLazyStatic node) {
-    unexpectedNode(node);
-  }
-
-  visitBranch(cps_ir.Branch exp) {
-    cps_ir.Continuation trueTarget = exp.trueContinuation;
-    if (!trueTarget.isReturnContinuation) {
-      currentBlock.addEdgeTo(getBlock(trueTarget));
-    }
-    cps_ir.Continuation falseTarget = exp.falseContinuation;
-    if (!falseTarget.isReturnContinuation) {
-      currentBlock.addEdgeTo(getBlock(falseTarget));
-    }
-  }
-
-  visitTypeCast(cps_ir.TypeCast node) {
-    unexpectedNode(node);
-  }
-
-  visitContinuation(cps_ir.Continuation c) {
-    var old_node = currentBlock;
-    currentBlock = getBlock(c);
-    visit(c.body);
-    currentBlock = old_node;
-  }
-
-  // Primitives and conditions are not visited when searching for blocks.
-  unexpectedNode(cps_ir.Node node) {
-    throw "The IR tracer's block collector reached an unexpected IR "
-        "instruction: $node";
-  }
-
-  visitLiteralList(cps_ir.LiteralList node) {
-    unexpectedNode(node);
-  }
-
-  visitConstant(cps_ir.Constant node) {
-    unexpectedNode(node);
-  }
-
-  visitGetMutable(cps_ir.GetMutable node) {
-    unexpectedNode(node);
-  }
-
-  visitParameter(cps_ir.Parameter node) {
-    unexpectedNode(node);
-  }
-
-  visitMutableVariable(cps_ir.MutableVariable node) {
-    unexpectedNode(node);
-  }
-
-  visitGetField(cps_ir.GetField node) {
-    unexpectedNode(node);
-  }
-
-  visitGetStatic(cps_ir.GetStatic node) {
-    unexpectedNode(node);
-  }
-
-  visitCreateBox(cps_ir.CreateBox node) {
-    unexpectedNode(node);
-  }
-
-  visitCreateInstance(cps_ir.CreateInstance node) {
-    unexpectedNode(node);
-  }
-
-  visitInterceptor(cps_ir.Interceptor node) {
-    unexpectedNode(node);
-  }
-
-  visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
-    unexpectedNode(node);
-  }
-
-  visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
-    unexpectedNode(node);
-  }
-
-  visitTypeExpression(cps_ir.TypeExpression node) {
-    unexpectedNode(node);
-  }
-
-  visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
-    unexpectedNode(node);
-  }
-
-  visitTypeTest(cps_ir.TypeTest node) {
-    unexpectedNode(node);
-  }
-
-  visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
-    unexpectedNode(node);
-  }
-
-  visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
-    unexpectedNode(node);
-  }
-
-  visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
-    unexpectedNode(node);
-  }
-
-  visitGetLength(cps_ir.GetLength node) {
-    unexpectedNode(node);
-  }
-
-  visitGetIndex(cps_ir.GetIndex node) {
-    unexpectedNode(node);
-  }
-
-  visitSetIndex(cps_ir.SetIndex node) {
-    unexpectedNode(node);
-  }
-
-  visitSetMutable(cps_ir.SetMutable node) {
-    unexpectedNode(node);
-  }
-
-  visitSetField(cps_ir.SetField node) {
-    unexpectedNode(node);
-  }
-
-  visitSetStatic(cps_ir.SetStatic node) {
-    unexpectedNode(node);
-  }
-
-  visitForeignCode(cps_ir.ForeignCode node) {
-    unexpectedNode(node);
-  }
-
-  visitAwait(cps_ir.Await node) {
-    unexpectedNode(node);
-  }
-
-  visitYield(cps_ir.Yield node) {
-    unexpectedNode(node);
-  }
-
-  visitRefinement(cps_ir.Refinement node) {
-    unexpectedNode(node);
-  }
-
-  visitBoundsCheck(cps_ir.BoundsCheck node) {
-    unexpectedNode(node);
-  }
-
-  visitReceiverCheck(cps_ir.ReceiverCheck 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
deleted file mode 100644
index 60a7977..0000000
--- a/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart
+++ /dev/null
@@ -1,76 +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.eagerly_load_statics;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart' show Pass;
-import '../elements/elements.dart';
-import 'cps_fragment.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 traverseLetPrim(LetPrim node) {
-    Expression next = node.body;
-    visit(node.primitive);
-    return next;
-  }
-
-  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 is GetLazyStatic && initializer.isFinal) {
-      // No reason to create a GetStatic when the field is final.
-      node.replaceWithFragment(new CpsFragment(), initializer);
-    } else if (initializer != null) {
-      GetStatic newNode = new GetStatic.witnessed(node.element, initializer,
-          sourceInformation: node.sourceInformation)..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/effects.dart b/pkg/compiler/lib/src/cps_ir/effects.dart
deleted file mode 100644
index 29d3172..0000000
--- a/pkg/compiler/lib/src/cps_ir/effects.dart
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library dart2js.cps_ir.effects;
-
-import 'dart:typed_data';
-import '../universe/side_effects.dart' show SideEffects;
-
-/// Bitmasks for tracking non-local side effects and dependencies.
-///
-/// All effects must be attributed to an effect area.  The `other` area is a
-/// catch-all for any effect that does not belong to any of the specific areas;
-/// this includes external effects such as printing to the console.
-class Effects {
-  // Effect areas.
-  // These are bit positions, not bit masks. They are private because it is
-  // otherwise easy to mistake them for bitmasks.
-  static const int _staticField = 0;
-  static const int _instanceField = 1;
-  static const int _indexableContent = 2;
-  static const int _indexableLength = 3;
-  static const int _other = 4;
-  static const int numberOfEffectAreas = 5;
-
-  // Bitmasks for computation that modifies state in a given area.
-  static const int _changes = 1;
-  static const int changesStaticField = _changes << _staticField;
-  static const int changesInstanceField = _changes << _instanceField;
-  static const int changesIndexableContent = _changes << _indexableContent;
-  static const int changesIndexableLength = _changes << _indexableLength;
-  static const int changesOther = _changes << _other;
-
-  static const int changesAll = changesStaticField |
-      changesInstanceField |
-      changesIndexableContent |
-      changesIndexableLength |
-      changesOther;
-
-  // Bitmasks for computation that depends on state in a given area.
-  static const int _depends = 1 << numberOfEffectAreas;
-  static const int dependsOnStaticField = _depends << _staticField;
-  static const int dependsOnInstanceField = _depends << _instanceField;
-  static const int dependsOnIndexableContent = _depends << _indexableContent;
-  static const int dependsOnIndexableLength = _depends << _indexableLength;
-  static const int dependsOnOther = _depends << _other;
-
-  static const int dependsOnAll = dependsOnStaticField |
-      dependsOnInstanceField |
-      dependsOnIndexableContent |
-      dependsOnIndexableLength |
-      dependsOnOther;
-
-  static const int all = changesAll | dependsOnAll;
-  static const int none = 0;
-
-  static int _changesArea(int effectArea) => _changes << effectArea;
-
-  static int _dependsOnArea(int effectArea) => _depends << effectArea;
-
-  static int changesToDepends(int changesFlags) {
-    return (changesFlags & changesAll) << numberOfEffectAreas;
-  }
-
-  static int dependsToChanges(int dependsFlags) {
-    return (dependsFlags & dependsOnAll) >> numberOfEffectAreas;
-  }
-
-  /// Converts [SideEffects] from a JS annotation or type inference to the
-  /// more fine-grained flag set.
-  //
-  // TODO(asgerf): Once we finalize the set of flags to use, unify the two
-  //               systems.
-  static int from(SideEffects fx) {
-    int result = 0;
-    if (fx.changesInstanceProperty()) {
-      result |= changesInstanceField;
-    }
-    if (fx.changesStaticProperty()) {
-      result |= changesStaticField;
-    }
-    if (fx.changesIndex()) {
-      result |= changesIndexableContent | changesIndexableLength;
-    }
-    if (fx.hasSideEffects()) {
-      result |= changesOther;
-    }
-    if (fx.dependsOnInstancePropertyStore()) {
-      result |= dependsOnInstanceField;
-    }
-    if (fx.dependsOnStaticPropertyStore()) {
-      result |= dependsOnStaticField;
-    }
-    if (fx.dependsOnIndexStore()) {
-      result |= dependsOnIndexableContent | dependsOnIndexableLength;
-    }
-    if (fx.dependsOnSomething()) {
-      result |= dependsOnOther;
-    }
-    return result;
-  }
-}
-
-/// Creates fresh IDs to ensure effect numbers do not clash with each other.
-class EffectNumberer {
-  int _id = 0;
-  int next() => ++_id;
-
-  /// Special effect number that can be used in place for an effect area that
-  /// is irrelevant for a computation.
-  ///
-  /// This value is never returned by [next].
-  static const int none = 0;
-}
-
-/// A mutable vector of effect numbers, one for each effect area.
-///
-/// Effect numbers are used to identify regions of code wherein the given
-/// effect area is unmodified.
-class EffectNumbers {
-  final Int32List _effectNumbers = new Int32List(Effects.numberOfEffectAreas);
-
-  EffectNumbers._zero();
-
-  EffectNumbers.fresh(EffectNumberer numberer) {
-    reset(numberer);
-  }
-
-  EffectNumbers copy() {
-    return new EffectNumbers._zero().._effectNumbers.setAll(0, _effectNumbers);
-  }
-
-  int operator [](int i) => _effectNumbers[i];
-
-  void operator []=(int i, int value) {
-    _effectNumbers[i] = value;
-  }
-
-  int get staticField => _effectNumbers[Effects._staticField];
-  int get instanceField => _effectNumbers[Effects._instanceField];
-  int get indexableContent => _effectNumbers[Effects._indexableContent];
-  int get indexableLength => _effectNumbers[Effects._indexableLength];
-  int get other => _effectNumbers[Effects._other];
-
-  void set staticField(int n) {
-    _effectNumbers[Effects._staticField] = n;
-  }
-
-  void set instanceField(int n) {
-    _effectNumbers[Effects._instanceField] = n;
-  }
-
-  void set indexableContent(int n) {
-    _effectNumbers[Effects._indexableContent] = n;
-  }
-
-  void set indexableLength(int n) {
-    _effectNumbers[Effects._indexableLength] = n;
-  }
-
-  void set other(int n) {
-    _effectNumbers[Effects._other] = n;
-  }
-
-  void reset(EffectNumberer numberer) {
-    for (int i = 0; i < Effects.numberOfEffectAreas; ++i) {
-      _effectNumbers[i] = numberer.next();
-    }
-  }
-
-  void join(EffectNumberer numberer, EffectNumbers other) {
-    for (int i = 0; i < Effects.numberOfEffectAreas; ++i) {
-      if (_effectNumbers[i] != other._effectNumbers[i]) {
-        _effectNumbers[i] = numberer.next();
-      }
-    }
-  }
-
-  void change(EffectNumberer numberer, int changeFlags) {
-    for (int i = 0; i < Effects.numberOfEffectAreas; ++i) {
-      if (changeFlags & Effects._changesArea(i) != 0) {
-        _effectNumbers[i] = numberer.next();
-      }
-    }
-  }
-
-  /// Builds a vector where all entries that are not depended on are replaced
-  /// by [EffectNumberer.none].
-  //
-  // TODO(asgerf): Use this in GVN to simplify the dispatching code.
-  List<int> getDependencies(int dependsFlags) {
-    Int32List copy = new Int32List.fromList(_effectNumbers);
-    for (int i = 0; i < Effects.numberOfEffectAreas; ++i) {
-      if (dependsFlags & Effects._dependsOnArea(i) == 0) {
-        copy[i] = EffectNumberer.none;
-      }
-    }
-    return copy;
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/finalize.dart b/pkg/compiler/lib/src/cps_ir/finalize.dart
deleted file mode 100644
index e583f49..0000000
--- a/pkg/compiler/lib/src/cps_ir/finalize.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-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';
-import '../js/js.dart' as js;
-
-/// 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)
-        ..destroy();
-      return cps;
-    }
-    Continuation fail = cps.letCont();
-    Primitive index = node.index;
-    if (node.hasIntegerCheck) {
-      cps
-          .ifTruthy(cps.applyBuiltin(
-              BuiltinOperator.IsNotUnsigned32BitInteger, [index, index]))
-          .invokeContinuation(fail);
-    } else if (node.hasLowerBoundCheck) {
-      cps
-          .ifTruthy(
-              cps.applyBuiltin(BuiltinOperator.NumLt, [index, cps.makeZero()]))
-          .invokeContinuation(fail);
-    }
-    if (node.hasUpperBoundCheck) {
-      Primitive length = node.length;
-      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, [index, length]))
-          .invokeContinuation(fail);
-    }
-    if (node.hasEmptinessCheck) {
-      cps
-          .ifTruthy(cps.applyBuiltin(
-              BuiltinOperator.StrictEq, [node.length, cps.makeZero()]))
-          .invokeContinuation(fail);
-    }
-    cps.insideContinuation(fail).invokeStaticThrower(
-        helpers.throwIndexOutOfRangeException, [node.object, index]);
-    node
-      ..replaceUsesWith(node.object)
-      ..destroy();
-    return cps;
-  }
-
-  void visitGetStatic(GetStatic node) {
-    if (node.witnessRef != null) {
-      node
-        ..witnessRef.unlink()
-        ..witnessRef = null;
-    }
-  }
-
-  void visitForeignCode(ForeignCode node) {
-    if (js.isIdentityTemplate(node.codeTemplate)) {
-      // The CPS builder replaces identity templates with refinements, except
-      // when the refined type is an array type.  Some optimizations assume the
-      // type of an object is immutable, but the type of an array can change
-      // after allocation.  After the finalize pass, this assumption is no
-      // longer needed, so we can replace the remaining idenitity templates.
-      Refinement refinement = new Refinement(node.argument(0), node.type)
-        ..type = node.type;
-      node.replaceWith(refinement);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/gvn.dart b/pkg/compiler/lib/src/cps_ir/gvn.dart
deleted file mode 100644
index 8970f5c..0000000
--- a/pkg/compiler/lib/src/cps_ir/gvn.dart
+++ /dev/null
@@ -1,618 +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.gvn;
-
-import 'cps_ir_nodes.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 'type_mask_system.dart';
-import 'effects.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.
-//
-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;
-
-  final EffectNumberer effectNumberer = new EffectNumberer();
-
-  /// Effect numbers at the given join point.
-  Map<Continuation, EffectNumbers> effectsAt = <Continuation, EffectNumbers>{};
-
-  /// The effect numbers at the current position (during traversal).
-  EffectNumbers 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);
-
-  void rewrite(FunctionDefinition node) {
-    effectNumbers = new EffectNumbers.fresh(effectNumberer);
-    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) {
-      addSideEffectsOfPrimitive(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) {
-      addSideEffectsOfPrimitive(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 ReceiverCheck ||
-        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);
-  }
-
-  /// 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;
-    }
-    int effects = loopEffects.getSideEffectsInLoop(loop);
-    return Effects.changesToDepends(effects) & prim.effects == 0;
-  }
-
-  // ------------------ TRAVERSAL AND EFFECT NUMBERING ---------------------
-  //
-  // These methods traverse the IR while updating the current effect numbers.
-  // They are not specific to GVN.
-
-  void addSideEffectsOfPrimitive(Primitive prim) {
-    addSideEffects(prim.effects);
-  }
-
-  void addSideEffects(int effectFlags) {
-    effectNumbers.change(effectNumberer, effectFlags);
-  }
-
-  Expression traverseLetHandler(LetHandler node) {
-    // Assume any kind of side effects may occur in the try block.
-    effectsAt[node.handler] = new EffectNumbers.fresh(effectNumberer);
-    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));
-      pushAction(() {
-        List<int> hoistedBindings = loopHoistedBindings[cont];
-        if (hoistedBindings != null) {
-          hoistedBindings.forEach(environment.remove);
-        }
-      });
-    } else {
-      effectNumbers = effectsAt[cont];
-      assert(effectNumbers != null);
-    }
-
-    return cont.body;
-  }
-
-  void visitInvokeContinuation(InvokeContinuation node) {
-    Continuation cont = node.continuation;
-    if (cont.isRecursive) return;
-    EffectNumbers join = effectsAt[cont];
-    if (join == null) {
-      effectsAt[cont] = effectNumbers.copy();
-    } else {
-      join.join(effectNumberer, effectNumbers);
-    }
-  }
-
-  void visitBranch(Branch node) {
-    Continuation trueCont = node.trueContinuation;
-    Continuation falseCont = node.falseContinuation;
-    // Copy the effect number vector once, so the analysis of one branch does
-    // not influence the other.
-    effectsAt[trueCont] = effectNumbers;
-    effectsAt[falseCont] = effectNumbers.copy();
-  }
-}
-
-/// 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 (node.isFinal) {
-      // 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 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 (node.isFinal) {
-      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 (node.isFinal) {
-      vector = [GvnCode.GET_STATIC, node.element];
-    } else {
-      vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField];
-    }
-    // Suppress visit to witness argument.
-  }
-
-  processGetLazyStatic(GetLazyStatic node) {
-    if (node.isFinal) {
-      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.kind.index, 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
deleted file mode 100644
index 89af4dc..0000000
--- a/pkg/compiler/lib/src/cps_ir/inline.dart
+++ /dev/null
@@ -1,613 +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.inline;
-
-import 'package:js_ast/js_ast.dart' as js;
-
-import '../dart_types.dart' show DartType, GenericType;
-import '../elements/elements.dart';
-import '../js_backend/codegen/task.dart' show CpsFunctionCompiler;
-import '../js_backend/js_backend.dart' show JavaScriptBackend;
-import '../types/types.dart' show TypeMask;
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import '../world.dart' show World;
-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;
-
-/// 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, FunctionDefinition> unoptimized =
-      <ExecutableElement, FunctionDefinition>{};
-
-  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;
-  }
-
-  /// Cache the unoptimized CPS term for a function.
-  ///
-  /// The unoptimized term should not have any inlining-context-specific
-  /// optimizations applied to it.  It will be used to compile the
-  /// non-specialized version of the function.
-  void putUnoptimized(ExecutableElement element, FunctionDefinition function) {
-    unoptimized.putIfAbsent(element, () => copier.copy(function));
-  }
-
-  /// Look up the unoptimized CPS term for a function.
-  ///
-  /// The unoptimized term will not have any inlining-context-specific
-  /// optimizations applied to it.  It can be used to compile the
-  /// non-specialized version of the function.
-  FunctionDefinition getUnoptimized(ExecutableElement element) {
-    FunctionDefinition function = unoptimized[element];
-    if (function != null) {
-      function = copier.copy(function);
-      ParentVisitor.setParents(function);
-    }
-    return function;
-  }
-}
-
-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) {
-    if (element is ConstructorBodyElement) {
-      ClassElement class_ = element.enclosingClass;
-      return !functionCompiler.compiler.world.hasAnyStrictSubclass(class_) &&
-              class_.constructors.tail?.isEmpty ??
-          false;
-    }
-    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.kind == ResolvedAstKind.PARSED &&
-        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(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.hasExactlyOneUse && parameter.hasNoUses) {
-      --size;
-    }
-  }
-
-  static int sizeOf(InvocationPrimitive invoke, FunctionDefinition function) {
-    SizeVisitor visitor = new SizeVisitor();
-    visitor.visit(function);
-    if (invoke.callingConvention == CallingConvention.Intercepted) {
-      // Note that if the invocation is a dummy-intercepted call, then the
-      // target has an unused interceptor parameter, but the caller provides
-      // no interceptor argument.
-      visitor.countArgument(invoke.interceptor, function.interceptorParameter);
-    }
-    visitor.countArgument(invoke.receiver, function.receiverParameter);
-    for (int i = 0; i < invoke.argumentRefs.length; ++i) {
-      visitor.countArgument(invoke.argument(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) => ++size;
-  processLetMutable(LetMutable node) => ++size;
-  processBranch(Branch node) => ++size;
-  processThrow(Throw nose) => ++size;
-  processRethrow(Rethrow node) => ++size;
-
-  // Discount primitives that do not generate code.
-  processRefinement(Refinement node) => --size;
-  processBoundsCheck(BoundsCheck node) {
-    if (node.hasNoChecks) {
-      --size;
-    }
-  }
-
-  processForeignCode(ForeignCode node) {
-    // Count the number of nodes in the JS fragment, and discount the size
-    // originally added by LetPrim.
-    JsSizeVisitor visitor = new JsSizeVisitor();
-    node.codeTemplate.ast.accept(visitor);
-    size += visitor.size - 1;
-  }
-}
-
-class JsSizeVisitor extends js.BaseVisitor {
-  int size = 0;
-
-  visitNode(js.Node node) {
-    ++size;
-    return super.visitNode(node);
-  }
-
-  visitInterpolatedExpression(js.InterpolatedExpression node) {
-    // Suppress call to visitNode.  Placeholders should not be counted, because
-    // the argument has already been counted, and will in most cases be inserted
-    // directly in the placeholder.
-  }
-}
-
-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(Primitive def) {
-    return def.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.type;
-    Parameter interceptorParameter =
-        node.interceptorRef != null ? new Parameter(null) : null;
-    List<Parameter> parameters =
-        new List<Parameter>.generate(node.argumentRefs.length, (int index) {
-      // TODO(kmillikin): Use a hint for the parameter names.
-      return new Parameter(null)..type = node.argument(index).type;
-    });
-    Continuation returnContinuation = new Continuation.retrn();
-    CpsFragment cps = new CpsFragment();
-
-    FunctionSignature signature = target.functionSignature;
-    int requiredParameterCount = signature.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.getConstantValue(formal.constant));
-          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.getConstantValue(formal.constant));
-          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,
-        interceptor: interceptorParameter,
-        callingConvention: node.callingConvention);
-    result.type = typeSystem.getInvokeReturnType(node.selector, node.mask);
-    returnContinuation.parameters.single.type = result.type;
-    cps.invokeContinuation(returnContinuation, <Primitive>[result]);
-    return new FunctionDefinition(
-        target, thisParameter, parameters, returnContinuation, cps.root,
-        interceptorParameter: interceptorParameter);
-  }
-
-  // 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 (backend.isJsInterop(target)) 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;
-    }
-
-    // Don't inline methods that never return. They are usually helper functions
-    // that throw an exception.
-    if (invoke.type.isEmpty) {
-      // TODO(sra): It would be ok to inline if doing so was shrinking.
-      return null;
-    }
-
-    if (isBlacklisted(target)) return null;
-
-    if (invoke.callingConvention == CallingConvention.OneShotIntercepted) {
-      // One-shot interceptor calls with a known target are only inserted on
-      // uncommon code paths, so they should not be inlined.
-      return null;
-    }
-
-    Primitive receiver = invoke.receiver;
-    TypeMask abstractReceiver =
-        receiver == null ? null : abstractType(receiver);
-    // 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.isEmptyOrNull
-            ? 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;
-      List<Primitive> arguments = invoke.arguments.toList();
-      // Add a null check to the inlined function body if necessary.  The
-      // cached function body does not contain the null check.
-      if (receiver != null && abstractReceiver.isNullable) {
-        receiver =
-            nullReceiverGuard(invoke, _fragment, receiver, abstractReceiver);
-      }
-      return _fragment.inlineFunction(function, receiver, arguments,
-          interceptor: invoke.interceptor, 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.
-      if (backend.isNative(target)) {
-        // TODO(25548): Generate correct adaptor for native methods.
-        return doNotInline();
-      } else {
-        function = buildAdapter(invoke, target);
-      }
-    } else {
-      function = compileToCpsIr(target);
-      if (function.receiverParameter != null) {
-        function.receiverParameter.type = abstractReceiverInMethod;
-      }
-      for (int i = 0; i < invoke.argumentRefs.length; ++i) {
-        function.parameters[i].type = invoke.argument(i).type;
-      }
-      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) {
-    if (invoke is! InvokeMethod) return dartReceiver;
-    InvokeMethod invokeMethod = invoke;
-    Selector selector = invokeMethod.selector;
-    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 ReceiverCheck.nullCheck(
-          dartReceiver, selector, invoke.sourceInformation,
-          condition: condition));
-      check.type = abstractReceiver.nonNullable();
-      return check;
-    }
-
-    Primitive check = _fragment.letPrim(new ReceiverCheck.nullCheck(
-        dartReceiver, selector, invoke.sourceInformation));
-    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.receiver;
-    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);
-  }
-
-  bool isBlacklisted(FunctionElement target) {
-    ClassElement enclosingClass = target.enclosingClass;
-    if (target.isOperator &&
-        (enclosingClass == backend.helpers.jsNumberClass ||
-            enclosingClass == backend.helpers.jsDoubleClass ||
-            enclosingClass == backend.helpers.jsIntClass)) {
-      // These should be handled by operator specialization.
-      return true;
-    }
-    if (target == backend.helpers.stringInterpolationHelper) return true;
-    return false;
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart b/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
deleted file mode 100644
index 28d013f..0000000
--- a/pkg/compiler/lib/src/cps_ir/insert_refinements.dart
+++ /dev/null
@@ -1,424 +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.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
-/// type analysis in the [TypePropagator] pass.
-///
-/// Refinement nodes are inserted at the arms of a [Branch] node with a
-/// condition of form `x is T` or `x == null`.
-///
-/// Refinement nodes are inserted after a method invocation to refine the
-/// receiver to the types that can respond to the given selector.
-class InsertRefinements extends TrampolineRecursiveVisitor implements Pass {
-  String get passName => 'Insert refinement nodes';
-
-  final TypeMaskSystem types;
-
-  /// Maps unrefined primitives to its refinement currently in scope (if any).
-  final Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{};
-
-  InsertRefinements(this.types);
-
-  void rewrite(FunctionDefinition node) {
-    visit(node.body);
-  }
-
-  /// Updates references to refer to the refinement currently in scope.
-  void processReference(Reference node) {
-    Definition definition = node.definition;
-    if (definition is Primitive) {
-      Primitive prim = definition.effectiveDefinition;
-      Refinement refined = refinementFor[prim];
-      if (refined != null && refined != definition) {
-        node.changeTo(refined);
-      }
-    }
-  }
-
-  /// Sinks the binding of [cont] to immediately above [use].
-  ///
-  /// This is used to ensure that everything in scope at [use] is also in scope
-  /// inside [cont], so refinements can be inserted inside [cont] without
-  /// accidentally referencing a primitive out of scope.
-  ///
-  /// It is always safe to do this for single-use continuations, because
-  /// strictly more things are in scope at the use site, and there can't be any
-  /// other use of [cont] that might fall out of scope since there is only
-  /// that single use.
-  void sinkContinuationToUse(Continuation cont, Expression use) {
-    assert(cont.hasExactlyOneUse && cont.firstRef.parent == use);
-    assert(!cont.isRecursive);
-    LetCont let = cont.parent;
-    InteriorNode useParent = use.parent;
-    if (useParent == let) return;
-    if (let.continuations.length > 1) {
-      // Create a new LetCont binding only this continuation.
-      let.continuations.remove(cont);
-      let = new LetCont(cont, null);
-    } else {
-      let.remove(); // Reuse the existing LetCont.
-    }
-    let.insertAbove(use);
-  }
-
-  /// 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) {
-        // Clean up refinements that are not used.
-        refined.destroy();
-      } else {
-        LetPrim let = new LetPrim(refined);
-        let.insertBelow(insertionParent);
-      }
-    });
-  }
-
-  /// 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.argumentRefs.length);
-    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.argument(i), argSuccessType));
-    }
-  }
-
-  void visitInvokeStatic(InvokeStatic node) {
-    node.argumentRefs.forEach(processReference);
-    _refineArguments(node, _getSuccessTypesForStaticMethod(types, node.target));
-  }
-
-  void visitInvokeMethod(InvokeMethod node) {
-    // Update references to their current refined values.
-    processReference(node.receiverRef);
-    node.argumentRefs.forEach(processReference);
-
-    // If the call is intercepted, we want to refine the actual receiver,
-    // not the interceptor.
-    Primitive receiver = node.receiver;
-
-    // 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(selector, node.mask);
-      Refinement refinement = new Refinement(receiver, type);
-      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));
-    }
-  }
-
-  void visitTypeCast(TypeCast node) {
-    Primitive value = node.value;
-
-    processReference(node.valueRef);
-    node.typeArgumentRefs.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) {
-    return prim is Constant && prim.value.isTrue;
-  }
-
-  void visitBranch(Branch node) {
-    processReference(node.conditionRef);
-    Primitive condition = node.condition;
-
-    Continuation trueCont = node.trueContinuation;
-    Continuation falseCont = node.falseContinuation;
-
-    // Sink both continuations to the Branch to ensure everything in scope
-    // here is also in scope inside the continuations.
-    sinkContinuationToUse(trueCont, node);
-    sinkContinuationToUse(falseCont, node);
-
-    // If the condition is an 'is' check, promote the checked value.
-    if (condition is TypeTest) {
-      Primitive value = condition.value;
-      TypeMask type = types.subtypesOf(condition.dartType);
-      Primitive refinedValue = new Refinement(value, type);
-      pushRefinement(trueCont, refinedValue);
-      push(falseCont);
-      return;
-    }
-
-    // If the condition is comparison with a constant, promote the other value.
-    // This can happen either for calls to `==` or `identical` calls, such
-    // as the ones inserted by the unsugaring pass.
-
-    void refineEquality(Primitive first, Primitive second,
-        Continuation trueCont, Continuation falseCont) {
-      if (second is Constant && second.value.isNull) {
-        Refinement refinedTrue = new Refinement(first, types.nullType);
-        Refinement refinedFalse = new Refinement(first, types.nonNullType);
-        pushRefinement(trueCont, refinedTrue);
-        pushRefinement(falseCont, refinedFalse);
-      } else if (first is Constant && first.value.isNull) {
-        Refinement refinedTrue = new Refinement(second, types.nullType);
-        Refinement refinedFalse = new Refinement(second, types.nonNullType);
-        pushRefinement(trueCont, refinedTrue);
-        pushRefinement(falseCont, refinedFalse);
-      } else {
-        push(trueCont);
-        push(falseCont);
-      }
-    }
-
-    if (condition is InvokeMethod && condition.selector == Selectors.equals) {
-      refineEquality(
-          condition.receiver, condition.argument(0), trueCont, falseCont);
-      return;
-    }
-
-    if (condition is ApplyBuiltinOperator &&
-        condition.operator == BuiltinOperator.Identical) {
-      refineEquality(
-          condition.argument(0), condition.argument(1), trueCont, falseCont);
-      return;
-    }
-
-    push(trueCont);
-    push(falseCont);
-  }
-
-  @override
-  Expression traverseLetCont(LetCont node) {
-    for (Continuation cont in node.continuations) {
-      // 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
deleted file mode 100644
index d7c3c6f..0000000
--- a/pkg/compiler/lib/src/cps_ir/loop_effects.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-library dart2js.cps_ir.loop_effects;
-
-import 'cps_ir_nodes.dart';
-import 'loop_hierarchy.dart';
-import '../world.dart';
-import 'effects.dart';
-
-/// Determines the side effects that may occur in each loop.
-class LoopSideEffects extends TrampolineRecursiveVisitor {
-  LoopHierarchy loopHierarchy;
-  final World world;
-  final Map<Continuation, List<Continuation>> exitContinuations = {};
-  final Map<Continuation, int> loopSideEffects = {};
-  Continuation currentLoopHeader;
-
-  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.
-  int 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 changesIndexableLength(Continuation loop) {
-    return loopSideEffects[loop] & Effects.changesIndexableLength != 0;
-  }
-
-  @override
-  Expression traverseContinuation(Continuation cont) {
-    if (cont.isRecursive) {
-      loopSideEffects[cont] = Effects.none;
-      exitContinuations[cont] = <Continuation>[];
-      pushAction(() {
-        if (currentLoopHeader != null) {
-          loopSideEffects[currentLoopHeader] |= loopSideEffects[cont];
-        }
-        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;
-  }
-
-  @override
-  Expression traverseLetPrim(LetPrim node) {
-    if (currentLoopHeader != null) {
-      loopSideEffects[currentLoopHeader] |= node.primitive.effects;
-    }
-    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);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart b/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
deleted file mode 100644
index 60129af..0000000
--- a/pkg/compiler/lib/src/cps_ir/loop_hierarchy.dart
+++ /dev/null
@@ -1,175 +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.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
-/// 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>)
-///       <loop body>
-///       InvokeContinuation kont x'
-///     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 {
-  /// Nesting depth of the given loop.
-  Map<Continuation, int> loopDepth = <Continuation, int>{};
-
-  /// The innermost loop (other than itself) that may be invoked recursively
-  /// as a result of invoking the given continuation.
-  Map<Continuation, Continuation> loopTarget = <Continuation, Continuation>{};
-
-  /// Current nesting depth.
-  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);
-  }
-
-  /// Returns the innermost loop which [cont] is effectively part of.
-  Continuation getLoopHeader(Continuation cont) {
-    return cont.isRecursive ? cont : loopTarget[cont];
-  }
-
-  /// Returns the innermost loop which the given continuation is part of, other
-  /// than itself.
-  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
-  /// both be in scope at that point.
-  Continuation _markInnerLoop(Continuation c1, Continuation c2) {
-    assert(c1 == null || c1.isRecursive);
-    assert(c2 == null || c2.isRecursive);
-    if (c1 == null) return c2;
-    if (c2 == null) return c1;
-    if (c1 == c2) return c1;
-    if (loopDepth[c1] > loopDepth[c2]) {
-      loopTarget[c1] = _markInnerLoop(loopTarget[c1], c2);
-      return c1;
-    } else {
-      loopTarget[c2] = _markInnerLoop(loopTarget[c2], c1);
-      return c2;
-    }
-  }
-
-  /// 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;
-      Continuation target = _processBlock(cont.body, catchLoop);
-      _markInnerLoop(loopTarget[cont], target);
-      --_currentDepth;
-    } else {
-      loopTarget[cont] = _processBlock(cont.body, catchLoop);
-    }
-    return loopTarget[cont];
-  }
-
-  /// Analyzes a basic block and returns the innermost loop that
-  /// can be invoked recursively from that block.
-  Continuation _processBlock(Expression node, Continuation catchLoop) {
-    for (; node != null && node is! TailExpression; node = node.next) {
-      if (node is LetCont) {
-        for (Continuation cont in node.continuations) {
-          _processContinuation(cont, catchLoop);
-        }
-      } else if (node is LetHandler) {
-        catchLoop = _processContinuation(node.handler, catchLoop);
-      }
-    }
-    Continuation target;
-    if (node is InvokeContinuation) {
-      if (node.isRecursive) {
-        target = node.continuation;
-      } else {
-        target = loopTarget[node.continuation];
-      }
-    } else if (node is Branch) {
-      target = _markInnerLoop(loopTarget[node.trueContinuation],
-          loopTarget[node.falseContinuation]);
-    } 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 || node == null);
-    }
-    return _markInnerLoop(target, catchLoop);
-  }
-
-  /// Returns 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 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
deleted file mode 100644
index 95ee597..0000000
--- a/pkg/compiler/lib/src/cps_ir/loop_invariant_branch.dart
+++ /dev/null
@@ -1,252 +0,0 @@
-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.argumentRefs
-              .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;
-    if (loopHeaderFor[condition] == loop) return false;
-
-    Continuation trueCont = branch.trueContinuation;
-    Continuation falseCont = branch.falseContinuation;
-    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.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
deleted file mode 100644
index ee44978..0000000
--- a/pkg/compiler/lib/src/cps_ir/mutable_ssa.dart
+++ /dev/null
@@ -1,247 +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.mutable_ssa;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-
-/// Determines which mutable variables should be rewritten to phi assignments
-/// in this pass.
-///
-/// We do not rewrite variables that have an assignment inside a try block that
-/// does not contain its declaration.
-class MutableVariablePreanalysis extends TrampolineRecursiveVisitor {
-  // Number of try blocks enclosing the current position.
-  int currentDepth = 0;
-
-  /// Number of try blocks enclosing the declaration of a given mutable
-  /// variable.
-  ///
-  /// All mutable variables seen will be present in the map after the analysis.
-  Map<MutableVariable, int> variableDepth = <MutableVariable, int>{};
-
-  /// Variables with an assignment inside a try block that does not contain
-  /// its declaration.
-  Set<MutableVariable> hasAssignmentInTry = new Set<MutableVariable>();
-
-  @override
-  Expression traverseLetHandler(LetHandler node) {
-    push(node.handler);
-    ++currentDepth;
-    pushAction(() => --currentDepth);
-    return node.body;
-  }
-
-  void processLetMutable(LetMutable node) {
-    variableDepth[node.variable] = currentDepth;
-  }
-
-  void processSetMutable(SetMutable node) {
-    MutableVariable variable = node.variable;
-    if (currentDepth > variableDepth[variable]) {
-      hasAssignmentInTry.add(variable);
-    }
-  }
-
-  /// True if there are no mutable variables or they are all assigned inside
-  /// a try block. In this case, there is nothing to do and the pass should
-  /// be skipped.
-  bool get allMutablesAreAssignedInTryBlocks {
-    return hasAssignmentInTry.length == variableDepth.length;
-  }
-}
-
-/// Replaces mutable variables with continuation parameters, effectively
-/// bringing them into SSA form.
-///
-/// This pass is intended to clean up mutable variables that were introduced
-/// by an optimization in the type propagation pass.
-///
-/// This implementation potentially creates a lot of redundant and dead phi
-/// parameters. These will be cleaned up by redundant phi elimination and
-/// shrinking reductions.
-///
-/// Discussion:
-/// For methods with a lot of mutable variables, creating all the spurious
-/// parameters might be too expensive. If this is the case, we should
-/// improve this pass to avoid most spurious parameters in practice.
-class MutableVariableEliminator implements Pass {
-  String get passName => 'Mutable variable elimination';
-
-  /// Mutable variables currently in scope, in order of declaration.
-  /// This list determines the order of the corresponding phi parameters.
-  final List<MutableVariable> mutableVariables = <MutableVariable>[];
-
-  /// Number of phi parameters added to the given continuation.
-  final Map<Continuation, int> continuationPhiCount = <Continuation, int>{};
-
-  /// Stack of yet unprocessed continuations interleaved with the
-  /// mutable variables currently in scope.
-  ///
-  /// Continuations are processed when taken off the stack and mutable
-  /// variables fall out of scope (i.e. removed from [mutableVariables]) when
-  /// taken off the stack.
-  final List<StackItem> stack = <StackItem>[];
-
-  MutableVariablePreanalysis analysis;
-
-  void rewrite(FunctionDefinition node) {
-    analysis = new MutableVariablePreanalysis()..visit(node);
-    if (analysis.allMutablesAreAssignedInTryBlocks) {
-      // Skip the pass if there is nothing to do.
-      return;
-    }
-    processBlock(node.body, <MutableVariable, Primitive>{});
-    while (stack.isNotEmpty) {
-      StackItem item = stack.removeLast();
-      if (item is ContinuationItem) {
-        processBlock(item.continuation.body, item.environment);
-      } else {
-        assert(item is VariableItem);
-        mutableVariables.removeLast();
-      }
-    }
-  }
-
-  bool shouldRewrite(MutableVariable variable) {
-    return !analysis.hasAssignmentInTry.contains(variable);
-  }
-
-  bool isJoinContinuation(Continuation cont) {
-    return !cont.hasExactlyOneUse || cont.firstRef.parent is InvokeContinuation;
-  }
-
-  /// If some useful source information is attached to exactly one of the
-  /// two definitions, the information is copied onto the other.
-  void mergeHints(MutableVariable variable, Primitive value) {
-    if (variable.hint == null) {
-      variable.hint = value.hint;
-    } else if (value.hint == null) {
-      value.hint = variable.hint;
-    }
-  }
-
-  /// Processes a basic block, replacing mutable variable uses with direct
-  /// references to their values.
-  ///
-  /// [environment] is the current value of each mutable variable. The map
-  /// will be mutated during the processing.
-  ///
-  /// Continuations to be processed are put on the stack for later processing.
-  void processBlock(
-      Expression node, Map<MutableVariable, Primitive> environment) {
-    Expression next = node.next;
-    for (; node is! TailExpression; node = next, next = node.next) {
-      if (node is LetMutable && shouldRewrite(node.variable)) {
-        // Put the new mutable variable on the stack while processing the body,
-        // and pop it off again when done with the body.
-        mutableVariables.add(node.variable);
-        stack.add(new VariableItem());
-
-        // Put the initial value into the environment.
-        Primitive value = node.value;
-        environment[node.variable] = value;
-
-        // Preserve variable names.
-        mergeHints(node.variable, value);
-
-        // Remove the mutable variable binding.
-        node.valueRef.unlink();
-        node.remove();
-      } else if (node is LetPrim && node.primitive is SetMutable) {
-        SetMutable setter = node.primitive;
-        MutableVariable variable = setter.variable;
-        if (shouldRewrite(variable)) {
-          // As above, update the environment, preserve variables and remove
-          // the mutable variable assignment.
-          environment[variable] = setter.value;
-          mergeHints(variable, setter.value);
-          setter.valueRef.unlink();
-          node.remove();
-        }
-      } else if (node is LetPrim && node.primitive is GetMutable) {
-        GetMutable getter = node.primitive;
-        MutableVariable variable = getter.variable;
-        if (shouldRewrite(variable)) {
-          // Replace with the reaching definition from the environment.
-          Primitive value = environment[variable];
-          getter.replaceUsesWith(value);
-          mergeHints(variable, value);
-          node.remove();
-        }
-      } else if (node is LetCont) {
-        // Create phi parameters for each join continuation bound here, and put
-        // them on the stack for later processing.
-        // Note that non-join continuations are handled at the use-site.
-        for (Continuation cont in node.continuations) {
-          if (!isJoinContinuation(cont)) continue;
-          // Create a phi parameter for every mutable variable in scope.
-          // At the same time, build the environment to use for processing
-          // the continuation (mapping mutables to phi parameters).
-          continuationPhiCount[cont] = mutableVariables.length;
-          Map<MutableVariable, Primitive> environment =
-              <MutableVariable, Primitive>{};
-          for (MutableVariable variable in mutableVariables) {
-            Parameter phi = new Parameter(variable.hint);
-            phi.type = variable.type;
-            cont.parameters.add(phi);
-            phi.parent = cont;
-            environment[variable] = phi;
-          }
-          stack.add(new ContinuationItem(cont, environment));
-        }
-      } else if (node is LetHandler) {
-        // Process the catch block later and continue into the try block.
-        // We can use the same environment object for the try and catch blocks.
-        // The current environment bindings cannot change inside the try block
-        // because we exclude all variables assigned inside a try block.
-        // The environment might be extended with more bindings before we
-        // analyze the catch block, but that's ok.
-        stack.add(new ContinuationItem(node.handler, environment));
-      }
-    }
-
-    // Analyze the terminal node.
-    if (node is InvokeContinuation) {
-      Continuation cont = node.continuation;
-      if (cont.isReturnContinuation) return;
-      // This is a call to a join continuation. Add arguments for the phi
-      // parameters that were added to this continuation.
-      int phiCount = continuationPhiCount[cont];
-      for (int i = 0; i < phiCount; ++i) {
-        Primitive value = environment[mutableVariables[i]];
-        Reference<Primitive> arg = new Reference<Primitive>(value);
-        node.argumentRefs.add(arg);
-        arg.parent = node;
-      }
-    } else if (node is Branch) {
-      // Enqueue both branches with the current environment.
-      // Clone the environments once so the processing of one branch does not
-      // mutate the environment needed to process the other branch.
-      stack.add(new ContinuationItem(node.trueContinuation,
-          new Map<MutableVariable, Primitive>.from(environment)));
-      stack.add(new ContinuationItem(node.falseContinuation, environment));
-    } else {
-      assert(node is Throw || node is Unreachable);
-    }
-  }
-}
-
-abstract class StackItem {}
-
-/// Represents a mutable variable that is in scope.
-///
-/// The topmost mutable variable falls out of scope when this item is
-/// taken off the stack.
-class VariableItem extends StackItem {}
-
-/// Represents a yet unprocessed continuation together with the
-/// environment in which to process it.
-class ContinuationItem extends StackItem {
-  final Continuation continuation;
-  final Map<MutableVariable, Primitive> environment;
-
-  ContinuationItem(this.continuation, this.environment);
-}
diff --git a/pkg/compiler/lib/src/cps_ir/octagon.dart b/pkg/compiler/lib/src/cps_ir/octagon.dart
deleted file mode 100644
index 83feb77..0000000
--- a/pkg/compiler/lib/src/cps_ir/octagon.dart
+++ /dev/null
@@ -1,197 +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.octagon;
-
-import 'dart:collection';
-
-/// For every variable in the constraint system, two [SignedVariable]s exist,
-/// representing the positive and negative uses of the variable.
-///
-/// For instance, `v1 - v2` is represented as `v1 + (-v2)`, with -v2 being
-/// a "negative use" of v2.
-class SignedVariable {
-  /// Negated version of this variable.
-  SignedVariable _negated;
-  SignedVariable get negated => _negated;
-
-  /// Constraints that mention this signed variable.
-  final List<Constraint> _constraints = <Constraint>[];
-
-  static int _hashCount = 0;
-  final int hashCode = (_hashCount = _hashCount + 1) & 0x0fffffff;
-
-  SignedVariable._make() {
-    _negated = new SignedVariable._makeTwin(this);
-  }
-
-  SignedVariable._makeTwin(this._negated);
-}
-
-/// A constraint of form `v1 + v2 <= k`.
-class Constraint {
-  final SignedVariable v1, v2;
-  final int bound;
-
-  Constraint(this.v1, this.v2, this.bound);
-}
-
-/// A system of constraints of form `v1 + v2 <= k`.
-///
-/// Constraints can be added and removed in stack-order.  The octagon will
-/// always determine whether it is in a solvable state, but will otherwise
-/// not optimize its internal representation.
-///
-/// There is currently no support for querying the upper and lower bounds
-/// of a variable, (which can be used to approximate ternary constraints
-/// `v1 + v2 + v3 <= k`), but it is something we could consider adding.
-class Octagon {
-  /// Number of constraints that have been added since the constraint system
-  /// became unsolvable (including the constraint that made it unsolvable).
-  ///
-  /// This is well-defined because constraints are pushed/popped in stack order.
-  int _unsolvableCounter = 0;
-
-  /// True if the constraint system is unsolvable in its current state.
-  ///
-  /// It will remain unsolvable until a number of constraints have been popped.
-  bool get isUnsolvable => _unsolvableCounter > 0;
-
-  /// True if the constraint system is solvable in its current state.
-  bool get isSolvable => _unsolvableCounter == 0;
-
-  /// Make a new variable, optionally with known lower and upper bounds
-  /// (both inclusive).
-  ///
-  /// The constraints generated for [min] and [max] are also expressible using
-  /// [Constraint] objects, but the constraints added in [makeVariable] live
-  /// outside the stack discipline (i.e. the bounds are never popped), which is
-  /// useful when generating variables on-the-fly.
-  SignedVariable makeVariable([int min, int max]) {
-    SignedVariable v1 = new SignedVariable._make();
-    if (min != null) {
-      // v1 >= min   <==>   -v1 - v1 <= -2 * min
-      v1.negated._constraints
-          .add(new Constraint(v1.negated, v1.negated, -2 * min));
-    }
-    if (max != null) {
-      // v1 <= max   <==>   v1 + v1 <= 2 * max
-      v1._constraints.add(new Constraint(v1, v1, 2 * max));
-    }
-    return v1;
-  }
-
-  /// Add the constraint `v1 + v2 <= k`.
-  ///
-  /// The constraint should be removed again using [popConstraint].
-  void pushConstraint(Constraint constraint) {
-    if (_unsolvableCounter > 0 ||
-        _unsolvableCounter == 0 && _checkUnsolvable(constraint)) {
-      ++_unsolvableCounter;
-    }
-    constraint.v1._constraints.add(constraint);
-    if (constraint.v1 != constraint.v2) {
-      constraint.v2._constraints.add(constraint);
-    }
-  }
-
-  /// Remove a constraint that was previously added with [pushConstraint].
-  ///
-  /// Constraints must be added and removed in stack-order.
-  void popConstraint(Constraint constraint) {
-    assert(constraint.v1._constraints.last == constraint);
-    assert(constraint.v2._constraints.last == constraint);
-    constraint.v1._constraints.removeLast();
-    if (constraint.v1 != constraint.v2) {
-      constraint.v2._constraints.removeLast();
-    }
-    if (_unsolvableCounter > 0) {
-      --_unsolvableCounter;
-    }
-  }
-
-  /// Return true if [constraint] would make the constraint system unsolvable.
-  ///
-  /// Assumes the system is currently solvable.
-  bool _checkUnsolvable(Constraint constraint) {
-    // Constraints are transitively composed like so:
-    //    v1 + v2 <= k1
-    //   -v2 + v3 <= k2
-    // implies:
-    //    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`.
-    //
-    // 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).
-
-    // Check if a negative-weight cycle would be created by adding [constraint].
-    int length = _cycleLength(constraint);
-    return length != null && length < 0;
-  }
-
-  /// 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);
-      }
-    }
-    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);
-        }
-      }
-    }
-    // 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
deleted file mode 100644
index 65500a5..0000000
--- a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
+++ /dev/null
@@ -1,327 +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.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.receiver.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.interceptorRef != 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.receiver.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;
-    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;
-    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.interceptor;
-    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.makeOneShotIntercepted();
-  }
-
-  @override
-  void visitTypeTestViaFlag(TypeTestViaFlag node) {
-    Primitive interceptor = node.interceptor;
-    if (interceptor is! Interceptor ||
-        interceptor.hasMultipleUses ||
-        loopHeaderFor[interceptor] != currentLoopHeader ||
-        !backend.mayGenerateInstanceofCheck(node.dartType)) {
-      return;
-    }
-    Interceptor inter = interceptor;
-    Primitive value = inter.input;
-    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
deleted file mode 100644
index 8af5154..0000000
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.cps_ir.optimizers;
-
-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;
-export 'redundant_phi.dart' show RedundantPhiEliminator;
-export 'redundant_join.dart' show RedundantJoinEliminator;
-export 'shrinking_reductions.dart' show ShrinkingReducer;
-export 'mutable_ssa.dart' show MutableVariableEliminator;
-export 'insert_refinements.dart' show InsertRefinements;
-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 'path_based_optimizer.dart' show PathBasedOptimizer;
-export 'use_field_initializers.dart' show UseFieldInitializers;
-export 'parent_visitor.dart' show ParentVisitor;
-
-/// An optimization pass over the CPS IR.
-abstract class Pass {
-  /// Applies optimizations to root, rewriting it in the process.
-  void rewrite(FunctionDefinition root);
-
-  String get passName;
-}
-
-// Shared code between optimizations
-
-/// Returns true if [value] is false, null, 0, -0, NaN, or the empty string.
-bool isFalsyConstant(ConstantValue value) {
-  return value.isFalse ||
-      value.isNull ||
-      value.isZero ||
-      value.isMinusZero ||
-      value.isNaN ||
-      value is StringConstantValue && value.primitiveValue.isEmpty;
-}
-
-/// Returns true if [value] satisfies a branching condition with the
-/// given strictness.
-///
-/// For non-strict, this is the opposite of [isFalsyConstant].
-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/parent_visitor.dart b/pkg/compiler/lib/src/cps_ir/parent_visitor.dart
deleted file mode 100644
index bb98c33..0000000
--- a/pkg/compiler/lib/src/cps_ir/parent_visitor.dart
+++ /dev/null
@@ -1,42 +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.parent_visitor;
-
-import 'cps_ir_nodes.dart';
-
-/// Traverses the CPS term and sets node.parent for each visited node.
-class ParentVisitor extends DeepRecursiveVisitor {
-  static void setParents(Node node) {
-    ParentVisitor visitor = new ParentVisitor._make();
-    visitor._worklist.add(node);
-    visitor.trampoline();
-  }
-
-  /// Private to avoid accidental `new ParentVisitor().visit(node)` calls.
-  ParentVisitor._make();
-
-  Node _parent;
-  final List<Node> _worklist = <Node>[];
-
-  void trampoline() {
-    while (_worklist.isNotEmpty) {
-      _parent = _worklist.removeLast();
-      _parent.accept(this);
-    }
-  }
-
-  @override
-  visit(Node node) {
-    _worklist.add(node);
-    assert(_parent != node);
-    assert(_parent != null);
-    node.parent = _parent;
-  }
-
-  @override
-  processReference(Reference node) {
-    node.parent = _parent;
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart b/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
deleted file mode 100644
index 933111e..0000000
--- a/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library dart2js.cps_ir.path_based_optimizer;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-import 'cps_fragment.dart';
-import '../js_backend/js_backend.dart';
-import 'type_mask_system.dart';
-
-/// Optimizations based on intraprocedural forward dataflow analysis, taking
-/// into account path information that is not expressed by [Refinement] nodes.
-///
-/// ---
-///
-/// Removes branches that branch on the same value as a previously seen branch.
-/// For example:
-///
-///     if (x == y) {
-///       if (x == y) TRUE else FALSE
-///     }
-///
-/// ==> ([GVN] pass merges identical expressions)
-///
-///     var b = (x == y)
-///     if (b) {
-///       if (b) TRUE else FALSE
-///     }
-///
-///  ==> (this pass removes the duplicate branch)
-///
-///     var b = (x == y)
-///     if (b) {
-///       TRUE
-///     }
-///
-/// ---
-///
-/// Removes interceptors for method calls whose receiver is known to be a
-/// self-interceptor. For example:
-///
-///     x.foo$1();
-///     getInterceptor(x).$eq(x, y);
-///
-/// ==> (`x` is a self-interceptor, remove the `getInterceptor` call)
-///
-///     x.foo$1();
-///     x.$eq(0, y);
-///
-/// Although there is a [Refinement] node after the call to `x.foo$1()`, the
-/// refined type cannot always be represented exactly, and type propagation
-/// may therefore not see that `x` is a self-interceptor.
-//
-// TODO(asgerf): A kind of redundant join can arise where a branching condition
-// is known to be true/false on all but one predecessor for a branch. We could
-// try to reduce those.
-//
-// TODO(asgerf): Could be more precise if GVN shared expressions that are not
-// in direct scope of one another, e.g. by using phis pass the shared value.
-//
-class PathBasedOptimizer extends TrampolineRecursiveVisitor implements Pass {
-  String get passName => 'Path-based optimizations';
-
-  // Classification of all values.
-  static const int TRUE = 1 << 0;
-  static const int SELF_INTERCEPTOR = 1 << 1;
-  static const int INTERCEPTED_TRUTHY = 1 << 2;
-  static const int FALSE = 1 << 3;
-  static const int OTHER_FALSY = 1 << 4;
-
-  static const int TRUTHY = TRUE | SELF_INTERCEPTOR | INTERCEPTED_TRUTHY;
-  static const int FALSY = FALSE | OTHER_FALSY;
-  static const int ANY = TRUTHY | FALSY;
-
-  final JavaScriptBackend backend;
-  final TypeMaskSystem typeSystem;
-
-  PathBasedOptimizer(this.backend, this.typeSystem);
-
-  /// The possible values of the given primitive (or ANY if absent) at the
-  /// current traversal position.
-  Map<Primitive, int> valueOf = <Primitive, int>{};
-
-  /// The possible values of each primitive at the entry to a continuation.
-  ///
-  /// Unreachable continuations are absent from the map.
-  final Map<Continuation, Map<Primitive, int>> valuesAt =
-      <Continuation, Map<Primitive, int>>{};
-
-  void rewrite(FunctionDefinition node) {
-    visit(node);
-  }
-
-  Map<Primitive, int> copy(Map<Primitive, int> map) {
-    return new Map<Primitive, int>.from(map);
-  }
-
-  Expression traverseLetHandler(LetHandler node) {
-    valuesAt[node.handler] = copy(valueOf);
-    push(node.handler);
-    return node.body;
-  }
-
-  Expression traverseContinuation(Continuation cont) {
-    valueOf = valuesAt[cont];
-    if (valueOf == null) {
-      // Do not go into unreachable code.
-      destroyAndReplace(cont.body, new Unreachable());
-    }
-    return cont.body;
-  }
-
-  void visitInvokeContinuation(InvokeContinuation node) {
-    Continuation cont = node.continuation;
-    if (cont.isReturnContinuation) return;
-    if (node.isRecursive) return;
-    Map<Primitive, int> target = valuesAt[cont];
-    if (target == null) {
-      valuesAt[cont] = valueOf;
-    } else {
-      for (Primitive prim in target.keys) {
-        target[prim] |= valueOf[prim] ?? ANY;
-      }
-    }
-  }
-
-  visitBranch(Branch node) {
-    Primitive condition = node.condition.effectiveDefinition;
-    Continuation trueCont = node.trueContinuation;
-    Continuation falseCont = node.falseContinuation;
-    if (condition.hasExactlyOneUse) {
-      // Handle common case specially. Do not add [condition] to the map if
-      // there are no other uses.
-      valuesAt[trueCont] = copy(valueOf);
-      valuesAt[falseCont] = valueOf;
-      return;
-    }
-    int values = valueOf[condition] ?? ANY;
-    int positiveValues = node.isStrictCheck ? TRUE : TRUTHY;
-    int negativeValues = (~positiveValues) & ANY;
-    if (values & positiveValues == 0) {
-      destroyAndReplace(node, new InvokeContinuation(falseCont, []));
-      valuesAt[falseCont] = valueOf;
-    } else if (values & negativeValues == 0) {
-      destroyAndReplace(node, new InvokeContinuation(trueCont, []));
-      valuesAt[trueCont] = valueOf;
-    } else {
-      valuesAt[trueCont] = copy(valueOf)..[condition] = values & positiveValues;
-      valuesAt[falseCont] = valueOf..[condition] = values & negativeValues;
-    }
-  }
-
-  void visitInvokeMethod(InvokeMethod node) {
-    int receiverValue = valueOf[node.receiver] ?? ANY;
-    if (!backend.isInterceptedSelector(node.selector)) {
-      // Only self-interceptors can respond to a non-intercepted selector.
-      valueOf[node.receiver] = receiverValue & SELF_INTERCEPTOR;
-    } else if (receiverValue & ~SELF_INTERCEPTOR == 0 &&
-        node.callingConvention == CallingConvention.Intercepted) {
-      // This is an intercepted call whose receiver is definitely a
-      // self-interceptor.
-      // TODO(25646): If TypeMasks could represent "any self-interceptor" this
-      //   optimization should be subsumed by type propagation.
-      node.interceptorRef.changeTo(node.receiver);
-
-      // Replace the extra receiver argument with a dummy value if the
-      // target definitely does not use it.
-      if (typeSystem.targetIgnoresReceiverArgument(
-          node.receiver.type, node.selector)) {
-        node.makeDummyIntercepted();
-      }
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_join.dart b/pkg/compiler/lib/src/cps_ir/redundant_join.dart
deleted file mode 100644
index 3ba1d61..0000000
--- a/pkg/compiler/lib/src/cps_ir/redundant_join.dart
+++ /dev/null
@@ -1,262 +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.redundant_join_elimination;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-
-/// Eliminates redundant join points.
-///
-/// A redundant join point is a continuation that immediately branches
-/// based on one of its parameters, and that parameter is a constant value
-/// at every invocation. Each invocation is redirected to jump directly
-/// to the branch target.
-///
-/// Internally in this pass, parameters are treated as names with lexical
-/// scoping, 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 RedundantJoinEliminator extends TrampolineRecursiveVisitor
-    implements Pass {
-  String get passName => 'Redundant join elimination';
-
-  final Set<Branch> workSet = new Set<Branch>();
-
-  void rewrite(FunctionDefinition node) {
-    visit(node);
-
-    while (workSet.isNotEmpty) {
-      Branch branch = workSet.first;
-      workSet.remove(branch);
-      rewriteBranch(branch);
-    }
-
-    new AlphaRenamer().visit(node);
-  }
-
-  void processBranch(Branch node) {
-    workSet.add(node);
-  }
-
-  /// Returns the body of [node], ignoring all LetCont nodes.
-  Expression getEffectiveBody(InteriorNode node) {
-    while (true) {
-      Expression body = node.body;
-      if (body is LetCont) {
-        node = body;
-      } else {
-        return body;
-      }
-    }
-  }
-
-  /// Returns the parent of [node], ignoring all LetCont nodes.
-  InteriorNode getEffectiveParent(Expression node) {
-    while (true) {
-      Node parent = node.parent;
-      if (parent is LetCont) {
-        node = parent;
-      } else {
-        return parent;
-      }
-    }
-  }
-
-  void rewriteBranch(Branch branch) {
-    InteriorNode parent = getEffectiveParent(branch);
-    if (parent is! Continuation) return;
-    Continuation branchCont = parent;
-
-    // Other optimizations take care of single-use continuations.
-    if (!branchCont.hasMultipleUses) return;
-
-    // It might be beneficial to rewrite calls to recursive continuations,
-    // but we currently do not support this.
-    if (branchCont.isRecursive) return;
-
-    // Check that the branching condition is a parameter on the
-    // enclosing continuation.
-    // Note: Do not use the parent pointer for this check, because parameters
-    // are temporarily shared between different continuations during this pass.
-    Primitive condition = branch.condition;
-    int parameterIndex = branchCont.parameters.indexOf(condition);
-    if (parameterIndex == -1) return;
-
-    // Check that all callers hit a fixed branch, and count the number
-    // of times each branch is hit.
-    // We know all callers are InvokeContinuations because they are the only
-    // valid uses of a multi-use continuation.
-    int trueHits = 0, falseHits = 0;
-    InvokeContinuation trueCall, falseCall;
-    for (Reference ref = branchCont.firstRef; ref != null; ref = ref.next) {
-      InvokeContinuation invoke = ref.parent;
-      Primitive argument = invoke.argument(parameterIndex);
-      if (argument is! Constant) return; // Branching condition is unknown.
-      Constant constant = argument;
-      if (isTruthyConstant(constant.value, strict: branch.isStrictCheck)) {
-        ++trueHits;
-        trueCall = invoke;
-      } else {
-        ++falseHits;
-        falseCall = invoke;
-      }
-    }
-
-    // The optimization is now known to be safe, but it only pays off if
-    // one of the callers can inline its target, since otherwise we end up
-    // replacing a boolean variable with a labeled break.
-    // TODO(asgerf): The labeled break might be better? Evaluate.
-    if (!(trueHits == 1 && !trueCall.isEscapingTry ||
-        falseHits == 1 && !falseCall.isEscapingTry)) {
-      return;
-    }
-
-    // Lift any continuations bound inside branchCont so they are in scope at
-    // the call sites. When lifting, the parameters of branchCont fall out of
-    // scope, so they are added as parameters on each lifted continuation.
-    // Schematically:
-    //
-    //   (LetCont (branchCont (x1, x2, x3) =
-    //        (LetCont (innerCont (y) = ...) in
-    //        [... innerCont(y') ...]))
-    //
-    //     =>
-    //
-    //   (LetCont (innerCont (y, x1, x2, x3) = ...) in
-    //   (LetCont (branchCont (x1, x2, x3) =
-    //        [... innerCont(y', x1, x2, x3) ...])
-    //
-    // Parameter objects become shared between branchCont and the lifted
-    // continuations. [AlphaRenamer] will clean up at the end of this pass.
-    LetCont outerLetCont = branchCont.parent;
-    while (branchCont.body is LetCont) {
-      LetCont innerLetCont = branchCont.body;
-      for (Continuation innerCont in innerLetCont.continuations) {
-        innerCont.parameters.addAll(branchCont.parameters);
-        for (Reference ref = innerCont.firstRef; ref != null; ref = ref.next) {
-          Expression use = ref.parent;
-          if (use is InvokeContinuation) {
-            for (Parameter param in branchCont.parameters) {
-              use.argumentRefs
-                  .add(new Reference<Primitive>(param)..parent = use);
-            }
-          } else {
-            // The branch will be eliminated, so don't worry about updating it.
-            assert(use == branch);
-          }
-        }
-      }
-      innerLetCont.remove();
-      innerLetCont.insertAbove(outerLetCont);
-    }
-
-    assert(branchCont.body == branch);
-
-    Continuation trueCont = branch.trueContinuation;
-    Continuation falseCont = branch.falseContinuation;
-
-    assert(branchCont != trueCont);
-    assert(branchCont != falseCont);
-
-    // Rewrite every invocation of branchCont to call either the true or false
-    // branch directly. Since these were lifted out above branchCont, they are
-    // now in scope.
-    // Since trueCont and falseCont were branch targets, they originally
-    // had no parameters, and so after the lifting, their parameters are
-    // exactly the same as those accepted by branchCont.
-    while (branchCont.firstRef != null) {
-      Reference reference = branchCont.firstRef;
-      InvokeContinuation invoke = branchCont.firstRef.parent;
-      Constant condition = invoke.argument(parameterIndex);
-      if (isTruthyConstant(condition.value, strict: branch.isStrictCheck)) {
-        invoke.continuationRef.changeTo(trueCont);
-      } else {
-        invoke.continuationRef.changeTo(falseCont);
-      }
-      assert(branchCont.firstRef != reference);
-    }
-
-    // Remove the now-unused branchCont continuation.
-    assert(branchCont.hasNoUses);
-    branch.trueContinuationRef.unlink();
-    branch.falseContinuationRef.unlink();
-    outerLetCont.continuations.remove(branchCont);
-    if (outerLetCont.continuations.isEmpty) {
-      outerLetCont.remove();
-    }
-
-    // We may have created new redundant join points in the two branches.
-    enqueueContinuation(trueCont);
-    enqueueContinuation(falseCont);
-  }
-
-  void enqueueContinuation(Continuation cont) {
-    Expression body = getEffectiveBody(cont);
-    if (body is Branch) {
-      workSet.add(body);
-    }
-  }
-}
-
-/// Ensures parameter objects are not shared between different continuations,
-/// akin to alpha-renaming variables so every variable is named uniquely.
-/// For example:
-///
-///   LetCont (k1 x = (return x)) in
-///   LetCont (k2 x = (InvokeContinuation k3 x)) in ...
-///     =>
-///   LetCont (k1 x = (return x)) in
-///   LetCont (k2 x' = (InvokeContinuation k3 x')) in ...
-///
-/// After lifting LetConts in the main pass above, parameter objects can have
-/// multiple bindings. Each reference implicitly refers to the binding that
-/// is currently in scope.
-///
-/// This returns the IR to its normal form after redundant joins have been
-/// eliminated.
-class AlphaRenamer extends TrampolineRecursiveVisitor {
-  Map<Parameter, Parameter> renaming = <Parameter, Parameter>{};
-
-  processContinuation(Continuation cont) {
-    if (cont.isReturnContinuation) return;
-
-    List<Parameter> shadowedKeys = <Parameter>[];
-    List<Parameter> shadowedValues = <Parameter>[];
-
-    // Create new parameters and update the environment.
-    for (int i = 0; i < cont.parameters.length; ++i) {
-      Parameter param = cont.parameters[i];
-      shadowedKeys.add(param);
-      shadowedValues.add(renaming.remove(param));
-      // If the parameter appears to belong to another continuation,
-      // create a new parameter object for this continuation.
-      if (param.parent != cont) {
-        Parameter newParam = new Parameter(param.hint);
-        newParam.type = param.type;
-        renaming[param] = newParam;
-        cont.parameters[i] = newParam;
-        newParam.parent = cont;
-      }
-    }
-
-    pushAction(() {
-      // Restore the original environment.
-      for (int i = 0; i < cont.parameters.length; ++i) {
-        renaming.remove(cont.parameters[i]);
-        if (shadowedValues[i] != null) {
-          renaming[shadowedKeys[i]] = shadowedValues[i];
-        }
-      }
-    });
-  }
-
-  processReference(Reference ref) {
-    Parameter target = renaming[ref.definition];
-    if (target != null) {
-      ref.changeTo(target);
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
deleted file mode 100644
index 96e6431..0000000
--- a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.cps_ir.redundant_phi_elimination;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-
-/// Eliminate redundant phis from the given [FunctionDefinition].
-///
-/// Phis in this case are [Continuations] together with corresponding
-/// [InvokeContinuation]s. A [Continuation] parameter at position i is redundant
-/// if for all [InvokeContinuation]s, the parameter at position i is identical
-/// (except for feedback). Redundant parameters are removed from the
-/// continuation signature, all invocations, and replaced within the
-/// continuation body.
-class RedundantPhiEliminator extends TrampolineRecursiveVisitor
-    implements Pass {
-  String get passName => 'Redundant phi elimination';
-
-  final Set<Continuation> workSet = new Set<Continuation>();
-
-  @override
-  void rewrite(FunctionDefinition root) {
-    // Traverse the tree once to build the work set.
-    visit(root);
-
-    // Process each continuation one-by-one.
-    while (workSet.isNotEmpty) {
-      Continuation cont = workSet.first;
-      workSet.remove(cont);
-
-      if (cont.isReturnContinuation) {
-        continue; // Skip function return continuations.
-      }
-
-      _processContinuation(cont);
-    }
-  }
-
-  /// Called for each continuation on the work set. Modifies the IR graph if
-  /// [cont] is a candidate for redundant phi elimination.
-  void _processContinuation(Continuation cont) {
-    // Generate the list of all cont invocations. If cont is used in any other
-    // context (i.e. as a continuation of InvokeMethod), it is not possible to
-    // optimize.
-    List<InvokeContinuation> invokes = <InvokeContinuation>[];
-    for (Reference ref = cont.firstRef; ref != null; ref = ref.next) {
-      Node parent = ref.parent;
-      if (parent is InvokeContinuation && ref == parent.continuationRef) {
-        invokes.add(parent);
-      } else {
-        return; // Can't optimize.
-      }
-    }
-
-    if (invokes.isEmpty) {
-      return; // Continuation is never invoked, can't optimize.
-    }
-
-    /// Returns the unique definition of parameter i if it exists and null
-    /// otherwise. A definition is unique if it is the only value used to
-    /// invoke the continuation, excluding feedback.
-    Primitive uniqueDefinitionOf(int i) {
-      Primitive value = null;
-      for (InvokeContinuation invoke in invokes) {
-        Primitive def = invoke.argument(i).effectiveDefinition;
-
-        if (cont.parameters[i] == def) {
-          // Invocation param == param in LetCont (i.e. a recursive call).
-          continue;
-        } else if (value == null) {
-          value = def; // Set initial comparison value.
-        } else if (value != def) {
-          return null; // Differing invocation arguments.
-        }
-      }
-
-      return value;
-    }
-
-    // If uniqueDefinition is in the body of the LetCont binding the
-    // continuation, then we will drop the continuation binding to just inside
-    // the binding of uniqueDefiniton.  This is not safe if we drop the
-    // continuation binding inside a LetHandler exception handler binding.
-    LetCont letCont = cont.parent;
-    bool safeForHandlers(Definition uniqueDefinition) {
-      bool seenHandler = false;
-      Node current = uniqueDefinition.parent;
-      while (current != null) {
-        if (current == letCont) return !seenHandler;
-        seenHandler = seenHandler || current is LetHandler;
-        current = current.parent;
-      }
-      // When uniqueDefinition is not in the body of the LetCont binding the
-      // continuation, we will not move any code, so that is safe.
-      return true;
-    }
-
-    // Check if individual parameters are always called with a unique
-    // definition, and remove them if that is the case. During each iteration,
-    // we read the current parameter/argument from index `src` and copy it
-    // to index `dst`.
-    int dst = 0;
-    for (int src = 0; src < cont.parameters.length; src++) {
-      // Is the current phi redundant?
-      Primitive uniqueDefinition = uniqueDefinitionOf(src);
-      if (uniqueDefinition == null || !safeForHandlers(uniqueDefinition)) {
-        // Reorganize parameters and arguments in case of deletions.
-        if (src != dst) {
-          cont.parameters[dst] = cont.parameters[src];
-          for (InvokeContinuation invoke in invokes) {
-            invoke.argumentRefs[dst] = invoke.argumentRefs[src];
-          }
-        }
-        dst++;
-        continue;
-      }
-
-      Primitive oldDefinition = cont.parameters[src];
-
-      // Add continuations of about-to-be modified invokes to worklist since
-      // we might introduce new optimization opportunities.
-      for (Reference ref = oldDefinition.firstRef;
-          ref != null;
-          ref = ref.next) {
-        Node parent = ref.parent;
-        if (parent is InvokeContinuation) {
-          Continuation thatCont = parent.continuation;
-          if (thatCont != cont) {
-            workSet.add(thatCont);
-          }
-        }
-      }
-
-      // Replace individual parameters:
-      // * In the continuation body, replace occurrence of param with value,
-      // * 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.
-      oldDefinition.replaceUsesWith(uniqueDefinition);
-      for (InvokeContinuation invoke in invokes) {
-        invoke.argumentRefs[src].unlink();
-      }
-
-      // Finally, if the substituted definition is not in scope of the affected
-      // continuation, move the continuation binding. This is safe to do since
-      // the continuation is referenced only as the target in continuation
-      // invokes, and all such invokes must be within the scope of
-      // [uniqueDefinition]. Note that this is linear in the depth of
-      // the binding of [uniqueDefinition].
-      letCont = _makeUniqueBinding(cont);
-      _moveIntoScopeOf(letCont, uniqueDefinition);
-    }
-
-    // Remove trailing items from parameter and argument lists.
-    cont.parameters.length = dst;
-    for (InvokeContinuation invoke in invokes) {
-      invoke.argumentRefs.length = dst;
-    }
-  }
-
-  void processLetCont(LetCont node) {
-    node.continuations.forEach(workSet.add);
-  }
-}
-
-/// Returns true, iff [letCont] is not scope of [definition].
-/// Linear in the depth of definition within the IR graph.
-bool _isInScopeOf(LetCont letCont, Definition definition) {
-  for (Node node = definition.parent; node != null; node = node.parent) {
-    if (node == letCont) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-/// Moves [letCont] below the binding of [definition] within the IR graph.
-/// Does nothing if [letCont] is already within the scope of [definition].
-/// Assumes that one argument is nested within the scope of the other
-/// when this method is called.
-void _moveIntoScopeOf(LetCont letCont, Definition definition) {
-  if (_isInScopeOf(letCont, definition)) return;
-
-  InteriorNode binding = definition.parent;
-  letCont.remove();
-  letCont.insertBelow(binding);
-}
-
-/// 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;
-  if (letCont.continuations.length == 1) return letCont;
-  letCont.continuations.remove(continuation);
-  LetCont newBinding = new LetCont(continuation, null);
-  continuation.parent = newBinding;
-  newBinding.insertBelow(letCont);
-  return newBinding;
-}
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_refinement.dart b/pkg/compiler/lib/src/cps_ir/redundant_refinement.dart
deleted file mode 100644
index 8cd13b3..0000000
--- a/pkg/compiler/lib/src/cps_ir/redundant_refinement.dart
+++ /dev/null
@@ -1,57 +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.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/scalar_replacement.dart b/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
deleted file mode 100644
index a913f08..0000000
--- a/pkg/compiler/lib/src/cps_ir/scalar_replacement.dart
+++ /dev/null
@@ -1,224 +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.scalar_replacement;
-
-import 'optimizers.dart';
-
-import 'dart:collection' show Queue;
-
-import '../common.dart';
-import '../compiler.dart' as dart2js show Compiler;
-import '../constants/values.dart';
-import '../elements/elements.dart';
-import '../types/types.dart';
-import '../world.dart' show World;
-import 'cps_ir_nodes.dart';
-
-/**
- * Replaces aggregates with a set of local values.  Performs inlining of
- * single-use closures to generate more replaceable aggregates.
- */
-class ScalarReplacer extends Pass {
-  String get passName => 'Scalar replacement';
-
-  final InternalErrorFunction _internalError;
-  final World _classWorld;
-
-  ScalarReplacer(dart2js.Compiler compiler)
-      : _internalError = compiler.reporter.internalError,
-        _classWorld = compiler.world;
-
-  @override
-  void rewrite(FunctionDefinition root) {
-    ScalarReplacementVisitor analyzer =
-        new ScalarReplacementVisitor(_internalError, _classWorld);
-    analyzer.analyze(root);
-    analyzer.process();
-  }
-}
-
-/**
- * Do scalar replacement of aggregates on instances. Since scalar replacement
- * can create new candidates, iterate until all scalar replacements are done.
- */
-class ScalarReplacementVisitor extends TrampolineRecursiveVisitor {
-  final InternalErrorFunction internalError;
-  final World classWorld;
-  ScalarReplacementRemovalVisitor removalVisitor;
-
-  Primitive _current = null;
-  Set<Primitive> _allocations = new Set<Primitive>();
-  Queue<Primitive> _queue = new Queue<Primitive>();
-
-  ScalarReplacementVisitor(this.internalError, this.classWorld) {
-    removalVisitor = new ScalarReplacementRemovalVisitor(this);
-  }
-
-  void analyze(FunctionDefinition root) {
-    visit(root);
-  }
-
-  void process() {
-    while (_queue.isNotEmpty) {
-      Primitive allocation = _queue.removeFirst();
-      _allocations.remove(allocation);
-      _current = allocation;
-      tryScalarReplacement(allocation);
-    }
-  }
-
-  void tryScalarReplacement(Primitive allocation) {
-    // We can do scalar replacement of an aggregate if all uses of an allocation
-    // are reads or writes.
-    for (Reference ref = allocation.firstRef; ref != null; ref = ref.next) {
-      Node use = ref.parent;
-      if (use is GetField) continue;
-      if (use is SetField && use.objectRef == ref) continue;
-      return;
-    }
-
-    Set<FieldElement> reads = new Set<FieldElement>();
-    Set<FieldElement> writes = new Set<FieldElement>();
-    for (Reference ref = allocation.firstRef; ref != null; ref = ref.next) {
-      Node use = ref.parent;
-      if (use is GetField) {
-        reads.add(use.field);
-      } else if (use is SetField) {
-        writes.add(use.field);
-      } else {
-        assert(false);
-      }
-    }
-
-    // Find the initial values of the fields. A CreateBox has no initial
-    // values. CreateInstance has initial values in the order of the fields.
-    Map<FieldElement, Primitive> fieldInitialValues =
-        <FieldElement, Primitive>{};
-    if (allocation is CreateInstance) {
-      int i = 0;
-      allocation.classElement.forEachInstanceField(
-          (ClassElement enclosingClass, FieldElement field) {
-        Primitive argument = allocation.argument(i++);
-        fieldInitialValues[field] = argument;
-      }, includeSuperAndInjectedMembers: true);
-    }
-
-    // Create [MutableVariable]s for each written field. Initialize the
-    // MutableVariable with the value from the allocator, or initialize with a
-    // `null` constant if there is not initial value.
-    Map<FieldElement, MutableVariable> cells =
-        <FieldElement, MutableVariable>{};
-    InteriorNode insertionPoint = allocation.parent; // LetPrim
-    for (FieldElement field in writes) {
-      MutableVariable variable = new MutableVariable(field);
-      variable.type = new TypeMask.nonNullEmpty();
-      cells[field] = variable;
-      Primitive initialValue = fieldInitialValues[field];
-      if (initialValue == null) {
-        assert(allocation is CreateBox);
-        initialValue = new Constant(new NullConstantValue());
-        LetPrim let = new LetPrim(initialValue);
-        let.primitive.parent = let;
-        insertionPoint = let..insertBelow(insertionPoint);
-      }
-      LetMutable let = new LetMutable(variable, initialValue);
-      let.valueRef.parent = let;
-      insertionPoint = let..insertBelow(insertionPoint);
-    }
-
-    // Replace references with MutableVariable operations or references to the
-    // field's value.
-    for (Reference ref = allocation.firstRef; ref != null; ref = ref.next) {
-      Node use = ref.parent;
-      if (use is GetField) {
-        GetField getField = use;
-        MutableVariable variable = cells[getField.field];
-        if (variable != null) {
-          GetMutable getter = new GetMutable(variable);
-          getter.type = getField.type;
-          getter.variableRef.parent = getter;
-          getField.replaceUsesWith(getter);
-          replacePrimitive(getField, getter);
-          deletePrimitive(getField);
-        } else {
-          Primitive value = fieldInitialValues[getField.field];
-          getField.replaceUsesWith(value);
-          deleteLetPrimOf(getField);
-        }
-      } else if (use is SetField && use.objectRef == ref) {
-        SetField setField = use;
-        MutableVariable variable = cells[setField.field];
-        Primitive value = setField.value;
-        variable.type = variable.type.union(value.type, classWorld);
-        SetMutable setter = new SetMutable(variable, value);
-        setter.variableRef.parent = setter;
-        setter.valueRef.parent = setter;
-        setField.replaceUsesWith(setter);
-        replacePrimitive(setField, setter);
-        deletePrimitive(setField);
-      } else {
-        assert(false);
-      }
-    }
-
-    // Delete [allocation] since that might 'free' another scalar replacement
-    // candidate by deleting the last non-field-access.
-    deleteLetPrimOf(allocation);
-  }
-
-  /// Replaces [old] with [primitive] in [old]'s parent [LetPrim].
-  void replacePrimitive(Primitive old, Primitive primitive) {
-    LetPrim letPrim = old.parent;
-    letPrim.primitive = primitive;
-    primitive.parent = letPrim;
-  }
-
-  void deleteLetPrimOf(Primitive primitive) {
-    assert(primitive.hasNoUses);
-    LetPrim letPrim = primitive.parent;
-    letPrim.remove();
-    deletePrimitive(primitive);
-  }
-
-  void deletePrimitive(Primitive primitive) {
-    assert(primitive.hasNoUses);
-    removalVisitor.visit(primitive);
-  }
-
-  void reconsider(Definition node) {
-    if (node is CreateInstance || node is CreateBox) {
-      if (node == _current) return;
-      enqueue(node);
-    }
-  }
-
-  void enqueue(Primitive node) {
-    assert(node is CreateInstance || node is CreateBox);
-    if (_allocations.contains(node)) return;
-    _allocations.add(node);
-    _queue.add(node);
-  }
-
-  // -------------------------- Visitor overrides ------------------------------
-  void visitCreateInstance(CreateInstance node) {
-    enqueue(node);
-  }
-
-  void visitCreateBox(CreateBox node) {
-    enqueue(node);
-  }
-}
-
-/// Visit a just-deleted subterm and unlink all [Reference]s in it.  Reconsider
-/// allocations for scalar replacement.
-class ScalarReplacementRemovalVisitor extends TrampolineRecursiveVisitor {
-  ScalarReplacementVisitor process;
-
-  ScalarReplacementRemovalVisitor(this.process);
-
-  processReference(Reference reference) {
-    process.reconsider(reference.definition);
-    reference.unlink();
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
deleted file mode 100644
index 3e3fd94..0000000
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ /dev/null
@@ -1,712 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.cps_ir.shrinking_reductions;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-
-/**
- * [ShrinkingReducer] applies shrinking reductions to CPS terms as described
- * in 'Compiling with Continuations, Continued' by Andrew Kennedy.
- */
-class ShrinkingReducer extends Pass {
-  String get passName => 'Shrinking reductions';
-
-  final List<_ReductionTask> _worklist = new List<_ReductionTask>();
-
-  /// Applies shrinking reductions to root, mutating root in the process.
-  @override
-  void rewrite(FunctionDefinition root) {
-    _RedexVisitor redexVisitor = new _RedexVisitor(_worklist);
-
-    // Sweep over the term, collecting redexes into the worklist.
-    redexVisitor.visit(root);
-
-    _iterateWorklist();
-  }
-
-  void _iterateWorklist() {
-    while (_worklist.isNotEmpty) {
-      _ReductionTask task = _worklist.removeLast();
-      _processTask(task);
-    }
-  }
-
-  /// Call instead of [_iterateWorklist] to check at every step that no
-  /// redex was missed.
-  void _debugWorklist(FunctionDefinition root) {
-    while (_worklist.isNotEmpty) {
-      _ReductionTask task = _worklist.removeLast();
-      String irBefore =
-          root.debugString({task.node: '${task.kind} applied here'});
-      _processTask(task);
-      Set seenRedexes = _worklist.where(isValidTask).toSet();
-      Set actualRedexes = (new _RedexVisitor([])..visit(root)).worklist.toSet();
-      if (!seenRedexes.containsAll(actualRedexes)) {
-        _ReductionTask missedTask =
-            actualRedexes.firstWhere((x) => !seenRedexes.contains(x));
-        print('\nBEFORE $task:\n');
-        print(irBefore);
-        print('\nAFTER $task:\n');
-        root.debugPrint({missedTask.node: 'MISSED ${missedTask.kind}'});
-        throw 'Missed $missedTask after processing $task';
-      }
-    }
-  }
-
-  bool isValidTask(_ReductionTask task) {
-    switch (task.kind) {
-      case _ReductionKind.DEAD_VAL:
-        return _isDeadVal(task.node);
-      case _ReductionKind.DEAD_CONT:
-        return _isDeadCont(task.node);
-      case _ReductionKind.BETA_CONT_LIN:
-        return _isBetaContLin(task.node);
-      case _ReductionKind.ETA_CONT:
-        return _isEtaCont(task.node);
-      case _ReductionKind.DEAD_PARAMETER:
-        return _isDeadParameter(task.node);
-      case _ReductionKind.BRANCH:
-        return _isBranchRedex(task.node);
-    }
-  }
-
-  /// Removes the given node from the CPS graph, replacing it with its body
-  /// and marking it as deleted. The node's parent must be a [[InteriorNode]].
-  void _removeNode(InteriorNode node) {
-    Node body = node.body;
-    InteriorNode parent = node.parent;
-    assert(parent.body == node);
-
-    body.parent = parent;
-    parent.body = body;
-    node.parent = null;
-
-    // The removed node could be the last node between a continuation and
-    // an InvokeContinuation in the body.
-    if (parent is Continuation) {
-      _checkEtaCont(parent);
-      _checkUselessBranchTarget(parent);
-    }
-  }
-
-  /// Remove a given continuation from the CPS graph.  The LetCont itself is
-  /// removed if the given continuation is the only binding.
-  void _removeContinuation(Continuation cont) {
-    LetCont parent = cont.parent;
-    if (parent.continuations.length == 1) {
-      _removeNode(parent);
-    } else {
-      parent.continuations.remove(cont);
-    }
-    cont.parent = null;
-  }
-
-  void _processTask(_ReductionTask task) {
-    // Skip tasks for deleted nodes.
-    if (task.node.parent == null) {
-      return;
-    }
-
-    switch (task.kind) {
-      case _ReductionKind.DEAD_VAL:
-        _reduceDeadVal(task);
-        break;
-      case _ReductionKind.DEAD_CONT:
-        _reduceDeadCont(task);
-        break;
-      case _ReductionKind.BETA_CONT_LIN:
-        _reduceBetaContLin(task);
-        break;
-      case _ReductionKind.ETA_CONT:
-        _reduceEtaCont(task);
-        break;
-      case _ReductionKind.DEAD_PARAMETER:
-        _reduceDeadParameter(task);
-        break;
-      case _ReductionKind.BRANCH:
-        _reduceBranch(task);
-        break;
-    }
-  }
-
-  /// Applies the dead-val reduction:
-  ///   letprim x = V in E -> E (x not free in E).
-  void _reduceDeadVal(_ReductionTask task) {
-    if (_isRemoved(task.node)) return;
-    assert(_isDeadVal(task.node));
-
-    LetPrim deadLet = task.node;
-    Primitive deadPrim = deadLet.primitive;
-    assert(deadPrim.hasNoRefinedUses);
-    // The node has no effective uses but can have refinement uses, which
-    // themselves can have more refinements uses (but only refinement uses).
-    // We must remove the entire refinement tree while looking for redexes
-    // whenever we remove one.
-    List<Primitive> deadlist = <Primitive>[deadPrim];
-    while (deadlist.isNotEmpty) {
-      Primitive node = deadlist.removeLast();
-      while (node.firstRef != null) {
-        Reference ref = node.firstRef;
-        Refinement use = ref.parent;
-        deadlist.add(use);
-        ref.unlink();
-      }
-      LetPrim binding = node.parent;
-      _removeNode(binding); // Remove the binding and check for eta redexes.
-    }
-
-    // Perform bookkeeping on removed body and scan for new redexes.
-    new _RemovalVisitor(_worklist).visit(deadPrim);
-  }
-
-  /// Applies the dead-cont reduction:
-  ///   letcont k x = E0 in E1 -> E1 (k not free in E1).
-  void _reduceDeadCont(_ReductionTask task) {
-    assert(_isDeadCont(task.node));
-
-    // Remove dead continuation.
-    Continuation cont = task.node;
-    _removeContinuation(cont);
-
-    // Perform bookkeeping on removed body and scan for new redexes.
-    new _RemovalVisitor(_worklist).visit(cont);
-  }
-
-  /// Applies the beta-cont-lin reduction:
-  ///   letcont k x = E0 in E1[k y] -> E1[E0[y/x]] (k not free in E1).
-  void _reduceBetaContLin(_ReductionTask task) {
-    // Might have been mutated, recheck if reduction is still valid.
-    // In the following example, the beta-cont-lin reduction of k0 could have
-    // been invalidated by removal of the dead continuation k1:
-    //
-    //  letcont k0 x0 = E0 in
-    //    letcont k1 x1 = k0 x1 in
-    //      return x2
-    if (!_isBetaContLin(task.node)) {
-      return;
-    }
-
-    Continuation cont = task.node;
-    InvokeContinuation invoke = cont.firstRef.parent;
-    InteriorNode invokeParent = invoke.parent;
-    Expression body = cont.body;
-
-    // Replace the invocation with the continuation body.
-    invokeParent.body = body;
-    body.parent = invokeParent;
-    cont.body = null;
-
-    // Substitute the invocation argument for the continuation parameter.
-    for (int i = 0; i < invoke.argumentRefs.length; i++) {
-      Parameter param = cont.parameters[i];
-      Primitive argument = invoke.argument(i);
-      param.replaceUsesWith(argument);
-      argument.useElementAsHint(param.hint);
-      _checkConstantBranchCondition(argument);
-    }
-
-    // Remove the continuation after inlining it so we can check for eta redexes
-    // which may arise after removing the LetCont.
-    _removeContinuation(cont);
-
-    // Perform bookkeeping on substituted body and scan for new redexes.
-    new _RemovalVisitor(_worklist).visit(invoke);
-
-    if (invokeParent is Continuation) {
-      _checkEtaCont(invokeParent);
-      _checkUselessBranchTarget(invokeParent);
-    }
-  }
-
-  /// Applies the eta-cont reduction:
-  ///   letcont k x = j x in E -> E[j/k].
-  /// If k is unused, degenerates to dead-cont.
-  void _reduceEtaCont(_ReductionTask task) {
-    // Might have been mutated, recheck if reduction is still valid.
-    // In the following example, the eta-cont reduction of k1 could have been
-    // invalidated by an earlier beta-cont-lin reduction of k0.
-    //
-    //  letcont k0 x0 = E0 in
-    //    letcont k1 x1 = k0 x1 in E1
-    if (!_isEtaCont(task.node)) {
-      return;
-    }
-
-    // Remove the continuation.
-    Continuation cont = task.node;
-    _removeContinuation(cont);
-
-    InvokeContinuation invoke = cont.body;
-    Continuation wrappedCont = invoke.continuation;
-
-    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 and find redexes.
-    while (cont.firstRef != null) {
-      Reference ref = cont.firstRef;
-      ref.changeTo(wrappedCont);
-      Node use = ref.parent;
-      if (use is InvokeContinuation && use.parent is Continuation) {
-        _checkUselessBranchTarget(use.parent);
-      }
-    }
-
-    // Perform bookkeeping on removed body and scan for new redexes.
-    new _RemovalVisitor(_worklist).visit(cont);
-  }
-
-  void _reduceBranch(_ReductionTask task) {
-    Branch branch = task.node;
-    // Replace Branch with InvokeContinuation of one of the targets. When the
-    // branch is deleted the other target becomes unreferenced and the chosen
-    // target becomes available for eta-cont and further reductions.
-    Continuation target;
-    Primitive condition = branch.condition;
-    if (condition is Constant) {
-      target = isTruthyConstant(condition.value, strict: branch.isStrictCheck)
-          ? branch.trueContinuation
-          : branch.falseContinuation;
-    } else if (_isBranchTargetOfUselessIf(branch.trueContinuation)) {
-      target = branch.trueContinuation;
-    } else {
-      return;
-    }
-
-    InvokeContinuation invoke = new InvokeContinuation(target, <Primitive>[]
-        // TODO(sra): Add sourceInformation.
-        /*, sourceInformation: branch.sourceInformation*/);
-    branch.parent.body = invoke;
-    invoke.parent = branch.parent;
-    branch.parent = null;
-
-    new _RemovalVisitor(_worklist).visit(branch);
-  }
-
-  void _reduceDeadParameter(_ReductionTask task) {
-    // Continuation eta-reduction can destroy a dead parameter redex.  For
-    // example, in the term:
-    //
-    // let cont k0(v0) = /* v0 is not used */ in
-    //   let cont k1(v1) = k0(v1) in
-    //     call foo () k1
-    //
-    // Continuation eta-reduction of k1 gives:
-    //
-    // let cont k0(v0) = /* v0 is not used */ in
-    //   call foo () k0
-    //
-    // Where the dead parameter reduction is no longer valid because we do not
-    // allow removing the paramter of call continuations.  We disallow such eta
-    // reductions in [_isEtaCont].
-    Parameter parameter = task.node;
-    if (_isParameterRemoved(parameter)) return;
-    assert(_isDeadParameter(parameter));
-
-    Continuation continuation = parameter.parent;
-    int index = continuation.parameters.indexOf(parameter);
-    assert(index != -1);
-    continuation.parameters.removeAt(index);
-    parameter.parent = null; // Mark as removed.
-
-    // Remove the index'th argument from each invocation.
-    for (Reference ref = continuation.firstRef; ref != null; ref = ref.next) {
-      InvokeContinuation invoke = ref.parent;
-      Reference<Primitive> argument = invoke.argumentRefs[index];
-      argument.unlink();
-      invoke.argumentRefs.removeAt(index);
-      // Removing an argument can create a dead primitive or an eta-redex
-      // in case the parent is a continuation that now has matching parameters.
-      _checkDeadPrimitive(argument.definition);
-      if (invoke.parent is Continuation) {
-        _checkEtaCont(invoke.parent);
-        _checkUselessBranchTarget(invoke.parent);
-      }
-    }
-
-    // Removing an unused parameter can create an eta-redex, in case the
-    // body is an InvokeContinuation that now has matching arguments.
-    _checkEtaCont(continuation);
-  }
-
-  void _checkEtaCont(Continuation continuation) {
-    if (_isEtaCont(continuation)) {
-      _worklist.add(new _ReductionTask(_ReductionKind.ETA_CONT, continuation));
-    }
-  }
-
-  void _checkUselessBranchTarget(Continuation continuation) {
-    if (_isBranchTargetOfUselessIf(continuation)) {
-      _worklist.add(new _ReductionTask(
-          _ReductionKind.BRANCH, continuation.firstRef.parent));
-    }
-  }
-
-  void _checkConstantBranchCondition(Primitive primitive) {
-    if (primitive is! Constant) return;
-    for (Reference ref = primitive.firstRef; ref != null; ref = ref.next) {
-      Node use = ref.parent;
-      if (use is Branch) {
-        _worklist.add(new _ReductionTask(_ReductionKind.BRANCH, use));
-      }
-    }
-  }
-
-  void _checkDeadPrimitive(Primitive primitive) {
-    primitive = primitive.unrefined;
-    if (primitive is Parameter) {
-      if (_isDeadParameter(primitive)) {
-        _worklist
-            .add(new _ReductionTask(_ReductionKind.DEAD_PARAMETER, primitive));
-      }
-    } else if (primitive.parent is LetPrim) {
-      LetPrim letPrim = primitive.parent;
-      if (_isDeadVal(letPrim)) {
-        _worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, letPrim));
-      }
-    }
-  }
-}
-
-bool _isRemoved(InteriorNode node) {
-  return node.parent == null;
-}
-
-bool _isParameterRemoved(Parameter parameter) {
-  // A parameter can be removed directly or because its continuation is removed.
-  return parameter.parent == null || _isRemoved(parameter.parent);
-}
-
-/// Returns true iff the bound primitive is unused, and has no effects
-/// preventing it from being eliminated.
-bool _isDeadVal(LetPrim node) {
-  return !_isRemoved(node) &&
-      node.primitive.hasNoRefinedUses &&
-      node.primitive.isSafeForElimination;
-}
-
-/// Returns true iff the continuation is unused.
-bool _isDeadCont(Continuation cont) {
-  return !_isRemoved(cont) &&
-      !cont.isReturnContinuation &&
-      !cont.hasAtLeastOneUse;
-}
-
-/// Returns true iff the continuation has a body (i.e., it is not the return
-/// continuation), it is used exactly once, and that use is as the continuation
-/// of a continuation invocation.
-bool _isBetaContLin(Continuation cont) {
-  if (_isRemoved(cont)) return false;
-
-  // There is a restriction on continuation eta-redexes that the body is not an
-  // invocation of the return continuation, because that leads to worse code
-  // when translating back to direct style (it duplicates returns).  There is no
-  // such restriction here because continuation beta-reduction is only performed
-  // for singly referenced continuations. Thus, there is no possibility of code
-  // duplication.
-  if (cont.isReturnContinuation || !cont.hasExactlyOneUse) {
-    return false;
-  }
-
-  if (cont.firstRef.parent is! InvokeContinuation) return false;
-
-  InvokeContinuation invoke = cont.firstRef.parent;
-
-  // Beta-reduction will move the continuation's body to its unique invocation
-  // site.  This is not safe if the body is moved into an exception handler
-  // binding.
-  if (invoke.isEscapingTry) return false;
-
-  return true;
-}
-
-/// Returns true iff the continuation consists of a continuation
-/// invocation, passing on all parameters. Special cases exist (see below).
-bool _isEtaCont(Continuation cont) {
-  if (_isRemoved(cont)) return false;
-
-  if (!cont.isJoinContinuation || cont.body is! InvokeContinuation) {
-    return false;
-  }
-
-  InvokeContinuation invoke = cont.body;
-  Continuation invokedCont = invoke.continuation;
-
-  // Do not eta-reduce return join-points since the direct-style code is worse
-  // in the common case (i.e. returns are moved inside `if` branches).
-  if (invokedCont.isReturnContinuation) {
-    return false;
-  }
-
-  // Translation to direct style generates different statements for recursive
-  // and non-recursive invokes. It should still be possible to apply eta-cont if
-  // this is not a self-invocation.
-  //
-  // TODO(kmillikin): Remove this restriction if it makes sense to do so.
-  if (invoke.isRecursive) {
-    return false;
-  }
-
-  // If cont has more parameters than the invocation has arguments, the extra
-  // parameters will be dead and dead-parameter will eventually create the
-  // eta-redex if possible.
-  //
-  // If the invocation's arguments are simply a permutation of cont's
-  // parameters, then there is likewise a possible reduction that involves
-  // rewriting the invocations of cont.  We are missing that reduction here.
-  //
-  // If cont has fewer parameters than the invocation has arguments then a
-  // reduction would still possible, since the extra invocation arguments must
-  // be in scope at all the invocations of cont.  For example:
-  //
-  // let cont k1(x1) = k0(x0, x1) in E -eta-> E'
-  // where E' has k0(x0, v) substituted for each k1(v).
-  //
-  // HOWEVER, adding continuation parameters is unlikely to be an optimization
-  // since it duplicates assignments used in direct-style to implement parameter
-  // passing.
-  //
-  // TODO(kmillikin): find real occurrences of these patterns, and see if they
-  // can be optimized.
-  if (cont.parameters.length != invoke.argumentRefs.length) {
-    return false;
-  }
-
-  // TODO(jgruber): Linear in the parameter count. Can be improved to near
-  // constant time by using union-find data structure.
-  for (int i = 0; i < cont.parameters.length; i++) {
-    if (invoke.argument(i) != cont.parameters[i]) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-Expression _unfoldDeadRefinements(Expression node) {
-  while (node is LetPrim) {
-    LetPrim let = node;
-    Primitive prim = let.primitive;
-    if (prim.hasAtLeastOneUse || prim is! Refinement) return node;
-    node = node.next;
-  }
-  return node;
-}
-
-bool _isBranchRedex(Branch branch) {
-  return _isUselessIf(branch) || branch.condition is Constant;
-}
-
-bool _isBranchTargetOfUselessIf(Continuation cont) {
-  // A useless-if has an empty then and else branch, e.g. `if (cond);`.
-  //
-  // Detect T or F in
-  //
-  //     let cont Join() = ...
-  //       in let cont T() = Join()
-  //                   F() = Join()
-  //         in branch condition T F
-  //
-  if (!cont.hasExactlyOneUse) return false;
-  Node use = cont.firstRef.parent;
-  if (use is! Branch) return false;
-  return _isUselessIf(use);
-}
-
-bool _isUselessIf(Branch branch) {
-  Continuation trueCont = branch.trueContinuation;
-  Expression trueBody = _unfoldDeadRefinements(trueCont.body);
-  if (trueBody is! InvokeContinuation) return false;
-  Continuation falseCont = branch.falseContinuation;
-  Expression falseBody = _unfoldDeadRefinements(falseCont.body);
-  if (falseBody is! InvokeContinuation) return false;
-  InvokeContinuation trueInvoke = trueBody;
-  InvokeContinuation falseInvoke = falseBody;
-  if (trueInvoke.continuation != falseInvoke.continuation) {
-    return false;
-  }
-  // Matching zero arguments should be adequate, since isomorphic true and false
-  // invocations should result in redundant phis which are removed elsewhere.
-  //
-  // Note that the argument lists are not necessarily the same length here,
-  // because we could be looking for new redexes in the middle of performing a
-  // dead parameter reduction, where some but not all of the invocations have
-  // been rewritten.  In that case, we will find the redex (once) after both
-  // of these invocations have been rewritten.
-  return trueInvoke.argumentRefs.isEmpty && falseInvoke.argumentRefs.isEmpty;
-}
-
-bool _isDeadParameter(Parameter parameter) {
-  if (_isParameterRemoved(parameter)) return false;
-
-  // We cannot remove function parameters as an intraprocedural optimization.
-  if (parameter.parent is! Continuation || parameter.hasAtLeastOneUse) {
-    return false;
-  }
-
-  // We cannot remove the parameter to a call continuation, because the
-  // resulting expression will not be well-formed (call continuations have
-  // exactly one argument).  The return continuation is a call continuation, so
-  // we cannot remove its dummy parameter.
-  Continuation continuation = parameter.parent;
-  if (!continuation.isJoinContinuation) return false;
-
-  return true;
-}
-
-/// Traverses a term and adds any found redexes to the worklist.
-class _RedexVisitor extends TrampolineRecursiveVisitor {
-  final List<_ReductionTask> worklist;
-
-  _RedexVisitor(this.worklist);
-
-  void processLetPrim(LetPrim node) {
-    if (_isDeadVal(node)) {
-      worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, node));
-    }
-  }
-
-  void processBranch(Branch node) {
-    if (_isBranchRedex(node)) {
-      worklist.add(new _ReductionTask(_ReductionKind.BRANCH, node));
-    }
-  }
-
-  void processContinuation(Continuation node) {
-    // While it would be nice to remove exception handlers that are provably
-    // unnecessary (e.g., the body cannot throw), that takes more sophisticated
-    // analysis than we do in this pass.
-    if (node.parent is LetHandler) return;
-
-    // Continuation beta- and eta-redexes can overlap, namely when an eta-redex
-    // is invoked exactly once.  We prioritize continuation beta-redexes over
-    // eta-redexes because some reductions (e.g., dead parameter elimination)
-    // can destroy a continuation eta-redex.  If we prioritized eta- over
-    // beta-redexes, this would implicitly "create" the corresponding beta-redex
-    // (in the sense that it would still apply) and the algorithm would not
-    // detect it.
-    if (_isDeadCont(node)) {
-      worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, node));
-    } else if (_isBetaContLin(node)) {
-      worklist.add(new _ReductionTask(_ReductionKind.BETA_CONT_LIN, node));
-    } else if (_isEtaCont(node)) {
-      worklist.add(new _ReductionTask(_ReductionKind.ETA_CONT, node));
-    }
-  }
-
-  void processParameter(Parameter node) {
-    if (_isDeadParameter(node)) {
-      worklist.add(new _ReductionTask(_ReductionKind.DEAD_PARAMETER, node));
-    }
-  }
-}
-
-/// Traverses a deleted CPS term, marking nodes that might participate in a
-/// redex as deleted and adding newly created redexes to the worklist.
-///
-/// Deleted nodes that might participate in a reduction task are marked so that
-/// any corresponding tasks can be skipped.  Nodes are marked so by setting
-/// their parent to the deleted sentinel.
-class _RemovalVisitor extends TrampolineRecursiveVisitor {
-  final List<_ReductionTask> worklist;
-
-  _RemovalVisitor(this.worklist);
-
-  void processLetPrim(LetPrim node) {
-    node.parent = null;
-  }
-
-  void processContinuation(Continuation node) {
-    node.parent = null;
-  }
-
-  void processBranch(Branch node) {
-    node.parent = null;
-  }
-
-  void processReference(Reference reference) {
-    reference.unlink();
-
-    if (reference.definition is Primitive) {
-      Primitive primitive = reference.definition.unrefined;
-      Node parent = primitive.parent;
-      // The parent might be the deleted sentinel, or it might be a
-      // Continuation or FunctionDefinition if the primitive is an argument.
-      if (parent is LetPrim && _isDeadVal(parent)) {
-        worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, parent));
-      } else if (primitive is Parameter && _isDeadParameter(primitive)) {
-        worklist
-            .add(new _ReductionTask(_ReductionKind.DEAD_PARAMETER, primitive));
-      }
-    } else if (reference.definition is Continuation) {
-      Continuation cont = reference.definition;
-      Node parent = cont.parent;
-      // The parent might be the deleted sentinel, or it might be a
-      // Body if the continuation is the return continuation.
-      if (parent is LetCont) {
-        if (cont.isRecursive && cont.hasAtMostOneUse) {
-          // Convert recursive to nonrecursive continuations.  If the
-          // continuation is still in use, it is either dead and will be
-          // removed, or it is called nonrecursively outside its body.
-          cont.isRecursive = false;
-        }
-        if (_isDeadCont(cont)) {
-          worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, cont));
-        } else if (_isBetaContLin(cont)) {
-          worklist.add(new _ReductionTask(_ReductionKind.BETA_CONT_LIN, cont));
-        } else if (_isBranchTargetOfUselessIf(cont)) {
-          worklist.add(
-              new _ReductionTask(_ReductionKind.BRANCH, cont.firstRef.parent));
-        }
-      }
-    }
-  }
-}
-
-enum _ReductionKind {
-  DEAD_VAL,
-  DEAD_CONT,
-  BETA_CONT_LIN,
-  ETA_CONT,
-  DEAD_PARAMETER,
-  BRANCH
-}
-
-/// Represents a reduction task on the worklist. Implements both hashCode and
-/// operator== since instantiations are used as Set elements.
-class _ReductionTask {
-  final _ReductionKind kind;
-  final Node node;
-
-  int get hashCode {
-    return (node.hashCode << 3) | kind.index;
-  }
-
-  _ReductionTask(this.kind, this.node) {
-    assert(node is Continuation ||
-        node is LetPrim ||
-        node is Parameter ||
-        node is Branch);
-  }
-
-  bool operator ==(_ReductionTask that) {
-    return (that.kind == this.kind && that.node == this.node);
-  }
-
-  String toString() => "$kind: $node";
-}
diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
deleted file mode 100644
index a2bb010..0000000
--- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
+++ /dev/null
@@ -1,615 +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.type_mask_system;
-
-import '../closure.dart' show ClosureFieldElement, BoxLocal, TypeVariableLocal;
-import '../common/names.dart' show Identifiers;
-import '../compiler.dart' as dart2js show Compiler;
-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/constants.dart' show computeTypeMask;
-import '../types/types.dart';
-import '../universe/selector.dart' show Selector;
-import '../world.dart' show World;
-
-class TypeMaskSystem implements AbstractValueDomain {
-  final TypesTask inferrer;
-  final World classWorld;
-  final JavaScriptBackend backend;
-
-  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;
-
-  @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;
-  }
-
-  @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 {}
-
-  @override
-  bool methodIgnoresReceiverArgument(FunctionElement function) {
-    assert(backend.isInterceptedMethod(function));
-    ClassElement clazz = function.enclosingClass.declaration;
-    return !clazz.isSubclassOf(helpers.jsInterceptorClass) &&
-        !classWorld.isUsedAsMixin(clazz);
-  }
-
-  @override
-  bool targetIgnoresReceiverArgument(TypeMask type, Selector selector) {
-    // Check if any of the possible targets depend on the extra receiver
-    // argument. Mixins do this, and tear-offs always needs the extra receiver
-    // argument because BoundClosure uses it for equality and hash code.
-    // TODO(15933): Make automatically generated property extraction
-    // closures work with the dummy receiver optimization.
-    bool needsReceiver(Element target) {
-      if (target is! FunctionElement) return false;
-      FunctionElement function = target;
-      return selector.isGetter && !function.isGetter ||
-          !methodIgnoresReceiverArgument(function);
-    }
-    return !classWorld.allFunctions.filter(selector, type).any(needsReceiver);
-  }
-
-  @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)) {
-      // If used as a mixin, the receiver could be any of the classes that mix
-      // in the class, and these are not considered subclasses.
-      // TODO(asgerf): Exclude the subtypes that only `implement` the class.
-      return nonNullSubtype(method.enclosingClass);
-    } else {
-      return nonNullSubclass(method.enclosingClass);
-    }
-  }
-
-  @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.
-    if (selector.isGetter &&
-        selector.name == Identifiers.call &&
-        !areDisjoint(functionType, mask)) {
-      result = join(result, functionType);
-    }
-    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);
-  }
-
-  @override
-  TypeMask intersection(TypeMask a, TypeMask b) {
-    if (a == null) return b;
-    if (b == null) return a;
-    return a.intersection(b, classWorld);
-  }
-
-  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.isEmptyOrNull);
-      _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'.
-    ValueTypeMask valueMask = mask;
-    if (valueMask.value.isBool) return valueMask.value;
-    // TODO(sra): Consider other values. Be careful with large strings.
-    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?
-    if (element.isClosure) return functionType;
-    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);
-  }
-
-  /// 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.
-  @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*
-    // double class, so this excludes things that are known to be instances of a
-    // more specific class.
-    // We currently exploit that there are no subclasses of double that are
-    // not integers (e.g. there is no UnsignedDouble class or whatever).
-    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(helpers.jsPositiveIntClass, classWorld);
-  }
-
-  @override
-  bool isDefinitelyInt(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().containsOnlyInt(classWorld);
-  }
-
-  @override
-  bool isDefinitelyUint31(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t.satisfies(helpers.jsUInt31Class, classWorld);
-  }
-
-  @override
-  bool isDefinitelyUint32(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t.satisfies(helpers.jsUInt32Class, classWorld);
-  }
-
-  @override
-  bool isDefinitelyUint(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t.satisfies(helpers.jsPositiveIntClass, classWorld);
-  }
-
-  @override
-  bool isDefinitelyArray(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(helpers.jsArrayClass, classWorld);
-  }
-
-  @override
-  bool isDefinitelyMutableArray(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(helpers.jsMutableArrayClass, classWorld);
-  }
-
-  @override
-  bool isDefinitelyFixedArray(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t.nonNullable().satisfies(helpers.jsFixedArrayClass, classWorld);
-  }
-
-  @override
-  bool isDefinitelyExtendableArray(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return t
-        .nonNullable()
-        .satisfies(helpers.jsExtendableArrayClass, classWorld);
-  }
-
-  @override
-  bool isDefinitelyIndexable(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    return _indexableTypeTest.containsMask(t.nonNullable(), classWorld);
-  }
-
-  @override
-  bool isDefinitelyMutableIndexable(TypeMask t, {bool allowNull: false}) {
-    if (!allowNull && t.isNullable) return false;
-    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);
-  }
-
-  @override
-  bool isDefinitelyIntercepted(TypeMask t, {bool allowNull}) {
-    assert(allowNull != null);
-    if (!allowNull && t.isNullable) return false;
-    return interceptedTypes.containsMask(t.nonNullable(), classWorld);
-  }
-
-  @override
-  bool isDefinitelySelfInterceptor(TypeMask t, {bool allowNull: false}) {
-    assert(allowNull != null);
-    if (!allowNull && t.isNullable) return false;
-    return areDisjoint(t, interceptorType);
-  }
-
-  /// 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) =>
-      leftType.isDisjoint(rightType, classWorld);
-
-  @override
-  bool isMorePreciseOrEqual(TypeMask t1, TypeMask t2) {
-    return t2.containsMask(t1, classWorld);
-  }
-
-  @override
-  AbstractBool isSubtypeOf(TypeMask value, types.DartType type,
-      {bool allowNull}) {
-    assert(allowNull != null);
-    if (type is types.DynamicType) {
-      return AbstractBool.True;
-    }
-    if (type is types.InterfaceType) {
-      TypeMask typeAsMask = allowNull
-          ? new TypeMask.subtype(type.element, classWorld)
-          : new TypeMask.nonNullSubtype(type.element, classWorld);
-      if (areDisjoint(value, typeAsMask)) {
-        // Disprove the subtype relation based on the class alone.
-        return AbstractBool.False;
-      }
-      if (!type.treatAsRaw) {
-        // If there are type arguments, we cannot prove the subtype relation,
-        // because the type arguments are unknown on both the value and type.
-        return AbstractBool.Maybe;
-      }
-      if (typeAsMask.containsMask(value, classWorld)) {
-        // All possible values are contained in the set of allowed values.
-        // Note that we exploit the fact that [typeAsMask] is an exact
-        // representation of [type], not an approximation.
-        return AbstractBool.True;
-      }
-      // The value is neither contained in the type, nor disjoint from the type.
-      return AbstractBool.Maybe;
-    }
-    // TODO(asgerf): Support function types, and what else might be missing.
-    return AbstractBool.Maybe;
-  }
-
-  /// 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;
-    }
-    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;
-      if (element.isObject) {
-        return dynamicType;
-      }
-      if (element == classWorld.nullClass) {
-        return nullType;
-      }
-      if (element == classWorld.stringClass) {
-        return stringType;
-      }
-      if (element == classWorld.numClass || element == classWorld.doubleClass) {
-        return numType;
-      }
-      if (element == classWorld.intClass) {
-        return intType;
-      }
-      if (element == classWorld.boolClass) {
-        return boolType;
-      }
-      return new TypeMask.nonNullSubtype(element, classWorld);
-    }
-    if (type is types.FunctionType) {
-      return functionType;
-    }
-    return dynamicType;
-  }
-
-  /// 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(
-          type.disjointMasks.map(elementTypeOfIndexable), classWorld);
-    }
-    if (type is ContainerTypeMask) {
-      return type.elementType;
-    }
-    if (isDefinitelyString(type)) {
-      return stringType;
-    }
-    if (type.satisfies(helpers.jsIndexingBehaviorInterface, classWorld)) {
-      return getInvokeReturnType(new Selector.index(), type);
-    }
-    return dynamicType;
-  }
-
-  /// The length of something of [type], or `null` if unknown.
-  @override
-  int getContainerLength(TypeMask type) {
-    if (type is ContainerTypeMask) {
-      return type.length;
-    } else {
-      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
deleted file mode 100644
index 4ee963c..0000000
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ /dev/null
@@ -1,3504 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library dart2js.cps_ir.type_propagation;
-
-import 'optimizers.dart';
-
-import '../closure.dart' show ClosureClassElement;
-import '../common.dart';
-import '../common/names.dart' show Identifiers, Selectors;
-import '../compiler.dart' as dart2js show Compiler;
-import '../constants/constant_system.dart';
-import '../constants/values.dart';
-import '../dart_types.dart' as types;
-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 CpsFunctionCompiler;
-import '../resolution/operators.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;
-import 'cps_fragment.dart';
-import 'cps_ir_nodes.dart';
-import 'type_mask_system.dart';
-import 'effects.dart';
-
-class ConstantPropagationLattice {
-  final TypeMaskSystem typeSystem;
-  final ConstantSystem constantSystem;
-  final types.DartTypes dartTypes;
-  final AbstractConstantValue anything;
-  final AbstractConstantValue nothing = new AbstractConstantValue.nothing();
-  final AbstractConstantValue nullValue;
-  final AbstractConstantValue trueValue;
-  final AbstractConstantValue falseValue;
-
-  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()),
-        trueValue = new AbstractConstantValue.constantValue(
-            new TrueConstantValue(), functionCompiler.typeSystem.boolType),
-        falseValue = new AbstractConstantValue.constantValue(
-            new FalseConstantValue(), functionCompiler.typeSystem.boolType);
-
-  AbstractConstantValue constant(ConstantValue value, [TypeMask type]) {
-    if (type == null) type = typeSystem.getTypeOf(value);
-    return new AbstractConstantValue.constantValue(value, type);
-  }
-
-  AbstractConstantValue nonConstant([TypeMask type]) {
-    if (type == null) type = typeSystem.dynamicType;
-    return new AbstractConstantValue.nonConstant(type);
-  }
-
-  /// Compute the join of two values in the lattice.
-  AbstractConstantValue join(AbstractConstantValue x, AbstractConstantValue y) {
-    assert(x != null);
-    assert(y != null);
-
-    if (x.isNothing) {
-      return y;
-    } else if (y.isNothing) {
-      return x;
-    } else if (x.isConstant && y.isConstant && x.constant == y.constant) {
-      return x;
-    } else {
-      return new AbstractConstantValue.nonConstant(
-          typeSystem.join(x.type, y.type));
-    }
-  }
-
-  /// True if all members of this value are booleans.
-  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(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(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(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(AbstractConstantValue value) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyNotNumStringBool(value.type);
-  }
-
-  /// True if this value cannot be a non-integer double.
-  ///
-  /// 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(AbstractConstantValue value) {
-    return value.isNothing ||
-        value.isConstant && !value.constant.isDouble ||
-        typeSystem.isDefinitelyNotNonIntegerDouble(value.type);
-  }
-
-  bool isDefinitelyInt(AbstractConstantValue value, {bool allowNull: false}) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyInt(value.type, allowNull: allowNull);
-  }
-
-  bool isDefinitelyUint31(AbstractConstantValue value,
-      {bool allowNull: false}) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyUint31(value.type, allowNull: allowNull);
-  }
-
-  bool isDefinitelyUint32(AbstractConstantValue value,
-      {bool allowNull: false}) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyUint32(value.type, allowNull: allowNull);
-  }
-
-  bool isDefinitelyUint(AbstractConstantValue value, {bool allowNull: false}) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyUint(value.type, allowNull: allowNull);
-  }
-
-  bool isDefinitelyArray(AbstractConstantValue value, {bool allowNull: false}) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyArray(value.type, allowNull: allowNull);
-  }
-
-  bool isDefinitelyMutableArray(AbstractConstantValue value,
-      {bool allowNull: false}) {
-    return value.isNothing ||
-        typeSystem.isDefinitelyMutableArray(value.type, allowNull: allowNull);
-  }
-
-  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.isDefinitelyExtendableArray(value.type,
-            allowNull: allowNull);
-  }
-
-  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(AbstractConstantValue value, {int min, int max}) {
-    if (value.isNothing) return true;
-    if (!isDefinitelyInt(value)) return false;
-    PrimitiveConstantValue constant = value.constant;
-    if (constant == null) return false;
-    if (!constant.isInt) return false;
-    if (min != null && constant.primitiveValue < min) return false;
-    if (max != null && constant.primitiveValue > max) return false;
-    return true;
-  }
-
-  /// Returns whether the given [value] is an instance of [type].
-  ///
-  /// Since [value] and [type] are not always known, [AbstractBool.Maybe] is
-  /// returned if the answer is not known.
-  ///
-  /// [AbstractBool.Nothing] is returned if [value] is nothing.
-  ///
-  /// 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(AbstractConstantValue value, types.DartType type,
-      {bool allowNull}) {
-    assert(allowNull != null);
-    if (value.isNothing) {
-      return AbstractBool.Nothing;
-    }
-    if (value.isConstant) {
-      if (value.constant.isNull) {
-        if (allowNull ||
-            type.isObject ||
-            type.isDynamic ||
-            type == dartTypes.coreTypes.nullType) {
-          return AbstractBool.True;
-        }
-        if (type is types.TypeVariableType) {
-          return AbstractBool.Maybe;
-        }
-        return AbstractBool.False;
-      }
-      if (type == dartTypes.coreTypes.intType) {
-        return constantSystem.isInt(value.constant)
-            ? AbstractBool.True
-            : AbstractBool.False;
-      }
-      types.DartType valueType = value.constant.getType(dartTypes.coreTypes);
-      if (constantSystem.isSubtype(dartTypes, valueType, type)) {
-        return AbstractBool.True;
-      }
-      if (!dartTypes.isPotentialSubtype(valueType, type)) {
-        return AbstractBool.False;
-      }
-      return AbstractBool.Maybe;
-    }
-    return typeSystem.isSubtypeOf(value.type, type, allowNull: allowNull);
-  }
-
-  /// Returns the possible results of applying [operator] to [value],
-  /// assuming the operation does not throw.
-  ///
-  /// Because we do not explicitly track thrown values, we currently use the
-  /// convention that constant values are returned from this method only
-  /// if the operation is known not to throw.
-  ///
-  /// 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.
-  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;
-    }
-    if (value.isConstant) {
-      UnaryOperation operation = constantSystem.lookupUnary(operator);
-      ConstantValue result = operation.fold(value.constant);
-      if (result == null) return anything;
-      return constant(result);
-    }
-    return null; // TODO(asgerf): Look up type?
-  }
-
-  /// Returns the possible results of applying [operator] to [left], [right],
-  /// assuming the operation does not throw.
-  ///
-  /// Because we do not explicitly track thrown values, we currently use the
-  /// convention that constant values are returned from this method only
-  /// if the operation is known not to throw.
-  ///
-  /// 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.
-  AbstractConstantValue binaryOp(BinaryOperator operator,
-      AbstractConstantValue left, AbstractConstantValue right) {
-    switch (operator.kind) {
-      case BinaryOperatorKind.ADD:
-        return addSpecial(left, right);
-
-      case BinaryOperatorKind.SUB:
-        return subtractSpecial(left, right);
-
-      case BinaryOperatorKind.MUL:
-        return multiplySpecial(left, right);
-
-      case BinaryOperatorKind.DIV:
-        return divideSpecial(left, right);
-
-      case BinaryOperatorKind.IDIV:
-        return truncatingDivideSpecial(left, right);
-
-      case BinaryOperatorKind.MOD:
-        return moduloSpecial(left, right);
-
-      case BinaryOperatorKind.EQ:
-        return equalSpecial(left, right);
-
-      case BinaryOperatorKind.AND:
-        return andSpecial(left, right);
-
-      case BinaryOperatorKind.OR:
-        return orSpecial(left, right);
-
-      case BinaryOperatorKind.XOR:
-        return xorSpecial(left, right);
-
-      case BinaryOperatorKind.SHL:
-        return shiftLeftSpecial(left, right);
-
-      case BinaryOperatorKind.SHR:
-        return shiftRightSpecial(left, right);
-
-      case BinaryOperatorKind.LT:
-        return lessSpecial(left, right);
-
-      case BinaryOperatorKind.LTEQ:
-        return lessEqualSpecial(left, right);
-
-      case BinaryOperatorKind.GT:
-        return greaterSpecial(left, right);
-
-      case BinaryOperatorKind.GTEQ:
-        return greaterEqualSpecial(left, right);
-
-      default:
-        break;
-    }
-
-    if (left.isNothing || right.isNothing) {
-      return nothing;
-    }
-    if (left.isConstant && right.isConstant) {
-      BinaryOperation operation = constantSystem.lookupBinary(operator);
-      ConstantValue result = operation.fold(left.constant, right.constant);
-      if (result != null) return constant(result);
-    }
-    return null; // The caller will use return type from type inference.
-  }
-
-  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, allowNull: true)) {
-      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);
-      if (result != null) return constant(result);
-    }
-    return null;
-  }
-
-  AbstractConstantValue closedOnInt(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (isDefinitelyInt(left, allowNull: true) &&
-        isDefinitelyInt(right, allowNull: true)) {
-      return nonConstant(typeSystem.intType);
-    }
-    return null;
-  }
-
-  AbstractConstantValue closedOnUint(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (isDefinitelyUint(left, allowNull: true) &&
-        isDefinitelyUint(right, allowNull: true)) {
-      return nonConstant(typeSystem.uintType);
-    }
-    return null;
-  }
-
-  AbstractConstantValue closedOnUint31(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (isDefinitelyUint31(left, allowNull: true) &&
-        isDefinitelyUint31(right, allowNull: true)) {
-      return nonConstant(typeSystem.uint31Type);
-    }
-    return null;
-  }
-
-  AbstractConstantValue addSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded = foldBinary(constantSystem.add, left, right);
-    if (folded != null) return folded;
-    if (isDefinitelyNum(left, allowNull: true)) {
-      if (isDefinitelyUint31(left, allowNull: true) &&
-          isDefinitelyUint31(right, allowNull: true)) {
-        return nonConstant(typeSystem.uint32Type);
-      }
-      return closedOnUint(left, right) ?? closedOnInt(left, right);
-    }
-    return null;
-  }
-
-  AbstractConstantValue subtractSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.subtract, left, right);
-    return folded ?? closedOnInt(left, right);
-  }
-
-  AbstractConstantValue multiplySpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.multiply, left, right);
-    return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right);
-  }
-
-  AbstractConstantValue divideSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    return foldBinary(constantSystem.divide, left, right);
-  }
-
-  AbstractConstantValue truncatingDivideSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.truncatingDivide, left, right);
-    if (folded != null) return folded;
-    if (isDefinitelyNum(left, allowNull: true)) {
-      if (isDefinitelyUint32(left, allowNull: true) &&
-          isDefinitelyIntInRange(right, min: 2)) {
-        return nonConstant(typeSystem.uint31Type);
-      }
-      if (isDefinitelyUint(right, allowNull: true)) {
-        // `0` will be an exception, other values will shrink the result.
-        if (isDefinitelyUint31(left, allowNull: true)) {
-          return nonConstant(typeSystem.uint31Type);
-        }
-        if (isDefinitelyUint32(left, allowNull: true)) {
-          return nonConstant(typeSystem.uint32Type);
-        }
-        if (isDefinitelyUint(left, allowNull: true)) {
-          return nonConstant(typeSystem.uintType);
-        }
-      }
-      return nonConstant(typeSystem.intType);
-    }
-    return null;
-  }
-
-  AbstractConstantValue moduloSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.modulo, left, right);
-    return folded ?? closedOnUint(left, right) ?? closedOnInt(left, right);
-  }
-
-  AbstractConstantValue remainderSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (left.isNothing || right.isNothing) return nothing;
-    AbstractConstantValue folded = null; // Remainder not in constant system.
-    return folded ?? closedOnUint(left, right) ?? closedOnInt(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) ||
-            right.isNullConstant;
-    if (behavesLikeIdentity && typeSystem.areDisjoint(left.type, right.type)) {
-      return constant(new FalseConstantValue());
-    }
-    return null;
-  }
-
-  AbstractConstantValue andSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.bitAnd, left, right);
-    if (folded != null) return folded;
-    if (isDefinitelyNum(left, allowNull: true)) {
-      if (isDefinitelyUint31(left, allowNull: true) ||
-          isDefinitelyUint31(right, allowNull: true)) {
-        // Either 31-bit argument will truncate the other.
-        return nonConstant(typeSystem.uint31Type);
-      }
-    }
-    return null;
-  }
-
-  AbstractConstantValue orSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.bitOr, left, right);
-    return folded ?? closedOnUint31(left, right);
-  }
-
-  AbstractConstantValue xorSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.bitXor, left, right);
-    return folded ?? closedOnUint31(left, right);
-  }
-
-  AbstractConstantValue shiftLeftSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    return foldBinary(constantSystem.shiftLeft, left, right);
-  }
-
-  AbstractConstantValue shiftRightSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    AbstractConstantValue folded =
-        foldBinary(constantSystem.shiftRight, left, right);
-    if (folded != null) return folded;
-    if (isDefinitelyUint31(left, allowNull: true)) {
-      return nonConstant(typeSystem.uint31Type);
-    } else if (isDefinitelyUint32(left, allowNull: true)) {
-      if (isDefinitelyIntInRange(right, min: 1, max: 31)) {
-        // A zero will be shifted into the 'sign' bit.
-        return nonConstant(typeSystem.uint31Type);
-      }
-      return nonConstant(typeSystem.uint32Type);
-    }
-    return null;
-  }
-
-  AbstractConstantValue lessSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (isDefinitelyUint(left) && right.isZeroOrNegativeConstant) {
-      return falseValue; // "uint < 0" is false.
-    } else if (left.isNegativeConstant && isDefinitelyUint(right)) {
-      return trueValue; // "-1 < uint" is true.
-    }
-    return foldBinary(constantSystem.less, left, right);
-  }
-
-  AbstractConstantValue lessEqualSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (isDefinitelyUint(left) && right.isNegativeConstant) {
-      return falseValue; // "uint <= -1" is false.
-    } else if (left.isZeroOrNegativeConstant && isDefinitelyUint(right)) {
-      return trueValue; // "0 <= uint" is true.
-    }
-    return foldBinary(constantSystem.lessEqual, left, right);
-  }
-
-  AbstractConstantValue greaterSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (left.isZeroOrNegativeConstant && isDefinitelyUint(right)) {
-      return falseValue; // "0 > uint" is false
-    } else if (isDefinitelyUint(left) && right.isNegativeConstant) {
-      return trueValue; // "uint > -1" is true
-    }
-    return foldBinary(constantSystem.greater, left, right);
-  }
-
-  AbstractConstantValue greaterEqualSpecial(
-      AbstractConstantValue left, AbstractConstantValue right) {
-    if (left.isNegativeConstant && isDefinitelyUint(right)) {
-      return falseValue; // "-1 >= uint" is false
-    } else if (isDefinitelyUint(left) && right.isZeroOrNegativeConstant) {
-      return trueValue; // "uint >= 0" is true
-    }
-    return foldBinary(constantSystem.greaterEqual, left, right);
-  }
-
-  AbstractConstantValue intConstant(int value) {
-    return constant(new IntConstantValue(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)));
-  }
-
-  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);
-    }
-    // TODO(asgerf): Handle case where 'left' is a List or Map constant but
-    //               the index is unknown.
-    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;
-    if (constantValue is StringConstantValue) {
-      return value;
-    } else if (constantValue is PrimitiveConstantValue) {
-      // Note: The primitiveValue for a StringConstantValue is not suitable
-      // for toString() use since it is a DartString. But the other subclasses
-      // returns an unwrapped Dart value we can safely convert to a string.
-      return stringConstant(constantValue.primitiveValue.toString());
-    } else {
-      return nonConstant(typeSystem.stringType);
-    }
-  }
-
-  /// Returns whether [value] is one of the falsy values: false, 0, -0, NaN,
-  /// the empty string, or null.
-  AbstractBool boolify(AbstractConstantValue value) {
-    if (value.isNothing) return AbstractBool.Nothing;
-    if (value.isConstant) {
-      ConstantValue constantValue = value.constant;
-      if (isFalsyConstant(constantValue)) {
-        return AbstractBool.False;
-      } else {
-        return AbstractBool.True;
-      }
-    }
-    return typeSystem.boolify(value.type);
-  }
-
-  /// Returns whether [value] is the value `true`.
-  AbstractBool strictBoolify(AbstractConstantValue value) {
-    if (value.isNothing) return AbstractBool.Nothing;
-    if (value.isConstant) {
-      return value.constant.isTrue ? AbstractBool.True : AbstractBool.False;
-    }
-    return typeSystem.strictBoolify(value.type);
-  }
-
-  /// The possible return types of a method that may be targeted by
-  /// [selector] on [receiver].
-  AbstractConstantValue getInvokeReturnType(
-      Selector selector, AbstractConstantValue receiver) {
-    return fromMask(typeSystem.getInvokeReturnType(selector, receiver.type));
-  }
-
-  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());
-  }
-
-  AbstractConstantValue intersectWithType(
-      AbstractConstantValue value, TypeMask type) {
-    if (value.isNothing || typeSystem.areDisjoint(value.type, type)) {
-      return nothing;
-    } else if (value.isConstant) {
-      return value;
-    } else {
-      return nonConstant(typeSystem.intersection(value.type, type));
-    }
-  }
-
-  /// 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;
-  }
-}
-
-/**
- * Propagates types (including value types for constants) throughout the IR, and
- * replaces branches with fixed jumps as well as side-effect free expressions
- * with known constant results.
- *
- * Should be followed by the [ShrinkingReducer] pass.
- *
- * Implemented according to 'Constant Propagation with Conditional Branches'
- * by Wegman, Zadeck.
- */
-class TypePropagator extends Pass {
-  String get passName => 'Type propagation';
-
-  final CpsFunctionCompiler _functionCompiler;
-  final Map<Variable, ConstantValue> _values = <Variable, ConstantValue>{};
-  final ConstantPropagationLattice _lattice;
-  final bool recomputeAll;
-
-  TypePropagator(CpsFunctionCompiler functionCompiler,
-      {this.recomputeAll: false})
-      : _functionCompiler = functionCompiler,
-        _lattice = new ConstantPropagationLattice(functionCompiler);
-
-  dart2js.Compiler get _compiler => _functionCompiler.compiler;
-  InternalErrorFunction get _internalError => _compiler.reporter.internalError;
-
-  @override
-  void rewrite(FunctionDefinition root) {
-    // Analyze. In this phase, the entire term is analyzed for reachability
-    // and the abstract value of each expression.
-    TypePropagationVisitor analyzer =
-        new TypePropagationVisitor(_lattice, _values, _internalError);
-
-    analyzer.analyze(root, recomputeAll);
-
-    // Transform. Uses the data acquired in the previous analysis phase to
-    // replace branches with fixed targets and side-effect-free expressions
-    // with constant results or existing values that are in scope.
-    TransformingVisitor transformer = new TransformingVisitor(
-        _compiler, _functionCompiler, _lattice, analyzer, _internalError);
-    transformer.transform(root);
-  }
-}
-
-final Map<String, BuiltinOperator> NumBinaryBuiltins =
-    const <String, BuiltinOperator>{
-  '+': BuiltinOperator.NumAdd,
-  '-': BuiltinOperator.NumSubtract,
-  '*': BuiltinOperator.NumMultiply,
-  '/': BuiltinOperator.NumDivide,
-  '&': BuiltinOperator.NumAnd,
-  '|': BuiltinOperator.NumOr,
-  '^': BuiltinOperator.NumXor,
-  '<': BuiltinOperator.NumLt,
-  '<=': BuiltinOperator.NumLe,
-  '>': BuiltinOperator.NumGt,
-  '>=': BuiltinOperator.NumGe
-};
-
-/**
- * Uses the information from a preceding analysis pass in order to perform the
- * actual transformations on the CPS graph.
- */
-class TransformingVisitor extends DeepRecursiveVisitor {
-  final TypePropagationVisitor analyzer;
-  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;
-
-  final List<Node> stack = <Node>[];
-
-  TypeCheckOperator checkIsNumber;
-
-  TransformingVisitor(this.compiler, this.functionCompiler, this.lattice,
-      this.analyzer, this.internalError) {
-    checkIsNumber = new ClassTypeCheckOperator(
-        helpers.jsNumberClass, BuiltinOperator.IsNotNumber);
-  }
-
-  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());
-    }
-  }
-
-  void push(Node node) {
-    assert(node != null);
-    stack.add(node);
-  }
-
-  void pushAll(Iterable<Node> nodes) {
-    nodes.forEach(push);
-  }
-
-  /************************* INTERIOR EXPRESSIONS *************************/
-  //
-  // These return nothing, and must push recursive children on the stack.
-
-  void visitLetCont(LetCont node) {
-    pushAll(node.continuations);
-    push(node.body);
-  }
-
-  void visitLetHandler(LetHandler node) {
-    push(node.handler);
-    push(node.body);
-  }
-
-  void visitLetMutable(LetMutable node) {
-    visit(node.variable);
-    push(node.body);
-  }
-
-  void visitLetPrim(LetPrim node) {
-    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).isNullConstant;
-    }
-    if (prim is SetIndex) {
-      return getValue(prim.object).isNullConstant;
-    }
-    // If a primitive has a value, but can't return anything, it must throw
-    // or diverge.
-    return prim.hasValue && prim.type.isEmpty;
-  }
-
-  void visitContinuation(Continuation node) {
-    if (node.isReturnContinuation) return;
-    if (!analyzer.reachableContinuations.contains(node)) {
-      replaceSubtree(node.body, new Unreachable());
-    }
-    // Process the continuation body.
-    // Note that the continuation body may have changed since the continuation
-    // was put on the stack (e.g. [visitInvokeContinuation] may do this).
-    push(node.body);
-  }
-
-  /************************* TRANSFORMATION HELPERS *************************/
-
-  /// Sets parent pointers and computes types for the given subtree.
-  void reanalyze(Node node) {
-    ParentVisitor.setParents(node);
-    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].
-  ///
-  /// 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, 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;
-    RemovalVisitor.remove(node);
-    reanalyze(replacement);
-  }
-
-  /// Inserts [insertedCode] before [node].
-  ///
-  /// [node] will end up in the hole of [insertedCode], and [insertedCode]
-  /// will become rooted where [node] was.
-  void insertBefore(Expression node, CpsFragment insertedCode) {
-    if (insertedCode.isEmpty) return; // Nothing to do.
-    assert(insertedCode.isOpen);
-    InteriorNode parent = node.parent;
-    InteriorNode context = insertedCode.context;
-
-    parent.body = insertedCode.root;
-    insertedCode.root.parent = parent;
-
-    // We want to recompute the types for [insertedCode] without
-    // traversing the entire subtree of [node]. Temporarily close the
-    // term with a dummy node while recomputing types.
-    context.body = new Unreachable();
-    reanalyze(insertedCode.root);
-
-    context.body = node;
-    node.parent = context;
-  }
-
-  /// Make a constant primitive for [constant] and set its entry in [values].
-  Constant makeConstantPrimitive(ConstantValue constant) {
-    Constant primitive = new Constant(constant);
-    primitive.type = typeSystem.getTypeOf(constant);
-    values[primitive] = constant;
-    return primitive;
-  }
-
-  /// Builds `(LetPrim p (InvokeContinuation k p))`.
-  ///
-  /// No parent pointers are set.
-  LetPrim makeLetPrimInvoke(Primitive primitive, Continuation continuation) {
-    assert(continuation.parameters.length == 1);
-
-    LetPrim letPrim = new LetPrim(primitive);
-    InvokeContinuation invoke =
-        new InvokeContinuation(continuation, <Primitive>[primitive]);
-    letPrim.body = invoke;
-    values[primitive] = values[continuation.parameters.single];
-    primitive.hint = continuation.parameters.single.hint;
-
-    return letPrim;
-  }
-
-  /************************* TAIL EXPRESSIONS *************************/
-
-  // A branch can be eliminated and replaced by an invocation if only one of
-  // the possible continuations is reachable. Removal often leads to both dead
-  // primitives (the condition variable) and dead continuations (the unreachable
-  // branch), which are both removed by the shrinking reductions pass.
-  //
-  // (Branch (IsTrue true) k0 k1) -> (InvokeContinuation k0)
-  void visitBranch(Branch node) {
-    Continuation trueCont = node.trueContinuation;
-    Continuation falseCont = node.falseContinuation;
-    Primitive condition = node.condition;
-    AbstractConstantValue conditionValue = getValue(condition);
-
-    // Change to non-strict check if the condition is a boolean or null.
-    if (lattice.isDefinitelyBool(conditionValue, allowNull: true)) {
-      node.isStrictCheck = false;
-    }
-
-    AbstractBool boolifiedValue = node.isStrictCheck
-        ? lattice.strictBoolify(conditionValue)
-        : lattice.boolify(conditionValue);
-
-    if (boolifiedValue == AbstractBool.True) {
-      replaceSubtree(falseCont.body, new Unreachable());
-      InvokeContinuation invoke = new InvokeContinuation(trueCont, []);
-      replaceSubtree(node, invoke);
-      push(invoke);
-      return;
-    }
-    if (boolifiedValue == AbstractBool.False) {
-      replaceSubtree(trueCont.body, new Unreachable());
-      InvokeContinuation invoke = new InvokeContinuation(falseCont, []);
-      replaceSubtree(node, invoke);
-      push(invoke);
-      return;
-    }
-
-    // Shortcut negation to help simplify control flow. The tree IR will insert
-    // a negation again if that's useful.
-    if (condition is ApplyBuiltinOperator &&
-        condition.operator == BuiltinOperator.IsFalsy) {
-      node.conditionRef.changeTo(condition.argument(0));
-      node.trueContinuationRef.changeTo(falseCont);
-      node.falseContinuationRef.changeTo(trueCont);
-      return;
-    }
-  }
-
-  void visitInvokeContinuation(InvokeContinuation node) {
-    // Inline the single-use continuations. These are often introduced when
-    // specializing an invocation node. These would also be inlined by a later
-    // pass, but doing it here helps simplify pattern matching code, since the
-    // effective definition of a primitive can then be found without going
-    // through redundant InvokeContinuations.
-    Continuation cont = node.continuation;
-    if (cont.hasExactlyOneUse &&
-        !cont.isReturnContinuation &&
-        !cont.isRecursive &&
-        !node.isEscapingTry) {
-      for (int i = 0; i < node.argumentRefs.length; ++i) {
-        Primitive argument = node.argument(i);
-        Parameter parameter = cont.parameters[i];
-        argument.useElementAsHint(parameter.hint);
-        parameter.replaceUsesWith(argument);
-        node.argumentRefs[i].unlink();
-      }
-      node.continuationRef.unlink();
-      InteriorNode parent = node.parent;
-      Expression body = cont.body;
-      parent.body = body;
-      body.parent = parent;
-      cont.body = new Unreachable();
-      cont.body.parent = cont;
-      push(body);
-    }
-  }
-
-  /// Returns the possible targets of [selector] when invoked on a receiver
-  /// of type [receiverType].
-  Iterable<Element> getAllTargets(TypeMask receiverType, Selector selector) {
-    return compiler.world.allFunctions.filter(selector, receiverType);
-  }
-
-  /************************* CALL EXPRESSIONS *************************/
-
-  /// Replaces [node] with a more specialized instruction, if possible.
-  ///
-  /// Returns `true` if the node was replaced.
-  specializeOperatorCall(InvokeMethod node) {
-    if (!backend.isInterceptedSelector(node.selector)) return null;
-    if (node.argumentRefs.length > 1) return null;
-    if (node.callingConvention == CallingConvention.OneShotIntercepted) {
-      return null;
-    }
-
-    bool trustPrimitives = compiler.options.trustPrimitives;
-
-    /// Check that the receiver and argument satisfy the given type checks, and
-    /// throw a [NoSuchMethodError] or [ArgumentError] if the check fails.
-    CpsFragment makeGuard(TypeCheckOperator receiverGuard,
-        [TypeCheckOperator argumentGuard]) {
-      CpsFragment cps = new CpsFragment(node.sourceInformation);
-
-      // Make no guards if trusting primitives.
-      if (trustPrimitives) return cps;
-
-      // Determine which guards are needed.
-      ChecksNeeded receiverChecks =
-          receiverGuard.getChecksNeeded(node.receiver, classWorld);
-      bool needReceiverGuard = receiverChecks != ChecksNeeded.None;
-      bool needArgumentGuard = argumentGuard != null &&
-          argumentGuard.needsCheck(node.argument(0), classWorld);
-
-      if (!needReceiverGuard && !needArgumentGuard) return cps;
-
-      // If we only need the receiver check, emit the specialized receiver
-      // check instruction. Examples:
-      //
-      //   if (typeof receiver !== "number") return receiver.$lt;
-      //   if (typeof receiver !== "number") return receiver.$lt();
-      //
-      if (!needArgumentGuard) {
-        Primitive condition = receiverGuard.makeCheck(cps, node.receiver);
-        cps.letPrim(new ReceiverCheck(
-            node.receiver, node.selector, node.sourceInformation,
-            condition: condition,
-            useSelector: true,
-            isNullCheck: receiverChecks == ChecksNeeded.Null));
-        return cps;
-      }
-
-      // TODO(asgerf): We should consider specialized instructions for
-      //   argument checks and receiver+argument checks, to avoid breaking up
-      //   basic blocks.
-
-      // Emit as `H.iae(x)` if only the argument check may fail. For example:
-      //
-      //   if (typeof argument !== "number") return H.iae(argument);
-      //
-      if (!needReceiverGuard) {
-        cps
-            .ifTruthy(argumentGuard.makeCheck(cps, node.argument(0)))
-            .invokeStaticThrower(
-                helpers.throwIllegalArgumentException, [node.argument(0)]);
-        return cps;
-      }
-
-      // Both receiver and argument check is needed. Emit as a combined check
-      // using a one-shot interceptor to produce the exact error message in
-      // the error case.  For example:
-      //
-      //   if (typeof receiver !== "number" || typeof argument !== "number")
-      //       return J.$lt(receiver, argument);
-      //
-      Continuation fail = cps.letCont();
-      cps
-          .ifTruthy(receiverGuard.makeCheck(cps, node.receiver))
-          .invokeContinuation(fail);
-      cps
-          .ifTruthy(argumentGuard.makeCheck(cps, node.argument(0)))
-          .invokeContinuation(fail);
-
-      cps.insideContinuation(fail)
-        ..invokeMethod(
-            node.receiver, node.selector, node.mask, [node.argument(0)],
-            callingConvention: CallingConvention.OneShotIntercepted)
-        ..put(new Unreachable());
-
-      return cps;
-    }
-
-    /// Replaces the call with [operator], using the receiver and first argument
-    /// as operands (in that order).
-    ///
-    /// If [guard] is given, the receiver and argument are both checked using
-    /// that operator.
-    CpsFragment makeBinary(BuiltinOperator operator,
-        {TypeCheckOperator guard: TypeCheckOperator.none}) {
-      CpsFragment cps = makeGuard(guard, guard);
-      Primitive left = guard.makeRefinement(cps, node.receiver, classWorld);
-      Primitive right = guard.makeRefinement(cps, node.argument(0), classWorld);
-      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,
-        {TypeCheckOperator guard: TypeCheckOperator.none}) {
-      CpsFragment cps = makeGuard(guard);
-      Primitive argument = guard.makeRefinement(cps, node.receiver, classWorld);
-      Primitive result = cps.applyBuiltin(operator, [argument]);
-      result.hint = node.hint;
-      node.replaceUsesWith(result);
-      return cps;
-    }
-
-    Selector renameToOptimizedSelector(String name) {
-      return new Selector.call(
-          new Name(name, backend.helpers.interceptorsLibrary),
-          node.selector.callStructure);
-    }
-
-    /// Replaces the call with a call to [name] with the same inputs.
-    InvokeMethod makeRenamedInvoke(String name) {
-      return new InvokeMethod(node.receiver, renameToOptimizedSelector(name),
-          node.mask, node.arguments.toList(),
-          sourceInformation: node.sourceInformation,
-          callingConvention: node.callingConvention,
-          interceptor: node.interceptor);
-    }
-
-    TypeMask successType =
-        typeSystem.receiverTypeFor(node.selector, node.receiver.type);
-
-    if (node.selector.isOperator && node.argumentRefs.length == 1) {
-      Primitive leftArg = node.receiver;
-      Primitive rightArg = node.argument(0);
-      AbstractConstantValue left = getValue(leftArg);
-      AbstractConstantValue right = getValue(rightArg);
-
-      String opname = node.selector.name;
-      if (opname == '==') {
-        // Equality is special due to its treatment of null values and the
-        // 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 makeBinary(BuiltinOperator.Identical);
-        }
-        // There are several implementations of == that behave like identical.
-        // Specialize it if we definitely call one of those.
-        bool behavesLikeIdentical = true;
-        for (Element target in getAllTargets(left.type, node.selector)) {
-          ClassElement clazz = target.enclosingClass.declaration;
-          if (clazz != compiler.world.objectClass &&
-              clazz != helpers.jsInterceptorClass &&
-              clazz != helpers.jsNullClass) {
-            behavesLikeIdentical = false;
-            break;
-          }
-        }
-        if (behavesLikeIdentical) {
-          return makeBinary(BuiltinOperator.Identical);
-        }
-      } else {
-        if (typeSystem.isDefinitelyNum(successType)) {
-          // Try to insert a numeric operator.
-          BuiltinOperator operator = NumBinaryBuiltins[opname];
-          if (operator != null) {
-            return makeBinary(operator, guard: checkIsNumber);
-          }
-
-          // The following specializations only apply to integers.
-          // The Math.floor test is quite large, so we only apply these in cases
-          // where the guard does not involve Math.floor.
-
-          // 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, allowNull: true) &&
-              lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
-            return makeBinary(BuiltinOperator.NumShl, guard: checkIsNumber);
-          }
-          // 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 == '>>') {
-            if (lattice.isDefinitelyUint32(left, allowNull: true) &&
-                lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
-              return makeBinary(BuiltinOperator.NumShr, guard: checkIsNumber);
-            } else if (lattice.isDefinitelyUint(left) &&
-                lattice.isDefinitelyUint(right)) {
-              return makeRenamedInvoke('_shrBothPositive');
-            } else if (lattice.isDefinitelyUint(left) &&
-                lattice.isDefinitelyNum(right)) {
-              return makeRenamedInvoke('_shrReceiverPositive');
-            } else if (lattice.isDefinitelyNum(left) &&
-                lattice.isDefinitelyUint(right)) {
-              return makeRenamedInvoke('_shrOtherPositive');
-            }
-          }
-          // Try to use remainder for '%'. Both operands must be non-negative
-          // and the divisor must be non-zero.
-          if (opname == '%' &&
-              lattice.isDefinitelyUint(left, allowNull: true) &&
-              lattice.isDefinitelyUint(right) &&
-              lattice.isDefinitelyIntInRange(right, min: 1)) {
-            return makeBinary(BuiltinOperator.NumRemainder,
-                guard: checkIsNumber);
-          }
-
-          if (opname == '~/' &&
-              lattice.isDefinitelyUint32(left, allowNull: true) &&
-              lattice.isDefinitelyIntInRange(right, min: 2)) {
-            return makeBinary(BuiltinOperator.NumTruncatingDivideToSigned32,
-                guard: checkIsNumber);
-          }
-        }
-        if (lattice.isDefinitelyString(left, allowNull: trustPrimitives) &&
-            lattice.isDefinitelyString(right, allowNull: trustPrimitives) &&
-            opname == '+') {
-          // TODO(asgerf): Add IsString builtin so we can use a guard here.
-          return makeBinary(BuiltinOperator.StringConcatenate);
-        }
-      }
-    }
-    if (node.selector.isOperator && node.argumentRefs.length == 0) {
-      if (typeSystem.isDefinitelyNum(successType)) {
-        String opname = node.selector.name;
-        if (opname == '~') {
-          return makeUnary(BuiltinOperator.NumBitNot, guard: checkIsNumber);
-        }
-        if (opname == 'unary-') {
-          return makeUnary(BuiltinOperator.NumNegate, guard: checkIsNumber);
-        }
-      }
-    }
-    if (node.selector.isCall) {
-      String name = node.selector.name;
-      Primitive receiver = node.receiver;
-      AbstractConstantValue receiverValue = getValue(receiver);
-      if (name == 'remainder') {
-        if (node.argumentRefs.length == 1) {
-          Primitive arg = node.argument(0);
-          AbstractConstantValue argValue = getValue(arg);
-          if (lattice.isDefinitelyInt(receiverValue, allowNull: true) &&
-              lattice.isDefinitelyInt(argValue) &&
-              isIntNotZero(argValue)) {
-            return makeBinary(BuiltinOperator.NumRemainder,
-                guard: checkIsNumber);
-          }
-        }
-      } else if (name == 'codeUnitAt') {
-        if (node.argumentRefs.length == 1) {
-          Primitive index = node.argument(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;
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  /// Returns `true` if [value] represents an int value that cannot be zero.
-  bool isIntNotZero(AbstractConstantValue value) {
-    return lattice.isDefinitelyIntInRange(value, min: 1) ||
-        lattice.isDefinitelyIntInRange(value, max: -1);
-  }
-
-  bool isInterceptedSelector(Selector selector) {
-    return backend.isInterceptedSelector(selector);
-  }
-
-  /// 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.
-  specializeFieldAccess(InvokeMethod node) {
-    AbstractConstantValue receiver = getValue(node.receiver);
-    Element target =
-        typeSystem.locateSingleElement(receiver.type, node.selector);
-    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 (backend.isNative(target) || backend.isJsInterop(target)) {
-      return null;
-    }
-    if (node.selector.isGetter) {
-      return new GetField(node.receiver, target);
-    } else if (node.selector.isSetter) {
-      if (target.isFinal) return null;
-      assert(node.hasNoUses);
-      return new SetField(node.receiver, target, node.argument(0));
-    } else if (node.selector.isCall) {
-      CpsFragment cps = new CpsFragment(node.sourceInformation);
-      Primitive fieldValue = cps.letPrim(new GetField(node.receiver, target));
-      Primitive result = cps.invokeMethod(
-          fieldValue,
-          new Selector.callClosureFrom(node.selector),
-          typeSystem.getFieldType(target),
-          node.arguments.toList());
-      node.replaceUsesWith(result);
-      return cps;
-    } else {
-      return null;
-    }
-  }
-
-  /// Create a check that throws if [index] is not a valid index on [list].
-  ///
-  /// This function assumes that [index] is an integer.
-  ///
-  /// Returns a CPS fragment whose context is the branch where no error
-  /// was thrown.
-  Primitive makeBoundsCheck(CpsFragment cps, Primitive list, Primitive index,
-      [int checkKind = BoundsCheck.BOTH_BOUNDS | BoundsCheck.INTEGER]) {
-    if (compiler.options.trustPrimitives) {
-      return cps.letPrim(new BoundsCheck.noCheck(list, cps.sourceInformation));
-    } else {
-      GetLength length = cps.letPrim(new GetLength(list));
-      list = cps.refine(list, typeSystem.nonNullType);
-      BoundsCheck check = cps.letPrim(new BoundsCheck(
-          list, index, length, checkKind, cps.sourceInformation));
-      if (check.hasIntegerCheck) {
-        if (typeSystem.isDefinitelyInt(index.type)) {
-          check.checks &= ~BoundsCheck.INTEGER;
-        } else {
-          cps.refine(index, typeSystem.uint32Type);
-        }
-      }
-      return check;
-    }
-  }
-
-  /// Create a check that throws if the length of [list] is not equal to
-  /// [originalLength].
-  ///
-  /// Returns a CPS fragment whose context is the branch where no error
-  /// was thrown.
-  CpsFragment makeConcurrentModificationCheck(
-      Primitive list, Primitive originalLength, SourceInformation sourceInfo) {
-    CpsFragment cps = new CpsFragment(sourceInfo);
-    Primitive lengthChanged = cps.applyBuiltin(BuiltinOperator.StrictNeq,
-        <Primitive>[originalLength, cps.letPrim(new GetLength(list))]);
-    cps.ifTruthy(lengthChanged).invokeStaticThrower(
-        helpers.throwConcurrentModificationError, <Primitive>[list]);
-    return cps;
-  }
-
-  /// Tries to replace [node] with a direct `length` or index access.
-  ///
-  /// Returns `true` if the node was replaced.
-  specializeIndexableAccess(InvokeMethod node) {
-    Primitive receiver = node.receiver;
-    AbstractConstantValue receiverValue = getValue(receiver);
-    if (!typeSystem.isDefinitelyIndexable(receiverValue.type,
-        allowNull: true)) {
-      return null;
-    }
-    switch (node.selector.name) {
-      case 'length':
-        if (node.selector.isGetter) {
-          return new GetLength(receiver);
-        }
-        if (node.selector.isSetter) {
-          if (!typeSystem.isDefinitelyExtendableArray(receiver.type,
-              allowNull: true)) {
-            return null;
-          }
-          CpsFragment cps = new CpsFragment(node.sourceInformation);
-          Primitive newLength = node.argument(0);
-          if (!typeSystem.isDefinitelyUint(newLength.type)) {
-            // TODO(asgerf): We could let the SetLength instruction throw for
-            // negative right-hand sides (see length setter in js_array.dart).
-            if (compiler.options.trustPrimitives) {
-              newLength = cps.refine(newLength, typeSystem.uint32Type);
-              newLength.type = typeSystem.uint32Type;
-            } else {
-              return null;
-            }
-          }
-          cps.letPrim(new ApplyBuiltinMethod(BuiltinMethod.SetLength, receiver,
-              [newLength], node.sourceInformation));
-          if (!typeSystem.isDefinitelyUint32(newLength.type)) {
-            // If the setter succeeded, the length must have been a uint32.
-            cps.refine(newLength, typeSystem.uint32Type);
-          }
-          return cps;
-        }
-        return null;
-
-      case '[]':
-        Primitive index = node.argument(0);
-        CpsFragment cps = new CpsFragment(node.sourceInformation);
-        receiver = makeBoundsCheck(cps, receiver, index);
-        GetIndex get = cps.letPrim(new GetIndex(receiver, index));
-        node.replaceUsesWith(get);
-        // TODO(asgerf): Make replaceUsesWith set the hint?
-        get.hint = node.hint;
-        return cps;
-
-      case '[]=':
-        if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type,
-            allowNull: true)) {
-          return null;
-        }
-        Primitive index = node.argument(0);
-        Primitive value = node.argument(1);
-        CpsFragment cps = new CpsFragment(node.sourceInformation);
-        receiver = makeBoundsCheck(cps, receiver, index);
-        cps.letPrim(new SetIndex(receiver, index, value));
-        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 null;
-    }
-  }
-
-  /// Tries to replace [node] with one or more direct array access operations.
-  ///
-  /// Returns `true` if the node was replaced.
-  CpsFragment specializeArrayAccess(InvokeMethod node) {
-    Primitive list = node.receiver;
-    AbstractConstantValue listValue = getValue(list);
-    // Ensure that the object is a native list or null.
-    if (!lattice.isDefinitelyArray(listValue, allowNull: true)) {
-      return null;
-    }
-    bool isFixedLength =
-        lattice.isDefinitelyFixedArray(listValue, allowNull: true);
-    bool isExtendable =
-        lattice.isDefinitelyExtendableArray(listValue, allowNull: true);
-    SourceInformation sourceInfo = node.sourceInformation;
-    switch (node.selector.name) {
-      case 'add':
-        if (!node.selector.isCall ||
-            node.selector.positionalArgumentCount != 1 ||
-            node.selector.namedArgumentCount != 0) {
-          return null;
-        }
-        if (!isExtendable) return null;
-        Primitive addedItem = node.argument(0);
-        CpsFragment cps = new CpsFragment(sourceInfo);
-        cps.invokeBuiltin(BuiltinMethod.Push, list, <Primitive>[addedItem]);
-        if (node.hasAtLeastOneUse) {
-          node.replaceUsesWith(cps.makeNull());
-        }
-        return cps;
-
-      case 'removeLast':
-        if (!node.selector.isCall || node.selector.argumentCount != 0) {
-          return null;
-        }
-        if (!isExtendable) return null;
-        CpsFragment cps = new CpsFragment(sourceInfo);
-        list = makeBoundsCheck(
-            cps, list, cps.makeMinusOne(), BoundsCheck.EMPTINESS);
-        Primitive removedItem =
-            cps.invokeBuiltin(BuiltinMethod.Pop, list, <Primitive>[]);
-        removedItem.hint = node.hint;
-        node.replaceUsesWith(removedItem);
-        return cps;
-
-      case 'addAll':
-        if (!node.selector.isCall || node.selector.argumentCount != 1) {
-          return null;
-        }
-        if (!isExtendable) return null;
-        Primitive addedList = node.argument(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 null;
-        }
-        LiteralList addedLiteral = addedList;
-        CpsFragment cps = new CpsFragment(sourceInfo);
-        for (Reference value in addedLiteral.valueRefs) {
-          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 null;
-        }
-        if (listValue.isNullable) return null;
-        Primitive index = node.argument(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));
-        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 null;
-        assert(node.selector.positionalArgumentCount == 1);
-        assert(node.selector.namedArgumentCount == 0);
-        FunctionDefinition target = functionCompiler.compileToCpsIr(element);
-
-        CpsFragment cps = new CpsFragment(node.sourceInformation);
-        Primitive result = cps.inlineFunction(
-            target, node.receiver, node.arguments.toList(),
-            interceptor: node.interceptor, hint: node.hint);
-        node.replaceUsesWith(result);
-        return cps;
-
-      case 'iterator':
-        // 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.refinedUses) {
-          if (ref.parent is! InvokeMethod) return null;
-          InvokeMethod use = ref.parent;
-          if (ref != use.receiverRef) return null;
-          if (use.selector != Selectors.moveNext &&
-              use.selector != Selectors.current) {
-            return null;
-          }
-        }
-
-        // Rewrite the iterator variable to 'current' and 'index' variables.
-        Primitive originalLength = new GetLength(list);
-        originalLength.hint = new OriginalLengthEntity();
-        MutableVariable index = new MutableVariable(new LoopIndexEntity());
-        MutableVariable current = new MutableVariable(new LoopItemEntity());
-
-        // Rewrite all uses of the iterator.
-        for (Reference ref in iterator.refinedUses) {
-          InvokeMethod use = ref.parent;
-          if (use.selector == Selectors.current) {
-            // Rewrite iterator.current to a use of the 'current' variable.
-            if (use.hint != null) {
-              // If 'current' was originally moved into a named variable, use
-              // that variable name for the mutable variable.
-              current.hint = use.hint;
-            }
-            use.replaceWith(new GetMutable(current));
-          } else {
-            assert(use.selector == Selectors.moveNext);
-            // Rewrite iterator.moveNext() to:
-            //
-            //   if (index < list.length) {
-            //     current = null;
-            //     continuation(false);
-            //   } else {
-            //     current = list[index];
-            //     index = index + 1;
-            //     continuation(true);
-            //   }
-            //
-            // (The above does not show concurrent modification checks)
-
-            // [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
-            // `index < list.length` from becoming the loop condition, and we
-            // get code like this:
-            //
-            //    while (true) {
-            //      if (originalLength !== list.length) throw;
-            //      if (index < list.length) {
-            //        ...
-            //      } else {
-            //        ...
-            //        break;
-            //      }
-            //    }
-            //
-            // For loops, we therefore check for concurrent modification before
-            // invoking the recursive continuation, so the loop becomes:
-            //
-            //    if (originalLength !== list.length) throw;
-            //    while (index < list.length) {
-            //      ...
-            //      if (originalLength !== list.length) throw;
-            //    }
-            //
-            // The check before the loop can often be eliminated because it
-            // follows immediately after the 'iterator' call.
-            InteriorNode parent = getEffectiveParent(use.parent);
-            if (!isFixedLength) {
-              if (parent is Continuation && parent.isRecursive) {
-                // Check for concurrent modification before every invocation
-                // of the continuation.
-                // TODO(asgerf): Do this in a continuation so multiple
-                //               continues can share the same code.
-                for (Reference ref = parent.firstRef;
-                    ref != null;
-                    ref = ref.next) {
-                  Expression invocationCaller = ref.parent;
-                  if (getEffectiveParent(invocationCaller) == iteratorBinding) {
-                    // No need to check for concurrent modification immediately
-                    // after the call to 'iterator'.
-                    continue;
-                  }
-                  CpsFragment check = makeConcurrentModificationCheck(
-                      list, originalLength, sourceInfo);
-                  insertBefore(invocationCaller, check);
-                }
-              } else {
-                cps.append(makeConcurrentModificationCheck(
-                    list, originalLength, sourceInfo));
-              }
-            }
-
-            // Check if there are more elements.
-            Primitive hasMore = cps.applyBuiltin(BuiltinOperator.NumLt,
-                [cps.getMutable(index), cps.letPrim(new GetLength(list))]);
-
-            // Return false if there are no more.
-            CpsFragment falseBranch = cps.ifFalsy(hasMore);
-            falseBranch
-              ..setMutable(current, falseBranch.makeNull())
-              ..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(moveNextCont, [cps.makeTrue()]);
-
-            reanalyzeFragment(cps);
-
-            // Replace the moveNext() call. It will be visited later.
-            LetPrim let = use.parent;
-            cps.context = moveNextCont;
-            cps.insertBelow(let);
-            let.remove();
-            use
-              ..replaceUsesWith(result)
-              ..destroy();
-          }
-        }
-
-        // All effective uses have been rewritten.
-        destroyRefinementsOfDeadPrimitive(iterator);
-
-        // Rewrite the iterator call to initializers for 'index' and 'current'.
-        CpsFragment cps = new CpsFragment();
-        cps.letMutable(index, cps.makeZero());
-        cps.letMutable(current, cps.makeNull());
-        cps.letPrim(originalLength);
-        return cps;
-
-      default:
-        return null;
-    }
-  }
-
-  /// Returns the first parent of [node] that is not a pure expression.
-  InteriorNode getEffectiveParent(Expression node) {
-    while (true) {
-      InteriorNode parent = node.parent;
-      if (parent is LetCont ||
-          parent is LetPrim && parent.primitive.isSafeForReordering ||
-          parent is LetPrim && parent.primitive is Refinement) {
-        node = parent as dynamic; // Make analyzer accept cross cast.
-      } else {
-        return parent;
-      }
-    }
-  }
-
-  /// Rewrites an invocation of a torn-off method into a method call directly
-  /// on the receiver. For example:
-  ///
-  ///     obj.get$foo().call$<n>(<args>)
-  ///       =>
-  ///     obj.foo$<n>(<args>)
-  ///
-  Primitive specializeClosureCall(InvokeMethod node) {
-    Selector call = node.selector;
-    if (!call.isClosureCall) return null;
-
-    assert(!isInterceptedSelector(call));
-    assert(call.argumentCount == node.argumentRefs.length);
-
-    Primitive tearOff = node.receiver.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.
-
-    if (tearOff is GetStatic && tearOff.element.isFunction) {
-      FunctionElement target = tearOff.element;
-      FunctionSignature signature = target.functionSignature;
-
-      // If the selector does not apply, don't bother (will throw at runtime).
-      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 null;
-
-      // Replace with InvokeStatic.
-      // The tear-off will be cleaned up by shrinking reductions.
-      return new InvokeStatic(target, new Selector.fromElement(target),
-          node.arguments.toList(), node.sourceInformation);
-    }
-    if (tearOff is InvokeMethod && tearOff.selector.isGetter) {
-      Selector getter = tearOff.selector;
-
-      // TODO(asgerf): Support torn-off intercepted methods.
-      if (isInterceptedSelector(getter)) return null;
-
-      LetPrim tearOffBinding = tearOff.parent;
-
-      Primitive object = tearOff.receiver;
-
-      // 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 null;
-
-      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.hasMultipleRefinedUses) return null;
-
-      // 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(
-          object,
-          new Selector.call(getter.memberName, call.callStructure),
-          type,
-          node.arguments.toList(),
-          sourceInformation: node.sourceInformation);
-      node.receiverRef
-          .changeTo(new Parameter(null)); // Remove the tear off use.
-
-      if (tearOff.hasNoRefinedUses) {
-        // 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);
-        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
-        // only get here if the getter has no side effects.
-        assert(isPure);
-      }
-
-      return invoke;
-    }
-    return null;
-  }
-
-  /// Inlines a single-use closure if it leaves the closure object with only
-  /// field accesses.  This is optimized later by [ScalarReplacer].
-  CpsFragment specializeSingleUseClosureCall(InvokeMethod node) {
-    Selector call = node.selector;
-    if (!call.isClosureCall) return null;
-
-    assert(!isInterceptedSelector(call));
-    assert(call.argumentCount == node.argumentRefs.length);
-
-    Primitive receiver = node.receiver;
-    if (receiver is! CreateInstance) return null;
-    CreateInstance createInstance = receiver;
-    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 null;
-
-    ClosureClassElement closureClassElement = createInstance.classElement;
-    Element element = closureClassElement.localLookup(Identifiers.call);
-
-    if (element == null || !element.isFunction) return null;
-    FunctionElement functionElement = element;
-    if (functionElement.asyncMarker != AsyncMarker.SYNC) return null;
-
-    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 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 null;
-
-    FunctionDefinition target =
-        functionCompiler.compileToCpsIr(functionElement);
-
-    // Accesses to closed-over values are field access primitives.  We we don't
-    // inline if there are other uses of 'this' since that could be an escape or
-    // a recursive call.
-    for (Reference ref = target.receiverParameter.firstRef;
-        ref != null;
-        ref = ref.next) {
-      Node use = ref.parent;
-      if (use is GetField) continue;
-      // 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.objectRef) continue;
-      return null;
-    }
-
-    CpsFragment cps = new CpsFragment(node.sourceInformation);
-    Primitive returnValue = cps.inlineFunction(
-        target, node.receiver, node.arguments.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;
-    if (!input.type.isNullable &&
-        typeSystem.areDisjoint(input.type, typeSystem.interceptorType)) {
-      node.replaceUsesWith(input);
-    }
-  }
-
-  visitInvokeConstructor(InvokeConstructor node) {
-    node.effects =
-        Effects.from(compiler.world.getSideEffectsOfElement(node.target));
-  }
-
-  visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    Element target = node.target;
-    if (target is ConstructorBodyElement) {
-      ConstructorBodyElement constructorBody = target;
-      target = constructorBody.constructor;
-    }
-    node.effects = Effects.from(compiler.world.getSideEffectsOfElement(target));
-    TypeMask receiverType = node.receiver.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.interceptorRef.changeTo(node.receiver);
-    }
-  }
-
-  visitInvokeMethod(InvokeMethod node) {
-    var specialized = specializeOperatorCall(node) ??
-        specializeFieldAccess(node) ??
-        specializeIndexableAccess(node) ??
-        specializeArrayAccess(node) ??
-        specializeSingleUseClosureCall(node) ??
-        specializeClosureCall(node);
-    if (specialized != null) return specialized;
-
-    TypeMask receiverType = node.receiver.type;
-    node.mask = typeSystem.intersection(node.mask, receiverType);
-
-    node.effects = Effects.from(
-        compiler.world.getSideEffectsOfSelector(node.selector, node.mask));
-
-    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.interceptorRef.changeTo(node.receiver);
-
-      // Replace the extra receiver argument with a dummy value if the
-      // target definitely does not use it.
-      if (typeSystem.targetIgnoresReceiverArgument(
-          receiverType, node.selector)) {
-        node.makeDummyIntercepted();
-      }
-    }
-  }
-
-  CpsFragment visitTypeCast(TypeCast node) {
-    AbstractConstantValue value = getValue(node.value);
-    switch (lattice.isSubtypeOf(value, node.dartType, allowNull: true)) {
-      case AbstractBool.Maybe:
-      case AbstractBool.Nothing:
-        return null;
-
-      case AbstractBool.True:
-        // Return an unused primitive moved again.
-        node.replaceUsesWith(node.value);
-        return new CpsFragment(); // Remove the node.
-
-      case AbstractBool.False:
-        // 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.
-  specializeInternalMethodCall(InvokeStatic node) {
-    if (node.target == backend.helpers.stringInterpolationHelper) {
-      Primitive argument = node.argument(0);
-      AbstractConstantValue value = getValue(argument);
-      if (lattice.isDefinitelyString(value)) {
-        node.replaceUsesWith(argument);
-        return new CpsFragment();
-      } else if (typeSystem.isDefinitelySelfInterceptor(value.type)) {
-        TypeMask toStringReturn =
-            typeSystem.getInvokeReturnType(Selectors.toString_, value.type);
-        if (typeSystem.isDefinitelyString(toStringReturn)) {
-          CpsFragment cps = new CpsFragment(node.sourceInformation);
-          Primitive invoke = cps.invokeMethod(
-              argument, Selectors.toString_, value.type, [],
-              callingConvention: CallingConvention.DummyIntercepted);
-          node.replaceUsesWith(invoke);
-          return cps;
-        }
-      }
-    } else if (node.target == compiler.identicalFunction) {
-      if (node.argumentRefs.length == 2) {
-        return new ApplyBuiltinOperator(BuiltinOperator.Identical,
-            [node.argument(0), node.argument(1)], node.sourceInformation);
-      }
-    }
-    return null;
-  }
-
-  visitInvokeStatic(InvokeStatic node) {
-    node.effects =
-        Effects.from(compiler.world.getSideEffectsOfElement(node.target));
-    return specializeInternalMethodCall(node);
-  }
-
-  AbstractConstantValue getValue(Variable node) {
-    assert(node.type != null);
-    ConstantValue constant = values[node];
-    if (constant != null) {
-      return new AbstractConstantValue.constantValue(constant, node.type);
-    }
-    return new AbstractConstantValue.nonConstant(node.type);
-  }
-
-  /*************************** PRIMITIVES **************************/
-  //
-  // 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.
-  //
-
-  visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    ast.DartString getString(AbstractConstantValue value) {
-      StringConstantValue constant = value.constant;
-      return constant.primitiveValue;
-    }
-    switch (node.operator) {
-      case BuiltinOperator.StringConcatenate:
-        // Concatenate consecutive constants.
-        bool argumentsWereRemoved = false;
-        int i = 0;
-        while (i < node.argumentRefs.length - 1) {
-          int startOfSequence = i;
-          AbstractConstantValue firstValue = getValue(node.argument(i++));
-          if (!firstValue.isConstant) continue;
-          AbstractConstantValue secondValue = getValue(node.argument(i++));
-          if (!secondValue.isConstant) continue;
-
-          ast.DartString string = new ast.ConsDartString(
-              getString(firstValue), getString(secondValue));
-
-          // We found a sequence of at least two constants.
-          // Look for the end of the sequence.
-          while (i < node.argumentRefs.length) {
-            AbstractConstantValue value = getValue(node.argument(i));
-            if (!value.isConstant) break;
-            string = new ast.ConsDartString(string, getString(value));
-            ++i;
-          }
-          Constant prim =
-              makeConstantPrimitive(new StringConstantValue(string));
-          new LetPrim(prim).insertAbove(node.parent);
-          for (int k = startOfSequence; k < i; ++k) {
-            node.argumentRefs[k].unlink();
-            node.argumentRefs[k] = null; // Remove the argument after the loop.
-          }
-          node.argumentRefs[startOfSequence] = new Reference<Primitive>(prim);
-          node.argumentRefs[startOfSequence].parent = node;
-          argumentsWereRemoved = true;
-        }
-        if (argumentsWereRemoved) {
-          node.argumentRefs.removeWhere((ref) => ref == null);
-        }
-        if (node.argumentRefs.length == 1) {
-          Primitive input = node.argument(0);
-          node.replaceUsesWith(input);
-          input.useElementAsHint(node.hint);
-        }
-        // TODO(asgerf): Rebalance nested StringConcats that arise from
-        //               rewriting the + operator to StringConcat.
-        break;
-
-      case BuiltinOperator.Identical:
-        Primitive leftArg = node.argument(0);
-        Primitive rightArg = node.argument(1);
-        AbstractConstantValue left = getValue(leftArg);
-        AbstractConstantValue right = getValue(rightArg);
-        BuiltinOperator newOperator;
-        if (left.isNullConstant || right.isNullConstant) {
-          // Use `==` for comparing against null, so JS undefined and JS null
-          // are considered equal.
-          newOperator = BuiltinOperator.LooseEq;
-        } else if (!left.isNullable || !right.isNullable) {
-          // If at most one operand can be Dart null, we can use `===`.
-          // This is not safe when we might compare JS null and JS undefined.
-          newOperator = BuiltinOperator.StrictEq;
-        } else if (lattice.isDefinitelyNum(left, allowNull: true) &&
-            lattice.isDefinitelyNum(right, allowNull: true)) {
-          // If both operands can be null, but otherwise are of the same type,
-          // we can use `==` for comparison.
-          // This is not safe e.g. for comparing strings against numbers.
-          newOperator = BuiltinOperator.LooseEq;
-        } else if (lattice.isDefinitelyString(left, allowNull: true) &&
-            lattice.isDefinitelyString(right, allowNull: true)) {
-          newOperator = BuiltinOperator.LooseEq;
-        } else if (lattice.isDefinitelyBool(left, allowNull: true) &&
-            lattice.isDefinitelyBool(right, allowNull: true)) {
-          newOperator = BuiltinOperator.LooseEq;
-        }
-        if (newOperator != null) {
-          return new ApplyBuiltinOperator(
-              newOperator, node.arguments.toList(), node.sourceInformation);
-        }
-        break;
-
-      case BuiltinOperator.StrictEq:
-      case BuiltinOperator.LooseEq:
-      case BuiltinOperator.StrictNeq:
-      case BuiltinOperator.LooseNeq:
-        bool negated = node.operator == BuiltinOperator.StrictNeq ||
-            node.operator == BuiltinOperator.LooseNeq;
-        for (int firstIndex in [0, 1]) {
-          int secondIndex = 1 - firstIndex;
-          Primitive firstArg = node.argument(firstIndex);
-          Primitive secondArg = node.argument(secondIndex);
-          AbstractConstantValue first = getValue(firstArg);
-          if (!lattice.isDefinitelyBool(first)) continue;
-          AbstractConstantValue second = getValue(secondArg);
-          if (!second.isConstant || !second.constant.isBool) continue;
-          bool isTrueConstant = second.constant.isTrue;
-          if (isTrueConstant == !negated) {
-            // (x === true) ==> x
-            // (x !== false) ==> x
-            node.replaceUsesWith(firstArg);
-            return null;
-          } else {
-            // (x === false) ==> !x
-            // (x !== true) ==> !x
-            return new ApplyBuiltinOperator(
-                BuiltinOperator.IsFalsy, [firstArg], node.sourceInformation);
-          }
-        }
-        break;
-
-      default:
-    }
-    return null;
-  }
-
-  void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {}
-
-  visitTypeTest(TypeTest node) {
-    Primitive prim = node.value;
-
-    Primitive unaryBuiltinOperator(BuiltinOperator operator) =>
-        new ApplyBuiltinOperator(
-            operator, <Primitive>[prim], node.sourceInformation);
-
-    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.
-      return null;
-    }
-
-    if (dartType == dartTypes.coreTypes.intType) {
-      // Compile as typeof x === 'number' && Math.floor(x) === x
-      if (lattice.isDefinitelyNum(value, allowNull: true)) {
-        // If value is null or a number, we can skip the typeof test.
-        return new ApplyBuiltinOperator(BuiltinOperator.IsFloor,
-            <Primitive>[prim, prim], node.sourceInformation);
-      }
-      if (lattice.isDefinitelyNotNonIntegerDouble(value)) {
-        // If the value cannot be a non-integer double, but might not be a
-        // number at all, we can skip the Math.floor test.
-        return unaryBuiltinOperator(BuiltinOperator.IsNumber);
-      }
-      return new ApplyBuiltinOperator(BuiltinOperator.IsInteger,
-          <Primitive>[prim, prim, prim], node.sourceInformation);
-    }
-    if (node.dartType == dartTypes.coreTypes.numType ||
-        node.dartType == dartTypes.coreTypes.doubleType) {
-      return new ApplyBuiltinOperator(
-          BuiltinOperator.IsNumber, <Primitive>[prim], node.sourceInformation);
-    }
-
-    AbstractBool isNullableSubtype =
-        lattice.isSubtypeOf(value, node.dartType, allowNull: true);
-    AbstractBool isNullPassingTest =
-        lattice.isSubtypeOf(lattice.nullValue, node.dartType, allowNull: false);
-    if (isNullableSubtype == AbstractBool.True &&
-        isNullPassingTest == AbstractBool.False) {
-      // Null is the only value not satisfying the type test.
-      // Replace the type test with a null-check.
-      // 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());
-      new LetPrim(nullConst).insertAbove(node.parent);
-      return new ApplyBuiltinOperator(BuiltinOperator.LooseNeq,
-          <Primitive>[prim, nullConst], node.sourceInformation);
-    }
-
-    if (dartType.element == functionCompiler.glue.jsFixedArrayClass) {
-      // TODO(sra): Check input is restricted to JSArray.
-      return unaryBuiltinOperator(BuiltinOperator.IsFixedLengthJSArray);
-    }
-
-    if (dartType.element == functionCompiler.glue.jsExtendableArrayClass) {
-      // TODO(sra): Check input is restricted to JSArray.
-      return unaryBuiltinOperator(BuiltinOperator.IsExtendableJSArray);
-    }
-
-    if (dartType.element == functionCompiler.glue.jsMutableArrayClass) {
-      // TODO(sra): Check input is restricted to JSArray.
-      return unaryBuiltinOperator(BuiltinOperator.IsModifiableJSArray);
-    }
-
-    if (dartType.element == functionCompiler.glue.jsUnmodifiableArrayClass) {
-      // TODO(sra): Check input is restricted to JSArray.
-      return unaryBuiltinOperator(BuiltinOperator.IsUnmodifiableJSArray);
-    }
-
-    if (dartType == dartTypes.coreTypes.stringType ||
-        dartType == dartTypes.coreTypes.boolType) {
-      // These types are recognized in tree_ir TypeOperator codegen.
-      return null;
-    }
-
-    // TODO(sra): If getInterceptor(x) === x or JSNull, rewrite
-    //     getInterceptor(x).$isFoo ---> x != null && x.$isFoo
-    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;
-  }
-
-  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;
-    Primitive indexPrim = node.index;
-    int index = lattice.intValue(getValue(indexPrim));
-    int length =
-        node.lengthRef == null ? null : lattice.intValue(getValue(node.length));
-    if (index != null && length != null && index < length) {
-      node.checks &= ~BoundsCheck.UPPER_BOUND;
-    }
-    if (index != null && index >= 0) {
-      node.checks &= ~BoundsCheck.LOWER_BOUND;
-    }
-    if (length != null && length > 0) {
-      node.checks &= ~BoundsCheck.EMPTINESS;
-    }
-    if (typeSystem.isDefinitelyInt(indexPrim.type)) {
-      node.checks &= ~BoundsCheck.INTEGER;
-    }
-    if (!node.lengthUsedInCheck && node.lengthRef != null) {
-      node
-        ..lengthRef.unlink()
-        ..lengthRef = 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
-        ..indexRef.unlink()
-        ..indexRef = null;
-    }
-  }
-
-  visitReceiverCheck(ReceiverCheck node) {
-    Primitive input = node.value;
-    if (!input.type.isNullable &&
-        (node.isNullCheck ||
-            !input.type.needsNoSuchMethodHandling(node.selector, classWorld))) {
-      node.replaceUsesWith(input);
-      return new CpsFragment();
-    }
-    return null;
-  }
-
-  visitGetLength(GetLength node) {
-    node.isFinal = typeSystem.isDefinitelyFixedLengthIndexable(node.object.type,
-        allowNull: true);
-  }
-
-  visitReadTypeVariable(ReadTypeVariable node) {
-    // Pattern match on
-    //
-    //    ReadTypeVariable(var, CreateInstance(..., TypeExpression(arguments)))
-    //
-    // and extract the argument that corresponds to the type variable. This is a
-    // shrinking reduction.
-    //
-    // TODO(sra): This is a shrinking reduction that does not depend on inferred
-    // types so it should be done in the shrinking reductions pass.
-    //
-    // TODO(sra): A non-shrinking version of this rewrite could be done as part
-    // of scalar replacement.
-
-    if (node.target is CreateInstance) {
-      CreateInstance instance = node.target;
-      if (instance.typeInformationRef != null &&
-          instance.typeInformation is TypeExpression) {
-        TypeExpression typeExpression = instance.typeInformation;
-        assert(typeExpression.kind == TypeExpressionKind.INSTANCE);
-        ClassElement context = node.variable.element.enclosingClass;
-        ClassElement createdClass = instance.classElement;
-        // In the general case, a substitution could generate a large type
-        // term. Avoid this by restricting to direct indexing.
-        // TODO(sra): Also include cases that require substitution but the end
-        // result is the same as some indexing or a simple constant type.
-        if (backend.rti.isTrivialSubstitution(createdClass, context)) {
-          int index = functionCompiler.glue.getTypeVariableIndex(node.variable);
-          if (0 <= index && index < typeExpression.argumentRefs.length) {
-            node.replaceUsesWith(typeExpression.argument(index));
-            return new CpsFragment();
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  bool isNullConstant(Primitive prim) => prim is Constant && prim.value.isNull;
-
-  visitCreateInstance(CreateInstance node) {
-    Primitive typeInformation = node.typeInformation;
-    if (typeInformation is TypeExpression &&
-        typeInformation.arguments.every(isNullConstant)) {
-      node
-        ..typeInformationRef.unlink()
-        ..typeInformationRef = null;
-    }
-  }
-}
-
-/**
- * Runs an analysis pass on the given function definition in order to detect
- * const-ness as well as reachability, both of which are used in the subsequent
- * transformation pass.
- */
-class TypePropagationVisitor implements Visitor {
-  // The node worklist stores nodes that are both reachable and need to be
-  // processed, but have not been processed yet. Using a worklist avoids deep
-  // recursion.
-  // The node worklist and the reachable set operate in concert: nodes are
-  // only ever added to the worklist when they have not yet been marked as
-  // reachable, and adding a node to the worklist is always followed by marking
-  // it reachable.
-  // TODO(jgruber): Storing reachability per-edge instead of per-node would
-  // allow for further optimizations.
-  final List<Node> nodeWorklist = <Node>[];
-  final Set<Continuation> reachableContinuations = new Set<Continuation>();
-
-  // The definition workset stores all definitions which need to be reprocessed
-  // since their lattice value has changed.
-  final List<Definition> defWorklist = <Definition>[];
-
-  final ConstantPropagationLattice lattice;
-  final InternalErrorFunction internalError;
-
-  TypeMaskSystem get typeSystem => lattice.typeSystem;
-
-  JavaScriptBackend get backend => typeSystem.backend;
-
-  dart2js.Compiler get compiler => backend.compiler;
-
-  World get classWorld => typeSystem.classWorld;
-
-  AbstractConstantValue get nothing => lattice.nothing;
-
-  AbstractConstantValue nonConstant([TypeMask type]) {
-    return lattice.nonConstant(type);
-  }
-
-  AbstractConstantValue constantValue(ConstantValue constant, [TypeMask type]) {
-    return lattice.constant(constant, type);
-  }
-
-  // Stores the current lattice value for primitives and mutable variables.
-  // Access through [getValue] and [setValue].
-  final Map<Variable, ConstantValue> values;
-
-  TypePropagationVisitor(this.lattice, this.values, this.internalError);
-
-  void analyze(FunctionDefinition root, bool recomputeAll) {
-    reachableContinuations.clear();
-    if (recomputeAll) {
-      new ResetAnalysisInfo(reachableContinuations, values).visit(root);
-    }
-
-    // Initially, only the root node is reachable.
-    push(root);
-
-    iterateWorklist();
-  }
-
-  void reanalyzeSubtree(Node node) {
-    new ResetAnalysisInfo(reachableContinuations, values).visit(node);
-    push(node);
-    iterateWorklist();
-  }
-
-  void iterateWorklist() {
-    while (true) {
-      if (nodeWorklist.isNotEmpty) {
-        // Process a new reachable expression.
-        Node node = nodeWorklist.removeLast();
-        visit(node);
-      } else if (defWorklist.isNotEmpty) {
-        // Process all usages of a changed definition.
-        Definition def = defWorklist.removeLast();
-
-        // Visit all uses of this definition. This might add new entries to
-        // [nodeWorklist], for example by visiting a newly-constant usage within
-        // a branch node.
-        for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
-          visit(ref.parent);
-        }
-      } else {
-        break; // Both worklists empty.
-      }
-    }
-  }
-
-  /// Adds [node] to the worklist.
-  void push(Node node) {
-    nodeWorklist.add(node);
-  }
-
-  /// If the passed node is not yet reachable, mark it reachable and add it
-  /// to the work list.
-  void setReachable(Continuation cont) {
-    if (reachableContinuations.add(cont)) {
-      push(cont);
-    }
-  }
-
-  /// Returns the lattice value corresponding to [node], defaulting to nothing.
-  ///
-  /// Never returns null.
-  AbstractConstantValue getValue(Variable node) {
-    ConstantValue constant = values[node];
-    if (constant != null) {
-      return new AbstractConstantValue.constantValue(constant, node.type);
-    }
-    if (node.type != null) {
-      return new AbstractConstantValue.nonConstant(node.type);
-    }
-    return lattice.nothing;
-  }
-
-  /// 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, 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;
-    }
-
-    // Values may only move in the direction NOTHING -> CONSTANT -> NONCONST.
-    assert(newValue.kind >= oldValue.kind);
-
-    values[node] = newValue.isConstant ? newValue.constant : null;
-    defWorklist.add(node);
-  }
-
-  /// 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}) {
-    // 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);
-  }
-
-  // -------------------------- Visitor overrides ------------------------------
-  void visit(Node node) {
-    node.accept(this);
-  }
-
-  void visitFunctionDefinition(FunctionDefinition node) {
-    if (node.interceptorParameter != null) {
-      setValue(node.interceptorParameter, nonConstant(typeSystem.nonNullType));
-    }
-    // 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.receiverParameter != null &&
-        getValue(node.receiverParameter).isNothing) {
-      setValue(node.receiverParameter,
-          nonConstant(typeSystem.getReceiverType(node.element)));
-    }
-    bool hasParameterWithoutValue = false;
-    for (Parameter param in node.parameters) {
-      if (getValue(param).isNothing) {
-        TypeMask type = param.hint is ParameterElement
-            ? typeSystem.getParameterType(param.hint)
-            : typeSystem.dynamicType;
-        setValue(param, lattice.fromMask(type));
-        if (type.isEmpty) hasParameterWithoutValue = true;
-      }
-    }
-    if (!hasParameterWithoutValue) {
-      // Don't analyze unreachable code.
-      push(node.body);
-    }
-  }
-
-  void visitLetPrim(LetPrim node) {
-    visit(node.primitive); // No reason to delay visits to primitives.
-    push(node.body);
-  }
-
-  void visitLetCont(LetCont node) {
-    // The continuation is only marked as reachable on use.
-    push(node.body);
-  }
-
-  void visitLetHandler(LetHandler node) {
-    push(node.body);
-    // The handler is assumed to be reachable (we could instead treat it as
-    // unreachable unless we find something reachable that might throw in the
-    // body --- it's not clear if we want to do that here or in some other
-    // pass).  The handler parameters are assumed to be unknown.
-    //
-    // TODO(kmillikin): we should set the type of the exception and stack
-    // trace here.  The way we do that depends on how we handle 'on T' catch
-    // clauses.
-    setReachable(node.handler);
-    for (Parameter param in node.handler.parameters) {
-      setValue(param, nonConstant());
-    }
-  }
-
-  void visitLetMutable(LetMutable node) {
-    setValue(node.variable, getValue(node.value));
-    push(node.body);
-  }
-
-  void visitInvokeStatic(InvokeStatic node) {
-    if (node.target == backend.helpers.stringInterpolationHelper) {
-      AbstractConstantValue argValue = getValue(node.argument(0));
-      setResult(node, lattice.stringify(argValue), canReplace: true);
-      return;
-    }
-
-    TypeMask returnType = typeSystem.getReturnType(node.target);
-    setResult(node, lattice.fromMask(returnType));
-  }
-
-  void visitInvokeContinuation(InvokeContinuation node) {
-    Continuation cont = node.continuation;
-    setReachable(cont);
-
-    // Forward the constant status of all continuation invokes to the
-    // continuation. Note that this is effectively a phi node in SSA terms.
-    for (int i = 0; i < node.argumentRefs.length; i++) {
-      Primitive def = node.argument(i);
-      AbstractConstantValue cell = getValue(def);
-      setValue(cont.parameters[i], cell);
-    }
-  }
-
-  void visitInvokeMethod(InvokeMethod node) {
-    AbstractConstantValue receiver = getValue(node.receiver);
-    if (receiver.isNothing) {
-      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.argument(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.argument(0));
-      AbstractConstantValue result = lattice.indexSpecial(receiver, right);
-      return finish(result, canReplace: !receiver.isNullable);
-    }
-
-    if (!node.selector.isOperator) {
-      return finish(null);
-    }
-
-    // Calculate the resulting constant if possible.
-    String opname = node.selector.name;
-    if (node.argumentRefs.length == 0) {
-      // Unary operator.
-      if (opname == "unary-") {
-        opname = "-";
-      }
-      UnaryOperator operator = UnaryOperator.parse(opname);
-      AbstractConstantValue result = lattice.unaryOp(operator, receiver);
-      return finish(result, canReplace: !receiver.isNullable);
-    } else if (node.argumentRefs.length == 1) {
-      // Binary operator.
-      AbstractConstantValue right = getValue(node.argument(0));
-      BinaryOperator operator = BinaryOperator.parse(opname);
-      AbstractConstantValue result =
-          lattice.binaryOp(operator, receiver, right);
-      return finish(result, canReplace: !receiver.isNullable);
-    }
-    return finish(null);
-  }
-
-  void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    void unaryOp(
-        AbstractConstantValue operation(AbstractConstantValue argument),
-        TypeMask defaultType) {
-      AbstractConstantValue value = getValue(node.argument(0));
-      setValue(node, operation(value) ?? nonConstant(defaultType));
-    }
-
-    void binaryOp(
-        AbstractConstantValue operation(
-            AbstractConstantValue left, AbstractConstantValue right),
-        TypeMask defaultType) {
-      AbstractConstantValue left = getValue(node.argument(0));
-      AbstractConstantValue right = getValue(node.argument(1));
-      setValue(node, operation(left, right) ?? nonConstant(defaultType));
-    }
-
-    void binaryNumOp(
-        AbstractConstantValue operation(
-            AbstractConstantValue left, AbstractConstantValue right)) {
-      binaryOp(operation, typeSystem.numType);
-    }
-
-    void binaryUint32Op(
-        AbstractConstantValue operation(
-            AbstractConstantValue left, AbstractConstantValue right)) {
-      binaryOp(operation, typeSystem.uint32Type);
-    }
-
-    void binaryBoolOp(
-        AbstractConstantValue operation(
-            AbstractConstantValue left, AbstractConstantValue right)) {
-      binaryOp(operation, typeSystem.boolType);
-    }
-
-    switch (node.operator) {
-      case BuiltinOperator.StringConcatenate:
-        ast.DartString stringValue = const ast.LiteralDartString('');
-        for (Reference<Primitive> arg in node.argumentRefs) {
-          AbstractConstantValue value = getValue(arg.definition);
-          if (value.isNothing) {
-            setValue(node, lattice.nothing);
-            return; // And come back later
-          } else if (value.isConstant &&
-              value.constant.isString &&
-              stringValue != null) {
-            StringConstantValue constant = value.constant;
-            stringValue =
-                new ast.ConsDartString(stringValue, constant.primitiveValue);
-          } else {
-            stringValue = null;
-            break;
-          }
-        }
-        if (stringValue == null) {
-          setValue(node, nonConstant(typeSystem.stringType));
-        } else {
-          setValue(node, constantValue(new StringConstantValue(stringValue)));
-        }
-        break;
-
-      case BuiltinOperator.CharCodeAt:
-        binaryOp(lattice.codeUnitAtSpecial, typeSystem.uint31Type);
-        break;
-
-      case BuiltinOperator.Identical:
-      case BuiltinOperator.StrictEq:
-      case BuiltinOperator.StrictNeq:
-      case BuiltinOperator.LooseEq:
-      case BuiltinOperator.LooseNeq:
-        bool negated = node.operator == BuiltinOperator.StrictNeq ||
-            node.operator == BuiltinOperator.LooseNeq;
-        AbstractConstantValue left = getValue(node.argument(0));
-        AbstractConstantValue right = getValue(node.argument(1));
-        if (left.isNothing || right.isNothing) {
-          setValue(node, lattice.nothing);
-          return;
-        }
-        if (left.isConstant && right.isConstant) {
-          ConstantValue equal = lattice.constantSystem.identity
-              .fold(left.constant, right.constant);
-          if (equal != null && equal.isBool) {
-            ConstantValue result =
-                new BoolConstantValue(equal.isTrue == !negated);
-            setValue(node, constantValue(result, typeSystem.boolType));
-            return;
-          }
-        }
-        if (typeSystem.areDisjoint(left.type, right.type)) {
-          ConstantValue result = new BoolConstantValue(negated);
-          setValue(node, constantValue(result, typeSystem.boolType));
-          return;
-        }
-        setValue(node, nonConstant(typeSystem.boolType));
-        break;
-
-      case BuiltinOperator.NumAdd:
-        binaryNumOp(lattice.addSpecial);
-        break;
-
-      case BuiltinOperator.NumSubtract:
-        binaryNumOp(lattice.subtractSpecial);
-        break;
-
-      case BuiltinOperator.NumMultiply:
-        binaryNumOp(lattice.multiplySpecial);
-        break;
-
-      case BuiltinOperator.NumDivide:
-        binaryNumOp(lattice.divideSpecial);
-        break;
-
-      case BuiltinOperator.NumRemainder:
-        binaryNumOp(lattice.remainderSpecial);
-        break;
-
-      case BuiltinOperator.NumTruncatingDivideToSigned32:
-        binaryNumOp(lattice.truncatingDivideSpecial);
-        break;
-
-      case BuiltinOperator.NumAnd:
-        binaryUint32Op(lattice.andSpecial);
-        break;
-
-      case BuiltinOperator.NumOr:
-        binaryUint32Op(lattice.orSpecial);
-        break;
-
-      case BuiltinOperator.NumXor:
-        binaryUint32Op(lattice.xorSpecial);
-        break;
-
-      case BuiltinOperator.NumShl:
-        binaryUint32Op(lattice.shiftLeftSpecial);
-        break;
-
-      case BuiltinOperator.NumShr:
-        binaryUint32Op(lattice.shiftRightSpecial);
-        break;
-
-      case BuiltinOperator.NumLt:
-        binaryBoolOp(lattice.lessSpecial);
-        break;
-
-      case BuiltinOperator.NumLe:
-        binaryBoolOp(lattice.lessEqualSpecial);
-        break;
-
-      case BuiltinOperator.NumGt:
-        binaryBoolOp(lattice.greaterSpecial);
-        break;
-
-      case BuiltinOperator.NumGe:
-        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:
-      case BuiltinOperator.IsNumber:
-      case BuiltinOperator.IsNotNumber:
-      case BuiltinOperator.IsNotInteger:
-      case BuiltinOperator.IsFloor:
-      case BuiltinOperator.IsInteger:
-      case BuiltinOperator.IsUnsigned32BitInteger:
-      case BuiltinOperator.IsNotUnsigned32BitInteger:
-        setValue(node, nonConstant(typeSystem.boolType));
-        break;
-
-      case BuiltinOperator.IsFixedLengthJSArray:
-      case BuiltinOperator.IsExtendableJSArray:
-      case BuiltinOperator.IsUnmodifiableJSArray:
-      case BuiltinOperator.IsModifiableJSArray:
-        setValue(node, nonConstant(typeSystem.boolType));
-        break;
-    }
-  }
-
-  void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    AbstractConstantValue receiver = getValue(node.receiver);
-    if (node.method == BuiltinMethod.Pop) {
-      setValue(
-          node, nonConstant(typeSystem.elementTypeOfIndexable(receiver.type)));
-    } else {
-      setValue(node, nonConstant());
-    }
-  }
-
-  void visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    if (node.isConstructorBodyCall) {
-      setResult(node, lattice.nullValue);
-    } else if (node.isTearOff) {
-      setResult(node, nonConstant(typeSystem.functionType));
-    } else {
-      setResult(node, nonConstant(typeSystem.getReturnType(node.target)));
-    }
-  }
-
-  void visitInvokeConstructor(InvokeConstructor node) {
-    if (node.allocationSiteType != null) {
-      setResult(node, nonConstant(node.allocationSiteType));
-    } else {
-      setResult(node, nonConstant(typeSystem.getReturnType(node.target)));
-    }
-  }
-
-  void visitThrow(Throw node) {}
-
-  void visitRethrow(Rethrow node) {}
-
-  void visitUnreachable(Unreachable node) {}
-
-  void visitBranch(Branch node) {
-    AbstractConstantValue conditionCell = getValue(node.condition);
-    AbstractBool boolifiedValue = node.isStrictCheck
-        ? lattice.strictBoolify(conditionCell)
-        : lattice.boolify(conditionCell);
-    switch (boolifiedValue) {
-      case AbstractBool.Nothing:
-        break;
-      case AbstractBool.True:
-        setReachable(node.trueContinuation);
-        break;
-      case AbstractBool.False:
-        setReachable(node.falseContinuation);
-        break;
-      case AbstractBool.Maybe:
-        setReachable(node.trueContinuation);
-        setReachable(node.falseContinuation);
-        break;
-    }
-  }
-
-  void visitTypeTest(TypeTest node) {
-    handleTypeTest(node, getValue(node.value), node.dartType);
-  }
-
-  void visitTypeTestViaFlag(TypeTestViaFlag node) {
-    // TODO(sra): We could see if we can find the value in the interceptor
-    // expression. It would probably have no benefit - we only see
-    // TypeTestViaFlag after rewriting TypeTest and the rewrite of TypeTest
-    // would already have done the interesting optimizations.
-    setValue(node, nonConstant(typeSystem.boolType));
-  }
-
-  void handleTypeTest(
-      Primitive node, AbstractConstantValue input, types.DartType dartType) {
-    TypeMask boolType = typeSystem.boolType;
-    switch (lattice.isSubtypeOf(input, dartType, allowNull: false)) {
-      case AbstractBool.Nothing:
-        break; // And come back later.
-
-      case AbstractBool.True:
-        setValue(node, constantValue(new TrueConstantValue(), boolType));
-        break;
-
-      case AbstractBool.False:
-        setValue(node, constantValue(new FalseConstantValue(), boolType));
-        break;
-
-      case AbstractBool.Maybe:
-        setValue(node, nonConstant(boolType));
-        break;
-    }
-  }
-
-  void visitTypeCast(TypeCast node) {
-    AbstractConstantValue input = getValue(node.value);
-    switch (lattice.isSubtypeOf(input, node.dartType, allowNull: true)) {
-      case AbstractBool.Nothing:
-        setValue(node, lattice.nothing);
-        break; // And come back later.
-
-      case AbstractBool.True:
-        setValue(node, input);
-        break;
-
-      case AbstractBool.False:
-        setValue(node, lattice.nothing); // Cast fails.
-        break;
-
-      case AbstractBool.Maybe:
-        // Narrow type of output to those that survive the cast.
-        TypeMask type = input.type.intersection(
-            typeSystem.subtypesOf(node.dartType).nullable(), classWorld);
-        setValue(node, nonConstant(type));
-        break;
-    }
-  }
-
-  void visitSetMutable(SetMutable node) {
-    setValue(node.variable, getValue(node.value));
-  }
-
-  void visitLiteralList(LiteralList node) {
-    if (node.allocationSiteType != null) {
-      setValue(node, nonConstant(node.allocationSiteType));
-    } else {
-      setValue(node, nonConstant(typeSystem.extendableArrayType));
-    }
-  }
-
-  void visitConstant(Constant node) {
-    ConstantValue value = node.value;
-    if (value.isDummy || !value.isConstant) {
-      // TODO(asgerf): Explain how this happens and why we don't want them.
-      setValue(node, nonConstant(typeSystem.getTypeOf(value)));
-    } else {
-      setValue(node, constantValue(value, typeSystem.getTypeOf(value)));
-    }
-  }
-
-  void visitGetMutable(GetMutable node) {
-    setValue(node, getValue(node.variable));
-  }
-
-  void visitMutableVariable(MutableVariable node) {}
-
-  void visitParameter(Parameter node) {}
-
-  void visitContinuation(Continuation node) {
-    node.parameters.forEach(visit);
-
-    if (node.body != null) {
-      push(node.body);
-    }
-  }
-
-  void visitGetStatic(GetStatic node) {
-    if (node.element.isFunction) {
-      setValue(node, nonConstant(typeSystem.functionType));
-    } else {
-      setValue(node, nonConstant(typeSystem.getFieldType(node.element)));
-    }
-  }
-
-  void visitSetStatic(SetStatic node) {}
-
-  void visitGetLazyStatic(GetLazyStatic node) {
-    setResult(node, nonConstant(typeSystem.getFieldType(node.element)));
-  }
-
-  void visitInterceptor(Interceptor node) {
-    push(node.input);
-    AbstractConstantValue value = getValue(node.input);
-    if (value.isNothing) {
-      setValue(node, nothing);
-    } else if (value.isNullable &&
-        !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
-      //               propagate an assignment.
-      setValue(node, nonConstant());
-    } else {
-      setValue(node, nonConstant(typeSystem.nonNullType));
-    }
-  }
-
-  void visitGetField(GetField node) {
-    AbstractConstantValue object = getValue(node.object);
-    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) {}
-
-  void visitCreateBox(CreateBox node) {
-    setValue(node, nonConstant(typeSystem.nonNullType));
-  }
-
-  void visitCreateInstance(CreateInstance node) {
-    setValue(node,
-        nonConstant(typeSystem.nonNullExact(node.classElement.declaration)));
-  }
-
-  void visitReifyRuntimeType(ReifyRuntimeType node) {
-    setValue(node, nonConstant(typeSystem.typeType));
-  }
-
-  void visitReadTypeVariable(ReadTypeVariable node) {
-    // TODO(karlklose): come up with a type marker for JS entities or switch to
-    // real constants of type [Type].
-    setValue(node, nonConstant());
-  }
-
-  @override
-  void visitTypeExpression(TypeExpression node) {
-    // TODO(karlklose): come up with a type marker for JS entities or switch to
-    // real constants of type [Type].
-    setValue(node, nonConstant());
-  }
-
-  void visitCreateInvocationMirror(CreateInvocationMirror node) {
-    // TODO(asgerf): Expose [Invocation] type.
-    setValue(node, nonConstant(typeSystem.nonNullType));
-  }
-
-  @override
-  void visitForeignCode(ForeignCode node) {
-    bool firstArgumentIsNullable = false;
-    if (node.argumentRefs.length > 0) {
-      AbstractConstantValue first =
-          getValue(node.argumentRefs.first.definition);
-      if (first.isNothing) {
-        setValue(node, nothing);
-        return;
-      }
-      firstArgumentIsNullable = first.isNullable;
-    }
-    setValue(node, nonConstant(node.storedType));
-    node.isSafeForElimination =
-        !node.nativeBehavior.sideEffects.hasSideEffects() &&
-            (!node.nativeBehavior.throwBehavior.canThrow ||
-                (!firstArgumentIsNullable &&
-                    node.nativeBehavior.throwBehavior.isOnlyNullNSMGuard));
-  }
-
-  @override
-  void visitGetLength(GetLength node) {
-    AbstractConstantValue input = getValue(node.object);
-    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, length);
-    } else {
-      setValue(node, nonConstant(typeSystem.uint32Type));
-    }
-  }
-
-  @override
-  void visitGetIndex(GetIndex node) {
-    AbstractConstantValue object = getValue(node.object);
-    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) {}
-
-  @override
-  void visitAwait(Await node) {
-    setResult(node, nonConstant());
-  }
-
-  @override
-  visitYield(Yield node) {
-    setValue(node, nonConstant());
-  }
-
-  @override
-  void visitRefinement(Refinement node) {
-    setValue(
-        node,
-        lattice.intersectWithType(
-            getValue(node.value.definition), node.refineType));
-  }
-
-  @override
-  void visitBoundsCheck(BoundsCheck node) {
-    setValue(node, getValue(node.object));
-  }
-
-  @override
-  void visitReceiverCheck(ReceiverCheck node) {
-    AbstractConstantValue value = getValue(node.value);
-    if (node.isNullCheck) {
-      // Avoid expensive TypeMask operations for null checks.
-      setValue(node, lattice.nonNullable(value));
-    } else if (value.isConstant &&
-        !value.type.needsNoSuchMethodHandling(node.selector, classWorld)) {
-      // Preserve constants, unless the check fails for the constant.
-      setValue(node, value);
-    } else {
-      setValue(node,
-          nonConstant(typeSystem.receiverTypeFor(node.selector, value.type)));
-    }
-  }
-}
-
-/// Represents the abstract value of a primitive value at some point in the
-/// program. Abstract values of all kinds have a type [T].
-///
-/// The different kinds of abstract values represents the knowledge about the
-/// constness of the value:
-///   NOTHING:  cannot have any value
-///   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 AbstractConstantValue {
-  static const int NOTHING = 0;
-  static const int CONSTANT = 1;
-  static const int NONCONST = 2;
-
-  final int kind;
-  final ConstantValue constant;
-  final TypeMask type;
-
-  AbstractConstantValue._internal(this.kind, this.constant, this.type) {
-    assert(kind != CONSTANT || constant != null);
-    assert(constant is! SyntheticConstantValue);
-  }
-
-  AbstractConstantValue.nothing()
-      : this._internal(NOTHING, null, new TypeMask.nonNullEmpty());
-
-  AbstractConstantValue.constantValue(ConstantValue constant, TypeMask type)
-      : this._internal(CONSTANT, constant, type);
-
-  factory AbstractConstantValue.nonConstant(TypeMask type) {
-    if (type.isEmpty) {
-      return new AbstractConstantValue.nothing();
-    } else if (type.isNull) {
-      return new AbstractConstantValue.constantValue(
-          new NullConstantValue(), type);
-    } else {
-      return new AbstractConstantValue._internal(NONCONST, null, type);
-    }
-  }
-
-  bool get isNothing => (kind == NOTHING);
-  bool get isConstant => (kind == CONSTANT);
-  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 isZeroConstant => kind == CONSTANT && constant.isZero;
-  bool get isZeroOrNegativeConstant {
-    if (kind != CONSTANT || !constant.isNum) return false;
-    PrimitiveConstantValue value = constant;
-    return value.primitiveValue <= 0;
-  }
-
-  bool get isNegativeConstant {
-    if (kind != CONSTANT || !constant.isNum) return false;
-    PrimitiveConstantValue value = constant;
-    return value.primitiveValue < 0;
-  }
-
-  bool get isNullable => kind != NOTHING && type.isNullable;
-  bool get isDefinitelyNotNull => kind == NOTHING || !type.isNullable;
-
-  int get hashCode {
-    int hash = kind * 31 + constant.hashCode * 59 + type.hashCode * 67;
-    return hash & 0x3fffffff;
-  }
-
-  bool operator ==(AbstractConstantValue that) {
-    return that.kind == this.kind &&
-        that.constant == this.constant &&
-        that.type == this.type;
-  }
-
-  String toString() {
-    switch (kind) {
-      case NOTHING:
-        return "Nothing";
-      case CONSTANT:
-        return "Constant: ${constant.toDartText()}: $type";
-      case NONCONST:
-        return "Non-constant: $type";
-      default:
-        assert(false);
-    }
-    return null;
-  }
-}
-
-/// Suggested name for a synthesized loop index.
-class LoopIndexEntity extends Entity {
-  String get name => 'i';
-}
-
-/// Suggested name for the current element of a list being iterated.
-class LoopItemEntity extends Entity {
-  String get name => 'current';
-}
-
-/// Suggested name for the original length of a list, for use in checks
-/// for concurrent modification.
-class OriginalLengthEntity extends Entity {
-  String get name => 'length';
-}
-
-class ResetAnalysisInfo extends TrampolineRecursiveVisitor {
-  Set<Continuation> reachableContinuations;
-  Map<Variable, ConstantValue> values;
-
-  ResetAnalysisInfo(this.reachableContinuations, this.values);
-
-  void clear(Variable variable) {
-    variable.type = null;
-    values[variable] = null;
-  }
-
-  processFunctionDefinition(FunctionDefinition node) {
-    clear(node.returnContinuation.parameters.single);
-    node.parameters.forEach(clear);
-  }
-
-  processContinuation(Continuation cont) {
-    reachableContinuations.remove(cont);
-    cont.parameters.forEach(clear);
-  }
-
-  processLetPrim(LetPrim node) {
-    clear(node.primitive);
-  }
-
-  processLetMutable(LetMutable node) {
-    clear(node.variable);
-  }
-}
-
-enum ChecksNeeded {
-  /// No check is needed.
-  None,
-
-  /// Only null may fail the check.
-  Null,
-
-  /// Full check required.
-  Complete,
-}
-
-/// Generates runtime checks against a some type criteria, and determines at
-/// compile-time if the check is needed.
-///
-/// This class only generates the condition for determining if a check should
-/// fail.  Throwing the appropriate error in response to a failure is handled
-/// elsewhere.
-abstract class TypeCheckOperator {
-  const TypeCheckOperator();
-  static const TypeCheckOperator none = const NoTypeCheckOperator();
-
-  /// Determines to what extent a runtime check is needed.
-  ///
-  /// Sometimes a check can be slightly improved if it is known that null is the
-  /// only possible input that fails the check.
-  ChecksNeeded getChecksNeeded(Primitive value, World world);
-
-  /// Make an expression that returns `true` if [value] should fail the check.
-  ///
-  /// The result should be used in a check of the form:
-  ///
-  ///     if (makeCheck(value)) throw Error(value);
-  ///
-  Primitive makeCheck(CpsFragment cps, Primitive value);
-
-  /// Refine [value] after a succesful check.
-  Primitive makeRefinement(CpsFragment cps, Primitive value, World world);
-
-  bool needsCheck(Primitive value, World world) {
-    return getChecksNeeded(value, world) != ChecksNeeded.None;
-  }
-}
-
-/// Check that always passes.
-class NoTypeCheckOperator extends TypeCheckOperator {
-  const NoTypeCheckOperator();
-
-  ChecksNeeded getChecksNeeded(Primitive value, World world) {
-    return ChecksNeeded.None;
-  }
-
-  Primitive makeCheck(CpsFragment cps, Primitive value) {
-    return cps.makeFalse();
-  }
-
-  Primitive makeRefinement(CpsFragment cps, Primitive value, World world) {
-    return value;
-  }
-}
-
-/// Checks using a built-in operator that a value is an instance of a given
-/// class.
-class ClassTypeCheckOperator extends TypeCheckOperator {
-  ClassElement classElement;
-  BuiltinOperator negatedOperator;
-
-  ClassTypeCheckOperator(this.classElement, this.negatedOperator);
-
-  ChecksNeeded getChecksNeeded(Primitive value, World world) {
-    TypeMask type = value.type;
-    if (type.satisfies(classElement, world)) {
-      return type.isNullable ? ChecksNeeded.Null : ChecksNeeded.None;
-    } else {
-      return ChecksNeeded.Complete;
-    }
-  }
-
-  Primitive makeCheck(CpsFragment cps, Primitive value) {
-    return cps.applyBuiltin(negatedOperator, [value]);
-  }
-
-  Primitive makeRefinement(CpsFragment cps, Primitive value, World world) {
-    return cps.refine(value, new TypeMask.nonNullSubclass(classElement, world));
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/update_refinements.dart b/pkg/compiler/lib/src/cps_ir/update_refinements.dart
deleted file mode 100644
index 09f5d7a..0000000
--- a/pkg/compiler/lib/src/cps_ir/update_refinements.dart
+++ /dev/null
@@ -1,100 +0,0 @@
-library dart2js.cps_ir.update_refinements;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart' show Pass;
-import 'type_mask_system.dart';
-import '../world.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;
-  World get classWorld => typeSystem.classWorld;
-
-  Map<Primitive, Primitive> refinementFor = <Primitive, Primitive>{};
-
-  UpdateRefinements(this.typeSystem);
-
-  void rewrite(FunctionDefinition node) {
-    visit(node);
-  }
-
-  Expression traverseLetPrim(LetPrim node) {
-    Expression next = node.body;
-    visit(node.primitive);
-    return next;
-  }
-
-  visitReceiverCheck(ReceiverCheck node) {
-    if (refine(node.valueRef)) {
-      // Update the type if the input has changed.
-      Primitive value = node.value;
-      if (value.type.needsNoSuchMethodHandling(node.selector, classWorld)) {
-        node.type = typeSystem.receiverTypeFor(node.selector, value.type);
-      } else {
-        // Check is no longer needed.
-        node
-          ..replaceUsesWith(value)
-          ..destroy();
-        LetPrim letPrim = node.parent;
-        letPrim.remove();
-        return;
-      }
-    }
-    // Use the ReceiverCheck as a refinement.
-    Primitive value = node.effectiveDefinition;
-    Primitive old = refinementFor[value];
-    refinementFor[value] = node;
-    pushAction(() {
-      refinementFor[value] = old;
-    });
-  }
-
-  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;
-    Primitive old = refinementFor[value];
-    refinementFor[value] = node;
-    pushAction(() {
-      refinementFor[value] = old;
-    });
-  }
-
-  visitBoundsCheck(BoundsCheck node) {
-    super.visitBoundsCheck(node);
-    if (node.hasIntegerCheck && typeSystem.isDefinitelyInt(node.index.type)) {
-      node.checks &= ~BoundsCheck.INTEGER;
-    }
-  }
-
-  processReference(Reference ref) {
-    refine(ref);
-  }
-
-  bool refine(Reference ref) {
-    Definition def = ref.definition;
-    if (def is Primitive) {
-      Primitive refinement = refinementFor[def.effectiveDefinition];
-      if (refinement != null && refinement != ref.definition) {
-        ref.changeTo(refinement);
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart b/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
deleted file mode 100644
index 1b218af..0000000
--- a/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library dart2js.cps_ir.use_field_initializers;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-import '../elements/elements.dart';
-import '../js_backend/js_backend.dart';
-
-/// Eliminates [SetField] instructions when the value can instead be passed into
-/// the field initializer of a [CreateInstance] instruction.
-///
-/// This compensates for a somewhat common pattern where fields are initialized
-/// in the constructor body instead of using initializers. For example:
-///
-///     class Foo {
-///       var x, y;
-///       Foo(x, y) {
-///          this.x = x;
-///          this.y = y;
-///        }
-///      }
-///
-///   ==> (IR for Foo constructor)
-///
-///      foo = new D.Foo(null, null);
-///      foo.x = 'a';
-///      foo.y = 'b';
-///
-///   ==> (after this pass)
-///
-///      foo = new D.Foo('a', 'b');
-//
-// TODO(asgerf): Store forwarding and load elimination could most likely
-//   handle this more generally.
-//
-class UseFieldInitializers extends BlockVisitor implements Pass {
-  String get passName => 'Use field initializers';
-
-  final JavaScriptBackend backend;
-
-  final Set<CreateInstance> unescaped = new Set<CreateInstance>();
-
-  /// Continuation bindings separating the current traversal position from an
-  /// unescaped [CreateInstance].  When [CreateInstance] is sunk, these
-  /// continuations must sink as well to ensure the object remains in scope
-  /// inside the bound continuations.
-  final List<LetCont> letConts = <LetCont>[];
-
-  /// If non-null, the bindings in [letConts] should sink to immediately below
-  /// this node.
-  InteriorNode letContSinkTarget = null;
-  EscapeVisitor escapeVisitor;
-
-  UseFieldInitializers(this.backend);
-
-  void rewrite(FunctionDefinition node) {
-    escapeVisitor = new EscapeVisitor(this);
-    BlockVisitor.traverseInPreOrder(node, this);
-  }
-
-  void escape(Reference ref) {
-    Definition def = ref.definition;
-    if (def is CreateInstance) {
-      unescaped.remove(def);
-      if (unescaped.isEmpty) {
-        sinkLetConts();
-        letConts.clear();
-      }
-    }
-  }
-
-  void visitContinuation(Continuation node) {
-    endBasicBlock();
-  }
-
-  void visitLetHandler(LetHandler node) {
-    endBasicBlock();
-  }
-
-  void visitInvokeContinuation(InvokeContinuation node) {
-    endBasicBlock();
-  }
-
-  void visitBranch(Branch node) {
-    endBasicBlock();
-  }
-
-  void visitRethrow(Rethrow node) {
-    endBasicBlock();
-  }
-
-  void visitThrow(Throw node) {
-    endBasicBlock();
-  }
-
-  void visitUnreachable(Unreachable node) {
-    endBasicBlock();
-  }
-
-  void visitLetMutable(LetMutable node) {
-    escape(node.valueRef);
-  }
-
-  void visitLetCont(LetCont node) {
-    if (unescaped.isNotEmpty) {
-      // Ensure we do not lift a LetCont if there is a sink target set above
-      // the current node.
-      sinkLetConts();
-      letConts.add(node);
-    }
-  }
-
-  void sinkLetConts() {
-    if (letContSinkTarget != null) {
-      for (LetCont letCont in letConts.reversed) {
-        letCont
-          ..remove()
-          ..insertBelow(letContSinkTarget);
-      }
-      letContSinkTarget = null;
-    }
-  }
-
-  void endBasicBlock() {
-    sinkLetConts();
-    letConts.clear();
-    unescaped.clear();
-  }
-
-  void visitLetPrim(LetPrim node) {
-    Primitive prim = node.primitive;
-    if (prim is CreateInstance) {
-      unescaped.add(prim);
-      prim.argumentRefs.forEach(escape);
-      return;
-    }
-    if (unescaped.isEmpty) return;
-    if (prim is SetField) {
-      escape(prim.valueRef);
-      Primitive object = prim.object;
-      if (object is CreateInstance && unescaped.contains(object)) {
-        int index = getFieldIndex(object.classElement, prim.field);
-        if (index == -1) {
-          // This field is not initialized at creation time, so we cannot pull
-          // set SetField into the CreateInstance instruction.  We have to
-          // leave the instruction here, and this counts as a use of the object.
-          escape(prim.objectRef);
-        } else {
-          // Replace the field initializer with the new value. There are no uses
-          // of the object before this, so the old value cannot have been seen.
-          object.argumentRefs[index].changeTo(prim.value);
-          prim.destroy();
-          // The right-hand side might not be in scope at the CreateInstance.
-          // Sink the creation down to this point.
-          rebindCreateInstanceAt(object, node);
-          letContSinkTarget = node;
-        }
-      }
-      return;
-    }
-    if (prim is GetField) {
-      // When reading the field of a newly created object, just use the initial
-      // value and destroy the GetField. This can unblock the other optimization
-      // since we remove a use of the object.
-      Primitive object = prim.object;
-      if (object is CreateInstance && unescaped.contains(object)) {
-        int index = getFieldIndex(object.classElement, prim.field);
-        if (index == -1) {
-          escape(prim.objectRef);
-        } else {
-          prim.replaceUsesWith(object.argument(index));
-          prim.destroy();
-          node.remove();
-        }
-      }
-      return;
-    }
-    escapeVisitor.visit(node.primitive);
-  }
-
-  void rebindCreateInstanceAt(CreateInstance prim, LetPrim newBinding) {
-    removeBinding(prim);
-    newBinding.primitive = prim;
-    prim.parent = newBinding;
-  }
-
-  /// Returns the index of [field] in the canonical initialization order in
-  /// [classElement], or -1 if the field is not initialized at creation time
-  /// for that class.
-  int getFieldIndex(ClassElement classElement, FieldElement field) {
-    // There is no stored map from a field to its index in a given class, so we
-    // have to iterate over all instance fields until we find it.
-    int current = -1, index = -1;
-    classElement.forEachInstanceField((host, currentField) {
-      if (!backend.isNativeOrExtendsNative(host)) {
-        ++current;
-        if (currentField == field) {
-          index = current;
-        }
-      }
-    }, includeSuperAndInjectedMembers: true);
-    return index;
-  }
-
-  void removeBinding(Primitive prim) {
-    LetPrim node = prim.parent;
-    node.remove();
-  }
-}
-
-class EscapeVisitor extends DeepRecursiveVisitor {
-  final UseFieldInitializers main;
-  EscapeVisitor(this.main);
-
-  processReference(Reference ref) {
-    main.escape(ref);
-  }
-}
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 4301a55..f839dd9 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -11,9 +11,8 @@
 import 'package:package_config/discovery.dart' show findPackages;
 
 import '../compiler_new.dart' as api;
-import 'apiimpl.dart';
-import 'common/names.dart' show Uris;
 import 'commandline_options.dart';
+import 'common/names.dart' show Uris;
 import 'filenames.dart';
 import 'io/source_file.dart';
 import 'null_compiler_output.dart';
@@ -82,7 +81,8 @@
   var pattern = new RegExp('^(${patterns.join(")\$|^(")})\$');
 
   Iterator<String> arguments = argv.iterator;
-  OUTER: while (arguments.moveNext()) {
+  OUTER:
+  while (arguments.moveNext()) {
     String argument = arguments.current;
     Match match = pattern.firstMatch(argument);
     assert(match.groupCount == handlers.length);
@@ -109,29 +109,31 @@
   Uri out = currentDirectory.resolve('out.js');
   Uri sourceMapOut = currentDirectory.resolve('out.js.map');
   List<Uri> resolutionInputs;
+  List<String> bazelPaths;
   Uri packageConfig = null;
   Uri packageRoot = null;
   List<String> options = new List<String>();
   List<String> explicitOutputArguments = <String>[];
   bool wantHelp = false;
   bool wantVersion = false;
-  String outputLanguage = 'JavaScript';
-  bool stripArgumentSet = false;
   bool analyzeOnly = false;
   bool analyzeAll = false;
   bool resolveOnly = false;
   Uri resolutionOutput = currentDirectory.resolve('out.data');
-  bool dumpInfo = false;
   bool allowNativeExtensions = false;
   bool trustTypeAnnotations = false;
   bool trustJSInteropTypeAnnotations = false;
   bool checkedMode = false;
+  List<String> hints = <String>[];
+  bool verbose;
+  bool throwOnError;
+  int throwOnErrorCount;
+  bool showWarnings;
+  bool showHints;
+  bool enableColors;
   // List of provided options that imply that output is expected.
   List<String> optionsImplyCompilation = <String>[];
   bool hasDisallowUnsafeEval = false;
-  // TODO(johnniwinther): Measure time for reading files.
-  SourceFileProvider inputProvider = new CompilerSourceFileProvider();
-  diagnosticHandler = new FormattingDiagnosticHandler(inputProvider);
   Map<String, dynamic> environment = new Map<String, dynamic>();
 
   void passThrough(String argument) => options.add(argument);
@@ -173,20 +175,10 @@
     optionsImplyCompilation.add(argument);
     if (argument == '--output-type=dart' ||
         argument == '--output-type=dart-multi') {
-      outputLanguage = OUTPUT_LANGUAGE_DART;
-      if (explicitOutputArguments.isNotEmpty) {
-        out = currentDirectory.resolve('out.dart');
-        sourceMapOut = currentDirectory.resolve('out.dart.map');
-      }
-      diagnosticHandler(
-          null,
-          null,
-          null,
-          "--output-type=dart is deprecated. It will remain available "
-          "in Dart 1.11, but will be removed in Dart 1.12.",
-          api.Diagnostic.WARNING);
+      helpAndFail(
+          "--output-type=dart is no longer supported. It was deprecated "
+          "since Dart 1.11 and removed in Dart 1.19.");
     }
-    passThrough(argument);
   }
 
   void setResolutionInput(String argument) {
@@ -197,6 +189,11 @@
     }
   }
 
+  void setBazelPaths(String argument) {
+    String paths = extractParameter(argument);
+    bazelPaths = <String>[]..addAll(paths.split(','));
+  }
+
   void setResolveOnly(String argument) {
     resolveOnly = true;
     passThrough(argument);
@@ -208,14 +205,14 @@
     return filenames.join("\n");
   }
 
-  void implyCompilation(String argument) {
+  implyCompilation(String argument) {
     optionsImplyCompilation.add(argument);
     passThrough(argument);
   }
 
-  void setStrip(String argument) {
-    stripArgumentSet = true;
-    implyCompilation(argument);
+  setStrip(String argument) {
+    helpAndFail("Option '--force-strip' is not in use now that"
+        "--output-type=dart is no longer supported.");
   }
 
   void setAnalyzeOnly(String argument) {
@@ -234,15 +231,10 @@
   }
 
   void setVerbose(_) {
-    diagnosticHandler.verbose = true;
+    verbose = true;
     passThrough('--verbose');
   }
 
-  void setDumpInfo(String argument) {
-    implyCompilation(argument);
-    dumpInfo = true;
-  }
-
   void setTrustTypeAnnotations(String argument) {
     trustTypeAnnotations = true;
     implyCompilation(argument);
@@ -285,10 +277,11 @@
   }
 
   void handleThrowOnError(String argument) {
-    diagnosticHandler.throwOnError = true;
+    throwOnError = true;
     String parameter = extractParameter(argument, isOptionalArgument: true);
     if (parameter != null) {
-      diagnosticHandler.throwOnErrorCount = int.parse(parameter);
+      var count = int.parse(parameter);
+      throwOnErrorCount = count;
     }
   }
 
@@ -320,16 +313,17 @@
     new OptionHandler('-[chvm?]+', handleShortOptions),
     new OptionHandler('--throw-on-error(?:=[0-9]+)?', handleThrowOnError),
     new OptionHandler(Flags.suppressWarnings, (_) {
-      diagnosticHandler.showWarnings = false;
+      showWarnings = false;
       passThrough(Flags.suppressWarnings);
     }),
     new OptionHandler(Flags.fatalWarnings, passThrough),
-    new OptionHandler(
-        Flags.suppressHints, (_) => diagnosticHandler.showHints = false),
+    new OptionHandler(Flags.suppressHints, (_) {
+      showHints = false;
+    }),
+    // TODO(sigmund): remove entirely after Dart 1.20
     new OptionHandler(
         '--output-type=dart|--output-type=dart-multi|--output-type=js',
         setOutputType),
-    new OptionHandler(Flags.useCpsIr, passThrough),
     new OptionHandler(Flags.noFrequencyBasedMinification, passThrough),
     new OptionHandler(Flags.verbose, setVerbose),
     new OptionHandler(Flags.version, (_) => wantVersion = true),
@@ -342,10 +336,12 @@
     new OptionHandler('${Flags.minify}|-m', implyCompilation),
     new OptionHandler(Flags.preserveUris, passThrough),
     new OptionHandler('--force-strip=.*', setStrip),
-    new OptionHandler(Flags.disableDiagnosticColors,
-        (_) => diagnosticHandler.enableColors = false),
-    new OptionHandler(Flags.enableDiagnosticColors,
-        (_) => diagnosticHandler.enableColors = true),
+    new OptionHandler(Flags.disableDiagnosticColors, (_) {
+      enableColors = false;
+    }),
+    new OptionHandler(Flags.enableDiagnosticColors, (_) {
+      enableColors = true;
+    }),
     new OptionHandler('--enable[_-]checked[_-]mode|--checked',
         (_) => setCheckedMode(Flags.enableCheckedMode)),
     new OptionHandler(Flags.trustTypeAnnotations,
@@ -363,6 +359,7 @@
     new OptionHandler(Flags.analyzeOnly, setAnalyzeOnly),
     new OptionHandler(Flags.noSourceMaps, passThrough),
     new OptionHandler(Option.resolutionInput, setResolutionInput),
+    new OptionHandler(Option.bazelPaths, setBazelPaths),
     new OptionHandler(Flags.resolveOnly, setResolveOnly),
     new OptionHandler(Flags.analyzeSignaturesOnly, setAnalyzeOnly),
     new OptionHandler(Flags.disableNativeLiveTypeAnalysis, passThrough),
@@ -370,7 +367,7 @@
     new OptionHandler(Flags.disableTypeInference, implyCompilation),
     new OptionHandler(Flags.terse, passThrough),
     new OptionHandler('--deferred-map=.+', implyCompilation),
-    new OptionHandler(Flags.dumpInfo, setDumpInfo),
+    new OptionHandler(Flags.dumpInfo, implyCompilation),
     new OptionHandler(
         '--disallow-unsafe-eval', (_) => hasDisallowUnsafeEval = true),
     new OptionHandler(Option.showPackageWarnings, passThrough),
@@ -383,22 +380,16 @@
     // launched the feature yet.
     new OptionHandler(Flags.conditionalDirectives, (_) {}),
     new OptionHandler('--enable-async', (_) {
-      diagnosticHandler.info(
-          "Option '--enable-async' is no longer needed. "
-          "Async-await is supported by default.",
-          api.Diagnostic.HINT);
+      hints.add("Option '--enable-async' is no longer needed. "
+          "Async-await is supported by default.");
     }),
     new OptionHandler('--enable-null-aware-operators', (_) {
-      diagnosticHandler.info(
-          "Option '--enable-null-aware-operators' is no longer needed. "
-          "Null aware operators are supported by default.",
-          api.Diagnostic.HINT);
+      hints.add("Option '--enable-null-aware-operators' is no longer needed. "
+          "Null aware operators are supported by default.");
     }),
     new OptionHandler('--enable-enum', (_) {
-      diagnosticHandler.info(
-          "Option '--enable-enum' is no longer needed. "
-          "Enums are supported by default.",
-          api.Diagnostic.HINT);
+      hints.add("Option '--enable-enum' is no longer needed. "
+          "Enums are supported by default.");
     }),
     new OptionHandler(Flags.allowNativeExtensions, setAllowNativeExtensions),
     new OptionHandler(Flags.generateCodeWithCompileTimeErrors, passThrough),
@@ -415,6 +406,38 @@
   ];
 
   parseCommandLine(handlers, argv);
+
+  // TODO(johnniwinther): Measure time for reading files.
+  SourceFileProvider inputProvider;
+  if (bazelPaths != null) {
+    inputProvider = new BazelInputProvider(bazelPaths);
+  } else {
+    inputProvider = new CompilerSourceFileProvider();
+  }
+
+  diagnosticHandler = new FormattingDiagnosticHandler(inputProvider);
+  if (verbose != null) {
+    diagnosticHandler.verbose = verbose;
+  }
+  if (throwOnError != null) {
+    diagnosticHandler.throwOnError = throwOnError;
+  }
+  if (throwOnErrorCount != null) {
+    diagnosticHandler.throwOnErrorCount = throwOnErrorCount;
+  }
+  if (showWarnings != null) {
+    diagnosticHandler.showWarnings = showWarnings;
+  }
+  if (showHints != null) {
+    diagnosticHandler.showHints = showHints;
+  }
+  if (enableColors != null) {
+    diagnosticHandler.enableColors = enableColors;
+  }
+  for (String hint in hints) {
+    diagnosticHandler.info(hint, api.Diagnostic.HINT);
+  }
+
   if (wantHelp || wantVersion) {
     helpAndExit(wantHelp, wantVersion, diagnosticHandler.verbose);
   }
@@ -429,10 +452,6 @@
         " '$precompiledName'.");
   }
 
-  if (outputLanguage != OUTPUT_LANGUAGE_DART && stripArgumentSet) {
-    helpAndFail("Option '--force-strip' may only be used with "
-        "'--output-type=dart'.");
-  }
   if (arguments.isEmpty) {
     helpAndFail('No Dart file specified.');
   }
@@ -487,10 +506,6 @@
           "in combination with the '${Flags.analyzeOnly}' option.");
     }
   }
-  if (dumpInfo && outputLanguage == OUTPUT_LANGUAGE_DART) {
-    helpAndFail("Option '${Flags.dumpInfo}' is not supported in "
-        "combination with the '--output-type=dart' option.");
-  }
 
   options.add('--out=$out');
   options.add('--source-map=$sourceMapOut');
@@ -511,11 +526,11 @@
     diagnosticHandler
         .info('Compiled ${inputProvider.dartCharactersRead} characters Dart '
             '-> ${outputProvider.totalCharactersWritten} characters '
-            '$outputLanguage in '
+            'JavaScript in '
             '${relativize(currentDirectory, out, Platform.isWindows)}');
     if (diagnosticHandler.verbose) {
       String input = uriPathToNative(arguments[0]);
-      print('Dart file ($input) compiled to $outputLanguage.');
+      print('Dart file ($input) compiled to JavaScript.');
       print('Wrote the following files:');
       for (String filename in outputProvider.allOutputFiles) {
         print("  $filename");
@@ -523,7 +538,7 @@
     } else if (explicitOutputArguments.isNotEmpty) {
       String input = uriPathToNative(arguments[0]);
       String output = relativize(currentDirectory, out, Platform.isWindows);
-      print('Dart file ($input) compiled to $outputLanguage: $output');
+      print('Dart file ($input) compiled to JavaScript: $output');
     }
     return result;
   }
@@ -672,9 +687,6 @@
 The following options are only used for compiler development and may
 be removed in a future version:
 
-  --output-type=dart
-    Output Dart code instead of JavaScript.
-
   --throw-on-error
     Throw an exception if a compile-time error is detected.
 
@@ -703,16 +715,11 @@
     Generates an out.info.json file with information about the generated code.
     You can inspect the generated file with the viewer at:
         https://dart-lang.github.io/dump-info-visualizer/
-    This feature is currently not supported in combination with the
-    '--output-type=dart' option.
 
   --generate-code-with-compile-time-errors
     Generates output even if the program contains compile-time errors. Use the
     exit code to determine if compilation failed.
 
-  --use-cps-ir
-    Experimental.  Use the new CPS based backend for code generation.
-
   --no-frequency-based-minification
     Experimental.  Disabled the new frequency based minifying namer and use the
     old namer instead.
@@ -861,7 +868,8 @@
       api.CompilerInput compilerInput,
       api.CompilerDiagnostics compilerDiagnostics,
       api.CompilerOutput compilerOutput,
-      List<_SerializedData> serializedData) {
+      List<_SerializedData> serializedData,
+      {bool compileOnly: false}) {
     api.CompilerInput input = compilerInput;
     CompilerOptions options = compilerOptions;
     if (serializedData != null && serializedData.isNotEmpty) {
@@ -878,7 +886,8 @@
           }
         }
       }
-      options = options.copy(resolutionInputs: resolutionInputs);
+      options = CompilerOptions.copy(options,
+          resolutionInputs: resolutionInputs, compileOnly: compileOnly);
     }
     return oldCompileFunc(options, input, compilerDiagnostics, compilerOutput);
   }
@@ -892,15 +901,12 @@
       api.CompilerDiagnostics compilerDiagnostics,
       api.CompilerOutput compilerOutput,
       [List<_SerializedData> serializedData]) {
-    CompilerOptions options = new CompilerOptions.parse(
+    CompilerOptions options = CompilerOptions.copy(compilerOptions,
         entryPoint: entryPoint,
-        libraryRoot: compilerOptions.libraryRoot,
-        packageRoot: compilerOptions.packageRoot,
-        packageConfig: compilerOptions.packageConfig,
-        packagesDiscoveryProvider: compilerOptions.packagesDiscoveryProvider,
-        environment: compilerOptions.environment,
         resolutionOutput: serializedUri,
-        options: [Flags.resolveOnly]);
+        analyzeAll: true,
+        analyzeOnly: true,
+        resolveOnly: true);
     return compileWithSerializedData(options, compilerInput,
         compilerDiagnostics, compilerOutput, serializedData);
   }
@@ -932,7 +938,8 @@
         compilerInput,
         compilerDiagnostics,
         compilerOutput,
-        [serializedDartCore, output.serializedData]);
+        [serializedDartCore, output.serializedData],
+        compileOnly: true);
   }
 
   /// Compiles the entry point using the serialized data from dart:core.
diff --git a/pkg/compiler/lib/src/dart2js_profile_many.dart b/pkg/compiler/lib/src/dart2js_profile_many.dart
index e29ec46..8288a9a 100644
--- a/pkg/compiler/lib/src/dart2js_profile_many.dart
+++ b/pkg/compiler/lib/src/dart2js_profile_many.dart
@@ -4,9 +4,10 @@
 
 library dart2js.profile_many;
 
-import 'dart2js.dart' as cmdline;
 import 'dart:async';
 
+import 'dart2js.dart' as cmdline;
+
 const String USAGE = """
 Usage: dart2js_profile_many.dart [OPTIONS] [FILES]
 
diff --git a/pkg/compiler/lib/src/dart2js_stress.dart b/pkg/compiler/lib/src/dart2js_stress.dart
index 453d95c..804c577 100644
--- a/pkg/compiler/lib/src/dart2js_stress.dart
+++ b/pkg/compiler/lib/src/dart2js_stress.dart
@@ -33,5 +33,6 @@
       }
     });
   }
+
   iterate();
 }
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
deleted file mode 100644
index 371eed6..0000000
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ /dev/null
@@ -1,548 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart_backend;
-
-// TODO(ahe): This class is simply wrong.  This backend should use
-// elements when it can, not AST nodes.  Perhaps a [Map<Element,
-// TreeElements>] is what is needed.
-class ElementAst {
-  final Node ast;
-  final TreeElements treeElements;
-
-  ElementAst(this.ast, this.treeElements);
-}
-
-class DartBackend extends Backend {
-  final List<CompilerTask> tasks;
-  final bool stripAsserts;
-
-  bool get supportsReflection => true;
-
-  bool get supportsAsyncAwait => true;
-
-  // TODO(zarah) Maybe change this to a command-line option.
-  // Right now, it is set by the tests.
-  bool useMirrorHelperLibrary = false;
-
-  /// Updated to a [MirrorRenamerImpl] instance if the [useMirrorHelperLibrary]
-  /// field is set and mirror are needed.
-  MirrorRenamer mirrorRenamer = const MirrorRenamer();
-
-  final DartOutputter outputter;
-
-  // Used in test.
-  PlaceholderRenamer get placeholderRenamer => outputter.renamer;
-  Map<ClassNode, List<Node>> get memberNodes => outputter.output.memberNodes;
-
-  ConstantSystem get constantSystem {
-    return constantCompilerTask.constantCompiler.constantSystem;
-  }
-
-  BackendConstantEnvironment get constants => constantCompilerTask;
-
-  DartConstantTask constantCompilerTask;
-
-  DartImpactTransformer impactTransformer;
-
-  final Set<ClassElement> usedTypeLiterals = new Set<ClassElement>();
-
-  /// The set of visible platform classes that are implemented by instantiated
-  /// user classes.
-  final Set<ClassElement> _userImplementedPlatformClasses =
-      new Set<ClassElement>();
-
-  bool enableCodegenWithErrorsIfSupported(Spannable node) {
-    reporter.reportHintMessage(node, MessageKind.GENERIC, {
-      'text': "Generation of code with compile time errors is not "
-          "supported for dart2dart."
-    });
-    return false;
-  }
-
-  /**
-   * Tells whether it is safe to remove type declarations from variables,
-   * functions parameters. It becomes not safe if:
-   * 1) TypeError is used somewhere in the code,
-   * 2) The code has typedefs in right hand side of IS checks,
-   * 3) The code has classes which extend typedefs, have type arguments typedefs
-   *    or type variable bounds typedefs.
-   * These restrictions can be less strict.
-   */
-  bool isSafeToRemoveTypeDeclarations(
-      Map<ClassElement, Iterable<Element>> classMembers) {
-    ClassElement typeErrorElement = compiler.coreLibrary.find('TypeError');
-    if (classMembers.containsKey(typeErrorElement) ||
-        compiler.resolverWorld.isChecks
-            .any((DartType type) => type.element == typeErrorElement)) {
-      return false;
-    }
-    Set<DartType> processedTypes = new Set<DartType>();
-    List<DartType> workQueue = new List<DartType>();
-    workQueue
-        .addAll(classMembers.keys.map((classElement) => classElement.thisType));
-    workQueue.addAll(compiler.resolverWorld.isChecks);
-
-    while (!workQueue.isEmpty) {
-      DartType type = workQueue.removeLast();
-      if (processedTypes.contains(type)) continue;
-      processedTypes.add(type);
-      if (type is FunctionType) return false;
-      if (type is TypedefType) return false;
-      if (type is InterfaceType) {
-        InterfaceType interfaceType = type;
-        // Check all type arguments.
-        interfaceType.typeArguments.forEach(workQueue.add);
-        ClassElement element = type.element;
-        // Check all supertypes.
-        if (element.allSupertypes != null) {
-          element.allSupertypes.forEach(workQueue.add);
-        }
-      }
-    }
-    return true;
-  }
-
-  DartBackend(Compiler compiler, List<String> strips, {bool multiFile})
-      : tasks = <CompilerTask>[],
-        stripAsserts = strips.indexOf('asserts') != -1,
-        constantCompilerTask = new DartConstantTask(compiler),
-        outputter = new DartOutputter(
-            compiler.reporter, compiler.outputProvider,
-            forceStripTypes: strips.indexOf('types') != -1,
-            multiFile: multiFile,
-            enableMinification: compiler.options.enableMinification),
-        super(compiler) {
-    impactTransformer = new DartImpactTransformer(this);
-  }
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  Resolution get resolution => compiler.resolution;
-
-  bool classNeedsRti(ClassElement cls) => false;
-  bool methodNeedsRti(FunctionElement function) => false;
-
-  void enqueueHelpers(ResolutionEnqueuer world, Registry registry) {
-    // Right now resolver doesn't always resolve interfaces needed
-    // for literals, so force them. TODO(antonm): fix in the resolver.
-    final LITERAL_TYPE_NAMES = const [
-      'Map',
-      'List',
-      'num',
-      'int',
-      'double',
-      'bool'
-    ];
-    final coreLibrary = compiler.coreLibrary;
-    for (final name in LITERAL_TYPE_NAMES) {
-      ClassElement classElement = coreLibrary.findLocal(name);
-      classElement.ensureResolved(resolution);
-    }
-    // Enqueue the methods that the VM might invoke on user objects because
-    // we don't trust the resolution to always get these included.
-    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) {
-    return const WorldImpact();
-  }
-
-  /**
-   * Tells whether we should output given element. Corelib classes like
-   * Object should not be in the resulting code.
-   */
-  @override
-  bool shouldOutput(Element element) {
-    return (!element.library.isPlatformLibrary &&
-            !element.isSynthesized &&
-            element is! AbstractFieldElement) ||
-        mirrorRenamer.isMirrorHelperLibrary(element.library);
-  }
-
-  int assembleProgram() {
-    ElementAst computeElementAst(AstElement element) {
-      return new ElementAst(
-          element.resolvedAst.node, element.resolvedAst.elements);
-    }
-
-    // TODO(johnniwinther): Remove the need for this method.
-    void postProcessElementAst(AstElement element, ElementAst elementAst,
-        newTypedefElementCallback, newClassElementCallback) {
-      ReferencedElementCollector collector = new ReferencedElementCollector(
-          reporter,
-          element,
-          elementAst,
-          newTypedefElementCallback,
-          newClassElementCallback);
-      collector.collect();
-    }
-
-    int totalSize = outputter.assembleProgram(
-        libraries: compiler.libraryLoader.libraries,
-        instantiatedClasses: compiler.resolverWorld.directlyInstantiatedClasses,
-        resolvedElements: compiler.enqueuer.resolution.processedElements,
-        usedTypeLiterals: usedTypeLiterals,
-        postProcessElementAst: postProcessElementAst,
-        computeElementAst: computeElementAst,
-        shouldOutput: shouldOutput,
-        isSafeToRemoveTypeDeclarations: isSafeToRemoveTypeDeclarations,
-        sortElements: Elements.sortedByPosition,
-        mirrorRenamer: mirrorRenamer,
-        mainFunction: compiler.mainFunction,
-        outputUri: compiler.options.outputUri);
-
-    // Output verbose info about size ratio of resulting bundle to all
-    // referenced non-platform sources.
-    logResultBundleSizeInfo(outputter.libraryInfo.userLibraries,
-        outputter.elementInfo.topLevelElements, totalSize);
-
-    return totalSize;
-  }
-
-  void logResultBundleSizeInfo(Iterable<LibraryElement> userLibraries,
-      Iterable<Element> topLevelElements, int totalOutputSize) {
-    // Sum total size of scripts in each referenced library.
-    int nonPlatformSize = 0;
-    for (LibraryElement lib in userLibraries) {
-      for (CompilationUnitElement compilationUnit in lib.compilationUnits) {
-        nonPlatformSize += compilationUnit.script.file.length;
-      }
-    }
-    int percentage = totalOutputSize * 100 ~/ nonPlatformSize;
-    log('Total used non-platform files size: ${nonPlatformSize} bytes, '
-        'Output total size: $totalOutputSize bytes (${percentage}%)');
-  }
-
-  log(String message) => reporter.log('[DartBackend] $message');
-
-  @override
-  Future onLibrariesLoaded(LoadedLibraries loadedLibraries) {
-    // All platform classes must be resolved to ensure that their member names
-    // are preserved.
-    loadedLibraries.forEachLibrary((LibraryElement library) {
-      if (library.isPlatformLibrary) {
-        library.forEachLocalMember((Element element) {
-          if (element.isClass) {
-            ClassElement classElement = element;
-            classElement.ensureResolved(resolution);
-          }
-        });
-      }
-    });
-    if (useMirrorHelperLibrary &&
-        loadedLibraries.containsLibrary(Uris.dart_mirrors)) {
-      return compiler.libraryLoader
-          .loadLibrary(compiler.resolvedUriTranslator.translate(
-              loadedLibraries.getLibrary(Uris.dart_mirrors),
-              MirrorRenamerImpl.DART_MIRROR_HELPER,
-              null))
-          .then((LibraryElement library) {
-        mirrorRenamer = new MirrorRenamerImpl(compiler, this, library);
-      });
-    }
-    return new Future.value();
-  }
-
-  @override
-  void registerStaticUse(Element element, Enqueuer enqueuer) {
-    if (element == compiler.mirrorSystemGetNameFunction) {
-      FunctionElement getNameFunction = mirrorRenamer.getNameFunction;
-      if (getNameFunction != null) {
-        enqueuer.addToWorkList(getNameFunction);
-      }
-    }
-  }
-
-  @override
-  void registerInstantiatedType(
-      InterfaceType type, Enqueuer enqueuer, Registry registry,
-      {bool mirrorUsage: false}) {
-    registerPlatformMembers(type, registerUse: registry.registerDynamicUse);
-    super.registerInstantiatedType(type, enqueuer, registry,
-        mirrorUsage: mirrorUsage);
-  }
-
-  /// Register dynamic access of members of [type] that implement members
-  /// of types defined in the platform libraries.
-  void registerPlatformMembers(InterfaceType type,
-      {void registerUse(DynamicUse dynamicUse)}) {
-    // Without patching, dart2dart has no way of performing sound tree-shaking
-    // in face external functions. Therefore we employ another scheme:
-    //
-    // Based on the assumption that the platform code only relies on the
-    // interfaces of it's own classes, we can approximate the semantics of
-    // external functions by eagerly registering dynamic invocation of instance
-    // members defined the platform interfaces.
-    //
-    // Since we only need to generate code for non-platform classes we can
-    // restrict this registration to platform interfaces implemented by
-    // instantiated non-platform classes.
-    //
-    // Consider for instance this program:
-    //
-    //     import 'dart:math' show Random;
-    //
-    //     class MyRandom implements Random {
-    //       int nextInt() => 0;
-    //     }
-    //
-    //     main() {
-    //       print([0, 1, 2].shuffle(new MyRandom()));
-    //     }
-    //
-    // Here `MyRandom` is a subtype if `Random` defined in 'dart:math'. By the
-    // assumption, all methods defined `Random` are potentially called, and
-    // therefore, though there are no visible call sites from the user node,
-    // dynamic invocation of for instance `nextInt` should be registered. In
-    // this case, `nextInt` is actually called by the standard implementation of
-    // `shuffle`.
-
-    ClassElement cls = type.element;
-    if (!cls.library.isPlatformLibrary) {
-      for (Link<DartType> link = cls.allSupertypes;
-          !link.isEmpty;
-          link = link.tail) {
-        InterfaceType supertype = link.head;
-        ClassElement superclass = supertype.element;
-        LibraryElement library = superclass.library;
-        if (library.isPlatformLibrary) {
-          if (_userImplementedPlatformClasses.add(superclass)) {
-            // Register selectors for all instance methods since these might
-            // be called on user classes from within the platform
-            // implementation.
-            superclass.forEachLocalMember((MemberElement element) {
-              if (element.isConstructor || element.isStatic) return;
-
-              element.computeType(resolution);
-              Selector selector = new Selector.fromElement(element);
-              registerUse(new DynamicUse(selector, null));
-            });
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) {
-    // TODO(sigurdm): Implement deferred loading for dart2dart.
-    reporter.reportWarningMessage(
-        node, MessageKind.DEFERRED_LIBRARY_DART_2_DART);
-    return false;
-  }
-
-  @override
-  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 (TypeUse typeUse in worldImpact.typeUses) {
-      if (typeUse.kind == TypeUseKind.TYPE_LITERAL &&
-          typeUse.type.isInterfaceType) {
-        backend.usedTypeLiterals.add(typeUse.type.element);
-      }
-      if (typeUse.kind == TypeUseKind.INSTANTIATION) {
-        backend.registerPlatformMembers(typeUse.type,
-            registerUse: transformed.registerDynamicUse);
-      }
-    }
-    return transformed;
-  }
-}
-
-class EmitterUnparser extends Unparser {
-  final Map<Node, String> renames;
-
-  EmitterUnparser(this.renames, {bool minify, bool stripTypes})
-      : super(minify: minify, stripTypes: stripTypes);
-
-  visit(Node node) {
-    if (node != null && renames.containsKey(node)) {
-      write(renames[node]);
-    } else {
-      super.visit(node);
-    }
-  }
-
-  unparseSendReceiver(Send node, {bool spacesNeeded: false}) {
-    // TODO(smok): Remove ugly hack for library prefices.
-    if (node.receiver != null && renames[node.receiver] == '') return;
-    super.unparseSendReceiver(node, spacesNeeded: spacesNeeded);
-  }
-
-  unparseFunctionName(Node name) {
-    if (name != null && renames.containsKey(name)) {
-      write(renames[name]);
-    } else {
-      super.unparseFunctionName(name);
-    }
-  }
-}
-
-/**
- * Some elements are not recorded by resolver now,
- * for example, typedefs or classes which are only
- * used in signatures, as/is operators or in super clauses
- * (just to name a few).  Retraverse AST to pick those up.
- */
-class ReferencedElementCollector extends Visitor {
-  final DiagnosticReporter reporter;
-  final Element element;
-  final ElementAst elementAst;
-  final newTypedefElementCallback;
-  final newClassElementCallback;
-
-  ReferencedElementCollector(this.reporter, this.element, this.elementAst,
-      this.newTypedefElementCallback, this.newClassElementCallback);
-
-  visitNode(Node node) {
-    node.visitChildren(this);
-  }
-
-  visitTypeAnnotation(TypeAnnotation typeAnnotation) {
-    TreeElements treeElements = elementAst.treeElements;
-    final DartType type = treeElements.getType(typeAnnotation);
-    assert(invariant(typeAnnotation, type != null,
-        message: "Missing type for type annotation: $treeElements."));
-    if (type.isTypedef) newTypedefElementCallback(type.element);
-    if (type.isInterfaceType) newClassElementCallback(type.element);
-    typeAnnotation.visitChildren(this);
-  }
-
-  void collect() {
-    reporter.withCurrentElement(element, () {
-      elementAst.ast.accept(this);
-    });
-  }
-}
-
-Comparator compareBy(f) => (x, y) => f(x).compareTo(f(y));
-
-List sorted(Iterable l, comparison) {
-  final result = new List.from(l);
-  result.sort(comparison);
-  return result;
-}
-
-compareElements(e0, e1) {
-  int result = compareBy((e) => e.library.canonicalUri.toString())(e0, e1);
-  if (result != 0) return result;
-  return compareBy((e) => e.position.charOffset)(e0, e1);
-}
-
-/// [ConstantCompilerTask] for compilation of constants for the Dart backend.
-///
-/// Since this task needs no distinction between frontend and backend constants
-/// it also serves as the [BackendConstantEnvironment].
-class DartConstantTask extends ConstantCompilerTask
-    implements BackendConstantEnvironment {
-  final DartConstantCompiler constantCompiler;
-
-  DartConstantTask(Compiler compiler)
-      : this.constantCompiler = new DartConstantCompiler(compiler),
-        super(compiler.measurer);
-
-  String get name => 'ConstantHandler';
-
-  @override
-  ConstantSystem get constantSystem => constantCompiler.constantSystem;
-
-  @override
-  bool hasConstantValue(ConstantExpression expression) {
-    return constantCompiler.hasConstantValue(expression);
-  }
-
-  @override
-  ConstantValue getConstantValue(ConstantExpression expression) {
-    return constantCompiler.getConstantValue(expression);
-  }
-
-  @override
-  ConstantValue getConstantValueForVariable(VariableElement element) {
-    return constantCompiler.getConstantValueForVariable(element);
-  }
-
-  @override
-  ConstantExpression getConstantForNode(Node node, TreeElements elements) {
-    return constantCompiler.getConstantForNode(node, elements);
-  }
-
-  @override
-  ConstantValue getConstantValueForNode(Node node, TreeElements elements) {
-    return getConstantValue(
-        constantCompiler.getConstantForNode(node, elements));
-  }
-
-  @override
-  ConstantValue getConstantValueForMetadata(MetadataAnnotation metadata) {
-    return getConstantValue(metadata.constant);
-  }
-
-  @override
-  ConstantExpression compileConstant(VariableElement element) {
-    return measure(() {
-      return constantCompiler.compileConstant(element);
-    });
-  }
-
-  @override
-  void evaluate(ConstantExpression constant) {
-    return measure(() {
-      return constantCompiler.evaluate(constant);
-    });
-  }
-
-  @override
-  ConstantExpression compileVariable(VariableElement element) {
-    return measure(() {
-      return constantCompiler.compileVariable(element);
-    });
-  }
-
-  @override
-  ConstantExpression compileNode(Node node, TreeElements elements,
-      {bool enforceConst: true}) {
-    return measure(() {
-      return constantCompiler.compileNodeWithDefinitions(node, elements,
-          isConst: enforceConst);
-    });
-  }
-
-  @override
-  ConstantExpression compileMetadata(
-      MetadataAnnotation metadata, Node node, TreeElements elements) {
-    return measure(() {
-      return constantCompiler.compileMetadata(metadata, node, elements);
-    });
-  }
-
-  // TODO(johnniwinther): Remove this when values are computed from the
-  // expressions.
-  @override
-  void copyConstantValues(DartConstantTask task) {
-    constantCompiler.constantValueMap
-        .addAll(task.constantCompiler.constantValueMap);
-  }
-
-  @override
-  void registerLazyStatic(FieldElement element) {
-    // Do nothing.
-  }
-}
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
deleted file mode 100644
index fd7a45f..0000000
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
+++ /dev/null
@@ -1,93 +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 backend_ast_emitter;
-
-import 'backend_ast_nodes.dart';
-import '../dart_types.dart';
-import '../elements/elements.dart';
-
-class TypeGenerator {
-  /// TODO(johnniwinther): Remove this when issue 21283 has been resolved.
-  static int pseudoNameCounter = 0;
-
-  static Parameter emitParameter(DartType type,
-      {String name, Element element}) {
-    if (name == null && element != null) {
-      name = element.name;
-    }
-    if (name == null) {
-      name = '_${pseudoNameCounter++}';
-    }
-    Parameter parameter;
-    if (type.isFunctionType) {
-      FunctionType functionType = type;
-      TypeAnnotation returnType = createOptionalType(functionType.returnType);
-      Parameters innerParameters = createParametersFromType(functionType);
-      parameter = new Parameter.function(name, returnType, innerParameters);
-    } else {
-      TypeAnnotation typeAnnotation = createOptionalType(type);
-      parameter = new Parameter(name, type: typeAnnotation);
-    }
-    parameter.element = element;
-    return parameter;
-  }
-
-  static Parameters createParametersFromType(FunctionType functionType) {
-    pseudoNameCounter = 0;
-    if (functionType.namedParameters.isEmpty) {
-      return new Parameters(createParameters(functionType.parameterTypes),
-          createParameters(functionType.optionalParameterTypes), false);
-    } else {
-      return new Parameters(
-          createParameters(functionType.parameterTypes),
-          createParameters(functionType.namedParameterTypes,
-              names: functionType.namedParameters),
-          true);
-    }
-  }
-
-  static List<Parameter> createParameters(Iterable<DartType> parameterTypes,
-      {Iterable<String> names: const <String>[],
-      Iterable<Element> elements: const <Element>[]}) {
-    Iterator<String> name = names.iterator;
-    Iterator<Element> element = elements.iterator;
-    return parameterTypes.map((DartType type) {
-      name.moveNext();
-      element.moveNext();
-      return emitParameter(type, name: name.current, element: element.current);
-    }).toList();
-  }
-
-  /// Like [createTypeAnnotation] except the dynamic type is converted to null.
-  static TypeAnnotation createOptionalType(DartType type) {
-    if (type.treatAsDynamic) {
-      return null;
-    } else {
-      return createType(type);
-    }
-  }
-
-  /// Creates the [TypeAnnotation] for a [type] that is not function type.
-  static TypeAnnotation createType(DartType type) {
-    if (type is GenericType) {
-      if (type.treatAsRaw) {
-        return new TypeAnnotation(type.element.name)..dartType = type;
-      }
-      return new TypeAnnotation(type.element.name,
-          type.typeArguments.map(createType).toList(growable: false))
-        ..dartType = type;
-    } else if (type is VoidType) {
-      return new TypeAnnotation('void')..dartType = type;
-    } else if (type is TypeVariableType) {
-      return new TypeAnnotation(type.name)..dartType = type;
-    } else if (type is DynamicType) {
-      return new TypeAnnotation("dynamic")..dartType = type;
-    } else if (type is MalformedType) {
-      return new TypeAnnotation(type.name)..dartType = type;
-    } else {
-      throw "Unsupported type annotation: $type";
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
deleted file mode 100644
index 1c8abd0..0000000
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
+++ /dev/null
@@ -1,1556 +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 backend_ast_nodes;
-
-import '../constants/values.dart' as values;
-import '../dart_types.dart' as types;
-import '../elements/elements.dart' as elements;
-import '../tree/tree.dart' as tree;
-import '../util/characters.dart' as characters;
-
-/// The following nodes correspond to [tree.Send] expressions:
-/// [FieldExpression], [IndexExpression], [Assignment], [Increment],
-/// [CallFunction], [CallMethod], [CallNew], [CallStatic], [UnaryOperator],
-/// [BinaryOperator], and [TypeOperator].
-abstract class Node {}
-
-/// Receiver is an [Expression] or the [SuperReceiver].
-abstract class Receiver extends Node {}
-
-/// Argument is an [Expression] or a [NamedArgument].
-abstract class Argument extends Node {}
-
-abstract class Expression extends Node implements Receiver, Argument {
-  bool get assignable => false;
-}
-
-abstract class RootNode extends Node {
-  elements.Element get element;
-}
-
-class FieldDefinition extends RootNode {
-  final elements.Element element;
-  final Expression initializer;
-  FieldDefinition(this.element, this.initializer);
-}
-
-abstract class Statement extends Node {}
-
-/// Used as receiver in expressions that dispatch to the super class.
-/// For instance, an expression such as `super.f()` is represented
-/// by a [CallMethod] node with [SuperReceiver] as its receiver.
-class SuperReceiver extends Receiver {
-  static final SuperReceiver _instance = new SuperReceiver._create();
-
-  factory SuperReceiver() => _instance;
-  SuperReceiver._create();
-}
-
-/// Named arguments may occur in the argument list of
-/// [CallFunction], [CallMethod], [CallNew], and [CallStatic].
-class NamedArgument extends Argument {
-  final String name;
-  final Expression expression;
-
-  NamedArgument(this.name, this.expression);
-}
-
-class TypeAnnotation extends Node {
-  final String name;
-  final List<TypeAnnotation> typeArguments;
-
-  types.DartType dartType;
-
-  TypeAnnotation(this.name, [this.typeArguments = const <TypeAnnotation>[]]);
-}
-
-// STATEMENTS
-
-class Block extends Statement {
-  final List<Statement> statements;
-
-  Block(this.statements);
-}
-
-class Break extends Statement {
-  final String label;
-
-  Break([this.label]);
-}
-
-class Continue extends Statement {
-  final String label;
-
-  Continue([this.label]);
-}
-
-class EmptyStatement extends Statement {
-  static final EmptyStatement _instance = new EmptyStatement._create();
-
-  factory EmptyStatement() => _instance;
-  EmptyStatement._create();
-}
-
-class ExpressionStatement extends Statement {
-  final Expression expression;
-
-  ExpressionStatement(this.expression);
-}
-
-class For extends Statement {
-  final Node initializer;
-  final Expression condition;
-  final List<Expression> updates;
-  final Statement body;
-
-  /// Initializer must be [VariableDeclarations] or [Expression] or null.
-  For(this.initializer, this.condition, this.updates, this.body) {
-    assert(initializer == null ||
-        initializer is VariableDeclarations ||
-        initializer is Expression);
-  }
-}
-
-class ForIn extends Statement {
-  final Node leftHandValue;
-  final Expression expression;
-  final Statement body;
-
-  /// [leftHandValue] must be [Identifier] or [VariableDeclarations] with
-  /// exactly one definition, and that variable definition must have no
-  /// initializer.
-  ForIn(Node leftHandValue, this.expression, this.body)
-      : this.leftHandValue = leftHandValue {
-    assert(leftHandValue is Identifier ||
-        (leftHandValue is VariableDeclarations &&
-            leftHandValue.declarations.length == 1 &&
-            leftHandValue.declarations[0].initializer == null));
-  }
-}
-
-class While extends Statement {
-  final Expression condition;
-  final Statement body;
-
-  While(this.condition, this.body);
-}
-
-class DoWhile extends Statement {
-  final Statement body;
-  final Expression condition;
-
-  DoWhile(this.body, this.condition);
-}
-
-class If extends Statement {
-  final Expression condition;
-  final Statement thenStatement;
-  final Statement elseStatement;
-
-  If(this.condition, this.thenStatement, [this.elseStatement]);
-}
-
-class LabeledStatement extends Statement {
-  final String label;
-  final Statement statement;
-
-  LabeledStatement(this.label, this.statement);
-}
-
-class Rethrow extends Statement {}
-
-class Return extends Statement {
-  final Expression expression;
-
-  Return([this.expression]);
-}
-
-class Switch extends Statement {
-  final Expression expression;
-  final List<SwitchCase> cases;
-
-  Switch(this.expression, this.cases);
-}
-
-/// A sequence of case clauses followed by a sequence of statements.
-/// Represents the default case if [expressions] is null.
-///
-/// NOTE:
-/// Control will never fall through to the following SwitchCase, even if
-/// the list of statements is empty. An empty list of statements will be
-/// unparsed to a semicolon to guarantee this behaviour.
-class SwitchCase extends Node {
-  final List<Expression> expressions;
-  final List<Statement> statements;
-
-  SwitchCase(this.expressions, this.statements);
-  SwitchCase.defaultCase(this.statements) : expressions = null;
-
-  bool get isDefaultCase => expressions == null;
-}
-
-/// A try statement. The try, catch and finally blocks will automatically
-/// be printed inside a block statement if necessary.
-class Try extends Statement {
-  final Statement tryBlock;
-  final List<CatchBlock> catchBlocks;
-  final Statement finallyBlock;
-
-  Try(this.tryBlock, this.catchBlocks, [this.finallyBlock]) {
-    assert(catchBlocks.length > 0 || finallyBlock != null);
-  }
-}
-
-class CatchBlock extends Node {
-  final TypeAnnotation onType;
-  final VariableDeclaration exceptionVar;
-  final VariableDeclaration stackVar;
-  final Statement body;
-
-  /// At least onType or exceptionVar must be given.
-  /// stackVar may only be given if exceptionVar is also given.
-  CatchBlock(this.body, {this.onType, this.exceptionVar, this.stackVar}) {
-    // Must specify at least a type or an exception binding.
-    assert(onType != null || exceptionVar != null);
-
-    // We cannot bind the stack trace without binding the exception too.
-    assert(stackVar == null || exceptionVar != null);
-  }
-}
-
-class VariableDeclarations extends Statement {
-  final TypeAnnotation type;
-  final bool isFinal;
-  final bool isConst;
-  final List<VariableDeclaration> declarations;
-
-  VariableDeclarations(this.declarations,
-      {this.type, this.isFinal: false, this.isConst: false}) {
-    // Cannot be both final and const.
-    assert(!isFinal || !isConst);
-  }
-}
-
-class VariableDeclaration extends Node {
-  final String name;
-  final Expression initializer;
-
-  elements.Element element;
-
-  VariableDeclaration(this.name, [this.initializer]);
-}
-
-class FunctionDeclaration extends Statement {
-  final FunctionExpression function;
-
-  TypeAnnotation get returnType => function.returnType;
-  Parameters get parameters => function.parameters;
-  String get name => function.name;
-  Statement get body => function.body;
-
-  FunctionDeclaration(this.function);
-}
-
-class Parameters extends Node {
-  final List<Parameter> requiredParameters;
-  final List<Parameter> optionalParameters;
-  final bool hasNamedParameters;
-
-  Parameters(this.requiredParameters,
-      [this.optionalParameters, this.hasNamedParameters = false]);
-
-  Parameters.named(this.requiredParameters, this.optionalParameters)
-      : hasNamedParameters = true;
-
-  Parameters.positional(this.requiredParameters, this.optionalParameters)
-      : hasNamedParameters = false;
-
-  bool get hasOptionalParameters =>
-      optionalParameters != null && optionalParameters.length > 0;
-}
-
-class Parameter extends Node {
-  final String name;
-
-  /// Type of parameter, or return type of function parameter.
-  final TypeAnnotation type;
-
-  Expression defaultValue;
-
-  /// Parameters to function parameter. Null for non-function parameters.
-  final Parameters parameters;
-
-  elements.FormalElement element;
-
-  Parameter(this.name, {this.type, this.defaultValue}) : parameters = null;
-
-  Parameter.function(this.name, TypeAnnotation returnType, this.parameters,
-      [this.defaultValue])
-      : type = returnType {
-    assert(parameters != null);
-  }
-
-  /// True if this is a function parameter.
-  bool get isFunction => parameters != null;
-}
-
-// EXPRESSIONS
-
-abstract class Initializer extends Expression {}
-
-class FieldInitializer extends Initializer {
-  final elements.FieldElement element;
-  final Expression body;
-
-  FieldInitializer(this.element, this.body);
-}
-
-class SuperInitializer extends Initializer {
-  final elements.ConstructorElement target;
-  final List<Argument> arguments;
-
-  SuperInitializer(this.target, this.arguments);
-}
-
-class FunctionExpression extends Expression implements RootNode {
-  final TypeAnnotation returnType;
-  String name;
-  final Parameters parameters;
-  final Statement body;
-  final bool isGetter;
-  final bool isSetter;
-
-  elements.FunctionElement element;
-
-  FunctionExpression(this.parameters, this.body,
-      {this.name,
-      this.returnType,
-      this.isGetter: false,
-      this.isSetter: false}) {
-    // Function must have a name if it has a return type
-    assert(returnType == null || name != null);
-  }
-}
-
-class ConstructorDefinition extends FunctionExpression {
-  final List<Initializer> initializers;
-  final bool isConst;
-
-  ConstructorDefinition(Parameters parameters, Statement body,
-      this.initializers, String name, this.isConst)
-      : super(parameters, body, name: name);
-}
-
-class Conditional extends Expression {
-  final Expression condition;
-  final Expression thenExpression;
-  final Expression elseExpression;
-
-  Conditional(this.condition, this.thenExpression, this.elseExpression);
-}
-
-/// An identifier expression.
-/// The unparser does not concern itself with scoping rules, and it is the
-/// responsibility of the AST creator to ensure that the identifier resolves
-/// to the proper definition.
-/// For the time being, this class is also used to reference static fields and
-/// top-level variables that are qualified with a class and/or library name,
-/// assuming the [element] is set. This is likely to change when the old backend
-/// is replaced.
-class Identifier extends Expression {
-  final String name;
-
-  elements.Element element;
-
-  Identifier(this.name);
-
-  bool get assignable => true;
-}
-
-class Literal extends Expression {
-  final values.PrimitiveConstantValue value;
-
-  Literal(this.value);
-}
-
-class LiteralList extends Expression {
-  final bool isConst;
-  final TypeAnnotation typeArgument;
-  final List<Expression> values;
-
-  LiteralList(this.values, {this.typeArgument, this.isConst: false});
-}
-
-class LiteralMap extends Expression {
-  final bool isConst;
-  final List<TypeAnnotation> typeArguments;
-  final List<LiteralMapEntry> entries;
-
-  LiteralMap(this.entries, {this.typeArguments, this.isConst: false}) {
-    assert(this.typeArguments == null ||
-        this.typeArguments.length == 0 ||
-        this.typeArguments.length == 2);
-  }
-}
-
-class LiteralMapEntry extends Node {
-  final Expression key;
-  final Expression value;
-
-  LiteralMapEntry(this.key, this.value);
-}
-
-class LiteralSymbol extends Expression {
-  final String id;
-
-  /// [id] should not include the # symbol
-  LiteralSymbol(this.id);
-}
-
-/// A type literal. This is distinct from [Identifier] since the unparser
-/// needs to this distinguish a static invocation from a method invocation
-/// on a type literal.
-class LiteralType extends Expression {
-  final String name;
-
-  types.DartType type;
-
-  LiteralType(this.name);
-}
-
-/// Reference to a type variable.
-/// This is distinct from [Identifier] since the unparser needs to this
-/// distinguish a function invocation `T()` from a type variable invocation
-/// `(T)()` (the latter is invalid, but must be generated anyway).
-class ReifyTypeVar extends Expression {
-  final String name;
-
-  elements.TypeVariableElement element;
-
-  ReifyTypeVar(this.name);
-}
-
-/// StringConcat is used in place of string interpolation and juxtaposition.
-/// Semantically, each subexpression is evaluated and converted to a string
-/// by `toString()`. These string are then concatenated and returned.
-/// StringConcat unparses to a string literal, possibly with interpolations.
-/// The unparser will flatten nested StringConcats.
-/// A StringConcat node may have any number of children, including zero and one.
-class StringConcat extends Expression {
-  final List<Expression> expressions;
-
-  StringConcat(this.expressions);
-}
-
-/// Expression of form `e.f`.
-class FieldExpression extends Expression {
-  final Receiver object;
-  final String fieldName;
-
-  FieldExpression(this.object, this.fieldName);
-
-  bool get assignable => true;
-}
-
-/// Expression of form `e1[e2]`.
-class IndexExpression extends Expression {
-  final Receiver object;
-  final Expression index;
-
-  IndexExpression(this.object, this.index);
-
-  bool get assignable => true;
-}
-
-/// Expression of form `e(..)`
-/// Note that if [callee] is a [FieldExpression] this will translate into
-/// `(e.f)(..)` and not `e.f(..)`. Use a [CallMethod] to generate
-/// the latter type of expression.
-class CallFunction extends Expression {
-  final Expression callee;
-  final List<Argument> arguments;
-
-  CallFunction(this.callee, this.arguments);
-}
-
-/// Expression of form `e.f(..)`.
-class CallMethod extends Expression {
-  final Receiver object;
-  final String methodName;
-  final List<Argument> arguments;
-
-  CallMethod(this.object, this.methodName, this.arguments);
-}
-
-/// Expression of form `new T(..)`, `new T.f(..)`, `const T(..)`,
-/// or `const T.f(..)`.
-class CallNew extends Expression {
-  final bool isConst;
-  final TypeAnnotation type;
-  final String constructorName;
-  final List<Argument> arguments;
-
-  elements.FunctionElement constructor;
-  types.DartType dartType;
-
-  CallNew(this.type, this.arguments,
-      {this.constructorName, this.isConst: false});
-}
-
-/// Expression of form `T.f(..)`.
-class CallStatic extends Expression {
-  final String className;
-  final String methodName;
-  final List<Argument> arguments;
-
-  elements.Element element;
-
-  CallStatic(this.className, this.methodName, this.arguments);
-}
-
-/// Expression of form `!e` or `-e` or `~e`.
-class UnaryOperator extends Expression {
-  final String operatorName;
-  final Receiver operand;
-
-  UnaryOperator(this.operatorName, this.operand) {
-    assert(isUnaryOperator(operatorName));
-  }
-}
-
-/// Expression of form `e1 + e2`, `e1 - e2`, etc.
-/// This node also represents application of the logical operators && and ||.
-class BinaryOperator extends Expression {
-  final Receiver left;
-  final String operator;
-  final Expression right;
-
-  BinaryOperator(this.left, this.operator, this.right) {
-    assert(isBinaryOperator(operator));
-  }
-}
-
-/// Expression of form `e is T` or `e is! T` or `e as T`.
-class TypeOperator extends Expression {
-  final Expression expression;
-  final String operator;
-  final TypeAnnotation type;
-
-  TypeOperator(this.expression, this.operator, this.type) {
-    assert(operator == 'is' || operator == 'as' || operator == 'is!');
-  }
-}
-
-class Increment extends Expression {
-  final Expression expression;
-  final String operator;
-  final bool isPrefix;
-
-  Increment(this.expression, this.operator, this.isPrefix) {
-    assert(operator == '++' || operator == '--');
-    assert(expression.assignable);
-  }
-
-  Increment.prefix(Expression expression, String operator)
-      : this(expression, operator, true);
-
-  Increment.postfix(Expression expression, String operator)
-      : this(expression, operator, false);
-}
-
-class Assignment extends Expression {
-  static final _operators = new Set.from([
-    '=',
-    '|=',
-    '^=',
-    '&=',
-    '<<=',
-    '>>=',
-    '+=',
-    '-=',
-    '*=',
-    '/=',
-    '%=',
-    '~/='
-  ]);
-
-  final Expression left;
-  final String operator;
-  final Expression right;
-
-  Assignment(this.left, this.operator, this.right) {
-    assert(_operators.contains(operator));
-    assert(left.assignable);
-  }
-}
-
-class Throw extends Expression {
-  final Expression expression;
-
-  Throw(this.expression);
-}
-
-class This extends Expression {
-  static final This _instance = new This._create();
-
-  factory This() => _instance;
-  This._create();
-}
-
-// UNPARSER
-
-bool isUnaryOperator(String op) {
-  return op == '!' || op == '-' || op == '~';
-}
-
-bool isBinaryOperator(String op) {
-  return BINARY_PRECEDENCE.containsKey(op);
-}
-
-/// True if the given operator can be converted to a compound assignment.
-bool isCompoundableOperator(String op) {
-  switch (BINARY_PRECEDENCE[op]) {
-    case BITWISE_OR:
-    case BITWISE_XOR:
-    case BITWISE_AND:
-    case SHIFT:
-    case ADDITIVE:
-    case MULTIPLICATIVE:
-      return true;
-    default:
-      return false;
-  }
-}
-
-// Precedence levels
-const int EXPRESSION = 1;
-const int CONDITIONAL = 2;
-const int LOGICAL_OR = 3;
-const int LOGICAL_AND = 4;
-const int EQUALITY = 6;
-const int RELATIONAL = 7;
-const int BITWISE_OR = 8;
-const int BITWISE_XOR = 9;
-const int BITWISE_AND = 10;
-const int SHIFT = 11;
-const int ADDITIVE = 12;
-const int MULTIPLICATIVE = 13;
-const int UNARY = 14;
-const int POSTFIX_INCREMENT = 15;
-const int TYPE_LITERAL = 19;
-const int PRIMARY = 20;
-
-/// Precedence level required for the callee in a [FunctionCall].
-const int CALLEE = 21;
-
-const Map<String, int> BINARY_PRECEDENCE = const {
-  '&&': LOGICAL_AND,
-  '||': LOGICAL_OR,
-  '==': EQUALITY,
-  '!=': EQUALITY,
-  '>': RELATIONAL,
-  '>=': RELATIONAL,
-  '<': RELATIONAL,
-  '<=': RELATIONAL,
-  '|': BITWISE_OR,
-  '^': BITWISE_XOR,
-  '&': BITWISE_AND,
-  '>>': SHIFT,
-  '<<': SHIFT,
-  '+': ADDITIVE,
-  '-': ADDITIVE,
-  '*': MULTIPLICATIVE,
-  '%': MULTIPLICATIVE,
-  '/': MULTIPLICATIVE,
-  '~/': MULTIPLICATIVE,
-};
-
-/// Return true if binary operators with the given precedence level are
-/// (left) associative. False if they are non-associative.
-bool isAssociativeBinaryOperator(int precedence) {
-  return precedence != EQUALITY && precedence != RELATIONAL;
-}
-
-/// True if [x] is a letter, digit, or underscore.
-/// Such characters may not follow a shorthand string interpolation.
-bool isIdentifierPartNoDollar(dynamic x) {
-  if (x is! int) {
-    return false;
-  }
-  return (characters.$0 <= x && x <= characters.$9) ||
-      (characters.$A <= x && x <= characters.$Z) ||
-      (characters.$a <= x && x <= characters.$z) ||
-      (x == characters.$_);
-}
-
-/// The unparser will apply the following syntactic rewritings:
-///   Use short-hand function returns:
-///     foo(){return E} ==> foo() => E;
-///   Remove empty else branch:
-///     if (E) S else ; ==> if (E) S
-///   Flatten nested blocks:
-///     {S; {S; S}; S} ==> {S; S; S; S}
-///   Remove empty statements from block:
-///     {S; ; S} ==> {S; S}
-///   Unfold singleton blocks:
-///     {S} ==> S
-///   Empty block to empty statement:
-///     {} ==> ;
-///   Introduce not-equals operator:
-///     !(E == E) ==> E != E
-///   Introduce is-not operator:
-///     !(E is T) ==> E is!T
-///
-/// The following transformations will NOT be applied here:
-///   Use implicit this:
-///     this.foo ==> foo              (preconditions too complex for unparser)
-///   Merge adjacent variable definitions:
-///     var x; var y  ==> var x,y;    (hoisting will be done elsewhere)
-///   Merge adjacent labels:
-///     foo: bar: S ==> foobar: S     (scoping is categorically ignored)
-///
-/// The following transformations might be applied here in the future:
-///   Use implicit dynamic types:
-///     dynamic x = E ==> var x = E
-///     <dynamic>[]   ==> []
-class Unparser {
-  StringSink output;
-
-  Unparser(this.output);
-
-  void write(String s) {
-    output.write(s);
-  }
-
-  /// Outputs each element from [items] separated by [separator].
-  /// The actual printing must be performed by the [callback].
-  void writeEach(String separator, Iterable items, void callback(any)) {
-    bool first = true;
-    for (var x in items) {
-      if (first) {
-        first = false;
-      } else {
-        write(separator);
-      }
-      callback(x);
-    }
-  }
-
-  void writeOperator(String operator) {
-    write(" ");
-    write(operator);
-    write(" ");
-  }
-
-  /// Unfolds singleton blocks and returns the inner statement.
-  /// If an empty block is found, the [EmptyStatement] is returned instead.
-  Statement unfoldBlocks(Statement stmt) {
-    while (stmt is Block && stmt.statements.length == 1) {
-      Statement inner = (stmt as Block).statements[0];
-      if (definesVariable(inner)) {
-        return stmt; // Do not unfold block with lexical scope.
-      }
-      stmt = inner;
-    }
-    if (stmt is Block && stmt.statements.length == 0)
-      return new EmptyStatement();
-    return stmt;
-  }
-
-  void writeArgument(Argument arg) {
-    if (arg is NamedArgument) {
-      write(arg.name);
-      write(':');
-      writeExpression(arg.expression);
-    } else {
-      writeExpression(arg);
-    }
-  }
-
-  /// Prints the expression [e].
-  void writeExpression(Expression e) {
-    writeExp(e, EXPRESSION);
-  }
-
-  /// Prints [e] as an expression with precedence of at least [minPrecedence],
-  /// using parentheses if necessary to raise the precedence level.
-  /// Abusing terminology slightly, the function accepts a [Receiver] which
-  /// may also be the [SuperReceiver] object.
-  void writeExp(Receiver e, int minPrecedence, {beginStmt: false}) {
-    void withPrecedence(int actual, void action()) {
-      if (actual < minPrecedence) {
-        write("(");
-        beginStmt = false;
-        action();
-        write(")");
-      } else {
-        action();
-      }
-    }
-    if (e is SuperReceiver) {
-      write('super');
-    } else if (e is FunctionExpression) {
-      assert(!e.isGetter && !e.isSetter);
-      Statement stmt = unfoldBlocks(e.body);
-      int precedence = stmt is Return ? EXPRESSION : PRIMARY;
-      withPrecedence(precedence, () {
-        // A named function expression at the beginning of a statement
-        // can be mistaken for a function declaration.
-        // (Note: Functions with a return type also have a name)
-        bool needParen = beginStmt && e.name != null;
-        if (needParen) {
-          write('(');
-        }
-        if (e.returnType != null) {
-          writeType(e.returnType);
-          write(' ');
-        }
-        if (e.name != null) {
-          write(e.name);
-        }
-        writeParameters(e.parameters);
-        if (stmt is Return) {
-          write('=> ');
-          writeExp(stmt.expression, EXPRESSION);
-        } else {
-          writeBlock(stmt);
-        }
-        if (needParen) {
-          write(')');
-        }
-      });
-    } else if (e is Conditional) {
-      withPrecedence(CONDITIONAL, () {
-        writeExp(e.condition, LOGICAL_OR, beginStmt: beginStmt);
-        write(' ? ');
-        writeExp(e.thenExpression, EXPRESSION);
-        write(' : ');
-        writeExp(e.elseExpression, EXPRESSION);
-      });
-    } else if (e is Identifier) {
-      write(e.name);
-    } else if (e is Literal) {
-      if (e.value.isString) {
-        writeStringLiteral(e);
-      } else if (e.value.isDouble) {
-        double v = e.value.primitiveValue;
-        if (v == double.INFINITY) {
-          withPrecedence(MULTIPLICATIVE, () {
-            write('1/0.0');
-          });
-        } else if (v == double.NEGATIVE_INFINITY) {
-          withPrecedence(MULTIPLICATIVE, () {
-            write('-1/0.0');
-          });
-        } else if (v.isNaN) {
-          withPrecedence(MULTIPLICATIVE, () {
-            write('0/0.0');
-          });
-        } else {
-          write(v.toString());
-        }
-      } else {
-        write(e.value.toDartText());
-      }
-    } else if (e is LiteralList) {
-      if (e.isConst) {
-        write(' const ');
-      }
-      if (e.typeArgument != null) {
-        write('<');
-        writeType(e.typeArgument);
-        write('>');
-      }
-      write('[');
-      writeEach(',', e.values, writeExpression);
-      write(']');
-    } else if (e is LiteralMap) {
-      // The curly brace can be mistaken for a block statement if we
-      // are at the beginning of a statement.
-      bool needParen = beginStmt;
-      if (e.isConst) {
-        write(' const ');
-        needParen = false;
-      }
-      if (e.typeArguments.length > 0) {
-        write('<');
-        writeEach(',', e.typeArguments, writeType);
-        write('>');
-        needParen = false;
-      }
-      if (needParen) {
-        write('(');
-      }
-      write('{');
-      writeEach(',', e.entries, (LiteralMapEntry en) {
-        writeExp(en.key, EXPRESSION);
-        write(' : ');
-        writeExp(en.value, EXPRESSION);
-      });
-      write('}');
-      if (needParen) {
-        write(')');
-      }
-    } else if (e is LiteralSymbol) {
-      write('#');
-      write(e.id);
-    } else if (e is LiteralType) {
-      withPrecedence(TYPE_LITERAL, () {
-        write(e.name);
-      });
-    } else if (e is ReifyTypeVar) {
-      withPrecedence(PRIMARY, () {
-        write(e.name);
-      });
-    } else if (e is StringConcat) {
-      writeStringLiteral(e);
-    } else if (e is UnaryOperator) {
-      Receiver operand = e.operand;
-      // !(x == y) ==> x != y.
-      if (e.operatorName == '!' &&
-          operand is BinaryOperator &&
-          operand.operator == '==') {
-        withPrecedence(EQUALITY, () {
-          writeExp(operand.left, RELATIONAL);
-          writeOperator('!=');
-          writeExp(operand.right, RELATIONAL);
-        });
-      }
-      // !(x is T) ==> x is!T
-      else if (e.operatorName == '!' &&
-          operand is TypeOperator &&
-          operand.operator == 'is') {
-        withPrecedence(RELATIONAL, () {
-          writeExp(operand.expression, BITWISE_OR, beginStmt: beginStmt);
-          write(' is!');
-          writeType(operand.type);
-        });
-      } else {
-        withPrecedence(UNARY, () {
-          writeOperator(e.operatorName);
-          writeExp(e.operand, UNARY);
-        });
-      }
-    } else if (e is BinaryOperator) {
-      int precedence = BINARY_PRECEDENCE[e.operator];
-      withPrecedence(precedence, () {
-        // All binary operators are left-associative or non-associative.
-        // For each operand, we use either the same precedence level as
-        // the current operator, or one higher.
-        int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1;
-        writeExp(e.left, precedence + deltaLeft, beginStmt: beginStmt);
-        writeOperator(e.operator);
-        writeExp(e.right, precedence + 1);
-      });
-    } else if (e is TypeOperator) {
-      withPrecedence(RELATIONAL, () {
-        writeExp(e.expression, BITWISE_OR, beginStmt: beginStmt);
-        write(' ');
-        write(e.operator);
-        write(' ');
-        writeType(e.type);
-      });
-    } else if (e is Assignment) {
-      withPrecedence(EXPRESSION, () {
-        writeExp(e.left, PRIMARY, beginStmt: beginStmt);
-        writeOperator(e.operator);
-        writeExp(e.right, EXPRESSION);
-      });
-    } else if (e is FieldExpression) {
-      withPrecedence(PRIMARY, () {
-        writeExp(e.object, PRIMARY, beginStmt: beginStmt);
-        write('.');
-        write(e.fieldName);
-      });
-    } else if (e is IndexExpression) {
-      withPrecedence(CALLEE, () {
-        writeExp(e.object, PRIMARY, beginStmt: beginStmt);
-        write('[');
-        writeExp(e.index, EXPRESSION);
-        write(']');
-      });
-    } else if (e is CallFunction) {
-      withPrecedence(CALLEE, () {
-        writeExp(e.callee, CALLEE, beginStmt: beginStmt);
-        write('(');
-        writeEach(',', e.arguments, writeArgument);
-        write(')');
-      });
-    } else if (e is CallMethod) {
-      withPrecedence(CALLEE, () {
-        writeExp(e.object, PRIMARY, beginStmt: beginStmt);
-        write('.');
-        write(e.methodName);
-        write('(');
-        writeEach(',', e.arguments, writeArgument);
-        write(')');
-      });
-    } else if (e is CallNew) {
-      withPrecedence(CALLEE, () {
-        write(' ');
-        write(e.isConst ? 'const ' : 'new ');
-        writeType(e.type);
-        if (e.constructorName != null) {
-          write('.');
-          write(e.constructorName);
-        }
-        write('(');
-        writeEach(',', e.arguments, writeArgument);
-        write(')');
-      });
-    } else if (e is CallStatic) {
-      withPrecedence(CALLEE, () {
-        write(e.className);
-        write('.');
-        write(e.methodName);
-        write('(');
-        writeEach(',', e.arguments, writeArgument);
-        write(')');
-      });
-    } else if (e is Increment) {
-      int precedence = e.isPrefix ? UNARY : POSTFIX_INCREMENT;
-      withPrecedence(precedence, () {
-        if (e.isPrefix) {
-          write(e.operator);
-          writeExp(e.expression, PRIMARY);
-        } else {
-          writeExp(e.expression, PRIMARY, beginStmt: beginStmt);
-          write(e.operator);
-        }
-      });
-    } else if (e is Throw) {
-      withPrecedence(EXPRESSION, () {
-        write('throw ');
-        writeExp(e.expression, EXPRESSION);
-      });
-    } else if (e is This) {
-      write('this');
-    } else {
-      throw "Unexpected expression: $e";
-    }
-  }
-
-  void writeParameters(Parameters params) {
-    write('(');
-    writeEach(',', params.requiredParameters, (Parameter p) {
-      if (p.type != null) {
-        writeType(p.type);
-        write(' ');
-      }
-      write(p.name);
-      if (p.parameters != null) {
-        writeParameters(p.parameters);
-      }
-    });
-    if (params.hasOptionalParameters) {
-      if (params.requiredParameters.length > 0) {
-        write(',');
-      }
-      write(params.hasNamedParameters ? '{' : '[');
-      writeEach(',', params.optionalParameters, (Parameter p) {
-        if (p.type != null) {
-          writeType(p.type);
-          write(' ');
-        }
-        write(p.name);
-        if (p.parameters != null) {
-          writeParameters(p.parameters);
-        }
-        if (p.defaultValue != null) {
-          write(params.hasNamedParameters ? ':' : '=');
-          writeExp(p.defaultValue, EXPRESSION);
-        }
-      });
-      write(params.hasNamedParameters ? '}' : ']');
-    }
-    write(')');
-  }
-
-  void writeStatement(Statement stmt, {bool shortIf: true}) {
-    stmt = unfoldBlocks(stmt);
-    if (stmt is Block) {
-      write('{');
-      stmt.statements.forEach(writeBlockMember);
-      write('}');
-    } else if (stmt is Break) {
-      write('break');
-      if (stmt.label != null) {
-        write(' ');
-        write(stmt.label);
-      }
-      write(';');
-    } else if (stmt is Continue) {
-      write('continue');
-      if (stmt.label != null) {
-        write(' ');
-        write(stmt.label);
-      }
-      write(';');
-    } else if (stmt is EmptyStatement) {
-      write(';');
-    } else if (stmt is ExpressionStatement) {
-      writeExp(stmt.expression, EXPRESSION, beginStmt: true);
-      write(';');
-    } else if (stmt is For) {
-      write('for(');
-      Node init = stmt.initializer;
-      if (init is Expression) {
-        writeExp(init, EXPRESSION);
-      } else if (init is VariableDeclarations) {
-        writeVariableDefinitions(init);
-      }
-      write(';');
-      if (stmt.condition != null) {
-        writeExp(stmt.condition, EXPRESSION);
-      }
-      write(';');
-      writeEach(',', stmt.updates, writeExpression);
-      write(')');
-      writeStatement(stmt.body, shortIf: shortIf);
-    } else if (stmt is ForIn) {
-      write('for(');
-      Node lhv = stmt.leftHandValue;
-      if (lhv is Identifier) {
-        write(lhv.name);
-      } else {
-        writeVariableDefinitions(lhv as VariableDeclarations);
-      }
-      write(' in ');
-      writeExp(stmt.expression, EXPRESSION);
-      write(')');
-      writeStatement(stmt.body, shortIf: shortIf);
-    } else if (stmt is While) {
-      write('while(');
-      writeExp(stmt.condition, EXPRESSION);
-      write(')');
-      writeStatement(stmt.body, shortIf: shortIf);
-    } else if (stmt is DoWhile) {
-      write('do ');
-      writeStatement(stmt.body);
-      write('while(');
-      writeExp(stmt.condition, EXPRESSION);
-      write(');');
-    } else if (stmt is If) {
-      // if (E) S else ; ==> if (E) S
-      Statement elsePart = unfoldBlocks(stmt.elseStatement);
-      if (elsePart is EmptyStatement) {
-        elsePart = null;
-      }
-      if (!shortIf && elsePart == null) {
-        write('{');
-      }
-      write('if(');
-      writeExp(stmt.condition, EXPRESSION);
-      write(')');
-      writeStatement(stmt.thenStatement, shortIf: elsePart == null);
-      if (elsePart != null) {
-        write('else ');
-        writeStatement(elsePart, shortIf: shortIf);
-      }
-      if (!shortIf && elsePart == null) {
-        write('}');
-      }
-    } else if (stmt is LabeledStatement) {
-      write(stmt.label);
-      write(':');
-      writeStatement(stmt.statement, shortIf: shortIf);
-    } else if (stmt is Rethrow) {
-      write('rethrow;');
-    } else if (stmt is Return) {
-      write('return');
-      if (stmt.expression != null) {
-        write(' ');
-        writeExp(stmt.expression, EXPRESSION);
-      }
-      write(';');
-    } else if (stmt is Switch) {
-      write('switch(');
-      writeExp(stmt.expression, EXPRESSION);
-      write('){');
-      for (SwitchCase caze in stmt.cases) {
-        if (caze.isDefaultCase) {
-          write('default:');
-        } else {
-          for (Expression exp in caze.expressions) {
-            write('case ');
-            writeExp(exp, EXPRESSION);
-            write(':');
-          }
-        }
-        if (caze.statements.isEmpty) {
-          write(';'); // Prevent fall-through.
-        } else {
-          caze.statements.forEach(writeBlockMember);
-        }
-      }
-      write('}');
-    } else if (stmt is Try) {
-      write('try');
-      writeBlock(stmt.tryBlock);
-      for (CatchBlock block in stmt.catchBlocks) {
-        if (block.onType != null) {
-          write('on ');
-          writeType(block.onType);
-        }
-        if (block.exceptionVar != null) {
-          write('catch(');
-          write(block.exceptionVar.name);
-          if (block.stackVar != null) {
-            write(',');
-            write(block.stackVar.name);
-          }
-          write(')');
-        }
-        writeBlock(block.body);
-      }
-      if (stmt.finallyBlock != null) {
-        write('finally');
-        writeBlock(stmt.finallyBlock);
-      }
-    } else if (stmt is VariableDeclarations) {
-      writeVariableDefinitions(stmt);
-      write(';');
-    } else if (stmt is FunctionDeclaration) {
-      assert(!stmt.function.isGetter && !stmt.function.isSetter);
-      if (stmt.returnType != null) {
-        writeType(stmt.returnType);
-        write(' ');
-      }
-      write(stmt.name);
-      writeParameters(stmt.parameters);
-      Statement body = unfoldBlocks(stmt.body);
-      if (body is Return) {
-        write('=> ');
-        writeExp(body.expression, EXPRESSION);
-        write(';');
-      } else {
-        writeBlock(body);
-      }
-    } else {
-      throw "Unexpected statement: $stmt";
-    }
-  }
-
-  /// Writes a variable definition statement without the trailing semicolon
-  void writeVariableDefinitions(VariableDeclarations vds) {
-    if (vds.isConst)
-      write('const ');
-    else if (vds.isFinal) write('final ');
-    if (vds.type != null) {
-      writeType(vds.type);
-      write(' ');
-    }
-    if (!vds.isConst && !vds.isFinal && vds.type == null) {
-      write('var ');
-    }
-    writeEach(',', vds.declarations, (VariableDeclaration vd) {
-      write(vd.name);
-      if (vd.initializer != null) {
-        write('=');
-        writeExp(vd.initializer, EXPRESSION);
-      }
-    });
-  }
-
-  /// True of statements that introduce variables in the scope of their
-  /// surrounding block. Blocks containing such statements cannot be unfolded.
-  static bool definesVariable(Statement s) {
-    return s is VariableDeclarations || s is FunctionDeclaration;
-  }
-
-  /// Writes the given statement in a context where only blocks are allowed.
-  void writeBlock(Statement stmt) {
-    if (stmt is Block) {
-      writeStatement(stmt);
-    } else {
-      write('{');
-      writeBlockMember(stmt);
-      write('}');
-    }
-  }
-
-  /// Outputs a statement that is a member of a block statement (or a similar
-  /// sequence of statements, such as in switch statement).
-  /// This will flatten blocks and skip empty statement.
-  void writeBlockMember(Statement stmt) {
-    if (stmt is Block && !stmt.statements.any(definesVariable)) {
-      stmt.statements.forEach(writeBlockMember);
-    } else if (stmt is EmptyStatement) {
-      // do nothing
-    } else {
-      writeStatement(stmt);
-    }
-  }
-
-  void writeType(TypeAnnotation type) {
-    write(type.name);
-    if (type.typeArguments != null && type.typeArguments.length > 0) {
-      write('<');
-      writeEach(',', type.typeArguments, writeType);
-      write('>');
-    }
-  }
-
-  /// A list of string quotings that the printer may use to quote strings.
-  // Ignore multiline quotings for now. Would need to make sure that no
-  // newline (potentially prefixed by whitespace) follows the quoting.
-  static const _QUOTINGS = const <tree.StringQuoting>[
-    const tree.StringQuoting(characters.$DQ, raw: false, leftQuoteLength: 1),
-    const tree.StringQuoting(characters.$DQ, raw: true, leftQuoteLength: 1),
-    const tree.StringQuoting(characters.$SQ, raw: false, leftQuoteLength: 1),
-    const tree.StringQuoting(characters.$SQ, raw: true, leftQuoteLength: 1),
-  ];
-
-  static StringLiteralOutput analyzeStringLiteral(Expression node) {
-    // Flatten the StringConcat tree.
-    List parts = []; // Expression or int (char node)
-    void collectParts(Expression e) {
-      if (e is StringConcat) {
-        e.expressions.forEach(collectParts);
-      } else if (e is Literal && e.value.isString) {
-        for (int char in e.value.primitiveValue) {
-          parts.add(char);
-        }
-      } else {
-        parts.add(e);
-      }
-    }
-    collectParts(node);
-
-    // We use a dynamic algorithm to compute the optimal way of printing
-    // the string literal.
-    //
-    // Using string juxtapositions, it is possible to switch from one quoting
-    // to another, e.g. the constant "''''" '""""' uses this trick.
-    //
-    // As we move through the string from left to right, we maintain a strategy
-    // for each StringQuoting Q, denoting the best way to print the current
-    // prefix so that we end with a string literal quoted with Q.
-    // At every step, each strategy is either:
-    //  1) Updated to include the cost of printing the next character.
-    //  2) Abandoned because it is cheaper to use another strategy as prefix,
-    //     and then switching quotation using a juxtaposition.
-
-    int getQuoteCost(tree.StringQuoting quot) {
-      return quot.leftQuoteLength + quot.rightQuoteLength;
-    }
-
-    // Create initial scores for each StringQuoting and index them
-    // into raw/non-raw and single-quote/double-quote.
-    List<OpenStringChunk> best = <OpenStringChunk>[];
-    List<int> raws = <int>[];
-    List<int> nonRaws = <int>[];
-    List<int> sqs = <int>[];
-    List<int> dqs = <int>[];
-    for (tree.StringQuoting q in _QUOTINGS) {
-      OpenStringChunk chunk = new OpenStringChunk(null, q, getQuoteCost(q));
-      int index = best.length;
-      best.add(chunk);
-
-      if (q.raw) {
-        raws.add(index);
-      } else {
-        nonRaws.add(index);
-      }
-      if (q.quote == characters.$SQ) {
-        sqs.add(index);
-      } else {
-        dqs.add(index);
-      }
-    }
-
-    /// Applies additional cost to each track in [penalized], and considers
-    /// switching from each [penalized] to a [nonPenalized] track.
-    void penalize(List<int> penalized, List<int> nonPenalized, int endIndex,
-        num cost(tree.StringQuoting q)) {
-      for (int j in penalized) {
-        // Check if another track can benefit from switching from this track.
-        for (int k in nonPenalized) {
-          num newCost = best[j].cost +
-              1 // Whitespace in string juxtaposition
-              +
-              getQuoteCost(best[k].quoting);
-          if (newCost < best[k].cost) {
-            best[k] = new OpenStringChunk(
-                best[j].end(endIndex), best[k].quoting, newCost);
-          }
-        }
-        best[j].cost += cost(best[j].quoting);
-      }
-    }
-
-    // Iterate through the string and update the score for each StringQuoting.
-    for (int i = 0; i < parts.length; i++) {
-      var part = parts[i];
-      if (part is int) {
-        int char = part;
-        switch (char) {
-          case characters.$$:
-          case characters.$BACKSLASH:
-            penalize(nonRaws, raws, i, (q) => 1);
-            break;
-          case characters.$DQ:
-            penalize(dqs, sqs, i, (q) => q.raw ? double.INFINITY : 1);
-            break;
-          case characters.$SQ:
-            penalize(sqs, dqs, i, (q) => q.raw ? double.INFINITY : 1);
-            break;
-          case characters.$LF:
-          case characters.$CR:
-          case characters.$FF:
-          case characters.$BS:
-          case characters.$VTAB:
-          case characters.$TAB:
-          case characters.$EOF:
-            penalize(raws, nonRaws, i, (q) => double.INFINITY);
-            break;
-        }
-      } else {
-        // Penalize raw literals for string interpolation.
-        penalize(raws, nonRaws, i, (q) => double.INFINITY);
-
-        // Splitting a string can sometimes allow us to use a shorthand
-        // string interpolation that would otherwise be illegal.
-        // E.g. "...${foo}x..." -> "...$foo" 'x...'
-        // If are other factors that make splitting advantageous,
-        // we can gain even more by doing the split here.
-        if (part is Identifier &&
-            !part.name.contains(r'$') &&
-            i + 1 < parts.length &&
-            isIdentifierPartNoDollar(parts[i + 1])) {
-          for (int j in nonRaws) {
-            for (int k = 0; k < best.length; k++) {
-              num newCost = best[j].cost +
-                  1 // Whitespace in string juxtaposition
-                  -
-                  2 // Save two curly braces
-                  +
-                  getQuoteCost(best[k].quoting);
-              if (newCost < best[k].cost) {
-                best[k] = new OpenStringChunk(
-                    best[j].end(i + 1), best[k].quoting, newCost);
-              }
-            }
-          }
-        }
-      }
-    }
-
-    // Select the cheapest strategy
-    OpenStringChunk bestChunk = best[0];
-    for (OpenStringChunk chunk in best) {
-      if (chunk.cost < bestChunk.cost) {
-        bestChunk = chunk;
-      }
-    }
-
-    return new StringLiteralOutput(parts, bestChunk.end(parts.length));
-  }
-
-  void writeStringLiteral(Expression node) {
-    StringLiteralOutput output = analyzeStringLiteral(node);
-    List parts = output.parts;
-    void printChunk(StringChunk chunk) {
-      int startIndex;
-      if (chunk.previous != null) {
-        printChunk(chunk.previous);
-        write(' '); // String juxtaposition requires a space between literals.
-        startIndex = chunk.previous.endIndex;
-      } else {
-        startIndex = 0;
-      }
-      if (chunk.quoting.raw) {
-        write('r');
-      }
-      write(chunk.quoting.quoteChar);
-      bool raw = chunk.quoting.raw;
-      int quoteCode = chunk.quoting.quote;
-      for (int i = startIndex; i < chunk.endIndex; i++) {
-        var part = parts[i];
-        if (part is int) {
-          int char = part;
-          write(getEscapedCharacter(char, quoteCode, raw));
-        } else if (part is Identifier &&
-            !part.name.contains(r'$') &&
-            (i == chunk.endIndex - 1 ||
-                !isIdentifierPartNoDollar(parts[i + 1]))) {
-          write(r'$');
-          write(part.name);
-        } else {
-          write(r'${');
-          writeExpression(part);
-          write('}');
-        }
-      }
-      write(chunk.quoting.quoteChar);
-    }
-    printChunk(output.chunk);
-  }
-
-  static String getEscapedCharacter(int char, int quoteCode, bool raw) {
-    switch (char) {
-      case characters.$$:
-        return raw ? r'$' : r'\$';
-      case characters.$BACKSLASH:
-        return raw ? r'\' : r'\\';
-      case characters.$DQ:
-        return quoteCode == char ? r'\"' : r'"';
-      case characters.$SQ:
-        return quoteCode == char ? r"\'" : r"'";
-      case characters.$LF:
-        return r'\n';
-      case characters.$CR:
-        return r'\r';
-      case characters.$FF:
-        return r'\f';
-      case characters.$BS:
-        return r'\b';
-      case characters.$TAB:
-        return r'\t';
-      case characters.$VTAB:
-        return r'\v';
-      case characters.$EOF:
-        return r'\x00';
-      default:
-        return new String.fromCharCode(char);
-    }
-  }
-}
-
-/// The contents of a string literal together with a strategy for printing it.
-class StringLiteralOutput {
-  /// Mix of [Expression] and `int`. Each expression is a string interpolation,
-  /// and each `int` is the character code of a character in a string literal.
-  final List parts;
-  final StringChunk chunk;
-
-  StringLiteralOutput(this.parts, this.chunk);
-}
-
-/// Strategy for printing a prefix of a string literal.
-/// A chunk represents the substring going from [:previous.endIndex:] to
-/// [endIndex] (or from 0 to [endIndex] if [previous] is null).
-class StringChunk {
-  final StringChunk previous;
-  final tree.StringQuoting quoting;
-  final int endIndex;
-
-  StringChunk(this.previous, this.quoting, this.endIndex);
-}
-
-/// [StringChunk] that has not yet been assigned an [endIndex].
-/// It additionally has a [cost] denoting the number of auxilliary characters
-/// (quotes, spaces, etc) needed to print the literal using this strategy
-class OpenStringChunk {
-  final StringChunk previous;
-  final tree.StringQuoting quoting;
-  num cost;
-
-  OpenStringChunk(this.previous, this.quoting, this.cost);
-
-  StringChunk end(int endIndex) {
-    return new StringChunk(previous, quoting, endIndex);
-  }
-}
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
deleted file mode 100644
index 469858d..0000000
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
+++ /dev/null
@@ -1,1353 +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 dart_tree_printer;
-
-import '../common.dart';
-import '../constants/values.dart' as values;
-import '../dart_types.dart' as types;
-import '../elements/elements.dart' as elements;
-import '../resolution/tree_elements.dart' show TreeElementMapping;
-import '../tokens/token.dart';
-import '../tokens/token_constants.dart';
-import '../tokens/precedence.dart';
-import '../tokens/precedence_constants.dart';
-import '../tree/tree.dart' as tree;
-import '../util/util.dart';
-import 'backend_ast_nodes.dart';
-import 'backend_ast_emitter.dart' show TypeGenerator;
-
-/// Translates the backend AST to Dart frontend AST.
-tree.Node emit(TreeElementMapping treeElements, RootNode root) {
-  return new TreePrinter(treeElements).makeDefinition(root);
-}
-
-/// If true, the unparser will insert a coment in front of every function
-/// it emits. This helps indicate which functions were translated by the new
-/// backend.
-bool INSERT_NEW_BACKEND_COMMENT =
-    const bool.fromEnvironment("INSERT_NEW_BACKEND_COMMENT");
-
-/// Converts backend ASTs to frontend ASTs.
-class TreePrinter {
-  TreeElementMapping treeElements;
-
-  TreePrinter([this.treeElements]);
-
-  tree.Node makeDefinition(RootNode node) {
-    if (node is FieldDefinition) {
-      tree.Node definition;
-      if (node.initializer == null) {
-        definition = makeIdentifier(node.element.name);
-      } else {
-        definition = new tree.SendSet(
-            null,
-            makeIdentifier(node.element.name),
-            new tree.Operator(assignmentToken("=")),
-            singleton(makeExpression(node.initializer)));
-      }
-      setElement(definition, node.element, node);
-      return new tree.VariableDefinitions(
-          null, // TODO(sigurdm): Type
-          makeVarModifiers(
-              useVar: true,
-              isFinal: node.element.isFinal,
-              isStatic: node.element.isStatic,
-              isConst: node.element.isConst),
-          makeList(null, [definition], close: semicolon));
-    } else if (node is FunctionExpression) {
-      return makeExpression(node);
-    } else {
-      assert(false);
-      return null;
-    }
-  }
-
-  void setElement(tree.Node node, elements.Element element, source) {
-    if (treeElements != null) {
-      if (element == null) {
-        throw "Missing element from ${source}";
-      }
-      treeElements[node] = element;
-    }
-  }
-
-  void setType(tree.Node node, types.DartType type, source) {
-    if (treeElements != null) {
-      if (type == null) {
-        throw "Missing type from ${source}";
-      }
-      treeElements.setType(node, type);
-    }
-  }
-
-  // Group tokens: () [] {} <>
-  static BeginGroupToken makeGroup(PrecedenceInfo open, PrecedenceInfo close) {
-    BeginGroupToken openTok = new BeginGroupToken(open, -1);
-    openTok.endGroup = new SymbolToken(close, -1);
-    return openTok;
-  }
-
-  final BeginGroupToken openParen =
-      makeGroup(OPEN_PAREN_INFO, CLOSE_PAREN_INFO);
-  final BeginGroupToken openBrace =
-      makeGroup(OPEN_CURLY_BRACKET_INFO, CLOSE_CURLY_BRACKET_INFO);
-  final BeginGroupToken openBracket =
-      makeGroup(OPEN_SQUARE_BRACKET_INFO, CLOSE_SQUARE_BRACKET_INFO);
-  final BeginGroupToken lt = makeGroup(LT_INFO, GT_INFO);
-
-  Token get closeParen => openParen.endGroup;
-  Token get closeBrace => openBrace.endGroup;
-  Token get closeBracket => openBracket.endGroup;
-  Token get gt => lt.endGroup;
-
-  // Symbol tokens
-  final Token semicolon = new SymbolToken(SEMICOLON_INFO, -1);
-  final Token indexToken = new SymbolToken(INDEX_INFO, -1); // "[]"
-  final Token question = new SymbolToken(QUESTION_INFO, -1);
-  final Token colon = new SymbolToken(COLON_INFO, -1);
-  final Token hash = new SymbolToken(HASH_INFO, -1);
-  final Token bang = new SymbolToken(BANG_INFO, -1);
-  final Token eq = new SymbolToken(EQ_INFO, -1);
-
-  // Keyword tokens
-  static Token makeIdToken(String text) {
-    return new StringToken.fromString(IDENTIFIER_INFO, text, -1);
-  }
-
-  final Token newToken = makeIdToken('new');
-  final Token constToken = makeIdToken('const');
-  final Token throwToken = makeIdToken('throw');
-  final Token rethrowToken = makeIdToken('rethrow');
-  final Token breakToken = makeIdToken('break');
-  final Token continueToken = makeIdToken('continue');
-  final Token doToken = makeIdToken('do');
-  final Token whileToken = makeIdToken('while');
-  final Token ifToken = makeIdToken('if');
-  final Token elseToken = makeIdToken('else');
-  final Token awaitToken = makeIdToken('await');
-  final Token forToken = makeIdToken('for');
-  final Token inToken = makeIdToken('in');
-  final Token returnToken = makeIdToken('return');
-  final Token switchToken = makeIdToken('switch');
-  final Token caseToken = makeIdToken('case');
-  final Token defaultToken = makeIdToken('default');
-  final Token tryToken = makeIdToken('try');
-  final Token catchToken = makeIdToken('catch');
-  final Token onToken = makeIdToken('on');
-  final Token finallyToken = makeIdToken('finally');
-  final Token getToken = makeIdToken('get');
-  final Token setToken = makeIdToken('set');
-  final Token classToken = makeIdToken('class');
-  final Token extendsToken = makeIdToken('extends');
-  final Token withToken = makeIdToken('with');
-  final Token implementsToken = makeIdToken('implements');
-  final Token typedefToken = makeIdToken('typedef');
-  final Token enumToken = makeIdToken('enum');
-
-  static tree.Identifier makeIdentifier(String name) {
-    return new tree.Identifier(
-        new StringToken.fromString(IDENTIFIER_INFO, name, -1));
-  }
-
-  static tree.Operator makeOperator(String name) {
-    return new tree.Operator(
-        new StringToken.fromString(IDENTIFIER_INFO, name, -1));
-  }
-
-  // Utilities for creating NodeLists
-  Link<tree.Node> makeLink(Iterable<tree.Node> nodes) {
-    LinkBuilder builder = new LinkBuilder();
-    for (tree.Node node in nodes) {
-      builder.addLast(node);
-    }
-    return builder.toLink();
-  }
-
-  tree.NodeList blankList() {
-    return new tree.NodeList(null, makeLink([]), null, '');
-  }
-
-  tree.NodeList singleton(tree.Node node) {
-    return new tree.NodeList(null, makeLink([node]), null, '');
-  }
-
-  tree.NodeList makeList(String delimiter, Iterable<tree.Node> nodes,
-      {Token open, Token close}) {
-    return new tree.NodeList(open, makeLink(nodes), close, delimiter);
-  }
-
-  tree.NodeList parenList(String delimiter, Iterable<tree.Node> nodes) {
-    return makeList(delimiter, nodes, open: openParen, close: closeParen);
-  }
-
-  tree.NodeList bracketList(String delimiter, Iterable<tree.Node> nodes) {
-    return makeList(delimiter, nodes, open: openBracket, close: closeBracket);
-  }
-
-  tree.NodeList braceList(String delimiter, Iterable<tree.Node> nodes) {
-    return makeList(delimiter, nodes, open: openBrace, close: closeBrace);
-  }
-
-  tree.NodeList argList(Iterable<tree.Node> nodes) {
-    return parenList(',', nodes);
-  }
-
-  tree.NodeList typeArgList(Iterable<tree.Node> nodes) {
-    return makeList(',', nodes, open: lt, close: gt);
-  }
-
-  /// Converts a qualified name into nested Sends.
-  tree.Node makeName(String name) {
-    if (name == null) {
-      return null;
-    }
-    List<String> names = name.split('.').toList(growable: false);
-    tree.Node node = makeIdentifier(names[0]);
-    for (int i = 1; i < names.length; i++) {
-      node = new tree.Send(node, makeIdentifier(names[i]));
-    }
-    return node;
-  }
-
-  static Token assignmentToken(String operatorName) {
-    switch (operatorName) {
-      case '=':
-        return new SymbolToken(EQ_INFO, -1);
-      case '+=':
-        return new SymbolToken(PLUS_EQ_INFO, -1);
-      case '-=':
-        return new SymbolToken(MINUS_EQ_INFO, -1);
-      case '*=':
-        return new SymbolToken(STAR_EQ_INFO, -1);
-      case '/=':
-        return new SymbolToken(SLASH_EQ_INFO, -1);
-      case '~/=':
-        return new SymbolToken(TILDE_SLASH_EQ_INFO, -1);
-      case '%=':
-        return new SymbolToken(PERCENT_EQ_INFO, -1);
-      case '&=':
-        return new SymbolToken(AMPERSAND_EQ_INFO, -1);
-      case '^=':
-        return new SymbolToken(CARET_EQ_INFO, -1);
-      case '|=':
-        return new SymbolToken(BAR_EQ_INFO, -1);
-      case '>>=':
-        return new SymbolToken(GT_GT_EQ_INFO, -1);
-      case '<<=':
-        return new SymbolToken(LT_LT_EQ_INFO, -1);
-      default:
-        throw "Unrecognized assignment operator: $operatorName";
-    }
-  }
-
-  static Token binopToken(String operatorName) {
-    switch (operatorName) {
-      case '+':
-        return new SymbolToken(PLUS_INFO, -1);
-      case '-':
-        return new SymbolToken(MINUS_INFO, -1);
-      case '*':
-        return new SymbolToken(STAR_INFO, -1);
-      case '/':
-        return new SymbolToken(SLASH_INFO, -1);
-      case '~/':
-        return new SymbolToken(TILDE_SLASH_INFO, -1);
-      case '%':
-        return new SymbolToken(PERCENT_INFO, -1);
-      case '&':
-        return new SymbolToken(AMPERSAND_INFO, -1);
-      case '^':
-        return new SymbolToken(CARET_INFO, -1);
-      case '|':
-        return new SymbolToken(BAR_INFO, -1);
-      case '>>':
-        return new SymbolToken(GT_GT_INFO, -1);
-      case '<<':
-        return new SymbolToken(LT_LT_INFO, -1);
-      case '==':
-        return new SymbolToken(EQ_EQ_INFO, -1);
-      case '!=':
-        return new SymbolToken(BANG_EQ_INFO, -1);
-      case '>':
-        return new SymbolToken(GT_INFO, -1);
-      case '>=':
-        return new SymbolToken(GT_EQ_INFO, -1);
-      case '<':
-        return new SymbolToken(LT_INFO, -1);
-      case '<=':
-        return new SymbolToken(LT_EQ_INFO, -1);
-      case '&&':
-        return new SymbolToken(AMPERSAND_AMPERSAND_INFO, -1);
-      case '||':
-        return new SymbolToken(BAR_BAR_INFO, -1);
-      default:
-        throw "Unrecognized binary operator: $operatorName";
-    }
-  }
-
-  static Token incrementToken(String operatorName) {
-    switch (operatorName) {
-      case '++':
-        return new SymbolToken(PLUS_PLUS_INFO, -1);
-      case '--':
-        return new SymbolToken(MINUS_MINUS_INFO, -1);
-      default:
-        throw "Unrecognized increment operator: $operatorName";
-    }
-  }
-
-  static Token typeOpToken(String operatorName) {
-    switch (operatorName) {
-      // "is!" is not an operator in the frontend AST.
-      case 'is':
-        return new SymbolToken(IS_INFO, -1);
-      case 'as':
-        return new SymbolToken(AS_INFO, -1);
-      default:
-        throw 'Unrecognized type operator: $operatorName';
-    }
-  }
-
-  Token unopToken(String operatorName) {
-    switch (operatorName) {
-      case '-':
-        return new SymbolToken(MINUS_INFO, -1);
-      case '~':
-        return new SymbolToken(TILDE_INFO, -1);
-      case '!':
-        return bang;
-      default:
-        throw "Unrecognized unary operator: $operatorName";
-    }
-  }
-
-  tree.Node makeStaticReceiver(elements.Element element) {
-    if (treeElements == null) return null;
-    if (element.isStatic) {
-      elements.ClassElement enclosingClass = element.enclosingClass;
-      tree.Send send = new tree.Send(null, makeIdentifier(enclosingClass.name));
-      treeElements[send] = enclosingClass;
-      return send;
-    } else {
-      return null;
-    }
-  }
-
-  tree.Node makeArgument(Argument arg) {
-    if (arg is Expression) {
-      return makeExpression(arg);
-    } else if (arg is NamedArgument) {
-      return new tree.NamedArgument(
-          makeIdentifier(arg.name), colon, makeExpression(arg.expression));
-    } else {
-      throw "Unrecognized argument type: ${arg}";
-    }
-  }
-
-  tree.Node makeExpression(Expression exp) {
-    return makeExp(exp, EXPRESSION);
-  }
-
-  /// Converts [exp] to a [tree.Node] that unparses to an expression with
-  /// a precedence level of at least [minPrecedence]. The expression will be
-  /// wrapped in a parenthesis if necessary.
-  tree.Node makeExp(Receiver exp, int minPrecedence, {bool beginStmt: false}) {
-    tree.Node result;
-    int precedence;
-    bool needParen = false;
-    if (exp is SuperReceiver) {
-      precedence = CALLEE;
-      result = makeIdentifier('super');
-    } else if (exp is Assignment) {
-      Expression left = exp.left;
-      tree.Node receiver;
-      tree.Node selector;
-      tree.NodeList arguments;
-      elements.Element element;
-      if (left is Identifier) {
-        receiver = makeStaticReceiver(left.element);
-        selector = makeIdentifier(left.name);
-        arguments = singleton(makeExpression(exp.right));
-        element = left.element;
-      } else if (left is FieldExpression) {
-        receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
-        selector = makeIdentifier(left.fieldName);
-        arguments = singleton(makeExpression(exp.right));
-      } else if (left is IndexExpression) {
-        receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
-        selector = new tree.Operator(indexToken);
-        arguments = bracketList(
-            ',', [makeExpression(left.index), makeExpression(exp.right)]);
-      } else {
-        throw "Unexpected left-hand side of assignment: ${left}";
-      }
-      tree.Operator op = new tree.Operator(assignmentToken(exp.operator));
-      result = new tree.SendSet(receiver, selector, op, arguments);
-      if (left is Identifier) {
-        setElement(result, element, exp);
-      }
-      precedence = EXPRESSION;
-    } else if (exp is FieldInitializer) {
-      precedence = EXPRESSION;
-      tree.Node receiver = makeIdentifier('this');
-      tree.Node selector = makeIdentifier(exp.element.name);
-      tree.Operator op = new tree.Operator(assignmentToken("="));
-      // We pass CALLEE to ensure we write eg.:
-      // class B { var x; B() : x = (() {return a;}) {}}
-      // Not the invalid:
-      // class B { var x; B() : x = () {return a;} {}}
-      result = new tree.SendSet(
-          receiver, selector, op, singleton(makeExp(exp.body, CALLEE)));
-      setElement(result, exp.element, exp);
-    } else if (exp is SuperInitializer) {
-      precedence = EXPRESSION;
-      tree.Node receiver = makeIdentifier('super');
-      tree.NodeList arguments =
-          argList(exp.arguments.map(makeArgument).toList());
-      if (exp.target.name == "") {
-        result = new tree.Send(null, receiver, arguments);
-      } else {
-        result =
-            new tree.Send(receiver, makeIdentifier(exp.target.name), arguments);
-      }
-      setElement(result, exp.target, exp);
-    } else if (exp is BinaryOperator) {
-      precedence = BINARY_PRECEDENCE[exp.operator];
-      int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1;
-      result = new tree.Send(
-          makeExp(exp.left, precedence + deltaLeft, beginStmt: beginStmt),
-          new tree.Operator(binopToken(exp.operator)),
-          singleton(makeExp(exp.right, precedence + 1)));
-    } else if (exp is CallFunction) {
-      precedence = CALLEE;
-      tree.Node selector;
-      Expression callee = exp.callee;
-      elements.Element element;
-      tree.Node receiver;
-      if (callee is Identifier) {
-        receiver = makeStaticReceiver(callee.element);
-        selector = makeIdentifier(callee.name);
-        element = callee.element;
-      } else {
-        selector = makeExp(callee, CALLEE, beginStmt: beginStmt);
-      }
-      result = new tree.Send(
-          receiver, selector, argList(exp.arguments.map(makeArgument)));
-      if (callee is Identifier) {
-        setElement(result, element, exp);
-      }
-    } else if (exp is CallMethod) {
-      precedence = CALLEE;
-      // TODO(sra): Elide receiver when This, but only if not in a scope that
-      // shadows the method (e.g. constructor body).
-      tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
-      result = new tree.Send(receiver, makeIdentifier(exp.methodName),
-          argList(exp.arguments.map(makeArgument)));
-    } else if (exp is CallNew) {
-      precedence = CALLEE;
-      tree.Node selector = makeName(exp.type.name);
-      if (exp.type.typeArguments.length > 0) {
-        selector = new tree.TypeAnnotation(
-            selector, typeArgList(exp.type.typeArguments.map(makeType)));
-        setType(selector, exp.dartType, exp);
-      }
-      if (exp.constructorName != null) {
-        selector = new tree.Send(selector, makeIdentifier(exp.constructorName));
-      }
-      tree.Send send = new tree.Send(
-          null, selector, argList(exp.arguments.map(makeArgument)));
-      result =
-          new tree.NewExpression(exp.isConst ? constToken : newToken, send);
-      setType(result, exp.dartType, exp);
-      setElement(send, exp.constructor, exp);
-    } else if (exp is CallStatic) {
-      precedence = CALLEE;
-      result = new tree.Send(
-          makeStaticReceiver(exp.element),
-          makeIdentifier(exp.methodName),
-          argList(exp.arguments.map(makeArgument)));
-      setElement(result, exp.element, exp);
-    } else if (exp is Conditional) {
-      precedence = CONDITIONAL;
-      result = new tree.Conditional(
-          makeExp(exp.condition, LOGICAL_OR, beginStmt: beginStmt),
-          makeExp(exp.thenExpression, EXPRESSION),
-          makeExp(exp.elseExpression, EXPRESSION),
-          question,
-          colon);
-    } else if (exp is FieldExpression) {
-      precedence = PRIMARY;
-      // TODO(sra): Elide receiver when This, but only if not in a scope that
-      // shadows the method (e.g. constructor body).
-      tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
-      result = new tree.Send(receiver, makeIdentifier(exp.fieldName));
-    } else if (exp is ConstructorDefinition) {
-      precedence = EXPRESSION;
-      tree.NodeList parameters = makeParameters(exp.parameters);
-      tree.NodeList initializers =
-          exp.initializers == null || exp.initializers.isEmpty
-              ? null
-              : makeList(",", exp.initializers.map(makeExpression).toList());
-      tree.Node body = exp.isConst || exp.body == null
-          ? new tree.EmptyStatement(semicolon)
-          : makeFunctionBody(exp.body);
-      result = new tree.FunctionExpression(
-          constructorName(exp),
-          // GENERIC_METHODS: In order to support generic methods fully,
-          // we must retrieve and pass the actual type variables here.
-          null, // typeVariables
-          parameters,
-          body,
-          null, // return type
-          makeFunctionModifiers(exp),
-          initializers,
-          null, // get/set
-          null); // async modifier
-      setElement(result, exp.element, exp);
-    } else if (exp is FunctionExpression) {
-      precedence = PRIMARY;
-      if (beginStmt && exp.name != null) {
-        needParen = true; // Do not mistake for function declaration.
-      }
-      Token getOrSet = exp.isGetter ? getToken : exp.isSetter ? setToken : null;
-      tree.NodeList parameters =
-          exp.isGetter ? makeList("", []) : makeParameters(exp.parameters);
-      tree.Node body = makeFunctionBody(exp.body);
-      result = new tree.FunctionExpression(
-          functionName(exp),
-          // GENERIC_METHODS: In order to support generic methods fully,
-          // we must retrieve and pass the actual type variables here.
-          null, // typeVariables
-          parameters,
-          body,
-          exp.returnType == null || exp.element.isConstructor
-              ? null
-              : makeType(exp.returnType),
-          makeFunctionModifiers(exp),
-          null, // initializers
-          getOrSet, // get/set
-          null); // async modifier
-      elements.Element element = exp.element;
-      if (element != null) setElement(result, element, exp);
-    } else if (exp is Identifier) {
-      precedence = CALLEE;
-      result = new tree.Send(
-          makeStaticReceiver(exp.element), makeIdentifier(exp.name));
-      setElement(result, exp.element, exp);
-    } else if (exp is Increment) {
-      Expression lvalue = exp.expression;
-      tree.Node receiver;
-      tree.Node selector;
-      tree.Node argument;
-      bool innerBeginStmt = beginStmt && !exp.isPrefix;
-      if (lvalue is Identifier) {
-        receiver = makeStaticReceiver(lvalue.element);
-        selector = makeIdentifier(lvalue.name);
-      } else if (lvalue is FieldExpression) {
-        receiver = makeExp(lvalue.object, PRIMARY, beginStmt: innerBeginStmt);
-        selector = makeIdentifier(lvalue.fieldName);
-      } else if (lvalue is IndexExpression) {
-        receiver = makeExp(lvalue.object, PRIMARY, beginStmt: innerBeginStmt);
-        selector = new tree.Operator(indexToken);
-        argument = makeExpression(lvalue.index);
-      } else {
-        throw "Unrecognized left-hand side: ${lvalue}";
-      }
-      tree.Operator op = new tree.Operator(incrementToken(exp.operator));
-      if (exp.isPrefix) {
-        precedence = UNARY;
-        result = new tree.SendSet.prefix(receiver, selector, op, argument);
-      } else {
-        precedence = POSTFIX_INCREMENT;
-        result = new tree.SendSet.postfix(receiver, selector, op, argument);
-      }
-      if (lvalue is Identifier) {
-        setElement(result, lvalue.element, exp);
-      }
-    } else if (exp is IndexExpression) {
-      precedence = CALLEE;
-      result = new tree.Send(
-          makeExp(exp.object, PRIMARY, beginStmt: beginStmt),
-          new tree.Operator(indexToken),
-          bracketList(',', [makeExpression(exp.index)]));
-    } else if (exp is Literal) {
-      precedence = CALLEE;
-      values.PrimitiveConstantValue value = exp.value;
-      Token tok = new StringToken.fromString(
-          STRING_INFO, '${value.primitiveValue}', -1);
-      if (value.isString) {
-        result = unparseStringLiteral(exp);
-      } else if (value.isInt) {
-        result = new tree.LiteralInt(tok, null);
-      } else if (value.isDouble) {
-        if (value.primitiveValue == double.INFINITY) {
-          precedence = MULTIPLICATIVE;
-          tok = new StringToken.fromString(STRING_INFO, '1/0.0', -1);
-        } else if (value.primitiveValue == double.NEGATIVE_INFINITY) {
-          precedence = MULTIPLICATIVE;
-          tok = new StringToken.fromString(STRING_INFO, '-1/0.0', -1);
-        } else if (value.primitiveValue.isNaN) {
-          precedence = MULTIPLICATIVE;
-          tok = new StringToken.fromString(STRING_INFO, '0/0.0', -1);
-        }
-        result = new tree.LiteralDouble(tok, null);
-      } else if (value.isBool) {
-        result = new tree.LiteralBool(tok, null);
-      } else if (value.isNull) {
-        result = new tree.LiteralNull(tok);
-      } else {
-        throw "Unrecognized constant: ${value}";
-      }
-    } else if (exp is LiteralList) {
-      precedence = PRIMARY;
-      tree.NodeList typeArgs = null;
-      if (exp.typeArgument != null) {
-        typeArgs = typeArgList([makeType(exp.typeArgument)]);
-      }
-      result = new tree.LiteralList(
-          typeArgs,
-          bracketList(',', exp.values.map(makeExpression)),
-          exp.isConst ? constToken : null);
-    } else if (exp is LiteralMap) {
-      precedence = PRIMARY;
-      if (beginStmt) {
-        // The opening brace can be confused with a block statement.
-        needParen = true;
-      }
-      tree.NodeList typeArgs = null;
-      if (exp.typeArguments != null && exp.typeArguments.length > 0) {
-        typeArgs = typeArgList(exp.typeArguments.map(makeType));
-      }
-      result = new tree.LiteralMap(
-          typeArgs,
-          braceList(',', exp.entries.map(makeLiteralMapEntry)),
-          exp.isConst ? constToken : null);
-    } else if (exp is LiteralSymbol) {
-      precedence = PRIMARY;
-      result = new tree.LiteralSymbol(
-          hash, makeList('.', exp.id.split('.').map(makeIdentifier)));
-    } else if (exp is LiteralType) {
-      precedence = TYPE_LITERAL;
-      elements.Element optionalElement = exp.type.element;
-      result = new tree.Send(
-          optionalElement == null ? null : makeStaticReceiver(optionalElement),
-          makeIdentifier(exp.name));
-      treeElements.setType(result, exp.type);
-      if (optionalElement != null) {
-        // dynamic does not have an element
-        setElement(result, optionalElement, exp);
-      }
-    } else if (exp is ReifyTypeVar) {
-      precedence = PRIMARY;
-      result = new tree.Send(null, makeIdentifier(exp.name));
-      setElement(result, exp.element, exp);
-      setType(result, exp.element.type, exp);
-    } else if (exp is StringConcat) {
-      precedence = PRIMARY;
-      result = unparseStringLiteral(exp);
-    } else if (exp is This) {
-      precedence = CALLEE;
-      result = makeIdentifier('this');
-    } else if (exp is Throw) {
-      precedence = EXPRESSION; // ???
-      result = new tree.Throw(makeExpression(exp.expression), throwToken,
-          throwToken); // endToken not used by unparser
-    } else if (exp is TypeOperator) {
-      precedence = RELATIONAL;
-      tree.Operator operator;
-      tree.Node rightOperand = makeType(exp.type);
-      if (exp.operator == 'is!') {
-        operator = new tree.Operator(typeOpToken('is'));
-        rightOperand =
-            new tree.Send(rightOperand, new tree.Operator(bang), blankList());
-      } else {
-        operator = new tree.Operator(typeOpToken(exp.operator));
-      }
-      result = new tree.Send(
-          makeExp(exp.expression, BITWISE_OR, beginStmt: beginStmt),
-          operator,
-          singleton(rightOperand));
-    } else if (exp is UnaryOperator) {
-      precedence = UNARY;
-      result = new tree.Send.prefix(makeExp(exp.operand, UNARY),
-          new tree.Operator(unopToken(exp.operatorName)));
-    } else {
-      throw "Unknown expression type: ${exp}";
-    }
-
-    needParen = needParen || precedence < minPrecedence;
-    if (needParen) {
-      result = parenthesize(result);
-    }
-    return result;
-  }
-
-  /// Creates a LiteralString with [verbatim] as the value.
-  /// No (un)quoting or (un)escaping will be performed by this method.
-  /// The [DartString] inside the literal will be set to null because the
-  /// code emitter does not use it.
-  tree.LiteralString makeVerbatimStringLiteral(String verbatim) {
-    Token tok = new StringToken.fromString(STRING_INFO, verbatim, -1);
-    return new tree.LiteralString(tok, null);
-  }
-
-  tree.LiteralMapEntry makeLiteralMapEntry(LiteralMapEntry en) {
-    return new tree.LiteralMapEntry(
-        makeExpression(en.key), colon, makeExpression(en.value));
-  }
-
-  /// A comment token to be inserted when [INSERT_NEW_BACKEND_COMMENT] is true.
-  final SymbolToken newBackendComment = new SymbolToken(
-      const PrecedenceInfo('/* new backend */ ', 0, OPEN_CURLY_BRACKET_TOKEN),
-      -1);
-
-  tree.Node makeFunctionBody(Statement stmt) {
-    if (INSERT_NEW_BACKEND_COMMENT) {
-      return new tree.Block(
-          makeList('', [makeBlock(stmt)], open: newBackendComment));
-    } else {
-      return makeBlock(stmt);
-    }
-  }
-
-  /// Produces a statement in a context where only blocks are allowed.
-  tree.Node makeBlock(Statement stmt) {
-    if (stmt is Block || stmt is EmptyStatement) {
-      return makeStatement(stmt);
-    } else {
-      return new tree.Block(braceList('', [makeStatement(stmt)]));
-    }
-  }
-
-  /// Adds the given statement to a block. If the statement itself is a block
-  /// it will be flattened (if this does not change lexical scoping).
-  void addBlockMember(Statement stmt, List<tree.Node> accumulator) {
-    if (stmt is Block && !stmt.statements.any(Unparser.definesVariable)) {
-      for (Statement innerStmt in stmt.statements) {
-        addBlockMember(innerStmt, accumulator);
-      }
-    } else if (stmt is EmptyStatement) {
-      // No need to include empty statements inside blocks
-    } else {
-      accumulator.add(makeStatement(stmt));
-    }
-  }
-
-  /// True if [stmt] is equivalent to an empty statement.
-  bool isEmptyStatement(Statement stmt) {
-    return stmt is EmptyStatement ||
-        (stmt is Block && stmt.statements.every(isEmptyStatement));
-  }
-
-  tree.Node makeStatement(Statement stmt, {bool shortIf: true}) {
-    if (stmt is Block) {
-      List<tree.Node> body = <tree.Node>[];
-      for (Statement innerStmt in stmt.statements) {
-        addBlockMember(innerStmt, body);
-      }
-      return new tree.Block(braceList('', body));
-    } else if (stmt is Break) {
-      return new tree.BreakStatement(
-          stmt.label == null ? null : makeIdentifier(stmt.label),
-          breakToken,
-          semicolon);
-    } else if (stmt is Continue) {
-      return new tree.ContinueStatement(
-          stmt.label == null ? null : makeIdentifier(stmt.label),
-          continueToken,
-          semicolon);
-    } else if (stmt is DoWhile) {
-      return new tree.DoWhile(
-          makeStatement(stmt.body, shortIf: shortIf),
-          parenthesize(makeExpression(stmt.condition)),
-          doToken,
-          whileToken,
-          semicolon);
-    } else if (stmt is EmptyStatement) {
-      return new tree.EmptyStatement(semicolon);
-    } else if (stmt is ExpressionStatement) {
-      return new tree.ExpressionStatement(
-          makeExp(stmt.expression, EXPRESSION, beginStmt: true), semicolon);
-    } else if (stmt is For) {
-      tree.Node initializer;
-      if (stmt.initializer is VariableDeclarations) {
-        initializer = makeVariableDeclarations(stmt.initializer);
-      } else if (stmt.initializer is Expression) {
-        initializer = makeExpression(stmt.initializer);
-      } else {
-        initializer = null;
-      }
-      tree.Node condition;
-      if (stmt.condition != null) {
-        condition = new tree.ExpressionStatement(
-            makeExpression(stmt.condition), semicolon);
-      } else {
-        condition = new tree.EmptyStatement(semicolon);
-      }
-      return new tree.For(
-          initializer,
-          condition,
-          makeList(',', stmt.updates.map(makeExpression)),
-          makeStatement(stmt.body, shortIf: shortIf),
-          forToken);
-    } else if (stmt is ForIn) {
-      tree.Node left;
-      if (stmt.leftHandValue is Identifier) {
-        left = makeExpression(stmt.leftHandValue);
-      } else {
-        left = makeVariableDeclarations(stmt.leftHandValue);
-      }
-      return new tree.SyncForIn(left, makeExpression(stmt.expression),
-          makeStatement(stmt.body, shortIf: shortIf), forToken, inToken);
-    } else if (stmt is FunctionDeclaration) {
-      tree.FunctionExpression function = new tree.FunctionExpression(
-          stmt.name != null ? makeIdentifier(stmt.name) : null,
-          // GENERIC_METHODS: In order to support generic methods fully,
-          // we must retrieve and pass the actual type variables here.
-          null, // typeVariables
-          makeParameters(stmt.parameters),
-          makeFunctionBody(stmt.body),
-          stmt.returnType != null ? makeType(stmt.returnType) : null,
-          makeEmptyModifiers(),
-          null, // initializers
-          null, // get/set
-          null); // async modifier
-      setElement(function, stmt.function.element, stmt);
-      return new tree.FunctionDeclaration(function);
-    } else if (stmt is If) {
-      if (stmt.elseStatement == null || isEmptyStatement(stmt.elseStatement)) {
-        tree.Node node = new tree.If(
-            parenthesize(makeExpression(stmt.condition)),
-            makeStatement(stmt.thenStatement),
-            null, // else statement
-            ifToken,
-            null); // else token
-        if (shortIf)
-          return node;
-        else
-          return new tree.Block(braceList('', [node]));
-      } else {
-        return new tree.If(
-            parenthesize(makeExpression(stmt.condition)),
-            makeStatement(stmt.thenStatement, shortIf: false),
-            makeStatement(stmt.elseStatement, shortIf: shortIf),
-            ifToken,
-            elseToken); // else token
-      }
-    } else if (stmt is LabeledStatement) {
-      List<tree.Label> labels = [];
-      Statement inner = stmt;
-      while (inner is LabeledStatement) {
-        LabeledStatement lbl = inner as LabeledStatement;
-        labels.add(new tree.Label(makeIdentifier(lbl.label), colon));
-        inner = lbl.statement;
-      }
-      return new tree.LabeledStatement(
-          makeList('', labels), makeStatement(inner, shortIf: shortIf));
-    } else if (stmt is Rethrow) {
-      return new tree.Rethrow(rethrowToken, semicolon);
-    } else if (stmt is Return) {
-      return new tree.Return(returnToken, semicolon,
-          stmt.expression == null ? null : makeExpression(stmt.expression));
-    } else if (stmt is Switch) {
-      return new tree.SwitchStatement(
-          parenthesize(makeExpression(stmt.expression)),
-          braceList('', stmt.cases.map(makeSwitchCase)),
-          switchToken);
-    } else if (stmt is Try) {
-      return new tree.TryStatement(
-          makeBlock(stmt.tryBlock),
-          makeList(null, stmt.catchBlocks.map(makeCatchBlock)),
-          stmt.finallyBlock == null ? null : makeBlock(stmt.finallyBlock),
-          tryToken,
-          stmt.finallyBlock == null ? null : finallyToken);
-    } else if (stmt is VariableDeclarations) {
-      return makeVariableDeclarations(stmt, useVar: true, endToken: semicolon);
-    } else if (stmt is While) {
-      return new tree.While(parenthesize(makeExpression(stmt.condition)),
-          makeStatement(stmt.body, shortIf: shortIf), whileToken);
-    } else {
-      throw "Unrecognized statement: ${stmt}";
-    }
-  }
-
-  tree.Node makeVariableDeclaration(VariableDeclaration vd) {
-    tree.Node id = makeIdentifier(vd.name);
-    setElement(id, vd.element, vd);
-    if (vd.initializer == null) {
-      return id;
-    }
-    tree.Node send = new tree.SendSet(null, id, new tree.Operator(eq),
-        singleton(makeExpression(vd.initializer)));
-    setElement(send, vd.element, vd);
-    return send;
-  }
-
-  /// If [useVar] is true, the variable definition will use `var` as modifier
-  /// if no other modifiers are present.
-  /// [endToken] will be used to terminate the declaration list.
-  tree.Node makeVariableDeclarations(VariableDeclarations decl,
-      {bool useVar: false, Token endToken: null}) {
-    return new tree.VariableDefinitions(
-        decl.type == null ? null : makeType(decl.type),
-        makeVarModifiers(
-            isConst: decl.isConst,
-            isFinal: decl.isFinal,
-            useVar: useVar && decl.type == null),
-        makeList(',', decl.declarations.map(makeVariableDeclaration),
-            close: endToken));
-  }
-
-  tree.CatchBlock makeCatchBlock(CatchBlock block) {
-    List<tree.VariableDefinitions> formals = [];
-    if (block.exceptionVar != null) {
-      tree.Node exceptionName = makeIdentifier(block.exceptionVar.name);
-      setElement(exceptionName, block.exceptionVar.element, block.exceptionVar);
-      formals.add(new tree.VariableDefinitions(
-          null, makeEmptyModifiers(), singleton(exceptionName)));
-    }
-    if (block.stackVar != null) {
-      tree.Node stackTraceName = makeIdentifier(block.stackVar.name);
-      setElement(stackTraceName, block.stackVar.element, block.stackVar);
-      formals.add(new tree.VariableDefinitions(
-          null, makeEmptyModifiers(), singleton(stackTraceName)));
-    }
-    return new tree.CatchBlock(
-        block.onType == null ? null : makeType(block.onType),
-        block.exceptionVar == null ? null : argList(formals),
-        makeBlock(block.body),
-        block.onType == null ? null : onToken,
-        block.exceptionVar == null ? null : catchToken);
-  }
-
-  tree.SwitchCase makeSwitchCase(SwitchCase caze) {
-    if (caze.isDefaultCase) {
-      return new tree.SwitchCase(
-          blankList(),
-          defaultToken,
-          makeList('', caze.statements.map(makeStatement)),
-          null); // startToken unused by unparser
-    } else {
-      return new tree.SwitchCase(
-          makeList('', caze.expressions.map(makeCaseMatch)),
-          null, // defaultKeyword,
-          makeList('', caze.statements.map(makeStatement)),
-          null); // startToken unused by unparser
-    }
-  }
-
-  tree.CaseMatch makeCaseMatch(Expression exp) {
-    return new tree.CaseMatch(caseToken, makeExpression(exp), colon);
-  }
-
-  tree.TypeAnnotation makeType(TypeAnnotation type) {
-    tree.NodeList typeArgs;
-    if (type.typeArguments.length > 0) {
-      typeArgs = typeArgList(type.typeArguments.map(makeType));
-    } else {
-      typeArgs = null;
-    }
-    tree.TypeAnnotation result =
-        new tree.TypeAnnotation(makeIdentifier(type.name), typeArgs);
-    setType(result, type.dartType, type);
-    return result;
-  }
-
-  tree.NodeList makeParameters(Parameters params) {
-    List<tree.Node> nodes =
-        params.requiredParameters.map(makeParameter).toList();
-    if (params.hasOptionalParameters) {
-      Token assign = params.hasNamedParameters ? colon : eq;
-      Token open = params.hasNamedParameters ? openBrace : openBracket;
-      Token close = params.hasNamedParameters ? closeBrace : closeBracket;
-      Iterable<tree.Node> opt =
-          params.optionalParameters.map((p) => makeParameter(p, assign));
-      nodes.add(new tree.NodeList(open, makeLink(opt), close, ','));
-    }
-    return argList(nodes);
-  }
-
-  /// [assignOperator] is used for writing the default value.
-  tree.Node makeParameter(Parameter param, [Token assignOperator]) {
-    if (param.isFunction) {
-      tree.Node definition = new tree.FunctionExpression(
-          makeIdentifier(param.name),
-          // GENERIC_METHODS: In order to support generic methods fully,
-          // we must retrieve and pass the actual type variables here.
-          null, // typeVariables
-          makeParameters(param.parameters),
-          null, // body
-              param.type == null ? null : makeType(param.type),
-          makeEmptyModifiers(), // TODO: Function parameter modifiers?
-          null, // initializers
-          null, // get/set
-          null); // async modifier
-      if (param.element != null) {
-        setElement(definition, param.element, param);
-      }
-      if (param.defaultValue != null) {
-        definition = new tree.SendSet(
-            null,
-            definition,
-            new tree.Operator(assignOperator),
-            singleton(makeExpression(param.defaultValue)));
-      }
-      return new tree.VariableDefinitions(
-          null, makeEmptyModifiers(), singleton(definition));
-    } else {
-      tree.Node definition;
-      if (param.defaultValue != null) {
-        definition = new tree.SendSet(
-            null,
-            makeIdentifier(param.name),
-            new tree.Operator(assignOperator),
-            singleton(makeExpression(param.defaultValue)));
-      } else {
-        definition = makeIdentifier(param.name);
-      }
-      if (param.element != null) {
-        setElement(definition, param.element, param);
-      }
-      return new tree.VariableDefinitions(
-          param.type == null ? null : makeType(param.type),
-          makeEmptyModifiers(), // TODO: Parameter modifiers?
-          singleton(definition));
-    }
-  }
-
-  tree.Modifiers makeEmptyModifiers() {
-    return new tree.Modifiers(blankList());
-  }
-
-  tree.Modifiers makeModifiers(
-      {bool isExternal: false,
-      bool isStatic: false,
-      bool isAbstract: false,
-      bool isFactory: false,
-      bool isConst: false,
-      bool isFinal: false,
-      bool isVar: false}) {
-    List<tree.Node> nodes = [];
-    if (isExternal) {
-      nodes.add(makeIdentifier('external'));
-    }
-    if (isStatic) {
-      nodes.add(makeIdentifier('static'));
-    }
-    if (isAbstract) {
-      nodes.add(makeIdentifier('abstract'));
-    }
-    if (isFactory) {
-      nodes.add(makeIdentifier('factory'));
-    }
-    if (isConst) {
-      nodes.add(makeIdentifier('const'));
-    }
-    if (isFinal) {
-      nodes.add(makeIdentifier('final'));
-    }
-    if (isVar) {
-      nodes.add(makeIdentifier('var'));
-    }
-    return new tree.Modifiers(makeList(' ', nodes));
-  }
-
-  tree.Modifiers makeVarModifiers(
-      {bool isConst: false,
-      bool isFinal: false,
-      bool useVar: false,
-      bool isStatic: false}) {
-    return makeModifiers(
-        isStatic: isStatic,
-        isConst: isConst,
-        isFinal: isFinal,
-        isVar: useVar && !(isConst || isFinal));
-  }
-
-  tree.Modifiers makeFunctionModifiers(FunctionExpression exp) {
-    if (exp.element == null) return makeEmptyModifiers();
-    return makeModifiers(
-        isExternal: exp.element.isExternal,
-        isStatic: exp.element.isStatic,
-        isFactory: exp.element.isFactoryConstructor,
-        isConst: exp.element.isConst);
-  }
-
-  tree.Node makeNodeForClassElement(elements.ClassElement cls) {
-    if (cls.isMixinApplication) {
-      return makeNamedMixinApplication(cls);
-    } else if (cls.isEnumClass) {
-      return makeEnum(cls);
-    } else {
-      return makeClassNode(cls);
-    }
-  }
-
-  tree.Typedef makeTypedef(elements.TypedefElement typdef) {
-    types.FunctionType functionType = typdef.alias;
-    final tree.TypeAnnotation returnType =
-        makeType(TypeGenerator.createType(functionType.returnType));
-
-    final tree.Identifier name = makeIdentifier(typdef.name);
-    final tree.NodeList typeParameters =
-        makeTypeParameters(typdef.typeVariables);
-    final tree.NodeList formals =
-        makeParameters(TypeGenerator.createParametersFromType(functionType));
-
-    final Token typedefKeyword = typedefToken;
-    final Token endToken = semicolon;
-
-    return new tree.Typedef(
-        returnType, name, typeParameters, formals, typedefKeyword, endToken);
-  }
-
-  /// Create a [tree.NodeList] containing the type variable declarations in
-  /// [typeVaraiables.
-  tree.NodeList makeTypeParameters(List<types.DartType> typeVariables) {
-    if (typeVariables.isEmpty) {
-      return new tree.NodeList.empty();
-    } else {
-      List<tree.Node> typeVariableList = <tree.Node>[];
-      for (types.TypeVariableType typeVariable in typeVariables) {
-        tree.Node id = makeIdentifier(typeVariable.name);
-        treeElements[id] = typeVariable.element;
-        tree.Node bound;
-        if (!typeVariable.element.bound.isObject) {
-          bound =
-              makeType(TypeGenerator.createType(typeVariable.element.bound));
-        }
-        tree.TypeVariable node = new tree.TypeVariable(id, extendsToken, bound);
-        treeElements.setType(node, typeVariable);
-        typeVariableList.add(node);
-      }
-      return makeList(',', typeVariableList, open: lt, close: gt);
-    }
-  }
-
-  /// Create a [tree.NodeList] containing the declared interfaces.
-  ///
-  /// [interfaces] is from [elements.ClassElement] in reverse declaration order
-  /// and it contains mixins. To produce a list of the declared interfaces only,
-  /// interfaces in [mixinTypes] are omitted.
-  ///
-  /// [forNamedMixinApplication] is because the structure of the [tree.NodeList]
-  /// differs between [tree.NamedMixinApplication] and [tree.ClassNode].
-  // TODO(johnniwinther): Normalize interfaces on[tree.NamedMixinApplication]
-  // and [tree.ClassNode].
-  tree.NodeList makeInterfaces(
-      Link<types.DartType> interfaces, Set<types.DartType> mixinTypes,
-      {bool forNamedMixinApplication: false}) {
-    Link<tree.Node> typeAnnotations = const Link<tree.Node>();
-    for (Link<types.DartType> link = interfaces;
-        !link.isEmpty;
-        link = link.tail) {
-      types.DartType interface = link.head;
-      if (!mixinTypes.contains(interface)) {
-        typeAnnotations = typeAnnotations
-            .prepend(makeType(TypeGenerator.createType(interface)));
-      }
-    }
-    if (typeAnnotations.isEmpty) {
-      return forNamedMixinApplication ? null : new tree.NodeList.empty();
-    } else {
-      return new tree.NodeList(
-          forNamedMixinApplication ? null : implementsToken,
-          typeAnnotations,
-          null,
-          ',');
-    }
-  }
-
-  /// Creates a [tree.NamedMixinApplication] node for [cls].
-  // TODO(johnniwinther): Unify creation of mixin lists between
-  // [NamedMixinApplicationElement] and [ClassElement].
-  tree.NamedMixinApplication makeNamedMixinApplication(
-      elements.MixinApplicationElement cls) {
-    assert(invariant(cls, !cls.isUnnamedMixinApplication,
-        message: "Cannot create ClassNode for unnamed mixin application "
-            "$cls."));
-    tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract);
-    tree.Identifier name = makeIdentifier(cls.name);
-    tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables);
-
-    Set<types.DartType> mixinTypes = new Set<types.DartType>();
-    Link<tree.Node> mixins = const Link<tree.Node>();
-
-    void addMixin(types.DartType mixinType) {
-      mixinTypes.add(mixinType);
-      mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType)));
-    }
-
-    addMixin(cls.mixinType);
-
-    tree.Node superclass;
-    types.InterfaceType supertype = cls.supertype;
-    while (supertype.element.isUnnamedMixinApplication) {
-      elements.MixinApplicationElement mixinApplication = supertype.element;
-      addMixin(cls.asInstanceOf(mixinApplication.mixin));
-      supertype = mixinApplication.supertype;
-    }
-    superclass =
-        makeType(TypeGenerator.createType(cls.asInstanceOf(supertype.element)));
-    tree.Node supernode = new tree.MixinApplication(
-        superclass, new tree.NodeList(null, mixins, null, ','));
-
-    tree.NodeList interfaces = makeInterfaces(cls.interfaces, mixinTypes,
-        forNamedMixinApplication: true);
-
-    return new tree.NamedMixinApplication(name, typeParameters, modifiers,
-        supernode, interfaces, classToken, semicolon);
-  }
-
-  tree.Enum makeEnum(elements.EnumClassElement cls) {
-    return new tree.Enum(
-        enumToken,
-        makeIdentifier(cls.name),
-        makeList(',', cls.enumValues.map((e) => makeIdentifier(e.name)),
-            open: openBrace, close: closeBrace));
-  }
-
-  /// Creates a [tree.ClassNode] node for [cls].
-  tree.ClassNode makeClassNode(elements.ClassElement cls) {
-    assert(invariant(cls, !cls.isUnnamedMixinApplication,
-        message: "Cannot create ClassNode for unnamed mixin application "
-            "$cls."));
-    tree.Modifiers modifiers = makeModifiers(isAbstract: cls.isAbstract);
-    tree.Identifier name = makeIdentifier(cls.name);
-    tree.NodeList typeParameters = makeTypeParameters(cls.typeVariables);
-    tree.Node supernode;
-    types.InterfaceType supertype = cls.supertype;
-    Set<types.DartType> mixinTypes = new Set<types.DartType>();
-    Link<tree.Node> mixins = const Link<tree.Node>();
-
-    void addMixin(types.DartType mixinType) {
-      mixinTypes.add(mixinType);
-      mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType)));
-    }
-
-    if (supertype != null) {
-      if (supertype.element.isUnnamedMixinApplication) {
-        while (supertype.element.isUnnamedMixinApplication) {
-          elements.MixinApplicationElement mixinApplication = supertype.element;
-          addMixin(cls.asInstanceOf(mixinApplication.mixin));
-          supertype = mixinApplication.supertype;
-        }
-        tree.Node superclass = makeType(
-            TypeGenerator.createType(cls.asInstanceOf(supertype.element)));
-        supernode = new tree.MixinApplication(
-            superclass, new tree.NodeList(null, mixins, null, ','));
-      } else if (!supertype.isObject) {
-        supernode = makeType(TypeGenerator.createType(supertype));
-      }
-    }
-    tree.NodeList interfaces = makeInterfaces(cls.interfaces, mixinTypes);
-
-    Token extendsKeyword = supernode != null ? extendsToken : null;
-    return new tree.ClassNode(
-        modifiers,
-        name,
-        typeParameters,
-        supernode,
-        interfaces,
-        openBrace,
-        extendsKeyword,
-        null, // No body.
-        closeBrace);
-  }
-
-  tree.Node constructorName(ConstructorDefinition exp) {
-    String name = exp.name;
-    tree.Identifier className = makeIdentifier(exp.element.enclosingClass.name);
-    tree.Node result =
-        name == "" ? className : new tree.Send(className, makeIdentifier(name));
-    setElement(result, exp.element, exp);
-    return result;
-  }
-
-  tree.Node functionName(FunctionExpression exp) {
-    String name = exp.name;
-    if (name == null) return null;
-    if (isUserDefinableOperator(name)) {
-      return makeOperator("operator$name");
-    } else if (name == "unary-") {
-      return makeOperator("operator-");
-    }
-    return makeIdentifier(name);
-  }
-
-  tree.Node parenthesize(tree.Node node) {
-    return new tree.ParenthesizedExpression(node, openParen);
-  }
-
-  tree.Node unparseStringLiteral(Expression exp) {
-    StringLiteralOutput output = Unparser.analyzeStringLiteral(exp);
-    List parts = output.parts;
-    tree.Node printStringChunk(StringChunk chunk) {
-      bool raw = chunk.quoting.raw;
-      int quoteCode = chunk.quoting.quote;
-
-      List<tree.StringInterpolationPart> literalParts = [];
-      tree.LiteralString firstLiteral;
-      tree.Node currentInterpolation;
-
-      // sb contains the current unfinished LiteralString
-      StringBuffer sb = new StringBuffer();
-      if (raw) {
-        sb.write('r');
-      }
-      for (int i = 0; i < chunk.quoting.leftQuoteCharCount; i++) {
-        sb.write(chunk.quoting.quoteChar);
-      }
-
-      // Print every character and string interpolation
-      int startIndex = chunk.previous != null ? chunk.previous.endIndex : 0;
-      for (int i = startIndex; i < chunk.endIndex; i++) {
-        var part = parts[i];
-        if (part is Expression) {
-          // Finish the previous string interpolation, if there is one.
-          tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
-          if (currentInterpolation != null) {
-            literalParts.add(
-                new tree.StringInterpolationPart(currentInterpolation, lit));
-          } else {
-            firstLiteral = lit;
-          }
-          sb.clear();
-          currentInterpolation = makeExpression(part);
-        } else {
-          int char = part;
-          sb.write(Unparser.getEscapedCharacter(char, quoteCode, raw));
-        }
-      }
-
-      // Print ending quotes
-      for (int i = 0; i < chunk.quoting.rightQuoteLength; i++) {
-        sb.write(chunk.quoting.quoteChar);
-      }
-
-      // Finish the previous string interpolation, if there is one.
-      // Then wrap everything in a StringInterpolation, if relevant.
-      tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
-      tree.Node node;
-      if (firstLiteral == null) {
-        node = lit;
-      } else {
-        literalParts
-            .add(new tree.StringInterpolationPart(currentInterpolation, lit));
-        node = new tree.StringInterpolation(
-            firstLiteral, makeList('', literalParts));
-      }
-
-      // Juxtapose with the previous string chunks, if any.
-      if (chunk.previous != null) {
-        return new tree.StringJuxtaposition(
-            printStringChunk(chunk.previous), node);
-      } else {
-        return node;
-      }
-    }
-    return printStringChunk(output.chunk);
-  }
-}
diff --git a/pkg/compiler/lib/src/dart_backend/dart_backend.dart b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
deleted file mode 100644
index 729091f..0000000
--- a/pkg/compiler/lib/src/dart_backend/dart_backend.dart
+++ /dev/null
@@ -1,40 +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 dart_backend;
-
-import 'dart:async' show Future;
-import 'dart:math' show max;
-
-import '../../compiler.dart' show CompilerOutputProvider;
-import '../common.dart';
-import '../common/backend_api.dart' show Backend, ImpactTransformer;
-import '../common/codegen.dart' show CodegenWorkItem;
-import '../common/names.dart' show Selectors, Uris;
-import '../common/registry.dart' show Registry;
-import '../common/resolution.dart' show Resolution, ResolutionImpact;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../compile_time_constants.dart';
-import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../dart_types.dart';
-import '../elements/elements.dart';
-import '../enqueue.dart' show Enqueuer, ResolutionEnqueuer;
-import '../library_loader.dart' show LoadedLibraries;
-import '../mirror_renamer/mirror_renamer.dart';
-import '../resolution/tree_elements.dart' show TreeElements, TreeElementMapping;
-import '../tokens/keyword.dart' show Keyword;
-import '../tree/tree.dart';
-import '../universe/selector.dart' show Selector;
-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;
-
-part 'backend.dart';
-part 'renamer.dart';
-part 'placeholder_collector.dart';
-part 'outputter.dart';
diff --git a/pkg/compiler/lib/src/dart_backend/outputter.dart b/pkg/compiler/lib/src/dart_backend/outputter.dart
deleted file mode 100644
index ce9022a..0000000
--- a/pkg/compiler/lib/src/dart_backend/outputter.dart
+++ /dev/null
@@ -1,576 +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.
-
-part of dart_backend;
-
-typedef bool IsSafeToRemoveTypeDeclarations(
-    Map<ClassElement, Iterable<Element>> classMembers);
-typedef void ElementCallback<E>(E element);
-typedef void ElementPostProcessFunction(
-    AstElement element,
-    ElementAst elementAst,
-    ElementCallback<TypedefElement> typedefCallback,
-    ElementCallback<ClassElement> classCallback);
-typedef ElementAst ComputeElementAstFunction(AstElement element);
-typedef bool ElementFilter(Element element);
-typedef List<Element> ElementSorter(Iterable<Element> elements);
-
-/// Output engine for dart2dart that is shared between the dart2js and the
-/// analyzer implementations of dart2dart.
-class DartOutputter {
-  final DiagnosticReporter reporter;
-  final CompilerOutputProvider outputProvider;
-  final bool forceStripTypes;
-
-  // TODO(antonm): make available from command-line options.
-  final bool outputAst = false;
-  final bool enableMinification;
-
-  /// If `true`, libraries are generated into separate files.
-  final bool multiFile;
-
-  /// Internal structures accessible for tests and logging.
-  // TODO(johnniwinther): Clean this up.
-  PlaceholderRenamer renamer;
-  MainOutputGenerator output;
-  LibraryInfo libraryInfo;
-  ElementInfo elementInfo;
-
-  // TODO(johnniwinther): Support recompilation.
-  DartOutputter(this.reporter, this.outputProvider,
-      {bool this.forceStripTypes: false,
-      bool this.enableMinification: false,
-      bool this.multiFile: false});
-
-  /// Generate Dart code for the program starting at [mainFunction].
-  ///
-  /// [libraries] is the set of all libraries (user/package/sdk) that are
-  /// referenced in the program.
-  ///
-  /// [instantiatedClasses] is the set of classes that are potentially
-  /// instantiated in the program.
-  ///
-  /// [resolvedElements] is the set of methods, constructors, and fields that
-  /// are potentially accessed/called in the program.
-  ///
-  /// The [sortElements] function is used to sort [instantiatedClasses] and
-  /// [resolvedElements] in the generated output.
-  ///
-  /// Returns the total size of the generated code.
-  int assembleProgram(
-      {MirrorRenamer mirrorRenamer: const MirrorRenamer(),
-      Iterable<LibraryElement> libraries,
-      Iterable<Element> instantiatedClasses,
-      Iterable<Element> resolvedElements,
-      Iterable<ClassElement> usedTypeLiterals: const <ClassElement>[],
-      FunctionElement mainFunction,
-      Uri outputUri,
-      ElementPostProcessFunction postProcessElementAst,
-      ComputeElementAstFunction computeElementAst,
-      ElementFilter shouldOutput,
-      IsSafeToRemoveTypeDeclarations isSafeToRemoveTypeDeclarations,
-      ElementSorter sortElements}) {
-    assert(invariant(NO_LOCATION_SPANNABLE, libraries != null,
-        message: "'libraries' must be non-null."));
-    assert(invariant(NO_LOCATION_SPANNABLE, instantiatedClasses != null,
-        message: "'instantiatedClasses' must be non-null."));
-    assert(invariant(NO_LOCATION_SPANNABLE, resolvedElements != null,
-        message: "'resolvedElements' must be non-null."));
-    assert(invariant(NO_LOCATION_SPANNABLE, mainFunction != null,
-        message: "'mainFunction' must be non-null."));
-    assert(invariant(NO_LOCATION_SPANNABLE, computeElementAst != null,
-        message: "'computeElementAst' must be non-null."));
-    assert(invariant(NO_LOCATION_SPANNABLE, shouldOutput != null,
-        message: "'shouldOutput' must be non-null."));
-    assert(invariant(
-        NO_LOCATION_SPANNABLE, isSafeToRemoveTypeDeclarations != null,
-        message: "'isSafeToRemoveTypeDeclarations' must be non-null."));
-
-    if (sortElements == null) {
-      // Ensure deterministic output order.
-      sortElements = (Iterable<Element> elements) {
-        List<Element> list = elements.toList();
-        list.sort((Element a, Element b) => a.name.compareTo(b.name));
-        return list;
-      };
-    }
-
-    libraryInfo =
-        LibraryInfo.processLibraries(reporter, libraries, resolvedElements);
-
-    elementInfo = ElementInfoProcessor.createElementInfo(
-        instantiatedClasses, resolvedElements, usedTypeLiterals,
-        postProcessElementAst: postProcessElementAst,
-        parseElementAst: computeElementAst,
-        shouldOutput: shouldOutput,
-        sortElements: sortElements);
-
-    PlaceholderCollector collector = collectPlaceholders(
-        reporter, mirrorRenamer, mainFunction, libraryInfo, elementInfo);
-
-    renamer = createRenamer(collector, libraryInfo, elementInfo,
-        enableMinification: enableMinification,
-        forceStripTypes: forceStripTypes,
-        isSafeToRemoveTypeDeclarations: isSafeToRemoveTypeDeclarations);
-
-    if (outputAst) {
-      String code = astOutput(reporter, elementInfo);
-      outputProvider("", "dart")
-        ..add(code)
-        ..close();
-      return code.length;
-    } else {
-      output = new MainOutputGenerator();
-      return output.generateCode(libraryInfo, elementInfo, collector, renamer,
-          mainFunction, outputUri, outputProvider, mirrorRenamer,
-          multiFile: multiFile,
-          forceStripTypes: forceStripTypes,
-          enableMinification: enableMinification);
-    }
-  }
-
-  static PlaceholderCollector collectPlaceholders(
-      DiagnosticReporter reporter,
-      MirrorRenamer mirrorRenamer,
-      FunctionElement mainFunction,
-      LibraryInfo libraryInfo,
-      ElementInfo elementInfo) {
-    // Create all necessary placeholders.
-    PlaceholderCollector collector = new PlaceholderCollector(
-        reporter,
-        mirrorRenamer,
-        libraryInfo.fixedDynamicNames,
-        elementInfo.elementAsts,
-        mainFunction);
-
-    makePlaceholders(element) {
-      collector.collect(element);
-
-      if (element.isClass && !element.isEnumClass) {
-        elementInfo.classMembers[element].forEach(makePlaceholders);
-      }
-    }
-    elementInfo.topLevelElements.forEach(makePlaceholders);
-    return collector;
-  }
-
-  static PlaceholderRenamer createRenamer(PlaceholderCollector collector,
-      LibraryInfo libraryInfo, ElementInfo elementInfo,
-      {bool enableMinification: false,
-      bool forceStripTypes: false,
-      isSafeToRemoveTypeDeclarations}) {
-    // Create renames.
-    bool shouldCutDeclarationTypes = forceStripTypes ||
-        (enableMinification &&
-            isSafeToRemoveTypeDeclarations(elementInfo.classMembers));
-
-    PlaceholderRenamer placeholderRenamer = new PlaceholderRenamer(
-        libraryInfo.fixedDynamicNames,
-        libraryInfo.fixedStaticNames,
-        libraryInfo.reexportingLibraries,
-        cutDeclarationTypes: shouldCutDeclarationTypes,
-        enableMinification: enableMinification);
-
-    placeholderRenamer.computeRenames(collector);
-    return placeholderRenamer;
-  }
-
-  static String astOutput(
-      DiagnosticReporter reporter, ElementInfo elementInfo) {
-    // TODO(antonm): Ideally XML should be a separate backend.
-    // TODO(antonm): obey renames and minification, at least as an option.
-    StringBuffer sb = new StringBuffer();
-    outputElement(element) {
-      sb.write(element.parseNode(reporter).toDebugString());
-    }
-
-    // Emit XML for AST instead of the program.
-    for (Element topLevel in elementInfo.topLevelElements) {
-      if (topLevel.isClass &&
-          !elementInfo.emitNoMembersFor.contains(topLevel)) {
-        // TODO(antonm): add some class info.
-        elementInfo.classMembers[topLevel].forEach(outputElement);
-      } else {
-        outputElement(topLevel);
-      }
-    }
-    return '<Program>\n$sb</Program>\n';
-  }
-}
-
-class LibraryInfo {
-  final Set<String> fixedStaticNames;
-  final Set<String> fixedDynamicNames;
-  final Map<Element, LibraryElement> reexportingLibraries;
-  final List<LibraryElement> userLibraries;
-
-  LibraryInfo(this.fixedStaticNames, this.fixedDynamicNames,
-      this.reexportingLibraries, this.userLibraries);
-
-  static LibraryInfo processLibraries(
-      DiagnosticReporter reporter,
-      Iterable<LibraryElement> libraries,
-      Iterable<AstElement> resolvedElements) {
-    Set<String> fixedStaticNames = new Set<String>();
-    Set<String> fixedDynamicNames = new Set<String>();
-    Map<Element, LibraryElement> reexportingLibraries =
-        <Element, LibraryElement>{};
-    List<LibraryElement> userLibraries = <LibraryElement>[];
-    // Conservatively traverse all platform libraries and collect member names.
-    // TODO(antonm): ideally we should only collect names of used members,
-    // however as of today there are problems with names of some core library
-    // interfaces, most probably for interfaces of literals.
-
-    for (LibraryElement library in libraries) {
-      if (!library.isPlatformLibrary) {
-        userLibraries.add(library);
-        continue;
-      }
-      library.forEachLocalMember((Element element) {
-        if (element.isClass) {
-          ClassElement classElement = element;
-          assert(invariant(classElement, classElement.isResolved,
-              message: "Unresolved platform class."));
-          classElement.forEachLocalMember((member) {
-            if (member.isInstanceMember) {
-              fixedDynamicNames.add(member.name);
-            } else {
-              fixedStaticNames.add(member.name);
-            }
-          });
-        }
-        // Even class names are added due to a delicate problem we have:
-        // if one imports dart:core with a prefix, we cannot tell prefix.name
-        // from dynamic invocation (alas!).  So we'd better err on preserving
-        // those names.
-        fixedStaticNames.add(element.name);
-      });
-
-      library.forEachExport((Element export) {
-        if (!library.isInternalLibrary && export.library.isInternalLibrary) {
-          // If an element of an internal library is reexported by a platform
-          // library, we have to import the reexporting library instead of the
-          // internal library, because the internal library is an
-          // implementation detail of dart2js.
-          reexportingLibraries[export] = library;
-        }
-      });
-    }
-
-    // Map to keep track of names of enum classes. Since these cannot be renamed
-    // we ensure that they are unique.
-    Map<String, ClassElement> enumClassMap = <String, ClassElement>{};
-
-    // As of now names of named optionals are not renamed. Therefore add all
-    // field names used as named optionals into [fixedMemberNames].
-    for (final element in resolvedElements) {
-      if (!element.isConstructor) continue;
-      for (ParameterElement parameter in element.parameters) {
-        if (parameter.isInitializingFormal && parameter.isNamed) {
-          fixedDynamicNames.add(parameter.name);
-        }
-      }
-      ClassElement cls = element.enclosingClass;
-      if (cls != null && cls.isEnumClass) {
-        fixedDynamicNames.add('index');
-
-        ClassElement existingEnumClass =
-            enumClassMap.putIfAbsent(cls.name, () => cls);
-        if (existingEnumClass != cls) {
-          reporter.reportError(
-              reporter.createMessage(cls, MessageKind.GENERIC, {
-                'text': "Duplicate enum names are not supported "
-                    "in dart2dart."
-              }),
-              <DiagnosticMessage>[
-                reporter.createMessage(existingEnumClass, MessageKind.GENERIC, {
-                  'text': "This is the other declaration of '${cls.name}'."
-                }),
-              ]);
-        }
-      }
-    }
-
-    fixedStaticNames.addAll(enumClassMap.keys);
-
-    // The VM will automatically invoke the call method of objects
-    // that are invoked as functions. Make sure to not rename that.
-    fixedDynamicNames.add('call');
-
-    return new LibraryInfo(fixedStaticNames, fixedDynamicNames,
-        reexportingLibraries, userLibraries);
-  }
-}
-
-class ElementInfo {
-  final Map<Element, ElementAst> elementAsts;
-  final Iterable<Element> topLevelElements;
-  final Map<ClassElement, Iterable<Element>> classMembers;
-  final Iterable<ClassElement> emitNoMembersFor;
-
-  ElementInfo(this.elementAsts, this.topLevelElements, this.classMembers,
-      this.emitNoMembersFor);
-}
-
-class ElementInfoProcessor implements ElementInfo {
-  final Map<Element, ElementAst> elementAsts = new Map<Element, ElementAst>();
-  final Set<Element> topLevelElements = new Set<Element>();
-  final Map<ClassElement, Set<Element>> classMembers =
-      new Map<ClassElement, Set<Element>>();
-  final Set<ClassElement> emitNoMembersFor = new Set<ClassElement>();
-  final ElementPostProcessFunction postProcessElementAst;
-  final ComputeElementAstFunction parseElementAst;
-  final ElementFilter shouldOutput;
-
-  ElementInfoProcessor(
-      {this.postProcessElementAst, this.parseElementAst, this.shouldOutput});
-
-  static ElementInfo createElementInfo(
-      Iterable<ClassElement> instantiatedClasses,
-      Iterable<AstElement> resolvedElements,
-      Iterable<ClassElement> usedTypeLiterals,
-      {ElementPostProcessFunction postProcessElementAst,
-      ComputeElementAstFunction parseElementAst,
-      ElementFilter shouldOutput,
-      ElementSorter sortElements}) {
-    ElementInfoProcessor processor = new ElementInfoProcessor(
-        postProcessElementAst: postProcessElementAst,
-        parseElementAst: parseElementAst,
-        shouldOutput: shouldOutput);
-    return processor.process(
-        instantiatedClasses, resolvedElements, usedTypeLiterals,
-        sortElements: sortElements);
-  }
-
-  ElementInfo process(
-      Iterable<ClassElement> instantiatedClasses,
-      Iterable<AstElement> resolvedElements,
-      Iterable<ClassElement> usedTypeLiterals,
-      {ElementSorter sortElements}) {
-    // Build all top level elements to emit and necessary class members.
-    instantiatedClasses.where(shouldOutput).forEach(addClass);
-    resolvedElements.where(shouldOutput).forEach(addMember);
-    usedTypeLiterals.forEach((ClassElement element) {
-      if (shouldOutput(element)) {
-        if (!topLevelElements.contains(element)) {
-          // The class is only referenced by type literals.
-          emitNoMembersFor.add(element);
-        }
-        addClass(element);
-      }
-    });
-
-    // Sort elements.
-    List<Element> sortedTopLevels = sortElements(topLevelElements);
-    Map<ClassElement, List<Element>> sortedClassMembers =
-        new Map<ClassElement, List<Element>>();
-    classMembers.forEach((classElement, members) {
-      sortedClassMembers[classElement] = sortElements(members);
-    });
-
-    return new ElementInfo(
-        elementAsts, sortedTopLevels, sortedClassMembers, emitNoMembersFor);
-  }
-
-  void processElement(Element element, ElementAst elementAst) {
-    if (postProcessElementAst != null) {
-      postProcessElementAst(element, elementAst, newTypedefElementCallback,
-          newClassElementCallback);
-    }
-    elementAsts[element] = elementAst;
-  }
-
-  void addTopLevel(AstElement element, ElementAst elementAst) {
-    if (topLevelElements.contains(element)) return;
-    topLevelElements.add(element);
-    processElement(element, elementAst);
-  }
-
-  void addClass(ClassElement classElement) {
-    TreeElements treeElements = new TreeElementMapping(classElement);
-    backend2frontend.TreePrinter treePrinter =
-        new backend2frontend.TreePrinter(treeElements);
-    Node node = treePrinter.makeNodeForClassElement(classElement);
-    addTopLevel(classElement, new ElementAst(node, treeElements));
-    classMembers.putIfAbsent(classElement, () => new Set());
-  }
-
-  void newTypedefElementCallback(TypedefElement element) {
-    if (!shouldOutput(element)) return;
-    TreeElements treeElements = new TreeElementMapping(element);
-    backend2frontend.TreePrinter treePrinter =
-        new backend2frontend.TreePrinter(treeElements);
-    Node node = treePrinter.makeTypedef(element);
-    addTopLevel(element, new ElementAst(node, treeElements));
-  }
-
-  void newClassElementCallback(ClassElement classElement) {
-    if (!shouldOutput(classElement)) return;
-    addClass(classElement);
-  }
-
-  void addMember(element) {
-    if (element.isClassMember) {
-      ClassElement enclosingClass = element.enclosingClass;
-      assert(enclosingClass.isClass);
-      assert(shouldOutput(enclosingClass));
-      addClass(enclosingClass);
-      classMembers[enclosingClass].add(element);
-      if (enclosingClass.isEnumClass) return;
-      processElement(element, parseElementAst(element));
-    } else {
-      if (element.isTopLevel) {
-        addTopLevel(element, parseElementAst(element));
-      }
-    }
-  }
-}
-
-/// Main output generator for [DartOutputter] that emits dart code through a
-/// [CompilerOutputProvider].
-class MainOutputGenerator {
-  final Map<ClassNode, List<Node>> memberNodes =
-      new Map<ClassNode, List<Node>>();
-  final List<Node> topLevelNodes = <Node>[];
-
-  /// Generates the code and returns the total size.
-  int generateCode(
-      LibraryInfo libraryInfo,
-      ElementInfo elementInfo,
-      PlaceholderCollector collector,
-      PlaceholderRenamer placeholderRenamer,
-      FunctionElement mainFunction,
-      Uri outputUri,
-      CompilerOutputProvider outputProvider,
-      MirrorRenamer mirrorRenamer,
-      {bool multiFile: false,
-      bool forceStripTypes: false,
-      bool enableMinification: false}) {
-    for (Element element in elementInfo.topLevelElements) {
-      topLevelNodes.add(elementInfo.elementAsts[element].ast);
-      if (element.isClass) {
-        ClassElement cls = element;
-        if (cls.isMixinApplication || cls.isEnumClass) {
-          continue;
-        }
-        final members = <Node>[];
-        for (Element member in elementInfo.classMembers[cls]) {
-          members.add(elementInfo.elementAsts[member].ast);
-        }
-        memberNodes[elementInfo.elementAsts[cls].ast] = members;
-      }
-    }
-
-    mirrorRenamer.addRenames(
-        placeholderRenamer.renames, topLevelNodes, collector);
-
-    Map<LibraryElement, String> outputPaths = new Map<LibraryElement, String>();
-    Map<LibraryElement, EmitterUnparser> unparsers =
-        new Map<LibraryElement, EmitterUnparser>();
-
-    // The single unparser used if we collect all the output in one file.
-    EmitterUnparser mainUnparser = multiFile
-        ? null
-        : new EmitterUnparser(placeholderRenamer.renames,
-            stripTypes: forceStripTypes, minify: enableMinification);
-
-    if (multiFile) {
-      // TODO(sigurdm): Factor handling of library-paths out from emitting.
-      String mainName = outputUri.pathSegments.last;
-      String mainBaseName = mainName.endsWith(".dart")
-          ? mainName.substring(0, mainName.length - 5)
-          : mainName;
-      // Map each library to a path based on the uri of the original
-      // library and [compiler.options.outputUri].
-      Set<String> usedLibraryPaths = new Set<String>();
-      for (LibraryElement library in libraryInfo.userLibraries) {
-        if (library == mainFunction.library) {
-          outputPaths[library] = mainBaseName;
-        } else {
-          List<String> names =
-              library.canonicalUri.pathSegments.last.split(".");
-          if (names.last == "dart") {
-            names = names.sublist(0, names.length - 1);
-          }
-          outputPaths[library] =
-              "$mainBaseName.${makeUnique(names.join("."), usedLibraryPaths)}";
-        }
-      }
-
-      /// Rewrites imports/exports to refer to the paths given in [outputPaths].
-      for (LibraryElement outputLibrary in libraryInfo.userLibraries) {
-        EmitterUnparser unparser = new EmitterUnparser(
-            placeholderRenamer.renames,
-            stripTypes: forceStripTypes,
-            minify: enableMinification);
-        unparsers[outputLibrary] = unparser;
-        if (outputLibrary.hasLibraryName) {
-          unparser.unparseLibraryName(outputLibrary.libraryName);
-        }
-        for (ImportElement import in outputLibrary.imports) {
-          LibraryElement libraryElement = import.importedLibrary;
-          String uri = outputPaths.containsKey(libraryElement)
-              ? "${outputPaths[libraryElement]}.dart"
-              : libraryElement.canonicalUri.toString();
-          unparser.unparseImportTag(uri);
-        }
-        for (ExportElement export in outputLibrary.exports) {
-          LibraryElement libraryElement = export.exportedLibrary;
-          String uri = outputPaths.containsKey(libraryElement)
-              ? "${outputPaths[libraryElement]}.dart"
-              : libraryElement.canonicalUri.toString();
-          unparser.unparseExportTag(uri);
-        }
-      }
-    } else {
-      placeholderRenamer.platformImports
-          .forEach((LibraryElement library, String prefix) {
-        assert(library.isPlatformLibrary && !library.isInternalLibrary);
-        mainUnparser.unparseImportTag(library.canonicalUri.toString());
-        if (prefix != null) {
-          // Adding a prefixed import because (some) top-level access need
-          // it to avoid shadowing.
-          // TODO(johnniwinther): Avoid prefix-less import if not needed.
-          mainUnparser.unparseImportTag(library.canonicalUri.toString(),
-              prefix: prefix);
-        }
-      });
-    }
-
-    for (int i = 0; i < elementInfo.topLevelElements.length; i++) {
-      Element element = elementInfo.topLevelElements.elementAt(i);
-      Node node = topLevelNodes[i];
-      Unparser unparser = multiFile ? unparsers[element.library] : mainUnparser;
-      if (node is ClassNode) {
-        // TODO(smok): Filter out default constructors here.
-        unparser.unparseClassWithBody(node, memberNodes[node]);
-      } else {
-        unparser.unparse(node);
-      }
-      unparser.newline();
-    }
-
-    int totalSize = 0;
-    if (multiFile) {
-      for (LibraryElement outputLibrary in libraryInfo.userLibraries) {
-        // TODO(sigurdm): Make the unparser output directly into the buffer
-        // instead of caching in `.result`.
-        String code = unparsers[outputLibrary].result;
-        totalSize += code.length;
-        outputProvider(outputPaths[outputLibrary], "dart")
-          ..add(code)
-          ..close();
-      }
-    } else {
-      String code = mainUnparser.result;
-      outputProvider("", "dart")
-        ..add(code)
-        ..close();
-
-      totalSize = code.length;
-    }
-
-    return totalSize;
-  }
-}
diff --git a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
deleted file mode 100644
index e6656a7..0000000
--- a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
+++ /dev/null
@@ -1,724 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart_backend;
-
-class LocalPlaceholder {
-  final String identifier;
-  final Set<Node> nodes;
-  LocalPlaceholder(this.identifier) : nodes = new Set<Node>();
-  int get hashCode => identifier.hashCode;
-  String toString() => 'local_placeholder[id($identifier), nodes($nodes)]';
-}
-
-class FunctionScope {
-  final Set<String> parameterIdentifiers;
-  final Set<LocalPlaceholder> localPlaceholders;
-  FunctionScope()
-      : parameterIdentifiers = new Set<String>(),
-        localPlaceholders = new Set<LocalPlaceholder>();
-  void registerParameter(Identifier node) {
-    parameterIdentifiers.add(node.source);
-  }
-}
-
-class ConstructorPlaceholder {
-  final Identifier node;
-  final ConstructorElement element;
-
-  ConstructorPlaceholder(this.node, this.element);
-}
-
-class DeclarationTypePlaceholder {
-  final TypeAnnotation typeNode;
-  final bool requiresVar;
-  DeclarationTypePlaceholder(this.typeNode, this.requiresVar);
-}
-
-class SendVisitor extends Visitor {
-  final TreeElements elements;
-  final PlaceholderCollector collector;
-
-  SendVisitor(this.collector, this.elements);
-
-  visitSend(Send node) {
-    Element element = elements[node];
-    if (elements.isTypeLiteral(node)) {
-      DartType type = elements.getTypeLiteralType(node);
-      if (!type.isDynamic) {
-        if (type is TypeVariableType) {
-          collector.makeTypeVariablePlaceholder(node.selector, type);
-        } else {
-          collector.makeTypePlaceholder(node.selector, type);
-        }
-      }
-    } else if (node.isSuperCall) {
-      if (element != null && element.isConstructor) {
-        collector.tryMakeConstructorPlaceholder(node, element);
-      } else {
-        collector.tryMakeMemberPlaceholder(node.selector);
-      }
-    } else if (node.isOperator) {
-      return;
-    } else if (node.isPropertyAccess) {
-      if (!Elements.isUnresolved(element) && element.impliesType) {
-        collector.makeElementPlaceholder(node, element);
-      } else {
-        visitGetterSend(node);
-      }
-    } else if (element != null && Initializers.isConstructorRedirect(node)) {
-      visitStaticSend(node);
-    } else if (Elements.isClosureSend(node, element)) {
-      if (element != null) {
-        collector.tryMakeLocalPlaceholder(element, node.selector);
-      }
-    } else {
-      if (Elements.isUnresolved(element)) {
-        if (element == null) {
-          // Example: f() with 'f' unbound.
-          // This can only happen inside an instance method.
-          visitDynamicSend(node);
-        } else {
-          visitStaticSend(node);
-        }
-      } else if (element.isInstanceMember) {
-        // Example: f() with 'f' bound to instance method.
-        visitDynamicSend(node);
-      } else if (!element.isInstanceMember) {
-        // Example: A.f() or f() with 'f' bound to a static function.
-        // Also includes new A() or new A.named() which is treated like a
-        // static call to a factory.
-        visitStaticSend(node);
-      }
-    }
-  }
-
-  visitDynamicSend(Send node) {
-    final element = elements[node];
-    if (element == null || !element.isMalformed) {
-      collector.tryMakeMemberPlaceholder(node.selector);
-    }
-  }
-
-  visitGetterSend(Send node) {
-    final element = elements[node];
-    // element == null means dynamic property access.
-    if (element == null) {
-      collector.tryMakeMemberPlaceholder(node.selector);
-    } else if (element.isMalformed) {
-      collector.makeUnresolvedPlaceholder(node);
-      return;
-    } else if (element.isPrefix) {
-      // Node is prefix part in case of source 'lib.somesetter = 5;'
-      collector.makeErasePrefixPlaceholder(node);
-    } else if (Elements.isStaticOrTopLevel(element)) {
-      // Unqualified or prefixed top level or static.
-      collector.makeElementPlaceholder(node.selector, element);
-    } else if (!element.isTopLevel) {
-      if (element.isInstanceMember) {
-        collector.tryMakeMemberPlaceholder(node.selector);
-      } else {
-        // May get FunctionExpression here in selector
-        // in case of A(int this.f());
-        if (node.selector is Identifier) {
-          collector.tryMakeLocalPlaceholder(element, node.selector);
-        } else {
-          assert(node.selector is FunctionExpression);
-        }
-      }
-    }
-  }
-
-  visitStaticSend(Send node) {
-    Element element = elements[node];
-    collector.mirrorRenamer
-        .registerStaticSend(collector.currentElement, element, node);
-
-    if (Elements.isUnresolved(element) || element.isDeferredLoaderGetter) {
-      return;
-    }
-    if (element.isConstructor || element.isFactoryConstructor) {
-      // Rename named constructor in redirection position:
-      // class C { C.named(); C.redirecting() : this.named(); }
-      if (node.receiver is Identifier &&
-          node.receiver.asIdentifier().isThis()) {
-        assert(node.selector is Identifier);
-        collector.tryMakeConstructorPlaceholder(node, element);
-      }
-      return;
-    }
-    collector.makeElementPlaceholder(node.selector, element);
-    // Another ugly case: <lib prefix>.<top level> is represented as
-    // receiver: lib prefix, selector: top level.
-    if (element.isTopLevel && node.receiver != null) {
-      assert(elements[node.receiver].isPrefix);
-      // Hack: putting null into map overrides receiver of original node.
-      collector.makeErasePrefixPlaceholder(node.receiver);
-    }
-  }
-
-  internalError(Spannable node, String reason) {
-    collector.internalError(reason, node: node);
-  }
-
-  visitNode(Node node) {
-    internalError(node, "Unhandled node");
-  }
-}
-
-class PlaceholderCollector extends Visitor {
-  final DiagnosticReporter reporter;
-  final MirrorRenamer mirrorRenamer;
-  final FunctionElement mainFunction;
-  final Set<String> fixedMemberNames; // member names which cannot be renamed.
-  final Map<Element, ElementAst> elementAsts;
-  final Set<Node> prefixNodesToErase = new Set<Node>();
-  final Set<Node> unresolvedNodes = new Set<Node>();
-  final Map<Element, Set<Node>> elementNodes = new Map<Element, Set<Node>>();
-  final Map<FunctionElement, FunctionScope> functionScopes =
-      new Map<FunctionElement, FunctionScope>();
-  final Map<LibraryElement, Set<Identifier>> privateNodes =
-      new Map<LibraryElement, Set<Identifier>>();
-  final List<DeclarationTypePlaceholder> declarationTypePlaceholders =
-      new List<DeclarationTypePlaceholder>();
-  final Map<String, Set<Identifier>> memberPlaceholders =
-      new Map<String, Set<Identifier>>();
-  final List<ConstructorPlaceholder> constructorPlaceholders =
-      new List<ConstructorPlaceholder>();
-  Map<String, LocalPlaceholder> currentLocalPlaceholders;
-  Element currentElement;
-  FunctionElement topmostEnclosingFunction;
-  TreeElements treeElements;
-
-  get currentFunctionScope => functionScopes.putIfAbsent(
-      topmostEnclosingFunction, () => new FunctionScope());
-
-  PlaceholderCollector(this.reporter, this.mirrorRenamer, this.fixedMemberNames,
-      this.elementAsts, this.mainFunction);
-
-  void collectFunctionDeclarationPlaceholders(
-      FunctionElement element, FunctionExpression node) {
-    if (element.isConstructor) {
-      ConstructorElement constructor = element;
-      tryMakeConstructorPlaceholder(node.name, element);
-      RedirectingFactoryBody bodyAsRedirectingFactoryBody =
-          node.body.asRedirectingFactoryBody();
-      if (bodyAsRedirectingFactoryBody != null) {
-        // Factory redirection.
-        FunctionElement redirectTarget = constructor.immediateRedirectionTarget;
-        assert(redirectTarget != null && redirectTarget != element);
-        tryMakeConstructorPlaceholder(
-            bodyAsRedirectingFactoryBody.constructorReference, redirectTarget);
-      }
-    } else if (Elements.isStaticOrTopLevel(element)) {
-      // Note: this code should only rename private identifiers for class'
-      // fields/getters/setters/methods.  Top-level identifiers are renamed
-      // just to escape conflicts and that should be enough as we shouldn't
-      // be able to resolve private identifiers for other libraries.
-      makeElementPlaceholder(node.name, element);
-    } else if (element.isClassMember) {
-      if (node.name is Identifier) {
-        tryMakeMemberPlaceholder(node.name);
-      } else {
-        assert(node.name.asSend().isOperator);
-      }
-    }
-  }
-
-  void collectFieldDeclarationPlaceholders(Element element, Node node) {
-    Identifier name = node is Identifier ? node : node.asSend().selector;
-    if (Elements.isStaticOrTopLevel(element)) {
-      makeElementPlaceholder(name, element);
-    } else if (Elements.isInstanceField(element)) {
-      tryMakeMemberPlaceholder(name);
-    }
-  }
-
-  void collect(Element element) {
-    this.currentElement = element;
-    this.topmostEnclosingFunction = null;
-    final ElementAst elementAst = elementAsts[element];
-    this.treeElements = elementAst.treeElements;
-    Node elementNode = elementAst.ast;
-    if (element is FunctionElement) {
-      collectFunctionDeclarationPlaceholders(element, elementNode);
-    } else if (element is VariableElement) {
-      VariableDefinitions definitions = elementNode;
-      Node definition = definitions.definitions.nodes.head;
-      collectFieldDeclarationPlaceholders(element, definition);
-      makeVarDeclarationTypePlaceholder(definitions);
-    } else {
-      assert(element is ClassElement || element is TypedefElement);
-    }
-    currentLocalPlaceholders = new Map<String, LocalPlaceholder>();
-    if (!(element is ConstructorElement && element.isRedirectingFactory)) {
-      // Do not visit the body of redirecting factories.
-      reporter.withCurrentElement(element, () {
-        elementNode.accept(this);
-      });
-    }
-  }
-
-  // TODO(karlklose): should we create placeholders for these?
-  bool isTypedefParameter(Element element) {
-    return element != null &&
-        element.enclosingElement != null &&
-        element.enclosingElement.isTypedef;
-  }
-
-  void tryMakeLocalPlaceholder(Element element, Identifier node) {
-    bool isNamedOptionalParameter() {
-      FunctionTypedElement function = element.enclosingElement;
-      FunctionSignature signature = function.functionSignature;
-      if (!signature.optionalParametersAreNamed) return false;
-      for (Element parameter in signature.optionalParameters) {
-        if (identical(parameter, element)) return true;
-      }
-      return false;
-    }
-    if (element.isParameter &&
-        !isTypedefParameter(element) &&
-        isNamedOptionalParameter()) {
-      currentFunctionScope.registerParameter(node);
-    } else if (Elements.isLocal(element) && !isTypedefParameter(element)) {
-      makeLocalPlaceholder(node);
-    }
-  }
-
-  void tryMakeMemberPlaceholder(Identifier node) {
-    assert(node != null);
-    if (node is Operator) return;
-    String identifier = node.source;
-    if (fixedMemberNames.contains(identifier)) return;
-    memberPlaceholders
-        .putIfAbsent(identifier, () => new Set<Identifier>())
-        .add(node);
-  }
-
-  void makeTypePlaceholder(Node node, DartType type) {
-    Send send = node.asSend();
-    if (send != null) {
-      // Prefix.
-      assert(send.receiver is Identifier);
-      assert(send.selector is Identifier);
-      makeErasePrefixPlaceholder(send.receiver);
-      node = send.selector;
-    }
-    makeElementPlaceholder(node, type.element);
-  }
-
-  void makeTypeVariablePlaceholder(Node node, TypeVariableType type) {
-    Send send = node.asSend();
-    if (send != null) {
-      // Prefix.
-      assert(send.receiver is Identifier);
-      assert(send.selector is Identifier);
-      makeErasePrefixPlaceholder(send.receiver);
-      node = send.selector;
-    }
-    tryMakeMemberPlaceholder(node);
-  }
-
-  void makeOmitDeclarationTypePlaceholder(TypeAnnotation type) {
-    if (type == null) return;
-    declarationTypePlaceholders
-        .add(new DeclarationTypePlaceholder(type, false));
-  }
-
-  void makeVarDeclarationTypePlaceholder(VariableDefinitions node) {
-    // TODO(smok): Maybe instead of calling this method and
-    // makeDeclaratioTypePlaceholder have type declaration placeholder
-    // collector logic in visitVariableDefinitions when resolver becomes better
-    // and/or catch syntax changes.
-    if (node.type == null) return;
-    bool requiresVar = !node.modifiers.isFinalOrConst;
-    declarationTypePlaceholders
-        .add(new DeclarationTypePlaceholder(node.type, requiresVar));
-  }
-
-  /// Marks [node] to be erased in the output.
-  /// This is done for library prefixes because they are not used in the output
-  /// because all imports are flattened and conflicts are renamed away.
-  void makeErasePrefixPlaceholder(Node node) {
-    assert(node is Identifier || node is Send);
-    prefixNodesToErase.add(node);
-  }
-
-  void makeElementPlaceholder(Node node, Element element) {
-    assert(node != null);
-    assert(element != null);
-    LibraryElement library = element.library;
-    if (identical(element, mainFunction)) return;
-    if (library.isDartCore) return;
-
-    if (library.isPlatformLibrary && !element.isTopLevel) {
-      return;
-    }
-
-    ClassElement cls = element.enclosingClass;
-    if (cls != null && cls.isEnumClass) {
-      // Enums and enum values cannot be changed, since the semantics of
-      // `toString` is defined by the names of the declarations.
-      return;
-    }
-
-    if (element.isAccessor) {
-      element = (element as AccessorElement).abstractField;
-    }
-    elementNodes.putIfAbsent(element, () => new Set<Node>()).add(node);
-  }
-
-  /// Marks [node] to be renamed per-library if it names an instance member
-  /// and has a private name.
-  void tryMakePrivateIdentifier(Node node, Element element) {
-    if (node is Identifier &&
-        !Elements.isStaticOrTopLevel(element) &&
-        !Elements.isLocal(element) &&
-        Name.isPrivateName(node.source)) {
-      privateNodes
-          .putIfAbsent(currentElement.library, () => new Set<Identifier>())
-          .add(node);
-    }
-  }
-
-  void makeUnresolvedPlaceholder(Node node) {
-    unresolvedNodes.add(node);
-  }
-
-  void makeLocalPlaceholder(Identifier identifier) {
-    LocalPlaceholder getLocalPlaceholder() {
-      String name = identifier.source;
-      return currentLocalPlaceholders.putIfAbsent(name, () {
-        LocalPlaceholder localPlaceholder = new LocalPlaceholder(name);
-        currentFunctionScope.localPlaceholders.add(localPlaceholder);
-        return localPlaceholder;
-      });
-    }
-    getLocalPlaceholder().nodes.add(identifier);
-  }
-
-  /// Finds the first constructor on the chain of definingConstructor from
-  /// [element] that is not in a synthetic class.
-  Element findDefiningConstructor(ConstructorElement element) {
-    while (element.definingConstructor != null) {
-      element = element.definingConstructor;
-    }
-    return element;
-  }
-
-  void tryMakeConstructorPlaceholder(Node node, ConstructorElement element) {
-    if (Elements.isUnresolved(element)) {
-      makeUnresolvedPlaceholder(node);
-      return;
-    }
-    // A library prefix.
-    Node prefix;
-    // The name of the class with the constructor.
-    Node className;
-    // Will be null for unnamed constructors.
-    Identifier constructorName;
-    // First deconstruct the constructor, there are 4 possibilities:
-    //  ClassName()
-    //  prefix.ClassName()
-    //  ClassName.constructorName()
-    //  prefix.ClassName.constructorName()
-    if (node is Send) {
-      if (node.receiver is Send) {
-        Send receiver = node.receiver;
-        // prefix.ClassName.constructorName()
-        assert(treeElements[receiver.receiver] != null &&
-            treeElements[receiver.receiver].isPrefix);
-        prefix = receiver.receiver;
-        className = receiver.selector;
-        constructorName = node.selector;
-      } else {
-        Element receiverElement = treeElements[node.receiver];
-        if (receiverElement != null && receiverElement.isPrefix) {
-          // prefix.ClassName()
-          prefix = node.receiver;
-          className = node.selector;
-        } else {
-          // ClassName.constructorName()
-          className = node.receiver;
-          constructorName = node.selector;
-        }
-      }
-    } else {
-      // ClassName()
-      className = node;
-    }
-
-    if (prefix != null) {
-      makeErasePrefixPlaceholder(prefix);
-    }
-
-    if (className is TypeAnnotation) {
-      visitTypeAnnotation(className);
-    } else if (Elements.isUnresolved(element)) {
-      // We handle unresolved nodes elsewhere.
-    } else if (className.isThis() || className.isSuper()) {
-      // Do not rename super and this.
-    } else if (className is Identifier) {
-      makeElementPlaceholder(className, element.contextClass);
-    } else {
-      throw "Bad type of constructor name $className";
-    }
-
-    if (constructorName != null) {
-      Element definingConstructor = findDefiningConstructor(element);
-      constructorPlaceholders.add(
-          new ConstructorPlaceholder(constructorName, definingConstructor));
-      tryMakePrivateIdentifier(constructorName, element);
-    }
-  }
-
-  void internalError(String reason, {Node node}) {
-    reporter.internalError(node, reason);
-  }
-
-  visit(Node node) => (node == null) ? null : node.accept(this);
-
-  visitNode(Node node) {
-    node.visitChildren(this);
-  } // We must go deeper.
-
-  visitNewExpression(NewExpression node) {
-    Send send = node.send;
-    DartType type = treeElements.getType(node);
-    assert(type != null);
-    Element constructor = treeElements[send];
-    assert(constructor != null);
-    assert(send.receiver == null);
-    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.
-      // class C {
-      //   final field;
-      //   C([this.field]);
-      // }
-      // Do not forget to rename them as well.
-      FunctionElement constructorFunction = constructor;
-      List<Element> optionalParameters =
-          constructorFunction.functionSignature.optionalParameters;
-      for (final argument in send.argumentsNode) {
-        NamedArgument named = argument.asNamedArgument();
-        if (named == null) continue;
-        Identifier name = named.name;
-        String nameAsString = name.source;
-        for (final parameter in optionalParameters) {
-          if (parameter.isInitializingFormal) {
-            if (parameter.name == nameAsString) {
-              tryMakeMemberPlaceholder(name);
-              break;
-            }
-          }
-        }
-      }
-    } else {
-      makeUnresolvedPlaceholder(node.send.selector);
-    }
-    visit(node.send.argumentsNode);
-  }
-
-  visitSend(Send send) {
-    Element element = treeElements[send];
-    tryMakePrivateIdentifier(send.selector, element);
-    new SendVisitor(this, treeElements).visitSend(send);
-    send.visitChildren(this);
-  }
-
-  visitSendSet(SendSet send) {
-    Element element = treeElements[send];
-    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
-      // that is needed to rename the construct properly.
-      element = treeElements[send.selector];
-    }
-    tryMakePrivateIdentifier(send.selector, element);
-    if (element == null) {
-      if (send.receiver != null) tryMakeMemberPlaceholder(send.selector);
-    } else if (!element.isMalformed) {
-      if (Elements.isStaticOrTopLevel(element)) {
-        // TODO(smok): Worth investigating why sometimes we get getter/setter
-        // here and sometimes abstract field.
-        assert(element.isClass ||
-            element is VariableElement ||
-            element.isAccessor ||
-            element.isAbstractField ||
-            element.isFunction ||
-            element.isTypedef ||
-            element is TypeVariableElement);
-        makeElementPlaceholder(send.selector, element);
-      } else {
-        Identifier identifier = send.selector.asIdentifier();
-        if (identifier == null) {
-          // Handle optional function expression parameters with default values.
-          identifier = send.selector.asFunctionExpression().name;
-        }
-        if (Elements.isInstanceField(element)) {
-          tryMakeMemberPlaceholder(identifier);
-        } else {
-          tryMakeLocalPlaceholder(element, identifier);
-        }
-      }
-    }
-    send.visitChildren(this);
-  }
-
-  visitTypeAnnotation(TypeAnnotation node) {
-    final type = treeElements.getType(node);
-    assert(invariant(node, type != null,
-        message: "Missing type for type annotation: $treeElements"));
-    if (!type.isVoid) {
-      if (!type.treatAsDynamic) {
-        if (type is TypeVariableType) {
-          makeTypeVariablePlaceholder(node.typeName, type);
-        } else {
-          makeTypePlaceholder(node.typeName, type);
-        }
-      } else if (!type.isDynamic) {
-        makeUnresolvedPlaceholder(node.typeName);
-      }
-    }
-    // Visit only type arguments, otherwise in case of lib.Class type
-    // annotation typeName is Send and we go to visitGetterSend, as a result
-    // "Class" is added to member placeholders.
-    visit(node.typeArguments);
-  }
-
-  visitVariableDefinitions(VariableDefinitions node) {
-    // Collect only local placeholders.
-    for (Node definition in node.definitions.nodes) {
-      Element definitionElement = treeElements[definition];
-      // definitionElement may be null if we're inside variable definitions
-      // of a function that is a parameter of another function.
-      // TODO(smok): Fix this when resolver correctly deals with
-      // such cases.
-      if (definitionElement == null) continue;
-
-      Send send = definition.asSend();
-      Identifier identifier = definition is Identifier
-          ? definition
-          : definition is Send
-              ? (send.selector is Identifier ? send.selector : null)
-              : null;
-
-      tryMakePrivateIdentifier(identifier, definitionElement);
-
-      if (send != null) {
-        // May get FunctionExpression here in definition.selector
-        // in case of A(int this.f());
-        if (send.selector is Identifier) {
-          if (definitionElement.isInitializingFormal) {
-            tryMakeMemberPlaceholder(send.selector);
-          } else {
-            tryMakeLocalPlaceholder(definitionElement, send.selector);
-          }
-        } else {
-          assert(send.selector is FunctionExpression);
-          if (definitionElement.isInitializingFormal) {
-            tryMakeMemberPlaceholder(send.selector.asFunctionExpression().name);
-          }
-        }
-      } else if (definition is Identifier) {
-        tryMakeLocalPlaceholder(definitionElement, definition);
-      } else if (definition is FunctionExpression) {
-        // Skip, it will be processed in visitFunctionExpression.
-      } else {
-        internalError('Unexpected definition structure $definition');
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  visitFunctionExpression(FunctionExpression node) {
-    bool isKeyword(Identifier id) =>
-        id != null && Keyword.keywords[id.source] != null;
-
-    Element element = treeElements[node];
-    // May get null;
-    if (element != null) {
-      tryMakePrivateIdentifier(node.name, element);
-
-      // Rename only local functions.
-      if (topmostEnclosingFunction == null &&
-          element is! LocalParameterElement &&
-          element is! InitializingFormalElement) {
-        topmostEnclosingFunction = element;
-      }
-      if (!identical(element, currentElement)) {
-        if (node.name != null) {
-          assert(node.name is Identifier);
-          tryMakeLocalPlaceholder(element, node.name);
-        }
-      }
-    }
-
-    node.visitChildren(this);
-
-    // Make sure we don't omit return type of methods which names are
-    // identifiers, because the following works fine:
-    // int interface() => 1;
-    // But omitting 'int' makes VM unhappy.
-    // TODO(smok): Remove it when http://dartbug.com/5278 is fixed.
-    if (node.name == null || !isKeyword(node.name.asIdentifier())) {
-      makeOmitDeclarationTypePlaceholder(node.returnType);
-    }
-    collectFunctionParameters(node.parameters);
-  }
-
-  void collectFunctionParameters(NodeList parameters) {
-    if (parameters == null) return;
-    for (Node parameter in parameters.nodes) {
-      if (parameter is NodeList) {
-        // Optional parameter list.
-        collectFunctionParameters(parameter);
-      } else {
-        assert(parameter is VariableDefinitions);
-        makeOmitDeclarationTypePlaceholder(
-            parameter.asVariableDefinitions().type);
-      }
-    }
-  }
-
-  visitClassNode(ClassNode node) {
-    ClassElement classElement = currentElement;
-    makeElementPlaceholder(node.name, classElement);
-    node.visitChildren(this);
-  }
-
-  visitNamedMixinApplication(NamedMixinApplication node) {
-    ClassElement classElement = currentElement;
-    makeElementPlaceholder(node.name, classElement);
-    node.visitChildren(this);
-  }
-
-  visitTypeVariable(TypeVariable node) {
-    DartType type = treeElements.getType(node);
-    assert(invariant(node, type != null,
-        message: "Missing type for type variable: $treeElements"));
-    makeTypeVariablePlaceholder(node.name, type);
-    node.visitChildren(this);
-  }
-
-  visitTypedef(Typedef node) {
-    assert(currentElement is TypedefElement);
-    makeElementPlaceholder(node.name, currentElement);
-    node.visitChildren(this);
-    makeOmitDeclarationTypePlaceholder(node.returnType);
-    collectFunctionParameters(node.formals);
-  }
-
-  visitBlock(Block node) {
-    for (Node statement in node.statements.nodes) {
-      if (statement is VariableDefinitions) {
-        makeVarDeclarationTypePlaceholder(statement);
-      }
-    }
-    node.visitChildren(this);
-  }
-}
diff --git a/pkg/compiler/lib/src/dart_backend/renamer.dart b/pkg/compiler/lib/src/dart_backend/renamer.dart
deleted file mode 100644
index 29b26d7..0000000
--- a/pkg/compiler/lib/src/dart_backend/renamer.dart
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart_backend;
-
-Comparator get _compareNodes => compareBy((n) => n.getBeginToken().charOffset);
-
-abstract class Renamable implements Comparable {
-  final int RENAMABLE_TYPE_ELEMENT = 1;
-  final int RENAMABLE_TYPE_MEMBER = 2;
-  final int RENAMABLE_TYPE_LOCAL = 3;
-
-  final Set<Node> nodes;
-
-  Renamable(this.nodes);
-  int compareTo(Renamable other) {
-    int nodesDiff = other.nodes.length.compareTo(this.nodes.length);
-    if (nodesDiff != 0) return nodesDiff;
-    int typeDiff = this.kind.compareTo(other.kind);
-    return typeDiff != 0 ? typeDiff : compareInternals(other);
-  }
-
-  int compareInternals(Renamable other);
-  int get kind;
-
-  String createNewName(PlaceholderRenamer placeholderRenamer);
-}
-
-class GlobalRenamable extends Renamable {
-  final Entity entity;
-
-  GlobalRenamable(this.entity, Set<Node> nodes) : super(nodes);
-
-  int compareInternals(GlobalRenamable other) =>
-      compareElements(this.entity, other.entity);
-  int get kind => RENAMABLE_TYPE_ELEMENT;
-  String createNewName(PlaceholderRenamer placeholderRenamer) {
-    return placeholderRenamer._renameGlobal(entity);
-  }
-}
-
-class MemberRenamable extends Renamable {
-  final String identifier;
-  MemberRenamable(this.identifier, Set<Node> nodes) : super(nodes);
-  int compareInternals(MemberRenamable other) =>
-      this.identifier.compareTo(other.identifier);
-  int get kind => RENAMABLE_TYPE_MEMBER;
-  String createNewName(PlaceholderRenamer placeholderRenamer) {
-    return placeholderRenamer._generateMemberName(identifier);
-  }
-}
-
-class LocalRenamable extends Renamable {
-  LocalRenamable(Set<Node> nodes) : super(nodes);
-  int compareInternals(LocalRenamable other) => _compareNodes(
-      sorted(this.nodes, _compareNodes)[0],
-      sorted(other.nodes, _compareNodes)[0]);
-  int get kind => RENAMABLE_TYPE_LOCAL;
-  String createNewName(PlaceholderRenamer placeholderRenamer) {
-    return placeholderRenamer._generateUniqueTopLevelName("");
-  }
-}
-
-/**
- * Renames only top-level elements that would lead to ambiguity if not renamed.
- */
-class PlaceholderRenamer {
-  /// After running [computeRenames] this will contain the computed renames.
-  final Map<Node, String> renames = new Map<Node, String>();
-
-  /// After running [computeRenames] this will map the used platform
-  /// libraries to their respective prefixes.
-  final Map<LibraryElement, String> platformImports =
-      <LibraryElement, String>{};
-
-  final bool enableMinification;
-  final Set<String> fixedDynamicNames;
-  final Set<String> fixedStaticNames;
-  final Map<Element, LibraryElement> reexportingLibraries;
-  final bool cutDeclarationTypes;
-
-  final Map<Entity, String> _renamedCache = new Map<Entity, String>();
-  final Map<Entity, Map<String, String>> _privateCache =
-      new Map<Entity, Map<String, String>>();
-
-  // Identifiers that has already been used, or are reserved by the
-  // language/platform.
-  Set<String> _forbiddenIdentifiers;
-  Set<String> _allNamedParameterIdentifiers;
-
-  Generator _generator;
-
-  PlaceholderRenamer(
-      this.fixedDynamicNames, this.fixedStaticNames, this.reexportingLibraries,
-      {this.enableMinification, this.cutDeclarationTypes});
-
-  void _renameNodes(Iterable<Node> nodes, String renamer(Node node)) {
-    for (Node node in sorted(nodes, _compareNodes)) {
-      renames[node] = renamer(node);
-    }
-  }
-
-  String _generateUniqueTopLevelName(String originalName) {
-    String newName = _generator.generate(originalName, (name) {
-      return _forbiddenIdentifiers.contains(name) ||
-          _allNamedParameterIdentifiers.contains(name);
-    });
-    _forbiddenIdentifiers.add(newName);
-    return newName;
-  }
-
-  String _generateMemberName(String original) {
-    return _generator.generate(original, _forbiddenIdentifiers.contains);
-  }
-
-  /// Looks up [originalName] in the [_privateCache] cache of [library].
-  /// If [originalName] was not renamed before, generate a new name.
-  String _getPrivateName(LibraryElement library, String originalName) {
-    return _privateCache
-        .putIfAbsent(library, () => new Map<String, String>())
-        .putIfAbsent(
-            originalName, () => _generateUniqueTopLevelName(originalName));
-  }
-
-  String _renameConstructor(ConstructorPlaceholder placeholder) {
-    String name = placeholder.element.name;
-    if (name == '') return "";
-    String result = _renameGlobal(placeholder.element);
-    return result;
-  }
-
-  String _renameGlobal(Entity entity) {
-    assert(entity is! Element ||
-        Elements.isMalformed(entity) ||
-        Elements.isStaticOrTopLevel(entity) ||
-        entity is TypeVariableElement);
-    // TODO(smok): We may want to reuse class static field and method names.
-    if (entity is Element) {
-      LibraryElement library = entity.library;
-      if (reexportingLibraries.containsKey(entity)) {
-        library = reexportingLibraries[entity];
-      }
-      if (library.isPlatformLibrary) {
-        // TODO(johnniwinther): Handle prefixes for dart:core.
-        if (library.canonicalUri == Uris.dart_core) return entity.name;
-        if (library.isInternalLibrary) {
-          throw new SpannableAssertionFailure(
-              entity,
-              "Internal library $library should never have been imported from "
-              "the code compiled by dart2dart.");
-        }
-
-        String prefix = platformImports.putIfAbsent(library, () => null);
-        if (entity.isTopLevel && fixedDynamicNames.contains(entity.name)) {
-          if (prefix == null) {
-            prefix = _generateUniqueTopLevelName('');
-            platformImports[library] = prefix;
-          }
-          return '$prefix.${entity.name}';
-        }
-        return entity.name;
-      }
-    }
-    String name = _renamedCache.putIfAbsent(
-        entity, () => _generateUniqueTopLevelName(entity.name));
-    // Look up in [_renamedCache] for a name for [entity] .
-    // If it was not renamed before, generate a new name.
-    return name;
-  }
-
-  void _computeMinifiedRenames(PlaceholderCollector placeholderCollector) {
-    _generator = new MinifyingGenerator();
-
-    // Build a list sorted by usage of local nodes that will be renamed to
-    // the same identifier. So the top-used local variables in all functions
-    // will be renamed first and will all share the same new identifier.
-    int maxLength = placeholderCollector.functionScopes.values
-        .fold(0, (a, b) => max(a, b.localPlaceholders.length));
-
-    List<Set<Node>> allLocals =
-        new List<Set<Node>>.generate(maxLength, (_) => new Set<Node>());
-
-    for (FunctionScope functionScope
-        in placeholderCollector.functionScopes.values) {
-      // Add current sorted local identifiers to the whole sorted list
-      // of all local identifiers for all functions.
-      List<LocalPlaceholder> currentSortedPlaceholders = sorted(
-          functionScope.localPlaceholders,
-          compareBy((LocalPlaceholder ph) => -ph.nodes.length));
-
-      List<Set<Node>> currentSortedNodes = currentSortedPlaceholders
-          .map((LocalPlaceholder ph) => ph.nodes)
-          .toList();
-
-      for (int i = 0; i < currentSortedNodes.length; i++) {
-        allLocals[i].addAll(currentSortedNodes[i]);
-      }
-    }
-
-    // Rename elements, members and locals together based on their usage
-    // count, otherwise when we rename elements first there will be no good
-    // identifiers left for members even if they are used often.
-    List<Renamable> renamables = new List<Renamable>();
-    placeholderCollector.elementNodes
-        .forEach((Element element, Set<Node> nodes) {
-      renamables.add(new GlobalRenamable(element, nodes));
-    });
-    placeholderCollector.memberPlaceholders
-        .forEach((String memberName, Set<Identifier> identifiers) {
-      renamables.add(new MemberRenamable(memberName, identifiers));
-    });
-    for (Set<Node> localIdentifiers in allLocals) {
-      renamables.add(new LocalRenamable(localIdentifiers));
-    }
-    renamables.sort();
-    for (Renamable renamable in renamables) {
-      String newName = renamable.createNewName(this);
-      _renameNodes(renamable.nodes, (_) => newName);
-    }
-  }
-
-  void _computeNonMinifiedRenames(PlaceholderCollector placeholderCollector) {
-    _generator = new ConservativeGenerator();
-    // Rename elements.
-    placeholderCollector.elementNodes
-        .forEach((Element element, Set<Node> nodes) {
-      _renameNodes(nodes, (_) => _renameGlobal(element));
-    });
-
-    // Rename locals.
-    placeholderCollector.functionScopes
-        .forEach((functionElement, functionScope) {
-      Set<String> memberIdentifiers = new Set<String>();
-      Set<LocalPlaceholder> placeholders = functionScope.localPlaceholders;
-      if (functionElement != null && functionElement.enclosingClass != null) {
-        functionElement.enclosingClass.forEachMember((enclosingClass, member) {
-          memberIdentifiers.add(member.name);
-        });
-      }
-      Set<String> usedLocalIdentifiers = new Set<String>();
-      for (LocalPlaceholder placeholder in placeholders) {
-        String nextId = _generator.generate(placeholder.identifier, (name) {
-          return functionScope.parameterIdentifiers.contains(name) ||
-              _forbiddenIdentifiers.contains(name) ||
-              usedLocalIdentifiers.contains(name) ||
-              memberIdentifiers.contains(name);
-        });
-        usedLocalIdentifiers.add(nextId);
-        _renameNodes(placeholder.nodes, (_) => nextId);
-      }
-    });
-
-    // Do not rename members to top-levels, that allows to avoid renaming
-    // members to constructors.
-    placeholderCollector.memberPlaceholders.forEach((identifier, nodes) {
-      String newIdentifier = _generateMemberName(identifier);
-      _renameNodes(nodes, (_) => newIdentifier);
-    });
-  }
-
-  /// Finds renamings for all the placeholders in [placeholderCollector] and
-  /// stores them in [renames].
-  /// Also adds to [platformImports] all the platform-libraries that are used.
-  void computeRenames(PlaceholderCollector placeholderCollector) {
-    _allNamedParameterIdentifiers = new Set<String>();
-    for (FunctionScope functionScope
-        in placeholderCollector.functionScopes.values) {
-      _allNamedParameterIdentifiers.addAll(functionScope.parameterIdentifiers);
-    }
-
-    _forbiddenIdentifiers = new Set<String>.from(fixedDynamicNames);
-    _forbiddenIdentifiers.addAll(fixedStaticNames);
-    _forbiddenIdentifiers.addAll(Keyword.keywords.keys);
-    _forbiddenIdentifiers.add('main');
-
-    if (enableMinification) {
-      _computeMinifiedRenames(placeholderCollector);
-    } else {
-      _computeNonMinifiedRenames(placeholderCollector);
-    }
-
-    // Rename constructors.
-    for (ConstructorPlaceholder placeholder
-        in placeholderCollector.constructorPlaceholders) {
-      renames[placeholder.node] = _renameConstructor(placeholder);
-    }
-    ;
-
-    // Rename private identifiers uniquely for each library.
-    placeholderCollector.privateNodes
-        .forEach((LibraryElement library, Set<Identifier> identifiers) {
-      for (Identifier identifier in identifiers) {
-        renames[identifier] = _getPrivateName(library, identifier.source);
-      }
-    });
-
-    // Rename unresolved nodes, to make sure they still do not resolve.
-    for (Node node in placeholderCollector.unresolvedNodes) {
-      renames[node] = _generateUniqueTopLevelName('Unresolved');
-    }
-
-    // Erase prefixes that are now not needed.
-    for (Node node in placeholderCollector.prefixNodesToErase) {
-      renames[node] = '';
-    }
-
-    if (cutDeclarationTypes) {
-      for (DeclarationTypePlaceholder placeholder
-          in placeholderCollector.declarationTypePlaceholders) {
-        renames[placeholder.typeNode] = placeholder.requiresVar ? 'var' : '';
-      }
-    }
-  }
-}
-
-/**
- * Generates mini ID based on index.
- * In other words, it converts index to visual representation
- * as if digits are given characters.
- */
-String generateMiniId(int index) {
-  const String firstCharAlphabet =
-      r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-  const String otherCharsAlphabet =
-      r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$';
-  // It's like converting index in decimal to [chars] radix.
-  if (index < firstCharAlphabet.length) return firstCharAlphabet[index];
-  StringBuffer resultBuilder = new StringBuffer();
-  resultBuilder.writeCharCode(
-      firstCharAlphabet.codeUnitAt(index % firstCharAlphabet.length));
-  index ~/= firstCharAlphabet.length;
-  int length = otherCharsAlphabet.length;
-  while (index >= length) {
-    resultBuilder.writeCharCode(otherCharsAlphabet.codeUnitAt(index % length));
-    index ~/= length;
-  }
-  resultBuilder.write(otherCharsAlphabet[index]);
-  return resultBuilder.toString();
-}
-
-abstract class Generator {
-  String generate(String originalName, bool isForbidden(String name));
-}
-
-/// Always tries to return original identifier name unless it is forbidden.
-class ConservativeGenerator implements Generator {
-  String generate(String originalName, bool isForbidden(String name)) {
-    String result = originalName;
-    int index = 0;
-    while (isForbidden(result)) {
-      //|| result == originalName) {
-      result = '${originalName}_${generateMiniId(index++)}';
-    }
-    return result;
-  }
-}
-
-/// Always tries to generate the most compact identifier.
-class MinifyingGenerator implements Generator {
-  int index = 0;
-
-  MinifyingGenerator();
-
-  String generate(String originalName, bool isForbidden(String name)) {
-    String result;
-    do {
-      result = generateMiniId(index++);
-    } while (isForbidden(result));
-    return result;
-  }
-}
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index fb0eac4..271d09f 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -10,7 +10,7 @@
 import 'common.dart';
 import 'core_types.dart';
 import 'elements/elements.dart';
-import 'elements/modelx.dart' show TypeDeclarationElementX, ErroneousElementX;
+import 'elements/modelx.dart' show TypeDeclarationElementX;
 import 'ordered_typeset.dart' show OrderedTypeSet;
 import 'util/util.dart' show equalElements;
 
@@ -298,6 +298,8 @@
   }
 
   String toString() => name;
+
+  int get hashCode => 6007;
 }
 
 class MalformedType extends DartType {
@@ -323,8 +325,8 @@
    */
   final List<DartType> typeArguments;
 
-  final int hashCode = (nextHash++) & 0x3fffffff;
-  static int nextHash = 43765;
+  final int hashCode = _nextHash = (_nextHash + 1).toUnsigned(30);
+  static int _nextHash = 43765;
 
   MalformedType(this.element, this.userProvidedBadType,
       [this.typeArguments = null]);
@@ -845,6 +847,10 @@
   void computeUnaliased(Resolution resolution) {
     if (_unaliased == null) {
       element.ensureResolved(resolution);
+      if (element.isMalformed) {
+        _unaliased = const DynamicType();
+        return;
+      }
       element.checkCyclicReference(resolution);
       element.alias.computeUnaliased(resolution);
       _unaliased = element.alias.unaliased.substByContext(this);
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 0f4f8d7..723bd9f 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -8,8 +8,7 @@
 import 'common/tasks.dart' show CompilerTask;
 import 'common.dart';
 import 'compiler.dart' show Compiler;
-import 'constants/expressions.dart'
-    show ConstantExpression, ConstantExpressionKind;
+import 'constants/expressions.dart' show ConstantExpression;
 import 'constants/values.dart'
     show
         ConstantValue,
@@ -36,7 +35,6 @@
 import 'resolution/resolution.dart' show AnalyzableElementX;
 import 'resolution/tree_elements.dart' show TreeElements;
 import 'tree/tree.dart' as ast;
-import 'tree/tree.dart' show Import, Node;
 import 'universe/use.dart' show StaticUse, TypeUse, TypeUseKind;
 import 'universe/world_impact.dart'
     show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
@@ -93,8 +91,7 @@
   /// DeferredLibrary from dart:async
   ClassElement get deferredLibraryClass => compiler.deferredLibraryClass;
 
-  /// A synthetic [Import] representing the loading of the main
-  /// program.
+  /// A synthetic import representing the loading of the main program.
   final _DeferredImport _fakeMainImport = const _DeferredImport();
 
   /// The OutputUnit that will be loaded when the program starts.
@@ -182,12 +179,22 @@
     return _elementToOutputUnit[element];
   }
 
+  /// Direct access to the output-unit to element relation used for testing.
+  OutputUnit getOutputUnitForElementForTesting(Element element) {
+    return _elementToOutputUnit[element];
+  }
+
   /// Returns the [OutputUnit] where [constant] belongs.
   OutputUnit outputUnitForConstant(ConstantValue constant) {
     if (!isProgramSplit) return mainOutputUnit;
     return _constantToOutputUnit[constant];
   }
 
+  /// Direct access to the output-unit to constants map used for testing.
+  Map<ConstantValue, OutputUnit> get outputUnitForConstantsForTesting {
+    return _constantToOutputUnit;
+  }
+
   bool isDeferred(Element element) {
     return outputUnitForElement(element) != mainOutputUnit;
   }
@@ -235,7 +242,7 @@
     return imports.every((ImportElement import) => import.isDeferred);
   }
 
-  /// Returns a [Link] of every [Import] that imports [element] into [library].
+  /// Returns every [ImportElement] that imports [element] into [library].
   Iterable<ImportElement> _getImports(Element element, LibraryElement library) {
     if (element.isClassMember) {
       element = element.enclosingClass;
@@ -347,10 +354,10 @@
         // implicit constant expression are seen that we should be able to add
         // (like primitive constant literals like `true`, `"foo"` and `0`).
         // See dartbug.com/26406 for context.
-        treeElements
-            .forEachConstantNode((Node node, ConstantExpression expression) {
+        treeElements.forEachConstantNode(
+            (ast.Node node, ConstantExpression expression) {
           if (compiler.serialization.isDeserialized(analyzableElement)) {
-            if (!expression.isImplicit && !expression.isPotential) {
+            if (!expression.isPotential) {
               // Enforce evaluation of [expression].
               backend.constants.getConstantValue(expression);
             }
@@ -397,6 +404,7 @@
         elements.add(element);
         collectDependencies(element);
       }
+
       ClassElement cls = element.declaration;
       cls.forEachLocalMember(addLiveInstanceMember);
       if (cls.implementation != cls) {
@@ -453,6 +461,7 @@
         iterateTags(library.implementation);
       }
     }
+
     traverseLibrary(root);
     result.add(compiler.coreLibrary);
     return result;
@@ -865,6 +874,7 @@
         }
       }
     }
+
     ast.Node first = firstNode(send);
     ast.Node identifier = first.asIdentifier();
     if (identifier == null) return null;
@@ -928,7 +938,8 @@
 
     StringBuffer sb = new StringBuffer();
     for (OutputUnit outputUnit in allOutputUnits) {
-      sb.write(outputUnit.name);
+      sb.write('\n-------------------------------\n');
+      sb.write('Output unit: ${outputUnit.name}');
       List<String> elements = elementMap[outputUnit];
       if (elements != null) {
         sb.write('\n elements:');
@@ -978,6 +989,10 @@
 
   /// Computes a suggestive name for this import.
   String computeImportDeferName(Compiler compiler) => 'main';
+
+  ImportElement get declaration => null;
+
+  String toString() => 'main';
 }
 
 /// A node in the deferred import graph defined by a deferred import directive.
@@ -1024,4 +1039,6 @@
   }
 
   int get hashCode => declaration.hashCode * 17;
+
+  String toString() => '$declaration';
 }
diff --git a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
index 0a9c5f5..e12c09c 100644
--- a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
+++ b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
@@ -4,11 +4,11 @@
 
 library dart2js.diagnostic_listener;
 
+import '../elements/elements.dart' show Element;
 import '../options.dart' show DiagnosticOptions;
+import 'messages.dart';
 import 'source_span.dart' show SourceSpan;
 import 'spannable.dart' show Spannable;
-import '../elements/elements.dart' show Element;
-import 'messages.dart';
 
 // TODO(johnniwinther): Rename and cleanup this interface. Add severity enum.
 abstract class DiagnosticReporter {
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index dbcab63..e1715744 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -63,12 +63,10 @@
 library dart2js.messages;
 
 import '../tokens/token.dart' show ErrorToken, Token;
-
+import 'generated/shared_messages.dart' as shared_messages;
 import 'invariant.dart' show invariant;
 import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
 
-import 'generated/shared_messages.dart' as shared_messages;
-
 const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
 
 /// Keys for the [MessageTemplate]s.
@@ -100,7 +98,6 @@
   BEFORE_TOP_LEVEL,
   BINARY_OPERATOR_BAD_ARITY,
   BODY_EXPECTED,
-  CALL_NOT_SUPPORTED_ON_NATIVE_CLASS,
   CANNOT_EXTEND,
   CANNOT_EXTEND_ENUM,
   CANNOT_EXTEND_MALFORMED,
@@ -186,9 +183,11 @@
   DUPLICATED_RESOURCE,
   EMPTY_CATCH_DECLARATION,
   EMPTY_ENUM_DECLARATION,
+  EMPTY_NAMED_PARAMETER_LIST,
+  EMPTY_OPTIONAL_PARAMETER_LIST,
   EMPTY_HIDE,
-  EQUAL_MAP_ENTRY_KEY,
   EMPTY_SHOW,
+  EQUAL_MAP_ENTRY_KEY,
   EXISTING_DEFINITION,
   EXISTING_LABEL,
   EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
@@ -610,7 +609,9 @@
           "Cannot resolve '#{name}'.",
           howToFix: "Did you mean to add the 'async' marker "
               "to the enclosing function?",
-          examples: const ["main() { (() => await -3)(); }",]),
+          examples: const [
+            "main() { (() => await -3)(); }",
+          ]),
 
       MessageKind.CANNOT_RESOLVE_IN_INITIALIZER: const MessageTemplate(
           MessageKind.CANNOT_RESOLVE_IN_INITIALIZER,
@@ -878,6 +879,36 @@
             },
           ]),
 
+      MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST: const MessageTemplate(
+          MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST,
+          "Optional parameter lists cannot be empty.",
+          howToFix: "Try adding an optional parameter to the list.",
+          examples: const [
+            const {
+              'main.dart': """
+foo([]) {}
+
+main() {
+  foo();
+}"""
+            }
+          ]),
+
+      MessageKind.EMPTY_NAMED_PARAMETER_LIST: const MessageTemplate(
+          MessageKind.EMPTY_NAMED_PARAMETER_LIST,
+          "Named parameter lists cannot be empty.",
+          howToFix: "Try adding a named parameter to the list.",
+          examples: const [
+            const {
+              'main.dart': """
+foo({}) {}
+
+main() {
+  foo();
+}"""
+            }
+          ]),
+
       MessageKind.NOT_A_TYPE: const MessageTemplate(
           MessageKind.NOT_A_TYPE, "'#{node}' is not a type."),
 
@@ -1967,7 +1998,9 @@
           "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);}",]),
+          examples: const [
+            "class A {} main() { print(A ??= 3);}",
+          ]),
 
       MessageKind.VOID_NOT_ALLOWED: const MessageTemplate(
           MessageKind.VOID_NOT_ALLOWED,
@@ -3056,7 +3089,11 @@
           MessageKind.UNMATCHED_TOKEN,
           "Can't find '#{end}' to match '#{begin}'.",
           howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["main(", "main(){", "main(){]}",]),
+          examples: const [
+            "main(",
+            "main(){",
+            "main(){]}",
+          ]),
 
       MessageKind.UNTERMINATED_TOKEN: const MessageTemplate(
           MessageKind.UNTERMINATED_TOKEN,
@@ -3180,7 +3217,8 @@
       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. */
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          /* Don't state the obvious. */
           examples: const ['main(a, b, c) {}']),
 
       MessageKind.COMPILER_CRASHED: const MessageTemplate(
@@ -3595,15 +3633,18 @@
       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 [
             """
+import 'package:js/js.dart';
+@JS()
 external foo() => 0;
 main() => foo();
 """,
             """
+import 'package:js/js.dart';
+@JS()
 external foo() {}
 main() => foo();
 """
@@ -3671,11 +3712,6 @@
           """
 $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 "
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index a8c39fa..93f1312 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -16,7 +16,6 @@
 import 'deferred_load.dart' show OutputUnit;
 import 'elements/elements.dart';
 import 'elements/visitor.dart';
-import 'info/send_info.dart' show collectSendMeasurements;
 import 'js/js.dart' as jsAst;
 import 'js_backend/js_backend.dart' show JavaScriptBackend;
 import 'js_emitter/full_emitter/emitter.dart' as full show Emitter;
@@ -313,9 +312,6 @@
     }
     info.closures = nestedClosures;
     result.functions.add(info);
-    if (const bool.fromEnvironment('send_stats')) {
-      info.measurements = collectSendMeasurements(element, compiler);
-    }
     return info;
   }
 
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index 5ff8341..2e99eff 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -10,7 +10,6 @@
 import '../core_types.dart' show CoreClasses;
 import '../dart_types.dart' show DartType, InterfaceType, FunctionType;
 import '../util/util.dart' show Link;
-
 import 'elements.dart';
 
 abstract class ElementCommon implements Element {
@@ -67,7 +66,7 @@
   bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD;
 
   @override
-  bool get isParameter => kind == ElementKind.PARAMETER;
+  bool get isRegularParameter => kind == ElementKind.PARAMETER;
 
   @override
   bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
@@ -183,19 +182,9 @@
       return path.substring(path.lastIndexOf('/') + 1);
     }
   }
-
-  int compareTo(LibraryElement other) {
-    if (this == other) return 0;
-    return libraryOrScriptName.compareTo(other.libraryOrScriptName);
-  }
 }
 
-abstract class CompilationUnitElementCommon implements CompilationUnitElement {
-  int compareTo(CompilationUnitElement other) {
-    if (this == other) return 0;
-    return '${script.readableUri}'.compareTo('${other.script.readableUri}');
-  }
-}
+abstract class CompilationUnitElementCommon implements CompilationUnitElement {}
 
 abstract class ClassElementCommon implements ClassElement {
   @override
@@ -590,8 +579,8 @@
     constructors.forEach(f);
     if (mixin != null)
       mixin.forEachLocalMember((Element mixedInElement) {
-      if (mixedInElement.isInstanceMember) f(mixedInElement);
-    });
+        if (mixedInElement.isInstanceMember) f(mixedInElement);
+      });
   }
 }
 
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 52f5f30..e80ea6b 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -11,16 +11,15 @@
 import '../constants/expressions.dart';
 import '../core_types.dart' show CoreClasses;
 import '../dart_types.dart';
+import '../ordered_typeset.dart' show OrderedTypeSet;
 import '../resolution/scope.dart' show Scope;
 import '../resolution/tree_elements.dart' show TreeElements;
-import '../ordered_typeset.dart' show OrderedTypeSet;
 import '../script.dart';
 import '../tokens/token.dart'
     show Token, isUserDefinableOperator, isMinusOperator;
 import '../tree/tree.dart';
 import '../util/characters.dart' show $_;
 import '../util/util.dart';
-
 import 'visitor.dart' show ElementVisitor;
 
 part 'names.dart';
@@ -254,18 +253,22 @@
   /// explicit getter and/or setter.
   bool get isAbstractField;
 
-  /// `true` if this element is formal parameter either from a constructor,
-  /// method, or typedef declaration or from an inlined function typed
+  /// `true` if this element is a formal parameter from a constructor,
+  /// a method, a typedef declaration, or from an inlined function typed
   /// parameter.
   ///
   /// This property is `false` if this element is an initializing formal.
   /// See [isInitializingFormal].
-  bool get isParameter;
+  bool get isRegularParameter;
 
   /// `true` if this element is an initializing formal of constructor, that
   /// is a formal of the form `this.foo`.
   bool get isInitializingFormal;
 
+  /// `true` if this element is a formal parameter, either regular or
+  /// initializing.
+  bool get isParameter => isRegularParameter || isInitializingFormal;
+
   /// `true` if this element represents a resolution error.
   bool get isError;
 
@@ -590,45 +593,45 @@
   static String operatorNameToIdentifier(String name) {
     if (name == null) {
       return name;
-    } else if (identical(name, '==')) {
+    } else if (name == '==') {
       return r'operator$eq';
-    } else if (identical(name, '~')) {
+    } else if (name == '~') {
       return r'operator$not';
-    } else if (identical(name, '[]')) {
+    } else if (name == '[]') {
       return r'operator$index';
-    } else if (identical(name, '[]=')) {
+    } else if (name == '[]=') {
       return r'operator$indexSet';
-    } else if (identical(name, '*')) {
+    } else if (name == '*') {
       return r'operator$mul';
-    } else if (identical(name, '/')) {
+    } else if (name == '/') {
       return r'operator$div';
-    } else if (identical(name, '%')) {
+    } else if (name == '%') {
       return r'operator$mod';
-    } else if (identical(name, '~/')) {
+    } else if (name == '~/') {
       return r'operator$tdiv';
-    } else if (identical(name, '+')) {
+    } else if (name == '+') {
       return r'operator$add';
-    } else if (identical(name, '<<')) {
+    } else if (name == '<<') {
       return r'operator$shl';
-    } else if (identical(name, '>>')) {
+    } else if (name == '>>') {
       return r'operator$shr';
-    } else if (identical(name, '>=')) {
+    } else if (name == '>=') {
       return r'operator$ge';
-    } else if (identical(name, '>')) {
+    } else if (name == '>') {
       return r'operator$gt';
-    } else if (identical(name, '<=')) {
+    } else if (name == '<=') {
       return r'operator$le';
-    } else if (identical(name, '<')) {
+    } else if (name == '<') {
       return r'operator$lt';
-    } else if (identical(name, '&')) {
+    } else if (name == '&') {
       return r'operator$and';
-    } else if (identical(name, '^')) {
+    } else if (name == '^') {
       return r'operator$xor';
-    } else if (identical(name, '|')) {
+    } else if (name == '|') {
       return r'operator$or';
-    } else if (identical(name, '-')) {
+    } else if (name == '-') {
       return r'operator$sub';
-    } else if (identical(name, 'unary-')) {
+    } else if (name == 'unary-') {
       return r'operator$negate';
     } else {
       return name;
@@ -690,9 +693,9 @@
   /// on the source code order.
   static int compareByPosition(Element a, Element b) {
     if (identical(a, b)) return 0;
-    int r = a.library.compareTo(b.library);
+    int r = _compareLibraries(a.library, b.library);
     if (r != 0) return r;
-    r = a.compilationUnit.compareTo(b.compilationUnit);
+    r = _compareCompilationUnits(a.compilationUnit, b.compilationUnit);
     if (r != 0) return r;
     int offsetA = a.sourceOffset ?? -1;
     int offsetB = b.sourceOffset ?? -1;
@@ -705,6 +708,62 @@
     return a.hashCode.compareTo(b.hashCode);
   }
 
+  // Somewhat stable ordering for [LibraryElement]s
+  static int _compareLibraries(LibraryElement a, LibraryElement b) {
+    if (a == b) return 0;
+
+    int byCanonicalUriPath() {
+      return a.canonicalUri.path.compareTo(b.canonicalUri.path);
+    }
+
+    // Order: platform < package < other.
+    if (a.isPlatformLibrary) {
+      if (b.isPlatformLibrary) return byCanonicalUriPath();
+      return -1;
+    }
+    if (b.isPlatformLibrary) return 1;
+
+    if (a.isPackageLibrary) {
+      if (b.isPackageLibrary) return byCanonicalUriPath();
+      return -1;
+    }
+    if (b.isPackageLibrary) return 1;
+
+    return _compareCanonicalUri(a.canonicalUri, b.canonicalUri);
+  }
+
+  static int _compareCanonicalUri(Uri a, Uri b) {
+    int r = a.scheme.compareTo(b.scheme);
+    if (r != 0) return r;
+
+    // We would like the order of 'file:' Uris to be stable across different
+    // users or different builds from temporary directories.  We sort by
+    // pathSegments elements from the last to the first since that tends to find
+    // a stable distinction regardless of directory root.
+    List<String> aSegments = a.pathSegments;
+    List<String> bSegments = b.pathSegments;
+    int aI = aSegments.length;
+    int bI = bSegments.length;
+    while (aI > 0 && bI > 0) {
+      String aSegment = aSegments[--aI];
+      String bSegment = bSegments[--bI];
+      r = aSegment.compareTo(bSegment);
+      if (r != 0) return r;
+    }
+    return aI.compareTo(bI); // Shortest first.
+  }
+
+  static int _compareCompilationUnits(
+      CompilationUnitElement a, CompilationUnitElement b) {
+    if (a == b) return 0;
+    // Compilation units are compared only within the same library so we expect
+    // the Uris to usually be clustered together with a common scheme and path
+    // prefix.
+    Uri aUri = a.script.readableUri;
+    Uri bUri = b.script.readableUri;
+    return '${aUri}'.compareTo('${bUri}');
+  }
+
   static List<Element> sortedByPosition(Iterable<Element> elements) {
     return elements.toList()..sort(compareByPosition);
   }
@@ -838,8 +897,6 @@
   Script get script;
 
   void forEachLocalMember(f(Element element));
-
-  int compareTo(CompilationUnitElement other);
 }
 
 abstract class ImportElement extends Element {
@@ -928,14 +985,14 @@
   /// Note: the returned filename is still escaped ("a%20b.dart" instead of
   /// "a b.dart").
   String get libraryOrScriptName;
-
-  int compareTo(LibraryElement other);
 }
 
 /// The implicit scope defined by a import declaration with a prefix clause.
 abstract class PrefixElement extends Element {
   Element lookupLocalMember(String memberName);
 
+  void forEachLocalMember(void f(Element member));
+
   /// Is true if this prefix belongs to a deferred import.
   bool get isDeferred;
 
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index bb331d9..4eb76bb 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -15,9 +15,9 @@
 import '../diagnostics/messages.dart' show MessageTemplate;
 import '../ordered_typeset.dart' show OrderedTypeSet;
 import '../resolution/class_members.dart' show ClassMemberMixin;
+import '../resolution/resolution.dart' show AnalyzableElementX;
 import '../resolution/scope.dart'
     show ClassScope, LibraryScope, Scope, TypeDeclarationScope;
-import '../resolution/resolution.dart' show AnalyzableElementX;
 import '../resolution/tree_elements.dart' show TreeElements;
 import '../resolution/typedefs.dart' show TypedefCyclicVisitor;
 import '../script.dart';
@@ -25,7 +25,6 @@
 import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
 import '../tree/tree.dart';
 import '../util/util.dart';
-
 import 'common.dart';
 import 'elements.dart';
 import 'visitor.dart' show ElementVisitor;
@@ -39,12 +38,14 @@
 abstract class DeclarationSite {}
 
 abstract class ElementX extends Element with ElementCommon {
-  static int elementHashCode = 0;
+  static int _elementHashCode = 0;
+  static int newHashCode() =>
+      _elementHashCode = (_elementHashCode + 1).toUnsigned(30);
 
   final String name;
   final ElementKind kind;
   final Element enclosingElement;
-  final int hashCode = ++elementHashCode;
+  final int hashCode = newHashCode();
   List<MetadataAnnotation> metadataInternal;
 
   ElementX(this.name, this.kind, this.enclosingElement) {
@@ -398,8 +399,18 @@
   }
 
   @override
-  set immediateRedirectionTarget(_) {
-    throw new UnsupportedError("immediateRedirectionTarget=");
+  get _immediateRedirectionTarget {
+    throw new UnsupportedError("_immediateRedirectionTarget");
+  }
+
+  @override
+  set _immediateRedirectionTarget(_) {
+    throw new UnsupportedError("_immediateRedirectionTarget=");
+  }
+
+  @override
+  setImmediateRedirectionTarget(a, b) {
+    throw new UnsupportedError("setImmediateRedirectionTarget");
   }
 
   @override
@@ -428,8 +439,13 @@
   }
 
   @override
-  set redirectionDeferredPrefix(_) {
-    throw new UnsupportedError("redirectionDeferredPrefix=");
+  get _redirectionDeferredPrefix {
+    throw new UnsupportedError("_redirectionDeferredPrefix");
+  }
+
+  @override
+  set _redirectionDeferredPrefix(_) {
+    throw new UnsupportedError("_redirectionDeferredPrefix=");
   }
 }
 
@@ -437,7 +453,7 @@
 class WrappedMessage {
   /// The message position. If [:null:] the position of the reference to the
   /// [WarnOnUseElementX] is used.
-  final Spannable spannable;
+  final SourceSpan sourceSpan;
 
   /**
    * The message to report on resolving a wrapped element.
@@ -449,7 +465,7 @@
    */
   final Map messageArguments;
 
-  WrappedMessage(this.spannable, this.messageKind, this.messageArguments);
+  WrappedMessage(this.sourceSpan, this.messageKind, this.messageArguments);
 }
 
 class WarnOnUseElementX extends ElementX implements WarnOnUseElement {
@@ -462,21 +478,21 @@
   /// The element whose usage cause a warning.
   final Element wrappedElement;
 
-  WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info,
-      Element enclosingElement, Element wrappedElement)
+  WarnOnUseElementX(
+      this.warning, this.info, Element enclosingElement, Element wrappedElement)
       : this.wrappedElement = wrappedElement,
         super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement);
 
   Element unwrap(DiagnosticReporter reporter, Spannable usageSpannable) {
     var unwrapped = wrappedElement;
     if (warning != null) {
-      Spannable spannable = warning.spannable;
+      Spannable spannable = warning.sourceSpan;
       if (spannable == null) spannable = usageSpannable;
       DiagnosticMessage warningMessage = reporter.createMessage(
           spannable, warning.messageKind, warning.messageArguments);
       List<DiagnosticMessage> infos = <DiagnosticMessage>[];
       if (info != null) {
-        Spannable spannable = info.spannable;
+        Spannable spannable = info.sourceSpan;
         if (spannable == null) spannable = usageSpannable;
         infos.add(reporter.createMessage(
             spannable, info.messageKind, info.messageArguments));
@@ -930,8 +946,11 @@
 }
 
 class SyntheticImportElement extends ImportElementX {
-  SyntheticImportElement(CompilationUnitElement enclosingElement, Uri uri)
-      : super(enclosingElement, null, uri);
+  SyntheticImportElement(CompilationUnitElement enclosingElement, Uri uri,
+      LibraryElement libraryDependency)
+      : super(enclosingElement, null, uri) {
+    this.libraryDependency = libraryDependency;
+  }
 
   @override
   Token get position => library.position;
@@ -1177,6 +1196,7 @@
           f(element);
         }
       }
+
       localMembers.forEach(filterPatch);
     } else {
       localMembers.forEach(f);
@@ -1247,6 +1267,8 @@
 
   Element lookupLocalMember(String memberName) => importScope[memberName];
 
+  void forEachLocalMember(f(Element member)) => importScope.forEach(f);
+
   DartType computeType(Resolution resolution) => const DynamicType();
 
   Token get position => firstPosition;
@@ -1451,6 +1473,7 @@
   final Token token;
   final VariableList variables;
   VariableDefinitions definitionsCache;
+  Expression definitionCache;
   Expression initializerCache;
 
   Modifiers get modifiers => variables.modifiers;
@@ -1483,6 +1506,16 @@
     return definitionsCache;
   }
 
+  /// Returns the node that defines this field.
+  ///
+  /// For instance in `var a, b = true`, the definitions nodes for fields 'a'
+  /// and 'b' are the nodes for `a` and `b = true`, respectively.
+  Expression get definition {
+    assert(invariant(this, definitionCache != null,
+        message: "Definition node has not been computed for $this."));
+    return definitionCache;
+  }
+
   Expression get initializer {
     assert(invariant(this, definitionsCache != null,
         message: "Initializer has not been computed for $this."));
@@ -1500,8 +1533,6 @@
   void createDefinitions(VariableDefinitions definitions) {
     assert(invariant(this, definitionsCache == null,
         message: "VariableDefinitions has already been computed for $this."));
-    Expression node;
-    int count = 0;
     for (Link<Node> link = definitions.definitions.nodes;
         !link.isEmpty;
         link = link.tail) {
@@ -1511,28 +1542,16 @@
         SendSet sendSet = initializedIdentifier.asSendSet();
         identifier = sendSet.selector.asIdentifier();
         if (identical(name, identifier.source)) {
-          node = initializedIdentifier;
+          definitionCache = initializedIdentifier;
           initializerCache = sendSet.arguments.first;
         }
       } else if (identical(name, identifier.source)) {
-        node = initializedIdentifier;
+        definitionCache = initializedIdentifier;
       }
-      count++;
     }
-    invariant(definitions, node != null, message: "Could not find '$name'.");
-    if (count == 1) {
-      definitionsCache = definitions;
-    } else {
-      // Create a [VariableDefinitions] node for the single definition of
-      // [node].
-      definitionsCache = new VariableDefinitions(
-          definitions.type,
-          definitions.modifiers,
-          new NodeList(
-              definitions.definitions.beginToken,
-              const Link<Node>().prepend(node),
-              definitions.definitions.endToken));
-    }
+    invariant(definitions, definitionCache != null,
+        message: "Could not find '$name'.");
+    definitionsCache = definitions;
   }
 
   DartType computeType(Resolution resolution) {
@@ -1637,6 +1656,14 @@
 
   Token get token => node.getBeginToken();
 
+  get definitionCache {
+    throw new UnsupportedError("definitionCache");
+  }
+
+  set definitionCache(_) {
+    throw new UnsupportedError("definitionCache=");
+  }
+
   get initializerCache {
     throw new UnsupportedError("initializerCache");
   }
@@ -1651,6 +1678,8 @@
 
   get initializer => null;
 
+  get definition => null;
+
   bool get isMalformed => true;
 
   get nestedClosures {
@@ -2197,8 +2226,10 @@
       String name, ElementKind kind, Modifiers modifiers, Element enclosing)
       : super(name, kind, modifiers, enclosing);
 
-  FunctionElement immediateRedirectionTarget;
-  PrefixElement redirectionDeferredPrefix;
+  ConstructorElement _immediateRedirectionTarget;
+  PrefixElement _redirectionDeferredPrefix;
+
+  ConstructorElementX get patch => super.patch;
 
   bool get isRedirectingFactory => immediateRedirectionTarget != null;
 
@@ -2211,45 +2242,93 @@
   DartType _effectiveTargetType;
   bool _isEffectiveTargetMalformed;
 
-  bool get hasEffectiveTarget => effectiveTargetInternal != null;
+  bool get hasEffectiveTarget {
+    if (isPatched) {
+      return patch.hasEffectiveTarget;
+    }
+    return effectiveTargetInternal != null;
+  }
+
+  void setImmediateRedirectionTarget(
+      ConstructorElement target, PrefixElement prefix) {
+    if (isPatched) {
+      patch.setImmediateRedirectionTarget(target, prefix);
+    } else {
+      assert(invariant(this, _immediateRedirectionTarget == null,
+          message: "Immediate redirection target has already been "
+              "set on $this."));
+      _immediateRedirectionTarget = target;
+      _redirectionDeferredPrefix = prefix;
+    }
+  }
+
+  ConstructorElement get immediateRedirectionTarget {
+    if (isPatched) {
+      return patch.immediateRedirectionTarget;
+    }
+    return _immediateRedirectionTarget;
+  }
+
+  PrefixElement get redirectionDeferredPrefix {
+    if (isPatched) {
+      return patch.redirectionDeferredPrefix;
+    }
+    return _redirectionDeferredPrefix;
+  }
 
   void setEffectiveTarget(ConstructorElement target, 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;
+    if (isPatched) {
+      patch.setEffectiveTarget(target, type, isMalformed: isMalformed);
+    } else {
+      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.'));
+      assert(invariant(this, !target.isMalformed || isMalformed,
+          message: 'Effective target is not marked as malformed for $this: '
+              'target=$target, type=$type, isMalformed: $isMalformed'));
+      assert(invariant(this, isMalformed || type.isInterfaceType,
+          message: 'Effective target type is not an interface type for $this: '
+              'target=$target, type=$type, isMalformed: $isMalformed'));
+      effectiveTargetInternal = target;
+      _effectiveTargetType = type;
+      _isEffectiveTargetMalformed = isMalformed;
+    }
   }
 
   ConstructorElement get effectiveTarget {
-    if (Elements.isMalformed(immediateRedirectionTarget)) {
-      return immediateRedirectionTarget;
-    }
-    assert(!isRedirectingFactory || effectiveTargetInternal != null);
-    if (isRedirectingFactory) {
-      return effectiveTargetInternal;
-    }
     if (isPatched) {
-      return effectiveTargetInternal ?? this;
+      return patch.effectiveTarget;
+    }
+    if (isRedirectingFactory) {
+      assert(effectiveTargetInternal != null);
+      return effectiveTargetInternal;
     }
     return this;
   }
 
-  InterfaceType get effectiveTargetType {
+  DartType get effectiveTargetType {
+    if (isPatched) {
+      return patch.effectiveTargetType;
+    }
     assert(invariant(this, _effectiveTargetType != null,
         message: 'Effective target type has not yet been computed for $this.'));
     return _effectiveTargetType;
   }
 
-  InterfaceType computeEffectiveTargetType(InterfaceType newType) {
+  DartType computeEffectiveTargetType(InterfaceType newType) {
+    if (isPatched) {
+      return patch.computeEffectiveTargetType(newType);
+    }
     if (!isRedirectingFactory) return newType;
     return effectiveTargetType.substByContext(newType);
   }
 
   bool get isEffectiveTargetMalformed {
+    if (isPatched) {
+      return patch.isEffectiveTargetMalformed;
+    }
     if (!isRedirectingFactory) return false;
     assert(invariant(this, _isEffectiveTargetMalformed != null,
         message: 'Malformedness has not yet been computed for $this.'));
@@ -2944,6 +3023,7 @@
     definitionsCache = new VariableDefinitions(
         null, variableList.modifiers, new NodeList.singleton(definition));
     initializerCache = initializer;
+    definitionCache = definition;
   }
 
   @override
@@ -3121,6 +3201,8 @@
   bool isBreakTarget = false;
   bool isContinueTarget = false;
 
+  final int hashCode = ElementX.newHashCode();
+
   JumpTargetX(this.statement, this.nestingLevel, this.executableContext);
 
   String get name => "target";
@@ -3220,6 +3302,8 @@
 
   Token get endToken;
 
+  final int hashCode = ElementX.newHashCode();
+
   MetadataAnnotationX([this.resolutionState = STATE_NOT_STARTED]);
 
   MetadataAnnotation ensureResolved(Resolution resolution) {
diff --git a/pkg/compiler/lib/src/elements/visitor.dart b/pkg/compiler/lib/src/elements/visitor.dart
index 2a1c917..0779288 100644
--- a/pkg/compiler/lib/src/elements/visitor.dart
+++ b/pkg/compiler/lib/src/elements/visitor.dart
@@ -4,9 +4,9 @@
 
 library visitor;
 
-import 'elements.dart';
 import '../closure.dart'
     show BoxFieldElement, ClosureClassElement, ClosureFieldElement;
+import 'elements.dart';
 
 abstract class ElementVisitor<R, A> {
   const ElementVisitor();
diff --git a/pkg/compiler/lib/src/hash/sha1.dart b/pkg/compiler/lib/src/hash/sha1.dart
index 8e5eec2..56ae8b9 100644
--- a/pkg/compiler/lib/src/hash/sha1.dart
+++ b/pkg/compiler/lib/src/hash/sha1.dart
@@ -8,8 +8,8 @@
  */
 library sha1;
 
-import 'dart:math' show pow;
 import 'dart:convert';
+import 'dart:math' show pow;
 
 import '../io/code_output.dart' show CodeOutputListener;
 
diff --git a/pkg/compiler/lib/src/helpers/debug_collection.dart b/pkg/compiler/lib/src/helpers/debug_collection.dart
index c0276cf..751b8c8 100644
--- a/pkg/compiler/lib/src/helpers/debug_collection.dart
+++ b/pkg/compiler/lib/src/helpers/debug_collection.dart
@@ -131,12 +131,16 @@
   E singleWhere(bool test(E element)) => iterable.singleWhere(test);
 
   E elementAt(int index) => iterable.elementAt(index);
+
+  String toString() => iterable.toString();
 }
 
 class DebugList<E> extends DebugIterable<E> implements List<E> {
   DebugCallback addCallback;
+  DebugCallback addAllCallback;
 
-  DebugList(List<E> list, {this.addCallback}) : super(list);
+  DebugList(List<E> list, {this.addCallback, this.addAllCallback})
+      : super(list);
 
   List<E> get list => iterable;
 
@@ -159,7 +163,12 @@
     list.add(value);
   }
 
-  void addAll(Iterable<E> iterable) => list.addAll(iterable);
+  void addAll(Iterable<E> iterable) {
+    if (addAllCallback != null) {
+      addAllCallback('addAll', iterable, null);
+    }
+    list.addAll(iterable);
+  }
 
   Iterable<E> get reversed => list.reversed;
 
diff --git a/pkg/compiler/lib/src/helpers/helpers.dart b/pkg/compiler/lib/src/helpers/helpers.dart
index 6c4cc63..14a7887 100644
--- a/pkg/compiler/lib/src/helpers/helpers.dart
+++ b/pkg/compiler/lib/src/helpers/helpers.dart
@@ -10,14 +10,13 @@
 import '../common.dart';
 import '../diagnostics/invariant.dart' show DEBUG_MODE;
 import '../util/util.dart';
-
 import 'trace.dart';
 
 export 'debug_collection.dart';
-export 'trace.dart';
 export 'expensive_map.dart';
 export 'expensive_set.dart';
 export 'stats.dart';
+export 'trace.dart';
 export 'track_map.dart';
 
 /// Global flag to enable [debugPrint]. This should always be `true` by default
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index ed2d198..80b7e3d 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -4,13 +4,13 @@
 
 library compiler.src.inferrer.closure_tracer;
 
-import '../types/types.dart' show TypeMask;
 import '../common/names.dart' show Names;
 import '../elements/elements.dart';
+import '../types/types.dart' show TypeMask;
 import '../universe/selector.dart' show Selector;
+import 'debug.dart' as debug;
 import 'node_tracer.dart';
 import 'type_graph_nodes.dart';
-import 'debug.dart' as debug;
 
 class ClosureTracerVisitor extends TracerVisitor<ApplyableTypeInformation> {
   final Iterable<FunctionElement> tracedElements;
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 65e7439..2e554e5 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -16,8 +16,8 @@
 import '../resolution/semantic_visitor.dart';
 import '../resolution/tree_elements.dart' show TreeElements;
 import '../tree/tree.dart';
-import '../types/types.dart' show TypeMask;
 import '../types/constants.dart' show computeTypeMask;
+import '../types/types.dart' show TypeMask;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
 import '../util/util.dart';
@@ -314,10 +314,6 @@
 
   bool hasNoArguments() => positional.isEmpty && named.isEmpty;
 
-  bool hasOnePositionalArgumentThatMatches(bool f(T type)) {
-    return named.isEmpty && positional.length == 1 && f(positional[0]);
-  }
-
   void forEach(void f(T type)) {
     positional.forEach(f);
     named.values.forEach(f);
@@ -472,6 +468,7 @@
         inferrer.recordLocalUpdate(local, type);
       }
     }
+
     if (capturedAndBoxed.containsKey(local)) {
       inferrer.recordTypeOfNonFinalField(node, capturedAndBoxed[local], type);
     } else if (inTryBlock) {
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index 83f2e8b..d0985e0 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -7,7 +7,6 @@
 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';
 
diff --git a/pkg/compiler/lib/src/inferrer/map_tracer.dart b/pkg/compiler/lib/src/inferrer/map_tracer.dart
index 3bd0e41..22a9f0f 100644
--- a/pkg/compiler/lib/src/inferrer/map_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/map_tracer.dart
@@ -6,7 +6,6 @@
 
 import '../elements/elements.dart';
 import '../universe/selector.dart' show Selector;
-
 import 'node_tracer.dart';
 import 'type_graph_nodes.dart';
 
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index c50929d..cc890bf 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -9,10 +9,9 @@
 import '../elements/elements.dart';
 import '../types/types.dart' show ContainerTypeMask, MapTypeMask;
 import '../util/util.dart' show Setlet;
-
+import 'debug.dart' as debug;
 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.
@@ -333,7 +332,7 @@
    * [isAddedToContainer].
    */
   bool isParameterOfListAddingMethod(Element element) {
-    if (!element.isParameter) return false;
+    if (!element.isRegularParameter) return false;
     if (element.enclosingClass != compiler.backend.listImplementation) {
       return false;
     }
@@ -349,7 +348,7 @@
    * [isValueAddedToMap] and [isKeyAddedToMap].
    */
   bool isParameterOfMapAddingMethod(Element element) {
-    if (!element.isParameter) return false;
+    if (!element.isRegularParameter) return false;
     if (element.enclosingClass != compiler.backend.mapImplementation) {
       return false;
     }
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index c2956ff..0a6c628 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -10,7 +10,6 @@
 import '../compiler.dart' show Compiler;
 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 DartType;
 import '../elements/elements.dart';
 import '../js_backend/js_backend.dart' as js;
@@ -259,10 +258,6 @@
   // TODO(johnniwinther): Pass the [ResolvedAst] instead of [owner].
   void updateSelectorInTree(
       AstElement owner, Spannable node, Selector selector, TypeMask mask) {
-    if (node is cps_ir.Node) {
-      // TODO(lry): update selector for IrInvokeDynamic.
-      throw "updateSelector for IR node $node";
-    }
     ast.Node astNode = node;
     TreeElements elements = owner.resolvedAst.elements;
     if (astNode.asSendSet() != null) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index 3e68725..8024e52 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -4,10 +4,11 @@
 library dart2js.inferrer.type_graph_dump;
 
 import 'dart:async';
-import 'type_graph_nodes.dart';
-import 'type_graph_inferrer.dart';
+
 import '../elements/elements.dart';
 import '../types/types.dart';
+import 'type_graph_inferrer.dart';
+import 'type_graph_nodes.dart';
 
 /// Dumps the type inference graph in Graphviz Dot format into the `typegraph`
 /// subfolder of the current working directory. Each function body is dumped in
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index f8ae6ea..d610c54 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -15,8 +15,8 @@
 import '../elements/elements.dart';
 import '../js_backend/js_backend.dart' show Annotations, JavaScriptBackend;
 import '../resolution/tree_elements.dart' show TreeElementMapping;
-import '../tree/tree.dart' as ast
-    show DartString, Node, LiteralBool, TryStatement;
+import '../tree/dartstring.dart' show DartString;
+import '../tree/tree.dart' as ast show Node, LiteralBool, TryStatement;
 import '../types/constants.dart' show computeTypeMask;
 import '../types/types.dart'
     show ContainerTypeMask, MapTypeMask, TypeMask, TypesInferrer;
@@ -227,7 +227,7 @@
 
   TypeInformation nonNullEmptyType;
 
-  TypeInformation stringLiteralType(ast.DartString value) {
+  TypeInformation stringLiteralType(DartString value) {
     return new StringLiteralTypeInformation(
         value, compiler.typesTask.stringType);
   }
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 3b0127a..0c3fb31 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -10,11 +10,10 @@
 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, TypeKind;
 import '../elements/elements.dart';
-import '../native/native.dart' as native;
-import '../tree/tree.dart' as ast show DartString, Node, LiteralBool, Send;
+import '../tree/dartstring.dart' show DartString;
+import '../tree/tree.dart' as ast show Node, LiteralBool, Send;
 import '../types/types.dart'
     show
         ContainerTypeMask,
@@ -88,9 +87,9 @@
   /// change.
   bool isStable = false;
 
-  // TypeInformations are unique.
-  static int staticHashCode = 0;
-  final int hashCode = staticHashCode++;
+  // TypeInformations are unique. Store an arbitrary identity hash code.
+  static int _staticHashCode = 0;
+  final int hashCode = _staticHashCode = (_staticHashCode + 1).toUnsigned(30);
 
   bool get isConcrete => false;
 
@@ -344,7 +343,7 @@
   bool disableInferenceForClosures = true;
 
   factory ElementTypeInformation(Element element, TypeInformationSystem types) {
-    if (element.isParameter || element.isInitializingFormal) {
+    if (element.isRegularParameter || element.isInitializingFormal) {
       ParameterElement parameter = element;
       if (parameter.functionDeclaration.isInstanceMember) {
         return new ParameterTypeInformation._instanceMember(element, types);
@@ -390,9 +389,8 @@
    * This map contains the callers of [element]. It stores all unique call sites
    * to enable counting the global number of call sites of [element].
    *
-   * A call site is either an AST [ast.Node], a [cps_ir.Node] or in the case of
-   * synthesized calls, an [Element] (see uses of [synthesizeForwardingCall]
-   * in [SimpleTypeInferrerVisitor]).
+   * A call site is either an AST [ast.Node], an [Element] (see uses of
+   * [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]).
    *
    * The global information is summarized in [cleanup], after which [_callers]
    * is set to `null`.
@@ -403,7 +401,7 @@
       : super._internal(null, element);
 
   void addCall(Element caller, Spannable node) {
-    assert(node is ast.Node || node is cps_ir.Node || node is Element);
+    assert(node is ast.Node || node is Element);
     _callers ??= <Element, Setlet>{};
     _callers.putIfAbsent(caller, () => new Setlet()).add(node);
   }
@@ -601,7 +599,7 @@
   bool isTearOffClosureParameter = false;
 
   void tagAsTearOffClosureParameter(TypeGraphInferrerEngine inferrer) {
-    assert(element.isParameter);
+    assert(element.isRegularParameter);
     isTearOffClosureParameter = true;
     // We have to add a flow-edge for the default value (if it exists), as we
     // might not see all call-sites and thus miss the use of it.
@@ -856,10 +854,13 @@
   }
 
   /**
-   * We optimize certain operations on the [int] class because we know
-   * more about their return type than the actual Dart code. For
-   * example, we know int + int returns an int. The Dart code for
-   * [int.operator+] only says it returns a [num].
+   * We optimize certain operations on the [int] class because we know more
+   * about their return type than the actual Dart code. For example, we know int
+   * + int returns an int. The Dart library code for [int.operator+] only says
+   * it returns a [num].
+   *
+   * Returns the more precise TypeInformation, or `null` to defer to the library
+   * code.
    */
   TypeInformation handleIntrisifiedSelector(
       Selector selector, TypeMask mask, TypeGraphInferrerEngine inferrer) {
@@ -879,67 +880,84 @@
     bool isUInt31(info) {
       return info.type.satisfies(uint31Implementation, classWorld);
     }
+
     bool isPositiveInt(info) {
       return info.type
           .satisfies(classWorld.backend.positiveIntImplementation, classWorld);
     }
 
+    TypeInformation tryLater() => inferrer.types.nonNullEmptyType;
+
+    TypeInformation argument =
+        arguments.isEmpty ? null : arguments.positional.first;
+
     String name = selector.name;
-    // We are optimizing for the cases that are not expressed in the
-    // Dart code, for example:
-    // int + int -> int
-    // uint31 | uint31 -> uint31
-    if (name == '*' ||
-        name == '+' ||
-        name == '%' ||
-        name == 'remainder' ||
-        name == '~/') {
-      if (isPositiveInt(receiver) &&
-          arguments.hasOnePositionalArgumentThatMatches(isPositiveInt)) {
-        // uint31 + uint31 -> uint32
-        if (name == '+' &&
-            isUInt31(receiver) &&
-            arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
-          return inferrer.types.uint32Type;
-        } else {
+    // These are type inference rules only for useful cases that are not
+    // expressed in the library code, for example:
+    //
+    //     int + int        ->  int
+    //     uint31 | uint31  ->  uint31
+    //
+    switch (name) {
+      case '*':
+      case '+':
+      case '%':
+      case 'remainder':
+      case '~/':
+        if (isEmpty(argument)) return tryLater();
+        if (isPositiveInt(receiver) && isPositiveInt(argument)) {
+          // uint31 + uint31 -> uint32
+          if (name == '+' && isUInt31(receiver) && isUInt31(argument)) {
+            return inferrer.types.uint32Type;
+          }
           return inferrer.types.positiveIntType;
         }
-      } else if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
-        return inferrer.types.intType;
-      } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
-        return inferrer.types.nonNullEmptyType;
-      } else {
+        if (isInt(argument)) {
+          return inferrer.types.intType;
+        }
         return null;
-      }
-    } else if (name == '|' || name == '^') {
-      if (isUInt31(receiver) &&
-          arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
-        return inferrer.types.uint31Type;
-      }
-    } else if (name == '>>') {
-      if (isUInt31(receiver)) {
-        return inferrer.types.uint31Type;
-      }
-    } else if (name == '&') {
-      if (isUInt31(receiver) ||
-          arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
-        return inferrer.types.uint31Type;
-      }
-    } else if (name == 'unary-') {
-      // The receiver being an int, the return value will also be an
-      // int.
-      return inferrer.types.intType;
-    } else if (name == '-') {
-      if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
+
+      case '|':
+      case '^':
+        if (isEmpty(argument)) return tryLater();
+        if (isUInt31(receiver) && isUInt31(argument)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '>>':
+        if (isEmpty(argument)) return tryLater();
+        if (isUInt31(receiver)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '&':
+        if (isEmpty(argument)) return tryLater();
+        if (isUInt31(receiver) || isUInt31(argument)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '-':
+        if (isEmpty(argument)) return tryLater();
+        if (isInt(argument)) {
+          return inferrer.types.intType;
+        }
+        return null;
+
+      case 'unary-':
+        // The receiver being an int, the return value will also be an int.
         return inferrer.types.intType;
-      } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
-        return inferrer.types.nonNullEmptyType;
-      }
-      return null;
-    } else if (name == 'abs') {
-      return arguments.hasNoArguments() ? inferrer.types.positiveIntType : null;
+
+      case 'abs':
+        return arguments.hasNoArguments()
+            ? inferrer.types.positiveIntType
+            : null;
+
+      default:
+        return null;
     }
-    return null;
   }
 
   TypeMask computeType(TypeGraphInferrerEngine inferrer) {
@@ -1191,7 +1209,7 @@
 }
 
 class StringLiteralTypeInformation extends ConcreteTypeInformation {
-  final ast.DartString value;
+  final DartString value;
 
   StringLiteralTypeInformation(value, TypeMask mask)
       : super(new ValueTypeMask(mask, new StringConstantValue(value))),
diff --git a/pkg/compiler/lib/src/info/analysis_result.dart b/pkg/compiler/lib/src/info/analysis_result.dart
deleted file mode 100644
index 5266a01..0000000
--- a/pkg/compiler/lib/src/info/analysis_result.dart
+++ /dev/null
@@ -1,73 +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.
-
-/// API to get results from a static analysis of the source program.
-library compiler.src.stats.analysis_result;
-
-import '../tree/tree.dart' show Node;
-import '../universe/selector.dart' show Selector;
-
-/// A three-value logic bool (yes, no, maybe). We say that `yes` and `maybe` are
-/// "truthy", while `no` and `maybe` are "falsy".
-// TODO(sigmund): is it worth using an enum? or switch to true/false/null?
-enum Boolish { yes, no, maybe }
-
-/// Specifies results of some kind of static analysis on a source program.
-abstract class AnalysisResult {
-  /// Information computed about a specific [receiver].
-  ReceiverInfo infoForReceiver(Node receiver);
-
-  /// Information computed about a specific [selector] applied to a specific
-  /// [receiver].
-  SelectorInfo infoForSelector(Node receiver, Selector selector);
-}
-
-/// Analysis information about a receiver of a send.
-abstract class ReceiverInfo {
-  /// Receiver node for which this information is computed.
-  Node get receiver;
-
-  /// Return whether [receiver] resolves to a value that implements no such
-  /// method. The answer is `yes` if all values that [receiver] could evaluate
-  /// to at runtime contain it, or `no` if none of them does. Maybe if it
-  /// depends on some context or we can't determine this information precisely.
-  Boolish get hasNoSuchMethod;
-
-  /// When [hasNoSuchMethod] is yes, the precise number of possible noSuchMethod
-  /// handlers for this receiver.
-  int get possibleNsmTargets;
-
-  /// Return whether [receiver] may ever be null.
-  Boolish get isNull;
-}
-
-/// Information about a specific selector applied to a specific receiver.
-abstract class SelectorInfo {
-  /// Receiver node of the [selector].
-  Node get receiver;
-
-  /// Specific selector on [receiver] for which this information is computed.
-  Selector get selector;
-
-  /// Whether a member matching [selector] exists in [receiver].
-  Boolish get exists;
-
-  /// Whether [receiver] needs an interceptor to implement [selector].
-  Boolish get usesInterceptor;
-
-  /// Possible total number of methods that could be the target of the selector.
-  /// This needs to be combined with [isAccurate] to correctly understand the
-  /// value. Some invariants:
-  ///
-  ///   * If [exists] is `no`, the value here should be 0, regardless of
-  ///   accuracy.
-  ///   * If [exists] is `yes`, the value is always considered 1 or more.
-  ///     If [isAccurate] is false, we treat it as there may be many possible
-  ///     targets.
-  ///   * If [exists] is `maybe`, the value is considered 0 or more.
-  int get possibleTargets;
-
-  /// Whether the information about [possibleTargets] is accurate.
-  bool get isAccurate;
-}
diff --git a/pkg/compiler/lib/src/info/naive_analysis_result.dart b/pkg/compiler/lib/src/info/naive_analysis_result.dart
deleted file mode 100644
index d18dc91..0000000
--- a/pkg/compiler/lib/src/info/naive_analysis_result.dart
+++ /dev/null
@@ -1,44 +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.
-
-/// API to get results from a static analysis of the source program.
-// TODO(sigmund): split out implementations out of this file.
-library compiler.src.stats.naive_analysis_result;
-
-import 'analysis_result.dart';
-import '../tree/tree.dart' show Node;
-import '../universe/selector.dart' show Selector;
-
-/// A naive [AnalysisResult] that tells us very little. This is the most
-/// conservative we can be when we only use information from the AST structure
-/// and from resolution, but no type information.
-class NaiveAnalysisResult implements AnalysisResult {
-  NaiveAnalysisResult();
-
-  ReceiverInfo infoForReceiver(Node receiver) =>
-      new NaiveReceiverInfo(receiver);
-  SelectorInfo infoForSelector(Node receiver, Selector selector) =>
-      new NaiveSelectorInfo(receiver, selector);
-}
-
-class NaiveReceiverInfo implements ReceiverInfo {
-  final Node receiver;
-
-  NaiveReceiverInfo(this.receiver);
-  Boolish get hasNoSuchMethod => Boolish.maybe;
-  Boolish get isNull => Boolish.maybe;
-  int get possibleNsmTargets => -1;
-}
-
-class NaiveSelectorInfo implements SelectorInfo {
-  final Node receiver;
-  final Selector selector;
-
-  NaiveSelectorInfo(this.receiver, this.selector);
-
-  Boolish get exists => Boolish.maybe;
-  Boolish get usesInterceptor => Boolish.maybe;
-  int get possibleTargets => -1;
-  bool get isAccurate => false;
-}
diff --git a/pkg/compiler/lib/src/info/send_info.dart b/pkg/compiler/lib/src/info/send_info.dart
deleted file mode 100644
index 86f3845..0000000
--- a/pkg/compiler/lib/src/info/send_info.dart
+++ /dev/null
@@ -1,2415 +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.
-
-/// Computes measurements about sends in a function.
-library compiler.src.info.send_info;
-
-import 'package:dart2js_info/src/measurements.dart';
-import 'package:dart2js_info/src/util.dart' show recursiveDiagnosticString;
-
-import '../closure.dart';
-import '../common.dart';
-import '../compiler.dart' show Compiler;
-import '../constants/expressions.dart';
-import '../dart_types.dart';
-import '../elements/elements.dart';
-import '../elements/visitor.dart' show ElementVisitor;
-import '../parser/partial_elements.dart' show PartialElement;
-import '../resolution/operators.dart';
-import '../resolution/semantic_visitor.dart';
-import '../resolution/tree_elements.dart';
-import '../tree/tree.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show Selector;
-import 'analysis_result.dart';
-import 'naive_analysis_result.dart';
-import 'trusted_types_analysis_result.dart';
-
-/// Collects a set of [Measurements] about send expressions in the function [f].
-// TODO(sigmund): collect information on initializers too.
-Measurements collectSendMeasurements(FunctionElement f, Compiler compiler) {
-  DiagnosticReporter reporter = compiler.reporter;
-  return reporter.withCurrentElement(f, () {
-    // TODO(sigmund): enable for platform too.
-    if (f.library.isPlatformLibrary) return null;
-    if (!f.hasNode) {
-      if (f is PartialElement) return const Measurements.unreachableFunction();
-      assert(f is ConstructorElement && f.isSynthesized);
-      // TODO(sigmund): measure synthethic forwarding sends, measure
-      // initializers
-      return new Measurements.reachableFunction();
-    }
-    if (!f.hasResolvedAst) {
-      _debug('no resolved ast ${f.runtimeType}');
-      return null;
-    }
-    var resolvedAst = f.resolvedAst;
-    if (resolvedAst.node == null) {
-      _debug('no node ${f.runtimeType}');
-      return null;
-    }
-    var def = resolvedAst.elements.getFunctionDefinition(resolvedAst.node);
-    if (def == null) {
-      assert(f is PartialElement);
-      return const Measurements.unreachableFunction();
-    }
-
-    var visitor = new _StatsTraversalVisitor(compiler, resolvedAst.elements,
-        reporter.spanFromSpannable(resolvedAst.node).uri);
-    resolvedAst.node.accept(visitor);
-    return visitor.measurements;
-  });
-}
-
-/// Visitor that categorizes data about an individual send.
-class _StatsVisitor<T> extends Visitor
-    with SemanticSendResolvedMixin<dynamic, T>
-    implements SemanticSendVisitor<dynamic, T> {
-  // TODO(sigmund): consider passing in several AnalysisResults at once, so we
-  // can compute the different metrics together.
-  /// Information we know about the program from static analysis.
-  final AnalysisResult info;
-
-  /// Results from this function.
-  final Measurements measurements;
-
-  final DiagnosticReporter reporter;
-  final TreeElements elements;
-
-  SemanticSendVisitor<dynamic, T> get sendVisitor => this;
-
-  _StatsVisitor(this.reporter, this.elements, this.info, Uri sourceUri)
-      : measurements = new Measurements.reachableFunction(sourceUri);
-
-  visitNode(Node node) => throw "unhandled ${node.runtimeType}: $node";
-  apply(Node node, T arg) => throw "missing apply ${node.runtimeType}: $node";
-  internalError(Node node, String arg) => throw "internal error on $node";
-
-  visitSend(Send node) {
-    _checkInvariant(node, 'before');
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.send, span.begin, span.end);
-    if (node is SendSet) {
-      if ((node.assignmentOperator != null &&
-              node.assignmentOperator.source != '=') ||
-          node.isPrefix ||
-          node.isPostfix) {
-        assert(!node.isIfNullAssignment);
-        // We count get and set separately in case one of them is defined by the
-        // other could be a nSM error.
-        measurements.record(Metric.send, span.begin, span.end);
-        measurements.record(Metric.send, span.begin, span.end);
-      } else if (node.isIfNullAssignment) {
-        measurements.record(Metric.send, span.begin, span.end);
-      }
-    }
-    super.visitSend(node);
-    _checkInvariant(node, 'after ');
-  }
-
-  visitNewExpression(NewExpression node) {
-    _checkInvariant(node, 'before');
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.send, span.begin, span.end);
-    super.visitNewExpression(node);
-    _checkInvariant(node, 'after ');
-  }
-
-  /// A monomorphic local variable read.
-  ///
-  /// See [Metric.send] for a full categorization of sends.
-  handleLocal(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.localSend, span.begin, span.end);
-  }
-
-  /// A monomorphic virual call on [node], where we know which function is the
-  /// target of the call (for example, because only one type in a class
-  /// hierarchy implements a function with a given name).
-  ///
-  /// See [Metric.send] for a full categorization of sends.
-  handleSingleInstance(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.instanceSend, span.begin, span.end);
-  }
-
-  /// A monomorphic call that goes through an interceptor. This is equivalent in
-  /// terms of what the compiler knows as we do with [handleSignleInstance], and
-  /// because we know the target of the call, we also know that it doesn't live
-  /// in the object instance, but on an interceptor on the side.
-  ///
-  /// See [Metric.send] for a full categorization of sends.
-  handleSingleInterceptor(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.interceptorSend, span.begin, span.end);
-  }
-
-  /// A polymorphic call that goes through an interceptor.
-  ///
-  /// See [Metric.send] for a full categorization of sends.
-  handleMultiInterceptor(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.polymorphicSend, span.begin, span.end);
-    measurements.record(Metric.multiInterceptorSend, span.begin, span.end);
-  }
-
-  handleConstructor(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.constructorSend, span.begin, span.end);
-  }
-
-  handleDynamic(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.polymorphicSend, span.begin, span.end);
-    measurements.record(Metric.dynamicSend, span.begin, span.end);
-  }
-
-  handleVirtual(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.polymorphicSend, span.begin, span.end);
-    measurements.record(Metric.virtualSend, span.begin, span.end);
-  }
-
-  handleNSMError(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.nsmErrorSend, span.begin, span.end);
-  }
-
-  handleNSMSingle(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.singleNsmCallSend, span.begin, span.end);
-  }
-
-  handleNSMSuper(Node node, ClassElement type) {
-    var superclass = type.superclass;
-    var member = superclass.lookupMember('noSuchMethod');
-    if (!member.enclosingClass.isObject) {
-      handleNSMSingle(node);
-    } else {
-      handleNSMError(node);
-    }
-  }
-
-  handleNSMAny(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.polymorphicSend, span.begin, span.end);
-    measurements.record(Metric.multiNsmCallSend, span.begin, span.end);
-  }
-
-  handleSuper(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.superSend, span.begin, span.end);
-  }
-
-  handleTypeVariable(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.typeVariableSend, span.begin, span.end);
-  }
-
-  handleStatic(Node node) {
-    var span = reporter.spanFromSpannable(node);
-    measurements.record(Metric.monomorphicSend, span.begin, span.end);
-    measurements.record(Metric.staticSend, span.begin, span.end);
-  }
-
-  handleNoSend(Node node) {
-    measurements.popLast(Metric.send);
-  }
-
-  void handleDynamicProperty(Node node, Node receiver, Selector selector) {
-    // staticSend: no (automatically)
-    // superSend: no (automatically)
-    // localSend: no (automatically)
-    // constructorSend: no (automatically)
-    // typeVariableSend: no (automatically)
-
-    // nsmErrorSend:      receiver has no `selector` nor nSM.
-    // singleNsmCallSend: receiver has no `selector`, but definitely has `nSM`
-    // instanceSend:      receiver has `selector`, no need to use an interceptor
-    // interceptorSend:   receiver has `selector`, but we know we need an
-    //                    interceptor to get it
-
-    // multiNsmCallSend:  receiver has no `selector`, not sure if receiver has
-    //                    nSM, or not sure which nSM is called (does this one
-    //                    matter, or does nSM is treated like an instance method
-    //                    call)?
-    // virtualSend:       receiver has `selector`, we know we do not need an
-    //                    interceptor, not sure which specific type implements
-    //                    the selector.
-    // multiInterceptorSend: multiple possible receiver types, all using an
-    //                       interceptor to get the `selector`, might be
-    //                       possbile to pick a special selector logic for this
-    //                       combination?
-    // dynamicSend: any combination of the above.
-
-    ReceiverInfo receiverInfo = info.infoForReceiver(receiver);
-    SelectorInfo selectorInfo = info.infoForSelector(receiver, selector);
-    Boolish hasSelector = selectorInfo.exists;
-    Boolish hasNsm = receiverInfo.hasNoSuchMethod;
-
-    if (hasSelector == Boolish.no) {
-      if (hasNsm == Boolish.no) {
-        handleNSMError(node);
-      } else if (hasNsm == Boolish.yes) {
-        if (receiverInfo.possibleNsmTargets == 1) {
-          handleNSMSingle(node);
-        } else {
-          handleNSMAny(node);
-        }
-      } else {
-        handleDynamic(node);
-      }
-      return;
-    }
-
-    Boolish usesInterceptor = selectorInfo.usesInterceptor;
-    if (hasSelector == Boolish.yes) {
-      if (selectorInfo.isAccurate && selectorInfo.possibleTargets == 1) {
-        assert(usesInterceptor != Boolish.maybe);
-        if (usesInterceptor == Boolish.yes) {
-          handleSingleInterceptor(node);
-        } else {
-          handleSingleInstance(node);
-        }
-      } else {
-        if (usesInterceptor == Boolish.no) {
-          handleVirtual(node);
-        } else if (usesInterceptor == Boolish.yes) {
-          handleMultiInterceptor(node);
-        } else {
-          handleDynamic(node);
-        }
-      }
-      return;
-    }
-    handleDynamic(node);
-  }
-
-  void handleThisProperty(Send node, Selector selector) {
-    handleDynamicProperty(node, node.receiver, selector);
-  }
-
-  void handleIndex(Node node) {
-    handleDynamic(node);
-  }
-
-  void handleOperator(Node node) {
-    handleDynamic(node);
-  }
-
-  void handleInvoke(Node node) {
-    handleDynamic(node);
-  }
-
-  void handleEquals(Node node) {
-    handleDynamic(node);
-  }
-
-  // Constructors
-
-  void visitAbstractClassConstructorInvoke(
-      NewExpression node,
-      ConstructorElement element,
-      InterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleConstructor(node);
-  }
-
-  void visitBoolFromEnvironmentConstructorInvoke(NewExpression node,
-      BoolFromEnvironmentConstantExpression constant, T arg) {
-    handleConstructor(node);
-  }
-
-  void visitConstConstructorInvoke(
-      NewExpression node, ConstructedConstantExpression constant, T arg) {
-    handleConstructor(node);
-  }
-
-  void visitGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      InterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleConstructor(node);
-  }
-
-  void visitIntFromEnvironmentConstructorInvoke(NewExpression node,
-      IntFromEnvironmentConstantExpression constant, T arg) {
-    handleConstructor(node);
-  }
-
-  void visitRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      InterfaceType type,
-      ConstructorElement effectiveTarget,
-      InterfaceType effectiveTargetType,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleConstructor(node);
-  }
-
-  void visitRedirectingGenerativeConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      InterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleConstructor(node);
-  }
-
-  void visitStringFromEnvironmentConstructorInvoke(NewExpression node,
-      StringFromEnvironmentConstantExpression constant, T arg) {
-    handleConstructor(node);
-  }
-
-  // Dynamic sends
-
-  // TODO(sigmund): many many things to add:
-  // -- support for operators, indexers, etc.
-  // -- logic about nullables
-  // -- int, JSArray
-  // -- all interceptors
-
-  void visitBinary(
-      Send node, Node left, BinaryOperator operator, Node right, T arg) {
-    handleOperator(node);
-  }
-
-  void visitCompoundIndexSet(SendSet node, Node receiver, Node index,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleIndex(node); // t1 = receiver[index]
-    handleOperator(node); // t2 = t1 op rhs
-    handleIndex(node); // receiver[index] = t2
-  }
-
-  void visitDynamicPropertyCompound(Send node, Node receiver, Name name,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleOperator(node);
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitDynamicPropertyGet(Send node, Node receiver, Name name, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-  }
-
-  void visitDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, T arg) {
-    handleDynamicProperty(node, receiver, selector);
-  }
-
-  void visitDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleOperator(node);
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleOperator(node);
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, T arg) {
-    // read to check for null?
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitEquals(Send node, Node left, Node right, T arg) {
-    handleEquals(node);
-  }
-
-  void visitExpressionInvoke(Send node, Node expression, NodeList arguments,
-      CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitIfNotNullDynamicPropertyCompound(Send node, Node receiver,
-      Name name, AssignmentOperator operator, Node rhs, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleOperator(node);
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitIfNotNullDynamicPropertyGet(
-      Send node, Node receiver, Name name, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-  }
-
-  void visitIfNotNullDynamicPropertyInvoke(
-      Send node, Node receiver, NodeList arguments, Selector selector, T arg) {
-    handleDynamicProperty(node, receiver, selector);
-  }
-
-  void visitIfNotNullDynamicPropertyPostfix(
-      Send node, Node receiver, Name name, IncDecOperator operator, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleOperator(node);
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitIfNotNullDynamicPropertyPrefix(
-      Send node, Node receiver, Name name, IncDecOperator operator, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleOperator(node);
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitIfNotNullDynamicPropertySet(
-      SendSet node, Node receiver, Name name, Node rhs, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitIfNotNullDynamicPropertySetIfNull(
-      Send node, Node receiver, Name name, Node rhs, T arg) {
-    handleDynamicProperty(node, receiver, new Selector.getter(name));
-    handleDynamicProperty(node, receiver, new Selector.setter(name));
-  }
-
-  void visitIndex(Send node, Node receiver, Node index, T arg) {
-    handleIndex(node);
-  }
-
-  void visitIndexPostfix(
-      Send node, Node receiver, Node index, IncDecOperator operator, T arg) {
-    handleIndex(node);
-    handleOperator(node);
-    handleIndex(node);
-  }
-
-  void visitIndexPrefix(
-      Send node, Node receiver, Node index, IncDecOperator operator, T arg) {
-    handleIndex(node);
-    handleOperator(node);
-    handleIndex(node);
-  }
-
-  void visitIndexSet(SendSet node, Node receiver, Node index, Node rhs, T arg) {
-    handleIndex(node);
-  }
-
-  void visitLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleLocal(node);
-  }
-
-  void visitLocalVariableInvoke(Send node, LocalVariableElement variable,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleLocal(node);
-  }
-
-  void visitLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleLocal(node);
-  }
-
-  void visitNotEquals(Send node, Node left, Node right, T arg) {
-    handleEquals(node);
-  }
-
-  void visitParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleLocal(node);
-  }
-
-  void visitParameterInvoke(Send node, ParameterElement parameter,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleLocal(node);
-  }
-
-  void visitParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleLocal(node);
-  }
-
-  void visitStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitStaticFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitStaticGetterInvoke(Send node, FunctionElement getter,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitStaticGetterSetterCompound(Send node, FunctionElement getter,
-      FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitStaticGetterSetterPostfix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitStaticGetterSetterPrefix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldFieldCompound(Send node, FieldElement readField,
-      FieldElement writtenField, AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldFieldPostfix(Send node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldFieldPrefix(Send node, FieldElement readField,
-      FieldElement writtenField, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldFieldSetIfNull(Send node, FieldElement readField,
-      FieldElement writtenField, Node rhs, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, readField.enclosingClass);
-  }
-
-  void visitSuperFieldInvoke(Send node, FieldElement field, NodeList arguments,
-      CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitSuperFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldSetterCompound(Send node, FieldElement field,
-      FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldSetterPostfix(Send node, FieldElement field,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldSetterPrefix(Send node, FieldElement field,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperFieldSetterSetIfNull(
-      Send node, FieldElement field, FunctionElement setter, Node rhs, T arg) {
-    handleSuper(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterFieldCompound(Send node, FunctionElement getter,
-      FieldElement field, AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterFieldPostfix(Send node, FunctionElement getter,
-      FieldElement field, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterFieldPrefix(Send node, FunctionElement getter,
-      FieldElement field, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterFieldSetIfNull(
-      Send node, FunctionElement getter, FieldElement field, Node rhs, T arg) {
-    handleSuper(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterInvoke(Send node, FunctionElement getter,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitSuperGetterSetterCompound(Send node, FunctionElement getter,
-      FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterSetterPostfix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterSetterPrefix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterSetterSetIfNull(Send node, FunctionElement getter,
-      FunctionElement setter, Node rhs, T arg) {
-    handleSuper(node);
-    handleSuper(node);
-  }
-
-  void visitSuperIndexPostfix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperIndexPrefix(
-      Send node,
-      MethodElement indexFunction,
-      MethodElement indexSetFunction,
-      Node index,
-      IncDecOperator operator,
-      T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitSuperMethodSetterCompound(Send node, FunctionElement method,
-      FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, method.enclosingClass);
-    handleSuper(node);
-  }
-
-  void visitSuperMethodSetterPostfix(Send node, FunctionElement method,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, method.enclosingClass);
-    handleSuper(node);
-  }
-
-  void visitSuperMethodSetterPrefix(Send node, FunctionElement method,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, method.enclosingClass);
-    handleSuper(node);
-  }
-
-  void visitSuperMethodSetterSetIfNull(Send node, FunctionElement method,
-      FunctionElement setter, Node rhs, T arg) {
-    handleSuper(node);
-    handleSuper(node);
-  }
-
-  void visitThisPropertyCompound(
-      Send node, Name name, AssignmentOperator operator, Node rhs, T arg) {
-    handleThisProperty(node, new Selector.getter(name));
-    handleOperator(node);
-    handleThisProperty(node, new Selector.setter(name));
-  }
-
-  void visitThisPropertyInvoke(
-      Send node, NodeList arguments, Selector selector, T arg) {
-    handleThisProperty(node, selector);
-  }
-
-  void visitThisPropertyPostfix(
-      Send node, Name name, IncDecOperator operator, T arg) {
-    handleThisProperty(node, new Selector.getter(name));
-    handleOperator(node);
-    handleThisProperty(node, new Selector.setter(name));
-  }
-
-  void visitThisPropertyPrefix(
-      Send node, Name name, IncDecOperator operator, T arg) {
-    handleThisProperty(node, new Selector.getter(name));
-    handleOperator(node);
-    handleThisProperty(node, new Selector.setter(name));
-  }
-
-  void visitTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelFieldInvoke(Send node, FieldElement field,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelGetterInvoke(Send node, FunctionElement getter,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleInvoke(node);
-  }
-
-  void visitTopLevelGetterSetterCompound(Send node, FunctionElement getter,
-      FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelGetterSetterPostfix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelGetterSetterPrefix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleStatic(node);
-  }
-
-  void visitUnary(Send node, UnaryOperator operator, Node expression, T arg) {
-    handleDynamic(node);
-  }
-
-  // Local variable sends
-
-  void visitLocalFunctionGet(Send node, LocalFunctionElement function, T arg) {
-    handleLocal(node);
-  }
-
-  void visitLocalFunctionInvoke(Send node, LocalFunctionElement function,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleLocal(node);
-  }
-
-  void visitLocalVariableGet(Send node, LocalVariableElement variable, T arg) {
-    handleLocal(node);
-  }
-
-  void visitLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, T arg) {
-    handleLocal(node);
-  }
-
-  void visitLocalVariableSetIfNull(
-      SendSet node, LocalVariableElement variable, Node rhs, T arg) {
-    handleLocal(node);
-    handleLocal(node);
-  }
-
-  void visitParameterGet(Send node, ParameterElement parameter, T arg) {
-    handleLocal(node);
-  }
-
-  void visitParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, T arg) {
-    handleLocal(node);
-  }
-
-  void visitParameterSetIfNull(
-      Send node, ParameterElement parameter, Node rhs, T arg) {
-    handleLocal(node);
-    handleLocal(node);
-  }
-
-  // Super monomorphic sends
-
-  void visitSuperBinary(Send node, FunctionElement function,
-      BinaryOperator operator, Node argument, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperEquals(
-      Send node, FunctionElement function, Node argument, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperFieldGet(Send node, FieldElement field, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperFieldSet(SendSet node, FieldElement field, Node rhs, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperFieldSetIfNull(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleSuper(node);
-    handleSuper(node);
-  }
-
-  void visitSuperGetterGet(Send node, FunctionElement getter, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperGetterSet(
-      SendSet node, FunctionElement getter, Node rhs, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperIndex(Send node, FunctionElement function, Node index, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperIndexSet(
-      SendSet node, FunctionElement function, Node index, Node rhs, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperMethodGet(Send node, MethodElement method, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperMethodInvoke(Send node, MethodElement method,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperNotEquals(
-      Send node, FunctionElement function, Node argument, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperSetterSet(
-      SendSet node, FunctionElement setter, Node rhs, T arg) {
-    handleSuper(node);
-  }
-
-  void visitSuperUnary(
-      Send node, UnaryOperator operator, FunctionElement function, T arg) {
-    handleSuper(node);
-  }
-
-  // Statically known "no such method" sends
-
-  void visitConstructorIncompatibleInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      InterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleNSMError(node);
-  }
-
-  void visitFinalLocalVariableCompound(Send node, LocalVariableElement variable,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalLocalVariablePostfix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalLocalVariablePrefix(Send node, LocalVariableElement variable,
-      IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalLocalVariableSet(
-      SendSet node, LocalVariableElement variable, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitFinalLocalVariableSetIfNull(
-      SendSet node, LocalVariableElement variable, Node rhs, T arg) {
-    handleLocal(node); // read for null
-    handleNSMError(node); // set fails
-  }
-
-  void visitFinalParameterCompound(Send node, ParameterElement parameter,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalParameterPostfix(
-      Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalParameterPrefix(
-      Send node, ParameterElement parameter, IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalParameterSet(
-      SendSet node, ParameterElement parameter, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitFinalParameterSetIfNull(
-      SendSet node, ParameterElement parameter, Node rhs, T arg) {
-    handleLocal(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalStaticFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalStaticFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalStaticFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalStaticFieldSet(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitFinalStaticFieldSetIfNull(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalSuperFieldSetIfNull(
-      Send node, FieldElement field, Node rhs, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, field.enclosingClass);
-  }
-
-  void visitFinalSuperFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, field.enclosingClass);
-  }
-
-  void visitFinalSuperFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, field.enclosingClass);
-  }
-
-  void visitFinalSuperFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, field.enclosingClass);
-  }
-
-  void visitFinalSuperFieldSet(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleNSMSuper(node, field.enclosingClass);
-  }
-
-  void visitFinalTopLevelFieldCompound(Send node, FieldElement field,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalTopLevelFieldPostfix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalTopLevelFieldPrefix(
-      Send node, FieldElement field, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleOperator(node);
-    handleNSMError(node);
-  }
-
-  void visitFinalTopLevelFieldSet(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitFinalTopLevelFieldSetIfNull(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-  }
-
-  void visitTopLevelGetterSetterSetIfNull(Send node, FunctionElement getter,
-      FunctionElement setter, Node rhs, T arg) {
-    handleStatic(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelMethodSetterSetIfNull(Send node, FunctionElement method,
-      FunctionElement setter, Node rhs, T arg) {
-    handleStatic(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-  }
-
-  void visitLocalFunctionIncompatibleInvoke(
-      Send node,
-      LocalFunctionElement function,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleNSMError(node);
-  }
-
-  void visitLocalFunctionCompound(Send node, LocalFunctionElement function,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleLocal(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitLocalFunctionPostfix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitLocalFunctionPrefix(Send node, LocalFunctionElement function,
-      IncDecOperator operator, T arg) {
-    handleLocal(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitLocalFunctionSet(
-      SendSet node, LocalFunctionElement function, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitLocalFunctionSetIfNull(
-      SendSet node, LocalFunctionElement function, Node rhs, T arg) {
-    handleLocal(node);
-    handleNSMError(node);
-  }
-
-  void visitStaticFunctionIncompatibleInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitStaticFunctionSet(
-      Send node, MethodElement function, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitStaticMethodCompound(Send node, MethodElement method,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node); // operator on a method closure yields nSM
-    handleNoSend(node); // setter is not invoked, don't count it.
-  }
-
-  void visitStaticMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitStaticMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitStaticMethodSetterCompound(Send node, MethodElement method,
-      MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node); // operator on a method closure yields nSM
-    handleNoSend(node); // setter is not invoked, don't count it.
-  }
-
-  void visitStaticMethodSetterPostfix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitStaticMethodSetterPrefix(Send node, FunctionElement getter,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitStaticSetterGet(Send node, FunctionElement setter, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitStaticSetterInvoke(Send node, FunctionElement setter,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitSuperMethodCompound(Send node, FunctionElement method,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-
-    // An operator send on a method closure yields nSM
-    handleNSMSuper(node, method.enclosingClass);
-
-    handleNoSend(node); // setter is not invoked, don't count it.
-  }
-
-  void visitSuperMethodIncompatibleInvoke(Send node, MethodElement method,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMSuper(node, method.enclosingClass);
-  }
-
-  void visitSuperMethodPostfix(
-      Send node, FunctionElement method, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, method.enclosingClass);
-    handleNoSend(node);
-  }
-
-  void visitSuperMethodPrefix(
-      Send node, FunctionElement method, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, method.enclosingClass);
-    handleNoSend(node);
-  }
-
-  void visitSuperMethodSet(Send node, MethodElement method, Node rhs, T arg) {
-    handleNSMSuper(node, method.enclosingClass);
-  }
-
-  void visitSuperMethodSetIfNull(
-      Send node, MethodElement method, Node rhs, T arg) {
-    handleNSMSuper(node, method.enclosingClass);
-  }
-
-  void visitSuperSetterGet(Send node, FunctionElement setter, T arg) {
-    handleNSMSuper(node, setter.enclosingClass);
-  }
-
-  void visitSuperSetterInvoke(Send node, FunctionElement setter,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMSuper(node, setter.enclosingClass);
-  }
-
-  void visitTopLevelFunctionIncompatibleInvoke(
-      Send node,
-      MethodElement function,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTopLevelFunctionSet(
-      Send node, MethodElement function, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTopLevelGetterSet(
-      SendSet node, FunctionElement getter, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTopLevelMethodCompound(Send node, FunctionElement method,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node); // operator on a method closure yields nSM
-    handleNoSend(node); // setter is not invoked, don't count it.
-  }
-
-  void visitTopLevelMethodPostfix(
-      Send node, MethodElement method, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTopLevelMethodPrefix(
-      Send node, MethodElement method, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTopLevelMethodSetterCompound(Send node, FunctionElement method,
-      FunctionElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node); // operator on a method closure yields nSM
-    handleNoSend(node); // setter is not invoked, don't count it.
-  }
-
-  void visitTopLevelMethodSetterPostfix(Send node, FunctionElement method,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTopLevelMethodSetterPrefix(Send node, FunctionElement method,
-      FunctionElement setter, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTopLevelSetterGet(Send node, FunctionElement setter, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTopLevelSetterInvoke(Send node, FunctionElement setter,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTypeVariableTypeLiteralCompound(
-      Send node,
-      TypeVariableElement element,
-      AssignmentOperator operator,
-      Node rhs,
-      T arg) {
-    handleTypeVariable(node);
-    handleNSMError(node); // operator on a method closure yields nSM
-    handleNoSend(node); // setter is not invoked, don't count it.
-  }
-
-  void visitTypeVariableTypeLiteralGet(
-      Send node, TypeVariableElement element, T arg) {
-    handleTypeVariable(node);
-  }
-
-  void visitTypeVariableTypeLiteralInvoke(
-      Send node,
-      TypeVariableElement element,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTypeVariableTypeLiteralPostfix(
-      Send node, TypeVariableElement element, IncDecOperator operator, T arg) {
-    handleTypeVariable(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTypeVariableTypeLiteralPrefix(
-      Send node, TypeVariableElement element, IncDecOperator operator, T arg) {
-    handleTypeVariable(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTypeVariableTypeLiteralSet(
-      SendSet node, TypeVariableElement element, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTypeVariableTypeLiteralSetIfNull(
-      SendSet node, TypeVariableElement element, Node rhs, T arg) {
-    handleTypeVariable(node);
-    handleNSMError(node);
-  }
-
-  void visitTypedefTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleTypeVariable(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTypedefTypeLiteralGet(
-      Send node, ConstantExpression constant, T arg) {
-    handleTypeVariable(node);
-  }
-
-  void visitTypedefTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTypedefTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
-    handleTypeVariable(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTypedefTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
-    handleTypeVariable(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitTypedefTypeLiteralSet(
-      SendSet node, ConstantExpression constant, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitTypedefTypeLiteralSetIfNull(
-      SendSet node, ConstantExpression constant, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-  }
-
-  void visitUnresolvedClassConstructorInvoke(
-      NewExpression node,
-      Element element,
-      DartType type,
-      NodeList arguments,
-      Selector selector,
-      T arg) {
-    handleNSMError(node);
-  }
-
-  void visitUnresolvedCompound(Send node, Element element,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedConstructorInvoke(NewExpression node, Element constructor,
-      DartType type, NodeList arguments, Selector selector, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitUnresolvedGet(Send node, Element element, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitUnresolvedInvoke(Send node, Element element, NodeList arguments,
-      Selector selector, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitUnresolvedPostfix(
-      Send node, Element element, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedPrefix(
-      Send node, Element element, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedRedirectingFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      InterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleNSMError(node);
-  }
-
-  void visitUnresolvedSet(Send node, Element element, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitUnresolvedSetIfNull(Send node, Element element, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticSetterCompound(Send node, MethodElement getter,
-      Element element, AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticSetterPostfix(Send node, MethodElement getter,
-      Element element, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticSetterPrefix(Send node, MethodElement getter,
-      Element element, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedStaticSetterSetIfNull(
-      Send node, MethodElement getter, Element element, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedSuperBinary(Send node, Element element,
-      BinaryOperator operator, Node argument, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperCompound(Send node, Element element,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    // TODO(sigmund): we should only count the next 2 if we know that the
-    // superclass has a nSM method.
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperCompoundIndexSet(Send node, Element element,
-      Node index, AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleNoSend(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperGet(Send node, Element element, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSet(Send node, Element element, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetIfNull(
-      Send node, Element element, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedSuperGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitUnresolvedSuperGetterCompoundIndexSet(
-      Send node,
-      Element element,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitUnresolvedSuperGetterIndexPostfix(Send node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitUnresolvedSuperGetterIndexPrefix(Send node, Element element,
-      MethodElement setter, Node index, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitUnresolvedSuperGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitUnresolvedSuperGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitUnresolvedSuperGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleSuper(node);
-  }
-
-  void visitUnresolvedSuperIndex(
-      Send node, Element element, Node index, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperIndexPostfix(
-      Send node, Element element, Node index, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperIndexPrefix(
-      Send node, Element element, Node index, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperIndexSet(
-      Send node, Element element, Node index, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperInvoke(Send node, Element element,
-      NodeList arguments, Selector selector, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperPostfix(
-      Send node, Element element, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperPrefix(
-      Send node, Element element, IncDecOperator operator, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetterCompound(Send node, MethodElement getter,
-      Element element, AssignmentOperator operator, Node rhs, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetterCompoundIndexSet(
-      Send node,
-      MethodElement getter,
-      Element element,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetterIndexPostfix(
-      Send node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetterIndexPrefix(
-      Send node,
-      MethodElement indexFunction,
-      Element element,
-      Node index,
-      IncDecOperator operator,
-      T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetterPostfix(Send node, MethodElement getter,
-      Element element, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetterPrefix(Send node, MethodElement getter,
-      Element element, IncDecOperator operator, T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperSetterSetIfNull(
-      Send node, MethodElement getter, Element element, Node rhs, T arg) {
-    handleSuper(node);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedSuperUnary(
-      Send node, UnaryOperator operator, Element element, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitUnresolvedTopLevelGetterCompound(Send node, Element element,
-      MethodElement setter, AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedTopLevelGetterPostfix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedTopLevelGetterPrefix(Send node, Element element,
-      MethodElement setter, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedTopLevelGetterSetIfNull(
-      Send node, Element element, MethodElement setter, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedTopLevelSetterCompound(Send node, MethodElement getter,
-      Element element, AssignmentOperator operator, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedTopLevelSetterPostfix(Send node, MethodElement getter,
-      Element element, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedTopLevelSetterPrefix(Send node, MethodElement getter,
-      Element element, IncDecOperator operator, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void visitUnresolvedTopLevelSetterSetIfNull(
-      Send node, MethodElement getter, Element element, Node rhs, T arg) {
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  // Static
-
-  void visitConstantGet(Send node, ConstantExpression constant, T arg) {
-    handleStatic(node);
-  }
-
-  void visitConstantInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStreucture, T arg) {
-    handleStatic(node);
-  }
-
-  void visitFactoryConstructorInvoke(
-      NewExpression node,
-      ConstructorElement constructor,
-      InterfaceType type,
-      NodeList arguments,
-      CallStructure callStructure,
-      T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticFieldGet(Send node, FieldElement field, T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticFieldSet(SendSet node, FieldElement field, Node rhs, T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticFieldSetIfNull(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleStatic(node);
-    handleStatic(node);
-  }
-
-  void visitStaticFunctionGet(Send node, MethodElement function, T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticGetterGet(Send node, FunctionElement getter, T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticGetterSet(
-      SendSet node, FunctionElement getter, Node rhs, T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticSetterSet(
-      SendSet node, FunctionElement setter, Node rhs, T arg) {
-    handleStatic(node);
-  }
-
-  void visitStaticGetterSetterSetIfNull(Send node, FunctionElement getter,
-      FunctionElement setter, Node rhs, T arg) {
-    handleStatic(node);
-    handleStatic(node);
-  }
-
-  void visitStaticMethodSetterSetIfNull(
-      Send node, MethodElement method, MethodElement setter, Node rhs, T arg) {
-    handleStatic(node);
-    handleStatic(node);
-  }
-
-  void visitStaticMethodSetIfNull(
-      Send node, FunctionElement method, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-  }
-
-  void visitTopLevelFieldGet(Send node, FieldElement field, T arg) {
-    handleStatic(node);
-  }
-
-  void visitTopLevelFieldSet(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleStatic(node);
-  }
-
-  void visitTopLevelFieldSetIfNull(
-      SendSet node, FieldElement field, Node rhs, T arg) {
-    handleStatic(node);
-    handleStatic(node);
-  }
-
-  void visitTopLevelFunctionGet(Send node, MethodElement function, T arg) {
-    handleStatic(node);
-  }
-
-  void visitTopLevelFunctionInvoke(Send node, MethodElement function,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleStatic(node);
-  }
-
-  void visitTopLevelGetterGet(Send node, FunctionElement getter, T arg) {
-    handleStatic(node);
-  }
-
-  void visitTopLevelSetterSet(
-      SendSet node, FunctionElement setter, Node rhs, T arg) {
-    handleStatic(node);
-  }
-
-  // Virtual
-
-  void visitSuperCompoundIndexSet(
-      SendSet node,
-      MethodElement getter,
-      MethodElement setter,
-      Node index,
-      AssignmentOperator operator,
-      Node rhs,
-      T arg) {
-    handleSuper(node);
-    handleOperator(node);
-    handleSuper(node);
-  }
-
-  void visitThisGet(Identifier node, T arg) {
-    handleLocal(node); // TODO(sigmund): should we add a metric for "this"?
-  }
-
-  void visitThisInvoke(
-      Send node, NodeList arguments, CallStructure callStructure, T arg) {
-    // TODO(sigmund): implement (treat like this.call())
-    handleDynamic(node);
-  }
-
-  void visitThisPropertyGet(Send node, Name name, T arg) {
-    handleThisProperty(node, new Selector.getter(name));
-  }
-
-  void visitThisPropertySet(SendSet node, Name name, Node rhs, T arg) {
-    handleThisProperty(node, new Selector.setter(name));
-  }
-
-  void visitThisPropertySetIfNull(Send node, Name name, Node rhs, T arg) {
-    handleThisProperty(node, new Selector.getter(name));
-    handleThisProperty(node, new Selector.setter(name));
-  }
-
-  // Not count
-
-  void errorNonConstantConstructorInvoke(NewExpression node, Element element,
-      DartType type, NodeList arguments, CallStructure callStructure, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorUndefinedBinaryExpression(
-      Send node, Node left, Operator operator, Node right, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorUndefinedUnaryExpression(
-      Send node, Operator operator, Node expression, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidGet(Send node, ErroneousElement error, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidInvoke(Send node, ErroneousElement error, NodeList arguments,
-      Selector selector, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidSet(Send node, ErroneousElement error, Node rhs, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidSetIfNull(
-      Send node, ErroneousElement error, Node rhs, T arg) {
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void errorInvalidPrefix(
-      Send node, ErroneousElement error, IncDecOperator operator, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidPostfix(
-      Send node, ErroneousElement error, IncDecOperator operator, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidCompound(Send node, ErroneousElement error,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidUnary(
-      Send node, UnaryOperator operator, ErroneousElement error, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidEquals(
-      Send node, ErroneousElement error, Node right, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidNotEquals(
-      Send node, ErroneousElement error, Node right, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidBinary(Send node, ErroneousElement error,
-      BinaryOperator operator, Node right, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidIndex(Send node, ErroneousElement error, Node index, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidIndexSet(
-      Send node, ErroneousElement error, Node index, Node rhs, T arg) {
-    handleNoSend(node);
-  }
-
-  void errorInvalidCompoundIndexSet(Send node, ErroneousElement error,
-      Node index, AssignmentOperator operator, Node rhs, T arg) {
-    handleNoSend(node);
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void errorInvalidIndexPrefix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, T arg) {
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void errorInvalidIndexPostfix(Send node, ErroneousElement error, Node index,
-      IncDecOperator operator, T arg) {
-    handleNoSend(node);
-    handleNoSend(node);
-  }
-
-  void previsitDeferredAccess(Send node, PrefixElement prefix, T arg) {}
-
-  void visitAs(Send node, Node expression, DartType type, T arg) {
-    handleNoSend(node);
-  }
-
-  void visitClassTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitClassTypeLiteralGet(Send node, ConstantExpression constant, T arg) {
-    handleStatic(node);
-  }
-
-  void visitClassTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitClassTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitClassTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitClassTypeLiteralSet(
-      SendSet node, ConstantExpression constant, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitClassTypeLiteralSetIfNull(
-      SendSet node, ConstantExpression constant, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-  }
-
-  void visitDynamicTypeLiteralCompound(Send node, ConstantExpression constant,
-      AssignmentOperator operator, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitDynamicTypeLiteralGet(
-      Send node, ConstantExpression constant, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitDynamicTypeLiteralInvoke(Send node, ConstantExpression constant,
-      NodeList arguments, CallStructure callStructure, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitDynamicTypeLiteralPostfix(
-      Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitDynamicTypeLiteralPrefix(
-      Send node, ConstantExpression constant, IncDecOperator operator, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-    handleNoSend(node);
-  }
-
-  void visitDynamicTypeLiteralSet(
-      SendSet node, ConstantExpression constant, Node rhs, T arg) {
-    handleNSMError(node);
-  }
-
-  void visitDynamicTypeLiteralSetIfNull(
-      SendSet node, ConstantExpression constant, Node rhs, T arg) {
-    handleStatic(node);
-    handleNSMError(node);
-  }
-
-  @override
-  errorInvalidIndexSetIfNull(
-      SendSet node, ErroneousElement error, Node index, Node rhs, T arg) {
-    handleNoSend(node);
-  }
-
-  @override
-  visitIndexSetIfNull(
-      SendSet node, Node receiver, Node index, Node rhs, T arg) {
-    handleIndex(node); // t1 = receiver[index]
-    handleIndex(node); // receiver[index] = t2
-  }
-
-  @override
-  visitSuperIndexSetIfNull(SendSet node, MethodElement getter,
-      MethodElement setter, Node index, Node rhs, T arg) {
-    handleSuper(node); // t1 = super[index]
-    handleSuper(node); // super[index] = t2
-  }
-
-  @override
-  visitUnresolvedSuperGetterIndexSetIfNull(Send node, Element element,
-      MethodElement setter, Node index, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  @override
-  visitUnresolvedSuperIndexSetIfNull(
-      Send node, Element element, Node index, Node rhs, T arg) {
-    handleNSMSuper(node, element.enclosingClass);
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  @override
-  visitUnresolvedSuperSetterIndexSetIfNull(Send node, MethodElement getter,
-      Element element, Node index, Node rhs, T arg) {
-    handleSuper(node); // t1 = super[index]
-    handleNSMSuper(node, element.enclosingClass);
-  }
-
-  void visitIfNull(Send node, Node left, Node right, T arg) {
-    handleNoSend(node);
-  }
-
-  void visitIs(Send node, Node expression, DartType type, T arg) {
-    handleNoSend(node);
-  }
-
-  void visitIsNot(Send node, Node expression, DartType type, T arg) {
-    handleNoSend(node);
-  }
-
-  void visitLogicalAnd(Send node, Node left, Node right, T arg) {
-    handleNoSend(node);
-  }
-
-  void visitLogicalOr(Send node, Node left, Node right, T arg) {
-    handleNoSend(node);
-  }
-
-  void visitNot(Send node, Node expression, T arg) {
-    handleNoSend(node);
-  }
-
-  String last;
-  _checkInvariant(node, String msg) {
-    msg = '$msg ${recursiveDiagnosticString(measurements, Metric.send)}';
-    if (!measurements.checkInvariant(Metric.send) ||
-        !measurements.checkInvariant(Metric.monomorphicSend) ||
-        !measurements.checkInvariant(Metric.polymorphicSend)) {
-      reporter.reportErrorMessage(node, MessageKind.GENERIC,
-          {'text': 'bad\n-- $msg\nlast:\n-- $last\n'});
-      last = msg;
-    } else {
-      last = msg;
-    }
-  }
-}
-
-/// Visitor that collects statistics for a single function.
-class _StatsTraversalVisitor<T> extends TraversalVisitor<dynamic, T>
-    implements SemanticSendVisitor<dynamic, T> {
-  final DiagnosticReporter reporter;
-  final _StatsVisitor statsVisitor;
-  Measurements get measurements => statsVisitor.measurements;
-  _StatsTraversalVisitor(
-      Compiler compiler, TreeElements elements, Uri sourceUri)
-      : reporter = compiler.reporter,
-        statsVisitor = new _StatsVisitor(
-            compiler.reporter,
-            elements,
-                // TODO(sigmund): accept a list of analyses, so we can compare them
-                // together.
-                true
-                ? new TrustTypesAnalysisResult(elements, compiler.world)
-                : new NaiveAnalysisResult(),
-            sourceUri),
-        super(elements);
-
-  void visitSend(Send node) {
-    try {
-      node.accept(statsVisitor);
-    } catch (e, t) {
-      reporter
-          .reportErrorMessage(node, MessageKind.GENERIC, {'text': '$e\n$t'});
-    }
-    super.visitSend(node);
-  }
-
-  void visitNewExpression(NewExpression node) {
-    try {
-      node.accept(statsVisitor);
-    } catch (e, t) {
-      reporter
-          .reportErrorMessage(node, MessageKind.GENERIC, {'text': '$e\n$t'});
-    }
-    super.visitNewExpression(node);
-  }
-}
-
-/// Helper to visit elements recursively
-// TODO(sigmund): maybe generalize and move to elements/visitor.dart?
-abstract class RecursiveElementVisitor<R, A> extends ElementVisitor<R, A> {
-  @override
-  R visitWarnOnUseElement(WarnOnUseElement e, A arg) =>
-      e.wrappedElement.accept(this, arg);
-
-  R visitScopeContainerElement(ScopeContainerElement e, A arg) {
-    e.forEachLocalMember((l) => l.accept(this, arg));
-    return null;
-  }
-
-  @override
-  R visitCompilationUnitElement(CompilationUnitElement e, A arg) {
-    e.forEachLocalMember((l) => l.accept(this, arg));
-    return null;
-  }
-
-  @override
-  R visitLibraryElement(LibraryElement e, A arg) {
-    e.implementation.compilationUnits.forEach((u) => u.accept(this, arg));
-    return null;
-  }
-
-  R visitVariableElement(VariableElement e, A arg) => null;
-
-  @override
-  R visitParameterElement(ParameterElement e, A arg) => null;
-
-  @override
-  R visitFormalElement(FormalElement e, A arg) => null;
-
-  @override
-  R visitFieldElement(FieldElement e, A arg) => null;
-
-  @override
-  R visitFieldParameterElement(InitializingFormalElement e, A arg) => null;
-
-  @override
-  R visitAbstractFieldElement(AbstractFieldElement e, A arg) => null;
-
-  R visitFunctionElement(FunctionElement e, A arg) => null;
-
-  @override
-  R visitConstructorElement(ConstructorElement e, A arg) {
-    return visitFunctionElement(e, arg);
-  }
-
-  @override
-  R visitConstructorBodyElement(ConstructorBodyElement e, A arg) {
-    return visitFunctionElement(e.constructor, arg);
-  }
-
-  @override
-  R visitClassElement(ClassElement e, A arg) {
-    return visitScopeContainerElement(e, arg);
-  }
-
-  @override
-  R visitEnumClassElement(EnumClassElement e, A arg) {
-    return visitClassElement(e, arg);
-  }
-
-  @override
-  R visitBoxFieldElement(BoxFieldElement e, A arg) => null;
-
-  @override
-  R visitClosureClassElement(ClosureClassElement e, A arg) {
-    return visitClassElement(e, arg);
-  }
-
-  @override
-  R visitClosureFieldElement(ClosureFieldElement e, A arg) {
-    return visitVariableElement(e, arg);
-  }
-}
-
-// TODO(sigmund): get rid of debug messages.
-_debug(String message) {
-  print('debug: $message');
-}
diff --git a/pkg/compiler/lib/src/info/trusted_types_analysis_result.dart b/pkg/compiler/lib/src/info/trusted_types_analysis_result.dart
deleted file mode 100644
index 5653f2e..0000000
--- a/pkg/compiler/lib/src/info/trusted_types_analysis_result.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// API to get results from a static analysis of the source program.
-// TODO(sigmund): split out implementations out of this file.
-library compiler.src.stats.trusted_types_analysis_result;
-
-import 'analysis_result.dart';
-import '../tree/tree.dart' show Node;
-import '../universe/selector.dart' show Selector;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../world.dart' show ClassWorld;
-import '../dart_types.dart' show InterfaceType;
-
-/// An [AnalysisResult] produced by using type-propagation based on
-/// trusted type annotations.
-class TrustTypesAnalysisResult implements AnalysisResult {
-  final ClassWorld world;
-  final TreeElements elements;
-
-  TrustTypesAnalysisResult(this.elements, this.world);
-
-  ReceiverInfo infoForReceiver(Node receiver) => new TrustTypesReceiverInfo(
-      receiver, elements.typesCache[receiver], world);
-  SelectorInfo infoForSelector(Node receiver, Selector selector) =>
-      new TrustTypesSelectorInfo(
-          receiver, elements.typesCache[receiver], selector, world);
-}
-
-class _SelectorLookupResult {
-  final Boolish exists;
-  // TODO(sigmund): implement
-  final Boolish usesInterceptor = Boolish.no;
-  final int possibleTargets;
-
-  _SelectorLookupResult(this.exists, this.possibleTargets);
-
-  const _SelectorLookupResult.dontKnow()
-      : exists = Boolish.maybe,
-        possibleTargets = -1;
-}
-
-_SelectorLookupResult _lookupSelector(
-    String selectorName, InterfaceType type, ClassWorld world) {
-  if (type == null) return const _SelectorLookupResult.dontKnow();
-  bool isNsm = selectorName == 'noSuchMethod';
-  bool notFound = false;
-  var uniqueTargets = new Set();
-  for (var cls in world.subtypesOf(type.element)) {
-    var member = cls.lookupMember(selectorName);
-    if (member != null &&
-        !member.isAbstract
-        // Don't match nsm in Object
-        &&
-        (!isNsm || !member.enclosingClass.isObject)) {
-      uniqueTargets.add(member);
-    } else {
-      notFound = true;
-    }
-  }
-  Boolish exists = uniqueTargets.length > 0
-      ? (notFound ? Boolish.maybe : Boolish.yes)
-      : Boolish.no;
-  return new _SelectorLookupResult(exists, uniqueTargets.length);
-}
-
-class TrustTypesReceiverInfo implements ReceiverInfo {
-  final Node receiver;
-  final Boolish hasNoSuchMethod;
-  final int possibleNsmTargets;
-  final Boolish isNull = Boolish.maybe;
-
-  factory TrustTypesReceiverInfo(
-      Node receiver, InterfaceType type, ClassWorld world) {
-    // TODO(sigmund): refactor, maybe just store nsm as a SelectorInfo
-    var res = _lookupSelector('noSuchMethod', type, world);
-    return new TrustTypesReceiverInfo._(
-        receiver, res.exists, res.possibleTargets);
-  }
-
-  TrustTypesReceiverInfo._(
-      this.receiver, this.hasNoSuchMethod, this.possibleNsmTargets);
-}
-
-class TrustTypesSelectorInfo implements SelectorInfo {
-  final Node receiver;
-  final Selector selector;
-
-  final Boolish exists;
-  final Boolish usesInterceptor;
-  final int possibleTargets;
-  final bool isAccurate;
-
-  factory TrustTypesSelectorInfo(
-      Node receiver, InterfaceType type, Selector selector, ClassWorld world) {
-    var res =
-        _lookupSelector(selector != null ? selector.name : null, type, world);
-    return new TrustTypesSelectorInfo._(receiver, selector, res.exists,
-        res.usesInterceptor, res.possibleTargets, res.exists != Boolish.maybe);
-  }
-  TrustTypesSelectorInfo._(this.receiver, this.selector, this.exists,
-      this.usesInterceptor, this.possibleTargets, this.isAccurate);
-}
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 321943f..b4a764f 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -9,11 +9,11 @@
 
 import '../common.dart';
 import '../elements/elements.dart'
-    show AstElement, FieldElement, ResolvedAst, ResolvedAstKind;
+    show AstElement, ResolvedAst, ResolvedAstKind;
 import '../js/js.dart' as js;
 import '../js/js_debug.dart';
 import '../js/js_source_mapping.dart';
-import '../tree/tree.dart' show FunctionExpression, Node, Send;
+import '../tree/tree.dart' show Node, Send;
 import 'code_output.dart' show CodeBuffer;
 import 'source_file.dart';
 import 'source_information.dart';
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index 93e6189..8b137c0 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -4,8 +4,8 @@
 
 library dart2js.io.source_file;
 
-import 'dart:math';
 import 'dart:convert' show UTF8;
+import 'dart:math';
 import 'dart:typed_data' show Uint8List;
 
 import 'line_column_provider.dart';
diff --git a/pkg/compiler/lib/src/io/source_map_builder.dart b/pkg/compiler/lib/src/io/source_map_builder.dart
index f6fa478..c3e6f5f 100644
--- a/pkg/compiler/lib/src/io/source_map_builder.dart
+++ b/pkg/compiler/lib/src/io/source_map_builder.dart
@@ -4,8 +4,8 @@
 
 library dart2js.source_map_builder;
 
-import '../util/util.dart';
 import '../util/uri_extras.dart' show relativize;
+import '../util/util.dart';
 import 'line_column_provider.dart';
 import 'source_information.dart' show SourceLocation;
 
diff --git a/pkg/compiler/lib/src/io/start_end_information.dart b/pkg/compiler/lib/src/io/start_end_information.dart
index 1734aa9..b246958 100644
--- a/pkg/compiler/lib/src/io/start_end_information.dart
+++ b/pkg/compiler/lib/src/io/start_end_information.dart
@@ -9,8 +9,7 @@
 
 import '../common.dart';
 import '../diagnostics/messages.dart' show MessageTemplate;
-import '../elements/elements.dart'
-    show AstElement, ResolvedAst, ResolvedAstKind;
+import '../elements/elements.dart' show ResolvedAst, ResolvedAstKind;
 import '../js/js.dart' as js;
 import '../js/js_source_mapping.dart';
 import '../tokens/token.dart' show Token;
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 2a9d8bf..eb0b535 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -4,15 +4,14 @@
 
 library rewrite_async;
 
-import "dart:math" show max;
 import 'dart:collection';
+import "dart:math" show max;
 
 import 'package:js_runtime/shared/async_await_error_codes.dart' as error_codes;
 
-import "js.dart" as js;
-
 import '../common.dart';
 import '../util/util.dart' show Pair;
+import "js.dart" as js;
 
 /// Rewrites a [js.Fun] with async/sync*/async* functions and await and yield
 /// (with dart-like semantics) to an equivalent function without these.
@@ -283,7 +282,7 @@
   /// Each buffer ends up as its own case part in the big state-switch.
   void beginLabel(int label) {
     assert(!labelledParts.containsKey(label));
-    currentStatementBuffer = new List<js.Statement>();
+    currentStatementBuffer = <js.Statement>[];
     labelledParts[label] = currentStatementBuffer;
     addStatement(new js.Comment(labelComments[label]));
   }
@@ -967,7 +966,7 @@
       bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable;
       insideUntranslatedBreakable = true;
       addStatement(js.js.statement('do {#} while (#)',
-          [translateInBlock(node.body), visitExpression(node.condition)]));
+          [translateToStatement(node.body), visitExpression(node.condition)]));
       insideUntranslatedBreakable = oldInsideUntranslatedBreakable;
       return;
     }
@@ -1013,7 +1012,7 @@
       withExpressions([node.init, node.condition, node.update],
           (List<js.Expression> transformed) {
         addStatement(new js.For(transformed[0], transformed[1], transformed[2],
-            translateInBlock(node.body)));
+            translateToStatement(node.body)));
       });
       insideUntranslatedBreakable = oldInsideUntranslated;
       return;
@@ -1063,23 +1062,33 @@
     unsupported(node);
   }
 
-  // Only used for code where `!shouldTransform(node)`.
-  js.Block translateInBlock(js.Statement node) {
+  List<js.Statement> translateToStatementSequence(js.Statement node) {
     assert(!shouldTransform(node));
     List<js.Statement> oldBuffer = currentStatementBuffer;
-    currentStatementBuffer = new List();
+    currentStatementBuffer = <js.Statement>[];
     List<js.Statement> resultBuffer = currentStatementBuffer;
     visitStatement(node);
     currentStatementBuffer = oldBuffer;
-    return new js.Block(resultBuffer);
+    return resultBuffer;
+  }
+
+  js.Statement translateToStatement(js.Statement node) {
+    List<js.Statement> statements = translateToStatementSequence(node);
+    if (statements.length == 1) return statements.single;
+    return new js.Block(statements);
+  }
+
+  js.Block translateToBlock(js.Statement node) {
+    return new js.Block(translateToStatementSequence(node));
   }
 
   @override
   void visitIf(js.If node) {
     if (!shouldTransform(node.then) && !shouldTransform(node.otherwise)) {
       withExpression(node.condition, (js.Expression condition) {
-        addStatement(new js.If(condition, translateInBlock(node.then),
-            translateInBlock(node.otherwise)));
+        js.Statement translatedThen = translateToStatement(node.then);
+        js.Statement translatedElse = translateToStatement(node.otherwise);
+        addStatement(new js.If(condition, translatedThen, translatedElse));
       }, store: false);
       return;
     }
@@ -1137,7 +1146,7 @@
   void visitLabeledStatement(js.LabeledStatement node) {
     if (!shouldTransform(node)) {
       addStatement(
-          new js.LabeledStatement(node.label, translateInBlock(node.body)));
+          new js.LabeledStatement(node.label, translateToStatement(node.body)));
       return;
     }
     // `continue label` is really continuing the nested loop.
@@ -1302,9 +1311,9 @@
         List<js.SwitchClause> cases = node.cases.map((js.SwitchClause clause) {
           if (clause is js.Case) {
             return new js.Case(
-                clause.expression, translateInBlock(clause.body));
+                clause.expression, translateToBlock(clause.body));
           } else if (clause is js.Default) {
-            return new js.Default(translateInBlock(clause.body));
+            return new js.Default(translateToBlock(clause.body));
           }
         }).toList();
         addStatement(new js.Switch(key, cases));
@@ -1426,14 +1435,14 @@
   /// See the comments of [rewriteFunction] for more explanation.
   void visitTry(js.Try node) {
     if (!shouldTransform(node)) {
-      js.Block body = translateInBlock(node.body);
+      js.Block body = translateToBlock(node.body);
       js.Catch catchPart = (node.catchPart == null)
           ? null
           : new js.Catch(node.catchPart.declaration,
-              translateInBlock(node.catchPart.body));
+              translateToBlock(node.catchPart.body));
       js.Block finallyPart = (node.finallyPart == null)
           ? null
-          : translateInBlock(node.finallyPart);
+          : translateToBlock(node.finallyPart);
       addStatement(new js.Try(body, catchPart, finallyPart));
       return;
     }
@@ -1576,7 +1585,7 @@
       bool oldInsideUntranslated = insideUntranslatedBreakable;
       insideUntranslatedBreakable = true;
       withExpression(node.condition, (js.Expression condition) {
-        addStatement(new js.While(condition, translateInBlock(node.body)));
+        addStatement(new js.While(condition, translateToStatement(node.body)));
       }, store: false);
       insideUntranslatedBreakable = oldInsideUntranslated;
       return;
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index cbae712..8433ec4 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -2,7 +2,81 @@
 // for 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 js_backend;
+library js_backend.backend;
+
+import 'dart:async' show Future;
+
+import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
+
+import '../closure.dart';
+import '../common.dart';
+import '../common/backend_api.dart'
+    show Backend, ImpactTransformer, ForeignResolver, NativeRegistry;
+import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem;
+import '../common/names.dart' show Identifiers, Selectors, Uris;
+import '../common/registry.dart' show EagerRegistry, Registry;
+import '../common/resolution.dart'
+    show
+        Frontend,
+        Resolution,
+        ResolutionImpact;
+import '../common/tasks.dart' show CompilerTask;
+import '../common/work.dart' show ItemCompilationContext;
+import '../compiler.dart' show Compiler;
+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 '../enqueue.dart' show Enqueuer, ResolutionEnqueuer;
+import '../io/position_information.dart' show PositionSourceInformationStrategy;
+import '../io/source_information.dart' show SourceInformationStrategy;
+import '../io/start_end_information.dart'
+    show StartEndSourceInformationStrategy;
+import '../js/js.dart' as jsAst;
+import '../js/js.dart' show js;
+import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy;
+import '../js/rewrite_async.dart';
+import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
+import '../library_loader.dart' show LibraryLoader, LoadedLibraries;
+import '../native/native.dart' as native;
+import '../ssa/builder.dart' show SsaFunctionCompiler;
+import '../ssa/nodes.dart' show HInstruction;
+import '../tree/tree.dart';
+import '../types/types.dart';
+import '../universe/call_structure.dart' show CallStructure;
+import '../universe/selector.dart' show Selector, SelectorKind;
+import '../universe/universe.dart';
+import '../universe/use.dart'
+    show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
+import '../universe/feature.dart';
+import '../universe/world_impact.dart'
+    show
+        ImpactStrategy,
+        ImpactUseCase,
+        TransformedWorldImpact,
+        WorldImpact,
+        WorldImpactVisitor;
+import '../util/util.dart';
+import '../world.dart' show ClassWorld;
+import 'backend_helpers.dart';
+import 'backend_impact.dart';
+import 'backend_serialization.dart' show JavaScriptBackendSerialization;
+import 'checked_mode_helpers.dart';
+import 'constant_handler_javascript.dart';
+import 'custom_elements_analysis.dart';
+import 'js_interop_analysis.dart' show JsInteropAnalysis;
+import 'lookup_map_analysis.dart' show LookupMapAnalysis;
+import 'namer.dart';
+import 'native_data.dart' show NativeData;
+import 'no_such_method_registry.dart';
+import 'patch_resolver.dart';
+import 'type_variable_handler.dart';
+
+part 'runtime_types.dart';
 
 const VERBOSE_OPTIMIZER_HINTS = false;
 
@@ -232,8 +306,6 @@
 
   bool get supportsReflection => emitter.emitter.supportsReflection;
 
-  bool get supportsAsyncAwait => true;
-
   final Annotations annotations;
 
   /// Set of classes that need to be considered for reflection although not
@@ -554,9 +626,7 @@
     constantCompilerTask = new JavaScriptConstantTask(compiler);
     impactTransformer = new JavaScriptImpactTransformer(this);
     patchResolverTask = new PatchResolverTask(compiler);
-    functionCompiler = compiler.options.useCpsIr
-        ? new CpsFunctionCompiler(compiler, this, sourceInformationStrategy)
-        : new SsaFunctionCompiler(this, sourceInformationStrategy);
+    functionCompiler = new SsaFunctionCompiler(this, sourceInformationStrategy);
     serialization = new JavaScriptBackendSerialization(this);
   }
 
@@ -660,7 +730,7 @@
   }
 
   bool usedByBackend(Element element) {
-    if (element.isParameter ||
+    if (element.isRegularParameter ||
         element.isInitializingFormal ||
         element.isField) {
       if (usedByBackend(element.enclosingElement)) return true;
@@ -669,7 +739,7 @@
   }
 
   bool invokedReflectively(Element element) {
-    if (element.isParameter || element.isInitializingFormal) {
+    if (element.isRegularParameter || element.isInitializingFormal) {
       ParameterElement parameter = element;
       if (invokedReflectively(parameter.functionDeclaration)) return true;
     }
@@ -947,8 +1017,6 @@
       cls.ensureResolved(resolution);
       cls.forEachMember((ClassElement classElement, Element member) {
         if (member.name == Identifiers.call) {
-          reporter.reportErrorMessage(
-              member, MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS);
           return;
         }
         if (member.isSynthesized) return;
@@ -1130,6 +1198,7 @@
           }
           return ctor;
         }
+
         Element getMember(String name) {
           // The constructor is on the patch class, but dart2js unit tests don't
           // have a patch class.
@@ -1143,6 +1212,7 @@
           }
           return element;
         }
+
         helpers.mapLiteralConstructor = getFactory('_literal', 1);
         helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
         enqueueInResolution(helpers.mapLiteralConstructor, registry);
@@ -2509,17 +2579,7 @@
   }
 
   @override
-  bool enableCodegenWithErrorsIfSupported(Spannable node) {
-    if (compiler.options.useCpsIr) {
-      // TODO(25747): Support code generation with compile-time errors.
-      reporter.reportHintMessage(node, MessageKind.GENERIC, {
-        'text': "Generation of code with compile time errors is currently "
-            "not supported with the CPS IR."
-      });
-      return false;
-    }
-    return true;
-  }
+  bool enableCodegenWithErrorsIfSupported(Spannable node) => true;
 
   jsAst.Expression rewriteAsync(
       FunctionElement element, jsAst.Expression code) {
diff --git a/pkg/compiler/lib/src/js_backend/backend_helpers.dart b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
index 7613305..3852e2f 100644
--- a/pkg/compiler/lib/src/js_backend/backend_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
@@ -23,7 +23,6 @@
 import '../library_loader.dart' show LoadedLibraries;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
-
 import 'js_backend.dart';
 
 /// Helper classes and functions for the JavaScript backend.
@@ -246,6 +245,7 @@
       }
       return result;
     }
+
     jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror');
     boundClosureClass = lookupHelperClass('BoundClosure');
     closureClass = lookupHelperClass('Closure');
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index ee1dab9..7606e4d 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -8,7 +8,6 @@
 import '../core_types.dart' show CoreClasses;
 import '../dart_types.dart' show InterfaceType;
 import '../elements/elements.dart' show ClassElement, Element;
-
 import 'backend_helpers.dart';
 import 'constant_system_javascript.dart';
 import 'js_backend.dart';
diff --git a/pkg/compiler/lib/src/js_backend/backend_serialization.dart b/pkg/compiler/lib/src/js_backend/backend_serialization.dart
index 97da2f5..523f188 100644
--- a/pkg/compiler/lib/src/js_backend/backend_serialization.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_serialization.dart
@@ -4,22 +4,23 @@
 
 library js_backend.serialization;
 
-import '../common.dart';
 import '../common/backend_api.dart' show BackendSerialization;
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../js/js.dart' as js;
 import '../native/native.dart';
+import '../serialization/keys.dart';
 import '../serialization/serialization.dart'
     show DeserializerPlugin, ObjectDecoder, ObjectEncoder, SerializerPlugin;
-import '../serialization/keys.dart';
 import '../universe/side_effects.dart';
 import 'js_backend.dart';
 
 const String _BACKEND_DATA_TAG = 'jsBackendData';
 const Key DART_TYPES_RETURNED = const Key('dartTypesReturned');
+const Key THIS_TYPES_RETURNED = const Key('thisTypesReturned');
 const Key SPECIAL_TYPES_RETURNED = const Key('specialTypesReturned');
 const Key DART_TYPES_INSTANTIATED = const Key('dartTypesInstantiated');
+const Key THIS_TYPES_INSTANTIATED = const Key('thisTypesInstantiated');
 const Key SPECIAL_TYPES_INSTANTIATED = const Key('specialTypesInstantiated');
 const Key CODE_TEMPLATE = const Key('codeTemplate');
 const Key SIDE_EFFECTS = const Key('sideEffects');
@@ -150,15 +151,43 @@
 }
 
 class NativeBehaviorSerialization {
-  /// Returns a list of the [DartType]s in [types].
+  static const int NORMAL_TYPE = 0;
+  static const int THIS_TYPE = 1;
+  static const int SPECIAL_TYPE = 2;
+
+  static int getTypeKind(var type) {
+    if (type is DartType) {
+      // TODO(johnniwinther): Remove this when annotation are no longer resolved
+      // to this-types.
+      if (type is GenericType &&
+          type.isGeneric &&
+          type == type.element.thisType) {
+        return THIS_TYPE;
+      }
+      return NORMAL_TYPE;
+    }
+    return SPECIAL_TYPE;
+  }
+
+  /// Returns a list of the non-this-type [DartType]s in [types].
   static List<DartType> filterDartTypes(List types) {
-    return types.where((type) => type is DartType).toList();
+    return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
+  }
+
+  // TODO(johnniwinther): Remove this when annotation are no longer resolved
+  // to this-types.
+  /// Returns a list of the classes of this-types in [types].
+  static List<Element> filterThisTypes(List types) {
+    return types
+        .where((type) => getTypeKind(type) == THIS_TYPE)
+        .map((type) => type.element)
+        .toList();
   }
 
   /// Returns a list of the names of the [SpecialType]s in [types].
   static List<String> filterSpecialTypes(List types) {
     return types
-        .where((type) => type is SpecialType)
+        .where((type) => getTypeKind(type) == SPECIAL_TYPE)
         .map((SpecialType type) => type.name)
         .toList();
   }
@@ -167,11 +196,15 @@
       NativeBehavior behavior, ObjectEncoder encoder) {
     encoder.setTypes(
         DART_TYPES_RETURNED, filterDartTypes(behavior.typesReturned));
+    encoder.setElements(
+        THIS_TYPES_RETURNED, filterThisTypes(behavior.typesReturned));
     encoder.setStrings(
         SPECIAL_TYPES_RETURNED, filterSpecialTypes(behavior.typesReturned));
 
     encoder.setTypes(
         DART_TYPES_INSTANTIATED, filterDartTypes(behavior.typesInstantiated));
+    encoder.setElements(
+        THIS_TYPES_INSTANTIATED, filterThisTypes(behavior.typesInstantiated));
     encoder.setStrings(SPECIAL_TYPES_INSTANTIATED,
         filterSpecialTypes(behavior.typesInstantiated));
 
@@ -193,12 +226,20 @@
     behavior.typesReturned
         .addAll(decoder.getTypes(DART_TYPES_RETURNED, isOptional: true));
     behavior.typesReturned.addAll(decoder
+        .getElements(THIS_TYPES_RETURNED, isOptional: true)
+        .map((element) => element.thisType)
+        .toList());
+    behavior.typesReturned.addAll(decoder
         .getStrings(SPECIAL_TYPES_RETURNED, isOptional: true)
         .map(SpecialType.fromName));
 
     behavior.typesInstantiated
         .addAll(decoder.getTypes(DART_TYPES_INSTANTIATED, isOptional: true));
     behavior.typesInstantiated.addAll(decoder
+        .getElements(THIS_TYPES_INSTANTIATED, isOptional: true)
+        .map((element) => element.thisType)
+        .toList());
+    behavior.typesInstantiated.addAll(decoder
         .getStrings(SPECIAL_TYPES_INSTANTIATED, isOptional: true)
         .map(SpecialType.fromName));
 
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 409c44d..38e0070 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -2,7 +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.
 
-part of js_backend;
+import '../compiler.dart' show Compiler;
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../js/js.dart' as jsAst;
+import '../js/js.dart' show js;
+import '../ssa/codegen.dart' show SsaCodeGenerator;
+import '../ssa/nodes.dart' show HTypeConversion;
+import '../universe/call_structure.dart' show CallStructure;
+import '../universe/use.dart' show StaticUse;
+import 'backend.dart';
 
 class CheckedModeHelper {
   final String name;
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
deleted file mode 100644
index d2c539d..0000000
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ /dev/null
@@ -1,1241 +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 code_generator;
-
-import 'glue.dart';
-
-import '../../closure.dart' show ClosureClassElement;
-import '../../common/codegen.dart' show CodegenRegistry;
-import '../../constants/values.dart';
-import '../../dart_types.dart';
-import '../../elements/elements.dart';
-import '../../io/source_information.dart' show SourceInformation;
-import '../../js/js.dart' as js;
-import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
-import '../../tree_ir/tree_ir_nodes.dart'
-    show BuiltinMethod, BuiltinOperator, isCompoundableOperator;
-import '../../types/types.dart' show TypeMask;
-import '../../universe/call_structure.dart' show CallStructure;
-import '../../universe/selector.dart' show Selector;
-import '../../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
-import '../../util/maplet.dart';
-
-class CodegenBailout {
-  final tree_ir.Node node;
-  final String reason;
-  CodegenBailout(this.node, this.reason);
-  String get message {
-    return 'bailout${node != null ? " on $node" : ""}: $reason';
-  }
-}
-
-class CodeGenerator extends tree_ir.StatementVisitor
-    with tree_ir.ExpressionVisitor<js.Expression> {
-  final CodegenRegistry registry;
-
-  final Glue glue;
-
-  ExecutableElement currentFunction;
-
-  /// Maps variables to their name.
-  Map<tree_ir.Variable, String> variableNames = <tree_ir.Variable, String>{};
-
-  /// Maps local constants to their name.
-  Maplet<VariableElement, String> constantNames =
-      new Maplet<VariableElement, String>();
-
-  /// Variable names that have already been used. Used to avoid name clashes.
-  Set<String> usedVariableNames = new Set<String>();
-
-  final tree_ir.FallthroughStack fallthrough = new tree_ir.FallthroughStack();
-
-  /// Stacks whose top element is the current target of an unlabeled break
-  /// or continue. For continues, this is the loop node itself.
-  final tree_ir.FallthroughStack shortBreak = new tree_ir.FallthroughStack();
-  final tree_ir.FallthroughStack shortContinue = new tree_ir.FallthroughStack();
-
-  /// 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>();
-
-  CodeGenerator(this.glue, this.registry);
-
-  /// Generates JavaScript code for the body of [function].
-  js.Fun buildFunction(tree_ir.FunctionDefinition function) {
-    registerDefaultParameterValues(function.element);
-    currentFunction = function.element;
-    tree_ir.Statement statement = function.body;
-    while (statement != null) {
-      statement = visitStatement(statement);
-    }
-
-    List<js.Parameter> parameters = new List<js.Parameter>();
-    Set<tree_ir.Variable> parameterSet = new Set<tree_ir.Variable>();
-    Set<String> declaredVariables = new Set<String>();
-
-    for (tree_ir.Variable parameter in function.parameters) {
-      String name = getVariableName(parameter);
-      parameters.add(new js.Parameter(name));
-      parameterSet.add(parameter);
-      declaredVariables.add(name);
-    }
-
-    List<js.VariableInitialization> jsVariables = <js.VariableInitialization>[];
-
-    // Declare variables with an initializer. Pull statements into the
-    // initializer until we find a statement that cannot be pulled in.
-    int accumulatorIndex = 0;
-    while (accumulatorIndex < accumulator.length) {
-      js.Node node = accumulator[accumulatorIndex];
-
-      // Check that node is an assignment to a local variable.
-      if (node is! js.ExpressionStatement) break;
-      js.ExpressionStatement stmt = node;
-      if (stmt.expression is! js.Assignment) break;
-      js.Assignment assign = stmt.expression;
-      if (assign.leftHandSide is! js.VariableUse) break;
-      if (assign.op != null) break; // Compound assignment.
-      js.VariableUse use = assign.leftHandSide;
-
-      // Do not touch non-local variables.
-      if (!usedVariableNames.contains(use.name)) break;
-
-      // We cannot declare a variable more than once.
-      if (!declaredVariables.add(use.name)) break;
-
-      js.VariableInitialization jsVariable = new js.VariableInitialization(
-          new js.VariableDeclaration(use.name), assign.value);
-      jsVariables.add(jsVariable);
-
-      ++accumulatorIndex;
-    }
-
-    // If the last statement is a for loop with an initializer expression, try
-    // to pull that expression into an initializer as well.
-    pullFromForLoop: if (accumulatorIndex < accumulator.length &&
-        accumulator[accumulatorIndex] is js.For) {
-      js.For forLoop = accumulator[accumulatorIndex];
-      if (forLoop.init is! js.Assignment) break pullFromForLoop;
-      js.Assignment assign = forLoop.init;
-      if (assign.leftHandSide is! js.VariableUse) break pullFromForLoop;
-      if (assign.op != null) break pullFromForLoop; // Compound assignment.
-      js.VariableUse use = assign.leftHandSide;
-
-      // Do not touch non-local variables.
-      if (!usedVariableNames.contains(use.name)) break pullFromForLoop;
-
-      // We cannot declare a variable more than once.
-      if (!declaredVariables.add(use.name)) break pullFromForLoop;
-
-      js.VariableInitialization jsVariable = new js.VariableInitialization(
-          new js.VariableDeclaration(use.name), assign.value);
-      jsVariables.add(jsVariable);
-
-      // Remove the initializer from the for loop.
-      accumulator[accumulatorIndex] =
-          new js.For(null, forLoop.condition, forLoop.update, forLoop.body);
-    }
-
-    // Discard the statements that were pulled in the initializer.
-    if (accumulatorIndex > 0) {
-      accumulator = accumulator.sublist(accumulatorIndex);
-    }
-
-    // Declare remaining variables.
-    for (tree_ir.Variable variable in variableNames.keys) {
-      String name = getVariableName(variable);
-      if (declaredVariables.contains(name)) continue;
-      js.VariableInitialization jsVariable =
-          new js.VariableInitialization(new js.VariableDeclaration(name), null);
-      jsVariables.add(jsVariable);
-    }
-
-    if (jsVariables.length > 0) {
-      // Would be nice to avoid inserting at the beginning of list.
-      accumulator.insert(
-          0,
-          new js.ExpressionStatement(new js.VariableDeclarationList(jsVariables)
-              .withSourceInformation(function.sourceInformation)));
-    }
-    return new js.Fun(parameters, new js.Block(accumulator));
-  }
-
-  @override
-  js.Expression visitExpression(tree_ir.Expression node) {
-    js.Expression result = node.accept(this);
-    if (result == null) {
-      glue.reportInternalError('$node did not produce code.');
-    }
-    return result;
-  }
-
-  /// Generates a name for the given variable. First trying with the name of
-  /// the [Variable.element] if it is non-null.
-  String getVariableName(tree_ir.Variable variable) {
-    // Functions are not nested in the JS backend.
-    assert(variable.host == currentFunction);
-
-    // Get the name if we already have one.
-    String name = variableNames[variable];
-    if (name != null) {
-      return name;
-    }
-
-    // Synthesize a variable name that isn't used elsewhere.
-    String prefix = variable.element == null ? 'v' : variable.element.name;
-    int counter = 0;
-    name = glue.safeVariableName(
-        variable.element == null ? '$prefix$counter' : variable.element.name);
-    while (!usedVariableNames.add(name)) {
-      ++counter;
-      name = '$prefix$counter';
-    }
-    variableNames[variable] = name;
-
-    return name;
-  }
-
-  List<js.Expression> visitExpressionList(
-      List<tree_ir.Expression> expressions) {
-    List<js.Expression> result = new List<js.Expression>(expressions.length);
-    for (int i = 0; i < expressions.length; ++i) {
-      result[i] = visitExpression(expressions[i]);
-    }
-    return result;
-  }
-
-  giveup(tree_ir.Node node,
-      [String reason = 'unimplemented in CodeGenerator']) {
-    throw new CodegenBailout(node, reason);
-  }
-
-  @override
-  js.Expression visitConditional(tree_ir.Conditional node) {
-    return new js.Conditional(
-        visitExpression(node.condition),
-        visitExpression(node.thenExpression),
-        visitExpression(node.elseExpression));
-  }
-
-  js.Expression buildConstant(ConstantValue constant,
-      {SourceInformation sourceInformation}) {
-    registry.registerCompileTimeConstant(constant);
-    return glue
-        .constantReference(constant)
-        .withSourceInformation(sourceInformation);
-  }
-
-  @override
-  js.Expression visitConstant(tree_ir.Constant node) {
-    return buildConstant(node.value, sourceInformation: node.sourceInformation);
-  }
-
-  js.Expression buildStaticInvoke(Element target, List<js.Expression> arguments,
-      {SourceInformation sourceInformation}) {
-    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);
-  }
-
-  @override
-  js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) {
-    if (node.constant != null) return giveup(node);
-
-    registry.registerInstantiation(node.type);
-    FunctionElement target = node.target;
-    List<js.Expression> arguments = visitExpressionList(node.arguments);
-    return buildStaticInvoke(target, arguments,
-        sourceInformation: node.sourceInformation);
-  }
-
-  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.registerDynamicUse(new DynamicUse(call, null));
-    }
-  }
-
-  @override
-  js.Expression visitInvokeMethod(tree_ir.InvokeMethod 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))
-        .withSourceInformation(node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) {
-    FunctionElement target = node.target;
-    List<js.Expression> arguments = visitExpressionList(node.arguments);
-    return buildStaticInvoke(target, arguments,
-        sourceInformation: node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) {
-    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('#.#(#)', [
-        visitExpression(node.receiver),
-        glue.instanceMethodName(node.target),
-        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),
-      visitExpression(node.receiver),
-      visitExpressionList(node.arguments)
-    ]).withSourceInformation(node.sourceInformation);
-  }
-
-  @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);
-    return new js.ArrayInitializer(entries);
-  }
-
-  @override
-  js.Expression visitLogicalOperator(tree_ir.LogicalOperator node) {
-    return new js.Binary(
-        node.operator, visitExpression(node.left), visitExpression(node.right));
-  }
-
-  @override
-  js.Expression visitNot(tree_ir.Not node) {
-    return new js.Prefix("!", visitExpression(node.operand));
-  }
-
-  @override
-  js.Expression visitThis(tree_ir.This node) {
-    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.
-  bool tryRegisterInstanceofCheck(ClassElement class_) {
-    if (glue.classWorld.isInstantiated(class_)) {
-      // Ensure the class remains instantiated during backend tree-shaking.
-      // TODO(asgerf): We could have a more precise hook to inform the emitter
-      // that the JS constructor function is needed, without the class being
-      // instantiated.
-      registry.registerInstantiatedClass(class_);
-      return true;
-    }
-    // Will throw if the JS constructor is not emitted, so do not allow the
-    // instanceof check.  This should only happen when certain optimization
-    // passes are disabled, as the type check itself is trivial.
-    return false;
-  }
-
-  @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) {
-      registry.registerTypeUse(new TypeUse.isCheck(type));
-      ClassElement clazz = type.element;
-
-      if (glue.isStringClass(clazz)) {
-        if (node.isTypeTest) {
-          return js.js(r'typeof # === "string"', <js.Expression>[value]);
-        }
-        // TODO(sra): Implement fast cast via calling 'stringTypeCast'.
-      } else if (glue.isBoolClass(clazz)) {
-        if (node.isTypeTest) {
-          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) &&
-          tryRegisterInstanceofCheck(clazz)) {
-        return js.js('# instanceof #', [value, glue.constructorAccess(clazz)]);
-      }
-
-      // The helper we use needs the JSArray class to exist, but for some
-      // reason the helper does not cause this dependency to be registered.
-      // TODO(asgerf): Most programs need List anyway, but we should fix this.
-      registry.registerInstantiatedClass(glue.listClass);
-
-      // We use one of the two helpers:
-      //
-      //     checkSubtype(value, $isT, typeArgs, $asT)
-      //     subtypeCast(value, $isT, typeArgs, $asT)
-      //
-      // Any of the last two arguments may be null if there are no type
-      // arguments, and/or if no substitution is required.
-      Element function =
-          node.isTypeTest ? glue.getCheckSubtype() : glue.getSubtypeCast();
-
-      js.Expression isT = js.quoteName(glue.getTypeTestTag(type));
-
-      js.Expression typeArgumentArray = typeArguments.isNotEmpty
-          ? new js.ArrayInitializer(typeArguments)
-          : new js.LiteralNull();
-
-      js.Expression asT = glue.hasStrictSubtype(clazz)
-          ? js.quoteName(glue.getTypeSubstitutionTag(clazz))
-          : new js.LiteralNull();
-
-      return buildStaticHelperInvocation(
-          function, <js.Expression>[value, isT, typeArgumentArray, asT]);
-    } else if (type is TypeVariableType || type is FunctionType) {
-      registry.registerTypeUse(new TypeUse.isCheck(type));
-
-      Element function = node.isTypeTest
-          ? glue.getCheckSubtypeOfRuntimeType()
-          : glue.getSubtypeOfRuntimeTypeCast();
-
-      // The only type argument is the type held in the type variable.
-      js.Expression typeValue = typeArguments.single;
-
-      return buildStaticHelperInvocation(
-          function, <js.Expression>[value, typeValue]);
-    }
-    return giveup(node, 'type check unimplemented for $type.');
-  }
-
-  @override
-  js.Expression visitGetTypeTestProperty(tree_ir.GetTypeTestProperty node) {
-    js.Expression object = visitExpression(node.object);
-    DartType dartType = node.dartType;
-    assert(dartType.isInterfaceType);
-    registry.registerTypeUse(new TypeUse.isCheck(dartType));
-    //glue.registerIsCheck(dartType, registry);
-    js.Expression property = glue.getTypeTestTag(dartType);
-    return js.js(r'#.#', [object, property]);
-  }
-
-  @override
-  js.Expression visitVariableUse(tree_ir.VariableUse node) {
-    return buildVariableAccess(node.variable)
-        .withSourceInformation(node.sourceInformation);
-  }
-
-  js.Expression buildVariableAccess(tree_ir.Variable variable) {
-    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,
-      {SourceInformation sourceInformation, BuiltinOperator compound}) {
-    if (isOneConstant(value)) {
-      if (compound == BuiltinOperator.NumAdd) {
-        return new js.Prefix('++', leftHand)
-            .withSourceInformation(sourceInformation);
-      }
-      if (compound == BuiltinOperator.NumSubtract) {
-        return new js.Prefix('--', leftHand)
-            .withSourceInformation(sourceInformation);
-      }
-    }
-    if (compound != null) {
-      return new js.Assignment.compound(
-              leftHand, getAsCompoundOperator(compound), visitExpression(value))
-          .withSourceInformation(sourceInformation);
-    }
-    return new js.Assignment(leftHand, visitExpression(value))
-        .withSourceInformation(sourceInformation);
-  }
-
-  @override
-  js.Expression visitAssign(tree_ir.Assign node) {
-    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, sourceInformation: node.sourceInformation);
-      }
-    }
-    return makeAssignment(variable, node.value,
-        sourceInformation: node.sourceInformation);
-  }
-
-  @override
-  void visitContinue(tree_ir.Continue node) {
-    tree_ir.Statement next = fallthrough.target;
-    if (node.target.binding == next ||
-        next is tree_ir.Continue && node.target == next.target) {
-      // Fall through to continue target or to equivalent continue.
-      fallthrough.use();
-    } else if (node.target.binding == shortContinue.target) {
-      // The target is the immediately enclosing loop.
-      shortContinue.use();
-      accumulator.add(new js.Continue(null));
-    } else {
-      accumulator.add(new js.Continue(makeLabel(node.target)));
-    }
-  }
-
-  /// True if [other] is the target of [node] or is a [Break] with the same
-  /// target. This means jumping to [other] is equivalent to executing [node].
-  bool isEffectiveBreakTarget(tree_ir.Break node, tree_ir.Statement other) {
-    return node.target.binding.next == other ||
-        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)) {
-      // Fall through to break target or to equivalent break.
-      fallthrough.use();
-    } else if (isEffectiveBreakTarget(node, shortBreak.target)) {
-      // 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 {
-      accumulator.add(new js.Break(makeLabel(node.target)));
-    }
-  }
-
-  @override
-  visitExpressionStatement(tree_ir.ExpressionStatement node) {
-    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.
-      SourceInformation sourceInformation = node.expression.sourceInformation;
-      accumulator
-          .add(new js.Return(exp).withSourceInformation(sourceInformation));
-      return null;
-    } else {
-      accumulator.add(new js.ExpressionStatement(exp));
-      return 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
-  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);
-      accumulator.add(new js.If(condition, thenBody, elseBody)
-          .withSourceInformation(node.sourceInformation));
-      return null;
-    } else {
-      // The 'then' body cannot complete normally, so emit a short 'if'
-      // and put the 'else' body after it.
-      accumulator.add(new js.If.noElse(condition, thenBody)
-          .withSourceInformation(node.sourceInformation));
-      return node.elseStatement;
-    }
-  }
-
-  @override
-  visitLabeledStatement(tree_ir.LabeledStatement node) {
-    fallthrough.push(node.next);
-    js.Statement body = buildBodyStatement(node.body);
-    fallthrough.pop();
-    accumulator.add(insertLabel(node.label, body));
-    return 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) {
-    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.
-  js.Statement _bodyAsStatement() {
-    if (accumulator.length == 0) {
-      return new js.EmptyStatement();
-    }
-    if (accumulator.length == 1) {
-      return accumulator.single;
-    }
-    return new js.Block(accumulator);
-  }
-
-  /// Builds a nested statement.
-  js.Statement buildBodyStatement(tree_ir.Statement statement) {
-    List<js.Statement> savedAccumulator = accumulator;
-    accumulator = <js.Statement>[];
-    while (statement != null) {
-      statement = visitStatement(statement);
-    }
-    js.Statement result = _bodyAsStatement();
-    accumulator = savedAccumulator;
-    return result;
-  }
-
-  js.Block buildBodyBlock(tree_ir.Statement statement) {
-    List<js.Statement> savedAccumulator = accumulator;
-    accumulator = <js.Statement>[];
-    while (statement != null) {
-      statement = visitStatement(statement);
-    }
-    js.Statement result = new js.Block(accumulator);
-    accumulator = savedAccumulator;
-    return result;
-  }
-
-  js.Expression makeSequence(List<tree_ir.Expression> list) {
-    return list.map(visitExpression).reduce((x, y) => new js.Binary(',', x, y));
-  }
-
-  @override
-  visitFor(tree_ir.For node) {
-    js.Expression condition = visitExpression(node.condition);
-    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();
-    js.Statement loopNode;
-    if (node.updates.isEmpty) {
-      loopNode = new js.While(condition, body);
-    } else {
-      // Compile as a for loop.
-      js.Expression init;
-      if (accumulator.isNotEmpty &&
-          accumulator.last is js.ExpressionStatement) {
-        // Take the preceding expression from the accumulator and use
-        // it as the initializer expression.
-        js.ExpressionStatement initStmt = accumulator.removeLast();
-        init = initStmt.expression;
-      }
-      js.Expression update = makeSequence(node.updates);
-      loopNode = new js.For(init, condition, update, body);
-    }
-    accumulator.add(insertLabel(node.label, loopNode));
-    return node.next;
-  }
-
-  @override
-  void visitWhileTrue(tree_ir.WhileTrue node) {
-    // A short break in the while will jump to the current fallthrough target.
-    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) {
-      // Short breaks use the current fallthrough target.
-      fallthrough.use();
-    }
-    shortBreak.pop();
-    accumulator
-        .add(insertLabel(node.label, new js.For(null, null, null, jsBody)));
-  }
-
-  bool isNull(tree_ir.Expression node) {
-    return node is tree_ir.Constant && node.value.isNull;
-  }
-
-  @override
-  void visitReturn(tree_ir.Return node) {
-    if (isNull(node.value) && fallthrough.target == null) {
-      // Do nothing. Implicitly return JS undefined by falling over the end.
-      registry.registerCompileTimeConstant(new NullConstantValue());
-      fallthrough.use();
-    } else {
-      accumulator.add(new js.Return(visitExpression(node.value))
-          .withSourceInformation(node.sourceInformation));
-    }
-  }
-
-  @override
-  void visitThrow(tree_ir.Throw node) {
-    accumulator.add(new js.Throw(visitExpression(node.value)));
-  }
-
-  @override
-  void visitUnreachable(tree_ir.Unreachable node) {
-    if (emitUnreachableAsReturn.last) {
-      // Emit a return to assist local analysis in the VM.
-      accumulator.add(new js.Return());
-    }
-  }
-
-  @override
-  void visitTry(tree_ir.Try node) {
-    js.Block tryBlock = buildBodyBlock(node.tryBody);
-    tree_ir.Variable exceptionVariable = node.catchParameters.first;
-    js.VariableDeclaration exceptionParameter =
-        new js.VariableDeclaration(getVariableName(exceptionVariable));
-    js.Block catchBlock = buildBodyBlock(node.catchBody);
-    js.Catch catchPart = new js.Catch(exceptionParameter, catchBlock);
-    accumulator.add(new js.Try(tryBlock, catchPart, null));
-  }
-
-  @override
-  js.Expression visitCreateBox(tree_ir.CreateBox node) {
-    return new js.ObjectInitializer(const <js.Property>[]);
-  }
-
-  @override
-  js.Expression visitCreateInstance(tree_ir.CreateInstance node) {
-    ClassElement classElement = node.classElement;
-    // TODO(asgerf): To allow inlining of InvokeConstructor, CreateInstance must
-    //               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.registerInstantiation(classElement.rawType);
-    if (classElement is ClosureClassElement) {
-      registry.registerInstantiatedClosure(classElement.methodElement);
-    }
-    js.Expression instance = new js.New(glue.constructorAccess(classElement),
-            visitExpressionList(node.arguments))
-        .withSourceInformation(node.sourceInformation);
-
-    tree_ir.Expression typeInformation = node.typeInformation;
-    if (typeInformation != null) {
-      FunctionElement helper = glue.getAddRuntimeTypeInformation();
-      js.Expression typeArguments = visitExpression(typeInformation);
-      return buildStaticHelperInvocation(
-          helper, <js.Expression>[instance, typeArguments],
-          sourceInformation: node.sourceInformation);
-    } else {
-      return instance;
-    }
-  }
-
-  @override
-  js.Expression visitCreateInvocationMirror(
-      tree_ir.CreateInvocationMirror node) {
-    js.Expression name = js.string(node.selector.name);
-    js.Expression internalName =
-        js.quoteName(glue.invocationName(node.selector));
-    js.Expression kind = js.number(node.selector.invocationMirrorKind);
-    js.Expression arguments =
-        new js.ArrayInitializer(visitExpressionList(node.arguments));
-    js.Expression argumentNames = new js.ArrayInitializer(
-        node.selector.namedArguments.map(js.string).toList(growable: false));
-    return buildStaticHelperInvocation(glue.createInvocationMirrorMethod,
-        <js.Expression>[name, internalName, kind, arguments, argumentNames]);
-  }
-
-  @override
-  js.Expression visitInterceptor(tree_ir.Interceptor node) {
-    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)
-    ]).withSourceInformation(node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitGetField(tree_ir.GetField node) {
-    registry.registerStaticUse(new StaticUse.fieldGet(node.field));
-    return new js.PropertyAccess(visitExpression(node.object),
-            glue.instanceFieldPropertyName(node.field))
-        .withSourceInformation(node.sourceInformation);
-  }
-
-  @override
-  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 makeAssignment(field, node.value,
-        compound: node.compound, sourceInformation: node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitGetStatic(tree_ir.GetStatic node) {
-    assert(node.element is FieldElement || node.element is FunctionElement);
-    if (node.element is FunctionElement) {
-      // Tear off a method.
-      registry.registerStaticUse(
-          new StaticUse.staticTearOff(node.element.declaration));
-      return glue
-          .isolateStaticClosureAccess(node.element)
-          .withSourceInformation(node.sourceInformation);
-    }
-    if (node.useLazyGetter) {
-      // Read a lazily initialized field.
-      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(new StaticUse.staticGet(node.element.declaration));
-    return glue
-        .staticFieldAccess(node.element)
-        .withSourceInformation(node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitSetStatic(tree_ir.SetStatic node) {
-    assert(node.element is FieldElement);
-    registry
-        .registerStaticUse(new StaticUse.staticSet(node.element.declaration));
-    js.Expression field = glue.staticFieldAccess(node.element);
-    return makeAssignment(field, node.value,
-        compound: node.compound, sourceInformation: node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitGetLength(tree_ir.GetLength node) {
-    return new js.PropertyAccess.field(visitExpression(node.object), 'length');
-  }
-
-  @override
-  js.Expression visitGetIndex(tree_ir.GetIndex node) {
-    return new js.PropertyAccess(
-        visitExpression(node.object), visitExpression(node.index));
-  }
-
-  @override
-  js.Expression visitSetIndex(tree_ir.SetIndex node) {
-    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(new StaticUse.staticInvoke(
-        helper, new CallStructure.unnamed(arguments.length)));
-    return buildStaticInvoke(helper, arguments,
-        sourceInformation: sourceInformation);
-  }
-
-  @override
-  js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) {
-    js.Expression typeToString = buildStaticHelperInvocation(
-        glue.getRuntimeTypeToString(), [visitExpression(node.value)],
-        sourceInformation: node.sourceInformation);
-    return buildStaticHelperInvocation(
-        glue.getCreateRuntimeType(), [typeToString],
-        sourceInformation: node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitReadTypeVariable(tree_ir.ReadTypeVariable node) {
-    ClassElement context = node.variable.element.enclosingClass;
-    js.Expression index = js.number(glue.getTypeVariableIndex(node.variable));
-    if (glue.needsSubstitutionForTypeVariableAccess(context)) {
-      js.Expression typeName = glue.getRuntimeTypeName(context);
-      return buildStaticHelperInvocation(glue.getRuntimeTypeArgument(),
-          [visitExpression(node.target), typeName, index],
-          sourceInformation: node.sourceInformation);
-    } else {
-      return buildStaticHelperInvocation(
-          glue.getTypeArgumentByIndex(), [visitExpression(node.target), index],
-          sourceInformation: node.sourceInformation);
-    }
-  }
-
-  @override
-  js.Expression visitTypeExpression(tree_ir.TypeExpression node) {
-    List<js.Expression> arguments = visitExpressionList(node.arguments);
-    switch (node.kind) {
-      case tree_ir.TypeExpressionKind.COMPLETE:
-        return glue.generateTypeRepresentation(
-            node.dartType, arguments, registry);
-      case tree_ir.TypeExpressionKind.INSTANCE:
-        // We expect only flat types for the INSTANCE representation.
-        assert(
-            node.dartType == (node.dartType.element as ClassElement).thisType);
-        registry.registerInstantiatedClass(glue.listClass);
-        return new js.ArrayInitializer(arguments);
-    }
-  }
-
-  js.Node handleForeignCode(tree_ir.ForeignCode node) {
-    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))
-        .withSourceInformation(node.sourceInformation);
-  }
-
-  @override
-  js.Expression visitForeignExpression(tree_ir.ForeignExpression node) {
-    return handleForeignCode(node);
-  }
-
-  @override
-  void visitForeignStatement(tree_ir.ForeignStatement node) {
-    accumulator.add(handleForeignCode(node));
-  }
-
-  @override
-  visitYield(tree_ir.Yield node) {
-    js.Expression value = visitExpression(node.input);
-    accumulator.add(new js.DartYield(value, node.hasStar));
-    return node.next;
-  }
-
-  @override
-  visitReceiverCheck(tree_ir.ReceiverCheck 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.useSelector
-        ? js.js('#.#', [value, glue.invocationName(node.selector)])
-        : js.js('#.toString', [value]);
-    if (node.useInvoke) {
-      access = new js.Call(access, []);
-    }
-    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));
-    }
-    return node.next;
-  }
-
-  @override
-  js.Expression visitApplyBuiltinOperator(tree_ir.ApplyBuiltinOperator node) {
-    List<js.Expression> args = visitExpressionList(node.arguments);
-
-    js.Expression createExpression() {
-      switch (node.operator) {
-        case BuiltinOperator.NumAdd:
-          return new js.Binary('+', args[0], args[1]);
-        case BuiltinOperator.NumSubtract:
-          return new js.Binary('-', args[0], args[1]);
-        case BuiltinOperator.NumMultiply:
-          return new js.Binary('*', args[0], args[1]);
-        case BuiltinOperator.NumDivide:
-          return new js.Binary('/', args[0], args[1]);
-        case BuiltinOperator.NumRemainder:
-          return new js.Binary('%', args[0], args[1]);
-        case BuiltinOperator.NumTruncatingDivideToSigned32:
-          return js.js('(# / #) | 0', args);
-        case BuiltinOperator.NumAnd:
-          return normalizeBitOp(js.js('# & #', args), node);
-        case BuiltinOperator.NumOr:
-          return normalizeBitOp(js.js('# | #', args), node);
-        case BuiltinOperator.NumXor:
-          return normalizeBitOp(js.js('# ^ #', args), node);
-        case BuiltinOperator.NumLt:
-          return new js.Binary('<', args[0], args[1]);
-        case BuiltinOperator.NumLe:
-          return new js.Binary('<=', args[0], args[1]);
-        case BuiltinOperator.NumGt:
-          return new js.Binary('>', args[0], args[1]);
-        case BuiltinOperator.NumGe:
-          return new js.Binary('>=', args[0], args[1]);
-        case BuiltinOperator.NumShl:
-          return normalizeBitOp(js.js('# << #', args), node);
-        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.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]);
-        case BuiltinOperator.StrictNeq:
-          return new js.Binary('!==', args[0], args[1]);
-        case BuiltinOperator.LooseEq:
-          return new js.Binary('==', args[0], args[1]);
-        case BuiltinOperator.LooseNeq:
-          return new js.Binary('!=', args[0], args[1]);
-        case BuiltinOperator.IsFalsy:
-          return new js.Prefix('!', args[0]);
-        case BuiltinOperator.IsNumber:
-          return js.js('typeof # === "number"', args);
-        case BuiltinOperator.IsNotNumber:
-          return js.js('typeof # !== "number"', args);
-        case BuiltinOperator.IsFloor:
-          return js.js('Math.floor(#) === #', args);
-        case BuiltinOperator.IsInteger:
-          return js.js('typeof # === "number" && Math.floor(#) === #', args);
-        case BuiltinOperator.IsNotInteger:
-          return js.js('typeof # !== "number" || Math.floor(#) !== #', args);
-        case BuiltinOperator.IsUnsigned32BitInteger:
-          return js.js('# >>> 0 === #', args);
-        case BuiltinOperator.IsNotUnsigned32BitInteger:
-          return js.js('# >>> 0 !== #', args);
-        case BuiltinOperator.IsFixedLengthJSArray:
-          // TODO(sra): Remove boolify (i.e. !!).
-          return js.js(r'!!#.fixed$length', args);
-        case BuiltinOperator.IsExtendableJSArray:
-          return js.js(r'!#.fixed$length', args);
-        case BuiltinOperator.IsModifiableJSArray:
-          return js.js(r'!#.immutable$list', args);
-        case BuiltinOperator.IsUnmodifiableJSArray:
-          // TODO(sra): Remove boolify (i.e. !!).
-          return js.js(r'!!#.immutable$list', args);
-      }
-    }
-
-    return createExpression().withSourceInformation(node.sourceInformation);
-  }
-
-  /// Add a uint32 normalization `op >>> 0` to [op] if it is not in 31-bit
-  /// range.
-  js.Expression normalizeBitOp(
-      js.Expression op, tree_ir.ApplyBuiltinOperator node) {
-    const MAX_UINT31 = 0x7fffffff;
-    const MAX_UINT32 = 0xffffffff;
-
-    int constantValue(tree_ir.Expression e) {
-      if (e is tree_ir.Constant) {
-        ConstantValue value = e.value;
-        if (!value.isInt) return null;
-        IntConstantValue intConstant = value;
-        if (intConstant.primitiveValue < 0) return null;
-        if (intConstant.primitiveValue > MAX_UINT32) return null;
-        return intConstant.primitiveValue;
-      }
-      return null;
-    }
-
-    /// Returns a value of the form 0b0001xxxx to represent the highest bit set
-    /// in the result.  This represents the range [0, 0b00011111], up to 32
-    /// bits.  `null` represents a result possibly outside the uint32 range.
-    int maxBitOf(tree_ir.Expression e) {
-      if (e is tree_ir.Constant) {
-        return constantValue(e);
-      }
-      if (e is tree_ir.ApplyBuiltinOperator) {
-        if (e.operator == BuiltinOperator.NumAnd) {
-          int left = maxBitOf(e.arguments[0]);
-          int right = maxBitOf(e.arguments[1]);
-          if (left == null && right == null) return MAX_UINT32;
-          if (left == null) return right;
-          if (right == null) return left;
-          return (left < right) ? left : right;
-        }
-        if (e.operator == BuiltinOperator.NumOr ||
-            e.operator == BuiltinOperator.NumXor) {
-          int left = maxBitOf(e.arguments[0]);
-          int right = maxBitOf(e.arguments[1]);
-          if (left == null || right == null) return MAX_UINT32;
-          return left | right;
-        }
-        if (e.operator == BuiltinOperator.NumShr) {
-          int right = constantValue(e.arguments[1]);
-          // NumShr is JavaScript '>>>' so always generates a uint32 result.
-          if (right == null || right <= 0 || right > 31) return MAX_UINT32;
-          int left = maxBitOf(e.arguments[0]);
-          if (left == null) return MAX_UINT32;
-          return left >> right;
-        }
-        if (e.operator == BuiltinOperator.NumShl) {
-          int right = constantValue(e.arguments[1]);
-          if (right == null || right <= 0 || right > 31) return MAX_UINT32;
-          int left = maxBitOf(e.arguments[0]);
-          if (left == null) return MAX_UINT32;
-          if (left.bitLength + right > 31) return MAX_UINT32;
-          return left << right;
-        }
-      }
-      return null;
-    }
-
-    int maxBit = maxBitOf(node);
-    if (maxBit != null && maxBit <= MAX_UINT31) return op;
-    return js.js('# >>> 0', [op]);
-  }
-
-  @override
-  js.Expression visitApplyBuiltinMethod(tree_ir.ApplyBuiltinMethod node) {
-    js.Expression receiver = visitExpression(node.receiver);
-    List<js.Expression> args = visitExpressionList(node.arguments);
-    switch (node.method) {
-      case BuiltinMethod.Push:
-        return js.js('#.push(#)', [receiver, args]);
-
-      case BuiltinMethod.Pop:
-        return js.js('#.pop()', [receiver]);
-
-      case BuiltinMethod.SetLength:
-        return js.js('#.length = #', [receiver, args[0]]);
-    }
-  }
-
-  @override
-  js.Expression visitAwait(tree_ir.Await node) {
-    return new js.Await(visitExpression(node.input));
-  }
-
-  /// 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
deleted file mode 100644
index 1650174..0000000
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ /dev/null
@@ -1,294 +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 code_generator_dependencies;
-
-import '../../common.dart';
-import '../../common/codegen.dart' show CodegenRegistry;
-import '../../compiler.dart' show Compiler;
-import '../../constants/values.dart';
-import '../../dart_types.dart' show DartType, TypeVariableType;
-import '../../elements/elements.dart';
-import '../../enqueue.dart' show CodegenEnqueuer;
-import '../../js/js.dart' as js;
-import '../../js_emitter/js_emitter.dart';
-import '../../native/native.dart' show NativeBehavior;
-import '../../types/types.dart';
-import '../../universe/selector.dart' show Selector;
-import '../../world.dart' show ClassWorld;
-import '../backend_helpers.dart' show BackendHelpers;
-import '../js_backend.dart';
-
-/// Encapsulates the dependencies of the function-compiler to the compiler,
-/// backend and emitter.
-// TODO(sigurdm): Should be refactored when we have a better feeling for the
-// interface.
-class Glue {
-  final Compiler _compiler;
-
-  CodegenEnqueuer get _enqueuer => _compiler.enqueuer.codegen;
-
-  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;
-
-  Glue(this._compiler);
-
-  ClassWorld get classWorld => _compiler.world;
-
-  DiagnosticReporter get reporter => _compiler.reporter;
-
-  js.Expression constantReference(ConstantValue value) {
-    return _emitter.constantReference(value);
-  }
-
-  reportInternalError(String message) {
-    reporter.internalError(CURRENT_ELEMENT_SPANNABLE, message);
-  }
-
-  bool isUsedAsMixin(ClassElement classElement) {
-    return classWorld.isUsedAsMixin(classElement);
-  }
-
-  js.Expression staticFunctionAccess(FunctionElement element) {
-    return _backend.emitter.staticFunctionAccess(element);
-  }
-
-  js.Expression isolateStaticClosureAccess(FunctionElement element) {
-    return _backend.emitter.isolateStaticClosureAccess(element);
-  }
-
-  js.Expression staticFieldAccess(FieldElement element) {
-    return _backend.emitter.staticFieldAccess(element);
-  }
-
-  js.Expression isolateLazyInitializerAccess(FieldElement element) {
-    return _backend.emitter.isolateLazyInitializerAccess(element);
-  }
-
-  bool isLazilyInitialized(FieldElement element) {
-    return _backend.constants.lazyStatics.contains(element);
-  }
-
-  String safeVariableName(String name) {
-    return _namer.safeVariableName(name);
-  }
-
-  ClassElement get listClass => _compiler.coreClasses.listClass;
-
-  ConstructorElement get mapLiteralConstructor {
-    return _helpers.mapLiteralConstructor;
-  }
-
-  ConstructorElement get mapLiteralConstructorEmpty {
-    return _helpers.mapLiteralConstructorEmpty;
-  }
-
-  FunctionElement get identicalFunction => _compiler.identicalFunction;
-
-  js.Name invocationName(Selector selector) {
-    return _namer.invocationName(selector);
-  }
-
-  FunctionElement get createInvocationMirrorMethod {
-    return _helpers.createInvocationMirror;
-  }
-
-  bool isInterceptedSelector(Selector selector) {
-    return _backend.isInterceptedSelector(selector);
-  }
-
-  bool isInterceptedMethod(Element element) {
-    return _backend.isInterceptedMethod(element);
-  }
-
-  bool isInterceptorClass(ClassElement element) {
-    return element.isSubclassOf(_helpers.jsInterceptorClass);
-  }
-
-  Set<ClassElement> getInterceptedClassesOn(Selector selector) {
-    return _backend.getInterceptedClassesOn(selector.name);
-  }
-
-  Set<ClassElement> get interceptedClasses {
-    return _backend.interceptedClasses;
-  }
-
-  void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
-    _backend.registerSpecializedGetInterceptor(classes);
-  }
-
-  js.Expression constructorAccess(ClassElement element) {
-    return _backend.emitter.constructorAccess(element);
-  }
-
-  js.Name instanceFieldPropertyName(Element field) {
-    return _namer.instanceFieldPropertyName(field);
-  }
-
-  js.Name instanceMethodName(FunctionElement element) {
-    return _namer.instanceMethodName(element);
-  }
-
-  js.Expression prototypeAccess(ClassElement e,
-      {bool hasBeenInstantiated: false}) {
-    return _emitter.prototypeAccess(e,
-        hasBeenInstantiated: hasBeenInstantiated);
-  }
-
-  js.Name getInterceptorName(Set<ClassElement> interceptedClasses) {
-    return _backend.namer.nameForGetInterceptor(interceptedClasses);
-  }
-
-  js.Expression getInterceptorLibrary() {
-    return new js.VariableUse(
-        _backend.namer.globalObjectFor(_helpers.interceptorsLibrary));
-  }
-
-  FunctionElement getWrapExceptionHelper() {
-    return _helpers.wrapExceptionHelper;
-  }
-
-  FunctionElement getExceptionUnwrapper() {
-    return _helpers.exceptionUnwrapper;
-  }
-
-  FunctionElement getTraceFromException() {
-    return _helpers.traceFromException;
-  }
-
-  FunctionElement getCreateRuntimeType() {
-    return _helpers.createRuntimeType;
-  }
-
-  FunctionElement getRuntimeTypeToString() {
-    return _helpers.runtimeTypeToString;
-  }
-
-  FunctionElement getRuntimeTypeArgument() {
-    return _helpers.getRuntimeTypeArgument;
-  }
-
-  FunctionElement getTypeArgumentByIndex() {
-    return _helpers.getTypeArgumentByIndex;
-  }
-
-  FunctionElement getAddRuntimeTypeInformation() {
-    return _helpers.setRuntimeTypeInfo;
-  }
-
-  /// checkSubtype(value, $isT, typeArgs, $asT)
-  FunctionElement getCheckSubtype() {
-    return _helpers.checkSubtype;
-  }
-
-  /// subtypeCast(value, $isT, typeArgs, $asT)
-  FunctionElement getSubtypeCast() {
-    return _helpers.subtypeCast;
-  }
-
-  /// checkSubtypeOfRuntime(value, runtimeType)
-  FunctionElement getCheckSubtypeOfRuntimeType() {
-    return _helpers.checkSubtypeOfRuntimeType;
-  }
-
-  /// subtypeOfRuntimeTypeCast(value, runtimeType)
-  FunctionElement getSubtypeOfRuntimeTypeCast() {
-    return _helpers.subtypeOfRuntimeTypeCast;
-  }
-
-  js.Expression getRuntimeTypeName(ClassElement cls) {
-    return js.quoteName(_namer.runtimeTypeName(cls));
-  }
-
-  int getTypeVariableIndex(TypeVariableType variable) {
-    return variable.element.index;
-  }
-
-  bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
-    ClassWorld classWorld = _compiler.world;
-    if (classWorld.isUsedAsMixin(cls)) return true;
-
-    return _compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) {
-      return !_backend.rti.isTrivialSubstitution(subclass, cls);
-    });
-  }
-
-  js.Expression generateTypeRepresentation(DartType dartType,
-      List<js.Expression> arguments, CodegenRegistry registry) {
-    int variableIndex = 0;
-    js.Expression representation = _backend.rtiEncoder
-        .getTypeRepresentation(dartType, (_) => arguments[variableIndex++]);
-    assert(variableIndex == arguments.length);
-    // Representation contains JavaScript Arrays.
-    registry.registerInstantiatedClass(_helpers.jsArrayClass);
-    return representation;
-  }
-
-  js.Name getTypeTestTag(DartType type) {
-    return _backend.namer.operatorIsType(type);
-  }
-
-  js.Name getTypeSubstitutionTag(ClassElement element) {
-    return _backend.namer.substitutionName(element);
-  }
-
-  bool operatorEqHandlesNullArgument(FunctionElement element) {
-    return _backend.operatorEqHandlesNullArgument(element);
-  }
-
-  bool hasStrictSubtype(ClassElement element) {
-    return _compiler.world.hasAnyStrictSubtype(element);
-  }
-
-  ClassElement get jsFixedArrayClass => _helpers.jsFixedArrayClass;
-  ClassElement get jsExtendableArrayClass => _helpers.jsExtendableArrayClass;
-  ClassElement get jsUnmodifiableArrayClass =>
-      _helpers.jsUnmodifiableArrayClass;
-  ClassElement get jsMutableArrayClass => _helpers.jsMutableArrayClass;
-
-  bool isStringClass(ClassElement classElement) =>
-      classElement == _helpers.jsStringClass ||
-      classElement == _compiler.coreClasses.stringClass;
-
-  bool isBoolClass(ClassElement classElement) =>
-      classElement == _helpers.jsBoolClass ||
-      classElement == _compiler.coreClasses.boolClass;
-
-  // 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.getConstantValue(elem.constant);
-  }
-
-  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);
-  }
-
-  bool methodUsesReceiverArgument(FunctionElement function) {
-    assert(isInterceptedMethod(function));
-    ClassElement class_ = function.enclosingClass.declaration;
-    return isInterceptorClass(class_) || isUsedAsMixin(class_);
-  }
-}
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
deleted file mode 100644
index 69b13f3..0000000
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ /dev/null
@@ -1,358 +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.
-
-/// Generate code using the cps-based IR pipeline.
-library code_generator_task;
-
-import 'glue.dart';
-import 'codegen.dart';
-import 'unsugar.dart';
-
-import '../js_backend.dart';
-
-import '../../common.dart';
-import '../../common/codegen.dart' show CodegenWorkItem;
-import '../../common/tasks.dart' show CompilerTask, GenericTask;
-import '../../compiler.dart' show Compiler;
-import '../../constants/constant_system.dart';
-import '../../cps_ir/cps_ir_builder_task.dart';
-import '../../cps_ir/cps_ir_nodes.dart' as cps;
-import '../../cps_ir/cps_ir_nodes_sexpr.dart';
-import '../../cps_ir/cps_ir_integrity.dart';
-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';
-import '../../js/js.dart' as js;
-import '../../js_backend/codegen/codegen.dart';
-import '../../io/source_information.dart' show SourceInformationStrategy;
-import '../../tree_ir/tree_ir_builder.dart' as tree_builder;
-import '../../tracer.dart';
-import '../../ssa/ssa.dart' as ssa;
-import '../../tree_ir/optimization/optimization.dart';
-import '../../tree_ir/optimization/optimization.dart' as tree_opt;
-import '../../tree_ir/tree_ir_integrity.dart';
-import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
-import '../../types/types.dart'
-    show FlatTypeMask, ForwardingTypeMask, TypeMask, UnionTypeMask;
-
-class CpsFunctionCompiler implements FunctionCompiler {
-  final ConstantSystem constantSystem;
-  // TODO(karlklose): remove the compiler.
-  final Compiler compiler;
-  final Glue glue;
-  final SourceInformationStrategy sourceInformationFactory;
-
-  // TODO(karlklose,sigurdm): remove and update dart-doc of [compile].
-  final FunctionCompiler fallbackCompiler;
-  TypeMaskSystem typeSystem;
-
-  Tracer get tracer => compiler.tracer;
-
-  final IrBuilderTask cpsBuilderTask;
-  final GenericTask cpsOptimizationTask;
-  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),
-        sourceInformationFactory = sourceInformationFactory,
-        constantSystem = backend.constantSystem,
-        compiler = compiler,
-        glue = new Glue(compiler),
-        cpsOptimizationTask =
-            new GenericTask('CPS optimization', compiler.measurer),
-        treeBuilderTask = new GenericTask('Tree builder', compiler.measurer),
-        treeOptimizationTask =
-            new GenericTask('Tree optimization', compiler.measurer) {
-    inliner = new Inliner(this);
-  }
-
-  String get name => 'CPS Ir pipeline';
-
-  JavaScriptBackend get backend => compiler.backend;
-
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  /// 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, () {
-      try {
-        // TODO(karlklose): remove this fallback when we do not need it for
-        // testing anymore.
-        if (false) {
-          reporter.log('Using SSA compiler for platform element $element');
-          return fallbackCompiler.compile(work);
-        }
-
-        if (tracer != null) {
-          tracer.traceCompilation('$element', null);
-        }
-        cps.FunctionDefinition cpsFunction = compileToCpsIr(element);
-        optimizeCpsBeforeInlining(cpsFunction);
-        applyCpsPass(inliner, cpsFunction);
-        optimizeCpsAfterInlining(cpsFunction);
-        cpsIntegrityChecker = null;
-        tree_ir.FunctionDefinition treeFunction = compileToTreeIr(cpsFunction);
-        treeFunction = optimizeTreeIr(treeFunction);
-        return compileToJavaScript(work, treeFunction);
-      } on CodegenBailout catch (e) {
-        String message = "Unable to compile $element with the new compiler.\n"
-            "  Reason: ${e.message}";
-        reporter.internalError(element, message);
-      }
-    });
-  }
-
-  void giveUp(String reason) {
-    throw new CodegenBailout(null, reason);
-  }
-
-  void traceGraph(String title, var irObject) {
-    if (tracer != null) {
-      tracer.traceGraph(title, irObject);
-    }
-  }
-
-  String stringify(cps.FunctionDefinition node) {
-    return new SExpressionStringifier().withTypes().visit(node);
-  }
-
-  /// For debugging purposes, replace a call to [applyCpsPass] with a call
-  /// to [debugCpsPass] to check that this pass is idempotent.
-  ///
-  /// This runs [pass] followed by shrinking reductions, and then checks that
-  /// one more run of [pass] does not change the IR.  The intermediate shrinking
-  /// reductions pass is omitted if [pass] itself is shrinking reductions.
-  ///
-  /// If [targetName] is given, functions whose name contains that substring
-  /// will be dumped out if the idempotency test fails.
-  void debugCpsPass(cps_opt.Pass makePass(), cps.FunctionDefinition cpsFunction,
-      [String targetName]) {
-    String original = stringify(cpsFunction);
-    cps_opt.Pass pass = makePass();
-    pass.rewrite(cpsFunction);
-    assert(checkCpsIntegrity(cpsFunction, pass.passName));
-    if (pass is! ShrinkingReducer) {
-      new ShrinkingReducer().rewrite(cpsFunction);
-    }
-    String before = stringify(cpsFunction);
-    makePass().rewrite(cpsFunction);
-    String after = stringify(cpsFunction);
-    if (before != after) {
-      print('SExpression changed for ${cpsFunction.element}');
-      if (targetName != null && '${cpsFunction.element}'.contains(targetName)) {
-        print(original);
-        print('\n-->\n');
-        print(before);
-        print('\n-->\n');
-        print(after);
-        compiler.outputProvider('original', 'dump')
-          ..add(original)
-          ..close();
-        compiler.outputProvider('before', 'dump')
-          ..add(before)
-          ..close();
-        compiler.outputProvider('after', 'dump')
-          ..add(after)
-          ..close();
-      }
-    }
-    traceGraph(pass.passName, cpsFunction);
-    dumpTypedIr(pass.passName, cpsFunction);
-  }
-
-  void applyCpsPass(cps_opt.Pass pass, cps.FunctionDefinition cpsFunction) {
-    cpsOptimizationTask.measureSubtask(pass.passName, () {
-      pass.rewrite(cpsFunction);
-    });
-    traceGraph(pass.passName, cpsFunction);
-    dumpTypedIr(pass.passName, cpsFunction);
-    assert(checkCpsIntegrity(cpsFunction, pass.passName));
-  }
-
-  cps.FunctionDefinition compileToCpsIr(AstElement element) {
-    cps.FunctionDefinition cpsFunction = inliner.cache.getUnoptimized(element);
-    if (cpsFunction != null) return cpsFunction;
-
-    cpsFunction = cpsBuilderTask.buildNode(element, typeSystem);
-    if (cpsFunction == null) {
-      if (cpsBuilderTask.bailoutMessage == null) {
-        giveUp('unable to build cps definition of $element');
-      } else {
-        giveUp(cpsBuilderTask.bailoutMessage);
-      }
-    }
-    ParentVisitor.setParents(cpsFunction);
-    traceGraph('IR Builder', cpsFunction);
-    dumpTypedIr('IR Builder', cpsFunction);
-    // Eliminating redundant phis before the unsugaring pass will make it
-    // insert fewer getInterceptor calls.
-    applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-    applyCpsPass(new UnsugarVisitor(glue), cpsFunction);
-    applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-    applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-    applyCpsPass(new InsertRefinements(typeSystem), cpsFunction);
-
-    inliner.cache.putUnoptimized(element, cpsFunction);
-    return cpsFunction;
-  }
-
-  static const Pattern PRINT_TYPED_IR_FILTER = null;
-
-  String formatTypeMask(TypeMask type) {
-    if (type is UnionTypeMask) {
-      return '[${type.disjointMasks.map(formatTypeMask).join(', ')}]';
-    } else if (type is FlatTypeMask) {
-      if (type.isEmpty) return "empty";
-      if (type.isNull) return "null";
-      String suffix = (type.isExact ? "" : "+") + (type.isNullable ? "?" : "!");
-      return '${type.base.name}$suffix';
-    } else if (type is ForwardingTypeMask) {
-      return formatTypeMask(type.forwardTo);
-    }
-    throw 'unsupported: $type';
-  }
-
-  void dumpTypedIr(String passName, cps.FunctionDefinition cpsFunction) {
-    if (PRINT_TYPED_IR_FILTER != null &&
-        PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsFunction.element.name) != null) {
-      String printType(nodeOrRef, String s) {
-        cps.Node node =
-            nodeOrRef is cps.Reference ? nodeOrRef.definition : nodeOrRef;
-        return node is cps.Variable && node.type != null
-            ? '$s:${formatTypeMask(node.type)}'
-            : s;
-      }
-      DEBUG_MODE = true;
-      print(';;; ==== After $passName ====');
-      print(new SExpressionStringifier(printType).visit(cpsFunction));
-    }
-  }
-
-  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().
-  }
-
-  void optimizeCpsBeforeInlining(cps.FunctionDefinition cpsFunction) {
-    cpsOptimizationTask.measure(() {
-      applyCpsPass(new TypePropagator(this), cpsFunction);
-      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-      applyCpsPass(new ShrinkingReducer(), cpsFunction);
-    });
-  }
-
-  void optimizeCpsAfterInlining(cps.FunctionDefinition cpsFunction) {
-    cpsOptimizationTask.measure(() {
-      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-      applyCpsPass(new ShrinkingReducer(), cpsFunction);
-      applyCpsPass(new RedundantRefinementEliminator(typeSystem), cpsFunction);
-      applyCpsPass(new UpdateRefinements(typeSystem), cpsFunction);
-      applyCpsPass(new TypePropagator(this, recomputeAll: true), cpsFunction);
-      applyCpsPass(new ShrinkingReducer(), cpsFunction);
-      applyCpsPass(new EagerlyLoadStatics(), cpsFunction);
-      applyCpsPass(new GVN(compiler, typeSystem), cpsFunction);
-      applyCpsPass(new PathBasedOptimizer(backend, typeSystem), cpsFunction);
-      applyCpsPass(new ShrinkingReducer(), 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 UseFieldInitializers(backend), cpsFunction);
-      applyCpsPass(new MutableVariableEliminator(), cpsFunction);
-      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-      applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-      applyCpsPass(new UpdateRefinements(typeSystem), 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, glue);
-    tree_ir.FunctionDefinition treeNode =
-        treeBuilderTask.measure(() => builder.buildFunction(cpsNode));
-    assert(treeNode != null);
-    traceGraph('Tree builder', treeNode);
-    assert(checkTreeIntegrity(treeNode));
-    return treeNode;
-  }
-
-  bool checkTreeIntegrity(tree_ir.FunctionDefinition node) {
-    treeOptimizationTask.measureSubtask('Check integrity', () {
-      new CheckTreeIntegrity().check(node);
-    });
-    return true; // So this can be used from assert().
-  }
-
-  tree_ir.FunctionDefinition optimizeTreeIr(tree_ir.FunctionDefinition node) {
-    void applyTreePass(tree_opt.Pass pass) {
-      treeOptimizationTask.measureSubtask(pass.passName, () {
-        pass.rewrite(node);
-      });
-      traceGraph(pass.passName, node);
-      assert(checkTreeIntegrity(node));
-    }
-
-    treeOptimizationTask.measure(() {
-      applyTreePass(new StatementRewriter());
-      applyTreePass(
-          new VariableMerger(minifying: compiler.options.enableMinification));
-      applyTreePass(new LoopRewriter());
-      applyTreePass(new LogicalRewriter());
-      applyTreePass(new PullIntoInitializers());
-    });
-
-    return node;
-  }
-
-  js.Fun compileToJavaScript(
-      CodegenWorkItem work, tree_ir.FunctionDefinition definition) {
-    CodeGenerator codeGen = new CodeGenerator(glue, work.registry);
-    Element element = work.element;
-    js.Fun code = codeGen.buildFunction(definition);
-    if (element is FunctionElement && element.asyncMarker != AsyncMarker.SYNC) {
-      code = backend.rewriteAsync(element, code);
-      work.registry.registerAsyncMarker(element);
-    }
-    return attachPosition(code, work.resolvedAst);
-  }
-
-  Iterable<CompilerTask> get tasks {
-    return <CompilerTask>[
-      cpsBuilderTask,
-      cpsOptimizationTask,
-      treeBuilderTask,
-      treeOptimizationTask
-    ]..addAll(fallbackCompiler.tasks);
-  }
-
-  js.Node attachPosition(js.Node node, ResolvedAst resolvedAst) {
-    return node.withSourceInformation(sourceInformationFactory
-        .createBuilderForContext(resolvedAst)
-        .buildDeclaration(resolvedAst));
-  }
-}
diff --git a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
deleted file mode 100644
index 3c0f485..0000000
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
+++ /dev/null
@@ -1,245 +0,0 @@
-library dart2js.unsugar_cps;
-
-import '../../cps_ir/cps_ir_nodes.dart';
-
-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_fragment.dart';
-import '../../common/names.dart';
-
-class ExplicitReceiverParameterEntity implements Local {
-  String get name => 'receiver';
-  final ExecutableElement executableContext;
-  ExplicitReceiverParameterEntity(this.executableContext);
-  toString() => 'ExplicitReceiverParameterEntity($executableContext)';
-}
-
-/// Suggested name for an interceptor.
-class InterceptorEntity extends Entity {
-  Entity interceptedVariable;
-
-  InterceptorEntity(this.interceptedVariable);
-
-  String get name => interceptedVariable.name + '_';
-}
-
-/// Rewrites the initial CPS IR to make Dart semantics explicit and inserts
-/// special nodes that respect JavaScript behavior.
-///
-/// Performs the following rewrites:
-///  - Add interceptors at call sites that use interceptor calling convention.
-///  - Add explicit receiver argument for methods that are called in interceptor
-///    calling convention.
-///  - Convert two-parameter exception handlers to one-parameter ones.
-class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
-  Glue _glue;
-
-  FunctionDefinition function;
-
-  Parameter get receiverParameter => function.receiverParameter;
-
-  /// The interceptor of the receiver.  For some methods, this is the receiver
-  /// itself, for others, it is the interceptor parameter.
-  Parameter receiverInterceptor;
-
-  // In a catch block, rethrow implicitly throws the block's exception
-  // parameter.  This is the exception parameter when nested in a catch
-  // block and null otherwise.
-  Parameter _exceptionParameter = null;
-
-  UnsugarVisitor(this._glue);
-
-  String get passName => 'Unsugaring';
-
-  void rewrite(FunctionDefinition function) {
-    this.function = function;
-    bool inInterceptedMethod = _glue.isInterceptedMethod(function.element);
-
-    if (function.element.name == '==' &&
-        function.parameters.length == 1 &&
-        !_glue.operatorEqHandlesNullArgument(function.element)) {
-      // Insert the null check that the language semantics requires us to
-      // perform before calling operator ==.
-      insertEqNullCheck(function);
-    }
-
-    if (inInterceptedMethod) {
-      function.interceptorParameter = new Parameter(null)..parent = function;
-      // Since the receiver won't be compiled to "this", set a hint on it
-      // so the parameter gets a meaningful name.
-      function.receiverParameter.hint =
-          new ExplicitReceiverParameterEntity(function.element);
-      // If we need an interceptor for the receiver, use the receiver itself
-      // if possible, otherwise the interceptor argument.
-      receiverInterceptor = _glue.methodUsesReceiverArgument(function.element)
-          ? function.interceptorParameter
-          : receiverParameter;
-    }
-
-    visit(function);
-  }
-
-  Constant get trueConstant {
-    return new Constant(new TrueConstantValue());
-  }
-
-  Constant get falseConstant {
-    return new Constant(new FalseConstantValue());
-  }
-
-  Constant get nullConstant {
-    return new Constant(new NullConstantValue());
-  }
-
-  void insertEqNullCheck(FunctionDefinition function) {
-    // Replace
-    //
-    //     body;
-    //
-    // with
-    //
-    //     if (identical(arg, null))
-    //       return false;
-    //     else
-    //       body;
-    //
-    CpsFragment cps = new CpsFragment();
-    Primitive isNull = cps.applyBuiltin(BuiltinOperator.Identical,
-        <Primitive>[function.parameters.single, cps.makeNull()]);
-    CpsFragment trueBranch = cps.ifTruthy(isNull);
-    trueBranch.invokeContinuation(
-        function.returnContinuation, <Primitive>[trueBranch.makeFalse()]);
-    cps.insertAbove(function.body);
-  }
-
-  /// 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, new Selector.fromElement(function), arguments, null);
-    new LetPrim(invoke).insertAbove(node);
-    return invoke;
-  }
-
-  @override
-  Expression traverseLetHandler(LetHandler node) {
-    assert(node.handler.parameters.length == 2);
-    Parameter previousExceptionParameter = _exceptionParameter;
-
-    // BEFORE: Handlers have two parameters, exception and stack trace.
-    // AFTER: Handlers have a single parameter, which is unwrapped to get
-    // the exception and stack trace.
-    _exceptionParameter = node.handler.parameters.first;
-    Parameter stackTraceParameter = node.handler.parameters.last;
-    Expression body = node.handler.body;
-    if (_exceptionParameter.hasAtLeastOneUse ||
-        stackTraceParameter.hasAtLeastOneUse) {
-      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.argumentRefs[0].changeTo(_exceptionParameter);
-
-      if (stackTraceParameter.hasAtLeastOneUse) {
-        InvokeStatic stackTraceValue = insertStaticCallAbove(
-            _glue.getTraceFromException(), [_exceptionParameter], body);
-        stackTraceParameter.replaceUsesWith(stackTraceValue);
-      }
-    }
-
-    assert(stackTraceParameter.hasNoUses);
-    node.handler.parameters.removeLast();
-
-    visit(node.handler);
-    _exceptionParameter = previousExceptionParameter;
-
-    return node.body;
-  }
-
-  processThrow(Throw node) {
-    // The subexpression of throw is wrapped in the JavaScript output.
-    Primitive wrappedException = insertStaticCallAbove(
-        _glue.getWrapExceptionHelper(), [node.value], node);
-    node.valueRef.changeTo(wrappedException);
-  }
-
-  processRethrow(Rethrow node) {
-    // Rethrow can only appear in a catch block.  It throws that block's
-    // (wrapped) caught exception.
-    Throw replacement = new Throw(_exceptionParameter);
-    InteriorNode parent = node.parent;
-    parent.body = replacement;
-    replacement.parent = parent;
-    // The original rethrow does not have any references that we need to
-    // worry about unlinking.
-  }
-
-  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.argumentRefs.length == 1 &&
-        isNullConstant(node.argument(0))) {
-      node.replaceWith(new ApplyBuiltinOperator(BuiltinOperator.Identical,
-          [node.receiver, node.argument(0)], node.sourceInformation));
-      return;
-    }
-
-    Primitive receiver = node.receiver;
-    Primitive interceptor;
-
-    if (receiver == receiverParameter && receiverInterceptor != null) {
-      // TODO(asgerf): This could be done by GVN.
-      // If the receiver is 'this', we are calling a method in
-      // the same interceptor:
-      //  Change 'receiver.foo()'  to  'this.foo(receiver)'.
-      interceptor = receiverInterceptor;
-    } else {
-      interceptor = new Interceptor(receiver, node.sourceInformation);
-      if (receiver.hint != null) {
-        interceptor.hint = new InterceptorEntity(receiver.hint);
-      }
-      new LetPrim(interceptor).insertAbove(node.parent);
-    }
-    assert(node.interceptorRef == null);
-    node.makeIntercepted(interceptor);
-  }
-
-  processInvokeMethodDirectly(InvokeMethodDirectly node) {
-    if (!_glue.isInterceptedMethod(node.target)) return;
-
-    Primitive receiver = node.receiver;
-    Primitive interceptor;
-
-    if (receiver == receiverParameter && receiverInterceptor != null) {
-      // If the receiver is 'this', we are calling a method in
-      // the same interceptor:
-      //  Change 'receiver.foo()'  to  'this.foo(receiver)'.
-      interceptor = receiverInterceptor;
-    } else {
-      interceptor = new Interceptor(receiver, node.sourceInformation);
-      if (receiver.hint != null) {
-        interceptor.hint = new InterceptorEntity(receiver.hint);
-      }
-      new LetPrim(interceptor).insertAbove(node.parent);
-    }
-    assert(node.interceptorRef == null);
-    node.makeIntercepted(interceptor);
-  }
-}
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index eba60d9..391a35c 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.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 js_backend;
+import '../common.dart';
+import '../compiler.dart' show Compiler;
+import '../constants/values.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../io/code_output.dart';
+import '../js/js.dart' as jsAst;
+import '../js/js.dart' show js;
+import 'backend.dart';
+import 'constant_system_javascript.dart';
+import 'namer.dart';
 
 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
 
@@ -269,7 +279,7 @@
 
   @override
   jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) {
-    switch (constant.kind) {
+    switch (constant.valueKind) {
       case SyntheticConstantKind.DUMMY_INTERCEPTOR:
       case SyntheticConstantKind.EMPTY_VALUE:
         return new jsAst.LiteralNumber('0');
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index 8e6de54..2ab684e 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -2,7 +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.
 
-part of js_backend;
+import '../compile_time_constants.dart';
+import '../compiler.dart' show Compiler;
+import '../constants/constant_system.dart';
+import '../constants/expressions.dart';
+import '../constants/values.dart';
+import '../elements/elements.dart';
+import '../elements/visitor.dart' show BaseElementVisitor;
+import '../resolution/tree_elements.dart' show TreeElements;
+import '../tree/tree.dart';
+import 'constant_system_javascript.dart';
 
 /// [ConstantCompilerTask] for compilation of constants for the JavaScript
 /// backend.
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 bfd156e..e717466 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -5,13 +5,13 @@
 library dart2js.constant_system.js;
 
 import '../compiler.dart' show Compiler;
+import '../constant_system_dart.dart';
 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, FieldElement;
-import '../tree/tree.dart' show DartString, LiteralDartString;
+import '../tree/dartstring.dart' show DartString, LiteralDartString;
 import 'js_backend.dart';
 
 const JAVA_SCRIPT_CONSTANT_SYSTEM = const JavaScriptConstantSystem();
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 450b826..11ff3c9 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.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 js_backend;
+import '../compiler.dart' show Compiler;
+import '../constants/values.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../enqueue.dart' show Enqueuer;
+import '../universe/use.dart' show StaticUse;
+import 'backend.dart';
 
 /**
  * Support for Custom Elements.
@@ -198,6 +204,7 @@
         }
       }
     }
+
     classElement.forEachMember(selectGenerativeConstructors,
         includeBackendMembers: false, includeSuperAndInjectedMembers: false);
     return result;
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 cfc0136..7ac77d5 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.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.
 
-part of js_backend;
+part of js_backend.namer;
 
 abstract class _MinifiedFieldNamer implements Namer {
   _FieldNamingRegistry get fieldRegistry;
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
index 7698c3d..9636e67 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.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.
 
-part of js_backend;
+part of js_backend.namer;
 
 class FrequencyBasedNamer extends Namer
     with _MinifiedFieldNamer, _MinifiedOneShotInterceptorNamer
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index 5e5424f..aa31961 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -4,96 +4,11 @@
 
 library js_backend;
 
-import 'dart:async' show Future;
-import 'dart:collection' show HashMap;
-
-import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
-import 'package:js_runtime/shared/embedded_names.dart' show JsGetName;
-
-import '../closure.dart';
-import '../common.dart';
-import '../common/backend_api.dart'
-    show Backend, ImpactTransformer, ForeignResolver, NativeRegistry;
-import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem;
-import '../common/names.dart' show Identifiers, Names, Selectors, Uris;
-import '../common/registry.dart' show EagerRegistry, Registry;
-import '../common/resolution.dart'
-    show
-        Feature,
-        Frontend,
-        ListLiteralUse,
-        MapLiteralUse,
-        Resolution,
-        ResolutionImpact;
-import '../common/tasks.dart' show CompilerTask;
-import '../common/work.dart' show ItemCompilationContext;
-import '../compile_time_constants.dart';
-import '../compiler.dart' show Compiler;
-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 '../diagnostics/invariant.dart' show DEBUG_MODE;
-import '../dump_info.dart' show DumpInfoTask;
-import '../elements/elements.dart';
-import '../elements/visitor.dart' show BaseElementVisitor;
-import '../enqueue.dart' show Enqueuer, ResolutionEnqueuer;
-import '../io/code_output.dart';
-import '../io/position_information.dart' show PositionSourceInformationStrategy;
-import '../io/source_information.dart' show SourceInformationStrategy;
-import '../io/start_end_information.dart'
-    show StartEndSourceInformationStrategy;
-import '../js/js.dart' as jsAst;
-import '../js/js.dart' show js;
-import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy;
-import '../js/rewrite_async.dart';
-import '../js_emitter/js_emitter.dart'
-    show CodeEmitterTask, MetadataCollector, Placeholder;
-import '../library_loader.dart' show LibraryLoader, LoadedLibraries;
-import '../native/native.dart' as native;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../ssa/builder.dart' show SsaFunctionCompiler;
-import '../ssa/codegen.dart' show SsaCodeGenerator;
-import '../ssa/nodes.dart' show HTypeConversion, HInstruction;
-import '../tree/tree.dart';
-import '../types/types.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import '../universe/selector.dart' show 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 ClassWorld;
-import 'backend_helpers.dart';
-import 'backend_impact.dart';
-import 'backend_serialization.dart' show JavaScriptBackendSerialization;
-import 'codegen/task.dart';
-import 'constant_system_javascript.dart';
-import 'js_interop_analysis.dart' show JsInteropAnalysis;
-import 'lookup_map_analysis.dart' show LookupMapAnalysis;
-import 'native_data.dart' show NativeData;
-import 'patch_resolver.dart';
-
-part 'backend.dart';
-part 'checked_mode_helpers.dart';
-part 'constant_emitter.dart';
-part 'constant_handler_javascript.dart';
-part 'custom_elements_analysis.dart';
-part 'field_naming_mixin.dart';
-part 'frequency_namer.dart';
-part 'minify_namer.dart';
-part 'namer.dart';
-part 'namer_names.dart';
-part 'no_such_method_registry.dart';
-part 'runtime_types.dart';
-part 'type_variable_handler.dart';
+export 'backend.dart';
+export 'checked_mode_helpers.dart';
+export 'constant_emitter.dart';
+export 'constant_handler_javascript.dart';
+export 'custom_elements_analysis.dart';
+export 'namer.dart';
+export 'no_such_method_registry.dart';
+export 'type_variable_handler.dart';
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 83f6284..74b10ab 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -8,11 +8,7 @@
 import '../common.dart';
 import '../constants/values.dart'
     show ConstantValue, ConstructedConstantValue, StringConstantValue;
-import '../dart_types.dart'
-    show
-        DartType,
-        DynamicType,
-        FunctionType;
+import '../dart_types.dart' show DartType, DynamicType, FunctionType;
 import '../diagnostics/messages.dart' show MessageKind;
 import '../elements/elements.dart'
     show
@@ -195,9 +191,7 @@
     // TODO(jacobr): consider using codegenWorld.isChecks to determine the
     // range of positional arguments that need to be supported by JavaScript
     // function types.
-    return new FunctionType.synthesized(
-      const DynamicType(),
-      [],
-      new List<DartType>.filled(16, const DynamicType()));
+    return new FunctionType.synthesized(const DynamicType(), [],
+        new List<DartType>.filled(16, const DynamicType()));
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index ff76d87..3e689d4 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.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.
 
-part of js_backend;
+part of js_backend.namer;
 
 /**
  * Assigns JavaScript identifiers to Dart variables, class-names and members.
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index c4a86ef..303f52c 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -2,7 +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.
 
-part of js_backend;
+library js_backend.namer;
+
+import 'dart:collection' show HashMap;
+
+import 'package:js_runtime/shared/embedded_names.dart' show JsGetName;
+
+import '../closure.dart';
+import '../common.dart';
+import '../common/names.dart' show Identifiers, Selectors;
+import '../compiler.dart' show Compiler;
+import '../constants/values.dart';
+import '../core_types.dart' show CoreClasses;
+import '../dart_types.dart';
+import '../diagnostics/invariant.dart' show DEBUG_MODE;
+import '../elements/elements.dart';
+import '../js/js.dart' as jsAst;
+import '../js/js.dart' show js;
+import '../tree/tree.dart';
+import '../universe/call_structure.dart' show CallStructure;
+import '../universe/selector.dart' show Selector, SelectorKind;
+import '../util/characters.dart';
+import '../util/util.dart';
+import '../world.dart' show ClassWorld;
+import 'backend.dart';
+import 'backend_helpers.dart';
+import 'constant_system_javascript.dart';
+
+part 'field_naming_mixin.dart';
+part 'frequency_namer.dart';
+part 'minify_namer.dart';
+part 'namer_names.dart';
 
 /**
  * Assigns JavaScript identifiers to Dart variables, class-names and members.
@@ -644,7 +674,9 @@
   String _jsNameHelper(Element e) {
     String jsInteropName = backend.nativeData.getJsInteropName(e);
     if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName;
-    return e.isLibrary ? 'self' : e.name;
+    return e.isLibrary
+        ? 'self'
+        : backend.nativeData.getUnescapedJSInteropName(e.name);
   }
 
   /// Returns a JavaScript path specifying the context in which
@@ -1147,63 +1179,72 @@
 
   /**
    * Returns a proposed name for the given top-level or static element.
-   * The returned id is guaranteed to be a valid JS-id.
+   * The returned id is guaranteed to be a valid JavaScript identifier.
    */
   String _proposeNameForGlobal(Element element) {
     assert(!element.isInstanceMember);
-    String name;
     if (element.isGenerativeConstructor) {
-      name = "${element.enclosingClass.name}\$"
-          "${element.name}";
-    } else if (element.isFactoryConstructor) {
+      return '${element.enclosingClass.name}\$${element.name}';
+    }
+    if (element.isFactoryConstructor) {
       // TODO(johnniwinther): Change factory name encoding as to not include
       // the class-name twice.
       String className = element.enclosingClass.name;
-      name = '${className}_${Elements.reconstructConstructorName(element)}';
-    } else if (Elements.isStaticOrTopLevel(element)) {
+      return '${className}_${Elements.reconstructConstructorName(element)}';
+    }
+    if (Elements.isStaticOrTopLevel(element)) {
       if (element.isClassMember) {
         ClassElement enclosingClass = element.enclosingClass;
-        name = "${enclosingClass.name}_"
-            "${element.name}";
-      } else {
-        name = element.name.replaceAll('+', '_');
+        return '${enclosingClass.name}_${element.name}';
       }
-    } else if (element.isLibrary) {
-      LibraryElement library = element;
-      name = libraryLongNames[library];
-      if (name != null) return name;
-      name = library.libraryOrScriptName;
-      if (name.contains('.')) {
-        // For libraries that have a library tag, we use the last part
-        // of the fully qualified name as their base name. For all other
-        // libraries, we use the first part of their filename.
-        name = library.hasLibraryName
-            ? name.substring(name.lastIndexOf('.') + 1)
-            : name.substring(0, name.indexOf('.'));
-      }
-      // The filename based name can contain all kinds of nasty characters. Make
-      // sure it is an identifier.
-      if (!IDENTIFIER.hasMatch(name)) {
-        name = name.replaceAllMapped(NON_IDENTIFIER_CHAR,
-            (match) => match[0].codeUnitAt(0).toRadixString(16));
-        if (!IDENTIFIER.hasMatch(name)) {
-          // e.g. starts with digit.
-          name = 'lib_$name';
-        }
-      }
-      // Names constructed based on a libary name will be further disambiguated.
-      // However, as names from the same libary should have the same libary
-      // name part, we disambiguate the library name here.
-      String disambiguated = name;
-      for (int c = 0; libraryLongNames.containsValue(disambiguated); c++) {
-        disambiguated = "$name$c";
-      }
-      libraryLongNames[library] = disambiguated;
-      name = disambiguated;
-    } else {
-      name = element.name;
+      return element.name.replaceAll('+', '_');
     }
-    return name;
+    if (element.isLibrary) {
+      return _proposeNameForLibrary(element);
+    }
+    return element.name;
+  }
+
+  /**
+   * Returns a proposed name for the given [LibraryElement].
+   * The returned id is guaranteed to be a valid JavaScript identifier.
+   */
+  // TODO(sra): Pre-process libraries to assign [libraryLongNames] in a way that
+  // is independent of the order of calls to namer.
+  String _proposeNameForLibrary(LibraryElement library) {
+    String name = libraryLongNames[library];
+    if (name != null) return name;
+    // Use the 'file' name, e.g. "package:expect/expect.dart" -> "expect"
+    name = library.canonicalUri.path;
+    name = name.substring(name.lastIndexOf('/') + 1);
+    if (name.contains('.')) {
+      // Drop file extension.
+      name = name.substring(0, name.lastIndexOf('.'));
+    }
+    // The filename based name can contain all kinds of nasty characters. Make
+    // sure it is an identifier.
+    if (!IDENTIFIER.hasMatch(name)) {
+      String replacer(Match match) {
+        String s = match[0];
+        if (s == '.') return '_';
+        return s.codeUnitAt(0).toRadixString(16);
+      }
+
+      name = name.replaceAllMapped(NON_IDENTIFIER_CHAR, replacer);
+      if (!IDENTIFIER.hasMatch(name)) {
+        // e.g. starts with digit.
+        name = 'lib_$name';
+      }
+    }
+    // Names constructed based on a libary name will be further disambiguated.
+    // However, as names from the same libary should have the same library
+    // name part, we disambiguate the library name here.
+    String disambiguated = name;
+    for (int c = 0; libraryLongNames.containsValue(disambiguated); c++) {
+      disambiguated = "$name$c";
+    }
+    libraryLongNames[library] = disambiguated;
+    return disambiguated;
   }
 
   String suffixForGetInterceptor(Iterable<ClassElement> classes) {
@@ -1219,6 +1260,7 @@
       if (cls == helpers.jsInterceptorClass) return "I";
       return cls.name;
     }
+
     List<String> names = classes
         .where((cls) => !backend.isNativeOrExtendsNative(cls))
         .map(abbreviate)
@@ -1766,7 +1808,7 @@
 
   @override
   void visitSynthetic(SyntheticConstantValue constant, [_]) {
-    switch (constant.kind) {
+    switch (constant.valueKind) {
       case SyntheticConstantKind.DUMMY_INTERCEPTOR:
         add('dummy_receiver');
         break;
@@ -1886,7 +1928,7 @@
 
   @override
   int visitSynthetic(SyntheticConstantValue constant, [_]) {
-    switch (constant.kind) {
+    switch (constant.valueKind) {
       case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
         // These contain a deferred opaque index into metadata. There is nothing
         // we can access that is stable between compiles.  Luckily, since they
diff --git a/pkg/compiler/lib/src/js_backend/namer_names.dart b/pkg/compiler/lib/src/js_backend/namer_names.dart
index 4baffb5..7e8e76f 100644
--- a/pkg/compiler/lib/src/js_backend/namer_names.dart
+++ b/pkg/compiler/lib/src/js_backend/namer_names.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.
 
-part of js_backend;
+part of js_backend.namer;
 
 abstract class _NamerName extends jsAst.Name {
   int get _kind;
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart
index 67b473b..31fe7d6 100644
--- a/pkg/compiler/lib/src/js_backend/native_data.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart
@@ -35,6 +35,10 @@
   Map<MemberElement, NativeBehavior> nativeFieldStoreBehavior =
       <FieldElement, NativeBehavior>{};
 
+  /// Prefix used to escape JS names that are not valid Dart names
+  /// when using JSInterop.
+  static const String _jsInteropEscapePrefix = r'JS$';
+
   /// Returns `true` if [element] is explicitly marked as part of JsInterop.
   bool _isJsInterop(Element element) {
     return jsInteropNames.containsKey(element.declaration);
@@ -93,7 +97,7 @@
     if (jsInteropName != null && jsInteropName.isNotEmpty) {
       return jsInteropName;
     }
-    return element.isLibrary ? 'self' : element.name;
+    return element.isLibrary ? 'self' : getUnescapedJSInteropName(element.name);
   }
 
   /// Computes the name for [element] to use in the generated JavaScript. This
@@ -216,4 +220,12 @@
       FieldElement field, NativeBehavior behavior) {
     nativeFieldStoreBehavior[field] = behavior;
   }
+
+  /// Apply JS$ escaping scheme to convert possible escaped Dart names into
+  /// JS names.
+  String getUnescapedJSInteropName(String name) {
+    return name.startsWith(_jsInteropEscapePrefix)
+        ? name.substring(_jsInteropEscapePrefix.length)
+        : name;
+  }
 }
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 d9e8681..4464214 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
@@ -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 js_backend;
+import '../common.dart';
+import '../common/names.dart' show Identifiers, Names, Selectors;
+import '../compiler.dart' show Compiler;
+import '../elements/elements.dart';
+import '../tree/tree.dart';
+import '../types/types.dart';
+import 'backend.dart';
 
 /**
  * Categorizes `noSuchMethod` implementations.
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 369cec0..a28f232 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.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.
 
-part of js_backend;
+part of js_backend.backend;
 
 /// For each class, stores the possible class subtype tests that could succeed.
 abstract class TypeChecks {
@@ -150,7 +150,7 @@
   @override
   void registerRtiDependency(Element element, Element dependency) {
     // We're not dealing with typedef for now.
-    if (!element.isClass || !dependency.isClass) return;
+    if (element == null || !element.isClass || !dependency.isClass) return;
     Set<ClassElement> classes =
         rtiDependencies.putIfAbsent(element, () => new Set<ClassElement>());
     classes.add(dependency);
@@ -298,6 +298,7 @@
               methodsNeedingRti.add(method);
             }
           }
+
           compiler.resolverWorld.closuresWithFreeTypeVariables
               .forEach(analyzeMethod);
           compiler.resolverWorld.callMethodsWithFreeTypeVariables
@@ -314,6 +315,7 @@
           methodsNeedingRti.add(method);
         }
       }
+
       compiler.resolverWorld.closuresWithFreeTypeVariables
           .forEach(analyzeMethod);
       compiler.resolverWorld.callMethodsWithFreeTypeVariables
@@ -417,6 +419,7 @@
         functionArgumentCollector.collect(type);
       }
     }
+
     collectFunctionTypeArguments(isChecks);
     collectFunctionTypeArguments(checkedBounds);
 
@@ -432,6 +435,7 @@
         }
       }
     }
+
     collectTypeArguments(instantiatedTypes);
     collectTypeArguments(checkedTypeArguments, isTypeArgument: true);
 
@@ -462,6 +466,7 @@
         functionArgumentCollector.collect(type);
       }
     }
+
     collectFunctionTypeArguments(instantiatedTypes);
     collectFunctionTypeArguments(checkedTypeArguments);
 
@@ -471,6 +476,7 @@
         collector.collect(type, isTypeArgument: isTypeArgument);
       }
     }
+
     collectTypeArguments(isChecks);
     collectTypeArguments(checkedBounds, isTypeArgument: true);
 
@@ -641,6 +647,7 @@
     jsAst.Expression onVariable(TypeVariableType v) {
       return new jsAst.VariableUse(v.name);
     }
+
     ;
     jsAst.Expression encoding = getTypeRepresentation(type, onVariable);
     if (contextClass == null && !alwaysGenerateFunction) {
@@ -1049,8 +1056,8 @@
 class TypeCheck {
   final ClassElement cls;
   final Substitution substitution;
-  final int hashCode = (nextHash++) & 0x3fffffff;
-  static int nextHash = 49;
+  final int hashCode = _nextHash = (_nextHash + 100003).toUnsigned(30);
+  static int _nextHash = 0;
 
   TypeCheck(this.cls, this.substitution);
 }
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 faf8539..ada9d16 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -2,7 +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.
 
-part of js_backend;
+import '../common.dart';
+import '../common/registry.dart' show Registry;
+import '../compiler.dart' show Compiler;
+import '../constants/expressions.dart';
+import '../constants/values.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../enqueue.dart' show Enqueuer;
+import '../js/js.dart' as jsAst;
+import '../js_emitter/js_emitter.dart'
+    show CodeEmitterTask, MetadataCollector, Placeholder;
+import '../universe/call_structure.dart' show CallStructure;
+import '../universe/use.dart' show StaticUse;
+import '../util/util.dart';
+import 'backend.dart';
 
 /**
  * Handles construction of TypeVariable constants needed at runtime.
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index 27651c2..6baa377 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -5,11 +5,10 @@
 library dart2js.js_emitter.constant_ordering;
 
 import '../constants/values.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;
+import '../tree/dartstring.dart' show DartString;
 
 /// A canonical but arbrary ordering of constants. The ordering is 'stable'
 /// under perturbation of the source.
@@ -148,11 +147,11 @@
     // 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;
+    SyntheticConstantKind aKind = a.valueKind;
+    SyntheticConstantKind bKind = b.valueKind;
     int r = aKind.index - bKind.index;
     if (r != 0) return r;
-    switch (a.kind) {
+    switch (aKind) {
       case SyntheticConstantKind.DUMMY_INTERCEPTOR:
       case SyntheticConstantKind.EMPTY_VALUE:
         // Never emitted.
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 138062e..352d7f7 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
@@ -4,17 +4,6 @@
 
 library dart2js.js_emitter.lazy_emitter.model_emitter;
 
-import '../../compiler.dart' show Compiler;
-import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
-import '../../core_types.dart' show CoreClasses;
-import '../../elements/elements.dart' show ClassElement, FunctionElement;
-import '../../js/js.dart' as js;
-import '../../js_backend/js_backend.dart'
-    show JavaScriptBackend, Namer, 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,
@@ -31,6 +20,15 @@
         TYPE_TO_INTERCEPTOR_MAP,
         TYPES;
 
+import '../../compiler.dart' show Compiler;
+import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
+import '../../core_types.dart' show CoreClasses;
+import '../../elements/elements.dart' show ClassElement, FunctionElement;
+import '../../js/js.dart' as js;
+import '../../js_backend/js_backend.dart'
+    show JavaScriptBackend, Namer, ConstantEmitter;
+import '../constant_ordering.dart' show deepCompareConstants;
+import '../js_emitter.dart' show NativeEmitter;
 import '../js_emitter.dart' show NativeGenerator, buildTearOffCode;
 import '../model.dart';
 
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index cbc18bc..d918135 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -222,8 +222,9 @@
     return defaultValues;
   }
 
-  Map<ParameterElement, ParameterElement> mapRedirectingFactoryConstructorOptionalParameters(
-      FunctionSignature source, FunctionSignature target) {
+  Map<ParameterElement, ParameterElement>
+      mapRedirectingFactoryConstructorOptionalParameters(
+          FunctionSignature source, FunctionSignature target) {
     var map = <ParameterElement, ParameterElement>{};
 
     if (source.optionalParametersAreNamed !=
@@ -361,6 +362,7 @@
       }
       return true;
     }
+
     void countTokensInTypes(Iterable<_BoundMetadataEntry> entries) {
       jsAst.TokenCounter counter = new jsAst.TokenCounter();
       entries
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 78f3cda..137f407 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -96,6 +96,7 @@
       walk(cls.superclass);
       preOrder.add(cls);
     }
+
     classes.forEach(walk);
 
     // Find which classes are needed and which are non-leaf classes.  Any class
@@ -187,6 +188,7 @@
       }
       cls.nativeExtensions = extensionPoints[cls];
     }
+
     // Add properties containing the information needed to construct maps used
     // by getNativeInterceptor and custom elements.
     if (compiler.enqueuer.codegen.nativeEnqueuer
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 1f81f6d..efec052 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
@@ -345,6 +345,8 @@
       for (Element e in elements) {
         if (e is ClassElement && backend.isJsInterop(e)) {
           e.declaration.forEachMember((_, Element member) {
+            var jsName =
+                backend.nativeData.getUnescapedJSInteropName(member.name);
             if (!member.isInstanceMember) return;
             if (member.isGetter || member.isField || member.isFunction) {
               var selectors =
@@ -354,7 +356,7 @@
                   var stubName = namer.invocationName(selector);
                   if (stubNames.add(stubName.key)) {
                     interceptorClass.callStubs.add(_buildStubMethod(stubName,
-                        js.js('function(obj) { return obj.# }', [member.name]),
+                        js.js('function(obj) { return obj.# }', [jsName]),
                         element: member));
                   }
                 }
@@ -367,10 +369,8 @@
               if (selectors != null && !selectors.isEmpty) {
                 var stubName = namer.setterForElement(member);
                 if (stubNames.add(stubName.key)) {
-                  interceptorClass.callStubs.add(_buildStubMethod(
-                      stubName,
-                      js.js('function(obj, v) { return obj.# = v }',
-                          [member.name]),
+                  interceptorClass.callStubs.add(_buildStubMethod(stubName,
+                      js.js('function(obj, v) { return obj.# = v }', [jsName]),
                       element: member));
                 }
               }
@@ -447,7 +447,7 @@
                   interceptorClass.callStubs.add(_buildStubMethod(
                       stubName,
                       js.js('function(receiver, #) { return receiver.#(#) }',
-                          [parameters, member.name, parameters]),
+                          [parameters, jsName, parameters]),
                       element: member));
                 }
               }
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 ddef40b..16ada26 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -133,15 +133,15 @@
         generateFunctionTypeSignature, generateSubstitution, generateTypeCheck);
 
     if (classElement == backend.helpers.jsJavaScriptFunctionClass) {
-        var type = backend.jsInteropAnalysis.buildJsFunctionType();
-        if (type != null) {
-          jsAst.Expression thisAccess = new jsAst.This();
-          RuntimeTypesEncoder rtiEncoder = backend.rtiEncoder;
-          jsAst.Expression encoding =
-              rtiEncoder.getSignatureEncoding(type, thisAccess);
-          jsAst.Name operatorSignature = namer.asName(namer.operatorSignature);
-          result.properties[operatorSignature] = encoding;
-        }
+      var type = backend.jsInteropAnalysis.buildJsFunctionType();
+      if (type != null) {
+        jsAst.Expression thisAccess = new jsAst.This();
+        RuntimeTypesEncoder rtiEncoder = backend.rtiEncoder;
+        jsAst.Expression encoding =
+            rtiEncoder.getSignatureEncoding(type, thisAccess);
+        jsAst.Name operatorSignature = namer.asName(namer.operatorSignature);
+        result.properties[operatorSignature] = encoding;
+      }
     }
     return result;
   }
@@ -265,6 +265,7 @@
         generateSubstitution(check);
       }
     }
+
     ;
 
     tryEmitTest(cls);
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 072e8cb..07be9d6 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -14,12 +14,10 @@
     show ClassElement, Element, FieldElement, FunctionElement;
 import '../../js/js.dart' as js;
 import '../../js_backend/js_backend.dart' show JavaScriptBackend, Namer;
-
 import '../js_emitter.dart' show NativeEmitter;
 import '../js_emitter.dart' as emitterTask show Emitter;
-import '../program_builder/program_builder.dart' show ProgramBuilder;
 import '../model.dart';
-
+import '../program_builder/program_builder.dart' show ProgramBuilder;
 import 'model_emitter.dart';
 
 class Emitter implements emitterTask.Emitter {
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 b3be363..046fa6f 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -31,8 +31,8 @@
         TYPES;
 
 import '../../common.dart';
-import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
 import '../../compiler.dart' show Compiler;
+import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
 import '../../core_types.dart' show CoreClasses;
 import '../../elements/elements.dart' show ClassElement, FunctionElement;
 import '../../hash/sha1.dart' show Hasher;
@@ -44,11 +44,9 @@
 import '../../js_backend/js_backend.dart'
     show JavaScriptBackend, Namer, ConstantEmitter;
 import '../../util/uri_extras.dart' show relativize;
-
 import '../constant_ordering.dart' show deepCompareConstants;
 import '../headers.dart';
 import '../js_emitter.dart' show NativeEmitter;
-
 import '../js_emitter.dart' show buildTearOffCode, NativeGenerator;
 import '../model.dart';
 
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index be0cb41..c7c6e86 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -548,7 +548,7 @@
             handler.registerDependency(
                 library,
                 new SyntheticImportElement(
-                    library.entryCompilationUnit, Uris.dart_core),
+                    library.entryCompilationUnit, Uris.dart_core, coreLibrary),
                 coreLibrary);
           });
         }
@@ -916,10 +916,9 @@
 class LibraryDependencyNode {
   final LibraryElementX library;
 
-  // TODO(ahe): Remove [hashCodeCounter] and [hashCode] when
-  // VM implementation of Object.hashCode is not slow.
-  final int hashCode = ++hashCodeCounter;
-  static int hashCodeCounter = 0;
+  // Stored identity based hashCode for performance.
+  final int hashCode = _nextHash = (_nextHash + 100019).toUnsigned(30);
+  static int _nextHash = 0;
 
   /**
    * A linked list of the import tags that import [library] mapped to the
diff --git a/pkg/compiler/lib/src/mirror_renamer/mirror_renamer.dart b/pkg/compiler/lib/src/mirror_renamer/mirror_renamer.dart
deleted file mode 100644
index e838f8e..0000000
--- a/pkg/compiler/lib/src/mirror_renamer/mirror_renamer.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.
-
-library mirror_renamer;
-
-import '../compiler.dart' show Compiler;
-import '../dart_backend/dart_backend.dart'
-    show DartBackend, PlaceholderCollector;
-import '../elements/elements.dart';
-import '../tokens/token.dart' show Token;
-import '../tree/tree.dart';
-
-part 'renamer.dart';
-
-class MirrorRenamer {
-  const MirrorRenamer();
-
-  LibraryElement get helperLibrary => null;
-
-  FunctionElement get getNameFunction => null;
-
-  bool isMirrorHelperLibrary(LibraryElement element) => false;
-
-  void registerStaticSend(Element currentElement, Element target, Node node) {}
-
-  void addRenames(Map<Node, String> renames, List<Node> topLevelNodes,
-      PlaceholderCollector placeholderCollector) {}
-}
diff --git a/pkg/compiler/lib/src/mirror_renamer/renamer.dart b/pkg/compiler/lib/src/mirror_renamer/renamer.dart
deleted file mode 100644
index 5b2daa1..0000000
--- a/pkg/compiler/lib/src/mirror_renamer/renamer.dart
+++ /dev/null
@@ -1,118 +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 mirror_renamer;
-
-class MirrorRenamerImpl implements MirrorRenamer {
-  static const String MIRROR_HELPER_GET_NAME_FUNCTION = 'helperGetName';
-  static final Uri DART_MIRROR_HELPER =
-      new Uri(scheme: 'dart', path: '_mirror_helper');
-  static const String MIRROR_HELPER_SYMBOLS_MAP_NAME = '_SYMBOLS';
-
-  /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary
-  /// field is set.
-  final LibraryElement helperLibrary;
-
-  /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary
-  /// field is set.
-  final FunctionElement getNameFunction;
-
-  /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary
-  /// field is set.
-  final FieldElement symbolsMapVariable;
-
-  /// Maps mangled name to original name.
-  Map<String, String> symbols = new Map<String, String>();
-
-  /// Contains all occurrencs of MirrorSystem.getName() calls in the user code.
-  List<Node> mirrorSystemGetNameNodes = <Node>[];
-
-  /**
-   *  Initialized when the placeholderCollector collects the FunctionElement
-   *  backend.mirrorHelperGetNameFunction which represents the helperGetName
-   *  function in _mirror_helper.
-   */
-  FunctionExpression get getNameFunctionNode => getNameFunction.node;
-  VariableDefinitions get symbolsMapNode => symbolsMapVariable.node;
-  Compiler compiler;
-  DartBackend backend;
-
-  MirrorRenamerImpl(this.compiler, this.backend, LibraryElement library)
-      : this.helperLibrary = library,
-        getNameFunction =
-            library.find(MirrorRenamerImpl.MIRROR_HELPER_GET_NAME_FUNCTION),
-        symbolsMapVariable =
-            library.find(MirrorRenamerImpl.MIRROR_HELPER_SYMBOLS_MAP_NAME);
-
-  bool isMirrorHelperLibrary(LibraryElement element) {
-    return element == helperLibrary;
-  }
-
-  void registerStaticSend(Element currentElement, Element target, Send node) {
-    if (target == compiler.mirrorSystemGetNameFunction &&
-        currentElement.library != helperLibrary) {
-      // Access to `MirrorSystem.getName` that needs to be redirected to the
-      // [getNameFunction].
-      mirrorSystemGetNameNodes.add(node);
-    }
-  }
-
-  /**
-   * Adds a toplevel node to the output containing a map from the mangled
-   * to the unmangled names and replaces calls to MirrorSystem.getName()
-   * with calls to the corresponding wrapper from _mirror_helper which has
-   * been added during resolution. [renames] is assumed to map nodes in user
-   * code to mangled names appearing in output code, and [topLevelNodes] should
-   * contain all the toplevel ast nodes that will be emitted in the output.
-   */
-  void addRenames(Map<Node, String> renames, List<Node> topLevelNodes,
-      PlaceholderCollector placeholderCollector) {
-    // Right now we only support instances of MirrorSystem.getName,
-    // hence if there are no occurence of these we don't do anything.
-    if (mirrorSystemGetNameNodes.isEmpty) {
-      return;
-    }
-
-    Node parse(String text) {
-      Token tokens = compiler.scanner.tokenize(text);
-      return compiler.parser.parseCompilationUnit(tokens);
-    }
-
-    // Add toplevel map containing all renames of members.
-    symbols = new Map<String, String>();
-    for (Set<Identifier> s in placeholderCollector.memberPlaceholders.values) {
-      // All members in a set have the same name so we only need to look at one.
-      Identifier sampleNode = s.first;
-      symbols.putIfAbsent(renames[sampleNode], () => sampleNode.source);
-    }
-
-    Identifier symbolsMapIdentifier =
-        symbolsMapNode.definitions.nodes.head.asSend().selector;
-    assert(symbolsMapIdentifier != null);
-    topLevelNodes.remove(symbolsMapNode);
-
-    StringBuffer sb = new StringBuffer(
-        'const ${renames[symbolsMapIdentifier]} = const<String,String>{');
-    bool first = true;
-    for (String mangledName in symbols.keys) {
-      if (!first) {
-        sb.write(',');
-      } else {
-        first = false;
-      }
-      sb.write("'$mangledName' : '");
-      sb.write(symbols[mangledName]);
-      sb.write("'");
-    }
-    sb.write('};');
-    sb.writeCharCode(0); // Terminate the string with '0', see [StringScanner].
-    topLevelNodes.add(parse(sb.toString()));
-
-    // Replace calls to Mirrorsystem.getName with calls to helper function.
-    mirrorSystemGetNameNodes.forEach((node) {
-      renames[node.selector] = renames[getNameFunctionNode.name];
-      renames[node.receiver] = '';
-    });
-  }
-}
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index a4e2922..57ef61a 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -15,7 +15,6 @@
 import '../tree/tree.dart';
 import '../universe/side_effects.dart' show SideEffects;
 import '../util/util.dart';
-
 import 'enqueue.dart';
 import 'js.dart';
 
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index e8f3340..166e6cf 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -296,6 +296,7 @@
       }
       return e;
     }
+
     _annotationCreatesClass = find('Creates');
     _annotationReturnsClass = find('Returns');
     _annotationJsNameClass = find('JSName');
diff --git a/pkg/compiler/lib/src/native/js.dart b/pkg/compiler/lib/src/native/js.dart
index 1251fe5..e7c7079 100644
--- a/pkg/compiler/lib/src/native/js.dart
+++ b/pkg/compiler/lib/src/native/js.dart
@@ -4,7 +4,6 @@
 
 import '../js/js.dart' as js;
 import '../universe/side_effects.dart' show SideEffects;
-
 import 'behavior.dart';
 
 class HasCapturedPlaceholders extends js.BaseVisitor {
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index c9c60f69..2c30a27 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -19,6 +19,7 @@
   'html_common',
   'indexed_db',
   'js',
+  'js_util',
   'svg',
   '_native_typed_data',
   'web_audio',
@@ -32,6 +33,7 @@
     return scriptName.contains('sdk/tests/compiler/dart2js_native') ||
         scriptName.contains('sdk/tests/compiler/dart2js_extra');
   }
+
   bool allowedDartLibary() {
     Uri uri = library.canonicalUri;
     if (uri.scheme != 'dart') return false;
diff --git a/pkg/compiler/lib/src/native/scanner.dart b/pkg/compiler/lib/src/native/scanner.dart
index f22b866..c1bc40d 100644
--- a/pkg/compiler/lib/src/native/scanner.dart
+++ b/pkg/compiler/lib/src/native/scanner.dart
@@ -4,7 +4,6 @@
 
 import '../common.dart';
 import '../parser/element_listener.dart' show ElementListener;
-import '../parser/listener.dart' show Listener;
 import '../tokens/token.dart' show BeginGroupToken, Token;
 import '../tokens/token_constants.dart' as Tokens show STRING_TOKEN;
 
diff --git a/pkg/compiler/lib/src/null_compiler_output.dart b/pkg/compiler/lib/src/null_compiler_output.dart
index acc323f..ed5a186 100644
--- a/pkg/compiler/lib/src/null_compiler_output.dart
+++ b/pkg/compiler/lib/src/null_compiler_output.dart
@@ -6,9 +6,10 @@
 
 library compiler.null_api;
 
-import '../compiler_new.dart';
 import 'dart:async';
 
+import '../compiler_new.dart';
+
 /// Null pattern implementation of the [CompilerOutput] interface.
 class NullCompilerOutput implements CompilerOutput {
   const NullCompilerOutput();
diff --git a/pkg/compiler/lib/src/old_to_new_api.dart b/pkg/compiler/lib/src/old_to_new_api.dart
index 7954091..d79b5f9 100644
--- a/pkg/compiler/lib/src/old_to_new_api.dart
+++ b/pkg/compiler/lib/src/old_to_new_api.dart
@@ -8,9 +8,10 @@
 library compiler.api.legacy;
 
 import 'dart:async' show EventSink, Future;
-import 'null_compiler_output.dart' show NullSink;
+
 import '../compiler.dart';
 import '../compiler_new.dart';
+import 'null_compiler_output.dart' show NullSink;
 
 /// Implementation of [CompilerInput] using a [CompilerInputProvider].
 class LegacyCompilerInput implements CompilerInput {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index ee3370e..1c597ef 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -4,8 +4,8 @@
 
 library dart2js.src.options;
 
-import 'commandline_options.dart' show Flags;
 import '../compiler.dart' show PackagesDiscoveryProvider;
+import 'commandline_options.dart' show Flags;
 
 /// Options used for parsing.
 ///
@@ -200,6 +200,9 @@
   // If `true`, sources are resolved and serialized.
   final bool resolveOnly;
 
+  // If `true`, sources are only available from serialized data.
+  final bool compileOnly;
+
   /// URI where the compiler should generate the output source map file.
   final Uri sourceMapUri;
 
@@ -218,9 +221,6 @@
   /// Whether to generate code compliant with content security policy (CSP).
   final bool useContentSecurityPolicy;
 
-  /// Use the experimental CPS based backend.
-  final bool useCpsIr;
-
   /// When obfuscating for minification, whether to use the frequency of a name
   /// as an heuristic to pick shorter names.
   final bool useFrequencyNamer;
@@ -245,12 +245,6 @@
   /// Whether to preserve comments while scanning (only use for dart:mirrors).
   final bool preserveComments;
 
-  /// Whether to emit JavaScript (false enables dart2dart).
-  final bool emitJavaScript;
-
-  /// When using dart2dart, whether to use the multi file format.
-  final bool dart2dartMultiFile;
-
   /// Strip option used by dart2dart.
   final List<String> strips;
 
@@ -280,7 +274,6 @@
         analyzeSignaturesOnly: _hasOption(options, Flags.analyzeSignaturesOnly),
         buildId: _extractStringOption(
             options, '--build-id=', _UNDETERMINED_BUILD_ID),
-        dart2dartMultiFile: _hasOption(options, '--output-type=dart-multi'),
         deferredMapUri: _extractUriOption(options, '--deferred-map='),
         fatalWarnings: _hasOption(options, Flags.fatalWarnings),
         terseDiagnostics: _hasOption(options, Flags.terse),
@@ -291,8 +284,6 @@
         disableInlining: _hasOption(options, Flags.disableInlining),
         disableTypeInference: _hasOption(options, Flags.disableTypeInference),
         dumpInfo: _hasOption(options, Flags.dumpInfo),
-        emitJavaScript: !(_hasOption(options, '--output-type=dart') ||
-            _hasOption(options, '--output-type=dart-multi')),
         enableAssertMessage: _hasOption(options, Flags.enableAssertMessage),
         enableGenericMethodSyntax:
             _hasOption(options, Flags.genericMethodSyntax),
@@ -327,7 +318,6 @@
         trustTypeAnnotations: _hasOption(options, Flags.trustTypeAnnotations),
         useContentSecurityPolicy:
             _hasOption(options, Flags.useContentSecurityPolicy),
-        useCpsIr: _hasOption(options, Flags.useCpsIr),
         useFrequencyNamer:
             !_hasOption(options, Flags.noFrequencyBasedMinification),
         useNewSourceInfo: _hasOption(options, Flags.useNewSourceInfo),
@@ -354,7 +344,6 @@
       bool analyzeOnly: false,
       bool analyzeSignaturesOnly: false,
       String buildId: _UNDETERMINED_BUILD_ID,
-      bool dart2dartMultiFile: false,
       Uri deferredMapUri: null,
       bool fatalWarnings: false,
       bool terseDiagnostics: false,
@@ -364,7 +353,6 @@
       bool disableInlining: false,
       bool disableTypeInference: false,
       bool dumpInfo: false,
-      bool emitJavaScript: true,
       bool enableAssertMessage: false,
       bool enableGenericMethodSyntax: false,
       bool enableInitializingFormalAccess: false,
@@ -390,7 +378,6 @@
       bool trustPrimitives: false,
       bool trustTypeAnnotations: false,
       bool useContentSecurityPolicy: false,
-      bool useCpsIr: false,
       bool useFrequencyNamer: true,
       bool useNewSourceInfo: false,
       bool useStartupEmitter: false,
@@ -428,7 +415,6 @@
             analyzeOnly || analyzeSignaturesOnly || analyzeAll || resolveOnly,
         analyzeSignaturesOnly: analyzeSignaturesOnly,
         buildId: buildId,
-        dart2dartMultiFile: dart2dartMultiFile,
         deferredMapUri: deferredMapUri,
         fatalWarnings: fatalWarnings,
         terseDiagnostics: terseDiagnostics,
@@ -436,9 +422,8 @@
         suppressHints: suppressHints,
         shownPackageWarnings: shownPackageWarnings,
         disableInlining: disableInlining || hasIncrementalSupport,
-        disableTypeInference: disableTypeInference || !emitJavaScript,
+        disableTypeInference: disableTypeInference,
         dumpInfo: dumpInfo,
-        emitJavaScript: emitJavaScript,
         enableAssertMessage: enableAssertMessage,
         enableGenericMethodSyntax: enableGenericMethodSyntax,
         enableInitializingFormalAccess: enableInitializingFormalAccess,
@@ -452,8 +437,7 @@
         hasIncrementalSupport: hasIncrementalSupport,
         outputUri: outputUri,
         platformConfigUri: platformConfigUri ??
-            _resolvePlatformConfig(
-                libraryRoot, null, !emitJavaScript, const []),
+            _resolvePlatformConfig(libraryRoot, null, const []),
         preserveComments: preserveComments,
         preserveUris: preserveUris,
         resolutionInputs: resolutionInputs,
@@ -466,7 +450,6 @@
         trustPrimitives: trustPrimitives,
         trustTypeAnnotations: trustTypeAnnotations,
         useContentSecurityPolicy: useContentSecurityPolicy,
-        useCpsIr: useCpsIr,
         useFrequencyNamer: useFrequencyNamer,
         useNewSourceInfo: useNewSourceInfo,
         useStartupEmitter: useStartupEmitter,
@@ -482,7 +465,6 @@
       this.analyzeOnly: false,
       this.analyzeSignaturesOnly: false,
       this.buildId: _UNDETERMINED_BUILD_ID,
-      this.dart2dartMultiFile: false,
       this.deferredMapUri: null,
       this.fatalWarnings: false,
       this.terseDiagnostics: false,
@@ -492,7 +474,6 @@
       this.disableInlining: false,
       this.disableTypeInference: false,
       this.dumpInfo: false,
-      this.emitJavaScript: true,
       this.enableAssertMessage: false,
       this.enableGenericMethodSyntax: false,
       this.enableInitializingFormalAccess: false,
@@ -511,6 +492,7 @@
       this.resolutionInputs: null,
       this.resolutionOutput: null,
       this.resolveOnly: false,
+      this.compileOnly: false,
       this.sourceMapUri: null,
       this.strips: const [],
       this.testMode: false,
@@ -518,7 +500,6 @@
       this.trustPrimitives: false,
       this.trustTypeAnnotations: false,
       this.useContentSecurityPolicy: false,
-      this.useCpsIr: false,
       this.useFrequencyNamer: false,
       this.useNewSourceInfo: false,
       this.useStartupEmitter: false,
@@ -527,7 +508,7 @@
 
   /// Creates a copy of the [CompilerOptions] where the provided non-null
   /// option values replace existing.
-  CompilerOptions copy(
+  static CompilerOptions copy(CompilerOptions options,
       {entryPoint,
       libraryRoot,
       packageRoot,
@@ -541,7 +522,6 @@
       analyzeOnly,
       analyzeSignaturesOnly,
       buildId,
-      dart2dartMultiFile,
       deferredMapUri,
       fatalWarnings,
       terseDiagnostics,
@@ -551,7 +531,6 @@
       disableInlining,
       disableTypeInference,
       dumpInfo,
-      emitJavaScript,
       enableAssertMessage,
       enableGenericMethodSyntax,
       enableInitializingFormalAccess,
@@ -570,6 +549,7 @@
       resolutionInputs,
       resolutionOutput,
       resolveOnly,
+      compileOnly,
       sourceMapUri,
       strips,
       testMode,
@@ -577,77 +557,79 @@
       trustPrimitives,
       trustTypeAnnotations,
       useContentSecurityPolicy,
-      useCpsIr,
       useFrequencyNamer,
       useNewSourceInfo,
       useStartupEmitter,
       verbose}) {
     return new CompilerOptions._(
-        entryPoint ?? this.entryPoint,
-        libraryRoot ?? this.libraryRoot,
-        packageRoot ?? this.packageRoot,
-        packageConfig ?? this.packageConfig,
-        packagesDiscoveryProvider ?? this.packagesDiscoveryProvider,
-        environment ?? this.environment,
-        allowMockCompilation: allowMockCompilation ?? this.allowMockCompilation,
+        entryPoint ?? options.entryPoint,
+        libraryRoot ?? options.libraryRoot,
+        packageRoot ?? options.packageRoot,
+        packageConfig ?? options.packageConfig,
+        packagesDiscoveryProvider ?? options.packagesDiscoveryProvider,
+        environment ?? options.environment,
+        allowMockCompilation:
+            allowMockCompilation ?? options.allowMockCompilation,
         allowNativeExtensions:
-            allowNativeExtensions ?? this.allowNativeExtensions,
-        analyzeAll: analyzeAll ?? this.analyzeAll,
-        analyzeMain: analyzeMain ?? this.analyzeMain,
-        analyzeOnly: analyzeOnly ?? this.analyzeOnly,
+            allowNativeExtensions ?? options.allowNativeExtensions,
+        analyzeAll: analyzeAll ?? options.analyzeAll,
+        analyzeMain: analyzeMain ?? options.analyzeMain,
+        analyzeOnly: analyzeOnly ?? options.analyzeOnly,
         analyzeSignaturesOnly:
-            analyzeSignaturesOnly ?? this.analyzeSignaturesOnly,
-        buildId: buildId ?? this.buildId,
-        dart2dartMultiFile: dart2dartMultiFile ?? this.dart2dartMultiFile,
-        deferredMapUri: deferredMapUri ?? this.deferredMapUri,
-        fatalWarnings: fatalWarnings ?? this.fatalWarnings,
-        terseDiagnostics: terseDiagnostics ?? this.terseDiagnostics,
-        suppressWarnings: suppressWarnings ?? this.suppressWarnings,
-        suppressHints: suppressHints ?? this.suppressHints,
+            analyzeSignaturesOnly ?? options.analyzeSignaturesOnly,
+        buildId: buildId ?? options.buildId,
+        deferredMapUri: deferredMapUri ?? options.deferredMapUri,
+        fatalWarnings: fatalWarnings ?? options.fatalWarnings,
+        terseDiagnostics: terseDiagnostics ?? options.terseDiagnostics,
+        suppressWarnings: suppressWarnings ?? options.suppressWarnings,
+        suppressHints: suppressHints ?? options.suppressHints,
         shownPackageWarnings:
-            shownPackageWarnings ?? this._shownPackageWarnings,
-        disableInlining: disableInlining ?? this.disableInlining,
-        disableTypeInference: disableTypeInference ?? this.disableTypeInference,
-        dumpInfo: dumpInfo ?? this.dumpInfo,
-        emitJavaScript: emitJavaScript ?? this.emitJavaScript,
-        enableAssertMessage: enableAssertMessage ?? this.enableAssertMessage,
+            shownPackageWarnings ?? options._shownPackageWarnings,
+        disableInlining: disableInlining ?? options.disableInlining,
+        disableTypeInference:
+            disableTypeInference ?? options.disableTypeInference,
+        dumpInfo: dumpInfo ?? options.dumpInfo,
+        enableAssertMessage: enableAssertMessage ?? options.enableAssertMessage,
         enableGenericMethodSyntax:
-            enableGenericMethodSyntax ?? this.enableGenericMethodSyntax,
+            enableGenericMethodSyntax ?? options.enableGenericMethodSyntax,
         enableInitializingFormalAccess: enableInitializingFormalAccess ??
-            this.enableInitializingFormalAccess,
+            options.enableInitializingFormalAccess,
         enableExperimentalMirrors:
-            enableExperimentalMirrors ?? this.enableExperimentalMirrors,
-        enableMinification: enableMinification ?? this.enableMinification,
-        enableNativeLiveTypeAnalysis:
-            enableNativeLiveTypeAnalysis ?? this.enableNativeLiveTypeAnalysis,
-        enableTypeAssertions: enableTypeAssertions ?? this.enableTypeAssertions,
-        enableUserAssertions: enableUserAssertions ?? this.enableUserAssertions,
+            enableExperimentalMirrors ?? options.enableExperimentalMirrors,
+        enableMinification: enableMinification ?? options.enableMinification,
+        enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis ??
+            options.enableNativeLiveTypeAnalysis,
+        enableTypeAssertions:
+            enableTypeAssertions ?? options.enableTypeAssertions,
+        enableUserAssertions:
+            enableUserAssertions ?? options.enableUserAssertions,
         generateCodeWithCompileTimeErrors: generateCodeWithCompileTimeErrors ??
-            this.generateCodeWithCompileTimeErrors,
-        generateSourceMap: generateSourceMap ?? this.generateSourceMap,
+            options.generateCodeWithCompileTimeErrors,
+        generateSourceMap: generateSourceMap ?? options.generateSourceMap,
         hasIncrementalSupport:
-            hasIncrementalSupport ?? this.hasIncrementalSupport,
-        outputUri: outputUri ?? this.outputUri,
-        platformConfigUri: platformConfigUri ?? this.platformConfigUri,
-        preserveComments: preserveComments ?? this.preserveComments,
-        preserveUris: preserveUris ?? this.preserveUris,
-        resolutionInputs: resolutionInputs ?? this.resolutionInputs,
-        resolutionOutput: resolutionOutput ?? this.resolutionOutput,
-        resolveOnly: resolveOnly ?? this.resolveOnly,
-        sourceMapUri: sourceMapUri ?? this.sourceMapUri,
-        strips: strips ?? this.strips,
-        testMode: testMode ?? this.testMode,
-        trustJSInteropTypeAnnotations:
-            trustJSInteropTypeAnnotations ?? this.trustJSInteropTypeAnnotations,
-        trustPrimitives: trustPrimitives ?? this.trustPrimitives,
-        trustTypeAnnotations: trustTypeAnnotations ?? this.trustTypeAnnotations,
+            hasIncrementalSupport ?? options.hasIncrementalSupport,
+        outputUri: outputUri ?? options.outputUri,
+        platformConfigUri: platformConfigUri ?? options.platformConfigUri,
+        preserveComments: preserveComments ?? options.preserveComments,
+        preserveUris: preserveUris ?? options.preserveUris,
+        resolutionInputs: resolutionInputs ?? options.resolutionInputs,
+        resolutionOutput: resolutionOutput ?? options.resolutionOutput,
+        resolveOnly: resolveOnly ?? options.resolveOnly,
+        compileOnly: compileOnly ?? options.compileOnly,
+        sourceMapUri: sourceMapUri ?? options.sourceMapUri,
+        strips: strips ?? options.strips,
+        testMode: testMode ?? options.testMode,
+        trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations ??
+            options.trustJSInteropTypeAnnotations,
+        trustPrimitives: trustPrimitives ?? options.trustPrimitives,
+        trustTypeAnnotations:
+            trustTypeAnnotations ?? options.trustTypeAnnotations,
         useContentSecurityPolicy:
-            useContentSecurityPolicy ?? this.useContentSecurityPolicy,
-        useCpsIr: useCpsIr ?? this.useCpsIr,
-        useFrequencyNamer: useFrequencyNamer ?? this.useFrequencyNamer,
-        useNewSourceInfo: useNewSourceInfo ?? this.useNewSourceInfo,
-        useStartupEmitter: useStartupEmitter ?? this.useStartupEmitter,
-        verbose: verbose ?? this.verbose);
+            useContentSecurityPolicy ?? options.useContentSecurityPolicy,
+        useFrequencyNamer: useFrequencyNamer ?? options.useFrequencyNamer,
+        useNewSourceInfo: useNewSourceInfo ?? options.useNewSourceInfo,
+        useStartupEmitter: useStartupEmitter ?? options.useStartupEmitter,
+        verbose: verbose ?? options.verbose);
   }
 
   /// Returns `true` if warnings and hints are shown for all packages.
@@ -716,12 +698,10 @@
   return null;
 }
 
-Uri _resolvePlatformConfig(Uri libraryRoot, String platformConfigPath,
-    bool isDart2Dart, Iterable<String> categories) {
+Uri _resolvePlatformConfig(
+    Uri libraryRoot, String platformConfigPath, Iterable<String> categories) {
   if (platformConfigPath != null) {
     return libraryRoot.resolve(platformConfigPath);
-  } else if (isDart2Dart) {
-    return libraryRoot.resolve(_dart2dartPlatform);
   } else {
     if (categories.length == 0) {
       return libraryRoot.resolve(_clientPlatform);
@@ -742,7 +722,6 @@
   return _resolvePlatformConfig(
       libraryRoot,
       _extractStringOption(options, "--platform-config=", null),
-      _hasOption(options, '--output-type=dart'),
       _extractCsvOption(options, '--categories='));
 }
 
@@ -750,7 +729,6 @@
 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";
 
 const String _UNDETERMINED_BUILD_ID = "build number could not be determined";
 const bool _forceIncrementalSupport =
diff --git a/pkg/compiler/lib/src/parser/class_element_parser.dart b/pkg/compiler/lib/src/parser/class_element_parser.dart
index b85114d..3d3cd27 100644
--- a/pkg/compiler/lib/src/parser/class_element_parser.dart
+++ b/pkg/compiler/lib/src/parser/class_element_parser.dart
@@ -4,10 +4,9 @@
 
 library dart2js.parser.classes;
 
-import '../tokens/token.dart' show Token;
-
-import 'listener.dart' show Listener;
 import '../options.dart' show ParserOptions;
+import '../tokens/token.dart' show Token;
+import 'listener.dart' show Listener;
 import 'partial_parser.dart' show PartialParser;
 
 class ClassElementParser extends PartialParser {
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 3c48a31..002bba0 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -9,11 +9,10 @@
 import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../elements/elements.dart' show CompilationUnitElement;
 import '../id_generator.dart';
-import '../tokens/token.dart' show Token;
-
-import 'listener.dart' show ParserError;
-import 'element_listener.dart' show ElementListener, ScannerOptions;
 import '../options.dart' show ParserOptions;
+import '../tokens/token.dart' show Token;
+import 'element_listener.dart' show ElementListener, ScannerOptions;
+import 'listener.dart' show ParserError;
 import 'partial_parser.dart' show PartialParser;
 
 class DietParserTask extends CompilerTask {
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 6d9bd82..e5904f0 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -4,7 +4,6 @@
 
 library dart2js.parser.element_listener;
 
-import '../compiler.dart' show Compiler;
 import '../common.dart';
 import '../diagnostics/messages.dart' show MessageTemplate;
 import '../elements/elements.dart'
@@ -30,7 +29,7 @@
 import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
 import '../tree/tree.dart';
 import '../util/util.dart' show Link, LinkBuilder;
-
+import 'listener.dart' show closeBraceFor, Listener, ParserError, VERBOSE;
 import 'partial_elements.dart'
     show
         PartialClassElement,
@@ -39,7 +38,6 @@
         PartialFunctionElement,
         PartialMetadataAnnotation,
         PartialTypedefElement;
-import 'listener.dart' show closeBraceFor, Listener, ParserError, VERBOSE;
 
 /// Options used for scanning.
 ///
@@ -323,6 +321,7 @@
     void buildFieldElement(Identifier name, VariableList fields) {
       pushElement(new FieldElementX(name, compilationUnitElement, fields));
     }
+
     NodeList variables = makeNodeList(count, null, null, ",");
     popNode(); // type
     Modifiers modifiers = popNode();
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index ce29d16..3115343 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -619,7 +619,13 @@
 }
 
 String closeBraceFor(String openBrace) {
-  return const {'(': ')', '[': ']', '{': '}', '<': '>', r'${': '}',}[openBrace];
+  return const {
+    '(': ')',
+    '[': ']',
+    '{': '}',
+    '<': '>',
+    r'${': '}',
+  }[openBrace];
 }
 
 class ParserError {
diff --git a/pkg/compiler/lib/src/parser/member_listener.dart b/pkg/compiler/lib/src/parser/member_listener.dart
index b50847e..c21f493 100644
--- a/pkg/compiler/lib/src/parser/member_listener.dart
+++ b/pkg/compiler/lib/src/parser/member_listener.dart
@@ -122,6 +122,7 @@
       Element element = new FieldElementX(name, enclosingClass, fields);
       addMember(element);
     }
+
     buildFieldElements(modifiers, variableDefinitions.definitions,
         enclosingClass, buildFieldElement, beginToken, endToken, hasParseError);
   }
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index 821fcad..f9998ca 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -4,8 +4,8 @@
 
 library dart2js.parser;
 
-import '../options.dart' show ParserOptions;
 import '../common.dart';
+import '../options.dart' show ParserOptions;
 import '../tokens/keyword.dart' show Keyword;
 import '../tokens/precedence.dart' show PrecedenceInfo;
 import '../tokens/precedence_constants.dart'
@@ -58,7 +58,6 @@
         STRING_TOKEN;
 import '../util/characters.dart' as Characters show $CLOSE_CURLY_BRACKET;
 import '../util/util.dart' show Link;
-
 import 'listener.dart' show Listener;
 
 class FormalParameterType {
@@ -424,13 +423,12 @@
     listener.beginFormalParameters(begin);
     expect('(', token);
     int parameterCount = 0;
-    if (optional(')', token.next)) {
-      listener.endFormalParameters(parameterCount, begin, token.next);
-      return token.next.next;
-    }
     do {
-      ++parameterCount;
       token = token.next;
+      if (optional(')', token)) {
+        break;
+      }
+      ++parameterCount;
       String value = token.stringValue;
       if (identical(value, '[')) {
         token = parseOptionalFormalParameters(token, false);
@@ -495,11 +493,23 @@
     int parameterCount = 0;
     do {
       token = token.next;
+      if (isNamed && optional('}', token)) {
+        break;
+      } else if (!isNamed && optional(']', token)) {
+        break;
+      }
       var type =
           isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
       token = parseFormalParameter(token, type);
       ++parameterCount;
     } while (optional(',', token));
+    if (parameterCount == 0) {
+      listener.reportError(
+          token,
+          isNamed
+              ? MessageKind.EMPTY_NAMED_PARAMETER_LIST
+              : MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST);
+    }
     listener.endOptionalFormalParameters(parameterCount, begin, token);
     if (isNamed) {
       return expect('}', token);
@@ -2565,6 +2575,10 @@
     bool old = mayParseFunctionExpressions;
     mayParseFunctionExpressions = true;
     do {
+      if (optional(')', token.next)) {
+        token = token.next;
+        break;
+      }
       Token colon = null;
       if (optional(':', token.next.next)) {
         token = parseIdentifier(token.next);
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index 02c3719..07734b9 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -11,7 +11,6 @@
 import '../options.dart' show ParserOptions;
 import '../tokens/token.dart' show Token;
 import '../tree/tree.dart' show Node;
-
 import 'element_listener.dart' show ScannerOptions;
 import 'listener.dart' show ParserError;
 import 'node_listener.dart' show NodeListener;
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
index 8e74bf3..87cb2f1 100644
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ b/pkg/compiler/lib/src/parser/partial_elements.dart
@@ -92,6 +92,7 @@
         p.parseFunction(beginToken, getOrSet);
       }
     }
+
     cachedNode = parse(parsing, this, declarationSite, parseFunction);
     return cachedNode;
   }
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 514a058..0868265 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -6,10 +6,9 @@
 
 import '../common.dart';
 import '../options.dart' show ParserOptions;
-import '../util/characters.dart' as Characters show $CLOSE_CURLY_BRACKET;
 import '../tokens/token.dart' show BeginGroupToken, ErrorToken, Token;
 import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
-
+import '../util/characters.dart' as Characters show $CLOSE_CURLY_BRACKET;
 import 'listener.dart' show Listener;
 import 'parser.dart' show Parser;
 
diff --git a/pkg/compiler/lib/src/platform_configuration.dart b/pkg/compiler/lib/src/platform_configuration.dart
index 56a48df..e721001 100644
--- a/pkg/compiler/lib/src/platform_configuration.dart
+++ b/pkg/compiler/lib/src/platform_configuration.dart
@@ -6,7 +6,9 @@
 library plaform_configuration;
 
 import "dart:async";
+
 import "package:charcode/ascii.dart";
+
 import "../compiler_new.dart" as api;
 
 /// Parses an Ini-like format.
diff --git a/pkg/compiler/lib/src/resolution/access_semantics.dart b/pkg/compiler/lib/src/resolution/access_semantics.dart
index fdd8410..ffb71f9 100644
--- a/pkg/compiler/lib/src/resolution/access_semantics.dart
+++ b/pkg/compiler/lib/src/resolution/access_semantics.dart
@@ -8,8 +8,8 @@
 library dart2js.access_semantics;
 
 import '../constants/expressions.dart';
-import '../elements/elements.dart';
 import '../dart_types.dart';
+import '../elements/elements.dart';
 
 /// Enum representing the different kinds of destinations which a property
 /// access or method or function invocation might refer to.
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index 87c00a8..edf87b7 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -5,8 +5,7 @@
 library dart2js.resolution.class_hierarchy;
 
 import '../common.dart';
-import '../common/resolution.dart' show Feature;
-import '../compiler.dart' show Compiler;
+import '../common/resolution.dart' show Resolution;
 import '../core_types.dart' show CoreClasses, CoreTypes;
 import '../dart_types.dart';
 import '../elements/elements.dart';
@@ -20,9 +19,9 @@
         UnnamedMixinApplicationElementX;
 import '../ordered_typeset.dart' show OrderedTypeSet, OrderedTypeSetBuilder;
 import '../tree/tree.dart';
-import '../util/util.dart' show Link, Setlet;
 import '../universe/call_structure.dart' show CallStructure;
-
+import '../universe/feature.dart' show Feature;
+import '../util/util.dart' show Link, Setlet;
 import 'enum_creator.dart';
 import 'members.dart' show lookupInScope;
 import 'registry.dart' show ResolutionRegistry;
@@ -34,13 +33,13 @@
   final TypeDeclarationElement enclosingElement;
   TypeDeclarationElement get element => enclosingElement;
 
-  TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element,
+  TypeDefinitionVisitor(Resolution resolution, TypeDeclarationElement element,
       ResolutionRegistry registry)
       : this.enclosingElement = element,
         scope = Scope.buildEnclosingScope(element),
-        super(compiler, registry);
+        super(resolution, registry);
 
-  CoreTypes get coreTypes => compiler.coreTypes;
+  CoreTypes get coreTypes => resolution.coreTypes;
 
   DartType get objectType => coreTypes.objectType;
 
@@ -93,6 +92,7 @@
             bound = element.bound;
           }
         }
+
         addDeferredAction(element, checkTypeVariableBound);
       } else {
         variableElement.boundCache = objectType;
@@ -118,9 +118,9 @@
 class ClassResolverVisitor extends TypeDefinitionVisitor {
   BaseClassElementX get element => enclosingElement;
 
-  ClassResolverVisitor(
-      Compiler compiler, ClassElement classElement, ResolutionRegistry registry)
-      : super(compiler, classElement, registry);
+  ClassResolverVisitor(Resolution resolution, ClassElement classElement,
+      ResolutionRegistry registry)
+      : super(resolution, classElement, registry);
 
   DartType visitClassNode(ClassNode node) {
     if (element == null) {
@@ -212,7 +212,7 @@
           new SynthesizedConstructorElementX.forDefault(superMember, element);
       if (superMember.isMalformed) {
         ErroneousElement erroneousElement = superMember;
-        compiler.registerCompiletimeError(
+        resolution.registerCompileTimeError(
             constructor,
             reporter.createMessage(node, erroneousElement.messageKind,
                 erroneousElement.messageArguments));
@@ -243,7 +243,7 @@
     }
 
     EnumCreator creator =
-        new EnumCreator(reporter, compiler.coreTypes, element);
+        new EnumCreator(reporter, resolution.coreTypes, element);
     creator.createMembers();
     return enumType;
   }
@@ -304,7 +304,7 @@
     String mixinName = mixinType.name;
     MixinApplicationElementX mixinApplication =
         new UnnamedMixinApplicationElementX("${superName}+${mixinName}",
-            element, compiler.idGenerator.getNextFreeId(), node);
+            element, resolution.idGenerator.getNextFreeId(), node);
     // Create synthetic type variables for the mixin application.
     List<DartType> typeVariables = <DartType>[];
     int index = 0;
@@ -360,7 +360,7 @@
 
     if (mixinApplication.supertype != null) {
       // [supertype] is not null if there was a cycle.
-      assert(invariant(node, compiler.compilationFailed));
+      assert(invariant(node, reporter.hasReportedError));
       supertype = mixinApplication.supertype;
       assert(invariant(node, supertype.isObject));
     } else {
@@ -545,7 +545,7 @@
               reporter: reporter, objectType: coreTypes.objectType)
           .createOrderedTypeSet(supertype, cls.interfaces);
     } else {
-      assert(cls == compiler.coreClasses.objectClass);
+      assert(cls == resolution.coreClasses.objectClass);
       cls.allSupertypesAndSelf =
           new OrderedTypeSet.singleton(cls.computeType(resolution));
     }
@@ -553,7 +553,7 @@
 
   isBlackListed(DartType type) {
     LibraryElement lib = element.library;
-    return !identical(lib, compiler.coreLibrary) &&
+    return !identical(lib, resolution.coreLibrary) &&
         !resolution.target.isTargetSpecificLibrary(lib) &&
         (type.isDynamic ||
             type == coreTypes.boolType ||
@@ -569,16 +569,16 @@
   Scope context;
   ClassElement classElement;
 
-  ClassSupertypeResolver(Compiler compiler, ClassElement cls)
+  ClassSupertypeResolver(Resolution resolution, ClassElement cls)
       : context = Scope.buildEnclosingScope(cls),
         this.classElement = cls,
-        super(compiler);
+        super(resolution);
 
-  CoreClasses get coreClasses => compiler.coreClasses;
+  CoreClasses get coreClasses => resolution.coreClasses;
 
   void loadSupertype(ClassElement element, Node from) {
     if (!element.isResolved) {
-      compiler.resolver.loadSupertypes(element, from);
+      resolution.resolver.loadSupertypes(element, from);
       element.ensureResolved(resolution);
     }
   }
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
index 7c28777..aca4df5 100644
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ b/pkg/compiler/lib/src/resolution/class_members.dart
@@ -7,7 +7,6 @@
 import '../common.dart';
 import '../common/names.dart' show Identifiers, Names;
 import '../common/resolution.dart' show Resolution;
-import '../compiler.dart' show Compiler;
 import '../dart_types.dart';
 import '../elements/elements.dart'
     show
@@ -281,6 +280,7 @@
           reporter.reportWarning(warning, infos);
         });
       }
+
       if (interfaceMember.isSetter) {
         reportWarning(
             MessageKind.UNIMPLEMENTED_SETTER_ONE,
@@ -444,6 +444,7 @@
                     ]);
               });
             }
+
             if (declared.isDeclaredByField) {
               if (inherited.isDeclaredByField) {
                 reportWarning(
@@ -687,7 +688,8 @@
         bool allAreGetters = true;
         Map<DartType, Setlet<Member>> subtypesOfAllInherited =
             new Map<DartType, Setlet<Member>>();
-        outer: for (Member inherited in inheritedMembers) {
+        outer:
+        for (Member inherited in inheritedMembers) {
           if (inherited.isGetter) {
             someAreGetters = true;
             if (!allAreGetters) break outer;
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 90f4716..b337d35 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -5,8 +5,7 @@
 library dart2js.resolution.constructors;
 
 import '../common.dart';
-import '../common/resolution.dart' show Feature;
-import '../compiler.dart' show Compiler;
+import '../common/resolution.dart' show Resolution;
 import '../constants/constructors.dart'
     show
         GenerativeConstantConstructor,
@@ -24,10 +23,10 @@
         InitializingFormalElementX,
         ParameterElementX;
 import '../tree/tree.dart';
-import '../util/util.dart' show Link;
 import '../universe/call_structure.dart' show CallStructure;
+import '../universe/feature.dart' show Feature;
 import '../universe/use.dart' show StaticUse;
-
+import '../util/util.dart' show Link;
 import 'members.dart' show lookupInScope, ResolverVisitor;
 import 'registry.dart' show ResolutionRegistry;
 import 'resolution_common.dart' show CommonResolverVisitor;
@@ -476,9 +475,9 @@
   final ResolverVisitor resolver;
   final bool inConstContext;
 
-  ConstructorResolver(Compiler compiler, this.resolver,
+  ConstructorResolver(Resolution resolution, this.resolver,
       {bool this.inConstContext: false})
-      : super(compiler);
+      : super(resolution);
 
   ResolutionRegistry get registry => resolver.registry;
 
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index b12218b..d2ca86e 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -6,8 +6,8 @@
 
 import '../common.dart';
 import '../common/names.dart' show Selectors;
-import '../common/resolution.dart' show Feature;
-import '../compiler.dart' show Compiler;
+import '../common/resolution.dart' show Resolution;
+import '../compile_time_constants.dart';
 import '../constants/constructors.dart'
     show RedirectingFactoryConstantConstructor;
 import '../constants/expressions.dart';
@@ -20,16 +20,17 @@
         ConstructorElementX,
         ErroneousElementX,
         FunctionElementX,
-        InitializingFormalElementX,
         JumpTargetX,
         LocalFunctionElementX,
         LocalParameterElementX,
         ParameterElementX,
         VariableElementX,
         VariableList;
+import '../options.dart';
 import '../tokens/token.dart' show isUserDefinableOperator;
 import '../tree/tree.dart';
 import '../universe/call_structure.dart' show CallStructure;
+import '../universe/feature.dart' show Feature;
 import '../universe/selector.dart' show Selector;
 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
 import '../util/util.dart' show Link;
@@ -112,7 +113,7 @@
 
   bool isPotentiallyMutableTarget(Element target) {
     if (target == null) return false;
-    return (target.isVariable || target.isParameter) &&
+    return (target.isVariable || target.isRegularParameter) &&
         !(target.isFinal || target.isConst);
   }
 
@@ -142,7 +143,7 @@
           r')$');
 
   ResolverVisitor(
-      Compiler compiler, Element element, ResolutionRegistry registry,
+      Resolution resolution, Element element, ResolutionRegistry registry,
       {Scope scope, bool useEnclosingScope: false})
       : this.enclosingElement = element,
         // When the element is a field, we are actually resolving its
@@ -159,7 +160,7 @@
                 : element.buildScope()),
         // The type annotations on a typedef do not imply type checks.
         // TODO(karlklose): clean this up (dartbug.com/8870).
-        inCheckContext = compiler.options.enableTypeAssertions &&
+        inCheckContext = resolution.options.enableTypeAssertions &&
             !element.isLibrary &&
             !element.isTypedef &&
             !element.enclosingElement.isTypedef,
@@ -167,11 +168,13 @@
         constantState = element.isConst
             ? ConstantState.CONSTANT
             : ConstantState.NON_CONSTANT,
-        super(compiler, registry);
+        super(resolution, registry);
 
-  CoreClasses get coreClasses => compiler.coreClasses;
-
-  CoreTypes get coreTypes => compiler.coreTypes;
+  CoreClasses get coreClasses => resolution.coreClasses;
+  CoreTypes get coreTypes => resolution.coreTypes;
+  ConstantEnvironment get constants => resolution.constants;
+  ResolverTask get resolver => resolution.resolver;
+  CompilerOptions get options => resolution.options;
 
   AsyncMarker get currentAsyncMarker {
     if (enclosingElement is FunctionElement) {
@@ -370,11 +373,7 @@
   }
 
   TypeResult visitTypeAnnotation(TypeAnnotation node) {
-    DartType type = resolveTypeAnnotation(node);
-    if (inCheckContext) {
-      registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
-    }
-    return new TypeResult(type);
+    return new TypeResult(resolveTypeAnnotation(node));
   }
 
   bool isNamedConstructor(Send node) => node.receiver != null;
@@ -454,18 +453,16 @@
     addDeferredAction(enclosingElement, () {
       functionSignature.forEachOptionalParameter((ParameterElementX parameter) {
         parameter.constant =
-            compiler.resolver.constantCompiler.compileConstant(parameter);
+            resolver.constantCompiler.compileConstant(parameter);
       });
     });
-    if (inCheckContext) {
-      functionSignature.forEachParameter((ParameterElement element) {
-        registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type));
-      });
-    }
+    functionSignature.forEachParameter((ParameterElement element) {
+      registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type));
+    });
   }
 
   ResolutionResult visitAssert(Assert node) {
-    if (!compiler.options.enableAssertMessage) {
+    if (!options.enableAssertMessage) {
       if (node.hasMessage) {
         reporter.reportErrorMessage(
             node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE);
@@ -564,7 +561,6 @@
       reporter.reportErrorMessage(node.name,
           MessageKind.NAMED_FUNCTION_EXPRESSION, {'name': node.name});
     }
-    visit(node.returnType);
     String name;
     if (node.name == null) {
       name = "";
@@ -573,9 +569,9 @@
     }
     LocalFunctionElementX function = new LocalFunctionElementX(
         name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement);
-    ResolverTask.processAsyncMarker(compiler, function, registry);
+    ResolverTask.processAsyncMarker(resolution, function, registry);
     function.functionSignature = SignatureResolver.analyze(
-        compiler,
+        resolution,
         scope,
         node.typeVariables,
         node.parameters,
@@ -880,7 +876,7 @@
   /// Compute the [AccessSemantics] corresponding to a local access of [target].
   AccessSemantics computeLocalAccessSemantics(
       Spannable node, LocalElement target) {
-    if (target.isParameter) {
+    if (target.isRegularParameter) {
       if (target.isFinal || target.isConst) {
         return new StaticAccess.finalParameter(target);
       } else {
@@ -2017,7 +2013,7 @@
   ResolutionResult handleConstantTypeLiteralUpdate(SendSet node, Name name,
       TypeDeclarationElement element, DartType type, ConstantAccess semantics) {
     // TODO(johnniwinther): Remove this when all constants are evaluated.
-    compiler.resolver.constantCompiler.evaluate(semantics.constant);
+    resolver.constantCompiler.evaluate(semantics.constant);
 
     ErroneousElement error;
     if (node.isIfNullAssignment) {
@@ -2560,7 +2556,7 @@
   ResolutionResult handleLocalUpdate(Send node, Name name, Element element) {
     AccessSemantics semantics;
     ErroneousElement error;
-    if (element.isParameter) {
+    if (element.isRegularParameter) {
       if (element.isFinal) {
         error = reportAndCreateErroneousElement(node.selector, name.text,
             MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
@@ -2569,7 +2565,7 @@
         semantics = new StaticAccess.parameter(element);
       }
     } else if (element.isInitializingFormal &&
-        compiler.options.enableInitializingFormalAccess) {
+        options.enableInitializingFormalAccess) {
       error = reportAndCreateErroneousElement(node.selector, name.text,
           MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
       semantics = new StaticAccess.finalParameter(element);
@@ -2627,12 +2623,12 @@
     // of parse errors to make [element] erroneous. Fix this!
     member.computeType(resolution);
 
-    if (member == compiler.mirrorSystemGetNameFunction &&
-        !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
+    if (member == resolution.mirrorSystemGetNameFunction &&
+        !resolution.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
       reporter
           .reportHintMessage(node.selector, MessageKind.STATIC_FUNCTION_BLOAT, {
-        'class': compiler.mirrorSystemClass.name,
-        'name': compiler.mirrorSystemGetNameFunction.name
+        'class': resolution.mirrorSystemClass.name,
+        'name': resolution.mirrorSystemGetNameFunction.name
       });
     }
 
@@ -2658,7 +2654,7 @@
             registry.registerStaticUse(
                 new StaticUse.staticInvoke(semantics.element, callStructure));
             handleForeignCall(node, semantics.element, callStructure);
-            if (method == compiler.identicalFunction &&
+            if (method == resolution.identicalFunction &&
                 argumentsResult.isValidAsConstant) {
               result = new ConstantResult(
                   node,
@@ -3028,7 +3024,7 @@
   // TODO(johnniwinther): Move this to the backend resolution callbacks.
   void handleForeignCall(
       Send node, Element target, CallStructure callStructure) {
-    if (target != null && compiler.backend.isForeign(target)) {
+    if (target != null && resolution.target.isForeign(target)) {
       registry.registerForeignCall(node, target, callStructure, this);
     }
   }
@@ -3577,7 +3573,7 @@
   }
 
   ResolutionResult visitYield(Yield node) {
-    if (!compiler.backend.supportsAsyncAwait) {
+    if (!resolution.target.supportsAsyncAwait) {
       reporter.reportErrorMessage(
           node.yieldToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
     } else {
@@ -3608,11 +3604,8 @@
     ConstructorResult result =
         resolveRedirectingFactory(node, inConstContext: isConstConstructor);
     ConstructorElement redirectionTarget = result.element;
-    constructor.immediateRedirectionTarget = redirectionTarget;
-
-    if (result.isDeferred) {
-      constructor.redirectionDeferredPrefix = result.prefix;
-    }
+    constructor.setImmediateRedirectionTarget(
+        redirectionTarget, result.isDeferred ? result.prefix : null);
 
     registry.setRedirectingTargetConstructor(node, redirectionTarget);
     switch (result.kind) {
@@ -3621,7 +3614,7 @@
         // 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);
+          resolver.resolveRedirectionChain(constructor, node);
         });
         break;
       case ConstructorResultKind.ABSTRACT:
@@ -3659,7 +3652,7 @@
         .subst(type.typeArguments, targetClass.typeVariables);
     FunctionType constructorType = constructor.computeType(resolution);
     bool isSubtype =
-        compiler.types.isSubtype(targetConstructorType, constructorType);
+        resolution.types.isSubtype(targetConstructorType, constructorType);
     if (!isSubtype) {
       reporter.reportWarningMessage(node, MessageKind.NOT_ASSIGNABLE,
           {'fromType': targetConstructorType, 'toType': constructorType});
@@ -3684,7 +3677,7 @@
     registry.registerTypeUse(new TypeUse.instantiation(redirectionTarget
         .enclosingClass.thisType
         .subst(type.typeArguments, targetClass.typeVariables)));
-    if (enclosingElement == compiler.symbolConstructor) {
+    if (enclosingElement == resolution.symbolConstructor) {
       registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
     }
     if (isValidAsConstant) {
@@ -3718,7 +3711,7 @@
   }
 
   ResolutionResult visitAwait(Await node) {
-    if (!compiler.backend.supportsAsyncAwait) {
+    if (!resolution.target.supportsAsyncAwait) {
       reporter.reportErrorMessage(
           node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
     } else {
@@ -3740,7 +3733,7 @@
     }
     VariableList variables = new VariableList.node(node, type);
     VariableDefinitionsVisitor visitor =
-        new VariableDefinitionsVisitor(compiler, node, this, variables);
+        new VariableDefinitionsVisitor(resolution, node, this, variables);
 
     Modifiers modifiers = node.modifiers;
     void reportExtraModifier(String modifier) {
@@ -3757,6 +3750,7 @@
       reporter.reportErrorMessage(modifierNode, MessageKind.EXTRANEOUS_MODIFIER,
           {'modifier': modifier});
     }
+
     if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) {
       reportExtraModifier('final');
     }
@@ -3773,7 +3767,7 @@
     }
     if (node.metadata != null) {
       variables.metadataInternal =
-          compiler.resolver.resolveMetadata(enclosingElement, node);
+          resolver.resolveMetadata(enclosingElement, node);
     }
     visitor.visit(node.definitions);
     return const NoneResult();
@@ -3893,11 +3887,11 @@
     if (node.isConst) {
       bool isValidAsConstant = !isInvalid && constructor.isConst;
 
-      if (constructor == compiler.symbolConstructor) {
+      if (constructor == resolution.symbolConstructor) {
         Node argumentNode = node.send.arguments.head;
-        ConstantExpression constant = compiler.resolver.constantCompiler
+        ConstantExpression constant = resolver.constantCompiler
             .compileNode(argumentNode, registry.mapping);
-        ConstantValue name = compiler.constants.getConstantValue(constant);
+        ConstantValue name = resolution.constants.getConstantValue(constant);
         if (!name.isString) {
           DartType type = name.getType(coreTypes);
           reporter.reportErrorMessage(
@@ -3909,8 +3903,8 @@
             registry.registerConstSymbol(nameString);
           }
         }
-      } else if (constructor == compiler.mirrorsUsedConstructor) {
-        compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
+      } else if (constructor == resolution.mirrorsUsedConstructor) {
+        resolution.mirrorUsageAnalyzerTask.validate(node, registry.mapping);
       }
 
       analyzeConstantDeferred(node);
@@ -3969,8 +3963,9 @@
       analyzeConstantDeferred(node, onAnalyzed: onAnalyzed);
     } else {
       // Not constant.
-      if (constructor == compiler.symbolConstructor &&
-          !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) {
+      if (constructor == resolution.symbolConstructor &&
+          !resolution.mirrorUsageAnalyzerTask
+              .hasMirrorUsage(enclosingElement)) {
         reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT,
             {'name': coreClasses.symbolClass.name});
       }
@@ -4001,15 +3996,15 @@
   }
 
   void analyzeConstant(Node node, {enforceConst: true}) {
-    ConstantExpression constant = compiler.resolver.constantCompiler
+    ConstantExpression constant = resolver.constantCompiler
         .compileNode(node, registry.mapping, enforceConst: enforceConst);
 
     if (constant == null) {
-      assert(invariant(node, compiler.compilationFailed));
+      assert(invariant(node, reporter.hasReportedError));
       return;
     }
 
-    ConstantValue value = compiler.constants.getConstantValue(constant);
+    ConstantValue value = resolution.constants.getConstantValue(constant);
     if (value.isMap) {
       checkConstMapKeysDontOverrideEquals(node, value);
     }
@@ -4050,13 +4045,13 @@
    * [:null:], if there is no corresponding constructor, class or library.
    */
   ConstructorResult resolveConstructor(NewExpression node) {
-    return node.accept(
-        new ConstructorResolver(compiler, this, inConstContext: node.isConst));
+    return node.accept(new ConstructorResolver(resolution, this,
+        inConstContext: node.isConst));
   }
 
   ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node,
       {bool inConstContext: false}) {
-    return node.accept(new ConstructorResolver(compiler, this,
+    return node.accept(new ConstructorResolver(resolution, this,
         inConstContext: inConstContext));
   }
 
@@ -4065,9 +4060,7 @@
     DartType type = typeResolver.resolveTypeAnnotation(this, node,
         malformedIsError: malformedIsError,
         deferredIsMalformed: deferredIsMalformed);
-    if (inCheckContext) {
-      registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
-    }
+    registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
     return type;
   }
 
@@ -4245,7 +4238,7 @@
   }
 
   ResolutionResult visitAsyncForIn(AsyncForIn node) {
-    if (!compiler.backend.supportsAsyncAwait) {
+    if (!resolution.target.supportsAsyncAwait) {
       reporter.reportErrorMessage(
           node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
     } else {
@@ -4333,7 +4326,7 @@
       }
     } else {
       // The selector may only be null if we reported an error.
-      assert(invariant(declaration, compiler.compilationFailed));
+      assert(invariant(declaration, reporter.hasReportedError));
     }
     if (loopVariable != null) {
       // loopVariable may be null if it could not be resolved.
@@ -4496,7 +4489,7 @@
         assert(invariant(node, constant != null,
             message: 'No constant computed for $node'));
 
-        ConstantValue value = compiler.constants.getConstantValue(constant);
+        ConstantValue value = resolution.constants.getConstantValue(constant);
         DartType caseType = value.getType(coreTypes); //typeOfConstant(value);
 
         if (firstCaseType == null) {
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index e52b185..7f5e927 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -7,26 +7,22 @@
 import '../common.dart';
 import '../common/backend_api.dart'
     show Backend, ForeignResolver, NativeRegistry;
-import '../common/resolution.dart'
-    show Feature, ListLiteralUse, MapLiteralUse, ResolutionImpact;
 import '../common/registry.dart' show Registry;
-import '../compiler.dart' show Compiler;
+import '../common/resolution.dart' show ResolutionImpact, Target;
 import '../constants/expressions.dart';
 import '../dart_types.dart';
 import '../diagnostics/source_span.dart';
-import '../enqueue.dart' show ResolutionEnqueuer;
 import '../elements/elements.dart';
 import '../tree/tree.dart';
-import '../util/util.dart' show Setlet;
 import '../universe/call_structure.dart' show CallStructure;
+import '../universe/feature.dart';
 import '../universe/selector.dart' show Selector;
 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
 import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilder;
 import '../util/enumset.dart' show EnumSet;
-
-import 'send_structure.dart';
-
+import '../util/util.dart' show Setlet;
 import 'members.dart' show ResolverVisitor;
+import 'send_structure.dart';
 import 'tree_elements.dart' show TreeElementMapping;
 
 class _ResolutionWorldImpact extends ResolutionImpact
@@ -160,20 +156,17 @@
 /// [Backend], [World] and [Enqueuer].
 // TODO(johnniwinther): Split this into an interface and implementation class.
 class ResolutionRegistry extends Registry {
-  final Compiler compiler;
+  final Target target;
   final TreeElementMapping mapping;
   final _ResolutionWorldImpact worldImpact;
 
-  ResolutionRegistry(Compiler compiler, TreeElementMapping mapping)
-      : this.compiler = compiler,
-        this.mapping = mapping,
+  ResolutionRegistry(this.target, TreeElementMapping mapping)
+      : this.mapping = mapping,
         this.worldImpact =
             new _ResolutionWorldImpact(mapping.analyzedElement.toString());
 
   bool get isForResolution => true;
 
-  Backend get backend => compiler.backend;
-
   String toString() => 'ResolutionRegistry for ${mapping.analyzedElement}';
 
   //////////////////////////////////////////////////////////////////////////////
@@ -364,7 +357,7 @@
 
   void registerForeignCall(Node node, Element element,
       CallStructure callStructure, ResolverVisitor visitor) {
-    var nativeData = backend.resolveForeignCall(node, element, callStructure,
+    var nativeData = target.resolveForeignCall(node, element, callStructure,
         new ForeignResolutionResolver(visitor, this));
     if (nativeData != null) {
       // Split impact from resolution result.
@@ -390,7 +383,7 @@
   }
 
   ClassElement defaultSuperclass(ClassElement element) {
-    return backend.defaultSuperclass(element);
+    return target.defaultSuperclass(element);
   }
 
   void registerInstantiation(InterfaceType type) {
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index f775190..73dd7fe 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -9,10 +9,9 @@
 import '../common.dart';
 import '../common/names.dart' show Identifiers;
 import '../common/resolution.dart'
-    show Feature, ParsingContext, Resolution, ResolutionImpact;
-import '../common/tasks.dart' show CompilerTask;
+    show ParsingContext, Resolution, ResolutionImpact, Target;
+import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../compile_time_constants.dart' show ConstantCompiler;
-import '../compiler.dart' show Compiler;
 import '../constants/expressions.dart'
     show
         ConstantExpression,
@@ -36,6 +35,8 @@
         ParameterMetadataAnnotation,
         SetterElementX,
         TypedefElementX;
+import '../enqueue.dart';
+import '../options.dart';
 import '../tokens/token.dart'
     show
         isBinaryOperator,
@@ -45,39 +46,39 @@
         isUserDefinableOperator;
 import '../tree/tree.dart';
 import '../universe/call_structure.dart' show CallStructure;
+import '../universe/feature.dart' show Feature;
 import '../universe/use.dart' show StaticUse, TypeUse;
 import '../universe/world_impact.dart' show WorldImpact;
 import '../util/util.dart' show Link, Setlet;
+import '../world.dart';
 import 'class_hierarchy.dart';
 import 'class_members.dart' show MembersCreator;
 import 'constructors.dart';
 import 'members.dart';
 import 'registry.dart';
 import 'resolution_result.dart';
-import 'scope.dart' show MutableScope;
 import 'signatures.dart';
 import 'tree_elements.dart';
 import 'typedefs.dart';
 
 class ResolverTask extends CompilerTask {
   final ConstantCompiler constantCompiler;
-  final Compiler compiler;
+  final Resolution resolution;
+  final World world;
 
-  ResolverTask(Compiler compiler, this.constantCompiler)
-      : compiler = compiler,
-        super(compiler.measurer);
+  ResolverTask(
+      this.resolution, this.constantCompiler, this.world, Measurer measurer)
+      : super(measurer);
 
   String get name => 'Resolver';
 
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  Resolution get resolution => compiler.resolution;
-
-  ParsingContext get parsingContext => compiler.parsingContext;
-
-  CoreClasses get coreClasses => compiler.coreClasses;
-
-  CoreTypes get coreTypes => compiler.coreTypes;
+  DiagnosticReporter get reporter => resolution.reporter;
+  Target get target => resolution.target;
+  CoreTypes get coreTypes => resolution.coreTypes;
+  CoreClasses get coreClasses => resolution.coreClasses;
+  ParsingContext get parsingContext => resolution.parsingContext;
+  CompilerOptions get options => resolution.options;
+  ResolutionEnqueuer get enqueuer => resolution.enqueuer;
 
   ResolutionImpact resolve(Element element) {
     return measure(() {
@@ -115,7 +116,7 @@
         return processMetadata(resolveTypedef(typdef));
       }
 
-      compiler.unimplemented(element, "resolve($element)");
+      reporter.internalError(element, "resolve($element) not implemented.");
     });
   }
 
@@ -142,15 +143,14 @@
     }
   }
 
-  static void processAsyncMarker(Compiler compiler,
+  static void processAsyncMarker(Resolution resolution,
       BaseFunctionElementX element, ResolutionRegistry registry) {
-    DiagnosticReporter reporter = compiler.reporter;
-    Resolution resolution = compiler.resolution;
-    CoreClasses coreClasses = compiler.coreClasses;
+    DiagnosticReporter reporter = resolution.reporter;
+    CoreClasses coreClasses = resolution.coreClasses;
     FunctionExpression functionExpression = element.node;
     AsyncModifier asyncModifier = functionExpression.asyncModifier;
     if (asyncModifier != null) {
-      if (!compiler.backend.supportsAsyncAwait) {
+      if (!resolution.target.supportsAsyncAwait) {
         reporter.reportErrorMessage(functionExpression.asyncModifier,
             MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
       } else {
@@ -207,7 +207,7 @@
   bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
     assert(classElement != null);
     while (classElement != null) {
-      if (compiler.backend.isNative(classElement)) return true;
+      if (target.isNative(classElement)) return true;
       classElement = classElement.superclass;
     }
     return false;
@@ -239,7 +239,7 @@
       ResolutionRegistry registry = visitor.registry;
       registry.defineFunction(tree, element);
       visitor.setupFunction(tree, element); // Modifies the scope.
-      processAsyncMarker(compiler, element, registry);
+      processAsyncMarker(resolution, element, registry);
 
       if (element.isGenerativeConstructor) {
         // Even if there is no initializer list we still have to do the
@@ -248,7 +248,7 @@
             new InitializerResolver(visitor, element, tree);
         FunctionElement redirection = resolver.resolveInitializers(
             enableInitializingFormalAccess:
-                compiler.options.enableInitializingFormalAccess);
+                options.enableInitializingFormalAccess);
         if (redirection != null) {
           resolveRedirectingConstructor(resolver, tree, element, redirection);
         }
@@ -257,8 +257,7 @@
             tree, MessageKind.FUNCTION_WITH_INITIALIZER);
       }
 
-      if (!compiler.options.analyzeSignaturesOnly ||
-          tree.isRedirectingFactory) {
+      if (!options.analyzeSignaturesOnly || tree.isRedirectingFactory) {
         // We need to analyze the redirecting factory bodies to ensure that
         // we can analyze compile-time constants.
         visitor.visit(tree.body);
@@ -274,7 +273,7 @@
       if (enclosingClass != null) {
         // TODO(johnniwinther): Find another way to obtain mixin uses.
         Iterable<MixinApplicationElement> mixinUses =
-            compiler.world.allMixinUsesOf(enclosingClass);
+            world.allMixinUsesOf(enclosingClass);
         ClassElement mixin = enclosingClass;
         for (MixinApplicationElement mixinApplication in mixinUses) {
           checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
@@ -298,7 +297,7 @@
   WorldImpact resolveMethodElement(FunctionElementX element) {
     assert(invariant(element, element.isDeclaration));
     return reporter.withCurrentElement(element, () {
-      if (compiler.enqueuer.resolution.hasBeenProcessed(element)) {
+      if (enqueuer.hasBeenProcessed(element)) {
         // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
         // should never be non-null, not even for constructors.
         assert(invariant(element, element.isConstructor,
@@ -309,7 +308,7 @@
       if (element.isSynthesized) {
         if (element.isGenerativeConstructor) {
           ResolutionRegistry registry =
-              new ResolutionRegistry(compiler, _ensureTreeElements(element));
+              new ResolutionRegistry(this.target, _ensureTreeElements(element));
           ConstructorElement constructor = element.asFunctionElement();
           ConstructorElement target = constructor.definingConstructor;
           // Ensure the signature of the synthesized element is
@@ -331,7 +330,7 @@
         element.computeType(resolution);
         FunctionElementX implementation = element;
         if (element.isExternal) {
-          implementation = compiler.backend.resolveExternalFunction(element);
+          implementation = target.resolveExternalFunction(element);
         }
         return resolveMethodElementImplementation(
             implementation, implementation.node);
@@ -346,86 +345,88 @@
   /// This method should only be used by this library (or tests of
   /// this library).
   ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) {
-    return new ResolverVisitor(compiler, element,
-        new ResolutionRegistry(compiler, _ensureTreeElements(element)),
+    return new ResolverVisitor(resolution, element,
+        new ResolutionRegistry(target, _ensureTreeElements(element)),
         useEnclosingScope: useEnclosingScope);
   }
 
   WorldImpact resolveField(FieldElementX element) {
-    VariableDefinitions tree = element.parseNode(parsingContext);
-    if (element.modifiers.isStatic && element.isTopLevel) {
-      reporter.reportErrorMessage(element.modifiers.getStatic(),
-          MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
-    }
-    ResolverVisitor visitor = visitorFor(element);
-    ResolutionRegistry registry = visitor.registry;
-    // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
-    // to the backend ast.
-    registry.defineElement(tree.definitions.nodes.head, element);
-    // TODO(johnniwinther): Share the resolved type between all variables
-    // declared in the same declaration.
-    if (tree.type != null) {
-      DartType type = visitor.resolveTypeAnnotation(tree.type);
-      assert(invariant(
-          element,
-          element.variables.type == null ||
-              // Crude check but we have no equivalence relation that
-              // equates malformed types, like matching creations of type
-              // `Foo<Unresolved>`.
-              element.variables.type.toString() == type.toString(),
-          message: "Unexpected type computed for $element. "
-              "Was ${element.variables.type}, computed $type."));
-      element.variables.type = type;
-    } else if (element.variables.type == null) {
-      // Only assign the dynamic type if the element has no known type. This
-      // happens for enum fields where the type is known but is not in the
-      // synthesized AST.
-      element.variables.type = const DynamicType();
-    }
-
-    Expression initializer = element.initializer;
-    Modifiers modifiers = element.modifiers;
-    if (initializer != null) {
-      // TODO(johnniwinther): Avoid analyzing initializers if
-      // [Compiler.analyzeSignaturesOnly] is set.
-      ResolutionResult result = visitor.visit(initializer);
-      if (result.isConstant) {
-        element.constant = result.constant;
+    return reporter.withCurrentElement(element, () {
+      VariableDefinitions tree = element.parseNode(parsingContext);
+      if (element.modifiers.isStatic && element.isTopLevel) {
+        reporter.reportErrorMessage(element.modifiers.getStatic(),
+            MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
       }
-    } else if (modifiers.isConst) {
-      reporter.reportErrorMessage(
-          element, MessageKind.CONST_WITHOUT_INITIALIZER);
-    } else if (modifiers.isFinal && !element.isInstanceMember) {
-      reporter.reportErrorMessage(
-          element, MessageKind.FINAL_WITHOUT_INITIALIZER);
-    } else {
-      // TODO(johnniwinther): Register a feature instead.
-      registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType));
-    }
+      ResolverVisitor visitor = visitorFor(element);
+      ResolutionRegistry registry = visitor.registry;
+      // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
+      // to the backend ast.
+      registry.defineElement(element.definition, element);
+      // TODO(johnniwinther): Share the resolved type between all variables
+      // declared in the same declaration.
+      if (tree.type != null) {
+        DartType type = visitor.resolveTypeAnnotation(tree.type);
+        assert(invariant(
+            element,
+            element.variables.type == null ||
+                // Crude check but we have no equivalence relation that
+                // equates malformed types, like matching creations of type
+                // `Foo<Unresolved>`.
+                element.variables.type.toString() == type.toString(),
+            message: "Unexpected type computed for $element. "
+                "Was ${element.variables.type}, computed $type."));
+        element.variables.type = type;
+      } else if (element.variables.type == null) {
+        // Only assign the dynamic type if the element has no known type. This
+        // happens for enum fields where the type is known but is not in the
+        // synthesized AST.
+        element.variables.type = const DynamicType();
+      }
 
-    if (Elements.isStaticOrTopLevelField(element)) {
-      visitor.addDeferredAction(element, () {
-        if (element.modifiers.isConst) {
-          element.constant = constantCompiler.compileConstant(element);
-        } else {
-          element.constant = constantCompiler.compileVariable(element);
-        }
-      });
+      Expression initializer = element.initializer;
+      Modifiers modifiers = element.modifiers;
       if (initializer != null) {
-        if (!element.modifiers.isConst) {
-          // TODO(johnniwinther): Determine the const-ness eagerly to avoid
-          // unnecessary registrations.
-          registry.registerFeature(Feature.LAZY_FIELD);
+        // TODO(johnniwinther): Avoid analyzing initializers if
+        // [Compiler.analyzeSignaturesOnly] is set.
+        ResolutionResult result = visitor.visit(initializer);
+        if (result.isConstant) {
+          element.constant = result.constant;
+        }
+      } else if (modifiers.isConst) {
+        reporter.reportErrorMessage(
+            element, MessageKind.CONST_WITHOUT_INITIALIZER);
+      } else if (modifiers.isFinal && !element.isInstanceMember) {
+        reporter.reportErrorMessage(
+            element, MessageKind.FINAL_WITHOUT_INITIALIZER);
+      } else {
+        // TODO(johnniwinther): Register a feature instead.
+        registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType));
+      }
+
+      if (Elements.isStaticOrTopLevelField(element)) {
+        visitor.addDeferredAction(element, () {
+          if (element.modifiers.isConst) {
+            element.constant = constantCompiler.compileConstant(element);
+          } else {
+            element.constant = constantCompiler.compileVariable(element);
+          }
+        });
+        if (initializer != null) {
+          if (!element.modifiers.isConst) {
+            // TODO(johnniwinther): Determine the const-ness eagerly to avoid
+            // unnecessary registrations.
+            registry.registerFeature(Feature.LAZY_FIELD);
+          }
         }
       }
-    }
 
-    // Perform various checks as side effect of "computing" the type.
-    element.computeType(resolution);
+      // Perform various checks as side effect of "computing" the type.
+      element.computeType(resolution);
 
-    resolution.target.resolveNativeElement(element, registry.worldImpact);
+      resolution.target.resolveNativeElement(element, registry.worldImpact);
 
-    return registry.worldImpact;
+      return registry.worldImpact;
+    });
   }
 
   DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
@@ -448,11 +449,11 @@
 
   void resolveRedirectionChain(ConstructorElement constructor, Spannable node) {
     ConstructorElement target = constructor;
-    InterfaceType targetType;
-    List<Element> seen = new List<Element>();
+    DartType targetType;
+    List<ConstructorElement> seen = new List<ConstructorElement>();
     bool isMalformed = false;
     // Follow the chain of redirections and check for cycles.
-    while (target.isRedirectingFactory || target.isPatched) {
+    while (target.isRedirectingFactory) {
       if (target.hasEffectiveTarget) {
         // We found a constructor that already has been processed.
         // TODO(johnniwinther): Should `effectiveTargetType` be part of the
@@ -466,12 +467,7 @@
         break;
       }
 
-      Element nextTarget;
-      if (target.isPatched) {
-        nextTarget = target.patch;
-      } else {
-        nextTarget = target.immediateRedirectionTarget;
-      }
+      Element nextTarget = target.immediateRedirectionTarget;
 
       if (seen.contains(nextTarget)) {
         reporter.reportErrorMessage(
@@ -503,16 +499,14 @@
     // substitution of the target type with respect to the factory type.
     while (!seen.isEmpty) {
       ConstructorElementX factory = seen.removeLast();
-      TreeElements treeElements = factory.treeElements;
-      assert(invariant(node, treeElements != null,
-          message: 'No TreeElements cached for $factory.'));
-      if (!factory.isPatched) {
-        FunctionExpression functionNode = factory.node;
-        RedirectingFactoryBody redirectionNode = functionNode.body;
-        DartType factoryType = treeElements.getType(redirectionNode);
-        if (!factoryType.isDynamic) {
-          targetType = targetType.substByContext(factoryType);
-        }
+      ResolvedAst resolvedAst = factory.resolvedAst;
+      assert(invariant(node, resolvedAst != null,
+          message: 'No ResolvedAst for $factory.'));
+      FunctionExpression functionNode = resolvedAst.node;
+      RedirectingFactoryBody redirectionNode = resolvedAst.body;
+      DartType factoryType = resolvedAst.elements.getType(redirectionNode);
+      if (!factoryType.isDynamic) {
+        targetType = targetType.substByContext(factoryType);
       }
       factory.setEffectiveTarget(target, targetType, isMalformed: isMalformed);
     }
@@ -545,7 +539,7 @@
         // TODO(ahe): Cache the node in cls.
         cls
             .parseNode(parsingContext)
-            .accept(new ClassSupertypeResolver(compiler, cls));
+            .accept(new ClassSupertypeResolver(resolution, cls));
         if (cls.supertypeLoadState != STATE_DONE) {
           cls.supertypeLoadState = STATE_DONE;
         }
@@ -610,8 +604,8 @@
   TreeElements resolveClass(BaseClassElementX element) {
     return _resolveTypeDeclaration(element, () {
       // TODO(johnniwinther): Store the mapping in the resolution enqueuer.
-      ResolutionRegistry registry =
-          new ResolutionRegistry(compiler, _ensureTreeElements(element));
+      ResolutionRegistry registry = new ResolutionRegistry(
+          resolution.target, _ensureTreeElements(element));
       resolveClassInternal(element, registry);
       return element.treeElements;
     });
@@ -637,10 +631,10 @@
                 loadSupertypes(element, tree);
 
                 ClassResolverVisitor visitor =
-                    new ClassResolverVisitor(compiler, element, registry);
+                    new ClassResolverVisitor(resolution, element, registry);
                 visitor.visit(tree);
                 element.resolutionState = STATE_DONE;
-                compiler.onClassResolved(element);
+                resolution.onClassResolved(element);
                 pendingClassesToBePostProcessed.add(element);
               }));
       if (element.isPatched) {
@@ -671,8 +665,8 @@
     for (MetadataAnnotation metadata in element.implementation.metadata) {
       metadata.ensureResolved(resolution);
       ConstantValue value =
-          compiler.constants.getConstantValue(metadata.constant);
-      if (!element.isProxy && compiler.isProxyConstant(value)) {
+          resolution.constants.getConstantValue(metadata.constant);
+      if (!element.isProxy && resolution.isProxyConstant(value)) {
         element.isProxy = true;
       }
     }
@@ -760,7 +754,7 @@
         // mixin application has been performed.
         // TODO(johnniwinther): Obtain the [TreeElements] for [member]
         // differently.
-        if (compiler.enqueuer.resolution.hasBeenProcessed(member)) {
+        if (resolution.enqueuer.hasBeenProcessed(member)) {
           if (member.resolvedAst.kind == ResolvedAstKind.PARSED) {
             checkMixinSuperUses(
                 member.resolvedAst.elements, mixinApplication, mixin);
@@ -1009,13 +1003,14 @@
     return reporter.withCurrentElement(element, () {
       FunctionExpression node = element.parseNode(parsingContext);
       return measure(() => SignatureResolver.analyze(
-          compiler,
+          resolution,
           element.enclosingElement.buildScope(),
           node.typeVariables,
           node.parameters,
           node.returnType,
           element,
-          new ResolutionRegistry(compiler, _ensureTreeElements(element)),
+          new ResolutionRegistry(
+              resolution.target, _ensureTreeElements(element)),
           defaultValuesError: defaultValuesError,
           createRealParameters: true));
     });
@@ -1023,17 +1018,17 @@
 
   WorldImpact resolveTypedef(TypedefElementX element) {
     if (element.isResolved) return const ResolutionImpact();
-    compiler.world.allTypedefs.add(element);
+    world.allTypedefs.add(element);
     return _resolveTypeDeclaration(element, () {
-      ResolutionRegistry registry =
-          new ResolutionRegistry(compiler, _ensureTreeElements(element));
+      ResolutionRegistry registry = new ResolutionRegistry(
+          resolution.target, _ensureTreeElements(element));
       return reporter.withCurrentElement(element, () {
         return measure(() {
           assert(element.resolutionState == STATE_NOT_STARTED);
           element.resolutionState = STATE_STARTED;
           Typedef node = element.parseNode(parsingContext);
           TypedefResolverVisitor visitor =
-              new TypedefResolverVisitor(compiler, element, registry);
+              new TypedefResolverVisitor(resolution, element, registry);
           visitor.visit(node);
           element.resolutionState = STATE_DONE;
           return registry.worldImpact;
diff --git a/pkg/compiler/lib/src/resolution/resolution_common.dart b/pkg/compiler/lib/src/resolution/resolution_common.dart
index 819c292..53d3c69 100644
--- a/pkg/compiler/lib/src/resolution/resolution_common.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_common.dart
@@ -6,22 +6,18 @@
 
 import '../common.dart';
 import '../common/resolution.dart' show Resolution;
-import '../compiler.dart' show Compiler;
 import '../elements/elements.dart';
 import '../tree/tree.dart';
-
 import 'registry.dart' show ResolutionRegistry;
 import 'scope.dart' show Scope;
 import 'type_resolver.dart' show TypeResolver;
 
 class CommonResolverVisitor<R> extends Visitor<R> {
-  final Compiler compiler;
+  final Resolution resolution;
 
-  CommonResolverVisitor(Compiler this.compiler);
+  CommonResolverVisitor(this.resolution);
 
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  Resolution get resolution => compiler.resolution;
+  DiagnosticReporter get reporter => resolution.reporter;
 
   R visitNode(Node node) {
     return reporter.internalError(
@@ -34,7 +30,7 @@
   R visit(Node node) => (node == null) ? null : node.accept(this);
 
   void addDeferredAction(Element element, void action()) {
-    compiler.enqueuer.resolution.addDeferredAction(element, action);
+    resolution.enqueuer.addDeferredAction(element, action);
   }
 }
 
@@ -52,9 +48,9 @@
   /// The current scope of the visitor.
   Scope get scope;
 
-  MappingVisitor(Compiler compiler, ResolutionRegistry this.registry)
-      : typeResolver = new TypeResolver(compiler),
-        super(compiler);
+  MappingVisitor(Resolution resolution, this.registry)
+      : typeResolver = new TypeResolver(resolution),
+        super(resolution);
 
   AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC;
 
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
index 6f0005e..c4fe79a 100644
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
@@ -7,11 +7,10 @@
 import '../common.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
-import '../tree/tree.dart';
 import '../elements/elements.dart';
+import '../tree/tree.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
-
 import 'operators.dart';
 import 'send_resolver.dart';
 import 'send_structure.dart';
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
index 7ef2a86..d53d4ec 100644
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -9,7 +9,6 @@
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../tree/tree.dart';
-
 import 'semantic_visitor.dart';
 import 'send_structure.dart';
 import 'tree_elements.dart';
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
index 4b6d187..52bf4dd 100644
--- a/pkg/compiler/lib/src/resolution/send_structure.dart
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -12,7 +12,6 @@
 import '../tree/tree.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
-
 import 'access_semantics.dart';
 import 'operators.dart';
 import 'semantic_visitor.dart';
@@ -1504,7 +1503,7 @@
   IndexSetIfNullStructure(this.semantics);
 
   @override
-  SendStructureKind get kind => SendStructureKind.INDEX_SET;
+  SendStructureKind get kind => SendStructureKind.INDEX_SET_IF_NULL;
 
   R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
     switch (semantics.kind) {
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
index d3f3264..eff4988 100644
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ b/pkg/compiler/lib/src/resolution/signatures.dart
@@ -5,7 +5,7 @@
 library dart2js.resolution.signatures;
 
 import '../common.dart';
-import '../compiler.dart' show Compiler;
+import '../common/resolution.dart';
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart'
@@ -40,15 +40,19 @@
   bool optionalParametersAreNamed = false;
   VariableDefinitions currentDefinitions;
 
-  SignatureResolver(Compiler compiler, FunctionTypedElement enclosingElement,
-      Scope scope, ResolutionRegistry registry,
-      {this.defaultValuesError, this.createRealParameters})
+  SignatureResolver(
+      Resolution resolution,
+      FunctionTypedElement enclosingElement,
+      Scope scope,
+      ResolutionRegistry registry,
+      {this.defaultValuesError,
+      this.createRealParameters})
       : this.scope = scope,
         this.enclosingElement = enclosingElement,
         this.resolver = new ResolverVisitor(
-            compiler, enclosingElement, registry,
+            resolution, enclosingElement, registry,
             scope: scope),
-        super(compiler, registry);
+        super(resolution, registry);
 
   bool get defaultValuesAllowed => defaultValuesError == null;
 
@@ -93,7 +97,7 @@
     FormalElementX element = definition.accept(this);
     if (currentDefinitions.metadata != null) {
       element.metadataInternal =
-          compiler.resolver.resolveMetadata(element, node);
+          resolution.resolver.resolveMetadata(element, node);
     }
     currentDefinitions = null;
     return element;
@@ -111,7 +115,7 @@
       [VariableElement fieldElement]) {
     void computeFunctionType(FunctionExpression functionExpression) {
       FunctionSignature functionSignature = SignatureResolver.analyze(
-          compiler,
+          resolution,
           scope,
           functionExpression.typeVariables,
           functionExpression.parameters,
@@ -290,7 +294,7 @@
    * the parameters will only implement [FormalElement].
    */
   static FunctionSignature analyze(
-      Compiler compiler,
+      Resolution resolution,
       Scope scope,
       NodeList typeVariables,
       NodeList formalParameters,
@@ -300,7 +304,7 @@
       {MessageKind defaultValuesError,
       bool createRealParameters: false,
       bool isFunctionExpression: false}) {
-    DiagnosticReporter reporter = compiler.reporter;
+    DiagnosticReporter reporter = resolution.reporter;
 
     List<DartType> createTypeVariables(NodeList typeVariableNodes) {
       if (typeVariableNodes == null) return const <DartType>[];
@@ -329,7 +333,7 @@
     List<DartType> typeVariableTypes = createTypeVariables(typeVariables);
     scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes);
     SignatureResolver visitor = new SignatureResolver(
-        compiler, element, scope, registry,
+        resolution, element, scope, registry,
         defaultValuesError: defaultValuesError,
         createRealParameters: createRealParameters);
     List<Element> parameters = const <Element>[];
@@ -341,7 +345,7 @@
           // reported. In the case of parse errors, it is possible that there
           // are formal parameters, but something else in the method failed to
           // parse. So we suppress the message about missing formals.
-          assert(invariant(element, compiler.compilationFailed));
+          assert(invariant(element, reporter.hasReportedError));
         } else {
           reporter.reportErrorMessage(element, MessageKind.MISSING_FORMALS);
         }
@@ -366,9 +370,7 @@
       returnType = element.enclosingClass.thisType;
       // Because there is no type annotation for the return type of
       // this element, we explicitly add one.
-      if (compiler.options.enableTypeAssertions) {
-        registry.registerTypeUse(new TypeUse.checkedModeCheck(returnType));
-      }
+      registry.registerTypeUse(new TypeUse.checkedModeCheck(returnType));
     } else {
       AsyncMarker asyncMarker = AsyncMarker.SYNC;
       if (isFunctionExpression) {
@@ -382,13 +384,13 @@
           returnType = visitor.resolveReturnType(returnNode);
           break;
         case AsyncMarker.SYNC_STAR:
-          returnType = compiler.coreTypes.iterableType();
+          returnType = resolution.coreTypes.iterableType();
           break;
         case AsyncMarker.ASYNC:
-          returnType = compiler.coreTypes.futureType();
+          returnType = resolution.coreTypes.futureType();
           break;
         case AsyncMarker.ASYNC_STAR:
-          returnType = compiler.coreTypes.streamType();
+          returnType = resolution.coreTypes.streamType();
           break;
       }
     }
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
index 1e52fca..bae0857 100644
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -9,11 +9,10 @@
 import '../dart_types.dart';
 import '../diagnostics/source_span.dart';
 import '../elements/elements.dart';
-import '../types/types.dart' show TypeMask;
 import '../tree/tree.dart';
-import '../util/util.dart';
+import '../types/types.dart' show TypeMask;
 import '../universe/selector.dart' show Selector;
-
+import '../util/util.dart';
 import 'secret_tree_element.dart' show getTreeElement, setTreeElement;
 import 'send_structure.dart';
 
@@ -139,7 +138,7 @@
   /// Map from nodes to native data.
   Map<Node, dynamic> _nativeData;
 
-  final int hashCode = ++_hashCodeCounter;
+  final int hashCode = _hashCodeCounter = (_hashCodeCounter + 1).toUnsigned(30);
   static int _hashCodeCounter = 0;
 
   TreeElementMapping(this.analyzedElement);
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
index 9837a09..c1fb6cc 100644
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/type_resolver.dart
@@ -5,9 +5,7 @@
 library dart2js.resolution.types;
 
 import '../common.dart';
-import '../common/resolution.dart' show Feature, Resolution;
-import '../compiler.dart' show Compiler;
-import '../dart_backend/dart_backend.dart' show DartBackend;
+import '../common/resolution.dart' show Resolution;
 import '../dart_types.dart';
 import '../elements/elements.dart'
     show
@@ -18,25 +16,25 @@
         ErroneousElement,
         PrefixElement,
         TypedefElement,
-        TypeDeclarationElement,
         TypeVariableElement;
 import '../elements/modelx.dart' show ErroneousElementX;
+import '../resolution/resolution.dart';
 import '../tree/tree.dart';
+import '../universe/feature.dart' show Feature;
 import '../util/util.dart' show Link;
-
 import 'members.dart' show lookupInScope;
 import 'registry.dart' show ResolutionRegistry;
 import 'resolution_common.dart' show MappingVisitor;
 import 'scope.dart' show Scope;
 
 class TypeResolver {
-  final Compiler compiler;
+  final Resolution resolution;
 
-  TypeResolver(this.compiler);
+  TypeResolver(this.resolution);
 
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  Resolution get resolution => compiler.resolution;
+  ResolverTask get resolver => resolution.resolver;
+  DiagnosticReporter get reporter => resolution.reporter;
+  Types get types => resolution.types;
 
   /// Tries to resolve the type name as an element.
   Element resolveTypeName(
@@ -50,12 +48,7 @@
         // The receiver is a prefix. Lookup in the imported members.
         PrefixElement prefix = prefixElement;
         element = prefix.lookupLocalMember(typeName.source);
-        // TODO(17260, sigurdm): The test for DartBackend is there because
-        // dart2dart outputs malformed types with prefix.
-        if (element != null &&
-            prefix.isDeferred &&
-            deferredIsMalformed &&
-            compiler.backend is! DartBackend) {
+        if (element != null && prefix.isDeferred && deferredIsMalformed) {
           element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION,
               {'node': typeName}, element.name, element);
         }
@@ -167,7 +160,7 @@
         ClassElement cls = element;
         // TODO(johnniwinther): [ensureClassWillBeResolvedInternal] should imply
         // [computeType].
-        compiler.resolver.ensureClassWillBeResolvedInternal(cls);
+        resolver.ensureClassWillBeResolvedInternal(cls);
         cls.computeType(resolution);
         List<DartType> arguments = <DartType>[];
         bool hasTypeArgumentMismatch =
@@ -240,7 +233,7 @@
   void checkTypeVariableBounds(TypeAnnotation node, GenericType type) {
     void checkTypeVariableBound(_, DartType typeArgument,
         TypeVariableType typeVariable, DartType bound) {
-      if (!compiler.types.isSubtype(typeArgument, bound)) {
+      if (!types.isSubtype(typeArgument, bound)) {
         reporter.reportWarningMessage(
             node, MessageKind.INVALID_TYPE_VARIABLE_BOUND, {
           'typeVariable': typeVariable,
@@ -250,9 +243,8 @@
         });
       }
     }
-    ;
 
-    compiler.types.checkTypeVariableBounds(type, checkTypeVariableBound);
+    types.checkTypeVariableBounds(type, checkTypeVariableBound);
   }
 
   /**
diff --git a/pkg/compiler/lib/src/resolution/typedefs.dart b/pkg/compiler/lib/src/resolution/typedefs.dart
index cee72df..1c52c93 100644
--- a/pkg/compiler/lib/src/resolution/typedefs.dart
+++ b/pkg/compiler/lib/src/resolution/typedefs.dart
@@ -5,14 +5,13 @@
 library dart2js.resolution.typedefs;
 
 import '../common.dart';
-import '../compiler.dart' show Compiler;
+import '../common/resolution.dart';
 import '../dart_types.dart';
 import '../elements/elements.dart'
     show FunctionSignature, TypedefElement, TypeVariableElement;
 import '../elements/modelx.dart' show ErroneousElementX, TypedefElementX;
 import '../tree/tree.dart';
 import '../util/util.dart' show Link;
-
 import 'class_hierarchy.dart' show TypeDefinitionVisitor;
 import 'registry.dart' show ResolutionRegistry;
 import 'scope.dart' show MethodScope, TypeDeclarationScope;
@@ -21,9 +20,9 @@
 class TypedefResolverVisitor extends TypeDefinitionVisitor {
   TypedefElementX get element => enclosingElement;
 
-  TypedefResolverVisitor(Compiler compiler, TypedefElement typedefElement,
+  TypedefResolverVisitor(Resolution resolution, TypedefElement typedefElement,
       ResolutionRegistry registry)
-      : super(compiler, typedefElement, registry);
+      : super(resolution, typedefElement, registry);
 
   visitTypedef(Typedef node) {
     element.computeType(resolution);
@@ -31,7 +30,7 @@
     resolveTypeVariableBounds(node.typeParameters);
 
     FunctionSignature signature = SignatureResolver.analyze(
-        compiler,
+        resolution,
         scope,
         null /* typeVariables */,
         node.formals,
@@ -49,6 +48,7 @@
     void checkCyclicReference() {
       element.checkCyclicReference(resolution);
     }
+
     addDeferredAction(element, checkCyclicReference);
   }
 }
@@ -67,7 +67,7 @@
   Link<TypeVariableElement> seenTypeVariables =
       const Link<TypeVariableElement>();
 
-  TypedefCyclicVisitor(this.reporter, TypedefElement this.element);
+  TypedefCyclicVisitor(this.reporter, this.element);
 
   visitType(DartType type, _) {
     // Do nothing.
@@ -115,7 +115,9 @@
       seenTypedefs = seenTypedefs.prepend(typedefElement);
       seenTypedefsCount++;
       type.visitChildren(this, null);
-      typedefElement.aliasCache.accept(this, null);
+      if (!typedefElement.isMalformed) {
+        typedefElement.aliasCache.accept(this, null);
+      }
       seenTypedefs = seenTypedefs.tail;
       seenTypedefsCount--;
     }
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
index c5609a8..77a8f4e 100644
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ b/pkg/compiler/lib/src/resolution/variables.dart
@@ -5,12 +5,11 @@
 library dart2js.resolution.variables;
 
 import '../common.dart';
-import '../compiler.dart' show Compiler;
+import '../common/resolution.dart';
 import '../elements/modelx.dart' show LocalVariableElementX, VariableList;
 import '../tree/tree.dart';
 import '../universe/use.dart' show TypeUse;
 import '../util/util.dart' show Link;
-
 import 'members.dart' show ResolverVisitor;
 import 'registry.dart' show ResolutionRegistry;
 import 'resolution_common.dart' show CommonResolverVisitor;
@@ -22,8 +21,8 @@
   VariableList variables;
 
   VariableDefinitionsVisitor(
-      Compiler compiler, this.definitions, this.resolver, this.variables)
-      : super(compiler) {}
+      Resolution resolution, this.definitions, this.resolver, this.variables)
+      : super(resolution);
 
   ResolutionRegistry get registry => resolver.registry;
 
@@ -45,7 +44,7 @@
     // The variable is initialized to null.
     // TODO(johnniwinther): Register a feature instead.
     registry.registerTypeUse(
-        new TypeUse.instantiation(compiler.coreTypes.nullType));
+        new TypeUse.instantiation(resolution.coreTypes.nullType));
     if (definitions.modifiers.isConst) {
       if (resolver.inLoopVariable) {
         reporter.reportErrorMessage(node, MessageKind.CONST_LOOP_VARIABLE);
@@ -68,9 +67,9 @@
       resolver.defineLocalVariable(link.head, element);
       resolver.addToScope(element);
       if (definitions.modifiers.isConst) {
-        compiler.enqueuer.resolution.addDeferredAction(element, () {
+        addDeferredAction(element, () {
           element.constant =
-              compiler.resolver.constantCompiler.compileConstant(element);
+              resolution.resolver.constantCompiler.compileConstant(element);
         });
       }
     }
diff --git a/pkg/compiler/lib/src/scanner/array_based_scanner.dart b/pkg/compiler/lib/src/scanner/array_based_scanner.dart
index 2496daa..edd22ae 100644
--- a/pkg/compiler/lib/src/scanner/array_based_scanner.dart
+++ b/pkg/compiler/lib/src/scanner/array_based_scanner.dart
@@ -15,7 +15,6 @@
     show LT_TOKEN, OPEN_CURLY_BRACKET_TOKEN, STRING_INTERPOLATION_TOKEN;
 import '../util/characters.dart' show $LF, $STX;
 import '../util/util.dart' show Link;
-
 import 'scanner.dart' show AbstractScanner;
 
 abstract class ArrayBasedScanner extends AbstractScanner {
diff --git a/pkg/compiler/lib/src/scanner/scanner.dart b/pkg/compiler/lib/src/scanner/scanner.dart
index 30d5caf..f069861 100644
--- a/pkg/compiler/lib/src/scanner/scanner.dart
+++ b/pkg/compiler/lib/src/scanner/scanner.dart
@@ -11,7 +11,6 @@
 import '../tokens/token.dart';
 import '../tokens/token_constants.dart';
 import '../util/characters.dart';
-
 import 'string_scanner.dart' show StringScanner;
 import 'utf8_bytes_scanner.dart' show Utf8BytesScanner;
 
@@ -685,7 +684,8 @@
   int tokenizeFractionPart(int next, int start) {
     bool done = false;
     bool hasDigit = false;
-    LOOP: while (!done) {
+    LOOP:
+    while (!done) {
       if ($0 <= next && next <= $9) {
         hasDigit = true;
       } else if (identical($e, next) || identical($E, next)) {
@@ -1003,7 +1003,8 @@
     bool asciiOnlyLine = true;
     int unicodeStart = start;
     int next = advance(); // Advance past the (last) quote (of three).
-    outer: while (!identical(next, $EOF)) {
+    outer:
+    while (!identical(next, $EOF)) {
       while (!identical(next, quoteChar)) {
         if (identical(next, $LF)) {
           if (!asciiOnlyLine) {
diff --git a/pkg/compiler/lib/src/scanner/scanner_task.dart b/pkg/compiler/lib/src/scanner/scanner_task.dart
index 6b25efd..1977248 100644
--- a/pkg/compiler/lib/src/scanner/scanner_task.dart
+++ b/pkg/compiler/lib/src/scanner/scanner_task.dart
@@ -7,12 +7,11 @@
 import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
 import '../elements/elements.dart' show CompilationUnitElement, LibraryElement;
-import '../script.dart' show Script;
 import '../parser/diet_parser_task.dart' show DietParserTask;
+import '../script.dart' show Script;
 import '../tokens/token.dart' show Token;
 import '../tokens/token_constants.dart' as Tokens show COMMENT_TOKEN, EOF_TOKEN;
 import '../tokens/token_map.dart' show TokenMap;
-
 import 'scanner.dart' show Scanner;
 import 'string_scanner.dart' show StringScanner;
 
diff --git a/pkg/compiler/lib/src/scanner/string_scanner.dart b/pkg/compiler/lib/src/scanner/string_scanner.dart
index 5c6604e..7e1f995d 100644
--- a/pkg/compiler/lib/src/scanner/string_scanner.dart
+++ b/pkg/compiler/lib/src/scanner/string_scanner.dart
@@ -7,7 +7,6 @@
 import '../io/source_file.dart' show SourceFile;
 import '../tokens/precedence.dart' show PrecedenceInfo;
 import '../tokens/token.dart' show StringToken, Token;
-
 import 'array_based_scanner.dart' show ArrayBasedScanner;
 
 /**
diff --git a/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart b/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
index c4b87ed..ea46e35 100644
--- a/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
+++ b/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
@@ -9,7 +9,6 @@
 import '../io/source_file.dart' show SourceFile;
 import '../tokens/precedence.dart' show PrecedenceInfo;
 import '../tokens/token.dart' show StringToken, Token;
-
 import 'array_based_scanner.dart' show ArrayBasedScanner;
 
 /**
diff --git a/pkg/compiler/lib/src/serialization/constant_serialization.dart b/pkg/compiler/lib/src/serialization/constant_serialization.dart
index ae3040a..fae3d2f 100644
--- a/pkg/compiler/lib/src/serialization/constant_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/constant_serialization.dart
@@ -10,8 +10,8 @@
 import '../elements/elements.dart' show FieldElement;
 import '../resolution/operators.dart';
 import '../universe/call_structure.dart' show CallStructure;
-import 'serialization.dart';
 import 'keys.dart';
+import 'serialization.dart';
 
 /// Visitor that serializes a [ConstantExpression] by encoding it into an
 /// [ObjectEncoder].
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index d51c67a..3b14778 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -5,14 +5,17 @@
 library dart2js.serialization.elements;
 
 import '../common.dart';
-import '../common/names.dart';
 import '../constants/constructors.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
 import '../diagnostics/messages.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart'
-    show DeferredLoaderGetterElementX, ErroneousElementX;
+    show
+        DeferredLoaderGetterElementX,
+        ErroneousElementX,
+        WarnOnUseElementX,
+        WrappedMessage;
 import 'constant_serialization.dart';
 import 'keys.dart';
 import 'modelz.dart';
@@ -55,6 +58,7 @@
   PREFIX,
   DEFERRED_LOAD_LIBRARY,
   LOCAL_VARIABLE,
+  WARN_ON_USE,
   EXTERNAL_LIBRARY,
   EXTERNAL_LIBRARY_MEMBER,
   EXTERNAL_CLASS_MEMBER,
@@ -84,6 +88,7 @@
   const ImportSerializer(),
   const ExportSerializer(),
   const LocalVariableSerializer(),
+  const WarnOnUseSerializer(),
 ];
 
 /// Interface for a function that can serialize a set of element kinds.
@@ -216,12 +221,7 @@
     encoder.setElement(Key.ENCLOSING, element.enclosingElement);
     encoder.setString(Key.NAME, element.name);
     encoder.setEnum(Key.MESSAGE_KIND, element.messageKind);
-    if (element.messageArguments.isNotEmpty) {
-      MapEncoder mapEncoder = encoder.createMap(Key.ARGUMENTS);
-      element.messageArguments.forEach((String key, var value) {
-        mapEncoder.setString(key, Message.convertToString(value));
-      });
-    }
+    serializeMessageArguments(encoder, Key.ARGUMENTS, element.messageArguments);
   }
 }
 
@@ -292,8 +292,52 @@
     encoder.setElements(Key.IMPORTS, getImports(element));
     encoder.setElements(Key.EXPORTS, element.exports);
 
-    encoder.setElements(Key.IMPORT_SCOPE, getImportedElements(element));
+    List<Element> importedElements = getImportedElements(element);
+    encoder.setElements(Key.IMPORT_SCOPE, importedElements);
     encoder.setElements(Key.EXPORT_SCOPE, getExportedElements(element));
+
+    Map<Element, Iterable<ImportElement>> importsForMap =
+        <Element, Iterable<ImportElement>>{};
+
+    /// Map imports for [importedElement] in importsForMap.
+    ///
+    /// Imports are mapped to [AbstractFieldElement] which are not serialized
+    /// so we use getter (or setter if there is no getter) as the key.
+    void addImportsForElement(Element importedElement) {
+      Element key = importedElement;
+      if (importedElement.isDeferredLoaderGetter) {
+        // Use [importedElement].
+      } else if (importedElement.isGetter) {
+        GetterElement getter = importedElement;
+        importedElement = getter.abstractField;
+      } else if (importedElement.isSetter) {
+        SetterElement setter = importedElement;
+        if (setter.getter != null) {
+          return;
+        }
+        importedElement = setter.abstractField;
+      }
+      importsForMap.putIfAbsent(
+          key, () => element.getImportsFor(importedElement));
+    }
+
+    for (ImportElement import in getImports(element)) {
+      if (import.prefix != null) {
+        Set<Element> importedElements = new Set<Element>();
+        import.prefix.forEachLocalMember(
+            SerializerUtil.flattenElements(importedElements));
+        importedElements.forEach(addImportsForElement);
+      }
+    }
+    importedElements.forEach(addImportsForElement);
+
+    ListEncoder importsForEncoder = encoder.createList(Key.IMPORTS_FOR);
+    importsForMap
+        .forEach((Element importedElement, Iterable<ImportElement> imports) {
+      ObjectEncoder objectEncoder = importsForEncoder.createObject();
+      objectEncoder.setElement(Key.ELEMENT, importedElement);
+      objectEncoder.setElements(Key.IMPORTS, imports);
+    });
   }
 }
 
@@ -454,6 +498,8 @@
                 .computeEffectiveTargetType(element.enclosingClass.thisType));
         encoder.setElement(Key.IMMEDIATE_REDIRECTION_TARGET,
             element.immediateRedirectionTarget);
+        encoder.setBool(Key.EFFECTIVE_TARGET_IS_MALFORMED,
+            element.isEffectiveTargetMalformed);
         if (element.redirectionDeferredPrefix != null) {
           encoder.setElement(Key.PREFIX, element.redirectionDeferredPrefix);
         }
@@ -544,6 +590,8 @@
     if (element.isFunction) {
       encoder.setBool(Key.IS_OPERATOR, element.isOperator);
       encoder.setEnum(Key.ASYNC_MARKER, element.asyncMarker);
+    } else if (element.isGetter) {
+      encoder.setEnum(Key.ASYNC_MARKER, element.asyncMarker);
     }
     SerializerUtil.serializeParentRelation(element, encoder);
     encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
@@ -554,6 +602,7 @@
       encoder.setElement(
           Key.EXECUTABLE_CONTEXT, localFunction.executableContext);
     }
+    encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
   }
 }
 
@@ -605,7 +654,7 @@
   const ParameterSerializer();
 
   SerializedElementKind getSerializedKind(Element element) {
-    if (element.isParameter) {
+    if (element.isRegularParameter) {
       return SerializedElementKind.PARAMETER;
     } else if (element.isInitializingFormal) {
       return SerializedElementKind.INITIALIZING_FORMAL;
@@ -721,6 +770,9 @@
     encoder.setElement(Key.LIBRARY, element.library);
     encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
     encoder.setBool(Key.IS_DEFERRED, element.isDeferred);
+    Set<Element> members = new Set<Element>();
+    element.forEachLocalMember(SerializerUtil.flattenElements(members));
+    encoder.setElements(Key.MEMBERS, members);
     if (element.isDeferred) {
       encoder.setElement(Key.IMPORT, element.deferredImport);
       encoder.setElement(Key.GETTER, element.loadLibrary);
@@ -744,6 +796,25 @@
   }
 }
 
+class WarnOnUseSerializer implements ElementSerializer {
+  const WarnOnUseSerializer();
+
+  SerializedElementKind getSerializedKind(Element element) {
+    if (element.isWarnOnUse) {
+      return SerializedElementKind.WARN_ON_USE;
+    }
+    return null;
+  }
+
+  void serialize(WarnOnUseElementX element, ObjectEncoder encoder,
+      SerializedElementKind kind) {
+    encoder.setElement(Key.ENCLOSING, element.enclosingElement);
+    encoder.setElement(Key.ELEMENT, element.wrappedElement);
+    serializeWrappedMessage(encoder, Key.WARNING, element.warning);
+    serializeWrappedMessage(encoder, Key.INFO, element.info);
+  }
+}
+
 /// Utility class for deserializing [Element]s.
 ///
 /// This is used by the [Deserializer].
@@ -762,13 +833,8 @@
         String name = decoder.getString(Key.NAME);
         MessageKind messageKind =
             decoder.getEnum(Key.MESSAGE_KIND, MessageKind.values);
-        Map<String, String> arguments = <String, String>{};
-        MapDecoder mapDecoder = decoder.getMap(Key.ARGUMENTS, isOptional: true);
-        if (mapDecoder != null) {
-          mapDecoder.forEachKey((String key) {
-            arguments[key] = mapDecoder.getString(key);
-          });
-        }
+        Map<String, String> arguments =
+            deserializeMessageArguments(decoder, Key.ARGUMENTS);
         return new ErroneousElementX(messageKind, arguments, name, enclosing);
       case SerializedElementKind.LIBRARY:
         return new LibraryElementZ(decoder);
@@ -839,6 +905,13 @@
         return new DeferredLoaderGetterElementX(decoder.getElement(Key.PREFIX));
       case SerializedElementKind.LOCAL_VARIABLE:
         return new LocalVariableElementZ(decoder);
+      case SerializedElementKind.WARN_ON_USE:
+        Element enclosing = decoder.getElement(Key.ENCLOSING);
+        Element element = decoder.getElement(Key.ELEMENT);
+        WrappedMessage warning =
+            deserializeWrappedMessage(decoder, Key.WARNING);
+        WrappedMessage info = deserializeWrappedMessage(decoder, Key.INFO);
+        return new WarnOnUseElementX(warning, info, enclosing, element);
       case SerializedElementKind.EXTERNAL_LIBRARY:
       case SerializedElementKind.EXTERNAL_LIBRARY_MEMBER:
       case SerializedElementKind.EXTERNAL_CLASS_MEMBER:
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index a7c08b5..4456623 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -7,9 +7,9 @@
 library dart2js.serialization.equivalence;
 
 import '../closure.dart';
-import '../common.dart';
 import '../common/resolution.dart';
 import '../constants/expressions.dart';
+import '../constants/values.dart';
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/visitor.dart';
@@ -22,6 +22,7 @@
 import '../tokens/token.dart';
 import '../tree/nodes.dart';
 import '../universe/selector.dart';
+import '../universe/feature.dart';
 import '../universe/use.dart';
 import '../util/util.dart';
 import 'resolved_ast_serialization.dart';
@@ -63,6 +64,31 @@
   return remaining.isEmpty;
 }
 
+/// Returns `true` if the content of [map1] and [map2] is equivalent using
+/// [keyEquivalence] and [valueEquivalence] to determine key/value equivalence.
+bool areMapsEquivalent(Map map1, Map map2,
+    [bool keyEquivalence(a, b) = equality,
+    bool valueEquivalence(a, b) = equality]) {
+  Set remaining = map2.keys.toSet();
+  for (var key1 in map1.keys) {
+    bool found = false;
+    for (var key2 in map2.keys) {
+      if (keyEquivalence(key2, key2)) {
+        found = true;
+        remaining.remove(key2);
+        if (!valueEquivalence(map1[key1], map2[key2])) {
+          return false;
+        }
+        break;
+      }
+    }
+    if (!found) {
+      return false;
+    }
+  }
+  return remaining.isEmpty;
+}
+
 /// Returns `true` if elements [a] and [b] are equivalent.
 bool areElementsEquivalent(Element a, Element b) {
   if (identical(a, b)) return true;
@@ -77,13 +103,20 @@
   return const TypeEquivalence().visit(a, b);
 }
 
-/// Returns `true` if constants [a] and [b] are equivalent.
+/// Returns `true` if constants [exp1] and [exp2] are equivalent.
 bool areConstantsEquivalent(ConstantExpression exp1, ConstantExpression exp2) {
   if (identical(exp1, exp2)) return true;
   if (exp1 == null || exp2 == null) return false;
   return const ConstantEquivalence().visit(exp1, exp2);
 }
 
+/// Returns `true` if constant values [value1] and [value2] are equivalent.
+bool areConstantValuesEquivalent(ConstantValue value1, ConstantValue value2) {
+  if (identical(value1, value2)) return true;
+  if (value1 == null || value2 == null) return false;
+  return const ConstantValueEquivalence().visit(value1, value2);
+}
+
 /// Returns `true` if the lists of elements, [a] and [b], are equivalent.
 bool areElementListsEquivalent(List<Element> a, List<Element> b) {
   return areListsEquivalent(a, b, areElementsEquivalent);
@@ -100,6 +133,12 @@
   return areListsEquivalent(a, b, areConstantsEquivalent);
 }
 
+/// Returns `true` if the lists of constant values, [a] and [b], are equivalent.
+bool areConstantValueListsEquivalent(
+    List<ConstantValue> a, List<ConstantValue> b) {
+  return areListsEquivalent(a, b, areConstantValuesEquivalent);
+}
+
 /// Returns `true` if the selectors [a] and [b] are equivalent.
 bool areSelectorsEquivalent(Selector a, Selector b) {
   if (identical(a, b)) return true;
@@ -242,7 +281,8 @@
       return areElementsEquivalent(ad.prefix, bd.prefix) &&
           areSendStructuresEquivalent(ad.sendStructure, bd.sendStructure);
 
-    semantics: case SendStructureKind.GET:
+    semantics:
+    case SendStructureKind.GET:
     case SendStructureKind.SET:
     case SendStructureKind.INDEX:
     case SendStructureKind.INDEX_SET:
@@ -307,6 +347,12 @@
     return areSetsEquivalent(set1, set2, elementEquivalence);
   }
 
+  bool testMaps(var object1, var object2, String property, Map map1, Map map2,
+      [bool keyEquivalence(a, b) = equality,
+      bool valueEquivalence(a, b) = equality]) {
+    return areMapsEquivalent(map1, map2, keyEquivalence, valueEquivalence);
+  }
+
   bool testElements(Object object1, Object object2, String property,
       Element element1, Element element2) {
     return areElementsEquivalent(element1, element2);
@@ -322,6 +368,11 @@
     return areConstantsEquivalent(exp1, exp2);
   }
 
+  bool testConstantValues(Object object1, Object object2, String property,
+      ConstantValue value1, ConstantValue value2) {
+    return areConstantValuesEquivalent(value1, value2);
+  }
+
   bool testTypeLists(Object object1, Object object2, String property,
       List<DartType> list1, List<DartType> list2) {
     return areTypeListsEquivalent(list1, list2);
@@ -332,6 +383,11 @@
     return areConstantListsEquivalent(list1, list2);
   }
 
+  bool testConstantValueLists(Object object1, Object object2, String property,
+      List<ConstantValue> list1, List<ConstantValue> list2) {
+    return areConstantValueListsEquivalent(list1, list2);
+  }
+
   bool testNodes(
       Object object1, Object object2, String property, Node node1, Node node2) {
     return areNodesEquivalent(node1, node2);
@@ -516,6 +572,20 @@
             element1, element2, 'name', element1.name, element2.name) &&
         visit(element1.library, element2.library);
   }
+
+  @override
+  bool visitErroneousElement(
+      ErroneousElement element1, ErroneousElement element2) {
+    return strategy.test(element1, element2, 'messageKind',
+        element1.messageKind, element2.messageKind);
+  }
+
+  @override
+  bool visitWarnOnUseElement(
+      WarnOnUseElement element1, WarnOnUseElement element2) {
+    return strategy.testElements(element1, element2, 'wrappedElement',
+        element1.wrappedElement, element2.wrappedElement);
+  }
 }
 
 /// Visitor that checks for equivalence of [DartType]s.
@@ -562,7 +632,9 @@
   @override
   bool visitTypeVariableType(TypeVariableType type, TypeVariableType other) {
     return strategy.testElements(
-        type, other, 'element', type.element, other.element);
+            type, other, 'element', type.element, other.element) &&
+        strategy.test(type, other, 'is MethodTypeVariableType',
+            type is MethodTypeVariableType, other is MethodTypeVariableType);
   }
 
   @override
@@ -764,9 +836,130 @@
   @override
   bool visitDeferred(
       DeferredConstantExpression exp1, DeferredConstantExpression exp2) {
-    // TODO(johnniwinther): Implement this.
+    return strategy.testElements(
+            exp1, exp2, 'prefix', exp1.prefix, exp2.prefix) &&
+        strategy.testConstants(
+            exp1, exp2, 'expression', exp1.expression, exp2.expression);
+  }
+}
+
+/// Visitor that checks for structural equivalence of [ConstantValue]s.
+class ConstantValueEquivalence
+    implements ConstantValueVisitor<bool, ConstantValue> {
+  final TestStrategy strategy;
+
+  const ConstantValueEquivalence([this.strategy = const TestStrategy()]);
+
+  bool visit(ConstantValue value1, ConstantValue value2) {
+    if (identical(value1, value2)) return true;
+    return strategy.test(value1, value2, 'kind', value1.kind, value2.kind) &&
+        value1.accept(this, value2);
+  }
+
+  @override
+  bool visitConstructed(
+      ConstructedConstantValue value1, ConstructedConstantValue value2) {
+    return strategy.testTypes(
+            value1, value2, 'type', value1.type, value2.type) &&
+        strategy.testMaps(
+            value1,
+            value2,
+            'fields',
+            value1.fields,
+            value2.fields,
+            areElementsEquivalent,
+            (a, b) => strategy.testConstantValues(
+                value1, value2, 'fields.values', a, b));
+  }
+
+  @override
+  bool visitFunction(
+      FunctionConstantValue value1, FunctionConstantValue value2) {
+    return strategy.testElements(
+        value1, value2, 'element', value1.element, value2.element);
+  }
+
+  @override
+  bool visitList(ListConstantValue value1, ListConstantValue value2) {
+    return strategy.testTypes(
+            value1, value2, 'type', value1.type, value2.type) &&
+        strategy.testConstantValueLists(
+            value1, value2, 'entries', value1.entries, value2.entries);
+  }
+
+  @override
+  bool visitMap(MapConstantValue value1, MapConstantValue value2) {
+    return strategy.testTypes(
+            value1, value2, 'type', value1.type, value2.type) &&
+        strategy.testConstantValueLists(
+            value1, value2, 'keys', value1.keys, value2.keys) &&
+        strategy.testConstantValueLists(
+            value1, value2, 'values', value1.values, value2.values);
+  }
+
+  @override
+  bool visitType(TypeConstantValue value1, TypeConstantValue value2) {
+    return strategy.testTypes(value1, value2, 'type', value1.type, value2.type);
+  }
+
+  @override
+  bool visitBool(BoolConstantValue value1, BoolConstantValue value2) {
+    return strategy.test(value1, value2, 'primitiveValue',
+        value1.primitiveValue, value2.primitiveValue);
+  }
+
+  @override
+  bool visitDouble(DoubleConstantValue value1, DoubleConstantValue value2) {
+    return strategy.test(value1, value2, 'primitiveValue',
+        value1.primitiveValue, value2.primitiveValue);
+  }
+
+  @override
+  bool visitInt(IntConstantValue value1, IntConstantValue value2) {
+    return strategy.test(value1, value2, 'primitiveValue',
+        value1.primitiveValue, value2.primitiveValue);
+  }
+
+  @override
+  bool visitNull(NullConstantValue value1, NullConstantValue value2) {
     return true;
   }
+
+  @override
+  bool visitString(StringConstantValue value1, StringConstantValue value2) {
+    return strategy.test(value1, value2, 'primitiveValue',
+        value1.primitiveValue, value2.primitiveValue);
+  }
+
+  @override
+  bool visitDeferred(
+      DeferredConstantValue value1, DeferredConstantValue value2) {
+    return strategy.testElements(
+            value1, value2, 'prefix', value1.prefix, value2.prefix) &&
+        strategy.testConstantValues(
+            value1, value2, 'referenced', value1.referenced, value2.referenced);
+  }
+
+  @override
+  bool visitNonConstant(NonConstantValue value1, NonConstantValue value2) {
+    return true;
+  }
+
+  @override
+  bool visitSynthetic(
+      SyntheticConstantValue value1, SyntheticConstantValue value2) {
+    return strategy.test(
+            value1, value2, 'payload', value1.payload, value2.payload) &&
+        strategy.test(
+            value1, value2, 'valueKind', value1.valueKind, value2.valueKind);
+  }
+
+  @override
+  bool visitInterceptor(
+      InterceptorConstantValue value1, InterceptorConstantValue value2) {
+    return strategy.testTypes(value1, value2, 'dispatchedType',
+        value1.dispatchedType, value2.dispatchedType);
+  }
 }
 
 /// Tests the equivalence of [impact1] and [impact2] using [strategy].
diff --git a/pkg/compiler/lib/src/serialization/impact_serialization.dart b/pkg/compiler/lib/src/serialization/impact_serialization.dart
index b2aa0455..e8ee514 100644
--- a/pkg/compiler/lib/src/serialization/impact_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/impact_serialization.dart
@@ -4,12 +4,12 @@
 
 library dart2js.serialization.impact;
 
-import '../common.dart';
 import '../common/resolution.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../universe/selector.dart';
+import '../universe/feature.dart';
 import '../universe/use.dart';
 import '../universe/world_impact.dart';
 import '../util/enumset.dart';
diff --git a/pkg/compiler/lib/src/serialization/json_serializer.dart b/pkg/compiler/lib/src/serialization/json_serializer.dart
index 32c6500..ba995bd 100644
--- a/pkg/compiler/lib/src/serialization/json_serializer.dart
+++ b/pkg/compiler/lib/src/serialization/json_serializer.dart
@@ -5,6 +5,7 @@
 library dart2js.serialization.json;
 
 import 'dart:convert';
+
 import 'keys.dart';
 import 'serialization.dart';
 import 'values.dart';
@@ -14,8 +15,13 @@
   const JsonSerializationEncoder();
 
   String encode(ObjectValue objectValue) {
-    return new JsonEncoder.withIndent(' ')
-        .convert(const JsonValueEncoder().convert(objectValue));
+    try {
+      return new JsonEncoder.withIndent(' ')
+          .convert(const JsonValueEncoder().convert(objectValue));
+    } on JsonUnsupportedObjectError catch (e) {
+      throw 'Error encoding `${e.unsupportedObject}` '
+          '(${e.unsupportedObject.runtimeType})';
+    }
   }
 }
 
@@ -47,7 +53,19 @@
   visitConstant(ConstantValue value, arg) => visit(value.id);
 
   @override
-  double visitDouble(DoubleValue value, arg) => value.value;
+  visitDouble(DoubleValue value, arg) {
+    double d = value.value;
+    if (d.isNaN) {
+      return 'NaN';
+    } else if (d.isInfinite) {
+      if (d.isNegative) {
+        return '-Infinity';
+      } else {
+        return 'Infinity';
+      }
+    }
+    return d;
+  }
 
   @override
   visitElement(ElementValue value, arg) => visit(value.id);
diff --git a/pkg/compiler/lib/src/serialization/keys.dart b/pkg/compiler/lib/src/serialization/keys.dart
index 2c70168..0fa501a 100644
--- a/pkg/compiler/lib/src/serialization/keys.dart
+++ b/pkg/compiler/lib/src/serialization/keys.dart
@@ -29,6 +29,8 @@
   static const Key DYNAMIC_USES = const Key('dynamic-uses');
   static const Key EFFECTIVE_TARGET = const Key('effectiveTarget');
   static const Key EFFECTIVE_TARGET_TYPE = const Key('effectiveTargetType');
+  static const Key EFFECTIVE_TARGET_IS_MALFORMED =
+      const Key('effectiveTargetIsMalformed');
   static const Key ELEMENT = const Key('element');
   static const Key ELEMENTS = const Key('elements');
   static const Key ENCLOSING = const Key('enclosing');
@@ -49,9 +51,11 @@
   static const Key IMPACTS = const Key('impacts');
   static const Key IMPORT = const Key('import');
   static const Key IMPORTS = const Key('imports');
+  static const Key IMPORTS_FOR = const Key('importsFor');
   static const Key IMPORT_SCOPE = const Key('import-scope');
-  static const Key INTERFACES = const Key('interfaces');
   static const Key INDEX = const Key('index');
+  static const Key INFO = const Key('info');
+  static const Key INTERFACES = const Key('interfaces');
   static const Key IS_ABSTRACT = const Key('isAbstract');
   static const Key IS_BREAK_TARGET = const Key('isBreakTarget');
   static const Key IS_CONST = const Key('isConst');
@@ -61,6 +65,8 @@
   static const Key IS_EXTERNAL = const Key('isExternal');
   static const Key IS_FINAL = const Key('isFinal');
   static const Key IS_INJECTED = const Key('isInjected');
+  static const Key IS_METHOD_TYPE_VARIABLE_TYPE =
+      const Key('isMethodTypeVariableType');
   static const Key IS_NAMED = const Key('isNamed');
   static const Key IS_OPERATOR = const Key('isOperator');
   static const Key IS_OPTIONAL = const Key('isOptional');
@@ -111,6 +117,7 @@
   static const Key SEMANTICS = const Key('semantics');
   static const Key SEND_STRUCTURE = const Key('sendStructure');
   static const Key SETTER = const Key('setter');
+  static const Key SOURCE_SPAN = const Key('sourceSpan');
   static const Key STATIC_USES = const Key('static-uses');
   static const Key SUB_KIND = const Key('subKind');
   static const Key SUPERTYPE = const Key('supertype');
@@ -128,6 +135,7 @@
   static const Key URI = const Key('uri');
   static const Key VALUE = const Key('value');
   static const Key VALUES = const Key('values');
+  static const Key WARNING = const Key('warning');
 
   final String name;
 
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 4c932f3..a6ba195 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -10,7 +10,6 @@
 library dart2js.serialization.modelz;
 
 import '../common.dart';
-import '../common/names.dart';
 import '../common/resolution.dart' show Resolution;
 import '../constants/constructors.dart';
 import '../constants/expressions.dart';
@@ -31,7 +30,6 @@
 import '../util/util.dart' show Link, LinkBuilder;
 import 'keys.dart';
 import 'serialization.dart';
-import 'serialization_util.dart';
 
 /// Compute a [Link] from an [Iterable].
 Link toLink(Iterable iterable) {
@@ -196,7 +194,7 @@
     String setterName = '$name,=';
     bool hasSetterId = members.containsKey(setterName);
     Element element;
-    Element setterElement;
+    SetterElement setterElement;
     if (!hasId && !hasSetterId) {
       _lookupCache[name] = null;
       return null;
@@ -236,7 +234,12 @@
     Map<String, Element> setters = <String, Element>{};
     for (Element element in elements) {
       String name = element.name;
-      if (element.isGetter) {
+      if (element.isDeferredLoaderGetter) {
+        // Store directly.
+        // TODO(johnniwinther): Should modelx be normalized to put `loadLibrary`
+        // in an [AbstractFieldElement] instead?
+        _lookupMap[name] = element;
+      } else if (element.isGetter) {
         accessorNames.add(name);
         getters[name] = element;
         // Inserting [element] here to ensure insert order of [name].
@@ -329,7 +332,18 @@
   final GetterElementZ getter;
   final SetterElementZ setter;
 
-  AbstractFieldElementZ(this.name, this.getter, this.setter) {
+  factory AbstractFieldElementZ(
+      String name, GetterElement getter, SetterElement setter) {
+    if (getter?.abstractField != null) {
+      return getter.abstractField;
+    } else if (setter?.abstractField != null) {
+      return setter.abstractField;
+    } else {
+      return new AbstractFieldElementZ._(name, getter, setter);
+    }
+  }
+
+  AbstractFieldElementZ._(this.name, this.getter, this.setter) {
     if (getter != null) {
       getter.abstractField = this;
       getter.setter = setter;
@@ -393,6 +407,7 @@
   List<ExportElement> _exports;
   ListedContainer _exportsMap;
   ListedContainer _importsMap;
+  Map<Element, List<ImportElement>> _importsFor;
 
   LibraryElementZ(ObjectDecoder decoder) : super(decoder);
 
@@ -492,7 +507,28 @@
 
   void _ensureImports() {
     if (_importsMap == null) {
-      _importsMap = new ListedContainer(_decoder.getElements(Key.IMPORT_SCOPE));
+      _importsMap = new ListedContainer(
+          _decoder.getElements(Key.IMPORT_SCOPE, isOptional: true));
+      _importsFor = <Element, List<ImportElement>>{};
+
+      ListDecoder importsDecoder = _decoder.getList(Key.IMPORTS_FOR);
+      for (int index = 0; index < importsDecoder.length; index++) {
+        ObjectDecoder objectDecoder = importsDecoder.getObject(index);
+        Element key = objectDecoder.getElement(Key.ELEMENT);
+        List<ImportElement> imports =
+            objectDecoder.getElements(Key.IMPORTS, isOptional: true);
+
+        // Imports are mapped to [AbstractFieldElement] which are not serialized
+        // so we use getter (or setter if there is no getter) as the key.
+        Element importedElement = key;
+        if (key.isDeferredLoaderGetter) {
+          // Use as [importedElement].
+        } else if (key.isAccessor) {
+          AccessorElement accessor = key;
+          importedElement = accessor.abstractField;
+        }
+        _importsFor[importedElement] = imports;
+      }
     }
   }
 
@@ -504,9 +540,8 @@
 
   @override
   Iterable<ImportElement> getImportsFor(Element element) {
-    // TODO(johnniwinther): Serialize this to support deferred access to
-    // serialized entities.
-    return <ImportElement>[];
+    _ensureImports();
+    return _importsFor[element] ?? const <ImportElement>[];
   }
 
   String toString() {
@@ -788,6 +823,8 @@
           namedParameterTypes.add(parameter.type);
         }
       }
+      List<DartType> typeVariables =
+          _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
 
       FunctionType type = new FunctionType(
           this,
@@ -797,6 +834,7 @@
           namedParameters,
           namedParameterTypes);
       _functionSignature = new FunctionSignatureX(
+          typeVariables: typeVariables,
           requiredParameters: requiredParameters,
           requiredParameterCount: requiredParameterCount,
           optionalParameters: optionalParameters,
@@ -1295,9 +1333,10 @@
 }
 
 class RedirectingFactoryConstructorElementZ extends ConstructorElementZ {
-  InterfaceType _effectiveTargetType;
+  DartType _effectiveTargetType;
   ConstructorElement _immediateRedirectionTarget;
   PrefixElement _redirectionDeferredPrefix;
+  bool _effectiveTargetIsMalformed;
 
   RedirectingFactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
 
@@ -1314,12 +1353,20 @@
       if (_effectiveTarget == null) {
         _effectiveTarget = this;
         _effectiveTargetType = enclosingClass.thisType;
+        _effectiveTargetIsMalformed = false;
       } else {
         _effectiveTargetType = _decoder.getType(Key.EFFECTIVE_TARGET_TYPE);
+        _effectiveTargetIsMalformed =
+            _decoder.getBool(Key.EFFECTIVE_TARGET_IS_MALFORMED);
       }
     }
   }
 
+  bool get isEffectiveTargetMalformed {
+    _ensureEffectiveTarget();
+    return _effectiveTargetIsMalformed;
+  }
+
   @override
   ConstructorElement get effectiveTarget {
     _ensureEffectiveTarget();
@@ -1327,7 +1374,7 @@
   }
 
   @override
-  InterfaceType computeEffectiveTargetType(InterfaceType newType) {
+  DartType computeEffectiveTargetType(InterfaceType newType) {
     _ensureEffectiveTarget();
     return _effectiveTargetType.substByContext(newType);
   }
@@ -1497,6 +1544,8 @@
 
 abstract class MemberElementMixin
     implements DeserializedElementZ, MemberElement {
+  final List<FunctionElement> nestedClosures = <FunctionElement>[];
+
   @override
   MemberElement get memberContext => this;
 
@@ -1504,10 +1553,12 @@
   Name get memberName => new Name(name, library);
 
   @override
-  List<FunctionElement> get nestedClosures => <FunctionElement>[];
+  bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
 
   @override
-  bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
+  void forgetElement() {
+    nestedClosures.clear();
+  }
 }
 
 abstract class FieldElementZ extends DeserializedElementZ
@@ -1634,6 +1685,9 @@
   Element get enclosingElement => executableContext;
 
   @override
+  Element get enclosingClass => memberContext.enclosingClass;
+
+  @override
   ExecutableElement get executableContext {
     if (_executableContext == null) {
       _executableContext = _decoder.getElement(Key.EXECUTABLE_CONTEXT);
@@ -1712,7 +1766,9 @@
   bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
 
   @override
-  AsyncMarker get asyncMarker => AsyncMarker.SYNC;
+  AsyncMarker get asyncMarker {
+    return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
+  }
 }
 
 class TopLevelGetterElementZ extends GetterElementZ with LibraryMemberMixin {
@@ -1871,7 +1927,7 @@
 class TypeVariableElementZ extends DeserializedElementZ
     with AnalyzableElementMixin, AstElementMixinZ, TypedElementMixin
     implements TypeVariableElement {
-  TypeDeclarationElement _typeDeclaration;
+  GenericElement _typeDeclaration;
   TypeVariableType _type;
   DartType _bound;
   Name _memberName;
@@ -1908,7 +1964,7 @@
   int get index => _decoder.getInt(Key.INDEX);
 
   @override
-  TypeDeclarationElement get typeDeclaration {
+  GenericElement get typeDeclaration {
     if (_typeDeclaration == null) {
       _typeDeclaration = _decoder.getElement(Key.TYPE_DECLARATION);
     }
@@ -2259,12 +2315,16 @@
   bool _isDeferred;
   ImportElement _deferredImport;
   GetterElement _loadLibrary;
+  ListedContainer _members;
 
   PrefixElementZ(ObjectDecoder decoder) : super(decoder);
 
   @override
   accept(ElementVisitor visitor, arg) => visitor.visitPrefixElement(this, arg);
 
+  @override
+  bool get isTopLevel => false;
+
   void _ensureDeferred() {
     if (_isDeferred == null) {
       _isDeferred = _decoder.getBool(Key.IS_DEFERRED);
@@ -2295,9 +2355,23 @@
   @override
   ElementKind get kind => ElementKind.PREFIX;
 
+  void _ensureMembers() {
+    if (_members == null) {
+      _members = new ListedContainer(
+          _decoder.getElements(Key.MEMBERS, isOptional: true));
+    }
+  }
+
   @override
   Element lookupLocalMember(String memberName) {
-    return _unsupported('lookupLocalMember');
+    _ensureMembers();
+    return _members.lookup(memberName);
+  }
+
+  @override
+  void forEachLocalMember(void f(Element member)) {
+    _ensureMembers();
+    _members.forEach(f);
   }
 }
 
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index b5d6cae..c3ef366 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -25,7 +25,6 @@
 import 'modelz.dart';
 import 'serialization.dart';
 import 'serialization_util.dart';
-import 'modelz.dart';
 
 /// Visitor that computes a node-index mapping.
 class AstIndexComputer extends Visitor {
@@ -166,21 +165,25 @@
         serializeLabelDefinition(labelDefinition, list.createObject());
       }
     }
+
     if (element is FunctionElement) {
-      FunctionElement function = element;
-      function.functionSignature.forEachParameter((ParameterElement parameter) {
-        ParameterElement parameterImpl = parameter.implementation;
-        // TODO(johnniwinther): Should we support element->node mapping as well?
-        getNodeDataEncoder(parameterImpl.node)
-            .setElement(PARAMETER_NODE, parameter);
-        if (parameter.initializer != null) {
-          getNodeDataEncoder(parameterImpl.initializer)
-              .setElement(PARAMETER_INITIALIZER, parameter);
-        }
-      });
+      serializeParameterNodes(element);
     }
   }
 
+  void serializeParameterNodes(FunctionElement function) {
+    function.functionSignature.forEachParameter((ParameterElement parameter) {
+      ParameterElement parameterImpl = parameter.implementation;
+      // TODO(johnniwinther): Should we support element->node mapping as well?
+      getNodeDataEncoder(parameterImpl.node)
+          .setElement(PARAMETER_NODE, parameter);
+      if (parameter.initializer != null) {
+        getNodeDataEncoder(parameterImpl.initializer)
+            .setElement(PARAMETER_INITIALIZER, parameter);
+      }
+    });
+  }
+
   /// Serialize [target] into [encoder].
   void serializeJumpTarget(JumpTarget jumpTarget, ObjectEncoder encoder) {
     encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext);
@@ -318,6 +321,7 @@
     if (function != null && function.isFunction && function.isLocal) {
       // Mark root nodes of local functions; these need their own ResolvedAst.
       getNodeDataEncoder(node).setElement(Key.FUNCTION, function);
+      serializeParameterNodes(function);
     }
   }
 }
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 1b97c3d..27baa60 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -11,7 +11,6 @@
 import '../elements/elements.dart';
 import '../library_loader.dart' show LibraryProvider;
 import '../util/enumset.dart';
-
 import 'constant_serialization.dart';
 import 'element_serialization.dart';
 import 'json_serializer.dart';
@@ -541,13 +540,21 @@
   /// If no value is associated with [key], then if [isOptional] is `true`,
   /// [defaultValue] is returned, otherwise an exception is thrown.
   double getDouble(K key, {bool isOptional: false, double defaultValue}) {
-    double value = _map[_getKeyValue(key)];
+    var value = _map[_getKeyValue(key)];
     if (value == null) {
       if (isOptional || defaultValue != null) {
         return defaultValue;
       }
       throw new StateError("double value '$key' not found in $_map.");
     }
+    // Support alternative encoding of NaN and +/- infinity for JSON.
+    if (value == 'NaN') {
+      return double.NAN;
+    } else if (value == '-Infinity') {
+      return double.NEGATIVE_INFINITY;
+    } else if (value == 'Infinity') {
+      return double.INFINITY;
+    }
     return value;
   }
 
@@ -692,6 +699,7 @@
         /// Helper used to check that external references are serialized by
         /// the right kind.
         bool verifyElement(var found, var expected) {
+          if (found == null) return false;
           found = found.declaration;
           if (found == expected) return true;
           if (found.isAbstractField && expected.isGetter) {
diff --git a/pkg/compiler/lib/src/serialization/serialization_util.dart b/pkg/compiler/lib/src/serialization/serialization_util.dart
index 1e40000..4883adb 100644
--- a/pkg/compiler/lib/src/serialization/serialization_util.dart
+++ b/pkg/compiler/lib/src/serialization/serialization_util.dart
@@ -7,7 +7,9 @@
 import '../common.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
+import '../diagnostics/messages.dart';
 import '../elements/elements.dart';
+import '../elements/modelx.dart' show WrappedMessage;
 import '../resolution/access_semantics.dart';
 import '../resolution/operators.dart';
 import '../resolution/send_structure.dart';
@@ -526,3 +528,63 @@
   }
   return element;
 }
+
+void serializeMessageArguments(
+    ObjectEncoder encoder, Key key, Map<String, dynamic> messageArguments) {
+  if (messageArguments.isNotEmpty) {
+    MapEncoder mapEncoder = encoder.createMap(Key.ARGUMENTS);
+    messageArguments.forEach((String key, var value) {
+      mapEncoder.setString(key, Message.convertToString(value));
+    });
+  }
+}
+
+Map<String, String> deserializeMessageArguments(
+    ObjectDecoder decoder, Key key) {
+  Map<String, String> arguments = <String, String>{};
+  MapDecoder mapDecoder = decoder.getMap(key, isOptional: true);
+  if (mapDecoder != null) {
+    mapDecoder.forEachKey((String key) {
+      arguments[key] = mapDecoder.getString(key);
+    });
+  }
+  return arguments;
+}
+
+void serializeSourceSpan(ObjectEncoder encoder, SourceSpan sourceSpan) {
+  encoder.setUri(Key.URI, sourceSpan.uri, sourceSpan.uri);
+  encoder.setInt(Key.OFFSET, sourceSpan.begin);
+  encoder.setInt(Key.LENGTH, sourceSpan.end - sourceSpan.begin);
+}
+
+SourceSpan deserializeSourceSpan(ObjectDecoder decoder) {
+  Uri uri = decoder.getUri(Key.URI);
+  int offset = decoder.getInt(Key.OFFSET);
+  int length = decoder.getInt(Key.LENGTH);
+  return new SourceSpan(uri, offset, offset + length);
+}
+
+void serializeWrappedMessage(
+    ObjectEncoder encoder, Key key, WrappedMessage message) {
+  ObjectEncoder object = encoder.createObject(key);
+  if (message.sourceSpan != null) {
+    serializeSourceSpan(
+        object.createObject(Key.SOURCE_SPAN), message.sourceSpan);
+  }
+  object.setEnum(Key.KIND, message.messageKind);
+  serializeMessageArguments(object, Key.ARGUMENTS, message.messageArguments);
+}
+
+WrappedMessage deserializeWrappedMessage(ObjectDecoder decoder, Key key) {
+  ObjectDecoder object = decoder.getObject(key);
+  SourceSpan sourceSpan;
+  ObjectDecoder sourceSpanDecoder =
+      object.getObject(Key.SOURCE_SPAN, isOptional: true);
+  if (sourceSpanDecoder != null) {
+    sourceSpan = deserializeSourceSpan(sourceSpanDecoder);
+  }
+  MessageKind messageKind = object.getEnum(Key.KIND, MessageKind.values);
+  Map<String, dynamic> messageArguments =
+      deserializeMessageArguments(object, Key.ARGUMENTS);
+  return new WrappedMessage(sourceSpan, messageKind, messageArguments);
+}
diff --git a/pkg/compiler/lib/src/serialization/system.dart b/pkg/compiler/lib/src/serialization/system.dart
index 5e2a24b..8d241ce 100644
--- a/pkg/compiler/lib/src/serialization/system.dart
+++ b/pkg/compiler/lib/src/serialization/system.dart
@@ -5,79 +5,69 @@
 library dart2js.serialization_system;
 
 import 'dart:async';
-import '../commandline_options.dart';
+
 import '../common.dart';
-import '../common/backend_api.dart';
-import '../common/names.dart';
 import '../common/resolution.dart';
 import '../compiler.dart';
 import '../elements/elements.dart';
-import '../io/source_file.dart';
 import '../scanner/scanner.dart';
 import '../script.dart';
 import '../serialization/impact_serialization.dart';
 import '../tokens/token.dart';
 import '../universe/call_structure.dart';
-import '../universe/world_impact.dart';
 import '../universe/use.dart';
-import 'json_serializer.dart';
+import '../universe/world_impact.dart';
 import 'modelz.dart';
 import 'resolved_ast_serialization.dart';
 import 'serialization.dart';
 import 'task.dart';
 
-class DeserializerSystemImpl extends DeserializerSystem {
+class ResolutionDeserializerSystem extends DeserializerSystem {
   final Compiler _compiler;
   final Resolution resolution;
   final DeserializationContext deserializationContext;
   final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
-  final ResolutionImpactDeserializer _resolutionImpactDeserializer;
-  final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
 
-  factory DeserializerSystemImpl(Compiler compiler) {
+  factory ResolutionDeserializerSystem(Compiler compiler,
+      {bool deserializeCompilationDataForTesting: false}) {
     DeserializationContext context = new DeserializationContext(
         compiler.reporter, compiler.resolution, compiler.libraryLoader);
     DeserializerPlugin backendDeserializer =
         compiler.backend.serialization.deserializer;
     context.plugins.add(backendDeserializer);
-    ResolutionImpactDeserializer resolutionImpactDeserializer =
-        new ResolutionImpactDeserializer(backendDeserializer);
-    context.plugins.add(resolutionImpactDeserializer);
-    ResolvedAstDeserializerPlugin resolvedAstDeserializer =
-        new ResolvedAstDeserializerPlugin(
-            compiler.parsingContext, backendDeserializer);
-    context.plugins.add(resolvedAstDeserializer);
-    return new DeserializerSystemImpl._(compiler, compiler.resolution, context,
-        resolutionImpactDeserializer, resolvedAstDeserializer);
+    if (compiler.options.resolveOnly && !deserializeCompilationDataForTesting) {
+      return new ResolutionDeserializerSystem._(
+          compiler, compiler.resolution, context);
+    } else {
+      ResolutionImpactDeserializer resolutionImpactDeserializer =
+          new ResolutionImpactDeserializer(backendDeserializer);
+      context.plugins.add(resolutionImpactDeserializer);
+      ResolvedAstDeserializerPlugin resolvedAstDeserializer =
+          new ResolvedAstDeserializerPlugin(
+              compiler.parsingContext, backendDeserializer);
+      context.plugins.add(resolvedAstDeserializer);
+      return new CompilationDeserializerSystem._(compiler, compiler.resolution,
+          context, resolutionImpactDeserializer, resolvedAstDeserializer);
+    }
   }
 
-  DeserializerSystemImpl._(
-      this._compiler,
-      this.resolution,
-      this.deserializationContext,
-      this._resolutionImpactDeserializer,
-      this._resolvedAstDeserializer);
+  ResolutionDeserializerSystem._(
+      this._compiler, this.resolution, this.deserializationContext);
 
   @override
   Future<LibraryElement> readLibrary(Uri resolvedUri) {
     LibraryElement library = deserializationContext.lookupLibrary(resolvedUri);
     if (library != null) {
       deserializedLibraries.add(library);
-      return Future.forEach(library.compilationUnits,
-          (CompilationUnitElement compilationUnit) {
-        ScriptZ script = compilationUnit.script;
-        return _compiler
-            .readScript(script.readableUri)
-            .then((Script newScript) {
-          script.file = newScript.file;
-          script.isSynthesized = newScript.isSynthesized;
-          _resolvedAstDeserializer.scripts[script.resourceUri] = script;
-        });
-      }).then((_) => library);
+      return onReadLibrary(library);
     }
     return new Future<LibraryElement>.value(library);
   }
 
+  Future<LibraryElement> onReadLibrary(LibraryElement library) {
+    return new Future<LibraryElement>.value(library);
+  }
+
   // TODO(johnniwinther): Remove the need for this method.
   @override
   bool hasResolvedAst(ExecutableElement element) {
@@ -85,6 +75,70 @@
   }
 
   @override
+  ResolvedAst getResolvedAst(ExecutableElement element) => null;
+
+  @override
+  bool hasResolutionImpact(Element element) => true;
+
+  @override
+  ResolutionImpact getResolutionImpact(Element element) {
+    return const ResolutionImpact();
+  }
+
+  @override
+  WorldImpact computeWorldImpact(Element element) {
+    ResolutionImpact resolutionImpact = getResolutionImpact(element);
+    assert(invariant(element, resolutionImpact != null,
+        message: 'No impact found for $element (${element.library})'));
+    if (element is ExecutableElement) {
+      getResolvedAst(element);
+    }
+    if (element.isField && !element.isConst) {
+      FieldElement field = element;
+      if (field.isTopLevel || field.isStatic) {
+        if (field.constant == null) {
+          // TODO(johnniwinther): Find a cleaner way to do this. Maybe
+          // `Feature.LAZY_FIELD` of the resolution impact should be used
+          // instead.
+          _compiler.backend.constants.registerLazyStatic(element);
+        }
+      }
+    }
+    return resolution.transformResolutionImpact(element, resolutionImpact);
+  }
+
+  @override
+  bool isDeserialized(Element element) {
+    return deserializedLibraries.contains(element.library);
+  }
+}
+
+class CompilationDeserializerSystem extends ResolutionDeserializerSystem {
+  final ResolutionImpactDeserializer _resolutionImpactDeserializer;
+  final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
+
+  CompilationDeserializerSystem._(
+      Compiler compiler,
+      Resolution resolution,
+      DeserializationContext deserializationContext,
+      this._resolutionImpactDeserializer,
+      this._resolvedAstDeserializer)
+      : super._(compiler, resolution, deserializationContext);
+
+  @override
+  Future<LibraryElement> onReadLibrary(LibraryElement library) {
+    return Future.forEach(library.compilationUnits,
+        (CompilationUnitElement compilationUnit) {
+      ScriptZ script = compilationUnit.script;
+      return _compiler.readScript(script.readableUri).then((Script newScript) {
+        script.file = newScript.file;
+        script.isSynthesized = newScript.isSynthesized;
+        _resolvedAstDeserializer.scripts[script.resourceUri] = script;
+      });
+    }).then((_) => library);
+  }
+
+  @override
   ResolvedAst getResolvedAst(ExecutableElement element) {
     return _resolvedAstDeserializer.getResolvedAst(element);
   }
@@ -120,33 +174,6 @@
     }
     return _resolutionImpactDeserializer.getResolutionImpact(element);
   }
-
-  @override
-  WorldImpact computeWorldImpact(Element element) {
-    ResolutionImpact resolutionImpact = getResolutionImpact(element);
-    assert(invariant(element, resolutionImpact != null,
-        message: 'No impact found for $element (${element.library})'));
-    if (element is ExecutableElement) {
-      getResolvedAst(element);
-    }
-    if (element.isField && !element.isConst) {
-      FieldElement field = element;
-      if (field.isTopLevel || field.isStatic) {
-        if (field.constant == null) {
-          // TODO(johnniwinther): Find a cleaner way to do this. Maybe
-          // `Feature.LAZY_FIELD` of the resolution impact should be used
-          // instead.
-          _compiler.backend.constants.registerLazyStatic(element);
-        }
-      }
-    }
-    return resolution.transformResolutionImpact(element, resolutionImpact);
-  }
-
-  @override
-  bool isDeserialized(Element element) {
-    return deserializedLibraries.contains(element.library);
-  }
 }
 
 const String WORLD_IMPACT_TAG = 'worldImpact';
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index f57ade6..9f319db 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -5,7 +5,7 @@
 library dart2js.serialization.task;
 
 import 'dart:async' show EventSink, Future;
-import '../common.dart';
+
 import '../common/resolution.dart' show ResolutionImpact, ResolutionWorkItem;
 import '../common/tasks.dart' show CompilerTask;
 import '../common/work.dart' show ItemCompilationContext;
@@ -41,6 +41,10 @@
   // retained, for instance impacts, resolution data etc.
   bool supportSerialization = false;
 
+  /// Set this flag to also deserialize [ResolvedAst]s and [ResolutionImpact]s
+  /// in `resolveOnly` mode. Use this for testing only.
+  bool deserializeCompilationDataForTesting = false;
+
   /// If `true`, deserialized data is supported.
   bool get supportsDeserialization => deserializer != null;
 
@@ -117,9 +121,11 @@
   void deserializeFromText(Uri sourceUri, String serializedData) {
     measure(() {
       if (deserializer == null) {
-        deserializer = new DeserializerSystemImpl(compiler);
+        deserializer = new ResolutionDeserializerSystem(compiler,
+            deserializeCompilationDataForTesting:
+                deserializeCompilationDataForTesting);
       }
-      DeserializerSystemImpl deserializerImpl = deserializer;
+      ResolutionDeserializerSystem deserializerImpl = deserializer;
       DeserializationContext context = deserializerImpl.deserializationContext;
       Deserializer dataDeserializer = new Deserializer.fromText(
           context, sourceUri, serializedData, const JsonSerializationDecoder());
diff --git a/pkg/compiler/lib/src/serialization/type_serialization.dart b/pkg/compiler/lib/src/serialization/type_serialization.dart
index 24a46ae..96f659e 100644
--- a/pkg/compiler/lib/src/serialization/type_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/type_serialization.dart
@@ -5,8 +5,9 @@
 library dart2js.serialization.types;
 
 import '../dart_types.dart';
-import 'serialization.dart';
+import '../elements/elements.dart';
 import 'keys.dart';
+import 'serialization.dart';
 
 /// Visitor that serializes a [DartType] by encoding it into an [ObjectEncoder].
 ///
@@ -24,6 +25,8 @@
 
   void visitTypeVariableType(TypeVariableType type, ObjectEncoder encoder) {
     encoder.setElement(Key.ELEMENT, type.element);
+    encoder.setBool(
+        Key.IS_METHOD_TYPE_VARIABLE_TYPE, type is MethodTypeVariableType);
   }
 
   void visitFunctionType(FunctionType type, ObjectEncoder encoder) {
@@ -76,7 +79,11 @@
             decoder.getStrings(Key.NAMED_PARAMETERS, isOptional: true),
             decoder.getTypes(Key.NAMED_PARAMETER_TYPES, isOptional: true));
       case TypeKind.TYPE_VARIABLE:
-        return new TypeVariableType(decoder.getElement(Key.ELEMENT));
+        TypeVariableElement element = decoder.getElement(Key.ELEMENT);
+        if (decoder.getBool(Key.IS_METHOD_TYPE_VARIABLE_TYPE)) {
+          return new MethodTypeVariableType(element);
+        }
+        return new TypeVariableType(element);
       case TypeKind.TYPEDEF:
         return new TypedefType(decoder.getElement(Key.ELEMENT),
             decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 57bc9d3..94052cb 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -19,16 +19,6 @@
 import 'io/source_file.dart';
 import 'util/uri_extras.dart';
 
-List<int> readAll(String filename) {
-  var file = (new File(filename)).openSync();
-  var length = file.lengthSync();
-  // +1 to have a 0 terminated list, see [Scanner].
-  var buffer = new Uint8List(length + 1);
-  file.readIntoSync(buffer, 0, length);
-  file.closeSync();
-  return buffer;
-}
-
 abstract class SourceFileProvider implements CompilerInput {
   bool isWindows = (Platform.operatingSystem == 'windows');
   Uri cwd = currentDirectory;
@@ -55,12 +45,10 @@
     try {
       source = readAll(resourceUri.toFilePath());
     } on FileSystemException catch (ex) {
-      OSError ose = ex.osError;
-      String detail =
-          (ose != null && ose.message != null) ? ' (${ose.message})' : '';
+      String message = ex.osError?.message;
+      String detail = message != null ? ' ($message)' : '';
       return new Future.error(
-          "Error reading '${relativize(cwd, resourceUri, isWindows)}'"
-          "$detail");
+          "Error reading '${relativizeUri(resourceUri)}' $detail");
     }
     dartCharactersRead += source.length;
     sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
@@ -100,7 +88,7 @@
 
   // TODO(johnniwinther): Remove this when no longer needed for the old compiler
   // API.
-  Future/*<List<int> | String>*/ call(Uri resourceUri);
+  Future/*<List<int> | String>*/ call(Uri resourceUri) => throw "unimplemented";
 
   relativizeUri(Uri uri) => relativize(cwd, uri, isWindows);
 
@@ -109,6 +97,16 @@
   }
 }
 
+List<int> readAll(String filename) {
+  var file = (new File(filename)).openSync();
+  var length = file.lengthSync();
+  // +1 to have a 0 terminated list, see [Scanner].
+  var buffer = new Uint8List(length + 1);
+  file.readIntoSync(buffer, 0, length);
+  file.closeSync();
+  return buffer;
+}
+
 class CompilerSourceFileProvider extends SourceFileProvider {
   // TODO(johnniwinther): Remove this when no longer needed for the old compiler
   // API.
@@ -168,9 +166,6 @@
   @override
   void report(var code, Uri uri, int begin, int end, String message,
       api.Diagnostic kind) {
-    // TODO(ahe): Remove this when source map is handled differently.
-    if (identical(kind.name, 'source map')) return;
-
     if (isAborting) return;
     isAborting = (kind == api.Diagnostic.CRASH);
 
@@ -333,14 +328,14 @@
       }
     }
 
-    return new EventSinkWrapper(writeStringSync, onDone);
+    return new _EventSinkWrapper(writeStringSync, onDone);
   }
 }
 
-class EventSinkWrapper extends EventSink<String> {
+class _EventSinkWrapper extends EventSink<String> {
   var onAdd, onClose;
 
-  EventSinkWrapper(this.onAdd, this.onClose);
+  _EventSinkWrapper(this.onAdd, this.onClose);
 
   void add(String data) => onAdd(data);
 
@@ -348,3 +343,66 @@
 
   void close() => onClose();
 }
+
+/// Adapter to integrate dart2js in bazel.
+///
+/// To handle bazel's special layout:
+///
+///  * We specify a .packages configuration file that expands packages to their
+///    corresponding bazel location. This way there is no need to create a pub
+///    cache prior to invoking dart2js.
+///
+///  * We provide an implicit mapping that can make all urls relative to the
+///  bazel root.
+///    To the compiler, URIs look like:
+///      file:///bazel-root/a/b/c.dart
+///
+///    even though in the file system the file is located at:
+///      file:///path/to/the/actual/bazel/root/a/b/c.dart
+///
+///    This mapping serves two purposes:
+///      - It makes compiler results independent of the machine layout, which
+///        enables us to share results across bazel runs and across machines.
+///
+///      - It hides the distinction between generated and source files. That way
+///      we can use the standard package-resolution mechanism and ignore the
+///      internals of how files are organized within bazel.
+///
+/// When invoking the compiler, bazel will use `package:` and
+/// `file:///bazel-root/` URIs to specify entrypoints.
+///
+/// The mapping is specified using search paths relative to the current
+/// directory. When this provider looks up a file, the bazel-root folder is
+/// replaced by the first directory in the search path containing the file, if
+/// any. For example, given the search path ".,bazel-bin/", and a URL
+/// of the form `file:///bazel-root/a/b.dart`, this provider will check if the
+/// file exists under "./a/b.dart", then check under "bazel-bin/a/b.dart".  If
+/// none of the paths matches, it will attempt to load the file from
+/// `/bazel-root/a/b.dart` which will likely fail.
+class BazelInputProvider extends SourceFileProvider {
+  final List<Uri> dirs;
+
+  BazelInputProvider(List<String> searchPaths)
+      : dirs = searchPaths.map(_resolve).toList();
+
+  static _resolve(String path) => currentDirectory.resolve(path);
+
+  @override
+  Future readFromUri(Uri uri) async {
+    var resolvedUri = uri;
+    var path = uri.path;
+    if (path.startsWith('/bazel-root')) {
+      path = path.substring('/bazel-root/'.length);
+      for (var dir in dirs) {
+        var file = dir.resolve(path);
+        if (await new File.fromUri(file).exists()) {
+          resolvedUri = file;
+          break;
+        }
+      }
+    }
+    var result = await readUtf8BytesFromUri(resolvedUri);
+    sourceFiles[uri] = sourceFiles[resolvedUri];
+    return result;
+  }
+}
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 7607077..77025b0 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -82,6 +82,10 @@
   final String name;
   final ExecutableElement executableContext;
 
+  // Avoid slow Object.hashCode.
+  final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30);
+  static int _nextHashCode = 0;
+
   SyntheticLocal(this.name, this.executableContext);
 
   toString() => 'SyntheticLocal($name)';
@@ -202,8 +206,10 @@
 
   LocalsHandler(
       this.builder, this.executableContext, InterfaceType instanceType)
-      : this.instanceType = instanceType == null ||
-            instanceType.containsTypeVariables ? null : instanceType;
+      : this.instanceType =
+            instanceType == null || instanceType.containsTypeVariables
+                ? null
+                : instanceType;
 
   /// Substituted type variables occurring in [type] into the context of
   /// [contextClass].
@@ -283,7 +289,7 @@
         (LocalVariableElement from, BoxFieldElement to) {
       // The [from] can only be a parameter for function-scopes and not
       // loop scopes.
-      if (from.isParameter && !element.isGenerativeConstructorBody) {
+      if (from.isRegularParameter && !element.isGenerativeConstructorBody) {
         // Now that the redirection is set up, the update to the local will
         // write the parameter value into the box.
         // Store the captured parameter in the box. Get the current value
@@ -1746,7 +1752,8 @@
   }
 
   HGraph buildCheckedSetter(VariableElement field) {
-    openFunction(field, field.node);
+    ResolvedAst resolvedAst = field.resolvedAst;
+    openFunction(field, resolvedAst.node);
     HInstruction thisInstruction = localsHandler.readThis();
     // Use dynamic type because the type computed by the inferrer is
     // narrowed to the type annotation.
@@ -2755,11 +2762,13 @@
       visit(node.condition);
       pushInvokeStatic(node, helpers.assertTest, [pop()]);
     }
+
     void fail() {
       visit(node.message);
       pushInvokeStatic(node, helpers.assertThrow, [pop()]);
       pop();
     }
+
     handleIf(node, visitCondition: buildCondition, visitThen: fail);
   }
 
@@ -3093,6 +3102,7 @@
         pop();
       }
     }
+
     HInstruction buildCondition() {
       if (node.condition == null) {
         return graph.addConstantBool(true, compiler);
@@ -3100,6 +3110,7 @@
       visit(node.condition);
       return popBoolified();
     }
+
     void buildUpdate() {
       for (ast.Expression expression in node.update) {
         visit(expression);
@@ -3109,9 +3120,11 @@
         pop();
       }
     }
+
     void buildBody() {
       visit(node.body);
     }
+
     handleLoop(node, buildInitializer, buildCondition, buildUpdate, buildBody);
   }
 
@@ -3121,6 +3134,7 @@
       visit(node.condition);
       return popBoolified();
     }
+
     handleLoop(node, () {}, buildCondition, () {}, () {
       visit(node.body);
     });
@@ -5614,14 +5628,15 @@
       var filteredArguments = <HInstruction>[];
       var parameterNameMap = new Map<String, js.Expression>();
       params.orderedForEachParameter((ParameterElement parameter) {
-        // TODO(jacobr): throw if parameter names do not match names of property
-        // names in the class.
+        // TODO(jacobr): consider throwing if parameter names do not match
+        // names of properties in the class.
         assert(parameter.isNamed);
         HInstruction argument = arguments[i];
         if (argument != null) {
           filteredArguments.add(argument);
-          parameterNameMap[parameter.name] =
-              new js.InterpolatedExpression(positions++);
+          var jsName =
+              backend.nativeData.getUnescapedJSInteropName(parameter.name);
+          parameterNameMap[jsName] = new js.InterpolatedExpression(positions++);
         }
         i++;
       });
@@ -5660,8 +5675,10 @@
     // Native behavior effects here are similar to native/behavior.dart.
     // The return type is dynamic if we don't trust js-interop type
     // declarations.
-    nativeBehavior.typesReturned.add(compiler
-        .options.trustJSInteropTypeAnnotations ? type : const DynamicType());
+    nativeBehavior.typesReturned.add(
+        compiler.options.trustJSInteropTypeAnnotations
+            ? type
+            : const DynamicType());
 
     // The allocation effects include the declared type if it is native (which
     // includes js interop types).
@@ -5795,6 +5812,7 @@
         add(buildInvokeSuper(setterSelector, element, setterInputs));
       }
     }
+
     if (identical(node.assignmentOperator.source, '=')) {
       addDynamicSendArgumentsToList(node, setterInputs);
       generateSuperSendSet();
@@ -6383,6 +6401,7 @@
           stack.add(getterInstruction);
         }
       }
+
       if (node.isConditional) {
         // generate `e?.x op= e2` as:
         //   t1 = e
@@ -6633,6 +6652,7 @@
     void loadLocal(ParameterElement parameter) {
       inputs.add(localsHandler.readLocal(parameter));
     }
+
     void loadPosition(int position, ParameterElement optionalParameter) {
       if (position < redirectingRequireds.length) {
         loadLocal(redirectingRequireds[position]);
@@ -6921,6 +6941,7 @@
           new TypeMask.subclass(coreClasses.objectClass, compiler.world)));
       return popBoolified();
     }
+
     void buildBody() {
       Selector call = Selectors.current;
       TypeMask callMask = elements.getCurrentTypeMask(node);
@@ -7335,6 +7356,7 @@
       visit(node.expression);
       return pop();
     }
+
     Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
       List<ConstantValue> constantList = <ConstantValue>[];
       for (ast.Node labelOrCase in switchCase.labelsAndCases) {
@@ -7344,12 +7366,15 @@
       }
       return constantList;
     }
+
     bool isDefaultCase(ast.SwitchCase switchCase) {
       return switchCase.isDefaultCase;
     }
+
     void buildSwitchCase(ast.SwitchCase node) {
       visit(node.statements);
     }
+
     handleSwitch(node, jumpHandler, buildExpression, node.cases, getConstants,
         isDefaultCase, buildSwitchCase);
     jumpHandler.close();
@@ -7408,6 +7433,7 @@
       visit(node.expression);
       return pop();
     }
+
     Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
       List<ConstantValue> constantList = <ConstantValue>[];
       if (switchCase != null) {
@@ -7419,9 +7445,11 @@
       }
       return constantList;
     }
+
     bool isDefaultCase(ast.SwitchCase switchCase) {
       return switchCase == null || switchCase.isDefaultCase;
     }
+
     void buildSwitchCase(ast.SwitchCase switchCase) {
       if (switchCase != null) {
         // Generate 'target = i; break;' for switch case i.
@@ -7435,6 +7463,7 @@
       }
       jumpTargets[switchTarget].generateBreak();
     }
+
     handleSwitch(node, jumpHandler, buildExpression, switchCases, getConstants,
         isDefaultCase, buildSwitchCase);
     jumpHandler.close();
@@ -7445,9 +7474,11 @@
       HInstruction buildExpression() {
         return localsHandler.readLocal(switchTarget);
       }
+
       Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
         return <ConstantValue>[constantSystem.createInt(caseIndex[switchCase])];
       }
+
       void buildSwitchCase(ast.SwitchCase switchCase) {
         visit(switchCase.statements);
         if (!isAborted()) {
@@ -7456,6 +7487,7 @@
           jumpTargets[switchTarget].generateBreak();
         }
       }
+
       // Pass a [NullJumpHandler] because the target for the contained break
       // is not the generated switch statement but instead the loop generated
       // in the call to [handleLoop] below.
@@ -7484,6 +7516,7 @@
             code, backend.boolType, [localsHandler.readLocal(switchTarget)],
             nativeBehavior: native.NativeBehavior.PURE));
       }
+
       handleIf(node,
           visitCondition: buildCondition,
           visitThen: buildLoop,
@@ -7859,6 +7892,7 @@
     addOptionalSuccessor(b1, b2) {
       if (b2 != null) b1.addSuccessor(b2);
     }
+
     addExitTrySuccessor(successor) {
       if (successor == null) return;
       // Iterate over all blocks created inside this try/catch, and
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 9637549..e961485 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -740,6 +740,7 @@
           registry.registerInstantiatedClass(classElement);
         }
       }
+
       register(helpers.jsPlainJavaScriptObjectClass);
       register(helpers.jsUnknownJavaScriptObjectClass);
 
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 681056f..5a0f558 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -8,7 +8,6 @@
 import '../js_backend/js_backend.dart';
 import '../types/types.dart';
 import '../universe/selector.dart' show Selector;
-
 import 'nodes.dart';
 
 /**
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 3249c31..8cc7467 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -185,7 +185,8 @@
 
   HInstruction findDominator(Iterable<HInstruction> instructions) {
     HInstruction result;
-    L1: for (HInstruction candidate in instructions) {
+    L1:
+    for (HInstruction candidate in instructions) {
       for (HInstruction current in instructions) {
         if (current != candidate && !candidate.dominates(current)) continue L1;
       }
@@ -232,17 +233,24 @@
       if (interceptedClasses.contains(helpers.jsNumberClass) &&
           !(interceptedClasses.contains(helpers.jsDoubleClass) ||
               interceptedClasses.contains(helpers.jsIntClass))) {
+        Set<ClassElement> required;
         for (HInstruction user in node.usedBy) {
           if (user is! HInvoke) continue;
           Set<ClassElement> intercepted =
               backend.getInterceptedClassesOn(user.selector.name);
           if (intercepted.contains(helpers.jsIntClass)) {
-            interceptedClasses.add(helpers.jsIntClass);
+            required ??= new Set<ClassElement>();
+            required.add(helpers.jsIntClass);
           }
           if (intercepted.contains(helpers.jsDoubleClass)) {
-            interceptedClasses.add(helpers.jsDoubleClass);
+            required ??= new Set<ClassElement>();
+            required.add(helpers.jsDoubleClass);
           }
         }
+        // Don't modify the result of [backend.getInterceptedClassesOn].
+        if (required != null) {
+          interceptedClasses = interceptedClasses.union(required);
+        }
       }
     } else {
       interceptedClasses = new Set<ClassElement>();
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 3b119bd..01be037 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -674,7 +674,8 @@
 
     if (better.isEmpty) return rewrite(from, to);
 
-    L1: for (HInstruction user in from.usedBy) {
+    L1:
+    for (HInstruction user in from.usedBy) {
       for (HCheck check in better) {
         if (check.dominates(user)) {
           user.rewriteInput(from, check);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index e1eee00c..9dd26ff 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -14,7 +14,7 @@
 import '../js_backend/backend_helpers.dart' show BackendHelpers;
 import '../js_backend/js_backend.dart';
 import '../native/native.dart' as native;
-import '../tree/tree.dart' as ast;
+import '../tree/dartstring.dart' as ast;
 import '../types/types.dart';
 import '../universe/selector.dart' show Selector;
 import '../universe/side_effects.dart' show SideEffects;
@@ -450,7 +450,33 @@
           node.element = element;
         }
       }
+      return node;
     }
+
+    // Replace method calls through fields with a closure call on the value of
+    // the field. This usually removes the demand for the call-through stub and
+    // makes the field load available to further optimization, e.g. LICM.
+
+    if (element != null &&
+        element.isField &&
+        element.name == node.selector.name) {
+      if (!backend.isNative(element) && !node.isCallOnInterceptor(compiler)) {
+        HInstruction receiver = node.getDartReceiver(compiler);
+        TypeMask type =
+            TypeMaskFactory.inferredTypeForElement(element, compiler);
+        HInstruction load = new HFieldGet(element, receiver, type);
+        node.block.addBefore(node, load);
+        Selector callSelector = new Selector.callClosureFrom(node.selector);
+        List<HInstruction> inputs = <HInstruction>[load]
+          ..addAll(node.inputs.skip(node.isInterceptedCall ? 2 : 1));
+        HInstruction closureCall =
+            new HInvokeClosure(callSelector, inputs, node.instructionType)
+              ..sourceInformation = node.sourceInformation;
+        node.block.addAfter(load, closureCall);
+        return closureCall;
+      }
+    }
+
     return node;
   }
 
@@ -1197,6 +1223,7 @@
       }
       return false;
     }
+
     return instruction.isAllocation &&
         instruction.isPure() &&
         trivialDeadStoreReceivers.putIfAbsent(
@@ -1249,7 +1276,8 @@
   }
 
   void cleanPhis(HGraph graph) {
-    L: for (HBasicBlock block in graph.blocks) {
+    L:
+    for (HBasicBlock block in graph.blocks) {
       List<HBasicBlock> predecessors = block.predecessors;
       // Zap all inputs to phis that correspond to dead blocks.
       block.forEachPhi((HPhi phi) {
@@ -1543,6 +1571,7 @@
       assert(instruction is HGoto || instruction is HLoopBranch);
       return instruction is HGoto || instruction.inputs[0].isConstantTrue();
     }
+
     bool firstInstructionInLoop = block == loopHeader
         // Compensate for lack of code motion.
         ||
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 9a6f6c6..5591851 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -10,7 +10,6 @@
 import '../diagnostics/invariant.dart' show DEBUG_MODE;
 import '../js_backend/js_backend.dart';
 import '../tracer.dart';
-
 import 'nodes.dart';
 
 /**
diff --git a/pkg/compiler/lib/src/ssa/value_set.dart b/pkg/compiler/lib/src/ssa/value_set.dart
index c990014..89dbeca 100644
--- a/pkg/compiler/lib/src/ssa/value_set.dart
+++ b/pkg/compiler/lib/src/ssa/value_set.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import '../universe/side_effects.dart' show SideEffects;
-
 import 'nodes.dart';
 
 class ValueSet {
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index 2145d6d..5ea597d 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -5,7 +5,6 @@
 import '../common.dart';
 import '../compiler.dart' show Compiler;
 import '../js_backend/js_backend.dart';
-
 import 'nodes.dart';
 
 /**
diff --git a/pkg/compiler/lib/src/string_validator.dart b/pkg/compiler/lib/src/string_validator.dart
index 1965695..60c3c78 100644
--- a/pkg/compiler/lib/src/string_validator.dart
+++ b/pkg/compiler/lib/src/string_validator.dart
@@ -10,7 +10,8 @@
 
 import 'common.dart';
 import 'tokens/token.dart' show Token;
-import 'tree/tree.dart';
+import 'tree/dartstring.dart' show DartString;
+import 'tree/nodes.dart' show StringQuoting;
 import 'util/characters.dart';
 
 class StringValidator {
diff --git a/pkg/compiler/lib/src/tokens/keyword.dart b/pkg/compiler/lib/src/tokens/keyword.dart
index ad22ee6..4d914bc 100644
--- a/pkg/compiler/lib/src/tokens/keyword.dart
+++ b/pkg/compiler/lib/src/tokens/keyword.dart
@@ -5,7 +5,6 @@
 library dart2js.tokens.keywords;
 
 import '../util/characters.dart' as Characters show $a;
-
 import 'precedence.dart' show PrecedenceInfo;
 import 'precedence_constants.dart' as Precedence
     show AS_INFO, IS_INFO, KEYWORD_INFO;
diff --git a/pkg/compiler/lib/src/tokens/token.dart b/pkg/compiler/lib/src/tokens/token.dart
index df66bd9..af31142 100644
--- a/pkg/compiler/lib/src/tokens/token.dart
+++ b/pkg/compiler/lib/src/tokens/token.dart
@@ -4,12 +4,11 @@
 
 library dart2js.tokens;
 
-import 'dart:convert' show UTF8;
 import 'dart:collection' show HashSet;
+import 'dart:convert' show UTF8;
 
 import '../common.dart';
 import '../util/util.dart' show computeHashCode;
-
 import 'keyword.dart' show Keyword;
 import 'precedence.dart' show PrecedenceInfo;
 import 'precedence_constants.dart' as Precedence show BAD_INPUT_INFO;
diff --git a/pkg/compiler/lib/src/tracer.dart b/pkg/compiler/lib/src/tracer.dart
index 359ea77..21d2ed5 100644
--- a/pkg/compiler/lib/src/tracer.dart
+++ b/pkg/compiler/lib/src/tracer.dart
@@ -5,15 +5,12 @@
 library tracer;
 
 import 'dart:async' show EventSink;
+
 import '../compiler.dart' as api;
 import 'common/work.dart' show ItemCompilationContext;
 import 'compiler.dart' show Compiler;
 import 'ssa/nodes.dart' as ssa show HGraph;
 import 'ssa/ssa_tracer.dart' show HTracer;
-import 'cps_ir/cps_ir_nodes.dart' as cps_ir;
-import 'cps_ir/cps_ir_tracer.dart' show IRTracer;
-import 'tree_ir/tree_ir_nodes.dart' as tree_ir;
-import 'tree_ir/tree_ir_tracer.dart' show TreeTracer;
 import 'util/util.dart' show Indentation;
 
 /**
@@ -57,10 +54,6 @@
     if (!traceActive) return;
     if (irObject is ssa.HGraph) {
       new HTracer(output, compiler, context).traceGraph(name, irObject);
-    } else if (irObject is cps_ir.FunctionDefinition) {
-      new IRTracer(output).traceGraph(name, irObject);
-    } else if (irObject is tree_ir.FunctionDefinition) {
-      new TreeTracer(output).traceGraph(name, irObject);
     }
   }
 
diff --git a/pkg/compiler/lib/src/tree/dartstring.dart b/pkg/compiler/lib/src/tree/dartstring.dart
index 684f55b..4ec773c 100644
--- a/pkg/compiler/lib/src/tree/dartstring.dart
+++ b/pkg/compiler/lib/src/tree/dartstring.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:collection';
+
 import '../util/characters.dart';
 
 /**
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
index d2e9d96..1885e0d 100644
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ b/pkg/compiler/lib/src/tree/nodes.dart
@@ -295,10 +295,10 @@
  * "Token".
  */
 abstract class Node extends NullTreeElementMixin implements Spannable {
-  final int hashCode;
+  final int hashCode = _HASH_COUNTER = (_HASH_COUNTER + 1).toUnsigned(30);
   static int _HASH_COUNTER = 0;
 
-  Node() : hashCode = ++_HASH_COUNTER;
+  Node();
 
   accept(Visitor visitor);
 
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
index 37838eb..12d4141 100644
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ b/pkg/compiler/lib/src/tree/unparser.dart
@@ -260,6 +260,7 @@
       write(' ');
     }
     unparseFunctionName(node.name);
+    visit(node.typeVariables);
     visit(node.parameters);
     if (node.initializers != null) {
       space();
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
deleted file mode 100644
index bfed37d..0000000
--- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
+++ /dev/null
@@ -1,566 +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 tree_ir.optimization.logical_rewriter;
-
-import '../tree_ir_nodes.dart';
-import 'optimization.dart' show Pass;
-import '../../constants/values.dart' as values;
-
-/// Rewrites logical expressions to be more compact in the Tree IR.
-///
-/// In this class an expression is said to occur in "boolean context" if
-/// its result is immediately applied to boolean conversion.
-///
-/// IF STATEMENTS:
-///
-/// We apply the following two rules to [If] statements (see [visitIf]).
-///
-///   if (E) {} else S  ==>  if (!E) S else {}    (else can be omitted)
-///   if (!E) S1 else S2  ==>  if (E) S2 else S1  (unless previous rule applied)
-///
-/// NEGATION:
-///
-/// De Morgan's Laws are used to rewrite negations of logical operators so
-/// negations are closer to the root:
-///
-///   !x && !y  -->  !(x || y)
-///
-/// This is to enable other rewrites, such as branch swapping in an if. In some
-/// contexts, the rule is reversed because we do not expect to apply a rewrite
-/// rule to the result. For example:
-///
-///   z = !(x || y)  ==>  z = !x && !y;
-///
-/// CONDITIONALS:
-///
-/// Conditionals with boolean constant operands occur frequently in the input.
-/// They can often the re-written to logical operators, for instance:
-///
-///   if (x ? y : false) S1 else S2
-///     ==>
-///   if (x && y) S1 else S2
-///
-/// Conditionals are tricky to rewrite when they occur out of boolean context.
-/// Here we must apply more conservative rules, such as:
-///
-///   x ? true : false  ==>  !!x
-///
-/// If the possible falsy values of the condition are known, we can sometimes
-/// introduce a logical operator:
-///
-///   !x ? y : false  ==>  !x && y
-///
-class LogicalRewriter extends RecursiveTransformer implements Pass {
-  String get passName => 'Logical rewriter';
-
-  @override
-  void rewrite(FunctionDefinition node) {
-    node.body = visitStatement(node.body);
-  }
-
-  final FallthroughStack fallthrough = new FallthroughStack();
-
-  /// True if the given statement is equivalent to its fallthrough semantics.
-  ///
-  /// This means it will ultimately translate to an empty statement.
-  bool isFallthrough(Statement node) {
-    return node is Break && isFallthroughBreak(node) ||
-        node is Continue && isFallthroughContinue(node) ||
-        node is Return && isFallthroughReturn(node);
-  }
-
-  bool isFallthroughBreak(Break node) {
-    Statement target = fallthrough.target;
-    return node.target.binding.next == target ||
-        target is Break && target.target == node.target;
-  }
-
-  bool isFallthroughContinue(Continue node) {
-    Statement target = fallthrough.target;
-    return node.target.binding == target ||
-        target is Continue && target.target == node.target;
-  }
-
-  bool isFallthroughReturn(Return node) {
-    return isNull(node.value) && fallthrough.target == null;
-  }
-
-  bool isTerminator(Statement node) {
-    return (node is Jump || node is Return) && !isFallthrough(node) ||
-        (node is ExpressionStatement && node.next is Unreachable) ||
-        node is Throw;
-  }
-
-  Statement visitIf(If node) {
-    // If one of the branches is empty (i.e. just a fallthrough), then that
-    // branch should preferably be the 'else' so we won't have to print it.
-    // In other words, we wish to perform this rewrite:
-    //   if (E) {} else {S}
-    //     ==>
-    //   if (!E) {S}
-    // In the tree language, empty statements do not exist yet, so we must check
-    // if one branch contains a break that can be eliminated by fallthrough.
-
-    // Rewrite each branch and keep track of which ones might fall through.
-    int usesBefore = fallthrough.useCount;
-    node.thenStatement = visitStatement(node.thenStatement);
-    int usesAfterThen = fallthrough.useCount;
-    node.elseStatement = visitStatement(node.elseStatement);
-    bool thenHasFallthrough = (fallthrough.useCount > usesBefore);
-    bool elseHasFallthrough = (fallthrough.useCount > usesAfterThen);
-
-    // Determine which branch is most beneficial as 'then' branch.
-    const int THEN = 1;
-    const int NEITHER = 0;
-    const int ELSE = -1;
-    int bestThenBranch = NEITHER;
-    if (isFallthrough(node.thenStatement) &&
-        !isFallthrough(node.elseStatement)) {
-      // Put the empty statement in the 'else' branch.
-      // if (E) {} else {S} ==> if (!E) {S}
-      bestThenBranch = ELSE;
-    } else if (isFallthrough(node.elseStatement) &&
-        !isFallthrough(node.thenStatement)) {
-      // Keep the empty statement in the 'else' branch.
-      // if (E) {S} else {}
-      bestThenBranch = THEN;
-    } else if (thenHasFallthrough && !elseHasFallthrough) {
-      // Put abrupt termination in the 'then' branch to omit 'else'.
-      // if (E) {S1} else {S2; return v} ==> if (!E) {S2; return v}; S1
-      bestThenBranch = ELSE;
-    } else if (!thenHasFallthrough && elseHasFallthrough) {
-      // Keep abrupt termination in the 'then' branch to omit 'else'.
-      // if (E) {S1; return v}; S2
-      bestThenBranch = THEN;
-    } else if (isTerminator(node.elseStatement) &&
-        !isTerminator(node.thenStatement)) {
-      // Put early termination in the 'then' branch to reduce nesting depth.
-      // if (E) {S}; return v ==> if (!E) return v; S
-      bestThenBranch = ELSE;
-    } else if (isTerminator(node.thenStatement) &&
-        !isTerminator(node.elseStatement)) {
-      // Keep early termination in the 'then' branch to reduce nesting depth.
-      // if (E) {return v;} S
-      bestThenBranch = THEN;
-    }
-
-    // Swap branches if 'else' is better as 'then'
-    if (bestThenBranch == ELSE) {
-      node.condition = new Not(node.condition);
-      Statement tmp = node.thenStatement;
-      node.thenStatement = node.elseStatement;
-      node.elseStatement = tmp;
-    }
-
-    // If neither branch is better, eliminate a negation in the condition
-    // if (!E) S1 else S2
-    //   ==>
-    // if (E) S2 else S1
-    node.condition = makeCondition(node.condition, true,
-        liftNots: bestThenBranch == NEITHER);
-    if (bestThenBranch == NEITHER && node.condition is Not) {
-      node.condition = (node.condition as Not).operand;
-      Statement tmp = node.thenStatement;
-      node.thenStatement = node.elseStatement;
-      node.elseStatement = tmp;
-    }
-
-    return node;
-  }
-
-  Statement visitLabeledStatement(LabeledStatement node) {
-    fallthrough.push(node.next);
-    node.body = visitStatement(node.body);
-    fallthrough.pop();
-    node.next = visitStatement(node.next);
-    return node;
-  }
-
-  Statement visitWhileTrue(WhileTrue node) {
-    fallthrough.push(node);
-    node.body = visitStatement(node.body);
-    fallthrough.pop();
-    return node;
-  }
-
-  Statement visitFor(For node) {
-    fallthrough.push(node);
-    node.condition = makeCondition(node.condition, true, liftNots: false);
-    node.body = visitStatement(node.body);
-    fallthrough.pop();
-    node.next = visitStatement(node.next);
-    return node;
-  }
-
-  Statement visitBreak(Break node) {
-    if (isFallthroughBreak(node)) {
-      fallthrough.use();
-    }
-    return node;
-  }
-
-  Statement visitContinue(Continue node) {
-    if (isFallthroughContinue(node)) {
-      fallthrough.use();
-    }
-    return node;
-  }
-
-  Statement visitReturn(Return node) {
-    node.value = visitExpression(node.value);
-    if (isFallthroughReturn(node)) {
-      fallthrough.use();
-    }
-    return node;
-  }
-
-  Expression visitNot(Not node) {
-    return toBoolean(makeCondition(node.operand, false, liftNots: false));
-  }
-
-  /// True if the only possible falsy return value of [condition] is [value].
-  ///
-  /// If [value] is `null` or a truthy value, false is returned. This is to make
-  /// pattern matching more convenient.
-  bool matchesFalsyValue(Expression condition, values.ConstantValue value) {
-    if (value == null) return false;
-    // TODO(asgerf): Here we could really use some more type information,
-    //               this is just the best we can do at the moment.
-    return isBooleanValued(condition) && value.isFalse;
-  }
-
-  /// True if the only possible truthy return value of [condition] is [value].
-  ///
-  /// If [value] is `null` or a falsy value, false is returned. This is to make
-  /// pattern matching more convenient.
-  bool matchesTruthyValue(Expression condition, values.ConstantValue value) {
-    if (value == null) return false;
-    // TODO(asgerf): Again, more type information could really beef this up.
-    return isBooleanValued(condition) && value.isTrue;
-  }
-
-  values.ConstantValue getConstant(Expression exp) {
-    return exp is Constant ? exp.value : null;
-  }
-
-  Expression visitConditional(Conditional node) {
-    // node.condition will be visited after the then and else parts, because its
-    // polarity depends on what rewrite we use.
-    node.thenExpression = visitExpression(node.thenExpression);
-    node.elseExpression = visitExpression(node.elseExpression);
-
-    // In the following, we must take care not to eliminate or introduce a
-    // boolean conversion.
-
-    // x ? true : false --> !!x
-    if (isTrue(node.thenExpression) && isFalse(node.elseExpression)) {
-      return toBoolean(makeCondition(node.condition, true, liftNots: false));
-    }
-    // x ? false : true --> !x
-    if (isFalse(node.thenExpression) && isTrue(node.elseExpression)) {
-      return toBoolean(makeCondition(node.condition, false, liftNots: false));
-    }
-
-    // x ? y : false ==> x && y  (if x is truthy or false)
-    // x ? y : null  ==> x && y  (if x is truthy or null)
-    // x ? y : 0     ==> x && y  (if x is truthy or zero) (and so on...)
-    if (matchesFalsyValue(node.condition, getConstant(node.elseExpression))) {
-      return new LogicalOperator.and(
-          visitExpression(node.condition), node.thenExpression);
-    }
-    // x ? true : y ==> x || y  (if x is falsy or true)
-    // x ? 1    : y ==> x || y  (if x is falsy or one) (and so on...)
-    if (matchesTruthyValue(node.condition, getConstant(node.thenExpression))) {
-      return new LogicalOperator.or(
-          visitExpression(node.condition), node.elseExpression);
-    }
-    // x ? y : true ==> !x || y
-    if (isTrue(node.elseExpression)) {
-      return new LogicalOperator.or(
-          toBoolean(makeCondition(node.condition, false, liftNots: false)),
-          node.thenExpression);
-    }
-    // x ? false : y ==> !x && y
-    if (isFalse(node.thenExpression)) {
-      return new LogicalOperator.and(
-          toBoolean(makeCondition(node.condition, false, liftNots: false)),
-          node.elseExpression);
-    }
-
-    node.condition = makeCondition(node.condition, true);
-
-    // !x ? y : z ==> x ? z : y
-    if (node.condition is Not) {
-      node.condition = (node.condition as Not).operand;
-      Expression tmp = node.thenExpression;
-      node.thenExpression = node.elseExpression;
-      node.elseExpression = tmp;
-    }
-
-    // x ? y : x ==> x && y
-    if (isSameVariable(node.condition, node.elseExpression)) {
-      destroyVariableUse(node.elseExpression);
-      return new LogicalOperator.and(node.condition, node.thenExpression);
-    }
-    // x ? x : y ==> x || y
-    if (isSameVariable(node.condition, node.thenExpression)) {
-      destroyVariableUse(node.thenExpression);
-      return new LogicalOperator.or(node.condition, node.elseExpression);
-    }
-
-    return node;
-  }
-
-  Expression visitLogicalOperator(LogicalOperator node) {
-    node.left = visitExpression(node.left);
-    node.right = visitExpression(node.right);
-    return node;
-  }
-
-  /// True if the given expression is known to evaluate to a boolean.
-  /// This will not recursively traverse [Conditional] expressions, but if
-  /// applied to the result of [visitExpression] conditionals will have been
-  /// rewritten anyway.
-  bool isBooleanValued(Expression e) {
-    return isTrue(e) ||
-        isFalse(e) ||
-        e is Not ||
-        e is LogicalOperator && isBooleanValuedLogicalOperator(e) ||
-        e is ApplyBuiltinOperator && operatorReturnsBool(e.operator) ||
-        e is TypeOperator && isBooleanValuedTypeOperator(e);
-  }
-
-  bool isBooleanValuedLogicalOperator(LogicalOperator e) {
-    return isBooleanValued(e.left) && isBooleanValued(e.right);
-  }
-
-  /// True if the given operator always returns `true` or `false`.
-  bool operatorReturnsBool(BuiltinOperator operator) {
-    switch (operator) {
-      case BuiltinOperator.StrictEq:
-      case BuiltinOperator.StrictNeq:
-      case BuiltinOperator.LooseEq:
-      case BuiltinOperator.LooseNeq:
-      case BuiltinOperator.NumLt:
-      case BuiltinOperator.NumLe:
-      case BuiltinOperator.NumGt:
-      case BuiltinOperator.NumGe:
-      case BuiltinOperator.IsNumber:
-      case BuiltinOperator.IsNotNumber:
-      case BuiltinOperator.IsFloor:
-      case BuiltinOperator.IsInteger:
-      case BuiltinOperator.IsNotInteger:
-      case BuiltinOperator.Identical:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  bool isBooleanValuedTypeOperator(TypeOperator e) {
-    return e.isTypeTest;
-  }
-
-  BuiltinOperator negateBuiltin(BuiltinOperator operator) {
-    switch (operator) {
-      case BuiltinOperator.StrictEq:
-        return BuiltinOperator.StrictNeq;
-      case BuiltinOperator.StrictNeq:
-        return BuiltinOperator.StrictEq;
-      case BuiltinOperator.LooseEq:
-        return BuiltinOperator.LooseNeq;
-      case BuiltinOperator.LooseNeq:
-        return BuiltinOperator.LooseEq;
-      case BuiltinOperator.IsNumber:
-        return BuiltinOperator.IsNotNumber;
-      case BuiltinOperator.IsNotNumber:
-        return BuiltinOperator.IsNumber;
-      case BuiltinOperator.IsInteger:
-        return BuiltinOperator.IsNotInteger;
-      case BuiltinOperator.IsNotInteger:
-        return BuiltinOperator.IsInteger;
-      case BuiltinOperator.IsUnsigned32BitInteger:
-        return BuiltinOperator.IsNotUnsigned32BitInteger;
-      case BuiltinOperator.IsNotUnsigned32BitInteger:
-        return BuiltinOperator.IsUnsigned32BitInteger;
-
-      // Because of NaN, these do not have a negated form.
-      case BuiltinOperator.NumLt:
-      case BuiltinOperator.NumLe:
-      case BuiltinOperator.NumGt:
-      case BuiltinOperator.NumGe:
-        return null;
-
-      default:
-        return null;
-    }
-  }
-
-  /// Forces a boolean conversion of the given expression.
-  Expression toBoolean(Expression e) {
-    if (isBooleanValued(e))
-      return e;
-    else
-      return new Not(new Not(e));
-  }
-
-  /// Creates an equivalent boolean expression. The expression must occur in a
-  /// context where its result is immediately subject to boolean conversion.
-  /// If [polarity] if false, the negated condition will be created instead.
-  /// If [liftNots] is true (default) then Not expressions will be lifted toward
-  /// the root of the condition so they can be eliminated by the caller.
-  Expression makeCondition(Expression e, bool polarity, {bool liftNots: true}) {
-    if (e is Not) {
-      // !!E ==> E
-      return makeCondition(e.operand, !polarity, liftNots: liftNots);
-    }
-    if (e is LogicalOperator) {
-      // If polarity=false, then apply the rewrite !(x && y) ==> !x || !y
-      e.left = makeCondition(e.left, polarity);
-      e.right = makeCondition(e.right, polarity);
-      if (!polarity) {
-        e.isAnd = !e.isAnd;
-      }
-      // !x && !y ==> !(x || y)  (only if lifting nots)
-      if (e.left is Not && e.right is Not && liftNots) {
-        e.left = (e.left as Not).operand;
-        e.right = (e.right as Not).operand;
-        e.isAnd = !e.isAnd;
-        return new Not(e);
-      }
-      return e;
-    }
-    if (e is ApplyBuiltinOperator && polarity == false) {
-      BuiltinOperator negated = negateBuiltin(e.operator);
-      if (negated != null) {
-        e.operator = negated;
-        return visitExpression(e);
-      } else {
-        return new Not(visitExpression(e));
-      }
-    }
-    if (e is Conditional) {
-      // Handle polarity by: !(x ? y : z) ==> x ? !y : !z
-      // Rewrite individual branches now. The condition will be rewritten
-      // when we know what polarity to use (depends on which rewrite is used).
-      e.thenExpression = makeCondition(e.thenExpression, polarity);
-      e.elseExpression = makeCondition(e.elseExpression, polarity);
-
-      // x ? true : false ==> x
-      if (isTrue(e.thenExpression) && isFalse(e.elseExpression)) {
-        return makeCondition(e.condition, true, liftNots: liftNots);
-      }
-      // x ? false : true ==> !x
-      if (isFalse(e.thenExpression) && isTrue(e.elseExpression)) {
-        return makeCondition(e.condition, false, liftNots: liftNots);
-      }
-      // x ? true : y  ==> x || y
-      if (isTrue(e.thenExpression)) {
-        return makeOr(makeCondition(e.condition, true), e.elseExpression,
-            liftNots: liftNots);
-      }
-      // x ? false : y  ==> !x && y
-      if (isFalse(e.thenExpression)) {
-        return makeAnd(makeCondition(e.condition, false), e.elseExpression,
-            liftNots: liftNots);
-      }
-      // x ? y : true  ==> !x || y
-      if (isTrue(e.elseExpression)) {
-        return makeOr(makeCondition(e.condition, false), e.thenExpression,
-            liftNots: liftNots);
-      }
-      // x ? y : false  ==> x && y
-      if (isFalse(e.elseExpression)) {
-        return makeAnd(makeCondition(e.condition, true), e.thenExpression,
-            liftNots: liftNots);
-      }
-
-      e.condition = makeCondition(e.condition, true);
-
-      // !x ? y : z ==> x ? z : y
-      if (e.condition is Not) {
-        e.condition = (e.condition as Not).operand;
-        Expression tmp = e.thenExpression;
-        e.thenExpression = e.elseExpression;
-        e.elseExpression = tmp;
-      }
-      // x ? !y : !z ==> !(x ? y : z)  (only if lifting nots)
-      if (e.thenExpression is Not && e.elseExpression is Not && liftNots) {
-        e.thenExpression = (e.thenExpression as Not).operand;
-        e.elseExpression = (e.elseExpression as Not).operand;
-        return new Not(e);
-      }
-
-      // x ? y : x ==> x && y
-      if (isSameVariable(e.condition, e.elseExpression)) {
-        destroyVariableUse(e.elseExpression);
-        return new LogicalOperator.and(e.condition, e.thenExpression);
-      }
-      // x ? x : y ==> x || y
-      if (isSameVariable(e.condition, e.thenExpression)) {
-        destroyVariableUse(e.thenExpression);
-        return new LogicalOperator.or(e.condition, e.elseExpression);
-      }
-
-      return e;
-    }
-    if (e is Constant && e.value.isBool) {
-      // !true ==> false
-      if (!polarity) {
-        values.BoolConstantValue value = e.value;
-        return new Constant.bool(value.negate());
-      }
-      return e;
-    }
-    e = visitExpression(e);
-    return polarity ? e : new Not(e);
-  }
-
-  bool isNull(Expression e) {
-    return e is Constant && e.value.isNull;
-  }
-
-  bool isTrue(Expression e) {
-    return e is Constant && e.value.isTrue;
-  }
-
-  bool isFalse(Expression e) {
-    return e is Constant && e.value.isFalse;
-  }
-
-  Expression makeAnd(Expression e1, Expression e2, {bool liftNots: true}) {
-    if (e1 is Not && e2 is Not && liftNots) {
-      return new Not(new LogicalOperator.or(e1.operand, e2.operand));
-    } else {
-      return new LogicalOperator.and(e1, e2);
-    }
-  }
-
-  Expression makeOr(Expression e1, Expression e2, {bool liftNots: true}) {
-    if (e1 is Not && e2 is Not && liftNots) {
-      return new Not(new LogicalOperator.and(e1.operand, e2.operand));
-    } else {
-      return new LogicalOperator.or(e1, e2);
-    }
-  }
-
-  /// 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) {
-    if (e1 is VariableUse) {
-      return e2 is VariableUse && e1.variable == e2.variable;
-    } else if (e1 is Assign) {
-      return e2 is VariableUse && e1.variable == e2.variable;
-    }
-    return false;
-  }
-
-  void destroyVariableUse(VariableUse node) {
-    --node.variable.readCount;
-  }
-}
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
deleted file mode 100644
index e57c938..0000000
--- a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
+++ /dev/null
@@ -1,195 +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 tree_ir.optimization.loop_rewriter;
-
-import 'optimization.dart' show Pass;
-import '../tree_ir_nodes.dart';
-
-/// Rewrites [WhileTrue] statements into [For] statements.
-///
-/// Before this phase, loops usually contain a lot of "exit code", that is,
-/// code that happens at a point where a [Continue] can no longer be reached,
-/// and is therefore not really part of the loop.
-/// Exit code is moved down after the loop using the following rewrites rules:
-///
-/// EXTRACT LABELED STATEMENT:
-///
-///   L:
-///   while (true) {
-///     L2: {
-///       S1  (has references to L)
-///     }
-///     S2    (has no references to L)
-///   }
-///
-///     ==>
-///
-///   L2: {
-///     L: while (true) S1
-///   }
-///   S2
-///
-/// INTRODUCE CONDITIONAL LOOP:
-///
-///   L:
-///   while (true) {
-///     if (E) {
-///       S1  (has references to L)
-///     } else {
-///       S2  (has no references to L)
-///     }
-///   }
-///     ==>
-///   L:
-///   while (E) {
-///     S1
-///   };
-///   S2
-///
-/// A similar transformation is used when S2 occurs in the 'then' position.
-///
-/// 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 ]
-///   }
-///     ==>
-///   L:
-///   for (; condition; updates, x = E) {
-///     S [ continue L ]
-///   }
-///
-/// 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.
-class LoopRewriter extends RecursiveTransformer implements Pass {
-  String get passName => 'Loop rewriter';
-
-  Set<Label> usedContinueLabels = new Set<Label>();
-
-  /// Maps loop labels to a list, if that loop can accept update expressions.
-  /// The list will then be populated while traversing the body of that loop.
-  /// If a loop is not in the map, update expressions cannot be hoisted there.
-  Map<Label, List<Expression>> updateExpressions = <Label, List<Expression>>{};
-
-  void rewrite(FunctionDefinition root) {
-    root.body = visitStatement(root.body);
-  }
-
-  Statement visitContinue(Continue node) {
-    usedContinueLabels.add(node.target);
-    return node;
-  }
-
-  Statement visitWhileTrue(WhileTrue node) {
-    assert(!usedContinueLabels.contains(node.label));
-
-    // Pull labeled statements outside the loop when possible.
-    // [head] and [tail] are the first and last labeled statements that were
-    // pulled out, and null when none have been pulled out.
-    LabeledStatement head, tail;
-    while (node.body is LabeledStatement) {
-      LabeledStatement inner = node.body;
-      inner.next = visitStatement(inner.next);
-      bool nextHasContinue = usedContinueLabels.remove(node.label);
-      if (nextHasContinue) break;
-      node.body = inner.body;
-      inner.body = node;
-      if (head == null) {
-        head = tail = inner;
-      } else {
-        tail.body = inner;
-        tail = inner;
-      }
-    }
-
-    // Rewrite while(true) to for(; condition; updates).
-    Statement loop = node;
-    if (node.body is If) {
-      If body = node.body;
-      updateExpressions[node.label] = <Expression>[];
-      body.thenStatement = visitStatement(body.thenStatement);
-      bool thenHasContinue = usedContinueLabels.remove(node.label);
-      body.elseStatement = visitStatement(body.elseStatement);
-      bool elseHasContinue = usedContinueLabels.remove(node.label);
-      if (thenHasContinue && !elseHasContinue) {
-        node.label.binding = null; // Prepare to rebind the label.
-        loop = new For(
-            node.label,
-            body.condition,
-            updateExpressions[node.label],
-            body.thenStatement,
-            body.elseStatement);
-      } else if (!thenHasContinue && elseHasContinue) {
-        node.label.binding = null;
-        loop = new For(
-            node.label,
-            new Not(body.condition),
-            updateExpressions[node.label],
-            body.elseStatement,
-            body.thenStatement);
-      }
-    } else if (node.body is LabeledStatement) {
-      // If the body is a labeled statement, its .next has already been visited.
-      LabeledStatement body = node.body;
-      body.body = visitStatement(body.body);
-      usedContinueLabels.remove(node.label);
-    } else {
-      node.body = visitStatement(node.body);
-      usedContinueLabels.remove(node.label);
-    }
-
-    if (head == null) return loop;
-    tail.body = loop;
-    return head;
-  }
-
-  Statement visitExpressionStatement(ExpressionStatement node) {
-    if (updateExpressions.isEmpty) {
-      // Avoid allocating a list if there is no loop.
-      return super.visitExpressionStatement(node);
-    }
-    List<ExpressionStatement> statements = <ExpressionStatement>[];
-    while (node.next is ExpressionStatement) {
-      statements.add(node);
-      node = node.next;
-    }
-    statements.add(node);
-    Statement next = visitStatement(node.next);
-    if (next is Continue && next.target.useCount == 1) {
-      List<Expression> updates = updateExpressions[next.target];
-      if (updates != null) {
-        // Pull expressions before the continue into the for loop update.
-        // As a heuristic, we only pull in assignment expressions.
-        // Determine the index of the first assignment to pull in.
-        int index = statements.length;
-        while (index > 0 && statements[index - 1].expression is Assign) {
-          --index;
-        }
-        for (ExpressionStatement stmt in statements.skip(index)) {
-          updates.add(stmt.expression);
-        }
-        if (index > 0) {
-          statements[index - 1].next = next;
-          return statements.first;
-        } else {
-          return next;
-        }
-      }
-    }
-    // The expression statements could not be pulled into a loop update.
-    node.next = next;
-    return statements.first;
-  }
-}
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart b/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
deleted file mode 100644
index 130e5e3..0000000
--- a/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-library tree_ir.optimization;
-
-import '../tree_ir_nodes.dart';
-
-export 'statement_rewriter.dart' show StatementRewriter;
-export 'variable_merger.dart' show VariableMerger;
-export 'loop_rewriter.dart' show LoopRewriter;
-export 'logical_rewriter.dart' show LogicalRewriter;
-export 'pull_into_initializers.dart' show PullIntoInitializers;
-
-/// An optimization pass over the Tree IR.
-abstract class Pass {
-  /// Applies optimizations to root, rewriting it in the process.
-  void rewrite(FunctionDefinition root);
-
-  String get passName;
-}
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
deleted file mode 100644
index 931368d..0000000
--- a/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart
+++ /dev/null
@@ -1,378 +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 tree_ir.optimization.pull_into_initializers;
-
-import 'optimization.dart' show Pass;
-import '../tree_ir_nodes.dart';
-
-/// Where a variable has been assigned.
-enum AssignArea {
-  /// The variable is only assigned in the initializer block.
-  Initializer,
-
-  // The variable has at least one assignment outside the initializer block.
-  Anywhere,
-}
-
-/// Pulls assignment expressions to the top of the function body so they can be
-/// translated into declaration-site variable initializaters.
-///
-/// This reverts the assignment expression propagation performed by
-/// [StatementRewriter] in cases where it not beneficial.
-///
-/// EXAMPLE:
-///
-///     var x = foo(),
-///         y = bar(x);
-///
-///     ==> [StatementRewriter]
-///
-///     var x,
-///         y = bar(x = foo());
-///
-///     ==> [PullIntoInitializers] restores the initializer for x
-///
-///     var x = foo(),
-///         y = bar(x);
-///
-///
-/// Sometimes the assignment propagation will trigger another optimization
-/// in the [StatementRewriter] which then prevents [PullIntoInitializers] from
-/// restoring the initializer. This is acceptable, since most optimizations
-/// at that level are better than restoring an initializer.
-///
-/// EXAMPLE:
-///
-///     var x = foo(),
-///         y = bar();
-///     baz(x, y, y);
-///
-///     ==> [StatementRewriter]
-///
-///     var y;
-///     baz(foo(), y = bar(), y);
-///
-/// [PullIntoInitializers] cannot pull `y` into an initializer because
-/// the impure expressions `foo()` and `bar()` would then be swapped.
-///
-class PullIntoInitializers extends RecursiveTransformer implements Pass {
-  String get passName => 'Pull into initializers';
-
-  /// Denotes where each variable is currently assigned.
-  ///
-  /// Variables without assignments are absent from the map.
-  Map<Variable, AssignArea> assignArea = <Variable, AssignArea>{};
-
-  /// The fragment between [first] and [last] holds the statements
-  /// we pulled into the initializer block.
-  ///
-  /// The "initializer block" is a sequence of [ExpressionStatement]s with
-  /// [Assign]s that we create in the beginning of the body, with the intent
-  /// that code generation will convert them to variable initializers.
-  ///
-  /// The block is empty when both are `null`.
-  Statement first, last;
-
-  /// The number of impure expressions separating the current program point
-  /// from the initializer block.
-  ///
-  /// A pure expression is an expression that cannot throw, diverge, have side
-  /// effects, or depend on mutable state.
-  ///
-  /// As a special case, variable uses are also considered pure when their only
-  /// reaching definition is an assignment in the initializer block.
-  int impureCounter = 0;
-
-  /// The number of assignments separating the current program point from the
-  /// initializer block. Note that these are also counted as impure expressions.
-  ///
-  /// Assignments are given special treatment because hoisting an assignment
-  /// may change the reaching definitions of a variable use. The analysis may
-  /// already have considered such a use to be pure, and we must then ensure
-  /// that it remains pure.
-  int assignCounter = 0;
-
-  /// The number of branch points separating the current program point from
-  /// the initializer block.
-  ///
-  /// We do not pull expressions out of branches, not even pure ones, but
-  /// we sometimes want to traverse branches to check if they are pure.
-  int branchCounter = 0;
-
-  /// Appends a statement to the initializer block.
-  void append(Statement node) {
-    if (first == null) {
-      first = last = node;
-    } else {
-      last.next = node;
-      last = node;
-    }
-  }
-
-  void rewrite(FunctionDefinition node) {
-    for (Variable param in node.parameters) {
-      assignArea[param] = AssignArea.Initializer;
-    }
-    Statement body = visitStatement(node.body);
-    append(body);
-    assert(first != null);
-    node.body = first;
-  }
-
-  void destroyVariableUse(VariableUse node) {
-    --node.variable.readCount;
-  }
-
-  Statement visitExpressionStatement(ExpressionStatement node) {
-    node.expression = visitExpression(node.expression);
-    if (node.expression is VariableUse) {
-      // The entire expression was pulled into an initializer.
-      // This can happen when the expression was an assignment that was
-      // pulled into the initializer block and replaced by a variable use.
-      // Discard the statement and try to pull in more initializers from
-      // the next statement.
-      destroyVariableUse(node.expression);
-      return visitStatement(node.next);
-    }
-    node.next = visitStatement(node.next);
-    return node;
-  }
-
-  Statement visitIf(If node) {
-    node.condition = visitExpression(node.condition);
-    // We could traverse the branches and pull out pure expressions, but
-    // some pure expressions might be too slow for this to pay off.
-    // A CPS transform should decide when things get hoisted out of branches.
-    return node;
-  }
-
-  Statement visitLabeledStatement(LabeledStatement node) {
-    node.body = visitStatement(node.body);
-    // The 'next' statement might not always get reached, so do not try to
-    // pull expressions up from there.
-    return node;
-  }
-
-  Statement visitWhileTrue(WhileTrue node) {
-    return node;
-  }
-
-  Statement visitFor(For node) {
-    return node;
-  }
-
-  Statement visitTry(Try node) {
-    return node;
-  }
-
-  Statement visitReceiverCheck(ReceiverCheck 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;
-
-    // Remember the number of impure expression seen yet, so we can tell if
-    // there are any impure expressions on the right-hand side.
-    int impureBefore = impureCounter;
-    int assignmentsBefore = assignCounter;
-    node.value = visitExpression(node.value);
-    bool rightHandSideIsImpure = (impureCounter > impureBefore);
-    bool rightHandSideHasAssign = (assignCounter > assignmentsBefore);
-
-    bool alreadyAssigned = assignArea.containsKey(node.variable);
-
-    // An impure right-hand side cannot be pulled out of impure context.
-    // Expressions should not be pulled out of branches.
-    // If this is not the first assignment, it cannot be hoisted.
-    // If the right-hand side contains an unhoistable assignment, this
-    // assignment cannot be hoisted either.
-    if (inImpureContext && rightHandSideIsImpure ||
-        inBranch ||
-        alreadyAssigned ||
-        rightHandSideHasAssign) {
-      assignArea[node.variable] = AssignArea.Anywhere;
-      ++impureCounter;
-      ++assignCounter;
-      return node;
-    }
-
-    // Pull the assignment into the initializer. Any side-effects in the
-    // right-hand side will move into the initializer block, so reset the
-    // impure counter.
-    assignArea[node.variable] = AssignArea.Initializer;
-    impureCounter = impureBefore;
-    append(new ExpressionStatement(node, null));
-    return new VariableUse(node.variable);
-  }
-
-  Expression visitVariableUse(VariableUse node) {
-    if (assignArea[node.variable] == AssignArea.Anywhere) {
-      // There is a reaching definition outside the initializer block.
-      ++impureCounter;
-    }
-    return node;
-  }
-
-  void rewriteList(List<Expression> nodes) {
-    for (int i = 0; i < nodes.length; ++i) {
-      nodes[i] = visitExpression(nodes[i]);
-    }
-  }
-
-  Expression visitInvokeMethod(InvokeMethod node) {
-    node.receiver = visitExpression(node.receiver);
-    if (!node.receiverIsNotNull) {
-      // If the receiver is null, the method lookup throws.
-      ++impureCounter;
-    }
-    rewriteList(node.arguments);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitInvokeStatic(InvokeStatic node) {
-    super.visitInvokeStatic(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    super.visitInvokeMethodDirectly(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitInvokeConstructor(InvokeConstructor node) {
-    super.visitInvokeConstructor(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitOneShotInterceptor(OneShotInterceptor node) {
-    super.visitOneShotInterceptor(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitAwait(Await node) {
-    super.visitAwait(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitConditional(Conditional node) {
-    node.condition = visitExpression(node.condition);
-    // Visit the branches to detect impure subexpressions, but do not pull
-    // expressions out of the branch.
-    ++branchCounter;
-    node.thenExpression = visitExpression(node.thenExpression);
-    node.elseExpression = visitExpression(node.elseExpression);
-    --branchCounter;
-    return node;
-  }
-
-  Expression visitLogicalOperator(LogicalOperator node) {
-    node.left = visitExpression(node.left);
-    ++branchCounter;
-    node.right = visitExpression(node.right);
-    --branchCounter;
-    return node;
-  }
-
-  Expression visitLiteralList(LiteralList node) {
-    super.visitLiteralList(node);
-    if (node.type != null) {
-      ++impureCounter; // Type casts can throw.
-    }
-    return node;
-  }
-
-  Expression visitTypeOperator(TypeOperator node) {
-    super.visitTypeOperator(node);
-    if (!node.isTypeTest) {
-      ++impureCounter; // Type casts can throw.
-    }
-    return node;
-  }
-
-  Expression visitGetField(GetField node) {
-    super.visitGetField(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitSetField(SetField node) {
-    super.visitSetField(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitGetStatic(GetStatic node) {
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitSetStatic(SetStatic node) {
-    super.visitSetStatic(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitGetTypeTestProperty(GetTypeTestProperty node) {
-    super.visitGetTypeTestProperty(node);
-    return node;
-  }
-
-  Expression visitGetLength(GetLength node) {
-    super.visitGetLength(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitGetIndex(GetIndex node) {
-    super.visitGetIndex(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitSetIndex(SetIndex node) {
-    super.visitSetIndex(node);
-    ++impureCounter;
-    return node;
-  }
-
-  Expression visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    rewriteList(node.arguments);
-    return node;
-  }
-
-  Expression visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    node.receiver = visitExpression(node.receiver);
-    if (!node.receiverIsNotNull) {
-      // If the receiver is null, the method lookup throws.
-      ++impureCounter;
-    }
-    rewriteList(node.arguments);
-    ++impureCounter;
-    return node;
-  }
-
-  @override
-  Expression visitForeignExpression(ForeignExpression node) {
-    rewriteList(node.arguments);
-    if (node.nativeBehavior.sideEffects.hasSideEffects()) {
-      ++impureCounter;
-    }
-    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
deleted file mode 100644
index 5db310a..0000000
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ /dev/null
@@ -1,1391 +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 tree_ir.optimization.statement_rewriter;
-
-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.
- *
- * In addition to the general IR constraints (see [CheckTreeIntegrity]),
- * the input is assumed to satisfy the following criteria:
- *
- * All expressions other than those nested in [Assign] or [ExpressionStatement]
- * must be simple. A [VariableUse] and [This] is a simple expression.
- * The right-hand of an [Assign] may not be an [Assign].
- *
- * Moreover, every variable must either be an SSA variable or a mutable
- * variable, and must satisfy the corresponding criteria:
- *
- * SSA VARIABLE:
- * An SSA variable must have a unique definition site, which is either an
- * assignment or label. In case of a label, its target must act as the unique
- * reaching definition of that variable at all uses of the variable and at
- * all other label targets where the variable is in scope.
- *
- * (The second criterion is to ensure that we can move a use of an SSA variable
- * across a label without changing its reaching definition).
- *
- * MUTABLE VARIABLE:
- * Uses of mutable variables are considered complex expressions, and hence must
- * not be nested in other expressions. Assignments to mutable variables must
- * have simple right-hand sides.
- *
- * ----
- *
- * This pass performs the following transformations on the tree:
- * - Assignment inlining
- * - Assignment expression propagation
- * - If-to-conditional conversion
- * - Flatten nested ifs
- * - Break inlining
- * - Redirect breaks
- *
- * The above transformations all eliminate statements from the tree, and may
- * introduce redexes of each other.
- *
- *
- * ASSIGNMENT INLINING:
- * Single-use definitions are inlined at their use site when possible.
- * For example:
- *
- *   { v0 = foo(); return v0; }
- *     ==>
- *   return foo()
- *
- * After translating out of CPS, all intermediate values are bound by [Assign].
- * This transformation propagates such definitions to their uses when it is
- * safe and profitable.  Bindings are processed "on demand" when their uses are
- * seen, but are only processed once to keep this transformation linear in
- * the size of the tree.
- *
- * The transformation builds an environment containing [Assign] bindings that
- * are in scope.  These bindings have yet-untranslated definitions.  When a use
- * is encountered the transformation determines if it is safe and profitable
- * to propagate the definition to its use.  If so, it is removed from the
- * environment and the definition is recursively processed (in the
- * new environment at the use site) before being propagated.
- *
- * See [visitVariableUse] for the implementation of the heuristic for
- * propagating a definition.
- *
- *
- * ASSIGNMENT EXPRESSION PROPAGATION:
- * Definitions with multiple uses are propagated to their first use site
- * when possible. For example:
- *
- *     { v0 = foo(); bar(v0); return v0; }
- *       ==>
- *     { bar(v0 = foo()); return v0; }
- *
- * Note that the [RestoreInitializers] phase will later undo this rewrite
- * in cases where it prevents an assignment from being pulled into an
- * initializer.
- *
- *
- * IF-TO-CONDITIONAL CONVERSION:
- * If-statement are converted to conditional expressions when possible.
- * For example:
- *
- *   if (v0) { v1 = foo(); break L } else { v1 = bar(); break L }
- *     ==>
- *   { v1 = v0 ? foo() : bar(); break L }
- *
- * This can lead to inlining of L, which in turn can lead to further propagation
- * of the variable v1.
- *
- * See [visitIf].
- *
- *
- * FLATTEN NESTED IFS:
- * An if inside an if is converted to an if with a logical operator.
- * For example:
- *
- *   if (E1) { if (E2) {S} else break L } else break L
- *     ==>
- *   if (E1 && E2) {S} else break L
- *
- * This may lead to inlining of L.
- *
- *
- * BREAK INLINING:
- * Single-use labels are inlined at [Break] statements.
- * For example:
- *
- *   L0: { v0 = foo(); break L0 }; return v0;
- *     ==>
- *   v0 = foo(); return v0;
- *
- * This can lead to propagation of v0.
- *
- * See [visitBreak] and [visitLabeledStatement].
- *
- *
- * REDIRECT BREAKS:
- * Labeled statements whose next is a break become flattened and all breaks
- * to their label are redirected.
- * For example, where 'jump' is either break or continue:
- *
- *   L0: {... break L0 ...}; jump L1
- *     ==>
- *   {... jump L1 ...}
- *
- * This may trigger a flattening of nested ifs in case the eliminated label
- * separated two ifs.
- */
-class StatementRewriter extends Transformer implements Pass {
-  String get passName => 'Statement rewriter';
-
-  @override
-  void rewrite(FunctionDefinition node) {
-    node.parameters.forEach(pushDominatingAssignment);
-    node.body = visitStatement(node.body);
-    node.parameters.forEach(popDominatingAssignment);
-  }
-
-  /// The most recently evaluated impure expressions, with the most recent
-  /// expression being last.
-  ///
-  /// Most importantly, this contains [Assign] expressions that we attempt to
-  /// inline at their use site. It also contains other impure expressions that
-  /// we can propagate to a variable use if they are known to return the value
-  /// of that variable.
-  ///
-  /// Assignments with constant right-hand sides (see [isEffectivelyConstant])
-  /// are not considered impure and are put in [constantEnvironment] instead.
-  ///
-  /// Except for [Conditional]s, expressions in the environment have
-  /// not been processed, and all their subexpressions must therefore be
-  /// variables uses.
-  List<Expression> environment = <Expression>[];
-
-  /// Binding environment for variables that are assigned to effectively
-  /// constant expressions (see [isEffectivelyConstant]).
-  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'.
-  Map<Label, Jump> labelRedirects = <Label, Jump>{};
-
-  /// Number of uses of the given variable that are still unseen.
-  /// Used to detect the first use of a variable (since we do backwards
-  /// traversal, the first use is the last one seen).
-  Map<Variable, int> unseenUses = <Variable, int>{};
-
-  /// Number of assignments to a given variable that dominate the current
-  /// position.
-  ///
-  /// Pure expressions will not be inlined if it uses a variable with more than
-  /// one dominating assignment, because the reaching definition of the used
-  /// variable might have changed since it was put in the environment.
-  final Map<Variable, int> dominatingAssignments = <Variable, int>{};
-
-  /// A set of labels that can be safely inlined at their use.
-  ///
-  /// The successor statements for labeled statements that have only one break
-  /// from them are normally rewritten inline at the site of the break.  This
-  /// is not safe if the code would be moved inside the scope of an exception
-  /// 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) {
-    Jump newJump = labelRedirects[jump.target];
-    return newJump != null ? newJump : jump;
-  }
-
-  void inEmptyEnvironment(void action(), {bool keepConstants: true}) {
-    List oldEnvironment = environment;
-    Map oldConstantEnvironment = constantEnvironment;
-    environment = <Expression>[];
-    if (!keepConstants) {
-      constantEnvironment = <Variable, Expression>{};
-    }
-    action();
-    assert(environment.isEmpty);
-    environment = oldEnvironment;
-    if (!keepConstants) {
-      constantEnvironment = oldConstantEnvironment;
-    }
-  }
-
-  /// Left-hand side of the given assignment, or `null` if not an assignment.
-  Variable getLeftHand(Expression e) {
-    return e is Assign ? e.variable : null;
-  }
-
-  /// If the given expression always returns the value of one of its
-  /// subexpressions, returns that subexpression, otherwise `null`.
-  Expression getValueSubexpression(Expression e) {
-    if (e is SetField) return e.value;
-    return null;
-  }
-
-  /// 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 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) {
-    bool wasFound = false;
-    VariableUseVisitor.visit(node, (VariableUse use) {
-      if (dominatingAssignments[use.variable] > 1) {
-        wasFound = true;
-      }
-    });
-    return wasFound;
-  }
-
-  void pushDominatingAssignment(Variable variable) {
-    if (variable != null) {
-      dominatingAssignments.putIfAbsent(variable, () => 0);
-      ++dominatingAssignments[variable];
-    }
-  }
-
-  void popDominatingAssignment(Variable variable) {
-    if (variable != null) {
-      --dominatingAssignments[variable];
-    }
-  }
-
-  @override
-  Expression visitVariableUse(VariableUse node) {
-    // Count of number of unseen uses remaining.
-    unseenUses.putIfAbsent(node.variable, () => node.variable.readCount);
-    --unseenUses[node.variable];
-
-    // We traverse the tree right-to-left, so when we have seen all uses,
-    // 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.
-    Expression constant = constantEnvironment[node.variable];
-    if (constant != null && !hasUnsafeVariableUse(constant)) {
-      --node.variable.readCount;
-      return visitExpression(constant);
-    }
-
-    // Try to propagate another expression into this variable use.
-    if (!environment.isEmpty) {
-      Expression binding = environment.last;
-
-      // Is this variable assigned by the most recently evaluated impure
-      // expression?
-      //
-      // If so, propagate the assignment, e.g:
-      //
-      //     { x = foo(); bar(x, x) } ==> bar(x = foo(), x)
-      //
-      // We must ensure that no other uses separate this use from the
-      // assignment. We therefore only propagate assignments into the first use.
-      //
-      // Note that if this is only use, `visitAssign` will then remove the
-      // redundant assignment.
-      if (getLeftHand(binding) == node.variable && isFirstUse) {
-        environment.removeLast();
-        --node.variable.readCount;
-        return visitExpression(binding);
-      }
-
-      // Is the most recently evaluated impure expression known to have the
-      // value of this variable?
-      //
-      // If so, we can replace this use with the impure expression, e.g:
-      //
-      //     { E.foo = x; bar(x) } ==> bar(E.foo = x)
-      //
-      if (isRhsPropagationAllowed &&
-          getRightHandVariable(binding) == node.variable) {
-        environment.removeLast();
-        --node.variable.readCount;
-        return visitExpression(binding);
-      }
-    }
-
-    // If the definition could not be propagated, leave the variable use.
-    return node;
-  }
-
-  /// True if [exp] contains a use of a variable that was assigned to by the
-  /// most recently evaluated impure expression (constant assignments are not
-  /// considered impure).
-  ///
-  /// This implies that the assignment can be propagated into this use unless
-  /// the use is moved further away.
-  ///
-  /// In this case, we will refrain from moving [exp] across other impure
-  /// expressions, even when this is safe, because doing so would immediately
-  /// prevent the previous expression from propagating, canceling out the
-  /// benefit we might otherwise gain from propagating [exp].
-  ///
-  /// [exp] must be an unprocessed expression, i.e. either a [Conditional] or
-  /// an expression whose subexpressions are all variable uses.
-  bool usesRecentlyAssignedVariable(Expression exp) {
-    if (environment.isEmpty) return false;
-    Variable variable = getLeftHand(environment.last);
-    if (variable == null) return false;
-    IsVariableUsedVisitor visitor = new IsVariableUsedVisitor(variable);
-    visitor.visitExpression(exp);
-    return visitor.wasFound;
-  }
-
-  /// Returns true if [exp] has no side effects and has a constant value within
-  /// any given activation of the enclosing method.
-  bool isEffectivelyConstant(Expression exp) {
-    // TODO(asgerf): Can be made more aggressive e.g. by checking conditional
-    // expressions recursively. Determine if that is a valuable optimization
-    // and/or if it is better handled at the CPS level.
-    return exp is Constant ||
-        exp is This ||
-        exp is CreateInvocationMirror ||
-        exp is CreateInstance ||
-        exp is CreateBox ||
-        exp is TypeExpression ||
-        exp is GetStatic && exp.element.isFunction ||
-        exp is Interceptor ||
-        exp is ApplyBuiltinOperator ||
-        exp is VariableUse && constantEnvironment.containsKey(exp.variable);
-  }
-
-  /// True if [node] is an assignment that can be propagated as a constant.
-  bool isEffectivelyConstantAssignment(Expression node) {
-    return node is Assign &&
-        node.variable.writeCount == 1 &&
-        isEffectivelyConstant(node.value);
-  }
-
-  Statement visitExpressionStatement(ExpressionStatement inputNode) {
-    // Analyze chains of expression statements.
-    // To avoid deep recursion, [processExpressionStatement] returns a callback
-    // to invoke after its successor node has been processed.
-    // These callbacks are stored in a list and invoked in reverse at the end.
-    List<Function> stack = [];
-    Statement node = inputNode;
-    while (node is ExpressionStatement) {
-      stack.add(processExpressionStatement(node));
-      node = node.next;
-    }
-    Statement result = visitStatement(node);
-    for (Function fun in stack.reversed) {
-      result = fun(result);
-    }
-    return result;
-  }
-
-  /// Attempts to propagate an assignment in an expression statement.
-  ///
-  /// Returns a callback to be invoked after the sucessor statement has
-  /// been processed.
-  Function processExpressionStatement(ExpressionStatement stmt) {
-    Variable leftHand = getLeftHand(stmt.expression);
-    pushDominatingAssignment(leftHand);
-    if (isEffectivelyConstantAssignment(stmt.expression) &&
-        !usesRecentlyAssignedVariable(stmt.expression)) {
-      Assign assign = stmt.expression;
-      // Handle constant assignments specially.
-      // They are always safe to propagate (though we should avoid duplication).
-      // Moreover, they should not prevent other expressions from propagating.
-      if (assign.variable.readCount == 1) {
-        // A single-use constant should always be propagated to its use site.
-        constantEnvironment[assign.variable] = assign.value;
-        return (Statement next) {
-          popDominatingAssignment(leftHand);
-          if (assign.variable.readCount > 0) {
-            // The assignment could not be propagated into the successor,
-            // either because it [hasUnsafeVariableUse] or because the
-            // use is outside the current try block, and we do not currently
-            // support constant propagation out of a try block.
-            constantEnvironment.remove(assign.variable);
-            assign.value = visitExpression(assign.value);
-            stmt.next = next;
-            return stmt;
-          } else {
-            --assign.variable.writeCount;
-            return next;
-          }
-        };
-      } else {
-        // With more than one use, we cannot propagate the constant.
-        // Visit the following statement without polluting [environment] so
-        // that any preceding non-constant assignments might still propagate.
-        return (Statement next) {
-          stmt.next = next;
-          popDominatingAssignment(leftHand);
-          assign.value = visitExpression(assign.value);
-          return stmt;
-        };
-      }
-    } else {
-      // Try to propagate the expression, and block previous impure expressions
-      // until this has propagated.
-      environment.add(stmt.expression);
-      return (Statement next) {
-        stmt.next = next;
-        popDominatingAssignment(leftHand);
-        if (!environment.isEmpty && environment.last == stmt.expression) {
-          // Retain the expression statement.
-          environment.removeLast();
-          stmt.expression = visitExpression(stmt.expression);
-          return stmt;
-        } else {
-          // Expression was propagated into the successor.
-          return stmt.next;
-        }
-      };
-    }
-  }
-
-  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:
-    //
-    //     { x = foo(); bar(x) } ==> bar(x = foo()) ==> bar(foo())
-    //
-    if (node.variable.readCount == 0) {
-      --node.variable.writeCount;
-      return node.value;
-    }
-    return node;
-  }
-
-  /// Process nodes right-to-left, the opposite of evaluation order in the case
-  /// of argument lists..
-  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) {
-    _rewriteList(node.arguments);
-    return node;
-  }
-
-  Expression visitInvokeMethod(InvokeMethod node) {
-    if (node.receiverIsNotNull) {
-      _rewriteList(node.arguments);
-      node.receiver = visitExpression(node.receiver);
-    } else {
-      // Impure expressions cannot be propagated across the method lookup,
-      // because it throws when the receiver is null.
-      inEmptyEnvironment(() {
-        _rewriteList(node.arguments);
-      });
-      node.receiver = visitExpression(node.receiver);
-    }
-    return node;
-  }
-
-  Expression visitOneShotInterceptor(OneShotInterceptor node) {
-    _rewriteList(node.arguments);
-    return node;
-  }
-
-  Expression visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    if (node.receiverIsNotNull) {
-      _rewriteList(node.arguments);
-      node.receiver = visitExpression(node.receiver);
-    } else {
-      // Impure expressions cannot be propagated across the method lookup,
-      // because it throws when the receiver is null.
-      inEmptyEnvironment(() {
-        _rewriteList(node.arguments);
-      });
-      node.receiver = visitExpression(node.receiver);
-    }
-    return node;
-  }
-
-  Expression visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    _rewriteList(node.arguments);
-    // 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;
-  }
-
-  Expression visitInvokeConstructor(InvokeConstructor node) {
-    _rewriteList(node.arguments);
-    return node;
-  }
-
-  Expression visitConditional(Conditional node) {
-    // Conditional expressions do not exist in the input, but they are
-    // introduced by if-to-conditional conversion.
-    // Their subexpressions have already been processed; do not reprocess them.
-    //
-    // Note that this can only happen for conditional expressions. It is an
-    // error for any other type of expression to be visited twice or to be
-    // created and then visited. We use this special treatment of conditionals
-    // to allow for assignment inlining after if-to-conditional conversion.
-    //
-    // There are several reasons we should not reprocess the subexpressions:
-    //
-    // - It will mess up the [seenUses] counter, since a single use will be
-    //   counted twice.
-    //
-    // - Other visit methods assume that all subexpressions are variable uses
-    //   because they come fresh out of the tree IR builder.
-    //
-    // - Reprocessing can be expensive.
-    //
-    return node;
-  }
-
-  Expression visitLogicalOperator(LogicalOperator node) {
-    // Impure expressions may not propagate across the branch.
-    inEmptyEnvironment(() {
-      node.right = visitExpression(node.right);
-    });
-    node.left = visitExpression(node.left);
-    return node;
-  }
-
-  Expression visitNot(Not node) {
-    node.operand = visitExpression(node.operand);
-    return node;
-  }
-
-  bool isNullConstant(Expression node) {
-    return node is Constant && node.value.isNull;
-  }
-
-  Statement visitReturn(Return node) {
-    if (!isNullConstant(node.value)) {
-      // Do not chain assignments into a null return.
-      node.value = visitExpression(node.value);
-    }
-    return node;
-  }
-
-  Statement visitThrow(Throw node) {
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  Statement visitUnreachable(Unreachable node) {
-    return node;
-  }
-
-  Statement visitBreak(Break node) {
-    // Redirect through chain of breaks.
-    // Note that useCount was accounted for at visitLabeledStatement.
-    // Note redirect may return either a Break or Continue statement.
-    Jump jump = redirect(node);
-    if (jump is Break &&
-        jump.target.useCount == 1 &&
-        safeForInlining.contains(jump.target)) {
-      --jump.target.useCount;
-      return visitStatement(jump.target.binding.next);
-    }
-    return jump;
-  }
-
-  Statement visitContinue(Continue node) {
-    return node;
-  }
-
-  Statement visitLabeledStatement(LabeledStatement node) {
-    if (node.next is Jump) {
-      // Eliminate label if next is a break or continue statement
-      // Breaks to this label are redirected to the outer label.
-      // Note that breakCount for the two labels is updated proactively here
-      // so breaks can reliably tell if they should inline their target.
-      Jump next = node.next;
-      Jump newJump = redirect(next);
-      labelRedirects[node.label] = newJump;
-      newJump.target.useCount += node.label.useCount - 1;
-      node.label.useCount = 0;
-      Statement result = visitStatement(node.body);
-      labelRedirects.remove(node.label); // Save some space.
-      return result;
-    }
-
-    safeForInlining.add(node.label);
-    node.body = visitStatement(node.body);
-    safeForInlining.remove(node.label);
-
-    if (node.label.useCount == 0) {
-      // Eliminate the label if next was inlined at a break
-      return node.body;
-    }
-
-    // Do not propagate assignments into the successor statements, since they
-    // may be overwritten by assignments in the body.
-    inEmptyEnvironment(() {
-      node.next = visitStatement(node.next);
-    });
-
-    return node;
-  }
-
-  Statement visitIf(If node) {
-    // Do not propagate assignments into branches.
-    inEmptyEnvironment(() {
-      node.thenStatement = visitStatement(node.thenStatement);
-      node.elseStatement = visitStatement(node.elseStatement);
-    });
-
-    node.condition = visitExpression(node.condition);
-
-    inEmptyEnvironment(() {
-      tryCollapseIf(node);
-    });
-
-    Statement reduced = combineStatementsInBranches(
-        node.thenStatement, node.elseStatement, node.condition);
-    if (reduced != null) {
-      return reduced;
-    }
-
-    return node;
-  }
-
-  Statement visitWhileTrue(WhileTrue node) {
-    // Do not propagate assignments into loops.  Doing so is not safe for
-    // variables modified in the loop (the initial value will be propagated).
-    // Do not propagate effective constant expressions into loops, since
-    // computing them is not free (e.g. interceptors are expensive).
-    inEmptyEnvironment(() {
-      node.body = visitStatement(node.body);
-    }, keepConstants: false);
-    return node;
-  }
-
-  Statement visitFor(For node) {
-    // Not introduced yet
-    throw "Unexpected For in StatementRewriter";
-  }
-
-  Statement visitTry(Try node) {
-    inEmptyEnvironment(() {
-      Set<Label> saved = safeForInlining;
-      safeForInlining = new Set<Label>();
-      node.tryBody = visitStatement(node.tryBody);
-      safeForInlining = saved;
-      node.catchParameters.forEach(pushDominatingAssignment);
-      node.catchBody = visitStatement(node.catchBody);
-      node.catchParameters.forEach(popDominatingAssignment);
-    });
-    return node;
-  }
-
-  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;
-  }
-
-  Expression visitThis(This node) {
-    return node;
-  }
-
-  Expression visitLiteralList(LiteralList node) {
-    _rewriteList(node.values);
-    return node;
-  }
-
-  Expression visitTypeOperator(TypeOperator node) {
-    _rewriteList(node.typeArguments);
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  bool isCompoundableBuiltin(Expression e) {
-    return e is ApplyBuiltinOperator &&
-        e.arguments.length >= 2 &&
-        isCompoundableOperator(e.operator);
-  }
-
-  /// Converts a compoundable operator application into the right-hand side for
-  /// use in a compound assignment, discarding the left-hand value.
-  ///
-  /// For example, for `x + y + z` it returns `y + z`.
-  Expression contractCompoundableBuiltin(ApplyBuiltinOperator e) {
-    assert(isCompoundableBuiltin(e));
-    if (e.arguments.length > 2) {
-      assert(e.operator == BuiltinOperator.StringConcatenate);
-      return new ApplyBuiltinOperator(
-          e.operator, e.arguments.skip(1).toList(), e.sourceInformation);
-    } else {
-      return e.arguments[1];
-    }
-  }
-
-  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];
-      if (left is GetField &&
-          left.field == node.field &&
-          samePrimary(left.object, node.object)) {
-        destroyPrimaryExpression(left.object);
-        node.compound = rhs.operator;
-        node.value = contractCompoundableBuiltin(rhs);
-      }
-    }
-    node.object = visitExpression(node.object);
-    allowRhsPropagation.removeLast();
-    return node;
-  }
-
-  Expression visitGetField(GetField node) {
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  Expression visitGetStatic(GetStatic node) {
-    return node;
-  }
-
-  Expression visitSetStatic(SetStatic node) {
-    allowRhsPropagation.add(true);
-    node.value = visitExpression(node.value);
-    if (isCompoundableBuiltin(node.value)) {
-      ApplyBuiltinOperator rhs = node.value;
-      Expression left = rhs.arguments[0];
-      if (left is GetStatic &&
-          left.element == node.element &&
-          !left.useLazyGetter) {
-        node.compound = rhs.operator;
-        node.value = contractCompoundableBuiltin(rhs);
-      }
-    }
-    allowRhsPropagation.removeLast();
-    return node;
-  }
-
-  Expression visitGetTypeTestProperty(GetTypeTestProperty node) {
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  Expression visitCreateBox(CreateBox node) {
-    return node;
-  }
-
-  Expression visitCreateInstance(CreateInstance node) {
-    if (node.typeInformation != null) {
-      node.typeInformation = visitExpression(node.typeInformation);
-    }
-    _rewriteList(node.arguments);
-    return node;
-  }
-
-  Expression visitReifyRuntimeType(ReifyRuntimeType node) {
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  Expression visitReadTypeVariable(ReadTypeVariable node) {
-    node.target = visitExpression(node.target);
-    return node;
-  }
-
-  Expression visitTypeExpression(TypeExpression node) {
-    _rewriteList(node.arguments);
-    return node;
-  }
-
-  Expression visitCreateInvocationMirror(CreateInvocationMirror node) {
-    _rewriteList(node.arguments);
-    return node;
-  }
-
-  Expression visitInterceptor(Interceptor node) {
-    node.input = visitExpression(node.input);
-    return node;
-  }
-
-  Expression visitGetLength(GetLength node) {
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  Expression visitGetIndex(GetIndex node) {
-    node.index = visitExpression(node.index);
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  Expression visitSetIndex(SetIndex node) {
-    node.value = visitExpression(node.value);
-    if (isCompoundableBuiltin(node.value)) {
-      ApplyBuiltinOperator rhs = node.value;
-      Expression left = rhs.arguments[0];
-      if (left is GetIndex &&
-          samePrimary(left.object, node.object) &&
-          samePrimary(left.index, node.index)) {
-        destroyPrimaryExpression(left.object);
-        destroyPrimaryExpression(left.index);
-        node.compound = rhs.operator;
-        node.value = contractCompoundableBuiltin(rhs);
-      }
-    }
-    node.index = visitExpression(node.index);
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  /// True if [operator] is a binary operator that always has the same value
-  /// if its arguments are swapped.
-  bool isSymmetricOperator(BuiltinOperator operator) {
-    switch (operator) {
-      case BuiltinOperator.StrictEq:
-      case BuiltinOperator.StrictNeq:
-      case BuiltinOperator.LooseEq:
-      case BuiltinOperator.LooseNeq:
-      case BuiltinOperator.NumAnd:
-      case BuiltinOperator.NumOr:
-      case BuiltinOperator.NumXor:
-      case BuiltinOperator.NumAdd:
-      case BuiltinOperator.NumMultiply:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  /// If [operator] is a commutable binary operator, returns the commuted
-  /// operator, possibly the operator itself, otherwise returns `null`.
-  BuiltinOperator commuteBinaryOperator(BuiltinOperator operator) {
-    if (isSymmetricOperator(operator)) {
-      // Symmetric operators are their own commutes.
-      return operator;
-    }
-    switch (operator) {
-      case BuiltinOperator.NumLt:
-        return BuiltinOperator.NumGt;
-      case BuiltinOperator.NumLe:
-        return BuiltinOperator.NumGe;
-      case BuiltinOperator.NumGt:
-        return BuiltinOperator.NumLt;
-      case BuiltinOperator.NumGe:
-        return BuiltinOperator.NumLe;
-      default:
-        return null;
-    }
-  }
-
-  /// Built-in binary operators are commuted when it is safe and can enable an
-  /// assignment propagation. For example:
-  ///
-  ///    var x = foo();
-  ///    var y = bar();
-  ///    var z = y < x;
-  ///
-  ///      ==>
-  ///
-  ///    var z = foo() > bar();
-  ///
-  /// 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) {
-      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;
-          }
-        }
-      }
-    }
-    // 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;
-  }
-
-  /// If [s] and [t] are similar statements we extract their subexpressions
-  /// and returns a new statement of the same type using expressions combined
-  /// with the [combine] callback. For example:
-  ///
-  ///   combineStatements(Return E1, Return E2) = Return combine(E1, E2)
-  ///
-  /// If [combine] returns E1 then the unified statement is equivalent to [s],
-  /// and if [combine] returns E2 the unified statement is equivalence to [t].
-  ///
-  /// It is guaranteed that no side effects occur between the beginning of the
-  /// statement and the position of the combined expression.
-  ///
-  /// Returns null if the statements are too different.
-  ///
-  /// If non-null is returned, the caller MUST discard [s] and [t] and use
-  /// the returned statement instead.
-  Statement combineStatementsInBranches(
-      Statement s, Statement t, Expression condition) {
-    if (s is Return && t is Return) {
-      return new Return(new Conditional(condition, s.value, t.value));
-    }
-    if (s is ExpressionStatement && t is ExpressionStatement) {
-      // Combine the two expressions and the two successor statements.
-      //
-      //    C ? {E1 ; S1} : {E2 ; S2}
-      //      ==>
-      //    (C ? E1 : E2) : combine(S1, S2)
-      //
-      // If E1 and E2 are assignments, we want to propagate these into the
-      // combined statement.
-      //
-      // It might not be possible to combine the statements, so we combine the
-      // expressions, put the result in the environment, and then uncombine the
-      // expressions if the statements could not be combined.
-
-      // Combine the expressions.
-      CombinedExpressions values =
-          combineAsConditional(s.expression, t.expression, condition);
-
-      // Put this into the environment and try to combine the statements.
-      // We are not in risk of reprocessing the original subexpressions because
-      // the combined expression will always hide them inside a Conditional.
-      environment.add(values.combined);
-
-      Variable leftHand = getLeftHand(values.combined);
-      pushDominatingAssignment(leftHand);
-      Statement next = combineStatements(s.next, t.next);
-      popDominatingAssignment(leftHand);
-
-      if (next == null) {
-        // Statements could not be combined.
-        // Restore the environment and uncombine expressions again.
-        environment.removeLast();
-        values.uncombine();
-        return null;
-      } else if (!environment.isEmpty && environment.last == values.combined) {
-        // Statements were combined but the combined expression could not be
-        // propagated. Leave it as an expression statement here.
-        environment.removeLast();
-        s.expression = values.combined;
-        s.next = next;
-        return s;
-      } else {
-        // Statements were combined and the combined expressions were
-        // propagated into the combined statement.
-        return next;
-      }
-    }
-    return null;
-  }
-
-  /// Creates the expression `[condition] ? [s] : [t]` or an equivalent
-  /// expression if something better can be done.
-  ///
-  /// In particular, assignments will be merged as follows:
-  ///
-  ///     C ? (v = E1) : (v = E2)
-  ///       ==>
-  ///     v = C ? E1 : E2
-  ///
-  /// The latter form is more compact and can also be inlined.
-  CombinedExpressions combineAsConditional(
-      Expression s, Expression t, Expression condition) {
-    if (s is Assign && t is Assign && s.variable == t.variable) {
-      Expression values = new Conditional(condition, s.value, t.value);
-      return new CombinedAssigns(s, t, new CombinedExpressions(values));
-    }
-    return new CombinedExpressions(new Conditional(condition, s, t));
-  }
-
-  /// Returns a statement equivalent to both [s] and [t], or null if [s] and
-  /// [t] are incompatible.
-  /// If non-null is returned, the caller MUST discard [s] and [t] and use
-  /// the returned statement instead.
-  /// If two breaks are combined, the label's break counter will be decremented.
-  Statement combineStatements(Statement s, Statement t) {
-    if (s is Break && t is Break && s.target == t.target) {
-      --t.target.useCount; // Two breaks become one.
-      if (s.target.useCount == 1 && safeForInlining.contains(s.target)) {
-        // Only one break remains; inline it.
-        --s.target.useCount;
-        return visitStatement(s.target.binding.next);
-      }
-      return s;
-    }
-    if (s is Continue && t is Continue && s.target == t.target) {
-      --t.target.useCount; // Two continues become one.
-      return s;
-    }
-    if (s is Return && t is Return) {
-      CombinedExpressions values = combineExpressions(s.value, t.value);
-      if (values != null) {
-        // TODO(johnniwinther): Handle multiple source informations.
-        SourceInformation sourceInformation = s.sourceInformation != null
-            ? s.sourceInformation
-            : t.sourceInformation;
-        return new Return(values.combined,
-            sourceInformation: sourceInformation);
-      }
-    }
-    if (s is ExpressionStatement && t is ExpressionStatement) {
-      CombinedExpressions values =
-          combineExpressions(s.expression, t.expression);
-      if (values == null) return null;
-      environment.add(values.combined);
-      Variable leftHand = getLeftHand(values.combined);
-      pushDominatingAssignment(leftHand);
-      Statement next = combineStatements(s.next, t.next);
-      popDominatingAssignment(leftHand);
-      if (next == null) {
-        // The successors could not be combined.
-        // Restore the environment and uncombine the values again.
-        assert(environment.last == values.combined);
-        environment.removeLast();
-        values.uncombine();
-        return null;
-      } else if (!environment.isEmpty && environment.last == values.combined) {
-        // The successors were combined but the combined expressions were not
-        // propagated. Leave the combined expression as a statement.
-        environment.removeLast();
-        s.expression = values.combined;
-        s.next = next;
-        return s;
-      } else {
-        // The successors were combined, and the combined expressions were
-        // propagated into the successors.
-        return next;
-      }
-    }
-    return null;
-  }
-
-  /// Returns an expression equivalent to both [e1] and [e2].
-  /// If non-null is returned, the caller must discard [e1] and [e2] and use
-  /// the resulting expression in the tree.
-  CombinedExpressions combineExpressions(Expression e1, Expression e2) {
-    if (e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable) {
-      return new CombinedUses(e1, e2);
-    }
-    if (e1 is Assign && e2 is Assign && e1.variable == e2.variable) {
-      CombinedExpressions values = combineExpressions(e1.value, e2.value);
-      if (values != null) {
-        return new CombinedAssigns(e1, e2, values);
-      }
-    }
-    if (e1 is Constant && e2 is Constant && e1.value == e2.value) {
-      return new CombinedExpressions(e1);
-    }
-    return null;
-  }
-
-  /// Try to collapse nested ifs using && and || expressions.
-  /// For example:
-  ///
-  ///   if (E1) { if (E2) S else break L } else break L
-  ///     ==>
-  ///   if (E1 && E2) S else break L
-  ///
-  /// [branch1] and [branch2] control the position of the S statement.
-  ///
-  /// Must be called with an empty environment.
-  void tryCollapseIf(If node) {
-    assert(environment.isEmpty);
-    // Repeatedly try to collapse nested ifs.
-    // The transformation is shrinking (destroys an if) so it remains linear.
-    // Here is an example where more than one iteration is required:
-    //
-    //   if (E1)
-    //     if (E2) break L2 else break L1
-    //   else
-    //     break L1
-    //
-    // L1.target ::=
-    //   if (E3) S else break L2
-    //
-    // After first collapse:
-    //
-    //   if (E1 && E2)
-    //     break L2
-    //   else
-    //     {if (E3) S else break L2}  (inlined from break L1)
-    //
-    // We can then do another collapse using the inlined nested if.
-    bool changed = true;
-    while (changed) {
-      changed = false;
-      if (tryCollapseIfAux(node, true, true)) {
-        changed = true;
-      }
-      if (tryCollapseIfAux(node, true, false)) {
-        changed = true;
-      }
-      if (tryCollapseIfAux(node, false, true)) {
-        changed = true;
-      }
-      if (tryCollapseIfAux(node, false, false)) {
-        changed = true;
-      }
-    }
-  }
-
-  bool tryCollapseIfAux(If outerIf, bool branch1, bool branch2) {
-    // NOTE: We name variables here as if S is in the then-then position.
-    Statement outerThen = getBranch(outerIf, branch1);
-    Statement outerElse = getBranch(outerIf, !branch1);
-    if (outerThen is If) {
-      If innerIf = outerThen;
-      Statement innerThen = getBranch(innerIf, branch2);
-      Statement innerElse = getBranch(innerIf, !branch2);
-      Statement combinedElse = combineStatements(innerElse, outerElse);
-      if (combinedElse != null) {
-        // We always put S in the then branch of the result, and adjust the
-        // condition expression if S was actually found in the else branch(es).
-        outerIf.condition = new LogicalOperator.and(
-            makeCondition(outerIf.condition, branch1),
-            makeCondition(innerIf.condition, branch2));
-        outerIf.thenStatement = innerThen;
-        outerIf.elseStatement = combinedElse;
-        return outerIf.elseStatement is If;
-      }
-    }
-    return false;
-  }
-
-  Expression makeCondition(Expression e, bool polarity) {
-    return polarity ? e : new Not(e);
-  }
-
-  Statement getBranch(If node, bool polarity) {
-    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) {
-    handleForeignCode(node);
-    return node;
-  }
-
-  @override
-  Statement visitForeignStatement(ForeignStatement node) {
-    handleForeignCode(node);
-    return node;
-  }
-
-  @override
-  Expression visitAwait(Await node) {
-    node.input = visitExpression(node.input);
-    return node;
-  }
-
-  @override
-  Statement visitYield(Yield node) {
-    node.next = visitStatement(node.next);
-    node.input = visitExpression(node.input);
-    return node;
-  }
-
-  @override
-  Statement visitReceiverCheck(ReceiverCheck 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
-/// combination.
-///
-/// Reverting a combination is done by calling [uncombine]. In this case,
-/// both the original expressions should remain in the tree, and the [combined]
-/// expression should be orphaned.
-///
-/// Explicitly reverting a combination is necessary to maintain variable
-/// reference counts.
-abstract class CombinedExpressions {
-  Expression get combined;
-  void uncombine();
-
-  factory CombinedExpressions(Expression e) = GenericCombinedExpressions;
-}
-
-/// Combines assignments of form `[variable] := E1` and `[variable] := E2` into
-/// a single assignment of form `[variable] := combine(E1, E2)`.
-class CombinedAssigns implements CombinedExpressions {
-  Assign assign1, assign2;
-  CombinedExpressions value;
-  Expression combined;
-
-  CombinedAssigns(this.assign1, this.assign2, this.value) {
-    assert(assign1.variable == assign2.variable);
-    assign1.variable.writeCount -= 2; // Destroy the two original assignemnts.
-    combined = new Assign(assign1.variable, value.combined);
-  }
-
-  void uncombine() {
-    value.uncombine();
-    ++assign1.variable.writeCount; // Restore original reference count.
-  }
-}
-
-/// Combines two variable uses into one.
-class CombinedUses implements CombinedExpressions {
-  VariableUse use1, use2;
-  Expression combined;
-
-  CombinedUses(this.use1, this.use2) {
-    assert(use1.variable == use2.variable);
-    use1.variable.readCount -= 2; // Destroy both the original uses.
-    combined = new VariableUse(use1.variable);
-  }
-
-  void uncombine() {
-    ++use1.variable.readCount; // Restore original reference count.
-  }
-}
-
-/// Result of combining two expressions that do not affect reference counting.
-class GenericCombinedExpressions implements CombinedExpressions {
-  Expression combined;
-
-  GenericCombinedExpressions(this.combined);
-
-  void uncombine() {}
-}
-
-/// Looks for uses of a specific variable.
-///
-/// Note that this visitor is only applied to expressions where all
-/// sub-expressions are known to be variable uses, so there is no risk of
-/// explosive reprocessing.
-class IsVariableUsedVisitor extends RecursiveVisitor {
-  Variable variable;
-  bool wasFound = false;
-
-  IsVariableUsedVisitor(this.variable);
-
-  visitVariableUse(VariableUse node) {
-    if (node.variable == variable) {
-      wasFound = true;
-    }
-  }
-}
-
-typedef VariableUseCallback(VariableUse use);
-
-class VariableUseVisitor extends RecursiveVisitor {
-  VariableUseCallback callback;
-
-  VariableUseVisitor(this.callback);
-
-  visitVariableUse(VariableUse use) => callback(use);
-
-  static void visit(Expression node, VariableUseCallback callback) {
-    new VariableUseVisitor(callback).visitExpression(node);
-  }
-}
-
-bool sameVariable(Expression e1, Expression e2) {
-  return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
-}
-
-/// True if [e1] and [e2] are primary expressions (expressions without
-/// subexpressions) with the same value.
-bool samePrimary(Expression e1, Expression e2) {
-  return sameVariable(e1, e2) || (e1 is This && e2 is This);
-}
-
-/// Decrement the reference count for [e] if it is a variable use.
-void destroyPrimaryExpression(Expression e) {
-  if (e is VariableUse) {
-    --e.variable.readCount;
-  } else {
-    assert(e is This);
-  }
-}
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
deleted file mode 100644
index 273d7a4..0000000
--- a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
+++ /dev/null
@@ -1,613 +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 tree_ir.optimization.variable_merger;
-
-import 'optimization.dart' show Pass;
-import '../tree_ir_nodes.dart';
-
-/// Merges variables based on liveness and source variable information.
-///
-/// This phase cleans up artifacts introduced by the translation through CPS,
-/// where each source variable is translated into several copies. The copies
-/// are merged again when they are not live simultaneously.
-class VariableMerger implements Pass {
-  String get passName => 'Variable merger';
-
-  final bool minifying;
-
-  VariableMerger({this.minifying: false});
-
-  void rewrite(FunctionDefinition node) {
-    BlockGraphBuilder builder = new BlockGraphBuilder()..build(node);
-    _computeLiveness(builder.blocks);
-    PriorityPairs priority = new PriorityPairs()..build(node);
-    Map<Variable, Variable> subst = _computeRegisterAllocation(
-        builder.blocks, node.parameters, priority,
-        minifying: minifying);
-    new SubstituteVariables(subst).apply(node);
-  }
-}
-
-/// A read or write access to a variable.
-class VariableAccess {
-  Variable variable;
-  bool isRead;
-  bool get isWrite => !isRead;
-
-  VariableAccess.read(this.variable) : isRead = true;
-  VariableAccess.write(this.variable) : isRead = false;
-}
-
-/// Basic block in a control-flow graph.
-class Block {
-  /// List of predecessors in the control-flow graph.
-  final List<Block> predecessors = <Block>[];
-
-  /// Entry to the catch block for the enclosing try, or `null`.
-  final Block catchBlock;
-
-  /// List of nodes with this block as [catchBlock].
-  final List<Block> catchPredecessors = <Block>[];
-
-  /// Sequence of read and write accesses in the block.
-  final List<VariableAccess> accesses = <VariableAccess>[];
-
-  /// Auxiliary fields used by the liveness analysis.
-  bool inWorklist = true;
-  Set<Variable> liveIn;
-  Set<Variable> liveOut = new Set<Variable>();
-  Set<Variable> gen = new Set<Variable>();
-  Set<Variable> kill = new Set<Variable>();
-
-  /// Adds a read operation to the block and updates gen/kill sets accordingly.
-  void addRead(Variable variable) {
-    // Operations are seen in forward order.
-    // If the read is not preceded by a write, then add it to the GEN set.
-    if (!kill.contains(variable)) {
-      gen.add(variable);
-    }
-    accesses.add(new VariableAccess.read(variable));
-  }
-
-  /// Adds a write operation to the block and updates gen/kill sets accordingly.
-  void addWrite(Variable variable) {
-    // If the write is not preceded by a read, then add it to the KILL set.
-    if (!gen.contains(variable)) {
-      kill.add(variable);
-    }
-    accesses.add(new VariableAccess.write(variable));
-  }
-
-  Block(this.catchBlock) {
-    if (catchBlock != null) {
-      catchBlock.catchPredecessors.add(this);
-    }
-  }
-}
-
-/// Builds a control-flow graph suitable for performing liveness analysis.
-class BlockGraphBuilder extends RecursiveVisitor {
-  Map<Label, Block> _jumpTarget = <Label, Block>{};
-  Block _currentBlock;
-  List<Block> blocks = <Block>[];
-
-  /// Variables with an assignment that should be treated as final.
-  ///
-  /// Such variables cannot be merged with any other variables, so we exclude
-  /// them from the control-flow graph entirely.
-  Set<Variable> _ignoredVariables = new Set<Variable>();
-
-  void build(FunctionDefinition node) {
-    _currentBlock = newBlock();
-    node.parameters.forEach(write);
-    visitStatement(node.body);
-  }
-
-  /// Creates a new block with the current exception handler or [catchBlock]
-  /// if provided.
-  Block newBlock({Block catchBlock}) {
-    if (catchBlock == null && _currentBlock != null) {
-      catchBlock = _currentBlock.catchBlock;
-    }
-    Block block = new Block(catchBlock);
-    blocks.add(block);
-    return block;
-  }
-
-  /// Starts a new block after the end of [block].
-  void branchFrom(Block block, {Block catchBlock}) {
-    _currentBlock = newBlock(catchBlock: catchBlock)..predecessors.add(block);
-  }
-
-  /// Starts a new block with the given blocks as predecessors.
-  void joinFrom(Block block1, Block block2) {
-    assert(block1.catchBlock == block2.catchBlock);
-    _currentBlock = newBlock(catchBlock: block1.catchBlock);
-    _currentBlock.predecessors.add(block1);
-    _currentBlock.predecessors.add(block2);
-  }
-
-  /// Called when reading from [variable].
-  ///
-  /// Appends a read operation to the current basic block.
-  void read(Variable variable) {
-    if (variable.isCaptured) return;
-    if (_ignoredVariables.contains(variable)) return;
-    _currentBlock.addRead(variable);
-  }
-
-  /// Called when writing to [variable].
-  ///
-  /// Appends a write operation to the current basic block.
-  void write(Variable variable) {
-    if (variable.isCaptured) return;
-    if (_ignoredVariables.contains(variable)) return;
-    _currentBlock.addWrite(variable);
-  }
-
-  /// Called to indicate that [variable] should not be merged, and therefore
-  /// be excluded from the control-flow graph.
-  /// Subsequent calls to [read] and [write] will ignore it.
-  void ignoreVariable(Variable variable) {
-    _ignoredVariables.add(variable);
-  }
-
-  visitVariableUse(VariableUse node) {
-    read(node.variable);
-  }
-
-  visitAssign(Assign node) {
-    visitExpression(node.value);
-    write(node.variable);
-  }
-
-  visitIf(If node) {
-    visitExpression(node.condition);
-    Block afterCondition = _currentBlock;
-    branchFrom(afterCondition);
-    visitStatement(node.thenStatement);
-    Block afterThen = _currentBlock;
-    branchFrom(afterCondition);
-    visitStatement(node.elseStatement);
-    joinFrom(_currentBlock, afterThen);
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    Block join = _jumpTarget[node.label] = newBlock();
-    visitStatement(node.body); // visitBreak will add predecessors to join.
-    _currentBlock = join;
-    visitStatement(node.next);
-  }
-
-  visitBreak(Break node) {
-    _jumpTarget[node.target].predecessors.add(_currentBlock);
-  }
-
-  visitContinue(Continue node) {
-    _jumpTarget[node.target].predecessors.add(_currentBlock);
-  }
-
-  visitWhileTrue(WhileTrue node) {
-    Block join = _jumpTarget[node.label] = newBlock();
-    join.predecessors.add(_currentBlock);
-    _currentBlock = join;
-    visitStatement(node.body); // visitContinue will add predecessors to join.
-  }
-
-  visitFor(For node) {
-    Block entry = _currentBlock;
-    _currentBlock = _jumpTarget[node.label] = newBlock();
-    node.updates.forEach(visitExpression);
-    joinFrom(entry, _currentBlock);
-    visitExpression(node.condition);
-    Block afterCondition = _currentBlock;
-    branchFrom(afterCondition);
-    visitStatement(node.body); // visitContinue will add predecessors to join.
-    branchFrom(afterCondition);
-    visitStatement(node.next);
-  }
-
-  visitTry(Try node) {
-    Block outerCatchBlock = _currentBlock.catchBlock;
-    Block catchBlock = newBlock(catchBlock: outerCatchBlock);
-    branchFrom(_currentBlock, catchBlock: catchBlock);
-    visitStatement(node.tryBody);
-    Block afterTry = _currentBlock;
-    _currentBlock = catchBlock;
-    // Catch parameters cannot be hoisted to the top of the function, so to
-    // avoid complications with scoping, we do not attempt to merge them.
-    node.catchParameters.forEach(ignoreVariable);
-    visitStatement(node.catchBody);
-    Block afterCatch = _currentBlock;
-    _currentBlock = newBlock(catchBlock: outerCatchBlock);
-    _currentBlock.predecessors.add(afterCatch);
-    _currentBlock.predecessors.add(afterTry);
-  }
-
-  visitConditional(Conditional node) {
-    visitExpression(node.condition);
-    Block afterCondition = _currentBlock;
-    branchFrom(afterCondition);
-    visitExpression(node.thenExpression);
-    Block afterThen = _currentBlock;
-    branchFrom(afterCondition);
-    visitExpression(node.elseExpression);
-    joinFrom(_currentBlock, afterThen);
-  }
-
-  visitLogicalOperator(LogicalOperator node) {
-    visitExpression(node.left);
-    Block afterLeft = _currentBlock;
-    branchFrom(afterLeft);
-    visitExpression(node.right);
-    joinFrom(_currentBlock, afterLeft);
-  }
-}
-
-/// Collects prioritized variable pairs -- pairs that lead to significant code
-/// reduction if merged into one variable.
-///
-/// These arise from moving assigments `v1 = v2`, and compoundable assignments
-/// `v1 = v2 [+] E` where [+] is a compoundable operator.
-//
-// TODO(asgerf): We could have a more fine-grained priority level. All pairs
-//   are treated as equally important, but some pairs can eliminate more than
-//   one assignment.
-//   Also, some assignments are more important to remove than others, as they
-//   can block a later optimization, such rewriting a loop, or removing the
-//   'else' part of an 'if'.
-//
-class PriorityPairs extends RecursiveVisitor {
-  final Map<Variable, List<Variable>> _priority = <Variable, List<Variable>>{};
-
-  void build(FunctionDefinition node) {
-    visitStatement(node.body);
-  }
-
-  void _prioritize(Variable x, Variable y) {
-    _priority.putIfAbsent(x, () => new List<Variable>()).add(y);
-    _priority.putIfAbsent(y, () => new List<Variable>()).add(x);
-  }
-
-  visitAssign(Assign node) {
-    super.visitAssign(node);
-    Expression value = node.value;
-    if (value is VariableUse) {
-      _prioritize(node.variable, value.variable);
-    } else if (value is ApplyBuiltinOperator &&
-        isCompoundableOperator(value.operator) &&
-        value.arguments[0] is VariableUse) {
-      VariableUse use = value.arguments[0];
-      _prioritize(node.variable, use.variable);
-    }
-  }
-
-  /// Returns the other half of every priority pair containing [variable].
-  List<Variable> getPriorityPairsWith(Variable variable) {
-    return _priority[variable] ?? const <Variable>[];
-  }
-
-  bool hasPriorityPairs(Variable variable) {
-    return _priority.containsKey(variable);
-  }
-}
-
-/// Computes liveness information of the given control-flow graph.
-///
-/// The results are stored in [Block.liveIn] and [Block.liveOut].
-void _computeLiveness(List<Block> blocks) {
-  // We use a LIFO queue as worklist. Blocks are given in AST order, so by
-  // inserting them in this order, we initially visit them backwards, which
-  // is a good ordering.
-  // The choice of LIFO for re-inserted blocks is currently arbitrary,
-  List<Block> worklist = new List<Block>.from(blocks);
-  while (!worklist.isEmpty) {
-    Block block = worklist.removeLast();
-    block.inWorklist = false;
-
-    bool changed = false;
-
-    // The liveIn set is computed as:
-    //
-    //    liveIn = (liveOut - kill) + gen
-    //
-    // We do the computation in two steps:
-    //
-    //    1. liveIn = gen
-    //    2. liveIn += (liveOut - kill)
-    //
-    // However, since liveIn only grows, and gen never changes, we only have
-    // to do the first step at the first iteration. Moreover, the gen set is
-    // not needed anywhere else, so we don't even need to copy it.
-    if (block.liveIn == null) {
-      block.liveIn = block.gen;
-      block.gen = null;
-      changed = true;
-    }
-
-    // liveIn += (liveOut - kill)
-    for (Variable variable in block.liveOut) {
-      if (!block.kill.contains(variable)) {
-        if (block.liveIn.add(variable)) {
-          changed = true;
-        }
-      }
-    }
-
-    // If anything changed, propagate liveness backwards.
-    if (changed) {
-      // Propagate live variables to predecessors.
-      for (Block predecessor in block.predecessors) {
-        int lengthBeforeChange = predecessor.liveOut.length;
-        predecessor.liveOut.addAll(block.liveIn);
-        if (!predecessor.inWorklist &&
-            predecessor.liveOut.length != lengthBeforeChange) {
-          worklist.add(predecessor);
-          predecessor.inWorklist = true;
-        }
-      }
-
-      // Propagate live variables to catch predecessors.
-      for (Block pred in block.catchPredecessors) {
-        bool changed = false;
-        int lengthBeforeChange = pred.liveOut.length;
-        pred.liveOut.addAll(block.liveIn);
-        if (pred.liveOut.length != lengthBeforeChange) {
-          changed = true;
-        }
-        // Assigning to a variable that is live in the catch block, does not
-        // kill the variable, because we conservatively assume that an exception
-        // could be thrown immediately before the assignment.
-        // Therefore remove live variables from all kill sets inside the try.
-        // Since the kill set is only used to subtract live variables from a
-        // set, the analysis remains monotone.
-        lengthBeforeChange = pred.kill.length;
-        pred.kill.removeAll(block.liveIn);
-        if (pred.kill.length != lengthBeforeChange) {
-          changed = true;
-        }
-        if (changed && !pred.inWorklist) {
-          worklist.add(pred);
-          pred.inWorklist = true;
-        }
-      }
-    }
-  }
-}
-
-/// Based on liveness information, computes a map of variable substitutions to
-/// merge variables.
-///
-/// Constructs a register interference graph. This is an undirected graph of
-/// variables, with an edge between two variables if they cannot be merged
-/// (because they are live simultaneously).
-///
-/// We then compute a graph coloring, where the color of a node denotes which
-/// variable it will be substituted by.
-Map<Variable, Variable> _computeRegisterAllocation(
-    List<Block> blocks, List<Variable> parameters, PriorityPairs priority,
-    {bool minifying}) {
-  Map<Variable, Set<Variable>> interference = <Variable, Set<Variable>>{};
-
-  bool allowUnmotivatedMerge(Variable x, Variable y) {
-    if (minifying) return true;
-    // Do not allow merging temporaries with named variables if they are
-    // not connected by a phi.  That would leads to confusing mergings like:
-    //    var v0 = receiver.length;
-    //        ==>
-    //    receiver = receiver.length;
-    return x.element?.name == y.element?.name;
-  }
-
-  bool allowPhiMerge(Variable x, Variable y) {
-    if (minifying) return true;
-    // Temporaries may be merged with a named variable if this eliminates a phi.
-    // The presence of the phi implies that the two variables can contain the
-    // same value, so it is not that confusing that they get the same name.
-    return x.element == null ||
-        y.element == null ||
-        x.element.name == y.element.name;
-  }
-
-  Set<Variable> empty = new Set<Variable>();
-
-  // At the assignment to a variable x, add an edge to every variable that is
-  // live after the assignment (if it came from the same source variable).
-  for (Block block in blocks) {
-    // Track the live set while traversing the block.
-    Set<Variable> live = new Set<Variable>();
-    for (Variable variable in block.liveOut) {
-      live.add(variable);
-      interference.putIfAbsent(variable, () => new Set<Variable>());
-    }
-    // Get variables that are live at the catch block.
-    Set<Variable> liveCatch =
-        block.catchBlock != null ? block.catchBlock.liveIn : empty;
-    // Add edges for each variable being assigned here.
-    for (VariableAccess access in block.accesses.reversed) {
-      Variable variable = access.variable;
-      interference.putIfAbsent(variable, () => new Set<Variable>());
-      if (access.isRead) {
-        live.add(variable);
-      } else {
-        if (!liveCatch.contains(variable)) {
-          // Assignment to a variable that is not live in the catch block.
-          live.remove(variable);
-        }
-        for (Variable other in live) {
-          interference[variable].add(other);
-          interference[other].add(variable);
-        }
-      }
-    }
-  }
-
-  // Sort the variables by descending degree.
-  // The most constrained variables will be assigned a color first.
-  List<Variable> variables = interference.keys.toList();
-  variables.sort((x, y) => interference[y].length - interference[x].length);
-
-  List<Variable> registers = <Variable>[];
-  Map<Variable, Variable> subst = <Variable, Variable>{};
-
-  /// Called when [variable] has been assigned [target] as its register/color.
-  /// Will immediately try to satisfy its priority pairs by assigning the same
-  /// color the other half of each pair.
-  void searchPriorityPairs(Variable variable, Variable target) {
-    if (!priority.hasPriorityPairs(variable)) {
-      return; // Most variables (around 90%) do not have priority pairs.
-    }
-    List<Variable> worklist = <Variable>[variable];
-    while (worklist.isNotEmpty) {
-      Variable v1 = worklist.removeLast();
-      for (Variable v2 in priority.getPriorityPairsWith(v1)) {
-        // If v2 already has a color, we cannot change it.
-        if (subst.containsKey(v2)) continue;
-
-        // Do not merge differently named variables.
-        if (!allowPhiMerge(v1, v2)) continue;
-
-        // Ensure the graph coloring remains valid. If a neighbour of v2 already
-        // has the desired color, we cannot assign the same color to v2.
-        if (interference[v2].any((v3) => subst[v3] == target)) continue;
-
-        subst[v2] = target;
-        target.element ??= v2.element; // Preserve the name.
-        worklist.add(v2);
-      }
-    }
-  }
-
-  void assignRegister(Variable variable, Variable registerRepresentative) {
-    subst[variable] = registerRepresentative;
-    // Ensure this register is never assigned to a variable with another name.
-    // This also ensures that named variables keep their name when merged
-    // with a temporary.
-    registerRepresentative.element ??= variable.element;
-    searchPriorityPairs(variable, registerRepresentative);
-  }
-
-  void assignNewRegister(Variable variable) {
-    registers.add(variable);
-    subst[variable] = variable;
-    searchPriorityPairs(variable, variable);
-  }
-
-  // Parameters cannot be merged with each other. Ensure that they are not
-  // substituted.  Other variables can still be substituted by a parameter.
-  for (Variable parameter in parameters) {
-    if (parameter.isCaptured) continue;
-    registers.add(parameter);
-    subst[parameter] = parameter;
-  }
-
-  // Try to merge parameters with locals to eliminate phis.
-  for (Variable parameter in parameters) {
-    searchPriorityPairs(parameter, parameter);
-  }
-
-  v1loop: for (Variable v1 in variables) {
-    // Ignore if the variable has already been assigned a register.
-    if (subst.containsKey(v1)) continue;
-
-    // Optimization: If there are no interference edges for this variable,
-    // find a color for it without copying the register list.
-    Set<Variable> interferenceSet = interference[v1];
-    if (interferenceSet.isEmpty) {
-      // Use the first register where naming constraints allow the merge.
-      for (Variable v2 in registers) {
-        if (allowUnmotivatedMerge(v1, v2)) {
-          assignRegister(v1, v2);
-          continue v1loop;
-        }
-      }
-      // No register allows merging with this one, create a new register.
-      assignNewRegister(v1);
-      continue;
-    }
-
-    // Find an unused color.
-    Set<Variable> potential = new Set<Variable>.from(
-        registers.where((v2) => allowUnmotivatedMerge(v1, v2)));
-    for (Variable v2 in interferenceSet) {
-      Variable v2subst = subst[v2];
-      if (v2subst != null) {
-        potential.remove(v2subst);
-        if (potential.isEmpty) break;
-      }
-    }
-
-    if (potential.isEmpty) {
-      // If no free color was found, add this variable as a new color.
-      assignNewRegister(v1);
-    } else {
-      assignRegister(v1, potential.first);
-    }
-  }
-
-  return subst;
-}
-
-/// Performs variable substitution and removes redundant assignments.
-class SubstituteVariables extends RecursiveTransformer {
-  Map<Variable, Variable> mapping;
-
-  SubstituteVariables(this.mapping);
-
-  Variable replaceRead(Variable variable) {
-    Variable w = mapping[variable];
-    if (w == null) return variable; // Skip ignored variables.
-    w.readCount++;
-    variable.readCount--;
-    return w;
-  }
-
-  Variable replaceWrite(Variable variable) {
-    Variable w = mapping[variable];
-    if (w == null) return variable; // Skip ignored variables.
-    w.writeCount++;
-    variable.writeCount--;
-    return w;
-  }
-
-  void apply(FunctionDefinition node) {
-    for (int i = 0; i < node.parameters.length; ++i) {
-      node.parameters[i] = replaceWrite(node.parameters[i]);
-    }
-    node.body = visitStatement(node.body);
-  }
-
-  Expression visitVariableUse(VariableUse node) {
-    node.variable = replaceRead(node.variable);
-    return node;
-  }
-
-  Expression visitAssign(Assign node) {
-    node.variable = replaceWrite(node.variable);
-    node.value = visitExpression(node.value);
-
-    // Remove assignments of form "x := x"
-    if (node.value is VariableUse) {
-      VariableUse value = node.value;
-      if (value.variable == node.variable) {
-        --node.variable.writeCount;
-        return value;
-      }
-    }
-
-    return node;
-  }
-
-  Statement visitExpressionStatement(ExpressionStatement node) {
-    node.expression = visitExpression(node.expression);
-    node.next = visitStatement(node.next);
-    if (node.expression is VariableUse) {
-      VariableUse use = node.expression;
-      --use.variable.readCount;
-      return node.next;
-    }
-    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
deleted file mode 100644
index 000f610..0000000
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ /dev/null
@@ -1,774 +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 tree_ir_builder;
-
-import '../common.dart';
-import '../constants/values.dart';
-import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
-import '../elements/elements.dart';
-import '../io/source_information.dart';
-import '../js_backend/codegen/glue.dart';
-
-import 'tree_ir_nodes.dart';
-
-typedef Statement NodeCallback(Statement next);
-
-/**
- * Builder translates from CPS-based IR to direct-style Tree.
- *
- * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced
- * non-exit continuation `Cont(v, body)` is translated into a direct-style call
- * whose value is bound in the continuation body:
- *
- * `LetVal(v, Invoke(fun, args), body)`
- *
- * and the continuation definition is eliminated.  A similar translation is
- * applied to continuation invocations where the continuation is
- * singly-referenced, though such invocations should not appear in optimized
- * IR.
- *
- * A call `Invoke(fun, cont, args)`, where cont is multiply referenced, is
- * translated into a call followed by a jump with an argument:
- *
- * `Jump L(Invoke(fun, args))`
- *
- * and the continuation is translated into a named block that takes an
- * argument:
- *
- * `LetLabel(L, v, body)`
- *
- * Block arguments are later replaced with data flow during the Tree-to-Tree
- * translation out of SSA.  Jumps are eliminated during the Tree-to-Tree
- * control-flow recognition.
- *
- * Otherwise, the output of Builder looks very much like the input.  In
- * particular, intermediate values and blocks used for local control flow are
- * still all named.
- */
-class Builder implements cps_ir.Visitor/*<NodeCallback|Node>*/ {
-  final InternalErrorFunction internalError;
-  final Glue glue;
-
-  final Map<cps_ir.Primitive, Variable> primitive2variable =
-      <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.
-  final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
-
-  ExecutableElement currentElement;
-
-  /// The parameter to be translated to 'this'.  This can either be the receiver
-  /// parameter, the interceptor parameter, or null if the method has neither.
-  cps_ir.Parameter thisParameter;
-  cps_ir.Continuation returnContinuation;
-
-  Builder(this.internalError, this.glue);
-
-  /// Variable used in [buildPhiAssignments] as a temporary when swapping
-  /// variables.
-  Variable phiTempVar;
-
-  Variable addMutableVariable(cps_ir.MutableVariable irVariable) {
-    assert(!mutable2variable.containsKey(irVariable));
-    Variable variable = new Variable(currentElement, irVariable.hint);
-    mutable2variable[irVariable] = variable;
-    return variable;
-  }
-
-  Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) {
-    return mutable2variable[mutableVariable];
-  }
-
-  VariableUse getMutableVariableUse(
-      cps_ir.Reference<cps_ir.MutableVariable> reference,
-      SourceInformation sourceInformation) {
-    Variable variable = getMutableVariable(reference.definition);
-    return new VariableUse(variable, sourceInformation: sourceInformation);
-  }
-
-  /// 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));
-  }
-
-  /// Obtains a reference to the tree Variable corresponding to the IR primitive
-  /// referred to by [reference].
-  /// 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,
-      {SourceInformation sourceInformation}) {
-    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(prim),
-        sourceInformation: sourceInformation);
-  }
-
-  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());
-  }
-
-  FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
-    currentElement = node.element;
-    List<Variable> parameters = node.parameters.map(getVariable).toList();
-    if (node.interceptorParameter != null) {
-      parameters.insert(0, getVariable(node.receiverParameter));
-      thisParameter = glue.methodUsesReceiverArgument(node.element)
-          ? node.interceptorParameter
-          : node.receiverParameter;
-    } else {
-      thisParameter = node.receiverParameter;
-    }
-    returnContinuation = node.returnContinuation;
-    phiTempVar = new Variable(node.element, null);
-    Statement body = translateExpression(node.body);
-    return new FunctionDefinition(node.element, parameters, body,
-        sourceInformation: node.sourceInformation);
-  }
-
-  /// Returns a list of variables corresponding to the arguments to a method
-  /// call or similar construct.
-  ///
-  /// The `readCount` for these variables will be incremented.
-  ///
-  /// The list will be typed as a list of [Expression] to allow inplace updates
-  /// on the list during the rewrite phases.
-  List<Expression> translateArguments(List<cps_ir.Reference> args) {
-    return new List<Expression>.generate(
-        args.length, (int index) => getVariableUse(args[index]),
-        growable: false);
-  }
-
-  /// Simultaneously assigns each argument to the corresponding parameter,
-  /// then continues at the statement created by [buildRest].
-  Statement buildPhiAssignments(List<cps_ir.Parameter> parameters,
-      List<Expression> arguments, Statement buildRest()) {
-    assert(parameters.length == arguments.length);
-    // We want a parallel assignment to all parameters simultaneously.
-    // Since we do not have parallel assignments in dart_tree, we must linearize
-    // the assignments without attempting to read a previously-overwritten
-    // value. For example {x,y = y,x} cannot be linearized to {x = y; y = x},
-    // for this we must introduce a temporary variable: {t = x; x = y; y = t}.
-
-    // [rightHand] is the inverse of [arguments], that is, it maps variables
-    // to the assignments on which is occurs as the right-hand side.
-    Map<Variable, List<int>> rightHand = <Variable, List<int>>{};
-    for (int i = 0; i < parameters.length; i++) {
-      Variable param = getVariable(parameters[i]);
-      Expression arg = arguments[i];
-      if (arg is VariableUse) {
-        if (param == null || param == arg.variable) {
-          // No assignment necessary.
-          --arg.variable.readCount;
-          continue;
-        }
-        // v1 = v0
-        List<int> list = rightHand[arg.variable];
-        if (list == null) {
-          rightHand[arg.variable] = list = <int>[];
-        }
-        list.add(i);
-      } else {
-        // v1 = this;
-      }
-    }
-
-    Statement first, current;
-    void addAssignment(Variable dst, Expression src) {
-      if (first == null) {
-        first = current = Assign.makeStatement(dst, src);
-      } else {
-        current = current.next = Assign.makeStatement(dst, src);
-      }
-    }
-
-    List<Expression> assignmentSrc = new List<Expression>(parameters.length);
-    List<bool> done = new List<bool>.filled(parameters.length, false);
-    void visitAssignment(int i) {
-      if (done[i]) {
-        return;
-      }
-      Variable param = getVariable(parameters[i]);
-      Expression arg = arguments[i];
-      if (param == null || (arg is VariableUse && param == arg.variable)) {
-        return; // No assignment necessary.
-      }
-      if (assignmentSrc[i] != null) {
-        // Cycle found; store argument in a temporary variable.
-        // The temporary will then be used as right-hand side when the
-        // assignment gets added.
-        VariableUse source = assignmentSrc[i];
-        if (source.variable != phiTempVar) {
-          // Only move to temporary once.
-          assignmentSrc[i] = new VariableUse(phiTempVar);
-          addAssignment(phiTempVar, arg);
-        }
-        return;
-      }
-      assignmentSrc[i] = arg;
-      List<int> paramUses = rightHand[param];
-      if (paramUses != null) {
-        for (int useIndex in paramUses) {
-          visitAssignment(useIndex);
-        }
-      }
-      addAssignment(param, assignmentSrc[i]);
-      done[i] = true;
-    }
-
-    for (int i = 0; i < parameters.length; i++) {
-      if (!done[i]) {
-        visitAssignment(i);
-      }
-    }
-
-    if (first == null) {
-      first = buildRest();
-    } else {
-      current.next = buildRest();
-    }
-    return first;
-  }
-
-  visit(cps_ir.Node node) => throw 'Use translateXXX instead of visit';
-
-  /// Translates a CPS expression into a tree statement.
-  ///
-  /// To avoid deep recursion, we traverse each basic blocks without
-  /// recursion.
-  ///
-  /// Non-tail expressions evaluate to a callback to be invoked once the
-  /// successor statement has been constructed. These callbacks are stored
-  /// in a stack until the block's tail expression has been translated.
-  Statement translateExpression(cps_ir.Expression node) {
-    List<NodeCallback> stack = <NodeCallback>[];
-    while (node is! cps_ir.TailExpression) {
-      stack.add(node.accept(this));
-      node = node.next;
-    }
-    Statement result = node.accept(this); // Translate the tail expression.
-    for (NodeCallback fun in stack.reversed) {
-      result = fun(result);
-    }
-    return result;
-  }
-
-  /// Translates a CPS primitive to a tree expression.
-  ///
-  /// This simply calls the visit method for the primitive.
-  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:
-  //
-  //    (Statement next) => <result statement>
-  //
-
-  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
-  // of them from anywhere, so it must be nested inside all of them.
-  //
-  // The continuation bodies are not always translated directly here because
-  // they may have been already translated:
-  //   * For singly-used continuations, the continuation's body is
-  //     translated at the site of the continuation invocation.
-  //   * For recursive continuations, there is a single non-recursive
-  //     invocation.  The continuation's body is translated at the site
-  //     of the non-recursive continuation invocation.
-  // See [visitInvokeContinuation] for the implementation.
-  NodeCallback visitLetCont(cps_ir.LetCont node) => (Statement next) {
-        for (cps_ir.Continuation continuation in node.continuations) {
-          // This happens after the body of the LetCont has been translated.
-          // Labels are created on-demand if the continuation could not be inlined,
-          // so the existence of the label indicates if a labeled statement should
-          // be emitted.
-          Label label = labels[continuation];
-          if (label != null && !continuation.isRecursive) {
-            // Recursively build the body. We only do this for join continuations,
-            // so we should not risk overly deep recursion.
-            next = new LabeledStatement(
-                label, next, translateExpression(continuation.body));
-          }
-        }
-        return next;
-      };
-
-  NodeCallback visitLetHandler(cps_ir.LetHandler node) => (Statement next) {
-        List<Variable> catchParameters =
-            node.handler.parameters.map(getVariable).toList();
-        Statement catchBody = translateExpression(node.handler.body);
-        return new Try(next, catchParameters, catchBody);
-      };
-
-  NodeCallback visitLetMutable(cps_ir.LetMutable node) {
-    Variable variable = addMutableVariable(node.variable);
-    Expression value = getVariableUse(node.valueRef);
-    return (Statement next) => Assign.makeStatement(variable, value, next);
-  }
-
-  /************************** TAIL EXPRESSIONS  **************************/
-  //
-  // Visit methods for tail expressions must return a statement directly
-  // (not a function like interior and call expressions).
-
-  Statement visitThrow(cps_ir.Throw node) {
-    Expression value = getVariableUse(node.valueRef);
-    return new Throw(value);
-  }
-
-  Statement visitUnreachable(cps_ir.Unreachable node) {
-    return new Unreachable();
-  }
-
-  Statement visitInvokeContinuation(cps_ir.InvokeContinuation node) {
-    // Invocations of the return continuation are translated to returns.
-    // Other continuation invocations are replaced with assignments of the
-    // arguments to formal parameter variables, followed by the body if
-    // the continuation is singly reference or a break if it is multiply
-    // referenced.
-    cps_ir.Continuation cont = node.continuation;
-    if (cont == returnContinuation) {
-      assert(node.argumentRefs.length == 1);
-      return new Return(getVariableUse(node.argumentRefs.single),
-          sourceInformation: node.sourceInformation);
-    } else {
-      List<Expression> arguments = translateArguments(node.argumentRefs);
-      return buildPhiAssignments(cont.parameters, arguments, () {
-        // Translate invocations of recursive and non-recursive
-        // continuations differently.
-        //   * Non-recursive continuations
-        //     - If there is one use, translate the continuation body
-        //       inline at the invocation site.
-        //     - If there are multiple uses, translate to Break.
-        //   * Recursive continuations
-        //     - There is a single non-recursive invocation.  Translate
-        //       the continuation body inline as a labeled loop at the
-        //       invocation site.
-        //     - Translate the recursive invocations to Continue.
-        if (cont.isRecursive) {
-          return node.isRecursive
-              ? new Continue(getLabel(cont))
-              : new WhileTrue(getLabel(cont), translateExpression(cont.body));
-        } else {
-          return cont.hasExactlyOneUse && !node.isEscapingTry
-              ? translateExpression(cont.body)
-              : new Break(getLabel(cont));
-        }
-      });
-    }
-  }
-
-  /// Translates a branch condition to a tree expression.
-  Expression translateCondition(cps_ir.Branch branch) {
-    Expression value = getVariableUse(branch.conditionRef,
-        sourceInformation: branch.sourceInformation);
-    if (branch.isStrictCheck) {
-      return new ApplyBuiltinOperator(
-          BuiltinOperator.StrictEq,
-          <Expression>[value, new Constant(new TrueConstantValue())],
-          branch.sourceInformation);
-    } else {
-      return value;
-    }
-  }
-
-  Statement visitBranch(cps_ir.Branch node) {
-    Expression condition = translateCondition(node);
-    Statement thenStatement, elseStatement;
-    cps_ir.Continuation cont = node.trueContinuation;
-    assert(cont.parameters.isEmpty);
-    thenStatement = cont.hasExactlyOneUse
-        ? translateExpression(cont.body)
-        : new Break(labels[cont]);
-    cont = node.falseContinuation;
-    assert(cont.parameters.isEmpty);
-    elseStatement = cont.hasExactlyOneUse
-        ? translateExpression(cont.body)
-        : new Break(labels[cont]);
-    return new If(
-        condition, thenStatement, elseStatement, node.sourceInformation);
-  }
-
-  /************************** PRIMITIVES  **************************/
-  //
-  // Visit methods for primitives must return an expression.
-  //
-
-  Expression visitSetField(cps_ir.SetField node) {
-    return new SetField(getVariableUse(node.objectRef), node.field,
-        getVariableUse(node.valueRef), node.sourceInformation);
-  }
-
-  Expression visitInterceptor(cps_ir.Interceptor node) {
-    return new Interceptor(getVariableUse(node.inputRef),
-        node.interceptedClasses, node.sourceInformation);
-  }
-
-  Expression visitCreateInstance(cps_ir.CreateInstance node) {
-    return new CreateInstance(
-        node.classElement,
-        translateArguments(node.argumentRefs),
-        getVariableUseOrNull(node.typeInformationRef),
-        node.sourceInformation);
-  }
-
-  Expression visitGetField(cps_ir.GetField node) {
-    return new GetField(
-        getVariableUse(node.objectRef), node.field, node.sourceInformation,
-        objectIsNotNull: !node.object.type.isNullable);
-  }
-
-  Expression visitCreateBox(cps_ir.CreateBox node) {
-    return new CreateBox();
-  }
-
-  Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
-    return new CreateInvocationMirror(
-        node.selector, translateArguments(node.argumentRefs));
-  }
-
-  Expression visitGetMutable(cps_ir.GetMutable node) {
-    return getMutableVariableUse(node.variableRef, node.sourceInformation);
-  }
-
-  Expression visitSetMutable(cps_ir.SetMutable node) {
-    Variable variable = getMutableVariable(node.variable);
-    Expression value = getVariableUse(node.valueRef);
-    return new Assign(variable, value,
-        sourceInformation: node.sourceInformation);
-  }
-
-  Expression visitConstant(cps_ir.Constant node) {
-    return new Constant(node.value, sourceInformation: node.sourceInformation);
-  }
-
-  Expression visitLiteralList(cps_ir.LiteralList node) {
-    return new LiteralList(node.dartType, translateArguments(node.valueRefs));
-  }
-
-  Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
-    return new ReifyRuntimeType(
-        getVariableUse(node.valueRef), node.sourceInformation);
-  }
-
-  Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
-    return new ReadTypeVariable(
-        node.variable, getVariableUse(node.targetRef), node.sourceInformation);
-  }
-
-  Expression visitTypeExpression(cps_ir.TypeExpression node) {
-    return new TypeExpression(node.kind, node.dartType,
-        node.argumentRefs.map(getVariableUse).toList());
-  }
-
-  Expression visitTypeTest(cps_ir.TypeTest node) {
-    Expression value = getVariableUse(node.valueRef);
-    List<Expression> typeArgs = translateArguments(node.typeArgumentRefs);
-    return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: true);
-  }
-
-  Expression visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
-    Expression value = getVariableUse(node.interceptorRef);
-    // TODO(sra): Move !! to cps_ir level.
-    return new Not(new Not(new GetTypeTestProperty(value, node.dartType)));
-  }
-
-  Expression visitGetStatic(cps_ir.GetStatic node) {
-    return new GetStatic(node.element, node.sourceInformation);
-  }
-
-  Expression visitSetStatic(cps_ir.SetStatic node) {
-    return new SetStatic(
-        node.element, getVariableUse(node.valueRef), node.sourceInformation);
-  }
-
-  Expression visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
-    if (node.operator == BuiltinOperator.IsFalsy) {
-      return new Not(getVariableUse(node.argumentRefs.single));
-    }
-    return new ApplyBuiltinOperator(node.operator,
-        translateArguments(node.argumentRefs), node.sourceInformation);
-  }
-
-  Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
-    return new ApplyBuiltinMethod(node.method, getVariableUse(node.receiverRef),
-        translateArguments(node.argumentRefs),
-        receiverIsNotNull: !node.receiver.type.isNullable);
-  }
-
-  Expression visitGetLength(cps_ir.GetLength node) {
-    return new GetLength(getVariableUse(node.objectRef));
-  }
-
-  Expression visitGetIndex(cps_ir.GetIndex node) {
-    return new GetIndex(
-        getVariableUse(node.objectRef), getVariableUse(node.indexRef));
-  }
-
-  Expression visitSetIndex(cps_ir.SetIndex node) {
-    return new SetIndex(getVariableUse(node.objectRef),
-        getVariableUse(node.indexRef), getVariableUse(node.valueRef));
-  }
-
-  Expression visitInvokeStatic(cps_ir.InvokeStatic node) {
-    List<Expression> arguments = translateArguments(node.argumentRefs);
-    return new InvokeStatic(
-        node.target, node.selector, arguments, node.sourceInformation);
-  }
-
-  List<Expression> insertReceiverArgument(
-      Expression receiver, List<Expression> arguments) {
-    return new List<Expression>.generate(
-        arguments.length + 1, (n) => n == 0 ? receiver : arguments[n - 1],
-        growable: false);
-  }
-
-  Expression visitInvokeMethod(cps_ir.InvokeMethod node) {
-    switch (node.callingConvention) {
-      case cps_ir.CallingConvention.Normal:
-        InvokeMethod invoke = new InvokeMethod(
-            getVariableUse(node.receiverRef),
-            node.selector,
-            node.mask,
-            translateArguments(node.argumentRefs),
-            node.sourceInformation);
-        invoke.receiverIsNotNull = !node.receiver.type.isNullable;
-        return invoke;
-
-      case cps_ir.CallingConvention.Intercepted:
-        List<Expression> arguments = insertReceiverArgument(
-            getVariableUse(node.receiverRef),
-            translateArguments(node.argumentRefs));
-        InvokeMethod invoke = new InvokeMethod(
-            getVariableUse(node.interceptorRef),
-            node.selector,
-            node.mask,
-            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.receiver.type.isNullable || !node.interceptor.type.isNullable;
-        return invoke;
-
-      case cps_ir.CallingConvention.DummyIntercepted:
-        List<Expression> arguments = insertReceiverArgument(
-            new Constant(new IntConstantValue(0)),
-            translateArguments(node.argumentRefs));
-        InvokeMethod invoke = new InvokeMethod(getVariableUse(node.receiverRef),
-            node.selector, node.mask, arguments, node.sourceInformation);
-        invoke.receiverIsNotNull = !node.receiver.type.isNullable;
-        return invoke;
-
-      case cps_ir.CallingConvention.OneShotIntercepted:
-        List<Expression> arguments = insertReceiverArgument(
-            getVariableUse(node.receiverRef),
-            translateArguments(node.argumentRefs));
-        return new OneShotInterceptor(
-            node.selector, node.mask, arguments, node.sourceInformation);
-    }
-  }
-
-  Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
-    if (node.interceptorRef != null) {
-      return new InvokeMethodDirectly(
-          getVariableUse(node.interceptorRef),
-          node.target,
-          node.selector,
-          insertReceiverArgument(getVariableUse(node.receiverRef),
-              translateArguments(node.argumentRefs)),
-          node.sourceInformation);
-    } else {
-      return new InvokeMethodDirectly(
-          getVariableUse(node.receiverRef),
-          node.target,
-          node.selector,
-          translateArguments(node.argumentRefs),
-          node.sourceInformation);
-    }
-  }
-
-  Expression visitTypeCast(cps_ir.TypeCast node) {
-    Expression value = getVariableUse(node.valueRef);
-    List<Expression> typeArgs = translateArguments(node.typeArgumentRefs);
-    return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: false);
-  }
-
-  Expression visitInvokeConstructor(cps_ir.InvokeConstructor node) {
-    List<Expression> arguments = translateArguments(node.argumentRefs);
-    return new InvokeConstructor(node.dartType, node.target, node.selector,
-        arguments, node.sourceInformation);
-  }
-
-  visitForeignCode(cps_ir.ForeignCode node) {
-    List<Expression> arguments =
-        node.argumentRefs.map(getVariableUse).toList(growable: false);
-    List<bool> nullableArguments = node.argumentRefs
-        .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,
-          node.sourceInformation);
-    } 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,
-            node.sourceInformation);
-      };
-    }
-  }
-
-  visitReceiverCheck(cps_ir.ReceiverCheck node) => (Statement next) {
-        // The CPS IR uses 'isNullCheck' because the semantics are important.
-        // In the Tree IR, syntax is more important, so the receiver check uses
-        // "useInvoke" to denote if an invocation should be emitted.
-        return new ReceiverCheck(
-            condition: getVariableUseOrNull(node.conditionRef),
-            value: getVariableUse(node.valueRef),
-            selector: node.selector,
-            useSelector: node.useSelector,
-            useInvoke: !node.isNullCheck,
-            next: next,
-            sourceInformation: node.sourceInformation);
-      };
-
-  Expression visitGetLazyStatic(cps_ir.GetLazyStatic node) {
-    return new GetStatic.lazy(node.element, node.sourceInformation);
-  }
-
-  @override
-  NodeCallback visitYield(cps_ir.Yield node) {
-    return (Statement next) {
-      return new Yield(getVariableUse(node.inputRef), node.hasStar, next);
-    };
-  }
-
-  @override
-  Expression visitAwait(cps_ir.Await node) {
-    return new Await(getVariableUse(node.inputRef));
-  }
-
-  @override
-  visitRefinement(cps_ir.Refinement node) {
-    return (Statement next) => next; // Compile to nothing.
-  }
-
-  /********** UNUSED VISIT METHODS *************/
-
-  unexpectedNode(cps_ir.Node node) {
-    internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node');
-  }
-
-  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
-    unexpectedNode(node);
-  }
-
-  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
deleted file mode 100644
index ea40782..0000000
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart
+++ /dev/null
@@ -1,161 +0,0 @@
-library tree_ir.integrity;
-
-import 'tree_ir_nodes.dart';
-
-/// Performs integrity checks on the tree_ir.
-///
-/// Should only be run for debugging purposes, not in production.
-///
-/// - Reference counts on must match the actual number of references.
-/// - Labels must be in scope when referenced.
-/// - Breaks must target a [LabeledStatement].
-/// - Continues must target a [Loop].
-/// - Variables must only be used after their first assignment
-///   (checked on a best-effort basis).
-/// - Variables with a declaration must only be referenced in scope.
-/// - Variables must not have more than one declaration.
-///
-class CheckTreeIntegrity extends RecursiveVisitor {
-  FunctionDefinition topLevelNode;
-
-  Map<Variable, int> varReads = <Variable, int>{};
-  Map<Variable, int> varWrites = <Variable, int>{};
-  Map<Label, int> labelUses = <Label, int>{};
-  Map<Label, JumpTarget> label2declaration = <Label, JumpTarget>{};
-
-  /// Variables that are currently in scope.
-  Set<Variable> scope = new Set<Variable>();
-
-  /// Variables for which we have seen a declaration.
-  Set<Variable> seenDeclaration = new Set<Variable>();
-
-  void write(Variable variable) {
-    if (!seenDeclaration.contains(variable)) {
-      // Implicitly-declared variables are in scope after the first assignment.
-      scope.add(variable);
-    } else if (!scope.contains(variable)) {
-      // There is a declaration for variable but it is no longer in scope.
-      error('$variable assigned out of scope');
-    }
-    varWrites.putIfAbsent(variable, () => 0);
-    varWrites[variable]++;
-  }
-
-  void read(Variable variable) {
-    if (!scope.contains(variable)) {
-      error('$variable used out of scope');
-    }
-    varReads.putIfAbsent(variable, () => 0);
-    varReads[variable]++;
-  }
-
-  void declare(Variable variable) {
-    if (!scope.add(variable) || !seenDeclaration.add(variable)) {
-      error('Redeclared $variable');
-    }
-    varWrites.putIfAbsent(variable, () => 0);
-    varWrites[variable]++;
-  }
-
-  void undeclare(Variable variable) {
-    scope.remove(variable);
-  }
-
-  visitVariableUse(VariableUse node) {
-    read(node.variable);
-  }
-
-  visitAssign(Assign node) {
-    visitExpression(node.value);
-    write(node.variable);
-  }
-
-  visitTry(Try node) {
-    visitStatement(node.tryBody);
-    node.catchParameters.forEach(declare);
-    visitStatement(node.catchBody);
-    node.catchParameters.forEach(undeclare);
-  }
-
-  visitJumpTargetBody(JumpTarget target) {
-    Label label = target.label;
-    if (label2declaration.containsKey(label)) {
-      error('Duplicate declaration of label $label');
-    }
-    label2declaration[label] = target;
-    labelUses[label] = 0;
-    visitStatement(target.body);
-    label2declaration.remove(label);
-
-    if (labelUses[label] != label.useCount) {
-      error('Label $label has ${labelUses[label]} uses '
-          'but its reference count is ${label.useCount}');
-    }
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    visitJumpTargetBody(node);
-    visitStatement(node.next);
-  }
-
-  visitWhileTrue(WhileTrue node) {
-    visitJumpTargetBody(node);
-  }
-
-  visitFor(For node) {
-    visitExpression(node.condition);
-    visitJumpTargetBody(node);
-    node.updates.forEach(visitExpression);
-    visitStatement(node.next);
-  }
-
-  visitBreak(Break node) {
-    if (!label2declaration.containsKey(node.target)) {
-      error('Break to label that is not in scope');
-    }
-    if (label2declaration[node.target] is! LabeledStatement) {
-      error('Break to non-labeled statement ${label2declaration[node.target]}');
-    }
-    labelUses[node.target]++;
-  }
-
-  visitContinue(Continue node) {
-    if (!label2declaration.containsKey(node.target)) {
-      error('Continue to label that is not in scope');
-    }
-    if (label2declaration[node.target] is! Loop) {
-      error('Continue to non-loop statement ${label2declaration[node.target]}');
-    }
-    labelUses[node.target]++;
-  }
-
-  void checkBody(FunctionDefinition node) {
-    node.parameters.forEach(declare);
-    visitStatement(node.body);
-    node.parameters.forEach(undeclare);
-  }
-
-  dynamic error(String message) {
-    throw 'Tree IR integrity violation in ${topLevelNode.element}:\n$message';
-  }
-
-  void check(FunctionDefinition node) {
-    topLevelNode = node;
-    checkBody(node);
-
-    // Verify reference counters for all variables.
-    List<Variable> seenVariables = new List<Variable>();
-    seenVariables.addAll(varReads.keys);
-    seenVariables.addAll(varWrites.keys);
-    for (Variable variable in seenVariables) {
-      int reads = varReads.putIfAbsent(variable, () => 0);
-      int writes = varWrites.putIfAbsent(variable, () => 0);
-      if (reads != variable.readCount || writes != variable.writeCount) {
-        error('Invalid reference count for $variable:\n'
-            '- Variable has $reads reads and $writes writes\n'
-            '- Reference count is ${variable.readCount} reads and '
-            '${variable.writeCount} writes');
-      }
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
deleted file mode 100644
index a1fe55e..0000000
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ /dev/null
@@ -1,1607 +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 tree_ir_nodes;
-
-import '../constants/values.dart' as values;
-import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
-import '../elements/elements.dart';
-import '../io/source_information.dart' show SourceInformation;
-import '../types/types.dart' show TypeMask;
-import '../universe/selector.dart' show Selector;
-
-import '../cps_ir/builtin_operator.dart';
-export '../cps_ir/builtin_operator.dart';
-import '../cps_ir/cps_ir_nodes.dart' show TypeExpressionKind;
-export '../cps_ir/cps_ir_nodes.dart' show TypeExpressionKind;
-
-// 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 '../native/native.dart' as native show NativeBehavior;
-import '../types/types.dart' as types show TypeMask;
-
-// The Tree language is the target of translation out of the CPS-based IR.
-//
-// The translation from CPS to Dart consists of several stages.  Among the
-// stages are translation to direct style, translation out of SSA, eliminating
-// unnecessary names, recognizing high-level control constructs.  Combining
-// these separate concerns is complicated and the constraints of the CPS-based
-// language do not permit a multi-stage translation.
-//
-// For that reason, CPS is translated to the direct-style language Tree.
-// Translation out of SSA, unnaming, and control-flow, as well as 'instruction
-// selection' are performed on the Tree language.
-//
-// In contrast to the CPS-based IR, non-primitive expressions can be named and
-// arguments (to calls, primitives, and blocks) can be arbitrary expressions.
-//
-// Additionally, variables are considered in scope within inner functions;
-// closure variables are thus handled directly instead of using ref cells.
-
-/**
- * The base class of all Tree nodes.
- */
-abstract class Node {
-  /// Workaround for a slow Object.hashCode in the VM.
-  static int _usedHashCodes = 0;
-  final int hashCode = ++_usedHashCodes;
-}
-
-/**
- * The base class of [Expression]s.
- */
-abstract class Expression extends Node {
-  accept(ExpressionVisitor v);
-  accept1(ExpressionVisitor1 v, arg);
-
-  SourceInformation get sourceInformation => null;
-}
-
-abstract class Statement extends Node {
-  Statement get next;
-  void set next(Statement s);
-  accept(StatementVisitor v);
-  accept1(StatementVisitor1 v, arg);
-}
-
-/**
- * Labels name [LabeledStatement]s.
- */
-class Label {
-  /// 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.
-  int useCount = 0;
-
-  /// The [LabeledStatement] or [WhileTrue] binding this label.
-  JumpTarget binding;
-}
-
-/**
- * A local variable in the tree IR.
- *
- * All tree IR variables are mutable.
- *
- * To use a variable as an expression, reference it from a [VariableUse], with
- * one [VariableUse] per expression.
- *
- * [Variable]s are reference counted. The node constructors [VariableUse],
- * [Assign], [FunctionDefinition], and [Try] automatically update the reference
- * count for their variables, but when transforming the tree, the transformer
- * is responsible for updating reference counts.
- */
-class Variable extends Node {
-  /// Function that declares this variable.
-  ExecutableElement host;
-
-  /// [Entity] used for synthesizing a name for the variable.
-  /// Different variables may have the same entity. May be null.
-  Entity element;
-
-  /// Number of places where this variable occurs in a [VariableUse].
-  int readCount = 0;
-
-  /// Number of places where this variable occurs as:
-  /// - left-hand of an [Assign]
-  /// - parameter in a [FunctionDefinition]
-  /// - catch parameter in a [Try]
-  int writeCount = 0;
-
-  /// True if an inner JS function might access this variable through a
-  /// [ForeignCode] node.
-  bool isCaptured = false;
-
-  Variable(this.host, this.element) {
-    assert(host != null);
-  }
-
-  String toString() =>
-      element == null ? 'Variable.${hashCode}' : element.toString();
-}
-
-/// Read the value of a variable.
-class VariableUse extends Expression {
-  Variable variable;
-  SourceInformation sourceInformation;
-
-  /// Creates a use of [variable] and updates its `readCount`.
-  VariableUse(this.variable, {this.sourceInformation}) {
-    variable.readCount++;
-  }
-
-  accept(ExpressionVisitor visitor) => visitor.visitVariableUse(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitVariableUse(this, arg);
-  }
-}
-
-class Assign extends Expression {
-  Variable variable;
-  Expression value;
-  SourceInformation sourceInformation;
-
-  Assign(this.variable, this.value, {this.sourceInformation}) {
-    variable.writeCount++;
-  }
-
-  accept(ExpressionVisitor v) => v.visitAssign(this);
-  accept1(ExpressionVisitor1 v, arg) => v.visitAssign(this, arg);
-
-  static ExpressionStatement makeStatement(Variable variable, Expression value,
-      [Statement next]) {
-    return new ExpressionStatement(new Assign(variable, value), next);
-  }
-}
-
-/**
- * Common interface for invocations with arguments.
- */
-abstract class Invoke {
-  List<Expression> get arguments;
-}
-
-/**
- * A call to a static function or getter/setter to a static field.
- *
- * In contrast to the CPS-based IR, the arguments can be arbitrary expressions.
- */
-class InvokeStatic extends Expression implements Invoke {
-  final Entity target;
-  final List<Expression> arguments;
-  final Selector selector;
-  final SourceInformation sourceInformation;
-
-  InvokeStatic(this.target, this.selector, this.arguments,
-      [this.sourceInformation]);
-
-  accept(ExpressionVisitor visitor) => visitor.visitInvokeStatic(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitInvokeStatic(this, arg);
-  }
-}
-
-/**
- * A call to a method, operator, getter, setter or index getter/setter.
- *
- * If [receiver] is `null`, an error is thrown before the arguments are
- * evaluated. This corresponds to the JS evaluation order.
- */
-class InvokeMethod extends Expression implements Invoke {
-  Expression receiver;
-  final Selector selector;
-  final TypeMask mask;
-  final List<Expression> arguments;
-  final SourceInformation sourceInformation;
-
-  /// If true, it is known that the receiver cannot be `null`.
-  bool receiverIsNotNull = false;
-
-  InvokeMethod(this.receiver, this.selector, this.mask, this.arguments,
-      this.sourceInformation) {
-    assert(receiver != null);
-  }
-
-  accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitInvokeMethod(this, arg);
-  }
-}
-
-/// Invoke [target] on [receiver], bypassing ordinary dispatch semantics.
-///
-/// Since the [receiver] is not used for method lookup, it may be `null`
-/// without an error being thrown.
-class InvokeMethodDirectly extends Expression implements Invoke {
-  Expression receiver;
-  final Element target;
-  final Selector selector;
-  final List<Expression> arguments;
-  final SourceInformation sourceInformation;
-
-  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);
-  }
-}
-
-/**
- * Call to a factory or generative constructor.
- */
-class InvokeConstructor extends Expression implements Invoke {
-  final DartType type;
-  final FunctionElement target;
-  final List<Expression> arguments;
-  final Selector selector;
-  final SourceInformation sourceInformation;
-
-  /// TODO(karlklose): get rid of this field.  Instead use the constant's
-  /// expression to find the constructor to be called in dart2dart.
-  final values.ConstantValue constant;
-
-  InvokeConstructor(this.type, this.target, this.selector, this.arguments,
-      this.sourceInformation,
-      [this.constant]);
-
-  ClassElement get targetClass => target.enclosingElement;
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitInvokeConstructor(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitInvokeConstructor(this, arg);
-  }
-}
-
-/// 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.
- */
-class Constant extends Expression {
-  final values.ConstantValue value;
-  final SourceInformation sourceInformation;
-
-  Constant(this.value, {this.sourceInformation});
-
-  Constant.bool(values.BoolConstantValue constantValue)
-      : value = constantValue,
-        sourceInformation = null;
-
-  accept(ExpressionVisitor visitor) => visitor.visitConstant(this);
-  accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg);
-
-  String toString() => 'Constant(value=${value.toStructuredText()})';
-}
-
-class This extends Expression {
-  accept(ExpressionVisitor visitor) => visitor.visitThis(this);
-  accept1(ExpressionVisitor1 visitor, arg) => visitor.visitThis(this, arg);
-}
-
-class LiteralList extends Expression {
-  final InterfaceType type;
-  final List<Expression> values;
-
-  LiteralList(this.type, this.values);
-
-  accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitLiteralList(this, arg);
-  }
-}
-
-/// Type test or type cast.
-///
-/// Note that if this is a type test, then [type] cannot be `Object`, `dynamic`,
-/// or the `Null` type. These cases are compiled to other node types.
-class TypeOperator extends Expression {
-  Expression value;
-  final DartType type;
-  final List<Expression> typeArguments;
-  final bool isTypeTest;
-
-  TypeOperator(this.value, this.type, this.typeArguments,
-      {bool this.isTypeTest});
-
-  accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitTypeOperator(this, arg);
-  }
-
-  String get operator => isTypeTest ? 'is' : 'as';
-}
-
-/**
- * Apply a built-in operator.
- *
- * It must be known that the arguments have the proper types.
- * Null is not a valid argument to any of the built-in operators.
- */
-class ApplyBuiltinOperator extends Expression {
-  BuiltinOperator operator;
-  List<Expression> arguments;
-  SourceInformation sourceInformation;
-
-  ApplyBuiltinOperator(this.operator, this.arguments, this.sourceInformation);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitApplyBuiltinOperator(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitApplyBuiltinOperator(this, arg);
-  }
-}
-
-class ApplyBuiltinMethod extends Expression {
-  BuiltinMethod method;
-  Expression receiver;
-  List<Expression> arguments;
-
-  bool receiverIsNotNull;
-
-  ApplyBuiltinMethod(this.method, this.receiver, this.arguments,
-      {this.receiverIsNotNull: false});
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitApplyBuiltinMethod(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitApplyBuiltinMethod(this, arg);
-  }
-}
-
-/// A conditional expression.
-class Conditional extends Expression {
-  Expression condition;
-  Expression thenExpression;
-  Expression elseExpression;
-
-  Conditional(this.condition, this.thenExpression, this.elseExpression);
-
-  accept(ExpressionVisitor visitor) => visitor.visitConditional(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitConditional(this, arg);
-  }
-
-  String toString() => 'Conditional(condition=$condition,thenExpression='
-      '$thenExpression,elseExpression=$elseExpression)';
-}
-
-/// An && or || expression. The operator is internally represented as a boolean
-/// [isAnd] to simplify rewriting of logical operators.
-/// Note the result of && and || is one of the arguments, which might not be
-/// boolean. 'ShortCircuitOperator' might have been a better name.
-class LogicalOperator extends Expression {
-  Expression left;
-  bool isAnd;
-  Expression right;
-
-  LogicalOperator(this.left, this.right, this.isAnd);
-  LogicalOperator.and(this.left, this.right) : isAnd = true;
-  LogicalOperator.or(this.left, this.right) : isAnd = false;
-
-  String get operator => isAnd ? '&&' : '||';
-
-  accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitLogicalOperator(this, arg);
-  }
-
-  String toString() => 'LogicalOperator(left=$left,right=$right,isAnd=$isAnd)';
-}
-
-/// Logical negation.
-// TODO(asgerf): Replace this class with the IsFalsy builtin operator?
-//               Right now the tree builder compiles IsFalsy to Not.
-class Not extends Expression {
-  Expression operand;
-
-  Not(this.operand);
-
-  accept(ExpressionVisitor visitor) => visitor.visitNot(this);
-  accept1(ExpressionVisitor1 visitor, arg) => visitor.visitNot(this, arg);
-}
-
-/// A [LabeledStatement] or [WhileTrue] or [For].
-abstract class JumpTarget extends Statement {
-  Label get label;
-  Statement get body;
-}
-
-/**
- * A labeled statement.  Breaks to the label within the labeled statement
- * target the successor statement.
- */
-class LabeledStatement extends JumpTarget {
-  Statement next;
-  final Label label;
-  Statement body;
-
-  LabeledStatement(this.label, this.body, this.next) {
-    assert(label.binding == null);
-    label.binding = this;
-  }
-
-  accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this);
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitLabeledStatement(this, arg);
-  }
-}
-
-/// A [WhileTrue] or [For] loop.
-abstract class Loop extends JumpTarget {}
-
-/**
- * A labeled while(true) loop.
- */
-class WhileTrue extends Loop {
-  final Label label;
-  Statement body;
-
-  WhileTrue(this.label, this.body) {
-    assert(label.binding == null);
-    label.binding = this;
-  }
-
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  accept(StatementVisitor visitor) => visitor.visitWhileTrue(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitWhileTrue(this, arg);
-}
-
-/**
- * A loop with a condition and update expressions. If there are any update
- * expressions, this generates a for loop, otherwise a while loop.
- *
- * When the condition is false, control resumes at the [next] statement.
- *
- * It is NOT valid to target this statement with a [Break].
- * The only way to reach [next] is for the condition to evaluate to false.
- *
- * [For] statements are introduced in the [LoopRewriter] and are
- * assumed not to occur before then.
- */
-class For extends Loop {
-  final Label label;
-  Expression condition;
-  List<Expression> updates;
-  Statement body;
-  Statement next;
-
-  For(this.label, this.condition, this.updates, this.body, this.next) {
-    assert(label.binding == null);
-    label.binding = this;
-  }
-
-  accept(StatementVisitor visitor) => visitor.visitFor(this);
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitFor(this, arg);
-  }
-}
-
-/// A [Break] or [Continue] statement.
-abstract class Jump extends Statement {
-  Label get target;
-}
-
-/**
- * A break from an enclosing [LabeledStatement].  The break targets the
- * labeled statement's successor statement.
- */
-class Break extends Jump {
-  final Label target;
-
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  Break(this.target) {
-    ++target.useCount;
-  }
-
-  accept(StatementVisitor visitor) => visitor.visitBreak(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitBreak(this, arg);
-}
-
-/**
- * A continue to an enclosing [WhileTrue] or [For] loop.
- * The continue targets the loop's body.
- */
-class Continue extends Jump {
-  final Label target;
-
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  Continue(this.target) {
-    ++target.useCount;
-  }
-
-  accept(StatementVisitor visitor) => visitor.visitContinue(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitContinue(this, arg);
-}
-
-/**
- * A return exit from the function.
- *
- * In contrast to the CPS-based IR, the return value is an arbitrary
- * expression.
- */
-class Return extends Statement {
-  /// Should not be null. Use [Constant] with [NullConstantValue] for void
-  /// returns.
-  /// Even in constructors this holds true. Take special care when translating
-  /// back to dart, where `return null;` in a constructor is an error.
-  Expression value;
-  SourceInformation sourceInformation;
-
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  Return(this.value, {this.sourceInformation});
-
-  accept(StatementVisitor visitor) => visitor.visitReturn(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitReturn(this, arg);
-}
-
-/// A throw statement.
-///
-/// In the Tree IR, throw is a statement (like JavaScript and unlike Dart).
-/// It does not have a successor statement.
-class Throw extends Statement {
-  Expression value;
-
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  Throw(this.value);
-
-  accept(StatementVisitor visitor) => visitor.visitThrow(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitThrow(this, arg);
-}
-
-/**
- * A conditional branch based on the true value of an [Expression].
- */
-class If extends Statement {
-  Expression condition;
-  Statement thenStatement;
-  Statement elseStatement;
-  SourceInformation sourceInformation;
-
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  If(this.condition, this.thenStatement, this.elseStatement,
-      this.sourceInformation);
-
-  accept(StatementVisitor visitor) => visitor.visitIf(this);
-  accept1(StatementVisitor1 visitor, arg) => visitor.visitIf(this, arg);
-}
-
-class ExpressionStatement extends Statement {
-  Statement next;
-  Expression expression;
-
-  ExpressionStatement(this.expression, this.next);
-
-  accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this);
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitExpressionStatement(this, arg);
-  }
-}
-
-class Try extends Statement {
-  Statement tryBody;
-  List<Variable> catchParameters;
-  Statement catchBody;
-
-  Statement get next => null;
-  void set next(Statement s) => throw 'UNREACHABLE';
-
-  Try(this.tryBody, this.catchParameters, this.catchBody) {
-    for (Variable variable in catchParameters) {
-      variable.writeCount++; // Being a catch parameter counts as a write.
-    }
-  }
-
-  accept(StatementVisitor visitor) => visitor.visitTry(this);
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitTry(this, arg);
-  }
-}
-
-/// A statement that is known to be unreachable.
-class Unreachable extends Statement {
-  Statement get next => null;
-  void set next(Statement value) => throw 'UNREACHABLE';
-
-  accept(StatementVisitor visitor) => visitor.visitUnreachable(this);
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitUnreachable(this, arg);
-  }
-}
-
-class FunctionDefinition extends Node {
-  final ExecutableElement element;
-  final List<Variable> parameters;
-  final SourceInformation sourceInformation;
-  Statement body;
-
-  /// Creates a function definition and updates `writeCount` for [parameters].
-  FunctionDefinition(this.element, this.parameters, this.body,
-      {this.sourceInformation}) {
-    for (Variable param in parameters) {
-      param.writeCount++; // Being a parameter counts as a write.
-    }
-  }
-}
-
-class CreateBox extends Expression {
-  accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this);
-  accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg);
-}
-
-class CreateInstance extends Expression {
-  ClassElement classElement;
-  List<Expression> arguments;
-  Expression typeInformation;
-  SourceInformation sourceInformation;
-
-  CreateInstance(this.classElement, this.arguments, this.typeInformation,
-      this.sourceInformation);
-
-  accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitCreateInstance(this, arg);
-  }
-}
-
-class GetField extends Expression {
-  Expression object;
-  Element field;
-  bool objectIsNotNull;
-  SourceInformation sourceInformation;
-
-  GetField(this.object, this.field, this.sourceInformation,
-      {this.objectIsNotNull: false});
-
-  accept(ExpressionVisitor visitor) => visitor.visitGetField(this);
-  accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetField(this, arg);
-}
-
-class SetField extends Expression {
-  Expression object;
-  Element field;
-  Expression value;
-  SourceInformation sourceInformation;
-
-  /// 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.sourceInformation,
-      {this.compound});
-
-  accept(ExpressionVisitor visitor) => visitor.visitSetField(this);
-  accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
-}
-
-/// Read the type test property from [object]. The value is truthy/fasly rather
-/// than bool. [object] must not be `null`.
-class GetTypeTestProperty extends Expression {
-  Expression object;
-  DartType dartType;
-
-  GetTypeTestProperty(this.object, this.dartType);
-
-  accept(ExpressionVisitor visitor) => visitor.visitGetTypeTestProperty(this);
-  accept1(ExpressionVisitor1 visitor, arg) =>
-      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);
-}
-
-class SetStatic extends Expression {
-  Element element;
-  Expression value;
-  SourceInformation sourceInformation;
-  BuiltinOperator compound;
-
-  SetStatic(this.element, this.value, this.sourceInformation, {this.compound});
-
-  accept(ExpressionVisitor visitor) => visitor.visitSetStatic(this);
-  accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetStatic(this, arg);
-}
-
-class GetLength extends Expression {
-  Expression object;
-
-  GetLength(this.object);
-
-  accept(ExpressionVisitor v) => v.visitGetLength(this);
-  accept1(ExpressionVisitor1 v, arg) => v.visitGetLength(this, arg);
-}
-
-class GetIndex extends Expression {
-  Expression object;
-  Expression index;
-
-  GetIndex(this.object, this.index);
-
-  accept(ExpressionVisitor v) => v.visitGetIndex(this);
-  accept1(ExpressionVisitor1 v, arg) => v.visitGetIndex(this, arg);
-}
-
-class SetIndex extends Expression {
-  Expression object;
-  Expression index;
-  Expression value;
-  BuiltinOperator compound;
-
-  SetIndex(this.object, this.index, this.value, {this.compound});
-
-  accept(ExpressionVisitor v) => v.visitSetIndex(this);
-  accept1(ExpressionVisitor1 v, arg) => v.visitSetIndex(this, arg);
-}
-
-class ReifyRuntimeType extends Expression {
-  Expression value;
-  SourceInformation sourceInformation;
-
-  ReifyRuntimeType(this.value, this.sourceInformation);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitReifyRuntimeType(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitReifyRuntimeType(this, arg);
-  }
-}
-
-class ReadTypeVariable extends Expression {
-  final TypeVariableType variable;
-  Expression target;
-  final SourceInformation sourceInformation;
-
-  ReadTypeVariable(this.variable, this.target, this.sourceInformation);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitReadTypeVariable(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitReadTypeVariable(this, arg);
-  }
-}
-
-class CreateInvocationMirror extends Expression {
-  final Selector selector;
-  final List<Expression> arguments;
-
-  CreateInvocationMirror(this.selector, this.arguments);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitCreateInvocationMirror(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitCreateInvocationMirror(this, arg);
-  }
-}
-
-class Interceptor extends Expression {
-  Expression input;
-  Set<ClassElement> interceptedClasses;
-  final SourceInformation sourceInformation;
-
-  Interceptor(this.input, this.interceptedClasses, this.sourceInformation);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitInterceptor(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitInterceptor(this, arg);
-  }
-}
-
-class ForeignCode extends Node {
-  final js.Template codeTemplate;
-  final types.TypeMask type;
-  final List<Expression> arguments;
-  final native.NativeBehavior nativeBehavior;
-  final List<bool> nullableArguments; // One 'bit' per argument.
-  final Element dependency;
-  final SourceInformation sourceInformation;
-
-  ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior,
-      this.nullableArguments, this.dependency, this.sourceInformation) {
-    assert(arguments.length == nullableArguments.length);
-  }
-}
-
-class ForeignExpression extends ForeignCode implements Expression {
-  ForeignExpression(
-      js.Template codeTemplate,
-      types.TypeMask type,
-      List<Expression> arguments,
-      native.NativeBehavior nativeBehavior,
-      List<bool> nullableArguments,
-      Element dependency,
-      SourceInformation sourceInformation)
-      : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
-            dependency, sourceInformation);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitForeignExpression(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitForeignExpression(this, arg);
-  }
-}
-
-class ForeignStatement extends ForeignCode implements Statement {
-  ForeignStatement(
-      js.Template codeTemplate,
-      types.TypeMask type,
-      List<Expression> arguments,
-      native.NativeBehavior nativeBehavior,
-      List<bool> nullableArguments,
-      Element dependency,
-      SourceInformation sourceInformation)
-      : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
-            dependency, sourceInformation);
-
-  accept(StatementVisitor visitor) {
-    return visitor.visitForeignStatement(this);
-  }
-
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitForeignStatement(this, arg);
-  }
-
-  @override
-  Statement get next => null;
-
-  @override
-  void set next(Statement s) => throw 'UNREACHABLE';
-}
-
-/// Denotes the internal representation of [dartType], where all type variables
-/// are replaced by the values in [arguments].
-/// (See documentation on the TypeExpression CPS node for more details.)
-class TypeExpression extends Expression {
-  final TypeExpressionKind kind;
-  final DartType dartType;
-  final List<Expression> arguments;
-
-  TypeExpression(this.kind, this.dartType, this.arguments);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitTypeExpression(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitTypeExpression(this, arg);
-  }
-}
-
-class Await extends Expression {
-  Expression input;
-
-  Await(this.input);
-
-  accept(ExpressionVisitor visitor) {
-    return visitor.visitAwait(this);
-  }
-
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitAwait(this, arg);
-  }
-}
-
-class Yield extends Statement {
-  Statement next;
-  Expression input;
-  final bool hasStar;
-
-  Yield(this.input, this.hasStar, this.next);
-
-  accept(StatementVisitor visitor) {
-    return visitor.visitYield(this);
-  }
-
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitYield(this, arg);
-  }
-}
-
-class ReceiverCheck extends Statement {
-  Expression condition;
-  Expression value;
-  Selector selector;
-  bool useSelector;
-  bool useInvoke;
-  Statement next;
-  SourceInformation sourceInformation;
-
-  ReceiverCheck(
-      {this.condition,
-      this.value,
-      this.selector,
-      this.useSelector,
-      this.useInvoke,
-      this.next,
-      this.sourceInformation});
-
-  accept(StatementVisitor visitor) {
-    return visitor.visitReceiverCheck(this);
-  }
-
-  accept1(StatementVisitor1 visitor, arg) {
-    return visitor.visitReceiverCheck(this, arg);
-  }
-}
-
-abstract class ExpressionVisitor<E> {
-  E visitExpression(Expression node) => node.accept(this);
-  E visitVariableUse(VariableUse node);
-  E visitAssign(Assign node);
-  E visitInvokeStatic(InvokeStatic node);
-  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);
-  E visitLogicalOperator(LogicalOperator node);
-  E visitNot(Not node);
-  E visitLiteralList(LiteralList node);
-  E visitTypeOperator(TypeOperator node);
-  E visitGetField(GetField node);
-  E visitSetField(SetField node);
-  E visitGetStatic(GetStatic node);
-  E visitSetStatic(SetStatic node);
-  E visitGetTypeTestProperty(GetTypeTestProperty node);
-  E visitCreateBox(CreateBox node);
-  E visitCreateInstance(CreateInstance node);
-  E visitReifyRuntimeType(ReifyRuntimeType node);
-  E visitReadTypeVariable(ReadTypeVariable node);
-  E visitTypeExpression(TypeExpression node);
-  E visitCreateInvocationMirror(CreateInvocationMirror node);
-  E visitInterceptor(Interceptor node);
-  E visitApplyBuiltinOperator(ApplyBuiltinOperator node);
-  E visitApplyBuiltinMethod(ApplyBuiltinMethod node);
-  E visitForeignExpression(ForeignExpression node);
-  E visitGetLength(GetLength node);
-  E visitGetIndex(GetIndex node);
-  E visitSetIndex(SetIndex node);
-  E visitAwait(Await node);
-}
-
-abstract class ExpressionVisitor1<E, A> {
-  E visitExpression(Expression node, A arg) => node.accept1(this, arg);
-  E visitVariableUse(VariableUse node, A arg);
-  E visitAssign(Assign node, A arg);
-  E visitInvokeStatic(InvokeStatic node, A arg);
-  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);
-  E visitLogicalOperator(LogicalOperator node, A arg);
-  E visitNot(Not node, A arg);
-  E visitLiteralList(LiteralList node, A arg);
-  E visitTypeOperator(TypeOperator node, A arg);
-  E visitGetField(GetField node, A arg);
-  E visitSetField(SetField node, A arg);
-  E visitGetStatic(GetStatic node, A arg);
-  E visitSetStatic(SetStatic node, A arg);
-  E visitGetTypeTestProperty(GetTypeTestProperty node, A arg);
-  E visitCreateBox(CreateBox node, A arg);
-  E visitCreateInstance(CreateInstance node, A arg);
-  E visitReifyRuntimeType(ReifyRuntimeType node, A arg);
-  E visitReadTypeVariable(ReadTypeVariable node, A arg);
-  E visitTypeExpression(TypeExpression node, A arg);
-  E visitCreateInvocationMirror(CreateInvocationMirror node, A arg);
-  E visitInterceptor(Interceptor node, A arg);
-  E visitApplyBuiltinOperator(ApplyBuiltinOperator node, A arg);
-  E visitApplyBuiltinMethod(ApplyBuiltinMethod node, A arg);
-  E visitForeignExpression(ForeignExpression node, A arg);
-  E visitGetLength(GetLength node, A arg);
-  E visitGetIndex(GetIndex node, A arg);
-  E visitSetIndex(SetIndex node, A arg);
-  E visitAwait(Await node, A arg);
-}
-
-abstract class StatementVisitor<S> {
-  S visitStatement(Statement node) => node.accept(this);
-  S visitLabeledStatement(LabeledStatement node);
-  S visitReturn(Return node);
-  S visitThrow(Throw node);
-  S visitBreak(Break node);
-  S visitContinue(Continue node);
-  S visitIf(If node);
-  S visitWhileTrue(WhileTrue node);
-  S visitFor(For node);
-  S visitExpressionStatement(ExpressionStatement node);
-  S visitTry(Try node);
-  S visitUnreachable(Unreachable node);
-  S visitForeignStatement(ForeignStatement node);
-  S visitYield(Yield node);
-  S visitReceiverCheck(ReceiverCheck node);
-}
-
-abstract class StatementVisitor1<S, A> {
-  S visitStatement(Statement node, A arg) => node.accept1(this, arg);
-  S visitLabeledStatement(LabeledStatement node, A arg);
-  S visitReturn(Return node, A arg);
-  S visitThrow(Throw node, A arg);
-  S visitBreak(Break node, A arg);
-  S visitContinue(Continue node, A arg);
-  S visitIf(If node, A arg);
-  S visitWhileTrue(WhileTrue node, A arg);
-  S visitFor(For node, A arg);
-  S visitExpressionStatement(ExpressionStatement node, A arg);
-  S visitTry(Try node, A arg);
-  S visitUnreachable(Unreachable node, A arg);
-  S visitForeignStatement(ForeignStatement node, A arg);
-  S visitYield(Yield node, A arg);
-  S visitReceiverCheck(ReceiverCheck node, A arg);
-}
-
-abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
-  visitExpression(Expression e) => e.accept(this);
-  visitStatement(Statement s) => s.accept(this);
-
-  visitVariable(Variable variable) {}
-
-  visitVariableUse(VariableUse node) {
-    visitVariable(node.variable);
-  }
-
-  visitAssign(Assign node) {
-    visitVariable(node.variable);
-    visitExpression(node.value);
-  }
-
-  visitInvokeStatic(InvokeStatic node) {
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitInvokeMethod(InvokeMethod node) {
-    visitExpression(node.receiver);
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    visitExpression(node.receiver);
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitInvokeConstructor(InvokeConstructor node) {
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitOneShotInterceptor(OneShotInterceptor node) {
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitConstant(Constant node) {}
-
-  visitThis(This node) {}
-
-  visitConditional(Conditional node) {
-    visitExpression(node.condition);
-    visitExpression(node.thenExpression);
-    visitExpression(node.elseExpression);
-  }
-
-  visitLogicalOperator(LogicalOperator node) {
-    visitExpression(node.left);
-    visitExpression(node.right);
-  }
-
-  visitNot(Not node) {
-    visitExpression(node.operand);
-  }
-
-  visitLiteralList(LiteralList node) {
-    node.values.forEach(visitExpression);
-  }
-
-  visitTypeOperator(TypeOperator node) {
-    visitExpression(node.value);
-    node.typeArguments.forEach(visitExpression);
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    visitStatement(node.body);
-    visitStatement(node.next);
-  }
-
-  visitReturn(Return node) {
-    visitExpression(node.value);
-  }
-
-  visitThrow(Throw node) {
-    visitExpression(node.value);
-  }
-
-  visitBreak(Break node) {}
-
-  visitContinue(Continue node) {}
-
-  visitIf(If node) {
-    visitExpression(node.condition);
-    visitStatement(node.thenStatement);
-    visitStatement(node.elseStatement);
-  }
-
-  visitWhileTrue(WhileTrue node) {
-    visitStatement(node.body);
-  }
-
-  visitFor(For node) {
-    visitExpression(node.condition);
-    node.updates.forEach(visitExpression);
-    visitStatement(node.body);
-    visitStatement(node.next);
-  }
-
-  visitExpressionStatement(ExpressionStatement inputNode) {
-    // Iterate over chains of expression statements to avoid deep recursion.
-    Statement node = inputNode;
-    while (node is ExpressionStatement) {
-      ExpressionStatement stmt = node;
-      visitExpression(stmt.expression);
-      node = stmt.next;
-    }
-    visitStatement(node);
-  }
-
-  visitTry(Try node) {
-    visitStatement(node.tryBody);
-    visitStatement(node.catchBody);
-  }
-
-  visitGetField(GetField node) {
-    visitExpression(node.object);
-  }
-
-  visitSetField(SetField node) {
-    visitExpression(node.object);
-    visitExpression(node.value);
-  }
-
-  visitGetStatic(GetStatic node) {}
-
-  visitSetStatic(SetStatic node) {
-    visitExpression(node.value);
-  }
-
-  visitGetTypeTestProperty(GetTypeTestProperty node) {
-    visitExpression(node.object);
-  }
-
-  visitCreateBox(CreateBox node) {}
-
-  visitCreateInstance(CreateInstance node) {
-    node.arguments.forEach(visitExpression);
-    if (node.typeInformation != null) visitExpression(node.typeInformation);
-  }
-
-  visitReifyRuntimeType(ReifyRuntimeType node) {
-    visitExpression(node.value);
-  }
-
-  visitReadTypeVariable(ReadTypeVariable node) {
-    visitExpression(node.target);
-  }
-
-  visitTypeExpression(TypeExpression node) {
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitCreateInvocationMirror(CreateInvocationMirror node) {
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitUnreachable(Unreachable node) {}
-
-  visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    visitExpression(node.receiver);
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitInterceptor(Interceptor node) {
-    visitExpression(node.input);
-  }
-
-  visitForeignCode(ForeignCode node) {
-    node.arguments.forEach(visitExpression);
-  }
-
-  visitForeignExpression(ForeignExpression node) => visitForeignCode(node);
-  visitForeignStatement(ForeignStatement node) => visitForeignCode(node);
-
-  visitGetLength(GetLength node) {
-    visitExpression(node.object);
-  }
-
-  visitGetIndex(GetIndex node) {
-    visitExpression(node.object);
-    visitExpression(node.index);
-  }
-
-  visitSetIndex(SetIndex node) {
-    visitExpression(node.object);
-    visitExpression(node.index);
-    visitExpression(node.value);
-  }
-
-  visitAwait(Await node) {
-    visitExpression(node.input);
-  }
-
-  visitYield(Yield node) {
-    visitExpression(node.input);
-    visitStatement(node.next);
-  }
-
-  visitReceiverCheck(ReceiverCheck node) {
-    if (node.condition != null) visitExpression(node.condition);
-    visitExpression(node.value);
-    visitStatement(node.next);
-  }
-}
-
-abstract class Transformer
-    implements ExpressionVisitor<Expression>, StatementVisitor<Statement> {
-  Expression visitExpression(Expression e) => e.accept(this);
-  Statement visitStatement(Statement s) => s.accept(this);
-}
-
-class RecursiveTransformer extends Transformer {
-  void _replaceExpressions(List<Expression> list) {
-    for (int i = 0; i < list.length; i++) {
-      list[i] = visitExpression(list[i]);
-    }
-  }
-
-  visitVariableUse(VariableUse node) => node;
-
-  visitAssign(Assign node) {
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  visitInvokeStatic(InvokeStatic node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitInvokeMethod(InvokeMethod node) {
-    node.receiver = visitExpression(node.receiver);
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    node.receiver = visitExpression(node.receiver);
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitInvokeConstructor(InvokeConstructor node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitOneShotInterceptor(OneShotInterceptor node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitConstant(Constant node) => node;
-
-  visitThis(This node) => node;
-
-  visitConditional(Conditional node) {
-    node.condition = visitExpression(node.condition);
-    node.thenExpression = visitExpression(node.thenExpression);
-    node.elseExpression = visitExpression(node.elseExpression);
-    return node;
-  }
-
-  visitLogicalOperator(LogicalOperator node) {
-    node.left = visitExpression(node.left);
-    node.right = visitExpression(node.right);
-    return node;
-  }
-
-  visitNot(Not node) {
-    node.operand = visitExpression(node.operand);
-    return node;
-  }
-
-  visitLiteralList(LiteralList node) {
-    _replaceExpressions(node.values);
-    return node;
-  }
-
-  visitTypeOperator(TypeOperator node) {
-    node.value = visitExpression(node.value);
-    _replaceExpressions(node.typeArguments);
-    return node;
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    node.body = visitStatement(node.body);
-    node.next = visitStatement(node.next);
-    return node;
-  }
-
-  visitReturn(Return node) {
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  visitThrow(Throw node) {
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  visitBreak(Break node) => node;
-
-  visitContinue(Continue node) => node;
-
-  visitIf(If node) {
-    node.condition = visitExpression(node.condition);
-    node.thenStatement = visitStatement(node.thenStatement);
-    node.elseStatement = visitStatement(node.elseStatement);
-    return node;
-  }
-
-  visitWhileTrue(WhileTrue node) {
-    node.body = visitStatement(node.body);
-    return node;
-  }
-
-  visitFor(For node) {
-    node.condition = visitExpression(node.condition);
-    _replaceExpressions(node.updates);
-    node.body = visitStatement(node.body);
-    node.next = visitStatement(node.next);
-    return node;
-  }
-
-  visitExpressionStatement(ExpressionStatement node) {
-    // Iterate over chains of expression statements to avoid deep recursion.
-    Statement first = node;
-    while (true) {
-      node.expression = visitExpression(node.expression);
-      if (node.next is ExpressionStatement) {
-        node = node.next;
-      } else {
-        break;
-      }
-    }
-    node.next = visitStatement(node.next);
-    return first;
-  }
-
-  visitTry(Try node) {
-    node.tryBody = visitStatement(node.tryBody);
-    node.catchBody = visitStatement(node.catchBody);
-    return node;
-  }
-
-  visitGetField(GetField node) {
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  visitSetField(SetField node) {
-    node.object = visitExpression(node.object);
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  visitGetStatic(GetStatic node) => node;
-
-  visitSetStatic(SetStatic node) {
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  visitGetTypeTestProperty(GetTypeTestProperty node) {
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  visitCreateBox(CreateBox node) => node;
-
-  visitCreateInstance(CreateInstance node) {
-    _replaceExpressions(node.arguments);
-    if (node.typeInformation != null) {
-      node.typeInformation = visitExpression(node.typeInformation);
-    }
-    return node;
-  }
-
-  visitReifyRuntimeType(ReifyRuntimeType node) {
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  visitReadTypeVariable(ReadTypeVariable node) {
-    node.target = visitExpression(node.target);
-    return node;
-  }
-
-  visitTypeExpression(TypeExpression node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitCreateInvocationMirror(CreateInvocationMirror node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitForeignExpression(ForeignExpression node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitForeignStatement(ForeignStatement node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitUnreachable(Unreachable node) {
-    return node;
-  }
-
-  visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    node.receiver = visitExpression(node.receiver);
-    _replaceExpressions(node.arguments);
-    return node;
-  }
-
-  visitInterceptor(Interceptor node) {
-    node.input = visitExpression(node.input);
-    return node;
-  }
-
-  visitGetLength(GetLength node) {
-    node.object = visitExpression(node.object);
-    return node;
-  }
-
-  visitGetIndex(GetIndex node) {
-    node.object = visitExpression(node.object);
-    node.index = visitExpression(node.index);
-    return node;
-  }
-
-  visitSetIndex(SetIndex node) {
-    node.object = visitExpression(node.object);
-    node.index = visitExpression(node.index);
-    node.value = visitExpression(node.value);
-    return node;
-  }
-
-  visitAwait(Await node) {
-    node.input = visitExpression(node.input);
-    return node;
-  }
-
-  visitYield(Yield node) {
-    node.input = visitExpression(node.input);
-    node.next = visitStatement(node.next);
-    return node;
-  }
-
-  visitReceiverCheck(ReceiverCheck node) {
-    if (node.condition != null) {
-      node.condition = visitExpression(node.condition);
-    }
-    node.value = visitExpression(node.value);
-    node.next = visitStatement(node.next);
-    return node;
-  }
-}
-
-class FallthroughTarget {
-  final Statement target;
-  int useCount = 0;
-
-  FallthroughTarget(this.target);
-}
-
-/// A stack machine for tracking fallthrough while traversing the Tree IR.
-class FallthroughStack {
-  final List<FallthroughTarget> _stack = <FallthroughTarget>[
-    new FallthroughTarget(null)
-  ];
-
-  /// Set a new fallthrough target.
-  void push(Statement newFallthrough) {
-    _stack.add(new FallthroughTarget(newFallthrough));
-  }
-
-  /// Remove the current fallthrough target.
-  void pop() {
-    _stack.removeLast();
-  }
-
-  /// The current fallthrough target, or `null` if control will fall over
-  /// the end of the method.
-  Statement get target => _stack.last.target;
-
-  /// Number of uses of the current fallthrough target.
-  int get useCount => _stack.last.useCount;
-
-  /// Indicate that a statement will fall through to the current fallthrough
-  /// target.
-  void use() {
-    ++_stack.last.useCount;
-  }
-}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
deleted file mode 100644
index 486ee13..0000000
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ /dev/null
@@ -1,620 +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 tree_ir_tracer;
-
-import 'dart:async' show EventSink;
-import '../tracer.dart';
-import 'tree_ir_nodes.dart';
-
-class Block {
-  Label label;
-  int index;
-
-  /// Mixed list of [Statement] and [Block].
-  /// A [Block] represents a synthetic goto statement.
-  final List statements = [];
-  final List<Block> predecessors = <Block>[];
-  final List<Block> successors = <Block>[];
-
-  /// The catch block associated with the immediately enclosing try block or
-  /// `null` if not inside a try block.
-  Block catcher;
-
-  /// True if this block is the entry point to one of the bodies
-  /// (constructors can have multiple bodies).
-  bool isEntryPoint = false;
-
-  String get name => 'B$index';
-
-  Block([this.label]);
-
-  void addEdgeTo(Block successor) {
-    successors.add(successor);
-    successor.predecessors.add(this);
-  }
-}
-
-class BlockCollector extends StatementVisitor {
-  // Accumulate a list of blocks.  The current block is the last block in
-  // the list.
-  final List<Block> blocks = [];
-
-  // Map tree [Label]s (break or continue targets) and [Statement]s
-  // (if targets) to blocks.
-  final Map<Label, Block> breakTargets = <Label, Block>{};
-  final Map<Label, Block> continueTargets = <Label, Block>{};
-  final Map<Statement, Block> substatements = <Statement, Block>{};
-
-  Block catcher;
-
-  void _addStatement(Statement statement) {
-    blocks.last.statements.add(statement);
-  }
-
-  void _addGotoStatement(Block target) {
-    blocks.last.statements.add(target);
-  }
-
-  void _addBlock(Block block) {
-    block.index = blocks.length;
-    block.catcher = catcher;
-    blocks.add(block);
-  }
-
-  void collect(FunctionDefinition node) {
-    _addBlock(new Block()..isEntryPoint = true);
-    visitStatement(node.body);
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    Block target = new Block(node.label);
-    breakTargets[node.label] = target;
-    visitStatement(node.body);
-    _addBlock(target);
-    visitStatement(node.next);
-  }
-
-  visitReturn(Return node) {
-    _addStatement(node);
-  }
-
-  visitThrow(Throw node) {
-    _addStatement(node);
-  }
-
-  visitUnreachable(Unreachable node) {
-    _addStatement(node);
-  }
-
-  visitBreak(Break node) {
-    _addStatement(node);
-    if (breakTargets.containsKey(node.target)) {
-      blocks.last.addEdgeTo(breakTargets[node.target]);
-    }
-  }
-
-  visitContinue(Continue node) {
-    _addStatement(node);
-    blocks.last.addEdgeTo(continueTargets[node.target]);
-  }
-
-  visitIf(If node) {
-    _addStatement(node);
-    Block thenTarget = new Block();
-    Block elseTarget = new Block();
-    substatements[node.thenStatement] = thenTarget;
-    substatements[node.elseStatement] = elseTarget;
-    blocks.last.addEdgeTo(thenTarget);
-    blocks.last.addEdgeTo(elseTarget);
-    _addBlock(thenTarget);
-    visitStatement(node.thenStatement);
-    _addBlock(elseTarget);
-    visitStatement(node.elseStatement);
-  }
-
-  visitWhileTrue(WhileTrue node) {
-    Block continueTarget = new Block();
-    _addGotoStatement(continueTarget);
-
-    continueTargets[node.label] = continueTarget;
-    blocks.last.addEdgeTo(continueTarget);
-    _addBlock(continueTarget);
-    _addStatement(node);
-    visitStatement(node.body);
-  }
-
-  visitFor(For node) {
-    Block whileBlock = new Block();
-    _addGotoStatement(whileBlock);
-
-    _addBlock(whileBlock);
-    _addStatement(node);
-    blocks.last.addEdgeTo(whileBlock);
-
-    Block bodyBlock = new Block();
-    Block nextBlock = new Block();
-    whileBlock.addEdgeTo(bodyBlock);
-    whileBlock.addEdgeTo(nextBlock);
-
-    continueTargets[node.label] = bodyBlock;
-    _addBlock(bodyBlock);
-    visitStatement(node.body);
-
-    _addBlock(nextBlock);
-    visitStatement(node.next);
-
-    substatements[node.body] = bodyBlock;
-    substatements[node.next] = nextBlock;
-  }
-
-  visitTry(Try node) {
-    _addStatement(node);
-    Block tryBlock = new Block();
-    Block catchBlock = new Block();
-
-    Block oldCatcher = catcher;
-    catcher = catchBlock;
-    _addBlock(tryBlock);
-    visitStatement(node.tryBody);
-    catcher = oldCatcher;
-
-    _addBlock(catchBlock);
-    visitStatement(node.catchBody);
-
-    substatements[node.tryBody] = tryBlock;
-    substatements[node.catchBody] = catchBlock;
-  }
-
-  visitExpressionStatement(ExpressionStatement node) {
-    _addStatement(node);
-    visitStatement(node.next);
-  }
-
-  visitForeignStatement(ForeignStatement node) {
-    _addStatement(node);
-  }
-
-  visitYield(Yield node) {
-    _addStatement(node);
-    visitStatement(node.next);
-  }
-
-  visitReceiverCheck(ReceiverCheck node) {
-    _addStatement(node);
-    visitStatement(node.next);
-  }
-}
-
-class TreeTracer extends TracerUtil with StatementVisitor {
-  String get passName => null;
-
-  final EventSink<String> output;
-
-  TreeTracer(this.output);
-
-  List<Variable> parameters;
-  Names names;
-  BlockCollector collector;
-  int statementCounter;
-
-  void traceGraph(String name, FunctionDefinition node) {
-    parameters = node.parameters;
-    tag("cfg", () {
-      printProperty("name", name);
-      names = new Names();
-      statementCounter = 0;
-      collector = new BlockCollector();
-      collector.collect(node);
-      collector.blocks.forEach(printBlock);
-    });
-  }
-
-  void printBlock(Block block) {
-    tag("block", () {
-      printProperty("name", block.name);
-      printProperty("from_bci", -1);
-      printProperty("to_bci", -1);
-      printProperty("predecessors", block.predecessors.map((b) => b.name));
-      printProperty("successors", block.successors.map((b) => b.name));
-      printEmptyProperty("xhandlers");
-      printEmptyProperty("flags");
-      tag("states", () {
-        tag("locals", () {
-          printProperty("size", 0);
-          printProperty("method", "None");
-        });
-      });
-      tag("HIR", () {
-        if (block.isEntryPoint) {
-          String params = parameters.map(names.varName).join(', ');
-          printStatement(null, 'Entry ($params)');
-        }
-        if (block.label != null) {
-          printStatement(
-              null, "Label ${block.name}, useCount=${block.label.useCount}");
-        }
-        if (block.catcher != null) {
-          printStatement(null, 'Catch exceptions at ${block.catcher.name}');
-        }
-        block.statements.forEach(visitBlockMember);
-      });
-    });
-  }
-
-  void visitBlockMember(member) {
-    if (member is Block) {
-      printStatement(null, "goto block B${member.name}");
-    } else {
-      assert(member is Statement);
-      visitStatement(member);
-    }
-  }
-
-  void printStatement(String name, String contents) {
-    int bci = 0;
-    int uses = 0;
-    if (name == null) {
-      name = 'x${statementCounter++}';
-    }
-    addIndent();
-    add("$bci $uses $name $contents <|@\n");
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    // These do not get added to a block's list of statements.
-  }
-
-  visitReturn(Return node) {
-    printStatement(null, "return ${expr(node.value)}");
-  }
-
-  visitThrow(Throw node) {
-    printStatement(null, "throw ${expr(node.value)}");
-  }
-
-  visitUnreachable(Unreachable node) {
-    printStatement(null, "unreachable");
-  }
-
-  visitBreak(Break node) {
-    Block block = collector.breakTargets[node.target];
-    String name = block != null ? block.name : '<missing label>';
-    printStatement(null, "break $name");
-  }
-
-  visitContinue(Continue node) {
-    printStatement(
-        null, "continue ${collector.continueTargets[node.target].name}");
-  }
-
-  visitIf(If node) {
-    String condition = expr(node.condition);
-    String thenTarget = collector.substatements[node.thenStatement].name;
-    String elseTarget = collector.substatements[node.elseStatement].name;
-    printStatement(null, "if $condition then $thenTarget else $elseTarget");
-  }
-
-  visitWhileTrue(WhileTrue node) {
-    printStatement(null, "while true do");
-  }
-
-  visitFor(For node) {
-    String bodyTarget = collector.substatements[node.body].name;
-    String nextTarget = collector.substatements[node.next].name;
-    String updates = node.updates.map(expr).join(', ');
-    printStatement(null, "while ${expr(node.condition)}");
-    printStatement(null, "do $bodyTarget");
-    printStatement(null, "updates ($updates)");
-    printStatement(null, "then $nextTarget");
-  }
-
-  visitTry(Try node) {
-    String tryTarget = collector.substatements[node.tryBody].name;
-    String catchParams = node.catchParameters.map(names.varName).join(',');
-    String catchTarget = collector.substatements[node.catchBody].name;
-    printStatement(null, 'try $tryTarget catch($catchParams) $catchTarget');
-  }
-
-  visitExpressionStatement(ExpressionStatement node) {
-    printStatement(null, expr(node.expression));
-  }
-
-  visitSetField(SetField node) {
-    String object = expr(node.object);
-    String field = node.field.name;
-    String value = expr(node.value);
-    if (SubexpressionVisitor.usesInfixNotation(node.object)) {
-      object = '($object)';
-    }
-    printStatement(null, '$object.$field = $value');
-  }
-
-  String expr(Expression e) {
-    return e.accept(new SubexpressionVisitor(names));
-  }
-
-  @override
-  visitForeignStatement(ForeignStatement node) {
-    printStatement(null, 'foreign ${node.codeTemplate.source}');
-  }
-
-  @override
-  visitYield(Yield node) {
-    String name = node.hasStar ? 'yield*' : 'yield';
-    printStatement(null, '$name ${expr(node.input)}');
-  }
-
-  @override
-  visitReceiverCheck(ReceiverCheck node) {
-    printStatement(null, 'NullCheck ${expr(node.value)}');
-  }
-}
-
-class SubexpressionVisitor extends ExpressionVisitor<String> {
-  Names names;
-
-  SubexpressionVisitor(this.names);
-
-  String visitVariableUse(VariableUse node) {
-    return names.varName(node.variable);
-  }
-
-  String visitAssign(Assign node) {
-    String variable = names.varName(node.variable);
-    String value = visitExpression(node.value);
-    return '$variable = $value';
-  }
-
-  String formatArguments(Invoke node) {
-    return node.arguments.map(visitExpression).join(', ');
-  }
-
-  String visitInvokeStatic(InvokeStatic node) {
-    String head = node.target.name;
-    String args = formatArguments(node);
-    return "$head($args)";
-  }
-
-  String visitInvokeMethod(InvokeMethod node) {
-    String receiver = node.receiver.accept(this);
-    String name = node.selector.name;
-    String args = formatArguments(node);
-    return "$receiver.$name($args)";
-  }
-
-  String visitInvokeMethodDirectly(InvokeMethodDirectly node) {
-    String receiver = visitExpression(node.receiver);
-    String host = node.target.enclosingClass.name;
-    String name = node.selector.name;
-    String args = formatArguments(node);
-    return "$receiver.$host::$name($args)";
-  }
-
-  String visitInvokeConstructor(InvokeConstructor node) {
-    String className = node.target.enclosingClass.name;
-    String callName;
-    if (node.target.name.isEmpty) {
-      callName = '${className}';
-    } else {
-      callName = '${className}.${node.target.name}';
-    }
-    String args = formatArguments(node);
-    String keyword = node.constant != null ? 'const' : 'new';
-    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]";
-  }
-
-  String visitConstant(Constant node) {
-    return "${node.value.toStructuredText()}";
-  }
-
-  String visitThis(This node) {
-    return "this";
-  }
-
-  static bool usesInfixNotation(Expression node) {
-    return node is Conditional ||
-        node is LogicalOperator ||
-        node is Assign ||
-        node is SetField;
-  }
-
-  String visitConditional(Conditional node) {
-    String condition = visitExpression(node.condition);
-    String thenExpr = visitExpression(node.thenExpression);
-    String elseExpr = visitExpression(node.elseExpression);
-    return "$condition ? $thenExpr : $elseExpr";
-  }
-
-  String visitLogicalOperator(LogicalOperator node) {
-    String left = visitExpression(node.left);
-    String right = visitExpression(node.right);
-    if (usesInfixNotation(node.left)) {
-      left = "($left)";
-    }
-    if (usesInfixNotation(node.right)) {
-      right = "($right)";
-    }
-    return "$left ${node.operator} $right";
-  }
-
-  String visitTypeOperator(TypeOperator node) {
-    String value = visitExpression(node.value);
-    String type = "${node.type}";
-    return "TypeOperator $value ${node.operator} $type";
-  }
-
-  String visitNot(Not node) {
-    String operand = visitExpression(node.operand);
-    if (usesInfixNotation(node.operand)) {
-      operand = '($operand)';
-    }
-    return '!$operand';
-  }
-
-  String visitGetField(GetField node) {
-    String object = visitExpression(node.object);
-    String field = node.field.name;
-    if (usesInfixNotation(node.object)) {
-      object = '($object)';
-    }
-    return '$object.$field';
-  }
-
-  String visitSetField(SetField node) {
-    String object = visitExpression(node.object);
-    String field = node.field.name;
-    if (usesInfixNotation(node.object)) {
-      object = '($object)';
-    }
-    String value = visitExpression(node.value);
-    return '$object.$field = $value';
-  }
-
-  String visitGetStatic(GetStatic node) {
-    String element = node.element.name;
-    return element;
-  }
-
-  String visitSetStatic(SetStatic node) {
-    String element = node.element.name;
-    String value = visitExpression(node.value);
-    return '$element = $value';
-  }
-
-  String visitGetTypeTestProperty(GetTypeTestProperty node) {
-    String object = visitExpression(node.object);
-    if (usesInfixNotation(node.object)) {
-      object = '($object)';
-    }
-    // TODO(sra): Fix up this.
-    return '$object."is-${node.dartType}"';
-  }
-
-  String visitCreateBox(CreateBox node) {
-    return 'CreateBox';
-  }
-
-  String visitCreateInstance(CreateInstance node) {
-    String className = node.classElement.name;
-    String arguments = node.arguments.map(visitExpression).join(', ');
-    return 'CreateInstance $className($arguments)';
-  }
-
-  @override
-  String visitReadTypeVariable(ReadTypeVariable node) {
-    return 'Read ${node.variable.element} ${visitExpression(node.target)}';
-  }
-
-  @override
-  String visitReifyRuntimeType(ReifyRuntimeType node) {
-    return 'Reify ${node.value}';
-  }
-
-  @override
-  String visitTypeExpression(TypeExpression node) {
-    String kind = '${node.kind}'.split('.').last;
-    String args = node.arguments.map(visitExpression).join(', ');
-    return 'TypeExpression($kind, ${node.dartType}, $args)';
-  }
-
-  @override
-  String visitCreateInvocationMirror(CreateInvocationMirror node) {
-    String args = node.arguments.map(visitExpression).join(', ');
-    return 'CreateInvocationMirror(${node.selector.name}, $args)';
-  }
-
-  @override
-  String visitInterceptor(Interceptor node) {
-    return 'Interceptor(${visitExpression(node.input)})';
-  }
-
-  @override
-  String visitForeignExpression(ForeignExpression node) {
-    String arguments = node.arguments.map(visitExpression).join(', ');
-    return 'Foreign "${node.codeTemplate.source}"($arguments)';
-  }
-
-  @override
-  String visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
-    String args = node.arguments.map(visitExpression).join(', ');
-    return 'ApplyBuiltinOperator ${node.operator} ($args)';
-  }
-
-  @override
-  String visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
-    String receiver = visitExpression(node.receiver);
-    String args = node.arguments.map(visitExpression).join(', ');
-    return 'ApplyBuiltinMethod ${node.method} $receiver ($args)';
-  }
-
-  @override
-  String visitGetLength(GetLength node) {
-    String object = visitExpression(node.object);
-    return 'GetLength($object)';
-  }
-
-  @override
-  String visitGetIndex(GetIndex node) {
-    String object = visitExpression(node.object);
-    String index = visitExpression(node.index);
-    return 'GetIndex($object, $index)';
-  }
-
-  @override
-  String visitSetIndex(SetIndex node) {
-    String object = visitExpression(node.object);
-    String index = visitExpression(node.index);
-    String value = visitExpression(node.value);
-    return 'SetIndex($object, $index, $value)';
-  }
-
-  @override
-  String visitAwait(Await node) {
-    String value = visitExpression(node.input);
-    return 'Await($value)';
-  }
-
-  String visitYield(Yield node) {
-    String value = visitExpression(node.input);
-    return 'Yield($value)';
-  }
-}
-
-/**
- * Invents (and remembers) names for Variables that do not have an associated
- * identifier.
- *
- * In case a variable is named v0, v1, etc, it may be assigned a different
- * name to avoid clashing with a previously synthesized variable name.
- */
-class Names {
-  final Map<Variable, String> _names = {};
-  final Set<String> _usedNames = new Set();
-  int _counter = 0;
-
-  String varName(Variable v) {
-    String name = _names[v];
-    if (name == null) {
-      String prefix = v.element == null ? 'v' : '${v.element.name}_';
-      while (name == null || _usedNames.contains(name)) {
-        name = "$prefix${_counter++}";
-      }
-      _names[v] = name;
-      _usedNames.add(name);
-    }
-    return name;
-  }
-}
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 69137ab..01cff2d 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -64,8 +64,12 @@
             compiler, resolvedAst.elements, compiler.types);
         if (element.isField) {
           visitor.analyzingInitializer = true;
+          DartType type =
+              visitor.analyzeVariableTypeAnnotation(resolvedAst.node);
+          visitor.analyzeVariableInitializer(element, type, resolvedAst.body);
+        } else {
+          resolvedAst.node.accept(visitor);
         }
-        resolvedAst.node.accept(visitor);
       });
     });
   }
@@ -443,7 +447,7 @@
     if (result == null) {
       reporter.internalError(node, 'Type is null.');
     }
-    return _record(node, result);
+    return result;
   }
 
   void checkTypePromotion(Node node, TypePromotion typePromotion,
@@ -683,7 +687,7 @@
       assert(invariant(
           node,
           element.isVariable ||
-              element.isParameter ||
+              element.isRegularParameter ||
               element.isField ||
               (element.isInitializingFormal &&
                   compiler.options.enableInitializingFormalAccess),
@@ -772,7 +776,7 @@
     }
     if (receiverElement != null &&
         (receiverElement.isVariable ||
-            receiverElement.isParameter ||
+            receiverElement.isRegularParameter ||
             (receiverElement.isInitializingFormal &&
                 compiler.options.enableInitializingFormalAccess))) {
       Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement];
@@ -815,6 +819,7 @@
             foundPrivateMember = true;
           }
         }
+
         // TODO(johnniwinther): Avoid computation of all class members.
         MembersCreator.computeAllClassMembers(resolution, interface.element);
         if (lookupClassMember) {
@@ -1070,7 +1075,7 @@
       // foo() where foo is a method in the same class.
       return createResolvedAccess(node, name, element);
     } else if (element.isVariable ||
-        element.isParameter ||
+        element.isRegularParameter ||
         element.isField ||
         element.isInitializingFormal) {
       // foo() where foo is a field in the same class.
@@ -1091,7 +1096,7 @@
 
   ElementAccess createPromotedAccess(Element element) {
     if (element.isVariable ||
-        element.isParameter ||
+        element.isRegularParameter ||
         (element.isInitializingFormal &&
             compiler.options.enableInitializingFormalAccess)) {
       TypePromotion typePromotion = getKnownTypePromotion(element);
@@ -1151,24 +1156,6 @@
     return null;
   }
 
-  static bool _fyiShown = false;
-  DartType _record(Node node, DartType type) {
-    if (node is! Expression) return type;
-    if (const bool.fromEnvironment('send_stats') &&
-        executableContext != null &&
-        // TODO(sigmund): enable also in core libs.
-        !executableContext.library.isPlatformLibrary &&
-        !type.isDynamic) {
-      if (!_fyiShown) {
-        print('FYI experiment to collect send stats is on: '
-            'caching types of expressions');
-        _fyiShown = true;
-      }
-      elements.typesCache[node] = type;
-    }
-    return type;
-  }
-
   DartType visitSend(Send node) {
     Element element = elements[node];
 
@@ -1230,7 +1217,7 @@
 
         if (variable != null &&
             (variable.isVariable ||
-                variable.isParameter ||
+                variable.isRegularParameter ||
                 (variable.isInitializingFormal &&
                     compiler.options.enableInitializingFormalAccess))) {
           DartType knownType = getKnownType(variable);
@@ -1658,6 +1645,8 @@
     checkPrivateAccess(node, element, element.name);
 
     DartType newType = elements.getType(node);
+    assert(invariant(node, newType != null,
+        message: "No new type registered in $elements."));
     DartType constructorType = computeConstructorType(element, newType);
     analyzeArguments(node.send, element, constructorType);
     return newType;
@@ -1742,7 +1731,7 @@
 
   DartType visitAwait(Await node) {
     DartType expressionType = analyze(node.expression);
-    if (compiler.backend.supportsAsyncAwait) {
+    if (resolution.target.supportsAsyncAwait) {
       return types.flatten(expressionType);
     } else {
       return const DynamicType();
@@ -1775,12 +1764,25 @@
     return elements.getType(node);
   }
 
-  DartType visitVariableDefinitions(VariableDefinitions node) {
+  DartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
     DartType type = analyzeWithDefault(node.type, const DynamicType());
     if (type.isVoid) {
       reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
       type = const DynamicType();
     }
+    return type;
+  }
+
+  void analyzeVariableInitializer(
+      Spannable spannable, DartType declaredType, Node initializer) {
+    if (initializer == null) return;
+    
+    DartType expressionType = analyzeNonVoid(initializer);
+    checkAssignable(spannable, expressionType, declaredType);
+  }
+
+  DartType visitVariableDefinitions(VariableDefinitions node) {
+    DartType type = analyzeVariableTypeAnnotation(node);
     for (Link<Node> link = node.definitions.nodes;
         !link.isEmpty;
         link = link.tail) {
@@ -1789,8 +1791,10 @@
           message: 'expected identifier or initialization');
       if (definition is SendSet) {
         SendSet initialization = definition;
-        DartType initializer = analyzeNonVoid(initialization.arguments.head);
-        checkAssignable(initialization.assignmentOperator, initializer, type);
+        analyzeVariableInitializer(
+            initialization.assignmentOperator,
+            type,
+            initialization.arguments.head);
         // TODO(sigmund): explore inferring a type for `var` using the RHS (like
         // DDC does), for example:
         // if (node.type == null && node.modifiers.isVar &&
@@ -1869,7 +1873,7 @@
   visitAsyncForIn(AsyncForIn node) {
     DartType elementType = computeForInElementType(node);
     DartType expressionType = analyze(node.expression);
-    if (compiler.backend.supportsAsyncAwait) {
+    if (resolution.target.supportsAsyncAwait) {
       DartType streamOfDynamic = coreTypes.streamType();
       if (!types.isAssignable(expressionType, streamOfDynamic)) {
         reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE,
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index d66a31c..219e6b1 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -48,7 +48,7 @@
 
   @override
   TypeMask visitSynthetic(SyntheticConstantValue constant, Compiler compiler) {
-    switch (constant.kind) {
+    switch (constant.valueKind) {
       case SyntheticConstantKind.DUMMY_INTERCEPTOR:
         return constant.payload;
       case SyntheticConstantKind.EMPTY_VALUE:
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 61dbabf..d12b2bd 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -12,15 +12,14 @@
 import '../elements/elements.dart';
 import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
 import '../tree/tree.dart';
-import '../util/util.dart';
 import '../universe/selector.dart' show Selector;
 import '../universe/universe.dart'
     show
         ReceiverConstraint,
         UniverseSelectorConstraints,
         SelectorConstraintsStrategy;
+import '../util/util.dart';
 import '../world.dart' show ClassWorld, World;
-
 import 'abstract_value_domain.dart' show AbstractValue;
 
 part 'container_type_mask.dart';
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index f05880a..5a191db 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -253,6 +253,7 @@
           return other.containsMask(maskDisregardNull, classWorld);
         });
       }
+
       return disjointMasks.every((FlatTypeMask disjointMask) {
         bool contained = containedInAnyOf(disjointMask, union.disjointMasks);
         if (PERFORM_EXTRA_CONTAINS_CHECK &&
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 84c0a62..a96622e 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -38,6 +38,17 @@
     return new NamedCallStructure(argumentCount, namedArguments);
   }
 
+  /// Creates the [CallStructure] corresponding to calling [signature] as
+  /// declared, that is, all named arguments are in the order of declaration.
+  factory CallStructure.fromSignature(FunctionSignature signature) {
+    List<String> namedParameters;
+    if (signature.optionalParametersAreNamed) {
+      namedParameters =
+          signature.optionalParameters.map((e) => e.name).toList();
+    }
+    return new CallStructure(signature.parameterCount, namedParameters);
+  }
+
   /// `true` if this call has named arguments.
   bool get isNamed => false;
 
@@ -220,13 +231,7 @@
 
     // Synthesize a structure for the call.
     // TODO(ngeoffray): Should the resolver do it instead?
-    List<String> namedParameters;
-    if (signature.optionalParametersAreNamed) {
-      namedParameters =
-          signature.optionalParameters.map((e) => e.name).toList();
-    }
-    CallStructure callStructure =
-        new CallStructure(signature.parameterCount, namedParameters);
+    CallStructure callStructure = new CallStructure.fromSignature(signature);
     if (!callStructure.signatureApplies(signature)) {
       return false;
     }
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index 038d757..be69cc2 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -5,6 +5,7 @@
 library dart2js.world.class_set;
 
 import 'dart:collection' show IterableBase;
+
 import '../elements/elements.dart' show ClassElement;
 import '../util/enumset.dart' show EnumSet;
 import '../util/util.dart' show Link;
@@ -213,6 +214,7 @@
     IterationStep wrapper(ClassElement cls) {
       return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
     }
+
     return forEachSubclass(wrapper, mask, strict: strict) == IterationStep.STOP;
   }
 
@@ -546,6 +548,7 @@
     IterationStep wrapper(ClassElement cls) {
       return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
     }
+
     return forEachSubtype(wrapper, mask, strict: strict) == IterationStep.STOP;
   }
 
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
new file mode 100644
index 0000000..a9faeb1
--- /dev/null
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -0,0 +1,138 @@
+// TODO(sigmund): rename universe => world
+/// Describes individual features that may be seen in a program. Most features
+/// can be described only by name using the [Feature] enum, some features are
+/// expressed including details on how they are used. For example, whether a
+/// list literal was constant or empty.
+///
+/// The use of these features is typically discovered in an early phase of the
+/// compilation pipeline, for example during resolution.
+library compiler.universe.feature;
+
+import '../dart_types.dart' show InterfaceType;
+
+/// A language feature that may be seen in the program.
+// TODO(johnniwinther): Should mirror usage be part of this?
+enum Feature {
+  /// Invocation of a generative construction on an abstract class.
+  ABSTRACT_CLASS_INSTANTIATION,
+
+  /// An assert statement with no message.
+  ASSERT,
+
+  /// An assert statement with a message.
+  ASSERT_WITH_MESSAGE,
+
+  /// A method with an `async` body modifier.
+  ASYNC,
+
+  /// An asynchronous for in statement like `await for (var e in i) {}`.
+  ASYNC_FOR_IN,
+
+  /// A method with an `async*` body modifier.
+  ASYNC_STAR,
+
+  /// A catch statement.
+  CATCH_STATEMENT,
+
+  /// A compile time error.
+  COMPILE_TIME_ERROR,
+
+  /// A fall through in a switch case.
+  FALL_THROUGH_ERROR,
+
+  /// A ++/-- operation.
+  INC_DEC_OPERATION,
+
+  /// A field whose initialization is not a constant.
+  LAZY_FIELD,
+
+  /// A catch clause with a variable for the stack trace.
+  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,
+
+  /// A redirection to the `Symbol` constructor.
+  SYMBOL_CONSTRUCTOR,
+
+  /// An synchronous for in statement, like `for (var e in i) {}`.
+  SYNC_FOR_IN,
+
+  /// A method with a `sync*` body modifier.
+  SYNC_STAR,
+
+  /// A throw expression.
+  THROW_EXPRESSION,
+
+  /// An implicit throw of a `NoSuchMethodError`, like calling an unresolved
+  /// static method.
+  THROW_NO_SUCH_METHOD,
+
+  /// An implicit throw of a runtime error, like
+  THROW_RUNTIME_ERROR,
+
+  /// The need for a type variable bound check, like instantiation of a generic
+  /// type whose type variable have non-trivial bounds.
+  TYPE_VARIABLE_BOUNDS_CHECK,
+}
+
+/// Describes a use of a map literal in the program.
+class MapLiteralUse {
+  final InterfaceType type;
+  final bool isConstant;
+  final bool isEmpty;
+
+  MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
+
+  int get hashCode {
+    return type.hashCode * 13 +
+        isConstant.hashCode * 17 +
+        isEmpty.hashCode * 19;
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! MapLiteralUse) return false;
+    return type == other.type &&
+        isConstant == other.isConstant &&
+        isEmpty == other.isEmpty;
+  }
+
+  String toString() {
+    return 'MapLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)';
+  }
+}
+
+/// Describes the use of a list literal in the program.
+class ListLiteralUse {
+  final InterfaceType type;
+  final bool isConstant;
+  final bool isEmpty;
+
+  ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
+
+  int get hashCode {
+    return type.hashCode * 13 +
+        isConstant.hashCode * 17 +
+        isEmpty.hashCode * 19;
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! ListLiteralUse) return false;
+    return type == other.type &&
+        isConstant == other.isConstant &&
+        isEmpty == other.isEmpty;
+  }
+
+  String toString() {
+    return 'ListLiteralUse($type,isConstant:$isConstant,isEmpty:$isEmpty)';
+  }
+}
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index c225b15..afa0951 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -10,7 +10,6 @@
 import '../types/types.dart';
 import '../util/util.dart' show Hashing, Setlet;
 import '../world.dart' show ClassWorld;
-
 import 'selector.dart' show Selector;
 import 'universe.dart' show ReceiverConstraint;
 
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index a76db34..19ce7c6 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -17,7 +17,6 @@
         PublicName;
 import '../util/util.dart' show Hashing;
 import '../world.dart' show World;
-
 import 'call_structure.dart' show CallStructure;
 
 class SelectorKind {
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index 8f08f6f..cb574bb 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -8,11 +8,10 @@
 
 import '../common.dart';
 import '../compiler.dart' show Compiler;
-import '../elements/elements.dart';
 import '../dart_types.dart';
+import '../elements/elements.dart';
 import '../util/util.dart';
 import '../world.dart' show ClassWorld, World;
-
 import 'selector.dart' show Selector;
 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
 
@@ -103,6 +102,11 @@
   UniverseSelectorConstraints createSelectorConstraints(Selector selector);
 }
 
+/// The [Universe] is an auxiliary class used in the process of computing the
+/// [ClassWorld]. The concepts here and in [ClassWorld] are very similar -- in
+/// the same way that the "universe expands" you can think of this as a mutable
+/// world that is expanding as we visit and discover parts of the program.
+/// TODO(sigmund): rename to "growing/expanding/mutable world"?
 class Universe {
   /// The set of all directly instantiated classes, that is, classes with a
   /// generative constructor that has been called directly and not only through
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index bb6b153..c1ab98f 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -2,18 +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.
 
-/// 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.
+/// This library defines individual world impacts.
+///
+/// We call these building blocks `uses`. Each `use` is a single impact of the
+/// world. Some example uses are:
+///
+///  * an invocation of a top level function
+///  * a call to the `foo()` method on an unknown class.
+///  * an instantiation of class T
+///
+/// The different compiler stages combine these uses into `WorldImpact` objects,
+/// which are later used to construct a closed-world understanding of the
+/// program.
 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 '../world.dart' show ClassWorld;
 import 'call_structure.dart' show CallStructure;
 import 'selector.dart' show Selector;
 import 'universe.dart' show ReceiverConstraint;
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
index 1ba0ab7..99c1c3c 100644
--- a/pkg/compiler/lib/src/universe/world_impact.dart
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -8,6 +8,17 @@
 import '../util/util.dart' show Setlet;
 import 'use.dart' show DynamicUse, StaticUse, TypeUse;
 
+/// Describes how an element (e.g. a method) impacts the closed-world
+/// semantics of a program.
+///
+/// A [WorldImpact] contains information about how a program element affects our
+/// understanding of what's live in a program. For example, it can indicate
+/// that a method uses a certain feature, or allocates a specific type.
+///
+/// The impact object can be computed locally by inspecting just the resolution
+/// information of that element alone. The compiler uses [Universe] and
+/// [ClassWorld] to combine the information discovered in the impact objects of
+/// all elements reachable in an application.
 class WorldImpact {
   const WorldImpact();
 
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index d3578f7..5e0b379 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -9,7 +9,6 @@
 library dart2js.use_unused_api;
 
 import '../compiler.dart' as api;
-
 import 'colors.dart' as colors;
 import 'compiler.dart' as compiler;
 import 'constants/constant_system.dart' as constants;
@@ -17,11 +16,8 @@
 import 'constants/evaluation.dart' as constants;
 import 'constants/expressions.dart' as constants;
 import 'constants/values.dart' as constants;
-import 'cps_ir/cps_ir_builder.dart' as ir_builder;
-import 'cps_ir/cps_ir_builder_task.dart' as ir_builder;
-import 'tree_ir/tree_ir_nodes.dart' as tree_ir;
-import 'dart_types.dart' as dart_types;
 import 'dart2js.dart' as dart2js;
+import 'dart_types.dart' as dart_types;
 import 'deferred_load.dart' as deferred;
 import 'diagnostics/source_span.dart' as diagnostics;
 import 'elements/elements.dart' as elements;
@@ -33,11 +29,13 @@
 import 'io/source_map_builder.dart' as io;
 import 'js/js.dart' as js;
 import 'js_backend/js_backend.dart' as js_backend;
-import 'js_emitter/js_emitter.dart' as js_emitter;
 import 'js_emitter/full_emitter/emitter.dart' as full;
+import 'js_emitter/js_emitter.dart' as js_emitter;
 import 'js_emitter/program_builder/program_builder.dart' as program_builder;
-import 'resolution/semantic_visitor.dart' as semantic_visitor;
+import 'parser/partial_elements.dart'
+    show PartialClassElement, PartialFunctionElement;
 import 'resolution/operators.dart' as operators;
+import 'resolution/semantic_visitor.dart' as semantic_visitor;
 import 'script.dart';
 import 'source_file_provider.dart' as source_file_provider;
 import 'ssa/nodes.dart' as ssa;
@@ -45,9 +43,6 @@
 import 'util/util.dart' as util;
 import 'world.dart';
 
-import 'parser/partial_elements.dart'
-    show PartialClassElement, PartialFunctionElement;
-
 class ElementVisitor extends elements_visitor.BaseElementVisitor {
   visitElement(e, a) {}
 }
@@ -73,14 +68,12 @@
   useIo();
   usedByTests();
   useElements();
-  useIr(null);
   useCompiler(null);
   useTypes();
   useCodeEmitterTask(null);
   useScript(null);
   useProgramBuilder(null);
   useSemanticVisitor();
-  useTreeVisitors();
   useDeferred();
 }
 
@@ -285,10 +278,6 @@
   l.forEachImport(null);
 }
 
-useIr(ir_builder.IrBuilder builder) {
-  builder..buildStringConstant(null);
-}
-
 useCompiler(compiler.Compiler c) {
   c.libraryLoader
     ..reset()
@@ -324,16 +313,6 @@
   new semantic_visitor.BulkDeclarationVisitor().apply(null, null);
 }
 
-class TreeVisitor1 extends tree_ir.ExpressionVisitor1
-    with tree_ir.StatementVisitor1 {
-  noSuchMethod(inv) {}
-}
-
-useTreeVisitors() {
-  new TreeVisitor1().visitExpression(null, null);
-  new TreeVisitor1().visitStatement(null, null);
-}
-
 useDeferred([deferred.DeferredLoadTask task]) {
   task.dump();
 }
diff --git a/pkg/compiler/lib/src/util/enumset.dart b/pkg/compiler/lib/src/util/enumset.dart
index 7d2f600..ab4dcc86 100644
--- a/pkg/compiler/lib/src/util/enumset.dart
+++ b/pkg/compiler/lib/src/util/enumset.dart
@@ -131,6 +131,7 @@
         value |= 1 << (enumValue as dynamic).index;
       }
     }
+
     values.forEach(add);
     return new _ConstEnumSet(value);
   }
diff --git a/pkg/compiler/lib/src/util/util.dart b/pkg/compiler/lib/src/util/util.dart
index d9cc16c..397bd6c 100644
--- a/pkg/compiler/lib/src/util/util.dart
+++ b/pkg/compiler/lib/src/util/util.dart
@@ -4,12 +4,12 @@
 
 library dart2js.util;
 
-import 'util_implementation.dart';
 import 'characters.dart';
+import 'util_implementation.dart';
 
-export 'setlet.dart';
-export 'maplet.dart';
 export 'emptyset.dart';
+export 'maplet.dart';
+export 'setlet.dart';
 
 part 'indentation.dart';
 part 'link.dart';
diff --git a/pkg/compiler/lib/src/util/util_implementation.dart b/pkg/compiler/lib/src/util/util_implementation.dart
index c28b63f..bdb6b90 100644
--- a/pkg/compiler/lib/src/util/util_implementation.dart
+++ b/pkg/compiler/lib/src/util/util_implementation.dart
@@ -4,7 +4,8 @@
 
 library util_implementation;
 
-import 'util.dart';
 import 'dart:collection';
 
+import 'util.dart';
+
 part 'link_implementation.dart';
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index bfa2100..99aca9f 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -5,8 +5,8 @@
 library dart2js.world;
 
 import 'closure.dart' show SynthesizedCallMethodElementX;
-import 'common.dart';
 import 'common/backend_api.dart' show Backend;
+import 'common.dart';
 import 'compiler.dart' show Compiler;
 import 'core_types.dart' show CoreClasses;
 import 'dart_types.dart';
@@ -26,6 +26,14 @@
 import 'universe/side_effects.dart' show SideEffects;
 import 'util/util.dart' show Link;
 
+/// The [ClassWorld] represents the information known about a program when
+/// compiling with closed-world semantics.
+///
+/// Given the entrypoint of an application, we can track what's reachable from
+/// it, what functions are called, what classes are allocated, which native
+/// JavaScript types are touched, what language features are used, and so on.
+/// This precise knowledge about what's live in the program is later used in
+/// optimizations and other compiler decisions during code generation.
 abstract class ClassWorld {
   // TODO(johnniwinther): Refine this into a `BackendClasses` interface.
   Backend get backend;
@@ -425,7 +433,8 @@
     } while (iterator.moveNext());
 
     List<ClassElement> commonSupertypes = <ClassElement>[];
-    OUTER: for (Link<DartType> link = typeSet[depth];
+    OUTER:
+    for (Link<DartType> link = typeSet[depth];
         link.head.element != objectClass;
         link = link.tail) {
       ClassElement cls = link.head.element;
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 922f69a..d8998ef 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -3,7 +3,7 @@
 name: compiler
 #version: do-not-upload
 dependencies:
-  package_config: ^0.1.1
+  package_config: '>=0.1.1 <2.0.0'
   pub_semver: ^1.2.1
   js:
     path: ../js
diff --git a/pkg/compiler/samples/compile_loop/compile_loop.dart b/pkg/compiler/samples/compile_loop/compile_loop.dart
deleted file mode 100644
index 097d046..0000000
--- a/pkg/compiler/samples/compile_loop/compile_loop.dart
+++ /dev/null
@@ -1,73 +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 sample demonstrates how to run the compiler in a loop reading
-// all sources from memory, instead of using dart:io.
-library sample.compile_loop;
-
-import 'dart:async';
-
-import '../../lib/compiler.dart' as compiler;
-
-// If this file is missing, generate it using ../jsonify/jsonify.dart.
-import 'sdk.dart';
-
-Future<String> compile(source) {
-  Future<String> inputProvider(Uri uri) {
-    if (uri.scheme == 'sdk') {
-      var value = SDK_SOURCES['$uri'];
-      if (value == null) {
-        // TODO(ahe): Use new Future.error.
-        throw new Exception('Error: Cannot read: $uri');
-      }
-      return new Future.value(value);
-    } else if ('$uri' == 'memory:/main.dart') {
-      return new Future.value(source);
-    }
-    // TODO(ahe): Use new Future.error.
-    throw new Exception('Error: Cannot read: $uri');
-  }
-  void handler(
-      Uri uri, int begin, int end, String message, compiler.Diagnostic kind) {
-    // TODO(ahe): Remove dart:io import from
-    // ../../lib/src/source_file_provider.dart and use
-    // FormattingDiagnosticHandler instead.
-    print({
-      'uri': '$uri',
-      'begin': begin,
-      'end': end,
-      'message': message,
-      'kind': kind.name
-    });
-    if (kind == compiler.Diagnostic.ERROR) {
-      throw new Exception('Unexpected error occurred.');
-    }
-  }
-  return compiler.compile(Uri.parse('memory:/main.dart'),
-      Uri.parse('sdk:/sdk/'), null, inputProvider, handler, []);
-}
-
-int iterations = 10;
-
-main() {
-  compile(EXAMPLE_HELLO_HTML).then((jsResult) {
-    if (jsResult == null) throw 'Compilation failed';
-    if (--iterations > 0) main();
-  });
-}
-
-const String EXAMPLE_HELLO_HTML = r'''
-// Go ahead and modify this example.
-
-import "dart:html";
-
-var greeting = "Hello, World!";
-
-// Displays a greeting.
-void main() {
-  // This example uses HTML to display the greeting and it will appear
-  // in a nested HTML frame (an iframe).
-  document.body.append(new HeadingElement.h1()..appendText(greeting));
-}
-''';
diff --git a/pkg/compiler/samples/darttags/darttags.dart b/pkg/compiler/samples/darttags/darttags.dart
deleted file mode 100644
index d77966d..0000000
--- a/pkg/compiler/samples/darttags/darttags.dart
+++ /dev/null
@@ -1,186 +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.
-
-// Usage: Add the following to your .gclient file (found in the parent
-// of the "dart" in a gclient checkout of the Dart repositor).
-//
-// hooks = [
-//   {
-//     "pattern": ".",
-//     "action": [
-//       "dart/sdk/bin/dart",
-//       # Replace "xcodebuild" with "out" on Linux, and "build" on Windows.
-//       "-pdart/xcodebuild/ReleaseIA32/packages/",
-//       "dart/pkg/compiler/samples/darttags/darttags.dart",
-//       "dart/TAGS",
-//       # Modify the following list to your preferences:
-//       "dart/tests/try/web/incremental_compilation_update_test.dart",
-//       "package:compiler/src/dart2js.dart",
-//     ],
-//   },
-// ]
-//
-// Modify .emacs to contain:
-//
-//      (setq tags-table-list
-//           '("DART_LOCATION/dart"))
-//
-// Where DART_LOCATION is the gclient directory where you found .gclient.
-
-import 'dart:io';
-import 'dart:mirrors';
-
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/io/source_file.dart';
-import 'package:compiler/src/mirrors/analyze.dart' show analyze;
-import 'package:compiler/src/mirrors/dart2js_mirrors.dart' show BackDoor;
-import 'package:compiler/src/mirrors/mirrors_util.dart' show nameOf;
-import 'package:compiler/src/source_file_provider.dart';
-import 'package:compiler/src/util/uri_extras.dart';
-import 'package:sdk_library_metadata/libraries.dart' show libraries;
-
-const DART2JS = 'package:compiler/src/dart2js.dart';
-const DART2JS_MIRROR = 'package:compiler/src/mirrors/dart2js_mirrors.dart';
-const SDK_ROOT = '../../../../sdk/';
-
-bool isPublicDart2jsLibrary(String name) {
-  return !name.startsWith('_') && libraries[name].isDart2jsLibrary;
-}
-
-var handler;
-RandomAccessFile output;
-Uri outputUri;
-
-main(List<String> arguments) {
-  handler = new FormattingDiagnosticHandler()..throwOnError = true;
-
-  outputUri = handler.provider.cwd.resolve(nativeToUriPath(arguments.first));
-  output = new File(arguments.first).openSync(mode: FileMode.WRITE);
-
-  Uri myLocation = handler.provider.cwd.resolveUri(Platform.script);
-
-  List<Uri> uris = <Uri>[];
-
-  if (arguments.length > 1) {
-    // Compute tags for libraries requested by the user.
-    uris.addAll(
-        arguments.skip(1).map((argument) => Uri.base.resolve(argument)));
-  } else {
-    // Compute tags for dart2js itself.
-    uris.add(myLocation.resolve(DART2JS));
-    uris.add(myLocation.resolve(DART2JS_MIRROR));
-  }
-
-  // Get the names of public dart2js libraries.
-  Iterable<String> names = libraries.keys.where(isPublicDart2jsLibrary);
-
-  // Prepend "dart:" to the names.
-  uris.addAll(names.map((String name) => Uri.parse('dart:$name')));
-
-  Uri platformConfigUri =
-      myLocation.resolve(SDK_ROOT).resolve("lib/dart2js_shared_sdk");
-  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
-
-  analyze(uris, platformConfigUri, packageRoot, handler.provider, handler)
-      .then(processMirrors);
-}
-
-processMirrors(MirrorSystem mirrors) {
-  mirrors.libraries.forEach((_, LibraryMirror library) {
-    BackDoor.compilationUnitsOf(library).forEach(emitTagsForCompilationUnit);
-  });
-
-  output.closeSync();
-}
-
-/**
- * From http://en.wikipedia.org/wiki/Ctags#Etags_2
- *
- * A section starts with a two line header, one line containing a
- * single <\x0c> character, followed by a line which consists of:
- *
- * {src_file},{size_of_tag_definition_data_in_bytes}
- *
- * The header is followed by tag definitions, one definition per line,
- * with the format:
- *
- * {tag_definition_text}<\x7f>{tagname}<\x01>{line_number},{byte_offset}
- */
-emitTagsForCompilationUnit(compilationUnit) {
-  // Certain variables in this method do not follow Dart naming
-  // conventions.  This is because the format as written on Wikipedia
-  // looks very similar to Dart string interpolation that the author
-  // felt it would make sense to keep the names.
-  Uri uri = compilationUnit.uri;
-  var buffer = new StringBuffer();
-  SourceFile file = handler.provider.sourceFiles[uri];
-  String src_file = relativize(outputUri, uri, false);
-
-  compilationUnit.declarations.forEach((_, DeclarationMirror mirror) {
-    Definition definition = new Definition.from(mirror, file);
-    String name = nameOf(mirror);
-    definition.writeOn(buffer, name);
-
-    if (mirror is ClassMirror) {
-      emitTagsForClass(mirror, file, buffer);
-    }
-  });
-
-  var tag_definition_data = '$buffer';
-  var size_of_tag_definition_data_in_bytes = tag_definition_data.length;
-
-  // The header.
-  output.writeStringSync(
-      '\x0c\n${src_file},${size_of_tag_definition_data_in_bytes}\n');
-  output.writeStringSync(tag_definition_data);
-}
-
-void emitTagsForClass(ClassMirror cls, SourceFile file, StringBuffer buffer) {
-  String className = nameOf(cls);
-
-  cls.declarations.forEach((_, DeclarationMirror mirror) {
-    Definition definition = new Definition.from(mirror, file);
-    String name = nameOf(mirror);
-    if (mirror is MethodMirror && mirror.isConstructor) {
-      if (name == '') {
-        name = className;
-        definition.writeOn(buffer, 'new $className');
-      } else {
-        definition.writeOn(buffer, 'new $className.$name');
-      }
-    } else {
-      definition.writeOn(buffer, '$className.$name');
-    }
-    definition.writeOn(buffer, name);
-  });
-}
-
-class Definition {
-  final int byte_offset;
-  final int line_number;
-  final String tag_definition_text;
-
-  Definition(this.byte_offset, this.line_number, this.tag_definition_text);
-
-  factory Definition.from(DeclarationMirror mirror, SourceFile file) {
-    var location = mirror.location;
-    int byte_offset = location.offset;
-    int line_number = file.getLine(byte_offset) + 1;
-
-    int lineStart = file.lineStarts[line_number - 1];
-
-    int lineEnd = file.lineStarts.length > line_number
-        // Subract 1 to remove trailing newline.
-        ? file.lineStarts[line_number] - 1
-        : null;
-    String tag_definition_text = file.slowText().substring(lineStart, lineEnd);
-
-    return new Definition(byte_offset, line_number, tag_definition_text);
-  }
-
-  void writeOn(StringBuffer buffer, String tagname) {
-    buffer.write('${tag_definition_text}\x7f${tagname}'
-        '\x01${line_number},${byte_offset}\n');
-  }
-}
diff --git a/pkg/js/CHANGELOG.md b/pkg/js/CHANGELOG.md
index 4ef2ebc..d9695c3 100644
--- a/pkg/js/CHANGELOG.md
+++ b/pkg/js/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.6.1
+* Add js_util library of utility methods to efficiently manipulate typed
+  JavaScript interop objects in cases where the member name is not known
+  statically.
+
 ## 0.6.0
 
  * Version 0.6.0 is a complete rewrite of `package:js`.
diff --git a/pkg/js/lib/js_util.dart b/pkg/js/lib/js_util.dart
new file mode 100644
index 0000000..1e47e5d
--- /dev/null
+++ b/pkg/js/lib/js_util.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Allows interoperability with Javascript APIs.
+library js_util;
+
+export 'dart:js_util';
diff --git a/pkg/js/pubspec.yaml b/pkg/js/pubspec.yaml
index 7555876..03cecdb 100644
--- a/pkg/js/pubspec.yaml
+++ b/pkg/js/pubspec.yaml
@@ -1,10 +1,10 @@
 name: js
-version: 0.6.0
+version: 0.6.1
 authors:
 - Dart Team <misc@dartlang.org>
 description: Access JavaScript from Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/js
 environment:
-  sdk: '>=1.13.0 <2.0.0'
+  sdk: '>=1.19.0-dev.0.0 <2.0.0'
 dev_dependencies:
   browser: '^0.10.0+2'
diff --git a/pkg/meta/CHANGELOG.md b/pkg/meta/CHANGELOG.md
index bf761f1..4a462d7 100644
--- a/pkg/meta/CHANGELOG.md
+++ b/pkg/meta/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 1.0.2
+* Introduce `@visibleForTesting` annotation for declarations that may be referenced only in the library or in a test.
+
 ## 1.0.1
 * Updated `@factory` to allow statics and methods returning `null`.
 
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index 99a3924..a9424f9 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -97,6 +97,18 @@
 ///   corresponding to a named parameter that has this annotation.
 const Required required = const Required();
 
+/// Used to annotate a declaration was made public, so that it is more visible
+/// than otherwise necessary, to make code testable.
+///
+/// Tools, such as the analyzer, can provide feedback if
+///
+/// * the annotation is associated with a declaration not in the `lib` folder
+///   of a package;
+///   or
+/// * the declaration is referenced outside of its the defining library or a
+///   library which is in the `test` folder of the defining package.
+const _VisibleForTesting visibleForTesting = const _VisibleForTesting();
+
 /// Used to annotate a named parameter `p` in a method or function `f`.
 ///
 /// See [required] for more details.
@@ -135,3 +147,7 @@
 class _Protected {
   const _Protected();
 }
+
+class _VisibleForTesting {
+  const _VisibleForTesting();
+}
diff --git a/pkg/meta/pubspec.yaml b/pkg/meta/pubspec.yaml
index acab306..f9c9dc3 100644
--- a/pkg/meta/pubspec.yaml
+++ b/pkg/meta/pubspec.yaml
@@ -1,5 +1,5 @@
 name: meta
-version: 1.0.1
+version: 1.0.2
 author: Dart Team <misc@dartlang.org>
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/pkg.gyp b/pkg/pkg.gyp
index 771152c..84fced2 100644
--- a/pkg/pkg.gyp
+++ b/pkg/pkg.gyp
@@ -21,7 +21,7 @@
                 '"../runtime"])',
             '../sdk/lib/_internal/js_runtime/lib',
             '../sdk/lib/_internal/sdk_library_metadata/lib',
-            '../site/try',
+            '../third_party/observatory_pub_packages/packages/charted/lib',
           ],
           'outputs': [
             '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 81fe4d1..a22b9e1 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -27,15 +27,9 @@
 
 [ $runtime == vm && $system == windows]
 analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
-analysis_server/test/context_manager_test: RuntimeError # Issue 26828
 analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796
 analyzer/test/generated/all_the_rest_test: Fail # Issue 21772
 analyzer/test/generated/source_factory_test: RuntimeError # Issue 26828
-analyzer/test/src/context/builder_test: RuntimeError # Issue 26828
-analyzer/test/src/summary/linker_test: RuntimeError # Issue 26828
-analyzer/test/src/summary/prelinker_test: RuntimeError # Issue 26828
-analyzer/test/src/summary/summarize_elements_strong_test: RuntimeError # Issue 26828
-analyzer/test/src/summary/summarize_elements_test: RuntimeError # Issue 26828
 
 [ $compiler == dart2js ]
 analysis_server/test/integration: SkipByDesign # 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 subprocess.
@@ -76,9 +70,6 @@
 # Unexplained errors only occuring on Safari 6.1 and earlier.
 typed_data/test/typed_buffers_test: RuntimeError
 
-[ $compiler == dart2analyzer ]
-compiler/samples/compile_loop/compile_loop: CompileTimeError  # Issue 16524
-
 [ $compiler == dart2js && $csp ]
 # This test cannot run under CSP because it is injecting a JavaScript polyfill
 mutation_observer: Skip
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index 2f7a6bd..9d1dfee 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -2,8 +2,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-third_party/pkg/scheduled_test: Fail # Issue 26585
-
 [ $use_public_packages ]
 pkg/compiler: SkipByDesign # js_ast is not published
 
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index e6794ec..df10d3a 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -77,11 +77,6 @@
       defines += ["DART_PRECOMPILED_RUNTIME"]
     }
   } else if (dart_runtime_mode == "profile") {
-    if (dart_debug) {
-      print("Debug and profile mode are mutually exclusive.")
-    }
-    assert(!dart_debug)
-
     if (!dart_experimental_interpreter) {
       defines += ["DART_PRECOMPILED_RUNTIME"]
     }
@@ -156,7 +151,7 @@
     ]
   }
 
-  if (is_asan) {
+  if (defined(is_asan) && is_asan) {
     ldflags = [
       "-Wl,-u_sanitizer_options_link_helper",
       "-fsanitize=address",
@@ -210,7 +205,6 @@
     "--quiet",
     "--output", rebase_path(output, root_build_dir),
     "--input", rebase_path("vm/version_in.cc", root_build_dir),
-    "--ignore_svn_revision",
   ]
 }
 
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index bff1387..099686e 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -5,7 +5,12 @@
 
 declare_args() {
   dart_io_support = false
-  dart_boringssl_path = "../../third_party/boringssl"
+
+  # TODO(zra, jamesr): Remove this check once we start building boringssl for
+  # the fuchsia port.
+  if (!defined(is_fuchsia) || !is_fuchsia) {
+    dart_boringssl_path = "../../third_party/boringssl"
+  }
 }
 
 
@@ -133,6 +138,7 @@
   set_sources_assignment_filter(["*_test.cc", "*_test.h"])
   sources = [
     "log_android.cc",
+    "log_fuchsia.cc",
     "log_linux.cc",
     "log_macos.cc",
     "log_win.cc",
@@ -207,6 +213,11 @@
   ]
 }
 
+io_impl_sources_gypi =
+    exec_script("../../tools/gypi_to_gn.py",
+                [ rebase_path("io_impl_sources.gypi") ],
+                "scope",
+                [ "io_impl_sources.gypi" ])
 
 executable("gen_snapshot") {
   configs += ["..:dart_config",
@@ -242,26 +253,15 @@
   include_dirs = [
     "..",
   ]
+
+  if (is_mac) {
+    libs = [
+      "CoreFoundation.framework",
+      "CoreServices.framework"
+    ]
+  }
 }
 
-
-source_set("libdart_embedder_noio") {
-  configs += ["..:dart_config",
-              "..:dart_product_config",
-              "..:dart_precompiled_runtime_config"]
-  deps = [
-    "..:libdart",
-    "../vm:libdart_platform",
-  ]
-}
-
-io_impl_sources_gypi =
-    exec_script("../../tools/gypi_to_gn.py",
-                [ rebase_path("io_impl_sources.gypi") ],
-                "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") {
@@ -303,6 +303,17 @@
   ]
 }
 
+source_set("libdart_embedder_noio") {
+  configs += ["..:dart_config",
+              "..:dart_product_config",
+              "..:dart_precompiled_runtime_config"]
+  deps = [
+    "..:libdart",
+    "../vm:libdart_platform",
+  ]
+}
+
+
 # A source set for the implementation of 'dart:io' library
 # (without secure sockets).
 source_set("embedded_dart_io") {
@@ -329,6 +340,10 @@
     libs = [
       "Security.framework",
     ]
+  } else if (defined(is_fuchsia) && is_fuchsia) {
+    defines = [
+      "DART_IO_SECURE_SOCKET_DISABLED"
+    ]
   } else {
     deps = [
       rebase_path(dart_boringssl_path, "."),
@@ -349,9 +364,232 @@
     "log_win.cc",
     "log.h",
   ]
+  if (is_linux) {
+    sources += [ "../../third_party/root_certificates/root_certificates.cc"]
+  }
 
   include_dirs = [
     "..",
     "//third_party"
   ]
 }
+
+
+action("generate_snapshot_bin") {
+  deps = [
+    "../bin:gen_snapshot($host_toolchain)",
+  ]
+
+  vm_isolate_snapshot = "$target_gen_dir/vm_isolate_snapshot.bin"
+  isolate_snapshot = "$target_gen_dir/isolate_snapshot.bin"
+  gen_snapshot_stamp_file = "$target_gen_dir/gen_snapshot.stamp"
+  outputs = [
+    vm_isolate_snapshot,
+    isolate_snapshot,
+    gen_snapshot_stamp_file,
+  ]
+
+  gen_snapshot_dir =
+      get_label_info("../bin:gen_snapshot($host_toolchain)", "root_out_dir")
+
+  script = rebase_path("../tools/create_snapshot_bin.py")
+  args = [
+    "--executable",
+    rebase_path("$gen_snapshot_dir/gen_snapshot"),
+    "--vm_output_bin",
+    rebase_path(vm_isolate_snapshot, root_build_dir),
+    "--output_bin",
+    rebase_path(isolate_snapshot, root_build_dir),
+    "--target_os",
+    current_os,
+    "--timestamp_file",
+    rebase_path(gen_snapshot_stamp_file, root_build_dir),
+  ]
+}
+
+
+action("generate_snapshot_file") {
+  deps = [
+    ":generate_snapshot_bin",
+  ]
+
+  snapshot_in_cc_file = "snapshot_in.cc"
+  inputs = [
+    "../tools/create_snapshot_file.py",
+    snapshot_in_cc_file,
+    "$target_gen_dir/vm_isolate_snapshot.bin",
+    "$target_gen_dir/isolate_snapshot.bin",
+  ]
+  output = "$root_gen_dir/dart_snapshot.cc"
+  outputs = [
+    output,
+  ]
+
+  script = "../tools/create_snapshot_file.py"
+  args = [
+    "--vm_input_bin",
+    rebase_path("$target_gen_dir/vm_isolate_snapshot.bin"),
+    "--input_bin",
+    rebase_path("$target_gen_dir/isolate_snapshot.bin"),
+    "--input_cc",
+    rebase_path(snapshot_in_cc_file),
+    "--output",
+    rebase_path(output),
+  ]
+}
+
+
+source_set("dart_snapshot_cc") {
+  sources = [
+    "$root_gen_dir/dart_snapshot.cc",
+  ]
+
+  deps = [
+    ":generate_snapshot_file",
+  ]
+}
+
+if (defined(is_fuchsia) && is_fuchsia) {
+  executable("fuchsia_test") {
+    configs += ["..:dart_config",
+                "..:dart_product_config",
+                "..:dart_precompiled_runtime_config"]
+    sources = [
+      "fuchsia_test.cc",
+      "log_fuchsia.cc",
+    ]
+
+    include_dirs = [
+      "..",
+      "../include"
+    ]
+
+    deps = [
+      ":dart_snapshot_cc",
+      ":libdart_embedder_noio",
+    ]
+  }
+
+  copy("hello_fuchsia") {
+    sources = [ "../tests/vm/dart/hello_fuchsia_test.dart" ]
+    outputs = [ "$root_out_dir/hello_fuchsia.dart" ]
+  }
+
+  executable("dart_no_observatory") {
+    configs += ["..:dart_config",
+                "..:dart_product_config",
+                "..:dart_precompiled_runtime_config",]
+    deps = [
+      ":hello_fuchsia",
+      ":gen_resources_cc",
+      ":embedded_dart_io",
+      ":libdart_builtin",
+      "../vm:libdart_platform",
+      "..:libdart",
+      ":dart_snapshot_cc",
+      "//third_party/zlib",
+    ]
+
+    defines = [
+      "NO_OBSERVATORY",
+    ]
+
+    sources = [
+      "main.cc",
+      "observatory_assets_empty.cc",
+      "vmservice_impl.cc",
+      "vmservice_impl.h",
+      "$target_gen_dir/resources_gen.cc",
+    ]
+
+    include_dirs = [
+      "..",
+      "//third_party",
+    ]
+  }
+
+  action("generate_snapshot_test_dat_file") {
+    snapshot_test_dat_file = "$root_gen_dir/snapshot_test.dat"
+    snapshot_test_in_dat_file = "../vm/snapshot_test_in.dat"
+    snapshot_test_dart_file = "../vm/snapshot_test.dart"
+    inputs = [
+      "../tools/create_string_literal.py",
+      snapshot_test_in_dat_file,
+      snapshot_test_dart_file,
+    ]
+
+    outputs = [
+      snapshot_test_dat_file,
+    ]
+
+    script = "../tools/create_string_literal.py"
+    args = [
+      "--output",
+      rebase_path(snapshot_test_dat_file),
+      "--input_cc",
+      rebase_path(snapshot_test_in_dat_file),
+      "--include",
+      "INTENTIONALLY_LEFT_BLANK",
+      "--var_name",
+      "INTENTIONALLY_LEFT_BLANK_TOO",
+      rebase_path(snapshot_test_dart_file),
+    ]
+  }
+
+  executable("run_vm_tests") {
+    testonly = true
+    configs += ["..:dart_config",
+                "..:dart_product_config",
+                "..:dart_precompiled_runtime_config",]
+    deps = [
+      "..:libdart",
+      ":libdart_builtin",
+      ":embedded_dart_io",
+      ":dart_snapshot_cc",
+      ":generate_snapshot_test_dat_file",
+      "../vm:libdart_platform",
+      "//third_party/zlib",
+    ]
+    include_dirs = [
+      "..",
+      "$target_gen_dir",
+    ]
+    defines = [
+      "TESTING",
+    ]
+
+    vm_tests_list = exec_script("../../tools/gypi_to_gn.py",
+                                  [rebase_path("../vm/vm_sources.gypi"),
+                                   "--keep_only=_test.cc",
+                                   "--keep_only=_test.h",],
+                                  "scope",
+                                  ["../vm/vm_sources.gypi"])
+    vm_tests = rebase_path(vm_tests_list.sources, ".", "../vm")
+
+    builtin_impl_tests_list =
+        exec_script("../../tools/gypi_to_gn.py",
+                    [rebase_path("builtin_impl_sources.gypi"),
+                     "--keep_only=_test.cc",
+                     "--keep_only=_test.h",],
+                    "scope",
+                    ["builtin_impl_sources.gypi"])
+
+    sources = [
+      "run_vm_tests.cc",
+    ] + builtin_impl_tests_list.sources + vm_tests
+  }
+
+  copy("fuchsia_vm_tests") {
+    sources = [ "fuchsia_vm_tests.txt" ]
+    outputs = [ "$root_out_dir/fuchsia_vm_tests.txt" ]
+  }
+
+  executable("run_vm_tests_fuchsia") {
+    testonly = true
+    configs += ["..:dart_config"]
+    sources = [
+      "run_vm_tests_fuchsia.cc"
+    ]
+    libs = [ "launchpad" ]
+  }
+}  # defined(is_fuchsia) && is_fuchsia
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 2d04720..43b5915 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -11,6 +11,7 @@
     'html_cc_file': '<(gen_source_dir)/html_gen.cc',
     'html_common_cc_file': '<(gen_source_dir)/html_common_gen.cc',
     'js_cc_file': '<(gen_source_dir)/js_gen.cc',
+    'js_util_cc_file': '<(gen_source_dir)/js_util_gen.cc',
     'blink_cc_file': '<(gen_source_dir)/blink_gen.cc',
     'indexeddb_cc_file': '<(gen_source_dir)/indexeddb_gen.cc',
     'cached_patches_cc_file': '<(gen_source_dir)/cached_patches_gen.cc',
@@ -234,6 +235,38 @@
       ]
     },
     {
+      'target_name': 'generate_js_util_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/js_util/dartium/js_util_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_js_util_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(js_util_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(js_util_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::js_util_source_paths_',
+        '--library_name', 'dart:js_util',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(js_util_cc_file)'' file.'
+      },
+      ]
+    },
+    {
       'target_name': 'generate_blink_cc_file',
       'type': 'none',
       'toolsets':['host'],
@@ -500,6 +533,7 @@
         'generate_html_cc_file#host',
         'generate_html_common_cc_file#host',
         'generate_js_cc_file#host',
+        'generate_js_util_cc_file#host',
         'generate_blink_cc_file#host',
         'generate_indexeddb_cc_file#host',
         'generate_cached_patches_cc_file#host',
@@ -682,6 +716,10 @@
           'defines': [
             'DART_IO_SECURE_SOCKET_DISABLED'
           ],
+        }, {
+          'sources': [
+            '../../third_party/root_certificates/root_certificates.cc',
+          ],
         }],
         ['OS=="win"', {
           'sources/' : [
@@ -758,6 +796,10 @@
           'defines': [
             'DART_IO_SECURE_SOCKET_DISABLED'
           ],
+        }, {
+          'sources': [
+            '../../third_party/root_certificates/root_certificates.cc',
+          ],
         }],
         ['OS != "mac" and dart_io_support==1 and dart_io_secure_socket==1', {
           'dependencies': [
@@ -818,6 +860,10 @@
           'defines': [
             'DART_IO_SECURE_SOCKET_DISABLED',
           ],
+        }, {
+          'sources': [
+            '../../third_party/root_certificates/root_certificates.cc',
+          ],
         }],
         ['OS != "mac" and dart_io_support==1 and dart_io_secure_socket==1', {
           'dependencies': [
@@ -1058,20 +1104,6 @@
       ]
     },
     {
-      'target_name': 'fuchsia_test',
-      'type': 'executable',
-      'dependencies': [
-        'libdart_nosnapshot',
-      ],
-      'include_dirs': [
-        '..',
-        '../include',
-      ],
-      'sources': [
-        'fuchsia_test.cc',
-      ],
-    },
-    {
       # dart binary with a snapshot of corelibs built in.
       'target_name': 'dart',
       'type': 'executable',
@@ -1264,6 +1296,7 @@
         '<(html_cc_file)',
         '<(html_common_cc_file)',
         '<(js_cc_file)',
+        '<(js_util_cc_file)',
         '<(blink_cc_file)',
         '<(indexeddb_cc_file)',
         '<(cached_patches_cc_file)',
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index c26a762..2c303a1 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -24,6 +24,7 @@
   { "dart:html", html_source_paths_, NULL, NULL, true },
   { "dart:html_common", html_common_source_paths_, NULL, NULL, true},
   { "dart:js", js_source_paths_, NULL, NULL, true},
+  { "dart:js_util", js_util_source_paths_, NULL, NULL, true},
   { "dart:_blink", blink_source_paths_, NULL, NULL, true },
   { "dart:indexed_db", indexeddb_source_paths_, NULL, NULL, true },
   { "cached_patches.dart", cached_patches_source_paths_, NULL, NULL, true },
@@ -118,7 +119,7 @@
   ASSERT(static_cast<int>(id) >= 0);
   ASSERT(static_cast<int>(id) < num_libs_);
 
-  Dart_Handle library = Dart_LoadLibrary(url, Source(id), 0, 0);
+  Dart_Handle library = Dart_LoadLibrary(url, Dart_Null(), Source(id), 0, 0);
   if (!Dart_IsError(library) && (builtin_libraries_[id].has_natives_)) {
     // Setup the native resolver for built in library functions.
     DART_CHECK_VALID(
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 7780208..d4aa012 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -346,11 +346,11 @@
 // Handling of Resource class by dispatching to the load port.
 Future<List<int>> _resourceReadAsBytes(Uri uri) async {
   List response = await _makeLoaderRequest(_Dart_kResourceLoad, uri.toString());
-  if (response[3] is String) {
+  if (response[4] is String) {
     // Throw the error.
-    throw response[3];
+    throw response[4];
   } else {
-    return response[3];
+    return response[4];
   }
 }
 
diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h
index 5029cf1..d90223a 100644
--- a/runtime/bin/builtin.h
+++ b/runtime/bin/builtin.h
@@ -74,6 +74,7 @@
   static const char* html_source_paths_[];
   static const char* html_common_source_paths_[];
   static const char* js_source_paths_[];
+  static const char* js_util_source_paths_[];
   static const char* blink_source_paths_[];
   static const char* indexeddb_source_paths_[];
   static const char* cached_patches_source_paths_[];
diff --git a/runtime/bin/builtin_impl_sources.gypi b/runtime/bin/builtin_impl_sources.gypi
index f775ffc..ac6ee92 100644
--- a/runtime/bin/builtin_impl_sources.gypi
+++ b/runtime/bin/builtin_impl_sources.gypi
@@ -10,8 +10,10 @@
     'crypto.cc',
     'crypto.h',
     'crypto_android.cc',
+    'crypto_fuchsia.cc',
     'crypto_linux.cc',
     'crypto_macos.cc',
+    'crypto_test.cc',
     'crypto_win.cc',
     'builtin_common.cc',
     'dartutils.cc',
@@ -19,6 +21,7 @@
     'directory.cc',
     'directory.h',
     'directory_android.cc',
+    'directory_fuchsia.cc',
     'directory_linux.cc',
     'directory_macos.cc',
     'directory_unsupported.cc',
@@ -27,6 +30,7 @@
     'extensions.h',
     'extensions.cc',
     'extensions_android.cc',
+    'extensions_fuchsia.cc',
     'extensions_linux.cc',
     'extensions_macos.cc',
     'extensions_win.cc',
@@ -37,6 +41,7 @@
     'file.cc',
     'file.h',
     'file_android.cc',
+    'file_fuchsia.cc',
     'file_linux.cc',
     'file_macos.cc',
     'file_support.cc',
@@ -53,6 +58,8 @@
     'thread.h',
     'thread_android.cc',
     'thread_android.h',
+    'thread_fuchsia.cc',
+    'thread_fuchsia.h',
     'thread_linux.cc',
     'thread_linux.h',
     'thread_macos.cc',
@@ -61,6 +68,7 @@
     'thread_win.h',
     'utils.h',
     'utils_android.cc',
+    'utils_fuchsia.cc',
     'utils_linux.cc',
     'utils_macos.cc',
     'utils_win.cc',
diff --git a/runtime/bin/common_patch.dart b/runtime/bin/common_patch.dart
index feaf552..b485dc9a 100644
--- a/runtime/bin/common_patch.dart
+++ b/runtime/bin/common_patch.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch class _IOCrypto {
-  /* patch */ static Uint8List getRandomBytes(int count)
+@patch class _IOCrypto {
+  @patch static Uint8List getRandomBytes(int count)
       native "Crypto_GetRandomBytes";
 }
 
diff --git a/runtime/bin/crypto_fuchsia.cc b/runtime/bin/crypto_fuchsia.cc
new file mode 100644
index 0000000..04c5f22
--- /dev/null
+++ b/runtime/bin/crypto_fuchsia.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "platform/globals.h"
+#if defined(TARGET_OS_FUCHSIA)
+
+#include "bin/crypto.h"
+
+#include <magenta/syscalls.h>
+
+namespace dart {
+namespace bin {
+
+bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
+  intptr_t read = 0;
+  while (read < count) {
+    const intptr_t remaining = count - read;
+    const intptr_t len =
+        (MX_CPRNG_DRAW_MAX_LEN < remaining) ? MX_CPRNG_DRAW_MAX_LEN
+                                            : remaining;
+    const mx_ssize_t res = mx_cprng_draw(buffer + read, len);
+    if (res == ERR_INVALID_ARGS) {
+      return false;
+    }
+    read += res;
+  }
+  return true;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/crypto_test.cc b/runtime/bin/crypto_test.cc
new file mode 100644
index 0000000..65a2ac3
--- /dev/null
+++ b/runtime/bin/crypto_test.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "bin/crypto.h"
+#include "platform/assert.h"
+#include "platform/globals.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+namespace bin {
+
+TEST_CASE(GetRandomBytes) {
+  const intptr_t kNumRandomBytes = 127;
+  uint8_t buf[kNumRandomBytes];
+  const bool res = Crypto::GetRandomBytes(kNumRandomBytes, buf);
+  EXPECT(res);
+}
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 1b1f42f..e723764 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -434,7 +434,7 @@
       Dart_Handle part_uri_obj = DartUtils::NewString(part_uri);
       free(part_uri);
       return Dart_LoadSource(library,
-                             part_uri_obj,
+                             part_uri_obj, Dart_Null(),
                              Builtin::PartSource(id, url_string), 0, 0);
     }
     // All cases should have been handled above.
@@ -570,7 +570,8 @@
         result = DartUtils::NewError("%s is not a valid UTF-8 script",
                                      resolved_script_uri);
       } else {
-        result = Dart_LoadScript(resolved_script_uri, source, 0, 0);
+        result = Dart_LoadScript(resolved_script_uri, Dart_Null(),
+                                 source, 0, 0);
       }
     }
   } else {
@@ -582,14 +583,16 @@
                                    resolved_script_uri);
     } else {
       if (tag == Dart_kImportTag) {
-        result = Dart_LoadLibrary(resolved_script_uri, source, 0, 0);
+        result = Dart_LoadLibrary(resolved_script_uri, Dart_Null(),
+                                  source, 0, 0);
       } else {
         ASSERT(tag == Dart_kSourceTag);
         Dart_Handle library = Dart_LookupLibrary(library_uri);
         if (Dart_IsError(library)) {
           Dart_PropagateError(library);
         }
-        result = Dart_LoadSource(library, resolved_script_uri, source, 0, 0);
+        result = Dart_LoadSource(library, resolved_script_uri, Dart_Null(),
+                                 source, 0, 0);
       }
     }
   }
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index a9b2331..ccf5918 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -14,6 +14,8 @@
 namespace dart {
 namespace bin {
 
+char* Directory::system_temp_path_override_ = NULL;
+
 void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) {
   const char* current = Directory::Current();
   if (current != NULL) {
@@ -187,6 +189,17 @@
 }
 
 
+void Directory::SetSystemTemp(const char* path) {
+  if (system_temp_path_override_ != NULL) {
+    free(system_temp_path_override_);
+    system_temp_path_override_ = NULL;
+  }
+  if (path != NULL) {
+    system_temp_path_override_ = strdup(path);
+  }
+}
+
+
 CObject* Directory::CreateRequest(const CObjectArray& request) {
   if ((request.Length() == 1) && request[0]->IsString()) {
     CObjectString path(request[0]);
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index f455710..ee1f389 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -274,6 +274,8 @@
   static const char* Current();
   static const char* SystemTemp();
   static const char* CreateTemp(const char* path);
+  // Set the system temporary directory.
+  static void SetSystemTemp(const char* path);
   static bool SetCurrent(const char* path);
   static bool Create(const char* path);
   static bool Delete(const char* path, bool recursive);
@@ -290,6 +292,7 @@
   static CObject* RenameRequest(const CObjectArray& request);
 
  private:
+  static char* system_temp_path_override_;
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(Directory);
 };
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index 95f42da..75ca974 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -403,6 +403,9 @@
 
 
 const char* Directory::SystemTemp() {
+  if (Directory::system_temp_path_override_ != NULL) {
+    return DartUtils::ScopedCopyCString(Directory::system_temp_path_override_);
+  }
   // Android does not have a /tmp directory. A partial substitute,
   // suitable for bring-up work and tests, is to create a tmp
   // directory in /data/local/tmp.
diff --git a/runtime/bin/directory_fuchsia.cc b/runtime/bin/directory_fuchsia.cc
new file mode 100644
index 0000000..a1387b0
--- /dev/null
+++ b/runtime/bin/directory_fuchsia.cc
@@ -0,0 +1,154 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_FUCHSIA)
+
+#include "bin/directory.h"
+
+#include <errno.h>  // NOLINT
+#include <stdlib.h>  // NOLINT
+#include <string.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+namespace dart {
+namespace bin {
+
+PathBuffer::PathBuffer() : length_(0) {
+  data_ = calloc(PATH_MAX + 1, sizeof(char));  // NOLINT
+}
+
+
+PathBuffer::~PathBuffer() {
+  free(data_);
+}
+
+
+bool PathBuffer::AddW(const wchar_t* name) {
+  UNREACHABLE();
+  return false;
+}
+
+
+char* PathBuffer::AsString() const {
+  return reinterpret_cast<char*>(data_);
+}
+
+
+wchar_t* PathBuffer::AsStringW() const {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+const char* PathBuffer::AsScopedString() const {
+  return DartUtils::ScopedCopyCString(AsString());
+}
+
+
+bool PathBuffer::Add(const char* name) {
+  const intptr_t name_length = strnlen(name, PATH_MAX + 1);
+  if (name_length == 0) {
+    errno = EINVAL;
+    return false;
+  }
+  char* data = AsString();
+  int written = snprintf(data + length_,
+                         PATH_MAX - length_,
+                         "%s",
+                         name);
+  data[PATH_MAX] = '\0';
+  if ((written <= (PATH_MAX - length_)) &&
+      (written > 0) &&
+      (static_cast<size_t>(written) == strnlen(name, PATH_MAX + 1))) {
+    length_ += written;
+    return true;
+  } else {
+    errno = ENAMETOOLONG;
+    return false;
+  }
+}
+
+
+void PathBuffer::Reset(intptr_t new_length) {
+  length_ = new_length;
+  AsString()[length_] = '\0';
+}
+
+
+ListType DirectoryListingEntry::Next(DirectoryListing* listing) {
+  UNIMPLEMENTED();
+  return kListError;
+}
+
+
+DirectoryListingEntry::~DirectoryListingEntry() {
+  UNIMPLEMENTED();
+}
+
+
+void DirectoryListingEntry::ResetLink() {
+  UNIMPLEMENTED();
+}
+
+
+Directory::ExistsResult Directory::Exists(const char* dir_name) {
+  UNIMPLEMENTED();
+  return UNKNOWN;
+}
+
+
+char* Directory::CurrentNoScope() {
+  return getcwd(NULL, 0);
+}
+
+
+const char* Directory::Current() {
+  char buffer[PATH_MAX];
+  if (getcwd(buffer, PATH_MAX) == NULL) {
+    return NULL;
+  }
+  return DartUtils::ScopedCopyCString(buffer);
+}
+
+
+bool Directory::SetCurrent(const char* path) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Directory::Create(const char* dir_name) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+const char* Directory::SystemTemp() {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+const char* Directory::CreateTemp(const char* prefix) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+bool Directory::Delete(const char* dir_name, bool recursive) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Directory::Rename(const char* path, const char* new_path) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/directory_patch.dart b/runtime/bin/directory_patch.dart
index 9f4a265..2518283 100644
--- a/runtime/bin/directory_patch.dart
+++ b/runtime/bin/directory_patch.dart
@@ -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.
 
-patch class _Directory {
-  /* patch */ static _current() native "Directory_Current";
-  /* patch */ static _setCurrent(path) native "Directory_SetCurrent";
-  /* patch */ static _createTemp(String path) native "Directory_CreateTemp";
-  /* patch */ static String _systemTemp() native "Directory_SystemTemp";
-  /* patch */ static _exists(String path) native "Directory_Exists";
-  /* patch */ static _create(String path) native "Directory_Create";
-  /* patch */ static _deleteNative(String path, bool recursive)
+@patch class _Directory {
+  @patch static _current() native "Directory_Current";
+  @patch static _setCurrent(path) native "Directory_SetCurrent";
+  @patch static _createTemp(String path) native "Directory_CreateTemp";
+  @patch static String _systemTemp() native "Directory_SystemTemp";
+  @patch static _exists(String path) native "Directory_Exists";
+  @patch static _create(String path) native "Directory_Create";
+  @patch static _deleteNative(String path, bool recursive)
       native "Directory_Delete";
-  /* patch */ static _rename(String path, String newPath)
+  @patch static _rename(String path, String newPath)
       native "Directory_Rename";
-  /* patch */ static void _fillWithDirectoryListing(
+  @patch static void _fillWithDirectoryListing(
       List<FileSystemEntity> list, String path, bool recursive,
       bool followLinks)
       native "Directory_FillWithDirectoryListing";
 }
 
-patch class _AsyncDirectoryListerOps {
-  /* patch */ factory _AsyncDirectoryListerOps(int pointer) =>
+@patch class _AsyncDirectoryListerOps {
+  @patch factory _AsyncDirectoryListerOps(int pointer) =>
       new _AsyncDirectoryListerOpsImpl(pointer);
 }
 
diff --git a/runtime/bin/embedded_dart_io.cc b/runtime/bin/embedded_dart_io.cc
index 9e38f02..8b1b7fb 100644
--- a/runtime/bin/embedded_dart_io.cc
+++ b/runtime/bin/embedded_dart_io.cc
@@ -4,6 +4,7 @@
 
 #include "bin/embedded_dart_io.h"
 
+#include "bin/directory.h"
 #include "bin/eventhandler.h"
 #include "bin/utils.h"
 #include "bin/thread.h"
@@ -18,5 +19,10 @@
   EventHandler::Start();
 }
 
+
+void SetSystemTempDirectory(const char* system_temp) {
+  Directory::SetSystemTemp(system_temp);
+}
+
 }  // namespace bin
 }  // namespace dart
diff --git a/runtime/bin/embedded_dart_io.h b/runtime/bin/embedded_dart_io.h
index a5b069d..56dbba8 100644
--- a/runtime/bin/embedded_dart_io.h
+++ b/runtime/bin/embedded_dart_io.h
@@ -11,6 +11,10 @@
 // Bootstraps 'dart:io'.
 void BootstrapDartIo();
 
+// Lets dart:io know where the system temporary directory is located.
+// Currently only wired up on Android.
+void SetSystemTempDirectory(const char* system_temp);
+
 // Tells the system whether to capture Stdout events.
 void SetCaptureStdout(bool value);
 
diff --git a/runtime/bin/eventhandler.h b/runtime/bin/eventhandler.h
index 34f6c65..44b5ec8 100644
--- a/runtime/bin/eventhandler.h
+++ b/runtime/bin/eventhandler.h
@@ -132,6 +132,8 @@
  public:
   CircularLinkedList() : head_(NULL) {}
 
+  typedef void (*ClearFun) (void* value);
+
   // Returns true if the list was empty.
   bool Add(T t) {
     Entry* e = new Entry(t);
@@ -151,7 +153,7 @@
     }
   }
 
-  void RemoveHead() {
+  void RemoveHead(ClearFun clear = NULL) {
     ASSERT(head_ != NULL);
 
     Entry* e = head_;
@@ -162,6 +164,9 @@
       e->next_->prev_ = e->prev_;
       head_ = e->next_;
     }
+    if (clear != NULL) {
+      clear(reinterpret_cast<void*>(e->t));
+    }
     delete e;
   }
 
@@ -195,9 +200,9 @@
     }
   }
 
-  void RemoveAll() {
+  void RemoveAll(ClearFun clear = NULL) {
     while (HasHead()) {
-      RemoveHead();
+      RemoveHead(clear);
     }
   }
 
@@ -413,7 +418,9 @@
       : DI(fd), tokens_map_(&SamePortValue, kTokenCount),
         disable_tokens_(disable_tokens) {}
 
-  virtual ~DescriptorInfoMultipleMixin() {}
+  virtual ~DescriptorInfoMultipleMixin() {
+    RemoveAllPorts();
+  }
 
   virtual bool IsListeningSocket() const { return true; }
 
@@ -497,14 +504,16 @@
   }
 
   virtual void RemoveAllPorts() {
-    active_readers_.RemoveAll();
     for (HashMap::Entry *entry = tokens_map_.Start();
          entry != NULL;
          entry = tokens_map_.Next(entry)) {
       PortEntry* pentry = reinterpret_cast<PortEntry*>(entry->value);
+      entry->value = NULL;
+      active_readers_.Remove(pentry);
       delete pentry;
     }
     tokens_map_.Clear();
+    active_readers_.RemoveAll(DeletePortEntry);
   }
 
   virtual Dart_Port NextNotifyDartPort(intptr_t events_ready) {
@@ -585,6 +594,11 @@
   }
 
  private:
+  static void DeletePortEntry(void* data) {
+    PortEntry* entry = reinterpret_cast<PortEntry*>(data);
+    delete entry;
+  }
+
   // The [Dart_Port]s which are not paused (i.e. are interested in read events,
   // i.e. `mask == (1 << kInEvent)`) and we have enough tokens to communicate
   // with them.
@@ -605,6 +619,8 @@
 // The event handler delegation class is OS specific.
 #if defined(TARGET_OS_ANDROID)
 #include "bin/eventhandler_android.h"
+#elif defined(TARGET_OS_FUCHSIA)
+#include "bin/eventhandler_fuchsia.h"
 #elif defined(TARGET_OS_LINUX)
 #include "bin/eventhandler_linux.h"
 #elif defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index 1b7bbdb..c298a04 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -118,7 +118,15 @@
 }
 
 
+static void DeleteDescriptorInfo(void* info) {
+  DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info);
+  di->Close();
+  delete di;
+}
+
+
 EventHandlerImplementation::~EventHandlerImplementation() {
+  socket_map_.Clear(DeleteDescriptorInfo);
   VOID_TEMP_FAILURE_RETRY(close(epoll_fd_));
   VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
   VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
new file mode 100644
index 0000000..69c2190
--- /dev/null
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if !defined(DART_IO_DISABLED)
+
+#include "platform/globals.h"
+#if defined(TARGET_OS_FUCHSIA)
+
+#include "bin/eventhandler.h"
+#include "bin/eventhandler_fuchsia.h"
+
+#include <magenta/syscalls.h>
+#include <runtime/status.h>
+
+#include "bin/thread.h"
+#include "bin/utils.h"
+
+namespace dart {
+namespace bin {
+
+EventHandlerImplementation::EventHandlerImplementation() {
+  mx_status_t status = mx_message_pipe_create(interrupt_handles_, 0);
+  if (status != NO_ERROR) {
+    FATAL1("mx_message_pipe_create failed: %s\n", mx_strstatus(status));
+  }
+}
+
+
+EventHandlerImplementation::~EventHandlerImplementation() {
+  mx_status_t status = mx_handle_close(interrupt_handles_[0]);
+  if (status != NO_ERROR) {
+    FATAL1("mx_handle_close failed: %s\n", mx_strstatus(status));
+  }
+  status = mx_handle_close(interrupt_handles_[1]);
+  if (status != NO_ERROR) {
+    FATAL1("mx_handle_close failed: %s\n", mx_strstatus(status));
+  }
+}
+
+
+void EventHandlerImplementation::WakeupHandler(intptr_t id,
+                                               Dart_Port dart_port,
+                                               int64_t data) {
+  InterruptMessage msg;
+  msg.id = id;
+  msg.dart_port = dart_port;
+  msg.data = data;
+
+  mx_status_t status =
+    mx_message_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0);
+  if (status != NO_ERROR) {
+    FATAL1("mx_message_write failed: %s\n", mx_strstatus(status));
+  }
+}
+
+
+void EventHandlerImplementation::HandleInterruptFd() {
+  InterruptMessage msg;
+  uint32_t bytes = kInterruptMessageSize;
+  mx_status_t status;
+  while (true) {
+    status = mx_message_read(
+        interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0);
+    if (status != NO_ERROR) {
+      break;
+    }
+    ASSERT(bytes == kInterruptMessageSize);
+    if (msg.id == kTimerId) {
+      timeout_queue_.UpdateTimeout(msg.dart_port, msg.data);
+    } else if (msg.id == kShutdownId) {
+      shutdown_ = true;
+    } else {
+      UNIMPLEMENTED();
+    }
+  }
+  // status == ERR_BAD_STATE when we try to read and there are no messages
+  // available, so it is an error if we get here and status != ERR_BAD_STATE.
+  if (status != ERR_BAD_STATE) {
+    FATAL1("mx_message_read failed: %s\n", mx_strstatus(status));
+  }
+}
+
+
+void EventHandlerImplementation::HandleEvents() {
+  // TODO(zra): Handle events from other handles. At the moment we are only
+  // interrupted when there is a message on interrupt_handles_[0].
+  HandleInterruptFd();
+}
+
+
+int64_t EventHandlerImplementation::GetTimeout() const {
+  if (!timeout_queue_.HasTimeout()) {
+    return kInfinityTimeout;
+  }
+  int64_t millis = timeout_queue_.CurrentTimeout() -
+      TimerUtils::GetCurrentMonotonicMillis();
+  return (millis < 0) ? 0 : millis;
+}
+
+
+void EventHandlerImplementation::HandleTimeout() {
+  if (timeout_queue_.HasTimeout()) {
+    int64_t millis = timeout_queue_.CurrentTimeout() -
+        TimerUtils::GetCurrentMonotonicMillis();
+    if (millis <= 0) {
+      DartUtils::PostNull(timeout_queue_.CurrentPort());
+      timeout_queue_.RemoveCurrent();
+    }
+  }
+}
+
+
+void EventHandlerImplementation::Poll(uword args) {
+  EventHandler* handler = reinterpret_cast<EventHandler*>(args);
+  EventHandlerImplementation* handler_impl = &handler->delegate_;
+  ASSERT(handler_impl != NULL);
+
+  while (!handler_impl->shutdown_) {
+    int64_t millis = handler_impl->GetTimeout();
+    ASSERT((millis == kInfinityTimeout) || (millis >= 0));
+
+    mx_time_t timeout =
+        millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond;
+    mx_signals_state_t signals_state;
+    mx_status_t status = mx_handle_wait_one(
+        handler_impl->interrupt_handles_[0],
+        MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED,
+        timeout,
+        &signals_state);
+    if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) {
+      FATAL1("mx_handle_wait_one failed: %s\n", mx_strstatus(status));
+    } else {
+      handler_impl->HandleTimeout();
+      if ((signals_state.satisfied & MX_SIGNAL_READABLE) != 0) {
+        handler_impl->HandleEvents();
+      }
+      if ((signals_state.satisfied & MX_SIGNAL_PEER_CLOSED) != 0) {
+        FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n");
+      }
+    }
+  }
+  handler->NotifyShutdownDone();
+}
+
+
+void EventHandlerImplementation::Start(EventHandler* handler) {
+  int result = Thread::Start(&EventHandlerImplementation::Poll,
+                             reinterpret_cast<uword>(handler));
+  if (result != 0) {
+    FATAL1("Failed to start event handler thread %d", result);
+  }
+}
+
+
+void EventHandlerImplementation::Shutdown() {
+  SendData(kShutdownId, 0, 0);
+}
+
+
+void EventHandlerImplementation::SendData(intptr_t id,
+                                          Dart_Port dart_port,
+                                          int64_t data) {
+  WakeupHandler(id, dart_port, data);
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
+
+#endif  // !defined(DART_IO_DISABLED)
diff --git a/runtime/bin/eventhandler_fuchsia.h b/runtime/bin/eventhandler_fuchsia.h
new file mode 100644
index 0000000..0130992
--- /dev/null
+++ b/runtime/bin/eventhandler_fuchsia.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_EVENTHANDLER_FUCHSIA_H_
+#define BIN_EVENTHANDLER_FUCHSIA_H_
+
+#if !defined(BIN_EVENTHANDLER_H_)
+#error Do not include eventhandler_fuchsia.h directly; use eventhandler.h instead.
+#endif
+
+#include <magenta/syscalls.h>
+
+namespace dart {
+namespace bin {
+
+class EventHandlerImplementation {
+ public:
+  EventHandlerImplementation();
+  ~EventHandlerImplementation();
+
+  void SendData(intptr_t id, Dart_Port dart_port, int64_t data);
+  void Start(EventHandler* handler);
+  void Shutdown();
+
+ private:
+  int64_t GetTimeout() const;
+  void HandleEvents();
+  void HandleTimeout();
+  void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data);
+  void HandleInterruptFd();
+  static void Poll(uword args);
+
+  TimeoutQueue timeout_queue_;
+  bool shutdown_;
+  mx_handle_t interrupt_handles_[2];
+
+  DISALLOW_COPY_AND_ASSIGN(EventHandlerImplementation);
+};
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // BIN_EVENTHANDLER_FUCHSIA_H_
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index 59cbdcd..bd61e80 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -127,7 +127,15 @@
 }
 
 
+static void DeleteDescriptorInfo(void* info) {
+  DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info);
+  di->Close();
+  delete di;
+}
+
+
 EventHandlerImplementation::~EventHandlerImplementation() {
+  socket_map_.Clear(DeleteDescriptorInfo);
   VOID_TEMP_FAILURE_RETRY(close(epoll_fd_));
   VOID_TEMP_FAILURE_RETRY(close(timer_fd_));
   VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index c2b7833..b55ea8e 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -140,7 +140,15 @@
 }
 
 
+static void DeleteDescriptorInfo(void* info) {
+  DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info);
+  di->Close();
+  delete di;
+}
+
+
 EventHandlerImplementation::~EventHandlerImplementation() {
+  socket_map_.Clear(DeleteDescriptorInfo);
   VOID_TEMP_FAILURE_RETRY(close(kqueue_fd_));
   VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
   VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
diff --git a/runtime/bin/eventhandler_patch.dart b/runtime/bin/eventhandler_patch.dart
index d92271b..effe402 100644
--- a/runtime/bin/eventhandler_patch.dart
+++ b/runtime/bin/eventhandler_patch.dart
@@ -4,8 +4,8 @@
 
 import 'dart:nativewrappers';
 
-patch class _EventHandler {
-  /* patch */ static void _sendData(Object sender,
+@patch class _EventHandler {
+  @patch static void _sendData(Object sender,
                                     SendPort sendPort,
                                     int data)
       native "EventHandler_SendData";
diff --git a/runtime/bin/extensions_fuchsia.cc b/runtime/bin/extensions_fuchsia.cc
new file mode 100644
index 0000000..d474672
--- /dev/null
+++ b/runtime/bin/extensions_fuchsia.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_FUCHSIA)
+
+#include "bin/extensions.h"
+#include <dlfcn.h>  // NOLINT
+
+namespace dart {
+namespace bin {
+
+const char* kPrecompiledLibraryName = "libprecompiled.so";
+const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot";
+const char* kPrecompiledDataSymbolName = "_kDataSnapshot";
+
+void* Extensions::LoadExtensionLibrary(const char* library_file) {
+  return dlopen(library_file, RTLD_LAZY);
+}
+
+void* Extensions::ResolveSymbol(void* lib_handle, const char* symbol) {
+  dlerror();
+  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
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 43e1944..a3dcd7f 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -113,6 +113,7 @@
 void FUNCTION_NAME(File_Close)(Dart_NativeArguments args) {
   File* file = GetFile(args);
   ASSERT(file != NULL);
+  file->Close();
   file->DeleteWeakHandle(Dart_CurrentIsolate());
   file->Release();
 
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
new file mode 100644
index 0000000..fdc2623
--- /dev/null
+++ b/runtime/bin/file_fuchsia.cc
@@ -0,0 +1,452 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_FUCHSIA)
+
+#include "bin/file.h"
+
+#include <errno.h>  // NOLINT
+#include <fcntl.h>  // NOLINT
+#include <libgen.h>  // NOLINT
+#include <sys/mman.h>  // NOLINT
+#include <sys/stat.h>  // NOLINT
+#include <sys/types.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#include "bin/builtin.h"
+#include "bin/log.h"
+#include "platform/signal_blocker.h"
+#include "platform/utils.h"
+
+namespace dart {
+namespace bin {
+
+class FileHandle {
+ public:
+  explicit FileHandle(int fd) : fd_(fd) { }
+  ~FileHandle() { }
+  int fd() const { return fd_; }
+  void set_fd(int fd) { fd_ = fd; }
+
+ private:
+  int fd_;
+
+  DISALLOW_COPY_AND_ASSIGN(FileHandle);
+};
+
+
+File::~File() {
+  if (!IsClosed()) {
+    Close();
+  }
+  delete handle_;
+}
+
+
+void File::Close() {
+  ASSERT(handle_->fd() >= 0);
+  if (handle_->fd() == STDOUT_FILENO) {
+    // If stdout, redirect fd to /dev/null.
+    int null_fd = NO_RETRY_EXPECTED(open("/dev/null", O_WRONLY));
+    ASSERT(null_fd >= 0);
+    VOID_NO_RETRY_EXPECTED(dup2(null_fd, handle_->fd()));
+    VOID_NO_RETRY_EXPECTED(close(null_fd));
+  } else {
+    int err = NO_RETRY_EXPECTED(close(handle_->fd()));
+    if (err != 0) {
+      const int kBufferSize = 1024;
+      char error_buf[kBufferSize];
+      Log::PrintErr("%s\n", Utils::StrError(errno, error_buf, kBufferSize));
+    }
+  }
+  handle_->set_fd(kClosedFd);
+}
+
+
+intptr_t File::GetFD() {
+  return handle_->fd();
+}
+
+
+bool File::IsClosed() {
+  return handle_->fd() == kClosedFd;
+}
+
+
+void* File::MapExecutable(intptr_t* len) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+int64_t File::Read(void* buffer, int64_t num_bytes) {
+  ASSERT(handle_->fd() >= 0);
+  return NO_RETRY_EXPECTED(read(handle_->fd(), buffer, num_bytes));
+}
+
+
+int64_t File::Write(const void* buffer, int64_t num_bytes) {
+  ASSERT(handle_->fd() >= 0);
+  return NO_RETRY_EXPECTED(write(handle_->fd(), buffer, num_bytes));
+}
+
+
+int64_t File::Position() {
+  ASSERT(handle_->fd() >= 0);
+  return NO_RETRY_EXPECTED(lseek(handle_->fd(), 0, SEEK_CUR));
+}
+
+
+bool File::SetPosition(int64_t position) {
+  ASSERT(handle_->fd() >= 0);
+  return NO_RETRY_EXPECTED(lseek(handle_->fd(), position, SEEK_SET)) >= 0;
+}
+
+
+bool File::Truncate(int64_t length) {
+  ASSERT(handle_->fd() >= 0);
+  return NO_RETRY_EXPECTED(ftruncate(handle_->fd(), length) != -1);
+}
+
+
+bool File::Flush() {
+  ASSERT(handle_->fd() >= 0);
+  return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1;
+}
+
+
+bool File::Lock(File::LockType lock, int64_t start, int64_t end) {
+  ASSERT(handle_->fd() >= 0);
+  ASSERT((end == -1) || (end > start));
+  struct flock fl;
+  switch (lock) {
+    case File::kLockUnlock:
+      fl.l_type = F_UNLCK;
+      break;
+    case File::kLockShared:
+    case File::kLockBlockingShared:
+      fl.l_type = F_RDLCK;
+      break;
+    case File::kLockExclusive:
+    case File::kLockBlockingExclusive:
+      fl.l_type = F_WRLCK;
+      break;
+    default:
+      return false;
+  }
+  fl.l_whence = SEEK_SET;
+  fl.l_start = start;
+  fl.l_len = end == -1 ? 0 : end - start;
+  int cmd = F_SETLK;
+  if ((lock == File::kLockBlockingShared) ||
+      (lock == File::kLockBlockingExclusive)) {
+    cmd = F_SETLKW;
+  }
+  return NO_RETRY_EXPECTED(fcntl(handle_->fd(), cmd, &fl)) != -1;
+}
+
+
+int64_t File::Length() {
+  ASSERT(handle_->fd() >= 0);
+  struct stat st;
+  if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) {
+    return st.st_size;
+  }
+  return -1;
+}
+
+
+File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+File* File::ScopedOpen(const char* name, FileOpenMode mode) {
+  // Report errors for non-regular files.
+  struct stat st;
+  if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
+    if (!S_ISREG(st.st_mode)) {
+      errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
+      return NULL;
+    }
+  }
+  int flags = O_RDONLY;
+  if ((mode & kWrite) != 0) {
+    ASSERT((mode & kWriteOnly) == 0);
+    flags = (O_RDWR | O_CREAT);
+  }
+  if ((mode & kWriteOnly) != 0) {
+    ASSERT((mode & kWrite) == 0);
+    flags = (O_WRONLY | O_CREAT);
+  }
+  if ((mode & kTruncate) != 0) {
+    flags = flags | O_TRUNC;
+  }
+  flags |= O_CLOEXEC;
+  int fd = NO_RETRY_EXPECTED(open(name, flags, 0666));
+  if (fd < 0) {
+    return NULL;
+  }
+  if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) ||
+      (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) {
+    int64_t position = lseek(fd, 0, SEEK_END);
+    if (position < 0) {
+      return NULL;
+    }
+  }
+  return new File(new FileHandle(fd));
+}
+
+
+File* File::Open(const char* path, FileOpenMode mode) {
+  // ScopedOpen doesn't actually need a scope.
+  return ScopedOpen(path, mode);
+}
+
+
+File* File::OpenStdio(int fd) {
+  return ((fd < 0) || (2 < fd)) ? NULL : new File(new FileHandle(fd));
+}
+
+
+bool File::Exists(const char* name) {
+  struct stat st;
+  if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
+    return S_ISREG(st.st_mode);
+  } else {
+    return false;
+  }
+}
+
+
+bool File::Create(const char* name) {
+  int fd = NO_RETRY_EXPECTED(open(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666));
+  if (fd < 0) {
+    return false;
+  }
+  return (close(fd) == 0);
+}
+
+
+bool File::CreateLink(const char* name, const char* target) {
+  return NO_RETRY_EXPECTED(symlink(target, name)) == 0;
+}
+
+
+bool File::Delete(const char* name) {
+  File::Type type = File::GetType(name, true);
+  if (type == kIsFile) {
+    return NO_RETRY_EXPECTED(unlink(name)) == 0;
+  } else if (type == kIsDirectory) {
+    errno = EISDIR;
+  } else {
+    errno = ENOENT;
+  }
+  return false;
+}
+
+
+bool File::DeleteLink(const char* name) {
+  File::Type type = File::GetType(name, false);
+  if (type == kIsLink) {
+    return NO_RETRY_EXPECTED(unlink(name)) == 0;
+  }
+  errno = EINVAL;
+  return false;
+}
+
+
+bool File::Rename(const char* old_path, const char* new_path) {
+  File::Type type = File::GetType(old_path, true);
+  if (type == kIsFile) {
+    return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
+  } else if (type == kIsDirectory) {
+    errno = EISDIR;
+  } else {
+    errno = ENOENT;
+  }
+  return false;
+}
+
+
+bool File::RenameLink(const char* old_path, const char* new_path) {
+  File::Type type = File::GetType(old_path, false);
+  if (type == kIsLink) {
+    return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
+  } else if (type == kIsDirectory) {
+    errno = EISDIR;
+  } else {
+    errno = EINVAL;
+  }
+  return false;
+}
+
+
+bool File::Copy(const char* old_path, const char* new_path) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+int64_t File::LengthFromPath(const char* name) {
+  struct stat st;
+  if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
+    return st.st_size;
+  }
+  return -1;
+}
+
+
+void File::Stat(const char* name, int64_t* data) {
+  struct stat st;
+  if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
+    if (S_ISREG(st.st_mode)) {
+      data[kType] = kIsFile;
+    } else if (S_ISDIR(st.st_mode)) {
+      data[kType] = kIsDirectory;
+    } else if (S_ISLNK(st.st_mode)) {
+      data[kType] = kIsLink;
+    } else {
+      data[kType] = kDoesNotExist;
+    }
+    data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000;
+    data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000;
+    data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000;
+    data[kMode] = st.st_mode;
+    data[kSize] = st.st_size;
+  } else {
+    data[kType] = kDoesNotExist;
+  }
+}
+
+
+time_t File::LastModified(const char* name) {
+  struct stat st;
+  if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
+    return st.st_mtime;
+  }
+  return -1;
+}
+
+
+const char* File::LinkTarget(const char* pathname) {
+  struct stat link_stats;
+  if (lstat(pathname, &link_stats) != 0) {
+    return NULL;
+  }
+  if (!S_ISLNK(link_stats.st_mode)) {
+    errno = ENOENT;
+    return NULL;
+  }
+  size_t target_size = link_stats.st_size;
+  char* target_name = DartUtils::ScopedCString(target_size + 1);
+  ASSERT(target_name != NULL);
+  size_t read_size = readlink(pathname, target_name, target_size + 1);
+  if (read_size != target_size) {
+    return NULL;
+  }
+  target_name[target_size] = '\0';
+  return target_name;
+}
+
+
+bool File::IsAbsolutePath(const char* pathname) {
+  return ((pathname != NULL) && (pathname[0] == '/'));
+}
+
+
+const char* File::GetCanonicalPath(const char* pathname) {
+  char* abs_path = NULL;
+  if (pathname != NULL) {
+    char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
+    ASSERT(resolved_path != NULL);
+    do {
+      abs_path = realpath(pathname, resolved_path);
+    } while ((abs_path == NULL) && (errno == EINTR));
+    ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path));
+    ASSERT((abs_path == NULL) || (abs_path == resolved_path));
+  }
+  return abs_path;
+}
+
+
+const char* File::PathSeparator() {
+  return "/";
+}
+
+
+const char* File::StringEscapedPathSeparator() {
+  return "/";
+}
+
+
+File::StdioHandleType File::GetStdioHandleType(int fd) {
+  ASSERT((0 <= fd) && (fd <= 2));
+  struct stat buf;
+  int result = fstat(fd, &buf);
+  if (result == -1) {
+    const int kBufferSize = 1024;
+    char 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;
+  }
+  if (S_ISFIFO(buf.st_mode)) {
+    return kPipe;
+  }
+  if (S_ISSOCK(buf.st_mode)) {
+    return kSocket;
+  }
+  if (S_ISREG(buf.st_mode)) {
+    return kFile;
+  }
+  return kOther;
+}
+
+
+File::Type File::GetType(const char* pathname, bool follow_links) {
+  struct stat entry_info;
+  int stat_success;
+  if (follow_links) {
+    stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info));
+  } else {
+    stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
+  }
+  if (stat_success == -1) {
+    return File::kDoesNotExist;
+  }
+  if (S_ISDIR(entry_info.st_mode)) {
+    return File::kIsDirectory;
+  }
+  if (S_ISREG(entry_info.st_mode)) {
+    return File::kIsFile;
+  }
+  if (S_ISLNK(entry_info.st_mode)) {
+    return File::kIsLink;
+  }
+  return File::kDoesNotExist;
+}
+
+
+File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
+  struct stat file_1_info;
+  struct stat file_2_info;
+  if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) ||
+      (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) {
+    return File::kError;
+  }
+  return ((file_1_info.st_ino == file_2_info.st_ino) &&
+          (file_1_info.st_dev == file_2_info.st_dev)) ?
+      File::kIdentical :
+      File::kDifferent;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index eab92d5..4f61db1 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -39,7 +39,8 @@
 
 
 File::~File() {
-  if (!IsClosed()) {
+  if (!IsClosed() &&
+      handle_->fd() != STDOUT_FILENO && handle_->fd() != STDERR_FILENO) {
     Close();
   }
   delete handle_;
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index a43b14e..38699cd 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -41,7 +41,8 @@
 
 
 File::~File() {
-  if (!IsClosed()) {
+  if (!IsClosed() &&
+      handle_->fd() != STDOUT_FILENO && handle_->fd() != STDERR_FILENO) {
     Close();
   }
   delete handle_;
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index a3d42e8..2fe1414 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -2,28 +2,28 @@
 // for 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 _File {
-  /* patch */ static _exists(String path) native "File_Exists";
-  /* patch */ static _create(String path) native "File_Create";
-  /* patch */ static _createLink(String path, String target)
+@patch class _File {
+  @patch static _exists(String path) native "File_Exists";
+  @patch static _create(String path) native "File_Create";
+  @patch static _createLink(String path, String target)
       native "File_CreateLink";
-  /* patch */ static _linkTarget(String path) native "File_LinkTarget";
-  /* patch */ static _deleteNative(String path) native "File_Delete";
-  /* patch */ static _deleteLinkNative(String path) native "File_DeleteLink";
-  /* patch */ static _rename(String oldPath, String newPath)
+  @patch static _linkTarget(String path) native "File_LinkTarget";
+  @patch static _deleteNative(String path) native "File_Delete";
+  @patch static _deleteLinkNative(String path) native "File_DeleteLink";
+  @patch static _rename(String oldPath, String newPath)
       native "File_Rename";
-  /* patch */ static _renameLink(String oldPath, String newPath)
+  @patch static _renameLink(String oldPath, String newPath)
       native "File_RenameLink";
-  /* patch */ static _copy(String oldPath, String newPath) native "File_Copy";
-  /* patch */ static _lengthFromPath(String path) native "File_LengthFromPath";
-  /* patch */ static _lastModified(String path) native "File_LastModified";
-  /* patch */ static _open(String path, int mode) native "File_Open";
-  /* patch */ static int _openStdio(int fd) native "File_OpenStdio";
+  @patch static _copy(String oldPath, String newPath) native "File_Copy";
+  @patch static _lengthFromPath(String path) native "File_LengthFromPath";
+  @patch static _lastModified(String path) native "File_LastModified";
+  @patch static _open(String path, int mode) native "File_Open";
+  @patch static int _openStdio(int fd) native "File_OpenStdio";
 }
 
 
-patch class _RandomAccessFileOps {
-  /* patch */ factory _RandomAccessFileOps(int pointer)
+@patch class _RandomAccessFileOps {
+  @patch factory _RandomAccessFileOps(int pointer)
       => new _RandomAccessFileOpsImpl(pointer);
 }
 
@@ -62,7 +62,7 @@
 }
 
 
-patch class _FileSystemWatcher {
+@patch class _FileSystemWatcher {
   static int _id;
   static final Map<int, _WatcherPath> _idMap = {};
 
@@ -74,7 +74,7 @@
 
   StreamController _broadcastController;
 
-  /* patch */ static Stream<FileSystemEvent> _watch(
+  @patch static Stream<FileSystemEvent> _watch(
       String path, int events, bool recursive) {
     if (Platform.isLinux) {
       return new _InotifyFileSystemWatcher(path, events, recursive).stream;
@@ -262,7 +262,7 @@
     });
   }
 
-  /* patch */ static bool get isSupported
+  @patch static bool get isSupported
       native "FileSystemWatcher_IsSupported";
 
   static int _initWatcher() native "FileSystemWatcher_InitWatcher";
diff --git a/runtime/bin/file_system_entity_patch.dart b/runtime/bin/file_system_entity_patch.dart
index 24782aa..c3faefe 100644
--- a/runtime/bin/file_system_entity_patch.dart
+++ b/runtime/bin/file_system_entity_patch.dart
@@ -2,16 +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.
 
-patch class FileStat {
-  /* patch */ static _statSync(String path) native "File_Stat";
+@patch class FileStat {
+  @patch static _statSync(String path) native "File_Stat";
 }
 
 
-patch class FileSystemEntity {
-  /* patch */ static _getType(String path, bool followLinks)
+@patch class FileSystemEntity {
+  @patch static _getType(String path, bool followLinks)
       native "File_GetType";
-  /* patch */ static _identical(String path1, String path2)
+  @patch static _identical(String path1, String path2)
       native "File_AreIdentical";
-  /* patch */ static _resolveSymbolicLinks(String path)
+  @patch static _resolveSymbolicLinks(String path)
       native "File_ResolveSymbolicLinks";
 }
diff --git a/runtime/bin/file_system_watcher_fuchsia.cc b/runtime/bin/file_system_watcher_fuchsia.cc
new file mode 100644
index 0000000..abfbaa8
--- /dev/null
+++ b/runtime/bin/file_system_watcher_fuchsia.cc
@@ -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.
+
+#if !defined(DART_IO_DISABLED)
+
+#include "platform/globals.h"
+#if defined(TARGET_OS_FUCHSIA)
+
+#include "bin/file_system_watcher.h"
+
+namespace dart {
+namespace bin {
+
+Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) {
+  UNIMPLEMENTED();
+  return DartUtils::NewDartOSError();
+}
+
+
+intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+bool FileSystemWatcher::IsSupported() {
+  return false;
+}
+
+
+void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) {
+  UNIMPLEMENTED();
+}
+
+
+intptr_t FileSystemWatcher::Init() {
+  return 0;
+}
+
+
+void FileSystemWatcher::Close(intptr_t id) {
+  UNIMPLEMENTED();
+}
+
+
+intptr_t FileSystemWatcher::WatchPath(intptr_t id,
+                                      const char* path,
+                                      int events,
+                                      bool recursive) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
+
+#endif  // !defined(DART_IO_DISABLED)
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 8d45a17..f487a88 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -38,7 +38,8 @@
 
 
 File::~File() {
-  if (!IsClosed()) {
+  if (!IsClosed() &&
+      handle_->fd() != _fileno(stdout) && handle_->fd() != _fileno(stderr)) {
     Close();
   }
   delete handle_;
diff --git a/runtime/bin/filter_patch.dart b/runtime/bin/filter_patch.dart
index a5626bb..db086f9 100644
--- a/runtime/bin/filter_patch.dart
+++ b/runtime/bin/filter_patch.dart
@@ -28,16 +28,16 @@
       native "Filter_CreateZLibDeflate";
 }
 
-patch class _Filter {
-  /* patch */ static _Filter _newZLibDeflateFilter(bool gzip, int level,
-                                                   int windowBits, int memLevel,
-                                                   int strategy,
-                                                   List<int> dictionary,
-                                                   bool raw) =>
+@patch class _Filter {
+  @patch static _Filter _newZLibDeflateFilter(bool gzip, int level,
+                                                    int windowBits, int memLevel,
+                                                    int strategy,
+                                                    List<int> dictionary,
+                                                    bool raw) =>
       new _ZLibDeflateFilter(gzip, level, windowBits, memLevel, strategy,
                              dictionary, raw);
-  /* patch */ static _Filter _newZLibInflateFilter(int windowBits,
-                                                   List<int> dictionary,
-                                                   bool raw) =>
+  @patch static _Filter _newZLibInflateFilter(int windowBits,
+                                                    List<int> dictionary,
+                                                    bool raw) =>
       new _ZLibInflateFilter(windowBits, dictionary, raw);
 }
diff --git a/runtime/bin/fuchsia_test.cc b/runtime/bin/fuchsia_test.cc
index 802ff31..fef899a 100644
--- a/runtime/bin/fuchsia_test.cc
+++ b/runtime/bin/fuchsia_test.cc
@@ -2,38 +2,215 @@
 // for 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 <dart_api.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
-#include <dart_api.h>
+#include "bin/log.h"
+#include "platform/assert.h"
+
+const char* kBuiltinScript =
+    "_printString(String line) native \"Builtin_PrintString\";\n"
+    "_getPrintClosure() => _printString;\n";
+
+const char* kHelloWorldScript = "main() { print(\"Hello, Fuchsia!\"); }";
+
+namespace dart {
+namespace bin {
+
+// 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* vm_isolate_snapshot_buffer;
+
+// isolate_snapshot_buffer points to a snapshot for an isolate if we link in a
+// snapshot otherwise it is initialized to NULL.
+extern const uint8_t* isolate_snapshot_buffer;
+
+static void Builtin_PrintString(Dart_NativeArguments args) {
+  intptr_t length = 0;
+  uint8_t* chars = NULL;
+  Dart_Handle str = Dart_GetNativeArgument(args, 0);
+  Dart_Handle result = Dart_StringToUTF8(str, &chars, &length);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  // Uses fwrite to support printing NUL bytes.
+  intptr_t res = fwrite(chars, 1, length, stdout);
+  ASSERT(res == length);
+  fputs("\n", stdout);
+  fflush(stdout);
+}
+
+static Dart_NativeFunction NativeLookup(Dart_Handle name,
+                                        int argument_count,
+                                        bool* auto_setup_scope) {
+  const char* function_name = NULL;
+  Dart_Handle err = Dart_StringToCString(name, &function_name);
+  DART_CHECK_VALID(err);
+  *auto_setup_scope = true;
+  if (strcmp(function_name, "Builtin_PrintString") == 0) {
+    return reinterpret_cast<Dart_NativeFunction>(Builtin_PrintString);
+  }
+  return NULL;
+}
+
+static const uint8_t* NativeSymbol(Dart_NativeFunction nf) {
+  if (reinterpret_cast<Dart_NativeFunction>(Builtin_PrintString) == nf) {
+    return reinterpret_cast<const uint8_t*>("Builtin_PrintString");
+  }
+  return NULL;
+}
+
+static Dart_Handle PrepareBuiltinLibrary(const char* script) {
+  Log::Print("Creating builtin library uri\n");
+  Dart_Handle builtin_uri = Dart_NewStringFromCString("builtin_uri");
+  DART_CHECK_VALID(builtin_uri);
+
+  Log::Print("Creating builtin library script string\n");
+  Dart_Handle builtin_script = Dart_NewStringFromCString(script);
+  DART_CHECK_VALID(builtin_script);
+
+  Log::Print("Loading builtin library\n");
+  Dart_Handle status =
+      Dart_LoadLibrary(builtin_uri, Dart_Null(), builtin_script, 0, 0);
+  DART_CHECK_VALID(status);
+
+  Log::Print("Looking up builtin library\n");
+  Dart_Handle builtin_library = Dart_LookupLibrary(builtin_uri);
+  DART_CHECK_VALID(builtin_library);
+
+  Log::Print("Setting up native resolver for builtin library\n");
+  status = Dart_SetNativeResolver(builtin_library, NativeLookup, NativeSymbol);
+  DART_CHECK_VALID(status);
+
+  return builtin_library;
+}
+
+static Dart_Handle PrepareScriptLibrary(const char* script) {
+  Log::Print("Creating script URI string\n");
+  Dart_Handle script_uri = Dart_NewStringFromCString("script_uri");
+  DART_CHECK_VALID(script_uri);
+
+  Log::Print("Creating script string\n");
+  Dart_Handle script_string = Dart_NewStringFromCString(script);
+  DART_CHECK_VALID(script_string);
+
+  Log::Print("Loading script into new library\n");
+  Dart_Handle status =
+      Dart_LoadLibrary(script_uri, Dart_Null(), script_string, 0, 0);
+  DART_CHECK_VALID(status);
+
+  Log::Print("Looking up script library\n");
+  Dart_Handle library = Dart_LookupLibrary(script_uri);
+  DART_CHECK_VALID(library);
+
+  return library;
+}
+
+static Dart_Handle LoadInternalLibrary() {
+  Log::Print("Creating internal library uri string\n");
+  Dart_Handle url = Dart_NewStringFromCString("dart:_internal");
+  DART_CHECK_VALID(url);
+
+  Log::Print("Looking up internal library\n");
+  Dart_Handle internal_library = Dart_LookupLibrary(url);
+  DART_CHECK_VALID(internal_library);
+
+  return internal_library;
+}
+
+static void PreparePrintClosure(Dart_Handle builtin_library,
+                                Dart_Handle internal_library) {
+  Log::Print("Creating _getPrintClosure name string\n");
+  Dart_Handle get_print_closure_name =
+      Dart_NewStringFromCString("_getPrintClosure");
+  DART_CHECK_VALID(get_print_closure_name);
+
+  Log::Print("Invoking _getPrintClosure\n");
+  Dart_Handle print_closure = Dart_Invoke(
+      builtin_library, get_print_closure_name, 0, NULL);
+  DART_CHECK_VALID(print_closure);
+
+  Log::Print("Creating _printClosure name string\n");
+  Dart_Handle print_closure_name = Dart_NewStringFromCString("_printClosure");
+  DART_CHECK_VALID(print_closure_name);
+
+  Log::Print("Setting _printClosure to result of _getPrintClosure\n");
+  Dart_Handle status = Dart_SetField(
+      internal_library, print_closure_name, print_closure);
+  DART_CHECK_VALID(status);
+}
+
+int Main() {
+  Log::Print("Calling Dart_SetVMFlags\n");
+  if (!Dart_SetVMFlags(0, NULL)) {
+    FATAL("Failed to set flags\n");
+  }
+  Log::Print("Calling Dart_Initialize\n");
+  Dart_InitializeParams init_params;
+  memset(&init_params, 0, sizeof(init_params));
+  init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
+  init_params.vm_isolate_snapshot = vm_isolate_snapshot_buffer;
+  char* error = Dart_Initialize(&init_params);
+  if (error != NULL) {
+    FATAL1("VM initialization failed: %s\n", error);
+  }
+
+  Log::Print("Creating Isolate\n");
+  Dart_Isolate isolate = Dart_CreateIsolate(
+      "script_uri",
+      "main",
+      isolate_snapshot_buffer,
+      NULL,
+      NULL,
+      &error);
+  if (isolate == NULL) {
+    FATAL1("Dart_CreateIsolate failed: %s\n", error);
+  }
+
+  Log::Print("Entering Scope\n");
+  Dart_EnterScope();
+
+  Dart_Handle library = PrepareScriptLibrary(kHelloWorldScript);
+
+  Dart_Handle builtin_library = PrepareBuiltinLibrary(kBuiltinScript);
+
+  Log::Print("Finalizing loading\n");
+  Dart_Handle status = Dart_FinalizeLoading(false);
+  DART_CHECK_VALID(status);
+
+  Dart_Handle internal_library = LoadInternalLibrary();
+
+  PreparePrintClosure(builtin_library, internal_library);
+
+  Log::Print("Creating main string\n");
+  Dart_Handle main_name = Dart_NewStringFromCString("main");
+  DART_CHECK_VALID(main_name);
+
+  Log::Print("---- Invoking main() ----\n");
+  status = Dart_Invoke(library, main_name, 0, NULL);
+  DART_CHECK_VALID(status);
+  Log::Print("---- main() returned ----\n");
+
+  Log::Print("Exiting Scope\n");
+  Dart_ExitScope();
+  Log::Print("Shutting down the isolate\n");
+  Dart_ShutdownIsolate();
+
+  Log::Print("Calling Dart_Cleanup\n");
+  error = Dart_Cleanup();
+  if (error != NULL) {
+    FATAL1("VM Cleanup failed: %s\n", error);
+  }
+
+  Log::Print("Success!\n");
+  return 0;
+}
+
+}  // namespace bin
+}  // namespace dart
 
 int main(void) {
-  fprintf(stderr, "Calling Dart_SetVMFlags\n");
-  fflush(stderr);
-  if (!Dart_SetVMFlags(0, NULL)) {
-    fprintf(stderr, "Failed to set flags\n");
-    fflush(stderr);
-    return -1;
-  }
-  fprintf(stderr, "Calling Dart_Initialize\n");
-  fflush(stderr);
-  char* error = Dart_Initialize(
-      NULL, NULL, NULL,
-      NULL, NULL, NULL, NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL);
-  if (error != NULL) {
-    fprintf(stderr, "VM initialization failed: %s\n", error);
-    fflush(stderr);
-    free(error);
-    return -1;
-  }
-  fprintf(stderr, "Success!\n");
-  fflush(stderr);
-  return 0;
+  return dart::bin::Main();
 }
diff --git a/runtime/bin/fuchsia_vm_tests.txt b/runtime/bin/fuchsia_vm_tests.txt
new file mode 100644
index 0000000..0cbf30a9
--- /dev/null
+++ b/runtime/bin/fuchsia_vm_tests.txt
@@ -0,0 +1,930 @@
+GetRandomBytes
+CircularLinkedList
+Read
+FileLength
+FilePosition
+Set
+StackAllocatedDestruction
+StackAllocatedLongJump
+StackResourceDestruction
+StackResourceLongJump
+StoreIntoObject
+ReadArgument
+AddressingModes
+JumpAroundCrash
+SimpleLoop
+Cmpb
+Testb
+Increment
+IncrementLong
+Decrement
+DecrementLong
+SignedMultiply
+UnsignedMultiply
+SignedMultiply64
+SignedMultiplyLong
+OverflowSignedMultiply
+SignedMultiply1
+SignedMultiply2
+UnsignedMultiplyLong
+SignedDivide
+UnsignedDivide
+SignedDivideLong
+UnsignedDivideLong
+Negate
+BitScanReverse
+MoveExtend
+MoveExtend32
+MoveExtendMemory
+MoveExtend32Memory
+MoveWord
+MoveWordRex
+LongAddReg
+LongAddImmediate
+LongAddAddress
+LongSubReg
+LongSubImmediate
+LongSubAddress
+AddReg
+AddImmediate
+AddAddress
+SubReg
+SubImmediate
+SubAddress
+Bitwise
+Bitwise64
+LogicalOps
+LogicalOps64
+LogicalTestL
+LogicalTestQ
+CompareSwapEQ
+CompareSwapNEQ
+Exchange
+LargeConstant
+CallSimpleLeaf
+JumpSimpleLeaf
+JumpIndirect
+SingleFPMoves
+SingleFPMoves2
+PackedDoubleAdd
+PackedDoubleSub
+PackedDoubleNegate
+PackedDoubleAbsolute
+PackedDoubleMul
+PackedDoubleDiv
+PackedDoubleSqrt
+PackedDoubleMin
+PackedDoubleMax
+PackedDoubleShuffle
+PackedDoubleToSingle
+PackedSingleToDouble
+SingleFPOperations
+PackedFPOperations
+PackedIntOperations
+PackedIntOperations2
+PackedFPOperations2
+PackedCompareEQ
+PackedCompareNEQ
+PackedCompareLT
+PackedCompareLE
+PackedCompareNLT
+PackedCompareNLE
+PackedNegate
+PackedAbsolute
+PackedSetWZero
+PackedMin
+PackedMax
+PackedLogicalOr
+PackedLogicalAnd
+PackedLogicalNot
+PackedMoveHighLow
+PackedMoveLowHigh
+PackedUnpackLow
+PackedUnpackHigh
+PackedUnpackLowPair
+PackedUnpackHighPair
+DoubleFPMoves
+DoubleFPOperations
+Int32ToDoubleConversion
+Int64ToDoubleConversion
+DoubleToInt64Conversion
+TestObjectCompare
+TestNop
+TestAlign0
+TestAlign1
+TestAlign1Offset1
+TestAlignLarge
+TestAdds
+TestNot
+TestNotInt32
+XorpdZeroing
+XorpdZeroing2
+Pxor
+SquareRootDouble
+DoubleFPUStackMoves
+Sine
+Cosine
+IntToDoubleConversion
+DoubleToDoubleTrunc
+DoubleAbs
+ExtractSignBits
+TestSetCC
+TestRepMovsBytes
+ConditionalMovesCompare
+BitTest
+ConditionalMovesEqual
+ConditionalMovesNoOverflow
+Assert
+Expect
+Fail0
+Fail1
+Fail2
+AstPrinter
+Ast
+FetchAndIncrement
+FetchAndDecrement
+IncrementBy
+DecrementBy
+LoadRelaxed
+CompareAndSwapWord
+CompareAndSwapUint32
+BigintSmi
+BigintInt64
+BigintUint64
+BigintDouble
+BigintHexStrings
+BigintDecStrings
+BigintCompare
+BigintDecimalStrings
+BitSetBasic
+BitVector
+BitFields
+BitmapBuilder
+BoolField
+ClassHierarchyAnalysis
+ClassFinalizer
+ClassFinalize_Cycles
+ClassFinalize_Resolve
+StackmapCodegen
+StackmapGC
+DescriptorList_TokenPositions
+CodeSourceMap_TokenPositions
+SimpleReturnCodegen
+SmiReturnCodegen
+SimpleStaticCallCodegen
+StaticCallReturnParameterCodegen
+StaticCallSmiParamSumCodegen
+SmiAddCodegen
+GenericAddCodegen
+SmiBinaryOpCodegen
+BoolNotCodegen
+BoolAndCodegen
+BinaryOpCodegen
+SmiUnaryOpCodegen
+DoubleUnaryOpCodegen
+StaticCallCodegen
+InstanceCallCodegen
+AllocateNewObjectCodegen
+IcDataAccess
+CompileScript
+CompileFunction
+CompileFunctionOnHelperThread
+RegenerateAllocStubs
+EvalExpression
+EvalExpressionWithLazyCompile
+EvalExpressionExhaustCIDs
+Id
+GetCpuModelTest
+CustomIsolates
+ErrorHandleBasics
+StacktraceInfo
+DeepStacktraceInfo
+StackOverflowStacktraceInfo
+OutOfMemoryStacktraceInfo
+CurrentStacktraceInfo
+ErrorHandleTypes
+UnhandleExceptionError
+Dart_PropagateError
+Dart_Error
+Null
+EmptyString
+IdentityEquals
+IdentityHash
+ObjectEquals
+InstanceValues
+InstanceGetType
+BooleanValues
+BooleanConstants
+DoubleValues
+NumberValues
+IntegerValues
+IntegerFitsIntoInt64
+IntegerFitsIntoUint64
+ArrayValues
+IsString
+NewString
+MalformedStringToUTF8
+ExternalStringCallback
+ExternalStringPretenure
+ExternalTypedDataPretenure
+ListAccess
+MapAccess
+IsFuture
+TypedDataViewListGetAsBytes
+TypedDataViewListIsTypedData
+TypedDataAccess
+ByteBufferAccess
+ByteDataAccess
+ExternalByteDataAccess
+OptimizedExternalByteDataAccess
+TypedDataDirectAccessUnverified
+TypedDataDirectAccessVerified
+TypedDataDirectAccess1Unverified
+TypedDataDirectAccess1Verified
+TypedDataViewDirectAccessUnverified
+TypedDataViewDirectAccessVerified
+ByteDataDirectAccessUnverified
+ByteDataDirectAccessVerified
+ExternalTypedDataAccess
+ExternalClampedTypedDataAccess
+ExternalUint8ClampedArrayAccess
+ExternalTypedDataCallback
+SlowFinalizer
+Float32x4List
+EnterExitScope
+PersistentHandles
+NewPersistentHandle_FromPersistentHandle
+AssignToPersistentHandle
+WeakPersistentHandle
+WeakPersistentHandleCallback
+WeakPersistentHandleNoCallback
+WeakPersistentHandlesCallbackShutdown
+WeakPersistentHandleExternalAllocationSize
+WeakPersistentHandleExternalAllocationSizeNewspaceGC
+WeakPersistentHandleExternalAllocationSizeOldspaceGC
+WeakPersistentHandleExternalAllocationSizeOddReferents
+ImplicitReferencesOldSpace
+ImplicitReferencesNewSpace
+SetGarbageCollectionCallbacks
+SingleGarbageCollectionCallback
+LocalHandles
+LocalZoneMemory
+Isolates
+CurrentIsolateData
+IsolateSetCheckedMode
+DebugName
+SetMessageCallbacks
+TypeGetNonParamtericTypes
+TypeGetParameterizedTypes
+FieldAccess
+SetField_FunnyValue
+InjectNativeFields1
+InjectNativeFields2
+InjectNativeFields3
+InjectNativeFields4
+TestNativeFieldsAccess
+InjectNativeFieldsSuperClass
+NativeFieldAccess
+ImplicitNativeFieldAccess
+NegativeNativeFieldAccess
+NegativeNativeFieldInIsolateMessage
+GetStaticField_RunsInitializer
+GetField_CheckIsolate
+SetField_CheckIsolate
+New
+New_Issue2971
+Invoke
+Invoke_PrivateStatic
+Invoke_FunnyArgs
+Invoke_Null
+InvokeNoSuchMethod
+Invoke_CrossLibrary
+InvokeClosure
+ThrowException
+GetNativeArguments
+GetNativeArgumentCount
+GetType
+InstanceOf
+LoadScript
+RootLibrary
+LoadScript_CompileError
+LookupLibrary
+LibraryName
+LibraryId
+LibraryUrl
+LibraryGetClassNames
+GetFunctionNames
+LibraryImportLibrary
+ImportLibraryWithPrefix
+LoadLibrary
+LoadLibrary_CompileError
+LoadSource
+LoadSource_LateLoad
+LoadPatch
+LoadPatchSignatureMismatch
+ParsePatchLibrary
+SetNativeResolver
+ImportLibrary2
+ImportLibrary3
+ImportLibrary4
+ImportLibrary5
+IllegalNewSendPort
+IllegalPost
+NewNativePort
+NativePortPostInteger
+NativePortReceiveNull
+NativePortReceiveInteger
+RunLoop_Success
+RunLoop_Exception
+IsolateShutdown
+IsolateShutdownRunDartCode
+NativeFunctionClosure
+NativeStaticFunctionClosure
+RangeLimits
+NewString_Null
+InvalidGetSetPeer
+OneNewSpacePeer
+CollectOneNewSpacePeer
+TwoNewSpacePeers
+CollectTwoNewSpacePeers
+CopyNewSpacePeers
+OnePromotedPeer
+OneOldSpacePeer
+CollectOneOldSpacePeer
+TwoOldSpacePeers
+CollectTwoOldSpacePeers
+MakeExternalString
+ExternalizeConstantStrings
+LazyLoadDeoptimizes
+GuardExternalizedString
+ExternalStringDeoptimize
+ExternalStringPolymorphicDeoptimize
+ExternalStringLoadElimination
+ExternalStringGuardFieldDeoptimize
+ExternalStringStaticFieldDeoptimize
+ExternalStringTrimDoubleParse
+ExternalStringDoubleParse
+ExternalStringIndexOf
+StringFromExternalTypedData
+Timeline_Dart_TimelineDuration
+Timeline_Dart_TimelineInstant
+Timeline_Dart_TimelineAsyncDisabled
+Timeline_Dart_TimelineAsync
+Timeline_Dart_TimelineGetTrace
+Timeline_Dart_TimelineGetTraceOnlyDartEvents
+Timeline_Dart_TimelineGetTraceWithDartEvents
+Timeline_Dart_TimelineGetTraceGlobalOverride
+Timeline_Dart_GlobalTimelineGetTrace
+Timeline_Dart_GlobalTimelineGetTrace_Threaded
+Timeline_Dart_EmbedderTimelineStartStopRecording
+Dart_LoadLibraryPatch_1
+Dart_LoadLibraryPatch_Error1
+Dart_LoadLibraryPatch_Error2
+Dart_LoadLibraryPatch_Error3
+DartEntry
+InvokeStatic_CompileError
+InvokeDynamic_CompileError
+Debugger_PrintBreakpointsToJSONArray
+Debugger_PauseEvent
+Debug_Breakpoint
+Debug_InspectStack_NotOptimized
+Debug_InspectStack_Optimized
+Debug_InspectStackWithClosure_NotOptimized
+Debug_InspectStackWithClosure_Optimized
+Debug_StepOut
+Debug_StepInto
+Debug_IgnoreBP
+Debug_DeoptimizeFunction
+Debug_SingleStep
+Debug_ClosureBreakpoint
+Debug_ExprClosureBreakpoint
+Debug_BreakpointStubPatching
+Debug_DeleteBreakpoint
+Debug_InspectStaticField
+Debug_InspectObject
+Debug_IsolateID
+Debug_InterruptIsolate
+Debug_StackTraceDump1
+Debug_StackTraceDump2
+Debug_EvaluateExpr
+Debug_EvaluateInActivationOfEvaluate
+Debug_BreakOnUnhandledException
+Debug_GetClosureInfo
+Debug_GetSupertype
+Debug_ListSuperType
+Debug_ScriptGetTokenInfo_Basic
+Debug_ScriptGetTokenInfo_MultiLineInterpolation
+Disassembler
+UnhandledExceptions
+FindCodeObject
+BasicFlags
+ParseFlags
+SourcePosition_InstanceCalls
+SourcePosition_If
+SourcePosition_ForLoop
+SourcePosition_While
+SourcePosition_WhileContinueBreak
+SourcePosition_LoadIndexed
+SourcePosition_StoreIndexed
+SourcePosition_BitwiseOperations
+SourcePosition_IfElse
+SourcePosition_Switch
+SourcePosition_TryCatchFinally
+SourcePosition_InstanceFields
+SourcePosition_Async
+SourcePosition_SyntheticTokens
+RangeTests
+RangeTestsInfinity
+RangeUtils
+RangeBinaryOp
+RangeAdd
+RangeSub
+RangeAnd
+RangeIntersectionMinMax
+RangeJoinMinMax
+FreeList
+FreeListProtected
+FreeListProtectedTinyObjects
+FreeListProtectedVariableSizeObjects
+GrowableArray
+MallocGrowableArray
+GrowableArraySort
+GrowableHandlePtr
+GuardFieldSimpleTest
+GuardFieldFinalListTest
+GuardFieldFinalVariableLengthListTest
+GuardFieldConstructorTest
+GuardFieldConstructor2Test
+AllocateZoneHandle
+AllocateScopeHandle
+DirectChainedHashMap
+MallocDirectChainedHashMap
+DirectChainedHashMapIterator
+HashTable
+Sets
+Maps
+OldGC
+OldGC_Unsync
+LargeSweep
+ClassHeapStats
+ArrayHeapStats
+FindObject
+IterateReadOnly
+BecomeFowardOldToOld
+BecomeFowardNewToNew
+BecomeFowardOldToNew
+BecomeFowardNewToOld
+BecomeForwardRememberedObject
+InstructionTests
+OptimizationTests
+IsolateReload_FunctionReplacement
+IsolateReload_BadClass
+IsolateReload_StaticValuePreserved
+IsolateReload_SavedClosure
+IsolateReload_TopLevelFieldAdded
+IsolateReload_ClassFieldAdded
+IsolateReload_ClassFieldAdded2
+IsolateReload_ClassFieldRemoved
+IsolateReload_ClassAdded
+IsolateReload_LibraryImportAdded
+IsolateReload_LibraryImportRemoved
+IsolateReload_LibraryDebuggable
+IsolateReload_ImplicitConstructorChanged
+IsolateReload_ConstructorChanged
+IsolateReload_SuperClassChanged
+IsolateReload_Generics
+IsolateReload_TypeIdentity
+IsolateReload_TypeIdentityGeneric
+IsolateReload_TypeIdentityParameter
+IsolateReload_MixinChanged
+IsolateReload_ComplexInheritanceChange
+IsolateReload_LiveStack
+IsolateReload_LibraryLookup
+IsolateReload_LibraryHide
+IsolateReload_LibraryShow
+IsolateReload_SmiFastPathStubs
+IsolateReload_ImportedMixinFunction
+IsolateReload_TopLevelParseError
+IsolateReload_PendingUnqualifiedCall_StaticToInstance
+IsolateReload_PendingUnqualifiedCall_InstanceToStatic
+IsolateReload_PendingConstructorCall_AbstractToConcrete
+IsolateReload_PendingConstructorCall_ConcreteToAbstract
+IsolateReload_PendingStaticCall_DefinedToNSM
+IsolateReload_PendingStaticCall_NSMToDefined
+IsolateReload_PendingSuperCall
+IsolateReload_TearOff_Equality
+IsolateReload_TearOff_List_Set
+IsolateReload_EnumEquality
+IsolateReload_EnumIdentical
+IsolateReload_EnumReorderIdentical
+IsolateReload_EnumAddition
+IsolateReload_EnumToNotEnum
+IsolateReload_NotEnumToEnum
+IsolateReload_EnumDelete
+IsolateReload_EnumIdentityReload
+IsolateReload_ConstantIdentical
+IsolateReload_EnumValuesToString
+IsolateReload_DirectSubclasses_Success
+IsolateReload_DirectSubclasses_GhostSubclass
+IsolateReload_DirectSubclasses_Failure
+IsolateReload_ChangeInstanceFormat0
+IsolateReload_ChangeInstanceFormat1
+IsolateReload_ChangeInstanceFormat2
+IsolateReload_ChangeInstanceFormat3
+IsolateReload_ChangeInstanceFormat4
+IsolateReload_ChangeInstanceFormat5
+IsolateReload_ChangeInstanceFormat6
+IsolateReload_ChangeInstanceFormat7
+IsolateReload_NoLibsModified
+IsolateReload_MainLibModified
+IsolateReload_ImportedLibModified
+IsolateReload_PrefixImportedLibModified
+IsolateCurrent
+IsolateSpawn
+StackLimitInterrupts
+NoOOBMessageScope
+JSON_TextBuffer
+JSON_JSONStream_Primitives
+JSON_JSONStream_Array
+JSON_JSONStream_Object
+JSON_JSONStream_NestedObject
+JSON_JSONStream_ObjectArray
+JSON_JSONStream_ArrayArray
+JSON_JSONStream_Printf
+JSON_JSONStream_ObjectPrintf
+JSON_JSONStream_DartObject
+JSON_JSONStream_EscapedString
+JSON_JSONStream_DartString
+JSON_JSONStream_Params
+JSON_JSONStream_AppendJSONStreamConsumer
+Log_Macro
+Log_Basic
+Log_Block
+LongJump
+NullRegion
+NewRegion
+Subregion
+ExtendedRegion
+MessageHandler_PostMessage
+MessageHandler_HasOOBMessages
+MessageHandler_ClosePort
+MessageHandler_CloseAllPorts
+MessageHandler_HandleNextMessage
+MessageHandler_HandleNextMessage_ProcessOOBAfterError
+MessageHandler_HandleNextMessage_Shutdown
+MessageHandler_HandleOOBMessages
+MessageHandler_Run
+MessageQueue_BasicOperations
+MessageQueue_Clear
+Metric_Simple
+Metric_OnDemand
+ObjectGraph
+ObjectIdRingSerialWrapTest
+ObjectIdRingScavengeMoveTest
+ObjectIdRingOldGCTest
+ObjectIdRingExpiredEntryTest
+Class
+TypeArguments
+TokenStream
+GenerateExactSource
+Class_ComputeEndTokenPos
+InstanceClass
+Smi
+StringCompareTo
+StringEncodeIRI
+StringDecodeIRI
+StringDecodeIRIInvalid
+StringIRITwoByte
+Mint
+Double
+Bigint
+Integer
+String
+StringFormat
+StringConcat
+StringHashConcat
+StringSubStringDifferentWidth
+StringFromUtf8Literal
+StringEqualsUtf8
+StringEqualsUTF32
+ExternalOneByteString
+EscapeSpecialCharactersOneByteString
+EscapeSpecialCharactersExternalOneByteString
+EscapeSpecialCharactersTwoByteString
+EscapeSpecialCharactersExternalTwoByteString
+ExternalTwoByteString
+Symbol
+SymbolUnicode
+Bool
+Array
+ArrayLengthNegativeOne
+ArrayLengthSmiMin
+ArrayLengthOneTooMany
+ArrayLengthMaxElements
+Int8ListLengthNegativeOne
+Int8ListLengthSmiMin
+Int8ListLengthOneTooMany
+Int8ListLengthMaxElements
+StringCodePointIterator
+StringCodePointIteratorRange
+GrowableObjectArray
+InternalTypedData
+ExternalTypedData
+Script
+EmbeddedScript
+Context
+ContextScope
+Closure
+ObjectPrinting
+CheckedHandle
+Code
+CodeImmutability
+EmbedStringInCode
+EmbedSmiInCode
+EmbedSmiIn64BitCode
+ExceptionHandlers
+PcDescriptors
+PcDescriptorsLargeDeltas
+ClassDictionaryIterator
+ICData
+SubtypeTestCache
+FieldTests
+EqualsIgnoringPrivate
+ArrayNew_Overflow_Crash
+StackTraceFormat
+WeakProperty_PreserveCrossGen
+WeakProperty_PreserveRecurse
+WeakProperty_PreserveOne_NewSpace
+WeakProperty_PreserveTwo_NewSpace
+WeakProperty_PreserveTwoShared_NewSpace
+WeakProperty_PreserveOne_OldSpace
+WeakProperty_PreserveTwo_OldSpace
+WeakProperty_PreserveTwoShared_OldSpace
+WeakProperty_ClearOne_NewSpace
+WeakProperty_ClearTwoShared_NewSpace
+WeakProperty_ClearOne_OldSpace
+WeakProperty_ClearTwoShared_OldSpace
+MirrorReference
+FindClosureIndex
+FindInvocationDispatcherFunctionIndex
+Metadata
+FunctionSourceFingerprint
+FunctionWithBreakpointNotInlined
+SpecialClassesHaveEmptyArrays
+PrintJSON
+PrintJSONPrimitives
+InstanceEquality
+HashCode
+LinkedHashMap
+LinkedHashMap_iteration
+Symbols_FromConcatAll
+String_ScrubName
+Sleep
+SNPrint
+SNPrint_BadArgs
+OsFuncs
+OSAlignedAllocate
+Pages
+ParseClassDefinition
+Parser_TopLevel
+Parser_AllocateVariables_CapturedVar
+Parser_AllocateVariables_NestedCapturedVar
+Parser_AllocateVariables_TwoChains
+Parser_AllocateVariables_Issue7681
+Parser_AllocateVariables_CaptureLoopVar
+Parser_AllocateVariables_MiddleChain
+PortMap_CreateAndCloseOnePort
+PortMap_CreateAndCloseTwoPorts
+PortMap_ClosePorts
+PortMap_CreateManyPorts
+PortMap_SetPortState
+PortMap_PostMessage
+PortMap_PostIntegerMessage
+PortMap_PostNullMessage
+PortMap_PostMessageClosedPort
+Profiler_SampleBufferWrapTest
+Profiler_SampleBufferIterateTest
+Profiler_AllocationSampleTest
+Profiler_TrivialRecordAllocation
+Profiler_ToggleRecordAllocation
+Profiler_CodeTicks
+Profiler_FunctionTicks
+Profiler_IntrinsicAllocation
+Profiler_ArrayAllocation
+Profiler_ContextAllocation
+Profiler_ClosureAllocation
+Profiler_TypedArrayAllocation
+Profiler_StringAllocation
+Profiler_StringInterpolation
+Profiler_FunctionInline
+Profiler_InliningIntervalBoundry
+Profiler_ChainedSamples
+Profiler_BasicSourcePosition
+Profiler_BasicSourcePositionOptimized
+Profiler_SourcePosition
+Profiler_SourcePositionOptimized
+Profiler_BinaryOperatorSourcePosition
+Profiler_BinaryOperatorSourcePositionOptimized
+Profiler_GetSourceReport
+RegExp_OneByteString
+RegExp_TwoByteString
+RegExp_ExternalOneByteString
+RegExp_ExternalTwoByteString
+DartStaticResolve
+DartDynamicResolve
+RingBuffer
+Scanner_Test
+ZeroSizeScavenger
+LocalScope
+Service_IdZones
+Service_Code
+Service_TokenStream
+Service_PcDescriptors
+Service_LocalVarDescriptors
+Service_PersistentHandles
+Service_Address
+Service_EmbedderRootHandler
+Service_EmbedderIsolateHandler
+Service_Profile
+SerializeNull
+SerializeSmi1
+SerializeSmi2
+SerializeMints
+SerializeDouble
+SerializeTrue
+SerializeFalse
+SerializeCapability
+SerializeBigint
+SerializeBigint2
+SerializeSingletons
+SerializeString
+SerializeArray
+FailSerializeLargeArray
+FailSerializeLargeNestedArray
+FailSerializeLargeTypedDataInt8
+FailSerializeLargeTypedDataUint8
+FailSerializeLargeExternalTypedData
+SerializeEmptyArray
+SerializeByteArray
+SerializeTypedArray
+SerializeExternalTypedArray
+SerializeEmptyByteArray
+SerializeScript
+CanonicalizationInScriptSnapshots
+GenerateSource
+FullSnapshot
+FullSnapshot1
+ScriptSnapshot
+ScriptSnapshot1
+ScriptSnapshot2
+IntArrayMessage
+DartGeneratedMessages
+DartGeneratedListMessages
+DartGeneratedArrayLiteralMessages
+DartGeneratedListMessagesWithBackref
+DartGeneratedArrayLiteralMessagesWithBackref
+DartGeneratedListMessagesWithTypedData
+PostCObject
+OmittedObjectEncodingLength
+SourceReport_Coverage_NoCalls
+SourceReport_Coverage_SimpleCall
+SourceReport_Coverage_ForceCompile
+SourceReport_Coverage_UnusedClass_NoForceCompile
+SourceReport_Coverage_UnusedClass_ForceCompile
+SourceReport_Coverage_UnusedClass_ForceCompileError
+SourceReport_Coverage_NestedFunctions
+SourceReport_Coverage_RestrictedRange
+SourceReport_Coverage_AllFunctions
+SourceReport_Coverage_AllFunctions_ForceCompile
+SourceReport_CallSites_SimpleCall
+SourceReport_CallSites_PolymorphicCall
+SourceReport_MultipleReports
+SourceReport_PossibleBreakpoints_Simple
+EmptyStackFrameIteration
+EmptyDartStackFrameIteration
+ValidateStackFrameIteration
+ValidateNoSuchMethodStackFrameIteration
+CallRuntimeStubCode
+CallLeafRuntimeStubCode
+ThreadBarrier
+ThreadPool_Create
+ThreadPool_RunOne
+ThreadPool_RunMany
+ThreadPool_WorkerShutdown
+ThreadPool_WorkerTimeout
+ThreadPool_RecursiveSpawn
+Mutex
+Monitor
+ManyTasksWithZones
+ThreadRegistry
+SafepointTestDart
+SafepointTestVM
+RecursiveSafepointTest1
+ThreadIterator_Count
+ThreadIterator_FindSelf
+ThreadIterator_AddFindRemove
+SafepointTestVM2
+RecursiveSafepointTest2
+HelperAllocAndGC
+TimelineEventIsValid
+TimelineEventDuration
+TimelineEventDurationPrintJSON
+TimelineEventArguments
+TimelineEventArgumentsPrintJSON
+TimelineEventBufferPrintJSON
+TimelineEventCallbackRecorderBasic
+TimelineAnalysis_ThreadBlockCount
+TimelineRingRecorderJSONOrder
+TimelinePauses_Basic
+TimelinePauses_BeginEnd
+Utf8Decode
+ParseUri_WithScheme_NoQueryNoUser
+ParseUri_WithScheme_WithQuery
+ParseUri_WithScheme_WithFragment
+ParseUri_WithScheme_WithQueryWithFragment
+ParseUri_WithScheme_WithUser
+ParseUri_WithScheme_ShortPath
+ParseUri_WithScheme_EmptyPath
+ParseUri_WithScheme_Rootless1
+ParseUri_WithScheme_Rootless2
+ParseUri_NoScheme_AbsPath_WithAuthority
+ParseUri_NoScheme_AbsPath_NoAuthority
+ParseUri_NoScheme_AbsPath_StrayColon
+ParseUri_NoScheme_Rootless1
+ParseUri_NoScheme_Rootless2
+ParseUri_NoScheme_Empty
+ParseUri_NoScheme_QueryOnly
+ParseUri_NoScheme_FragmentOnly
+ParseUri_LowerCaseScheme
+ParseUri_NormalizeEscapes_PathQueryFragment
+ParseUri_NormalizeEscapes_UppercaseEscapesPreferred
+ParseUri_NormalizeEscapes_Authority
+ParseUri_NormalizeEscapes_UppercaseEscapeInHost
+ParseUri_BrokenEscapeSequence
+ResolveUri_WithScheme_NoAuthorityNoQuery
+ResolveUri_WithScheme_WithAuthorityWithQuery
+ResolveUri_NoScheme_WithAuthority
+ResolveUri_NoSchemeNoAuthority_AbsolutePath
+ResolveUri_NoSchemeNoAuthority_RelativePath
+ResolveUri_NoSchemeNoAuthority_RelativePathEmptyBasePath
+ResolveUri_NoSchemeNoAuthority_RelativePathWeirdBasePath
+ResolveUri_NoSchemeNoAuthority_EmptyPath
+ResolveUri_NoSchemeNoAuthority_EmptyPathWithQuery
+ResolveUri_NoSchemeNoAuthority_EmptyPathWithFragment
+ResolveUri_RemoveDots_RemoveOneDotSegment
+ResolveUri_RemoveDots_RemoveTwoDotSegments
+ResolveUri_RemoveDots_RemoveOneDotDotSegment
+ResolveUri_RemoveDots_RemoveTwoDotDotSegments
+ResolveUri_RemoveDots_RemoveTooManyDotDotSegments
+ResolveUri_RemoveDots_RemoveDotSegmentsNothingLeft1
+ResolveUri_RemoveDots_RemoveDotSegmentsNothingLeft2
+ResolveUri_RemoveDots_RemoveDotSegmentsInitialPrefix
+ResolveUri_RemoveDots_RemoveDotSegmentsMixed
+ResolveUri_NormalizeEscapes_PathQueryFragment
+ResolveUri_NormalizeEscapes_UppercaseHexPreferred
+ResolveUri_NormalizeEscapes_Authority
+ResolveUri_NormalizeEscapes_BrokenEscapeSequence
+ResolveUri_DataUri
+ResolveUri_RelativeBase_NotImplemented
+ResolveUri_TestUriPerRFCs
+ResolveUri_MoreDotSegmentTests
+Minimum
+Maximum
+IsPowerOfTwo
+ShiftForPowerOfTwo
+IsAligned
+RoundDown
+RoundUp
+RoundUpToPowerOfTwo
+CountOneBits
+CountZeros
+IsInt
+IsUint
+IsAbsoluteUint
+LowBits
+Endianity
+DoublesBitEqual
+AllocateVirtualMemory
+FreeVirtualMemory
+VirtualMemoryCommitPartial
+AllocateZone
+AllocGeneric_Success
+AllocGeneric_Overflow
+ZoneAllocated
+PrintToString
+CorelibCompileAll
+CorelibCompilerStats
+Dart2JSCompilerStats
+CorelibIsolateStartup
+UseDartApi
+DartStringAccess
+Dart2JSCompileAll
+FrameLookup
+CoreSnapshotSize
+StandaloneSnapshotSize
+CreateMirrorSystem
+EnterExitIsolate
+SerializeNull
+SerializeSmi
+SimpleMessage
+LargeMap
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index cc8bb06..319a322 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -491,9 +491,9 @@
     return source;
   }
   if (IsSnapshottingForPrecompilation()) {
-    return Dart_LoadScript(resolved_uri, source, 0, 0);
+    return Dart_LoadScript(resolved_uri, Dart_Null(), source, 0, 0);
   } else {
-    return Dart_LoadLibrary(resolved_uri, source, 0, 0);
+    return Dart_LoadLibrary(resolved_uri, Dart_Null(), source, 0, 0);
   }
 }
 
@@ -558,7 +558,7 @@
   if (libraryBuiltinId != Builtin::kInvalidLibrary) {
     // Special case for parting sources of a builtin library.
     if (tag == Dart_kSourceTag) {
-      return Dart_LoadSource(library, url,
+      return Dart_LoadSource(library, url, Dart_Null(),
           Builtin::PartSource(libraryBuiltinId, url_string), 0, 0);
     }
     ASSERT(tag == Dart_kImportTag);
@@ -579,10 +579,10 @@
     return source;
   }
   if (tag == Dart_kImportTag) {
-    return Dart_LoadLibrary(url, source, 0, 0);
+    return Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   } else {
     ASSERT(tag == Dart_kSourceTag);
-    return Dart_LoadSource(library, url, source, 0, 0);
+    return Dart_LoadSource(library, url, Dart_Null(), source, 0, 0);
   }
 }
 
@@ -721,7 +721,8 @@
              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_Handle loaded = Dart_LoadLibrary(script_url, Dart_Null(),
+                                          script_handle, 0, 0);
     DART_CHECK_VALID(loaded);
 
     // Do a fresh lookup
@@ -1169,7 +1170,10 @@
   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 */)) {
+  if (!VmService::Setup("127.0.0.1",
+                        -1,
+                        false /* running_precompiled */,
+                        false /* server dev mode */)) {
     *error = strdup(VmService::GetErrorMessage());
     return NULL;
   }
@@ -1201,6 +1205,7 @@
   }
 
   Thread::InitOnce();
+  Loader::InitOnce();
   DartUtils::SetOriginalWorkingDirectory();
   // Start event handler.
   TimerUtils::InitOnce();
@@ -1226,21 +1231,20 @@
   // core library snapshot generation. However for the case when a full
   // snasphot is generated from a script (app_script_name != NULL) we will
   // need the service isolate to resolve URI and load code.
-  char* error = Dart_Initialize(
-      NULL,
-      NULL,
-      NULL,
-      (app_script_name != NULL) ? CreateServiceIsolate : NULL,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      DartUtils::OpenFile,
-      DartUtils::ReadFile,
-      DartUtils::WriteFile,
-      DartUtils::CloseFile,
-      DartUtils::EntropySource,
-      NULL);
+
+  Dart_InitializeParams init_params;
+  memset(&init_params, 0, sizeof(init_params));
+  init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
+  if (app_script_name != NULL) {
+    init_params.create = CreateServiceIsolate;
+  }
+  init_params.file_open = DartUtils::OpenFile;
+  init_params.file_read = DartUtils::ReadFile;
+  init_params.file_write = DartUtils::WriteFile;
+  init_params.file_close = DartUtils::CloseFile;
+  init_params.entropy_source = DartUtils::EntropySource;
+
+  char* error = Dart_Initialize(&init_params);
   if (error != NULL) {
     Log::PrintErr("VM initialization failed: %s\n", error);
     free(error);
diff --git a/runtime/bin/io_impl_sources.gypi b/runtime/bin/io_impl_sources.gypi
index c0de4c23..1e5a1a4 100644
--- a/runtime/bin/io_impl_sources.gypi
+++ b/runtime/bin/io_impl_sources.gypi
@@ -10,6 +10,8 @@
     'eventhandler.h',
     'eventhandler_android.cc',
     'eventhandler_android.h',
+    'eventhandler_fuchsia.cc',
+    'eventhandler_fuchsia.h',
     'eventhandler_linux.cc',
     'eventhandler_linux.h',
     'eventhandler_macos.cc',
@@ -20,6 +22,7 @@
     'file_system_watcher.cc',
     'file_system_watcher.h',
     'file_system_watcher_android.cc',
+    'file_system_watcher_fuchsia.cc',
     'file_system_watcher_linux.cc',
     'file_system_watcher_macos.cc',
     'file_system_watcher_unsupported.cc',
@@ -35,6 +38,7 @@
     'platform.cc',
     'platform.h',
     'platform_android.cc',
+    'platform_fuchsia.cc',
     'platform_linux.cc',
     'platform_macos.cc',
     'platform_unsupported.cc',
@@ -42,12 +46,12 @@
     'process.cc',
     'process.h',
     'process_android.cc',
+    'process_fuchsia.cc',
     'process_linux.cc',
     'process_macos.cc',
     'process_unsupported.cc',
     'process_win.cc',
     'reference_counting.h',
-    '../../third_party/root_certificates/root_certificates.cc',
     'root_certificates_unsupported.cc',
     'secure_socket.h',
     'secure_socket_boringssl.cc',
@@ -61,6 +65,8 @@
     'socket.h',
     'socket_android.cc',
     'socket_android.h',
+    'socket_fuchsia.cc',
+    'socket_fuchsia.h',
     'socket_linux.cc',
     'socket_linux.h',
     'socket_macos.cc',
@@ -71,6 +77,7 @@
     'stdio.cc',
     'stdio.h',
     'stdio_android.cc',
+    'stdio_fuchsia.cc',
     'stdio_linux.cc',
     'stdio_macos.cc',
     'stdio_unsupported.cc',
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 609bbef..8c9c8c8 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -121,6 +121,7 @@
   V(Socket_CreateConnect, 3)                                                   \
   V(Socket_CreateBindConnect, 4)                                               \
   V(Socket_CreateBindDatagram, 4)                                              \
+  V(Socket_IsBindError, 2)                                                     \
   V(Socket_Available, 1)                                                       \
   V(Socket_Read, 2)                                                            \
   V(Socket_RecvFrom, 1)                                                        \
diff --git a/runtime/bin/io_service_patch.dart b/runtime/bin/io_service_patch.dart
index add622f..3ae7d922 100644
--- a/runtime/bin/io_service_patch.dart
+++ b/runtime/bin/io_service_patch.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.
 
-patch class _IOService {
+@patch class _IOService {
   // Lazy initialize service ports, 32 per isolate.
   static const int _SERVICE_PORT_COUNT = 32;
   static List<SendPort> _servicePort = new List(_SERVICE_PORT_COUNT);
@@ -11,7 +11,7 @@
   static Map<int, Completer> _messageMap = {};
   static int _id = 0;
 
-  /* patch */ static Future _dispatch(int request, List data) {
+  @patch static Future _dispatch(int request, List data) {
     int id;
     do {
       id = _getNextId();
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 6a99a4e..2220478 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -66,14 +66,16 @@
 // Copy the contents of |message| into an |IOResult|.
 void Loader::IOResult::Setup(Dart_CObject* message) {
   ASSERT(message->type == Dart_CObject_kArray);
-  ASSERT(message->value.as_array.length == 4);
+  ASSERT(message->value.as_array.length == 5);
   Dart_CObject* tag_message = message->value.as_array.values[0];
   ASSERT(tag_message != NULL);
   Dart_CObject* uri_message = message->value.as_array.values[1];
   ASSERT(uri_message != NULL);
-  Dart_CObject* library_uri_message = message->value.as_array.values[2];
+  Dart_CObject* resolved_uri_message = message->value.as_array.values[2];
+  ASSERT(resolved_uri_message != NULL);
+  Dart_CObject* library_uri_message = message->value.as_array.values[3];
   ASSERT(library_uri_message != NULL);
-  Dart_CObject* payload_message = message->value.as_array.values[3];
+  Dart_CObject* payload_message = message->value.as_array.values[4];
   ASSERT(payload_message != NULL);
 
   // Grab the tag.
@@ -84,6 +86,10 @@
   ASSERT(uri_message->type == Dart_CObject_kString);
   uri = strdup(uri_message->value.as_string);
 
+  // Grab the resolved uri.
+  ASSERT(resolved_uri_message->type == Dart_CObject_kString);
+  resolved_uri = strdup(resolved_uri_message->value.as_string);
+
   // Grab the library uri if one is present.
   if (library_uri_message->type != Dart_CObject_kNull) {
     ASSERT(library_uri_message->type == Dart_CObject_kString);
@@ -113,6 +119,7 @@
 
 void Loader::IOResult::Cleanup() {
   free(uri);
+  free(resolved_uri);
   free(library_uri);
   free(payload);
 }
@@ -268,6 +275,8 @@
   // dropping the lock below |result| may no longer valid.
   Dart_Handle uri =
       Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri));
+  Dart_Handle resolved_uri =
+      Dart_NewStringFromCString(reinterpret_cast<char*>(result->resolved_uri));
   Dart_Handle library_uri = Dart_Null();
   if (result->library_uri != NULL) {
     library_uri =
@@ -360,20 +369,20 @@
 
   switch (tag) {
     case Dart_kImportTag:
-      dart_result = Dart_LoadLibrary(uri, source, 0, 0);
+      dart_result = Dart_LoadLibrary(uri, resolved_uri, source, 0, 0);
     break;
     case Dart_kSourceTag: {
       ASSERT(library_uri != Dart_Null());
       Dart_Handle library = Dart_LookupLibrary(library_uri);
       ASSERT(!Dart_IsError(library));
-      dart_result = Dart_LoadSource(library, uri, source, 0, 0);
+      dart_result = Dart_LoadSource(library, uri, resolved_uri, source, 0, 0);
     }
     break;
     case Dart_kScriptTag:
       if (is_snapshot) {
         dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length);
       } else {
-        dart_result = Dart_LoadScript(uri, source, 0, 0);
+        dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0);
       }
     break;
     default:
@@ -653,7 +662,7 @@
     Dart_Handle part_uri_obj = DartUtils::NewString(part_uri);
     free(part_uri);
     return Dart_LoadSource(library,
-                           part_uri_obj,
+                           part_uri_obj, Dart_Null(),
                            Builtin::PartSource(id, url_string), 0, 0);
   }
   // All cases should have been handled above.
@@ -661,7 +670,12 @@
 }
 
 
-Mutex Loader::loader_infos_lock_;
+void Loader::InitOnce() {
+  loader_infos_lock_ = new Mutex();
+}
+
+
+Mutex* Loader::loader_infos_lock_;
 Loader::LoaderInfo* Loader::loader_infos_ = NULL;
 intptr_t Loader::loader_infos_length_ = 0;
 intptr_t Loader::loader_infos_capacity_ = 0;
@@ -672,7 +686,7 @@
 // correct loader.
 // This happens whenever an isolate begins loading.
 void Loader::AddLoader(Dart_Port port, IsolateData* isolate_data) {
-  MutexLocker ml(&loader_infos_lock_);
+  MutexLocker ml(loader_infos_lock_);
   ASSERT(LoaderForLocked(port) == NULL);
   if (loader_infos_length_ == loader_infos_capacity_) {
     // Grow to an initial capacity or double in size.
@@ -700,7 +714,7 @@
 // Remove |port| from the map.
 // This happens once an isolate has finished loading.
 void Loader::RemoveLoader(Dart_Port port) {
-  MutexLocker ml(&loader_infos_lock_);
+  MutexLocker ml(loader_infos_lock_);
   const intptr_t index = LoaderIndexFor(port);
   ASSERT(index >= 0);
   const intptr_t last = loader_infos_length_ - 1;
@@ -733,14 +747,14 @@
 
 
 Loader* Loader::LoaderFor(Dart_Port port) {
-  MutexLocker ml(&loader_infos_lock_);
+  MutexLocker ml(loader_infos_lock_);
   return LoaderForLocked(port);
 }
 
 
 void Loader::NativeMessageHandler(Dart_Port dest_port_id,
                                   Dart_CObject* message) {
-  MutexLocker ml(&loader_infos_lock_);
+  MutexLocker ml(loader_infos_lock_);
   Loader* loader = LoaderForLocked(dest_port_id);
   if (loader == NULL) {
     return;
diff --git a/runtime/bin/loader.h b/runtime/bin/loader.h
index 034138e..4fe6ac0 100644
--- a/runtime/bin/loader.h
+++ b/runtime/bin/loader.h
@@ -37,6 +37,8 @@
     return error_;
   }
 
+  static void InitOnce();
+
  private:
   // The port assigned to our native message handler.
   Dart_Port port_;
@@ -59,6 +61,7 @@
     intptr_t payload_length;
     char* library_uri;
     char* uri;
+    char* resolved_uri;
     int8_t tag;
 
     void Setup(Dart_CObject* message);
@@ -124,7 +127,7 @@
   };
 
   // The map of active loaders.
-  static Mutex loader_infos_lock_;
+  static Mutex* loader_infos_lock_;
   static LoaderInfo* loader_infos_;
   static intptr_t loader_infos_length_;
   static intptr_t loader_infos_capacity_;
diff --git a/runtime/bin/log_fuchsia.cc b/runtime/bin/log_fuchsia.cc
new file mode 100644
index 0000000..0c1f7af
--- /dev/null
+++ b/runtime/bin/log_fuchsia.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_FUCHSIA)
+
+#include "bin/log.h"
+
+#include <stdio.h>  // NOLINT
+
+namespace dart {
+namespace bin {
+
+void Log::VPrint(const char* format, va_list args) {
+  vfprintf(stdout, format, args);
+  fflush(stdout);
+}
+
+void Log::VPrintErr(const char* format, va_list args) {
+  vfprintf(stderr, format, args);
+  fflush(stdout);
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index a1f859a..9f71238 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -119,7 +119,9 @@
 // The 0 port is a magic value which results in the first available port
 // being allocated.
 static int vm_service_server_port = -1;
-
+// True when we are running in development mode and cross origin security
+// checks are disabled.
+static bool vm_service_dev_mode = false;
 
 // Exit code indicating an API error.
 static const int kApiErrorExitCode = 253;
@@ -130,10 +132,6 @@
 // Exit code indicating a vm restart request.  Never returned to the user.
 static const int kRestartRequestExitCode = 1000;
 
-// 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);
@@ -153,9 +151,7 @@
     free(error);
   }
 
-  if (do_vm_shutdown) {
-    EventHandler::Stop();
-  }
+  EventHandler::Stop();
   Platform::Exit(exit_code);
 }
 
@@ -286,28 +282,32 @@
     environment = new HashMap(&HashMap::SameStringValue, 4);
   }
   // Split the name=value part of the -Dname=value argument.
-  char* name;
-  char* value = NULL;
   const char* equals_pos = strchr(arg, '=');
   if (equals_pos == NULL) {
     // No equal sign (name without value) currently not supported.
     Log::PrintErr("No value given to -D option\n");
     return false;
-  } else {
-    int name_len = equals_pos - arg;
-    if (name_len == 0) {
-      Log::PrintErr("No name given to -D option\n");
-      return false;
-    }
-    // Split name=value into name and value.
-    name = reinterpret_cast<char*>(malloc(name_len + 1));
-    strncpy(name, arg, name_len);
-    name[name_len] = '\0';
-    value = strdup(equals_pos + 1);
   }
+
+  char* name;
+  char* value = NULL;
+  int name_len = equals_pos - arg;
+  if (name_len == 0) {
+    Log::PrintErr("No name given to -D option\n");
+    return false;
+  }
+  // Split name=value into name and value.
+  name = reinterpret_cast<char*>(malloc(name_len + 1));
+  strncpy(name, arg, name_len);
+  name[name_len] = '\0';
+  value = strdup(equals_pos + 1);
   HashMap::Entry* entry = environment->Lookup(
       GetHashmapKeyFromString(name), HashMap::StringHash(name), true);
   ASSERT(entry != NULL);  // Lookup adds an entry if key not found.
+  if (entry->value != NULL) {
+    free(name);
+    free(entry->value);
+  }
   entry->value = value;
   return true;
 }
@@ -393,6 +393,16 @@
 }
 
 
+static bool ProcessDisableServiceOriginCheckOption(
+    const char* option_value, CommandLineOptions* vm_options) {
+  ASSERT(option_value != NULL);
+  Log::PrintErr("WARNING: You are running with the service protocol in an "
+                "insecure mode.\n");
+  vm_service_dev_mode = true;
+  return true;
+}
+
+
 static bool ProcessObserveOption(const char* option_value,
                                  CommandLineOptions* vm_options) {
   ASSERT(option_value != NULL);
@@ -434,42 +444,53 @@
   // Identity reload.
   vm_options->AddArgument("--identity_reload");
   // Start reloading quickly.
-  vm_options->AddArgument("--reload_every=50");
+  vm_options->AddArgument("--reload_every=4");
   // Reload from optimized and unoptimized code.
   vm_options->AddArgument("--reload_every_optimized=false");
   // Reload less frequently as time goes on.
   vm_options->AddArgument("--reload_every_back_off");
-  // Ensure that an isolate has reloaded once.
+  // Ensure that every isolate has reloaded once before exiting.
   vm_options->AddArgument("--check_reloaded");
 
   return true;
 }
 
 
-static bool ProcessShutdownOption(const char* arg,
-                                  CommandLineOptions* vm_options) {
-  ASSERT(arg != NULL);
-  if (*arg == '\0') {
-    do_vm_shutdown = true;
-    vm_options->AddArgument("--shutdown");
-    return true;
-  }
+static bool ProcessHotReloadRollbackTestModeOption(
+      const char* arg,
+      CommandLineOptions* vm_options) {
+  // Identity reload.
+  vm_options->AddArgument("--identity_reload");
+  // Start reloading quickly.
+  vm_options->AddArgument("--reload_every=4");
+  // Reload from optimized and unoptimized code.
+  vm_options->AddArgument("--reload_every_optimized=false");
+  // Reload less frequently as time goes on.
+  vm_options->AddArgument("--reload_every_back_off");
+  // Ensure that every isolate has reloaded once before exiting.
+  vm_options->AddArgument("--check_reloaded");
+  // Force all reloads to fail and execute the rollback code.
+  vm_options->AddArgument("--reload_force_rollback");
 
-  if ((*arg != '=') && (*arg != ':')) {
-    return false;
-  }
+  return true;
+}
 
-  if (strcmp(arg + 1, "true") == 0) {
-    do_vm_shutdown = true;
-    vm_options->AddArgument("--shutdown");
-    return true;
-  } else if (strcmp(arg + 1, "false") == 0) {
-    do_vm_shutdown = false;
-    vm_options->AddArgument("--no-shutdown");
-    return true;
-  }
 
-  return false;
+extern bool short_socket_read;
+
+extern bool short_socket_write;
+
+static bool ProcessShortSocketReadOption(const char* arg,
+                                         CommandLineOptions* vm_options) {
+  short_socket_read = true;
+  return true;
+}
+
+
+static bool ProcessShortSocketWriteOption(const char* arg,
+                                          CommandLineOptions* vm_options) {
+  short_socket_write = true;
+  return true;
 }
 
 
@@ -490,14 +511,17 @@
   // VM specific options to the standalone dart program.
   { "--compile_all", ProcessCompileAllOption },
   { "--enable-vm-service", ProcessEnableVmServiceOption },
+  { "--disable-service-origin-check", ProcessDisableServiceOriginCheckOption },
   { "--observe", ProcessObserveOption },
-  { "--shutdown", ProcessShutdownOption },
   { "--snapshot=", ProcessSnapshotFilenameOption },
   { "--snapshot-kind=", ProcessSnapshotKindOption },
   { "--run-app-snapshot=", ProcessRunAppSnapshotOption },
   { "--use-blobs", ProcessUseBlobsOption },
   { "--trace-loading", ProcessTraceLoadingOption },
   { "--hot-reload-test-mode", ProcessHotReloadTestModeOption },
+  { "--hot-reload-rollback-test-mode", ProcessHotReloadRollbackTestModeOption },
+  { "--short_socket_read", ProcessShortSocketReadOption },
+  { "--short_socket_write", ProcessShortSocketWriteOption },
   { NULL, NULL }
 };
 
@@ -766,7 +790,8 @@
     bool skip_library_load = run_app_snapshot;
     if (!VmService::Setup(vm_service_server_ip,
                           vm_service_server_port,
-                          skip_library_load)) {
+                          skip_library_load,
+                          vm_service_dev_mode)) {
       *error = strdup(VmService::GetErrorMessage());
       return NULL;
     }
@@ -1063,6 +1088,22 @@
 }
 
 
+static bool FileModifiedCallback(const char* url, int64_t since) {
+  if (strncmp(url, "file:///", 8) == 0) {
+    // If it isn't a file on local disk, we don't know if it has been
+    // modified.
+    return true;
+  }
+  int64_t data[File::kStatSize];
+  File::Stat(url + 7, data);
+  if (data[File::kType] == File::kDoesNotExist) {
+    return true;
+  }
+  bool modified = data[File::kModifiedTime] > since;
+  return modified;
+}
+
+
 static void WriteSnapshotFile(const char* snapshot_directory,
                               const char* filename,
                               bool write_magic_number,
@@ -1080,7 +1121,11 @@
   }
 
   File* file = File::Open(qualified_filename, File::kWriteTruncate);
-  ASSERT(file != NULL);
+  if (file == NULL) {
+    ErrorExit(kErrorExitCode,
+              "Unable to open file %s for writing snapshot\n",
+              qualified_filename);
+  }
 
   if (write_magic_number) {
     // Write the magic number to indicate file is a script snapshot.
@@ -1089,7 +1134,7 @@
 
   if (!file->WriteFully(buffer, size)) {
     ErrorExit(kErrorExitCode,
-              "Unable to open file %s for writing snapshot\n",
+              "Unable to write file %s for writing snapshot\n",
               qualified_filename);
   }
   file->Release();
@@ -1131,7 +1176,7 @@
   }
   DartUtils::CloseFile(file);
   if (concat != NULL) {
-    delete concat;
+    delete[] concat;
   }
 }
 
@@ -1160,7 +1205,7 @@
     Platform::Exit(kErrorExitCode);
   }
   if (concat != NULL) {
-    delete concat;
+    delete[] concat;
   }
 }
 
@@ -1377,9 +1422,7 @@
       Log::PrintErr("VM cleanup failed: %s\n", error);
       free(error);
     }
-    if (do_vm_shutdown) {
-      EventHandler::Stop();
-    }
+    EventHandler::Stop();
     Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
   }
   delete [] isolate_name;
@@ -1521,7 +1564,7 @@
 
 
 // Observatory assets are only needed in the regular dart binary.
-#if !defined(DART_PRECOMPILER)
+#if !defined(DART_PRECOMPILER) && !defined(NO_OBSERVATORY)
 extern unsigned int observatory_assets_archive_len;
 extern const uint8_t* observatory_assets_archive;
 
@@ -1610,7 +1653,7 @@
 
 void main(int argc, char** argv) {
   char* script_name;
-  const int EXTRA_VM_ARGUMENTS = 2;
+  const int EXTRA_VM_ARGUMENTS = 8;
   CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
   CommandLineOptions dart_options(argc);
   bool print_flags_seen = false;
@@ -1653,6 +1696,8 @@
 
   Thread::InitOnce();
 
+  Loader::InitOnce();
+
   if (!DartUtils::SetOriginalWorkingDirectory()) {
     OSError err;
     fprintf(stderr, "Error determining current directory: %s\n", err.message());
@@ -1706,20 +1751,24 @@
   }
 
   // Initialize the Dart VM.
-  char* error = Dart_Initialize(
-      vm_isolate_snapshot_buffer, instructions_snapshot, data_snapshot,
-      CreateIsolateAndSetup, NULL, NULL, ShutdownIsolate,
-      NULL,
-      DartUtils::OpenFile,
-      DartUtils::ReadFile,
-      DartUtils::WriteFile,
-      DartUtils::CloseFile,
-      DartUtils::EntropySource,
-      GetVMServiceAssetsArchiveCallback);
+  Dart_InitializeParams init_params;
+  memset(&init_params, 0, sizeof(init_params));
+  init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
+  init_params.vm_isolate_snapshot = vm_isolate_snapshot_buffer;
+  init_params.instructions_snapshot = instructions_snapshot;
+  init_params.data_snapshot = data_snapshot;
+  init_params.create = CreateIsolateAndSetup;
+  init_params.shutdown = ShutdownIsolate;
+  init_params.file_open = DartUtils::OpenFile;
+  init_params.file_read = DartUtils::ReadFile;
+  init_params.file_write = DartUtils::WriteFile;
+  init_params.file_close = DartUtils::CloseFile;
+  init_params.entropy_source = DartUtils::EntropySource;
+  init_params.get_service_assets = GetVMServiceAssetsArchiveCallback;
+
+  char* error = Dart_Initialize(&init_params);
   if (error != NULL) {
-    if (do_vm_shutdown) {
-      EventHandler::Stop();
-    }
+    EventHandler::Stop();
     fprintf(stderr, "VM initialization failed: %s\n", error);
     fflush(stderr);
     free(error);
@@ -1730,6 +1779,7 @@
         "getIO", &ServiceGetIOHandler, NULL);
   Dart_SetServiceStreamCallbacks(&ServiceStreamListenCallback,
                                  &ServiceStreamCancelCallback);
+  Dart_SetFileModifiedCallback(&FileModifiedCallback);
 
   // Run the main isolate until we aren't told to restart.
   while (RunMainIsolate(script_name, &dart_options)) {
@@ -1744,9 +1794,7 @@
     Log::PrintErr("VM cleanup failed: %s\n", error);
     free(error);
   }
-  if (do_vm_shutdown) {
-    EventHandler::Stop();
-  }
+  EventHandler::Stop();
 
   // Free copied argument strings if converted.
   if (argv_converted) {
diff --git a/runtime/bin/platform_fuchsia.cc b/runtime/bin/platform_fuchsia.cc
new file mode 100644
index 0000000..3e636d1
--- /dev/null
+++ b/runtime/bin/platform_fuchsia.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_FUCHSIA)
+
+#include "bin/platform.h"
+
+#include <string.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#include "bin/fdutils.h"
+#include "bin/file.h"
+
+namespace dart {
+namespace bin {
+
+const char* Platform::executable_name_ = NULL;
+char* Platform::resolved_executable_name_ = NULL;
+int Platform::script_index_ = 1;
+char** Platform::argv_ = NULL;
+
+bool Platform::Initialize() {
+  return true;
+}
+
+
+int Platform::NumberOfProcessors() {
+  return sysconf(_SC_NPROCESSORS_CONF);
+}
+
+
+const char* Platform::OperatingSystem() {
+  return "fuchsia";
+}
+
+
+const char* Platform::LibraryPrefix() {
+  return "lib";
+}
+
+
+const char* Platform::LibraryExtension() {
+  return "so";
+}
+
+
+bool Platform::LocalHostname(char *buffer, intptr_t buffer_length) {
+  return gethostname(buffer, buffer_length) == 0;
+}
+
+
+char** Platform::Environment(intptr_t* count) {
+  char** result =
+      reinterpret_cast<char**>(Dart_ScopeAllocate(1 * sizeof(*result)));
+  result[0] = NULL;
+  return result;
+}
+
+
+const char* Platform::ResolveExecutablePath() {
+  return "dart";
+}
+
+
+void Platform::Exit(int exit_code) {
+  exit(exit_code);
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index 577bbb6..8110ea1 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -2,33 +2,33 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch class _Platform {
-  /* patch */ static int _numberOfProcessors()
+@patch class _Platform {
+  @patch static int _numberOfProcessors()
       native "Platform_NumberOfProcessors";
-  /* patch */ static String _pathSeparator()
+  @patch static String _pathSeparator()
       native "Platform_PathSeparator";
-  /* patch */ static String _operatingSystem()
+  @patch static String _operatingSystem()
       native "Platform_OperatingSystem";
-  /* patch */ static _localHostname()
+  @patch static _localHostname()
       native "Platform_LocalHostname";
-  /* patch */ static _executable()
+  @patch static _executable()
       native "Platform_ExecutableName";
-  /* patch */ static _resolvedExecutable()
+  @patch static _resolvedExecutable()
       native "Platform_ResolvedExecutableName";
-  /* patch */ static _environment()
+  @patch static _environment()
       native "Platform_Environment";
-  /* patch */ static List<String> _executableArguments()
+  @patch static List<String> _executableArguments()
       native "Platform_ExecutableArguments";
-  /* patch */ static String _version()
+  @patch static String _version()
       native "Platform_GetVersion";
 
-  /* patch */ static String _packageRoot()
+  @patch static String _packageRoot()
       => VMLibraryHooks.packageRootString;
-  /* patch */ static String _packageConfig()
+  @patch static String _packageConfig()
       => VMLibraryHooks.packageConfigString;
 
   // This script singleton is written to by the embedder if applicable.
-  /* patch */ static void set _nativeScript(String path) {
+  @patch static void set _nativeScript(String path) {
     if (path.startsWith('http:') ||
         path.startsWith('https:') ||
         path.startsWith('package:') ||
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
new file mode 100644
index 0000000..5858800
--- /dev/null
+++ b/runtime/bin/process_fuchsia.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if !defined(DART_IO_DISABLED)
+
+#include "platform/globals.h"
+#if defined(TARGET_OS_FUCHSIA)
+
+#include "bin/process.h"
+
+#include "bin/lockers.h"
+#include "platform/assert.h"
+
+
+namespace dart {
+namespace bin {
+
+int Process::global_exit_code_ = 0;
+Mutex* Process::global_exit_code_mutex_ = new Mutex();
+
+void Process::TerminateExitCodeHandler() {
+}
+
+intptr_t Process::CurrentProcessId() {
+  UNIMPLEMENTED();
+  return 0;
+}
+
+intptr_t Process::SetSignalHandler(intptr_t signal) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+void Process::ClearSignalHandler(intptr_t signal) {
+  UNIMPLEMENTED();
+}
+
+bool Process::Wait(intptr_t pid,
+                   intptr_t in,
+                   intptr_t out,
+                   intptr_t err,
+                   intptr_t exit_event,
+                   ProcessResult* result) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+bool Process::Kill(intptr_t id, int signal) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+int Process::Start(const char* path,
+                   char* arguments[],
+                   intptr_t arguments_length,
+                   const char* working_directory,
+                   char* environment[],
+                   intptr_t environment_length,
+                   ProcessStartMode mode,
+                   intptr_t* in,
+                   intptr_t* out,
+                   intptr_t* err,
+                   intptr_t* id,
+                   intptr_t* exit_event,
+                   char** os_error_message) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
+
+#endif  // !defined(DART_IO_DISABLED)
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 60fb2b5..bfb09db 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -2,20 +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.
 
-patch class _WindowsCodePageDecoder {
-  /* patch */ static String _decodeBytes(List<int> bytes)
+@patch class _WindowsCodePageDecoder {
+  @patch static String _decodeBytes(List<int> bytes)
       native "SystemEncodingToString";
 }
 
 
-patch class _WindowsCodePageEncoder {
-  /* patch */ static List<int> _encodeString(String string)
+@patch class _WindowsCodePageEncoder {
+  @patch static List<int> _encodeString(String string)
       native "StringToSystemEncoding";
 }
 
 
-patch class Process {
-  /* patch */ static Future<Process> start(
+@patch class Process {
+  @patch static Future<Process> start(
       String executable,
       List<String> arguments,
       {String workingDirectory,
@@ -33,7 +33,7 @@
     return process._start();
   }
 
-  /* patch */ static Future<ProcessResult> run(
+  @patch static Future<ProcessResult> run(
       String executable,
       List<String> arguments,
       {String workingDirectory,
@@ -52,7 +52,7 @@
                                      stderrEncoding);
   }
 
-  /* patch */ static ProcessResult runSync(
+  @patch static ProcessResult runSync(
       String executable,
       List<String> arguments,
       {String workingDirectory,
@@ -71,7 +71,7 @@
                                          stderrEncoding);
   }
 
-  /* patch */ static bool killPid(
+  @patch static bool killPid(
       int pid, [ProcessSignal signal = ProcessSignal.SIGTERM]) {
     if (signal is! ProcessSignal) {
       throw new ArgumentError(
@@ -125,25 +125,25 @@
     }
   }
 
-  /* patch */ static _setSignalHandler(int signal)
+  @patch static _setSignalHandler(int signal)
       native "Process_SetSignalHandler";
-  /* patch */ static int _clearSignalHandler(int signal)
+  @patch static int _clearSignalHandler(int signal)
       native "Process_ClearSignalHandler";
 }
 
 Function _getWatchSignalInternal() => _ProcessUtils._watchSignalInternal;
 
 
-patch class _ProcessUtils {
-  /* patch */ static void _exit(int status) native "Process_Exit";
-  /* patch */ static void _setExitCode(int status)
+@patch class _ProcessUtils {
+  @patch static void _exit(int status) native "Process_Exit";
+  @patch static void _setExitCode(int status)
       native "Process_SetExitCode";
-  /* patch */ static int _getExitCode() native "Process_GetExitCode";
-  /* patch */ static void _sleep(int millis) native "Process_Sleep";
-  /* patch */ static int _pid(Process process) native "Process_Pid";
+  @patch static int _getExitCode() native "Process_GetExitCode";
+  @patch static void _sleep(int millis) native "Process_Sleep";
+  @patch static int _pid(Process process) native "Process_Pid";
   static bool _killPid(int pid, int signal)
       native "Process_KillPid";
-  /* patch */ static Stream<ProcessSignal> _watchSignal(ProcessSignal signal) {
+  @patch static Stream<ProcessSignal> _watchSignal(ProcessSignal signal) {
     if (signal != ProcessSignal.SIGHUP &&
         signal != ProcessSignal.SIGINT &&
         signal != ProcessSignal.SIGTERM &&
diff --git a/runtime/bin/run_vm_tests_fuchsia.cc b/runtime/bin/run_vm_tests_fuchsia.cc
new file mode 100644
index 0000000..e98837a
--- /dev/null
+++ b/runtime/bin/run_vm_tests_fuchsia.cc
@@ -0,0 +1,331 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 <fcntl.h>
+#include <launchpad/launchpad.h>
+#include <magenta/syscalls.h>
+#include <mxio/util.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+// This program runs Dart VM unit tests. The Dart VM unit tests are contained
+// in a separate binary whose location is defined in kRunVmTestsPath below.
+// That program accepts a command line argument --list to list all the available
+// tests, or the name of a single test to run. This program accepts a single
+// command line argument which is the path to a file containing a list of tests
+// to run, one per line.
+
+// TODO(zra): Make this a command line argument
+const char* kRunVmTestsPath = "/boot/bin/dart_vm_tests";
+
+// The simulator only has 512MB;
+const intptr_t kOldGenHeapSizeMB = 256;
+
+// Tests that are invalid, wedge, or cause panics.
+const char* kSkip[] = {
+  // These expect a file to exist that we aren't putting in the image.
+  "Read",
+  "FileLength",
+  "FilePosition",
+  // Crash and then Hang.
+  "ArrayLengthMaxElements",
+  "Int8ListLengthMaxElements",
+  // Crashes in realloc.
+  "LargeMap",
+  // The profiler is turned off.
+  "Profiler_AllocationSampleTest",
+  "Profiler_ArrayAllocation",
+  "Profiler_BasicSourcePosition",
+  "Profiler_BasicSourcePositionOptimized",
+  "Profiler_BinaryOperatorSourcePosition",
+  "Profiler_BinaryOperatorSourcePositionOptimized",
+  "Profiler_ChainedSamples",
+  "Profiler_ClosureAllocation",
+  "Profiler_CodeTicks",
+  "Profiler_ContextAllocation",
+  "Profiler_FunctionInline",
+  "Profiler_FunctionTicks",
+  "Profiler_InliningIntervalBoundry",
+  "Profiler_IntrinsicAllocation",
+  "Profiler_SampleBufferIterateTest",
+  "Profiler_SampleBufferWrapTest",
+  "Profiler_SourcePosition",
+  "Profiler_SourcePositionOptimized",
+  "Profiler_StringAllocation",
+  "Profiler_StringInterpolation",
+  "Profiler_ToggleRecordAllocation",
+  "Profiler_TrivialRecordAllocation",
+  "Profiler_TypedArrayAllocation",
+  "Profiler_GetSourceReport",
+  "Service_Profile",
+  // No realpath.
+  "Dart2JSCompilerStats",
+  "Dart2JSCompileAll",
+  // Uses too much memory.
+  "PrintJSON",
+};
+
+// Expected to fail/crash.
+const char* kExpectFail[] = {
+  "Fail0",
+  "Fail1",
+  "Fail2",
+  "IsolateReload_PendingUnqualifiedCall_InstanceToStatic",
+  "IsolateReload_PendingUnqualifiedCall_StaticToInstance",
+  "IsolateReload_PendingConstructorCall_AbstractToConcrete",
+  "IsolateReload_PendingConstructorCall_ConcreteToAbstract",
+  "IsolateReload_PendingStaticCall_DefinedToNSM",
+  "IsolateReload_PendingStaticCall_NSMToDefined",
+  "ArrayNew_Overflow_Crash",
+  "AllocGeneric_Overflow",
+  "CodeImmutability",
+  "SNPrint_BadArgs",
+};
+
+// Bugs to fix, or things that are not yet impelemnted.
+const char* kBugs[] = {
+  // pthreads not using specified stack size?
+  "StackOverflowStacktraceInfo",
+  // Needs OS::GetCurrentThreadCPUMicros.
+  "Timeline_Dart_TimelineGetTrace",
+  "Timeline_Dart_TimelineGetTraceOnlyDartEvents",
+  "Timeline_Dart_TimelineGetTraceWithDartEvents",
+  "Timeline_Dart_TimelineGetTraceGlobalOverride",
+  "Timeline_Dart_GlobalTimelineGetTrace",
+  "Timeline_Dart_GlobalTimelineGetTrace_Threaded",
+  "TimelineEventDuration",
+  "TimelineEventDurationPrintJSON",
+  "TimelineEventArguments",
+  "TimelineEventArgumentsPrintJSON",
+  "TimelineEventCallbackRecorderBasic",
+  "TimelineAnalysis_ThreadBlockCount",
+  "TimelineRingRecorderJSONOrder",
+  "TimelinePauses_BeginEnd",
+  // Needs NativeSymbolResolver
+  "Service_PersistentHandles",
+  // Crashes in realloc:
+  "FindCodeObject",
+  "SourceReport_Coverage_AllFunctions_ForceCompile",
+  // pthread TLS destructors are not run.
+  "ThreadIterator_AddFindRemove",
+};
+
+
+static bool contains(const char** list, intptr_t len, const char* str) {
+  for (intptr_t i = 0; i < len; i++) {
+    if (strcmp(list[i], str) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+static bool isSkip(const char* test) {
+  return contains(
+      kSkip, sizeof(kSkip) / sizeof(kSkip[0]), test);
+}
+
+
+static bool isExpectFail(const char* test) {
+  return contains(
+      kExpectFail, sizeof(kExpectFail) / sizeof(kExpectFail[0]), test);
+}
+
+
+static bool isBug(const char* test) {
+  return contains(kBugs, sizeof(kBugs) / sizeof(kBugs[0]), test);
+}
+
+
+static int run_test(const char* test_name) {
+  const intptr_t kArgc = 3;
+  const char* argv[kArgc];
+
+  char old_gen_arg[64];
+  snprintf(old_gen_arg, sizeof(old_gen_arg), "--old_gen_heap_size=%ld",
+      kOldGenHeapSizeMB);
+
+  argv[0] = kRunVmTestsPath;
+  argv[1] = old_gen_arg;
+  argv[2] = test_name;
+
+  mx_handle_t p = launchpad_launch_mxio(argv[0], kArgc, argv);
+  if (p < 0) {
+    fprintf(stderr, "process failed to start\n");
+    return -1;
+  }
+
+  mx_signals_state_t state;
+  mx_status_t r = mx_handle_wait_one(
+      p, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, &state);
+  if (r != NO_ERROR) {
+    fprintf(stderr, "[process(%x): wait failed? %d]\n", p, r);
+    return -1;
+  }
+
+  mx_process_info_t proc_info;
+  mx_ssize_t ret = mx_handle_get_info(
+      p, MX_INFO_PROCESS, &proc_info, sizeof(proc_info));
+  if (ret != sizeof(proc_info)) {
+    fprintf(stderr, "[process(%x): handle_get_info failed? %ld]\n", p, ret);
+    return -1;
+  }
+
+  mx_handle_close(p);
+  return proc_info.return_code;
+}
+
+
+static void handle_result(intptr_t result, const char* test) {
+  if (result != 0) {
+    if (!isExpectFail(test) && !isBug(test)) {
+      printf("******** Test %s FAILED\n", test);
+    }
+  } else {
+    if (isExpectFail(test)) {
+      printf("******** Test %s is expected to fail, but PASSED\n", test);
+    }
+    if (isBug(test)) {
+      printf("******** Test %s is marked as a bug, but PASSED\n", test);
+    }
+  }
+}
+
+
+typedef struct {
+  pthread_mutex_t* test_list_lock;
+  char** test_list;
+  intptr_t test_list_length;
+  intptr_t* test_list_index;
+} runner_args_t;
+
+
+static void* test_runner_thread(void* arg) {
+  runner_args_t* args = reinterpret_cast<runner_args_t*>(arg);
+
+  pthread_mutex_lock(args->test_list_lock);
+  while (*args->test_list_index < args->test_list_length) {
+    const intptr_t index = *args->test_list_index;
+    *args->test_list_index = index + 1;
+    pthread_mutex_unlock(args->test_list_lock);
+    const char* test = args->test_list[index];
+    handle_result(run_test(test), test);
+    pthread_mutex_lock(args->test_list_lock);
+  }
+  pthread_mutex_unlock(args->test_list_lock);
+
+  return NULL;
+}
+
+
+static void trim(char* line) {
+  const intptr_t line_len = strlen(line);
+  if (line[line_len - 1] == '\n') {
+    line[line_len - 1] = '\0';
+  }
+}
+
+
+static bool should_run(const char* test) {
+  return !(test[0] == '#') && !isSkip(test);
+}
+
+
+static intptr_t count_lines(FILE* fp) {
+  intptr_t lines = 0;
+
+  // Make sure we're at the beginning of the file.
+  rewind(fp);
+
+  intptr_t ch;
+  while ((ch = fgetc(fp)) != EOF) {
+    if (ch == '\n') {
+      lines++;
+    }
+  }
+
+  rewind(fp);
+  return lines;
+}
+
+
+static intptr_t read_lines(FILE* fp, char** lines, intptr_t lines_length) {
+  char* test = NULL;
+  size_t len = 0;
+  ssize_t read;
+  intptr_t i = 0;
+  while (((read = getline(&test, &len, fp)) != -1) && (i < lines_length)) {
+    trim(test);
+    if (!should_run(test)) {
+      continue;
+    }
+    lines[i] = strdup(test);
+    i++;
+  }
+
+  if (test != NULL) {
+    free(test);
+  }
+  return i;
+}
+
+
+int main(int argc, char** argv) {
+  if (argc <= 1) {
+    fprintf(stderr, "Pass the path to a file containing the list of tests\n");
+    return -1;
+  }
+  const char* tests_path = argv[1];
+
+  FILE* fp = fopen(tests_path, "r");
+  if (fp == NULL) {
+    fprintf(stderr, "Failed to read the file: %s\n", tests_path);
+    return -1;
+  }
+
+  intptr_t lines_count = count_lines(fp);
+  char** test_list =
+      reinterpret_cast<char**>(malloc(sizeof(*test_list) * lines_count));
+  lines_count = read_lines(fp, test_list, lines_count);
+  fclose(fp);
+
+  pthread_mutex_t args_mutex;
+  pthread_mutex_init(&args_mutex, NULL);
+  intptr_t test_list_index = 0;
+  runner_args_t args;
+  args.test_list_lock = &args_mutex;
+  args.test_list = test_list;
+  args.test_list_length = lines_count;
+  args.test_list_index = &test_list_index;
+
+  const intptr_t num_cpus = sysconf(_SC_NPROCESSORS_CONF);
+  pthread_t* threads =
+    reinterpret_cast<pthread_t*>(malloc(num_cpus * sizeof(pthread_t)));
+  for (int i = 0; i < num_cpus; i++) {
+    pthread_create(&threads[i], NULL, test_runner_thread, &args);
+  }
+
+  for (int i = 0; i < num_cpus; i++) {
+    pthread_join(threads[i], NULL);
+  }
+
+  free(threads);
+  for (int i = 0; i < lines_count; i++) {
+    free(test_list[i]);
+  }
+  free(test_list);
+  pthread_mutex_destroy(&args_mutex);
+
+  if (test_list_index != lines_count) {
+    fprintf(stderr, "Failed to attempt all the tests!\n");
+    return -1;
+  }
+
+  return 0;
+}
diff --git a/runtime/bin/secure_socket_boringssl.cc b/runtime/bin/secure_socket_boringssl.cc
index 0fd1c9e..e881815 100644
--- a/runtime/bin/secure_socket_boringssl.cc
+++ b/runtime/bin/secure_socket_boringssl.cc
@@ -94,11 +94,14 @@
                              const char* message) {
   char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE];
   FetchErrorString(error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE);
-  OSError os_error_struct(status, error_string, OSError::kBoringSSL);
-  Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
-  Dart_Handle exception =
-      DartUtils::NewDartIOException(exception_type, message, os_error);
-  ASSERT(!Dart_IsError(exception));
+  Dart_Handle exception;
+  {
+    OSError os_error_struct(status, error_string, OSError::kBoringSSL);
+    Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
+    exception =
+        DartUtils::NewDartIOException(exception_type, message, os_error);
+    ASSERT(!Dart_IsError(exception));
+  }
   Dart_ThrowException(exception);
   UNREACHABLE();
 }
@@ -143,8 +146,8 @@
 }
 
 
-static SSL_CTX* GetSecurityContext(Dart_NativeArguments args) {
-  SSL_CTX* context;
+static SSLContext* GetSecurityContext(Dart_NativeArguments args) {
+  SSLContext* context;
   Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
   ASSERT(Dart_IsInstance(dart_this));
   ThrowIfError(Dart_GetNativeInstanceField(
@@ -155,17 +158,17 @@
 }
 
 
-static void FreeSecurityContext(
+static void DeleteSecurityContext(
     void* isolate_data,
     Dart_WeakPersistentHandle handle,
     void* context_pointer) {
-  SSL_CTX* context = static_cast<SSL_CTX*>(context_pointer);
-  SSL_CTX_free(context);
+  SSLContext* context = static_cast<SSLContext*>(context_pointer);
+  delete context;
 }
 
 
 static Dart_Handle SetSecurityContext(Dart_NativeArguments args,
-                                      SSL_CTX* context) {
+                                      SSLContext* context) {
   const int approximate_size_of_context = 1500;
   Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
   RETURN_IF_ERROR(dart_this);
@@ -178,7 +181,7 @@
   Dart_NewWeakPersistentHandle(dart_this,
                                context,
                                approximate_size_of_context,
-                               FreeSecurityContext);
+                               DeleteSecurityContext);
   return Dart_Null();
 }
 
@@ -198,7 +201,7 @@
 // Forward declaration.
 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
                                 SSL* ssl,
-                                SSL_CTX* context,
+                                SSLContext* context,
                                 bool is_server);
 
 
@@ -235,7 +238,7 @@
   // TODO(whesse): Is truncating a Dart string containing \0 what we want?
   ThrowIfError(Dart_StringToCString(host_name_object, &host_name));
 
-  SSL_CTX* context = NULL;
+  SSLContext* context = NULL;
   if (!Dart_IsNull(context_object)) {
     ThrowIfError(Dart_GetNativeInstanceField(
         context_object,
@@ -248,7 +251,7 @@
   ASSERT(!Dart_IsNull(protocols_handle));
 
   GetFilter(args)->Connect(host_name,
-                           context,
+                           context->context(),
                            is_server,
                            request_client_certificate,
                            require_client_certificate,
@@ -426,14 +429,15 @@
 
 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
   SSLFilter::InitializeLibrary();
-  SSL_CTX* context = SSL_CTX_new(TLS_method());
-  SSL_CTX_set_verify(context, SSL_VERIFY_PEER, CertificateCallback);
-  SSL_CTX_set_min_version(context, TLS1_VERSION);
-  SSL_CTX_set_cipher_list(context, "HIGH:MEDIUM");
-  SSL_CTX_set_cipher_list_tls11(context, "HIGH:MEDIUM");
+  SSL_CTX* ctx = SSL_CTX_new(TLS_method());
+  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback);
+  SSL_CTX_set_min_version(ctx, TLS1_VERSION);
+  SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM");
+  SSL_CTX_set_cipher_list_tls11(ctx, "HIGH:MEDIUM");
+  SSLContext* context = new SSLContext(ctx);
   Dart_Handle err = SetSecurityContext(args, context);
   if (Dart_IsError(err)) {
-    SSL_CTX_free(context);
+    delete context;
     Dart_PropagateError(err);
   }
 }
@@ -663,14 +667,17 @@
 
 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
     Dart_NativeArguments args) {
-  SSL_CTX* context = GetSecurityContext(args);
+  SSLContext* context = GetSecurityContext(args);
   const char* password = GetPasswordArgument(args, 2);
 
   int status;
   {
     ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
     EVP_PKEY *key = GetPrivateKey(bio.bio(), password);
-    status = SSL_CTX_use_PrivateKey(context, key);
+    status = SSL_CTX_use_PrivateKey(context->context(), key);
+    // SSL_CTX_use_PrivateKey increments the reference count of key on success,
+    // so we have to call EVP_PKEY_free on both success and failure.
+    EVP_PKEY_free(key);
   }
 
   // TODO(24184): Handle different expected errors here - file missing,
@@ -699,16 +706,18 @@
   ScopedX509Stack cert_stack(ca_certs);
   X509_STORE* store = SSL_CTX_get_cert_store(context);
   status = X509_STORE_add_cert(store, cert);
+  // X509_STORE_add_cert increments the reference count of cert on success.
+  X509_free(cert);
   if (status == 0) {
-    X509_free(cert);
     return status;
   }
 
   X509* ca;
   while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
     status = X509_STORE_add_cert(store, ca);
+    // X509_STORE_add_cert increments the reference count of cert on success.
+    X509_free(ca);
     if (status == 0) {
-      X509_free(ca);
       return status;
     }
   }
@@ -724,8 +733,9 @@
   X509* cert = NULL;
   while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
     status = X509_STORE_add_cert(store, cert);
+    // X509_STORE_add_cert increments the reference count of cert on success.
+    X509_free(cert);
     if (status == 0) {
-      X509_free(cert);
       return status;
     }
   }
@@ -759,12 +769,13 @@
 
 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
     Dart_NativeArguments args) {
-  SSL_CTX* context = GetSecurityContext(args);
+  SSLContext* context = GetSecurityContext(args);
   const char* password = GetPasswordArgument(args, 2);
   int status;
   {
     ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
-    status = SetTrustedCertificatesBytes(context, bio.bio(), password);
+    status = SetTrustedCertificatesBytes(
+        context->context(), bio.bio(), password);
   }
   CheckStatus(status,
               "TlsException",
@@ -779,7 +790,7 @@
 
 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
     Dart_NativeArguments args) {
-  SSL_CTX* context = GetSecurityContext(args);
+  SSLContext* context = GetSecurityContext(args);
 #if defined(TARGET_OS_ANDROID)
   // On Android, we don't compile in the trusted root certificates. Insead,
   // we use the directory of trusted certificates already present on the device.
@@ -789,10 +800,11 @@
   // the Dart thread so that Dart code can be invoked from the "bad certificate"
   // callback called by SSL_do_handshake.
   const char* android_cacerts = "/system/etc/security/cacerts";
-  int status = SSL_CTX_load_verify_locations(context, NULL, android_cacerts);
+  int status = SSL_CTX_load_verify_locations(
+      context->context(), NULL, android_cacerts);
   CheckStatus(status, "TlsException", "Failure trusting builtint roots");
 #else
-  X509_STORE* store = SSL_CTX_get_cert_store(context);
+  X509_STORE* store = SSL_CTX_get_cert_store(context->context());
   BIO* roots_bio =
       BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem),
                       root_certificates_pem_length);
@@ -800,10 +812,19 @@
   // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case,
   // backed by a memory buffer), and returns X509 objects, one by one.
   // When the end of the bio is reached, it returns null.
-  while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL))) {
-    X509_STORE_add_cert(store, root_cert);
+  while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) {
+    int status = X509_STORE_add_cert(store, root_cert);
+    // X509_STORE_add_cert increments the reference count of cert on success.
+    X509_free(root_cert);
+    if (status == 0) {
+      break;
+    }
   }
   BIO_free(roots_bio);
+  // If there is an error here, it must be the error indicating that we are done
+  // reading PEM certificates.
+  ASSERT((ERR_peek_error() == 0) || NoPEMStartLine());
+  ERR_clear_error();
 #endif  // defined(TARGET_OS_ANDROID)
 }
 
@@ -840,6 +861,8 @@
   X509* ca;
   while ((ca = sk_X509_shift(certs.get())) != NULL) {
     status = SSL_CTX_add0_chain_cert(context, ca);
+    // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
+    // call fails.
     if (status == 0) {
       X509_free(ca);
       return status;
@@ -871,6 +894,8 @@
   X509* ca;
   while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
     status = SSL_CTX_add0_chain_cert(context, ca);
+    // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
+    // call fails.
     if (status == 0) {
       X509_free(ca);
       return status;
@@ -902,12 +927,12 @@
 
 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
     Dart_NativeArguments args) {
-  SSL_CTX* context = GetSecurityContext(args);
+  SSLContext* context = GetSecurityContext(args);
   const char* password = GetPasswordArgument(args, 2);
   int status;
   {
     ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
-    status = UseChainBytes(context, bio.bio(), password);
+    status = UseChainBytes(context->context(), bio.bio(), password);
   }
   CheckStatus(status,
               "TlsException",
@@ -933,14 +958,16 @@
 
   ScopedX509Stack cert_stack(ca_certs);
   status = SSL_CTX_add_client_CA(context, cert);
+  // SSL_CTX_add_client_CA increments the reference count of cert on success.
+  X509_free(cert);
   if (status == 0) {
-    X509_free(cert);
     return status;
   }
 
   X509* ca;
   while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
     status = SSL_CTX_add_client_CA(context, ca);
+    // SSL_CTX_add_client_CA increments the reference count of ca on success.
     X509_free(ca);  // The name has been extracted.
     if (status == 0) {
       return status;
@@ -985,13 +1012,13 @@
 
 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
     Dart_NativeArguments args) {
-  SSL_CTX* context = GetSecurityContext(args);
+  SSLContext* context = GetSecurityContext(args);
   const char* password = GetPasswordArgument(args, 2);
 
   int status;
   {
     ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
-    status = SetClientAuthorities(context, bio.bio(), password);
+    status = SetClientAuthorities(context->context(), bio.bio(), password);
   }
 
   CheckStatus(status,
@@ -1002,7 +1029,7 @@
 
 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
     Dart_NativeArguments args) {
-  SSL_CTX* context = GetSecurityContext(args);
+  SSLContext* context = GetSecurityContext(args);
   Dart_Handle protocols_handle =
       ThrowIfError(Dart_GetNativeArgument(args, 1));
   Dart_Handle is_server_handle =
@@ -1359,7 +1386,7 @@
 // Sets the protocol list for ALPN on a SSL object or a context.
 static void SetAlpnProtocolList(Dart_Handle protocols_handle,
                                 SSL* ssl,
-                                SSL_CTX* context,
+                                SSLContext* context,
                                 bool is_server) {
   // Enable ALPN (application layer protocol negotiation) if the caller provides
   // a valid list of supported protocols.
@@ -1396,13 +1423,9 @@
           static_cast<uint8_t*>(malloc(protocol_string_len + 1));
       memmove(protocol_string_copy, protocol_string, protocol_string_len);
       protocol_string_copy[protocol_string_len] = '\0';
-      SSL_CTX_set_alpn_select_cb(context, AlpnCallback, protocol_string_copy);
-      // TODO(whesse): If this function is called again, free the previous
-      // protocol_string_copy.  It may be better to keep this as a native
-      // field on the Dart object, since fetching it from the structure is
-      // not in the public api.
-      // Also free protocol_string_copy when the context is destroyed,
-      // in FreeSecurityContext()
+      SSL_CTX_set_alpn_select_cb(
+          context->context(), AlpnCallback, protocol_string_copy);
+      context->set_alpn_protocol_string(protocol_string_copy);
     } else {
       // The function makes a local copy of protocol_string, which it owns.
       if (ssl != NULL) {
@@ -1412,7 +1435,7 @@
         ASSERT(context != NULL);
         ASSERT(ssl == NULL);
         status = SSL_CTX_set_alpn_protos(
-            context, protocol_string, protocol_string_len);
+            context->context(), protocol_string, protocol_string_len);
       }
       ASSERT(status == 0);  // The function returns a non-standard status.
     }
diff --git a/runtime/bin/secure_socket_boringssl.h b/runtime/bin/secure_socket_boringssl.h
index d5449a4..788b257 100644
--- a/runtime/bin/secure_socket_boringssl.h
+++ b/runtime/bin/secure_socket_boringssl.h
@@ -33,8 +33,39 @@
 extern const unsigned char* root_certificates_pem;
 extern unsigned int root_certificates_pem_length;
 
+class SSLContext {
+ public:
+  explicit SSLContext(SSL_CTX* context) :
+      context_(context),
+      alpn_protocol_string_(NULL) {
+  }
+
+  ~SSLContext() {
+    SSL_CTX_free(context_);
+    if (alpn_protocol_string_ != NULL) {
+      free(alpn_protocol_string_);
+    }
+  }
+
+  SSL_CTX* context() const { return context_; }
+
+  uint8_t* alpn_protocol_string() const { return alpn_protocol_string_; }
+  void set_alpn_protocol_string(uint8_t* protocol_string) {
+    if (alpn_protocol_string_ != NULL) {
+      free(alpn_protocol_string_);
+    }
+    alpn_protocol_string_ = protocol_string;
+  }
+
+ private:
+  SSL_CTX* context_;
+  uint8_t* alpn_protocol_string_;
+
+  DISALLOW_COPY_AND_ASSIGN(SSLContext);
+};
+
 /*
- * SSLFilter encapsulates the NSS SSL(TLS) code in a filter, that communicates
+ * SSLFilter encapsulates the SSL(TLS) code in a filter, that communicates
  * with the containing _SecureFilterImpl Dart object through four shared
  * ExternalByteArray buffers, for reading and writing plaintext, and
  * reading and writing encrypted text.  The filter handles handshaking
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index c47c941..ad29bd5 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -2,18 +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.
 
-patch class SecureSocket {
-  /* patch */ factory SecureSocket._(RawSecureSocket rawSocket) =>
+@patch class SecureSocket {
+  @patch factory SecureSocket._(RawSecureSocket rawSocket) =>
       new _SecureSocket(rawSocket);
 }
 
 
-patch class _SecureFilter {
-  /* patch */ factory _SecureFilter() => new _SecureFilterImpl();
+@patch class _SecureFilter {
+  @patch factory _SecureFilter() => new _SecureFilterImpl();
 }
 
-patch class X509Certificate {
-  /* patch */ factory X509Certificate._() => new _X509CertificateImpl();
+@patch class X509Certificate {
+  @patch factory X509Certificate._() => new _X509CertificateImpl();
 }
 
 class _SecureSocket extends _Socket implements SecureSocket {
@@ -115,16 +115,16 @@
   List<_ExternalBuffer> buffers;
 }
 
-patch class SecurityContext {
-  /* patch */ factory SecurityContext() {
+@patch class SecurityContext {
+  @patch factory SecurityContext() {
     return new _SecurityContext();
   }
 
-  /* patch */ static SecurityContext get defaultContext {
+  @patch static SecurityContext get defaultContext {
     return _SecurityContext.defaultContext;
   }
 
-  /* patch */ static bool get alpnSupported {
+  @patch static bool get alpnSupported {
     return _SecurityContext.alpnSupported;
   }
 }
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 7b6f95a..687b773 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -23,9 +23,11 @@
 
 static const int kSocketIdNativeField = 0;
 
-
 ListeningSocketRegistry *globalTcpListeningSocketRegistry = NULL;
 
+bool short_socket_read = false;
+
+bool short_socket_write = false;
 
 void ListeningSocketRegistry::Initialize() {
   ASSERT(globalTcpListeningSocketRegistry == NULL);
@@ -44,6 +46,60 @@
 }
 
 
+ListeningSocketRegistry::OSSocket* ListeningSocketRegistry::LookupByPort(
+    intptr_t port) {
+  HashMap::Entry* entry =
+     sockets_by_port_.Lookup(GetHashmapKeyFromIntptr(port),
+                             GetHashmapHashFromIntptr(port), false);
+  if (entry == NULL) {
+    return NULL;
+  }
+  return reinterpret_cast<OSSocket*>(entry->value);
+}
+
+
+void ListeningSocketRegistry::InsertByPort(intptr_t port, OSSocket* socket) {
+  HashMap::Entry* entry =
+     sockets_by_port_.Lookup(GetHashmapKeyFromIntptr(port),
+                             GetHashmapHashFromIntptr(port), true);
+  ASSERT(entry != NULL);
+  entry->value = reinterpret_cast<void*>(socket);
+}
+
+
+void ListeningSocketRegistry::RemoveByPort(intptr_t port) {
+  sockets_by_port_.Remove(
+      GetHashmapKeyFromIntptr(port), GetHashmapHashFromIntptr(port));
+}
+
+
+ListeningSocketRegistry::OSSocket* ListeningSocketRegistry::LookupByFd(
+    intptr_t fd) {
+  HashMap::Entry* entry =
+     sockets_by_fd_.Lookup(GetHashmapKeyFromIntptr(fd),
+                           GetHashmapHashFromIntptr(fd), false);
+  if (entry == NULL) {
+    return NULL;
+  }
+  return reinterpret_cast<OSSocket*>(entry->value);
+}
+
+
+void ListeningSocketRegistry::InsertByFd(intptr_t fd, OSSocket* socket) {
+  HashMap::Entry* entry =
+     sockets_by_fd_.Lookup(GetHashmapKeyFromIntptr(fd),
+                           GetHashmapHashFromIntptr(fd), true);
+  ASSERT(entry != NULL);
+  entry->value = reinterpret_cast<void*>(socket);
+}
+
+
+void ListeningSocketRegistry::RemoveByFd(intptr_t fd) {
+  sockets_by_fd_.Remove(
+      GetHashmapKeyFromIntptr(fd), GetHashmapHashFromIntptr(fd));
+}
+
+
 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object,
                                                       RawAddr addr,
                                                       intptr_t backlog,
@@ -52,18 +108,12 @@
   MutexLocker ml(ListeningSocketRegistry::mutex_);
 
   intptr_t port = SocketAddress::GetAddrPort(addr);
-
-  SocketsIterator it = sockets_by_port_.find(port);
-  OSSocket *first_os_socket = NULL;
-  if (it != sockets_by_port_.end()) {
-    first_os_socket = it->second;
-  }
-
+  OSSocket* first_os_socket = LookupByPort(port);
   if (first_os_socket != NULL) {
     // There is already a socket listening on this port. We need to ensure
     // that if there is one also listening on the same address, it was created
     // with `shared = true`, ...
-    OSSocket *os_socket = it->second;
+    OSSocket *os_socket = first_os_socket;
     OSSocket *os_socket_same_addr = findOSSocketWithAddress(os_socket, addr);
 
     if (os_socket_same_addr != NULL) {
@@ -117,8 +167,9 @@
       new OSSocket(addr, allocated_port, v6_only, shared, socketfd);
   os_socket->ref_count = 1;
   os_socket->next = first_os_socket;
-  sockets_by_port_[allocated_port] = os_socket;
-  sockets_by_fd_[socketfd] = os_socket;
+
+  InsertByPort(allocated_port, os_socket);
+  InsertByFd(socketfd, os_socket);
 
   // We set as a side-effect the port on the dart socket_object.
   Socket::SetSocketIdNativeField(socket_object, socketfd);
@@ -127,42 +178,57 @@
 }
 
 
+bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket) {
+  ASSERT(!mutex_->TryLock());
+  ASSERT(os_socket != NULL);
+  ASSERT(os_socket->ref_count > 0);
+  os_socket->ref_count--;
+  if (os_socket->ref_count > 0) {
+    return false;
+  }
+  // We free the OS socket by removing it from two datastructures.
+  RemoveByFd(os_socket->socketfd);
+
+  OSSocket* prev = NULL;
+  OSSocket* current = LookupByPort(os_socket->port);
+  while (current != os_socket) {
+    ASSERT(current != NULL);
+    prev = current;
+    current = current->next;
+  }
+
+  if ((prev == NULL) && (current->next == NULL)) {
+    // Remove last element from the list.
+    RemoveByPort(os_socket->port);
+  } else if (prev == NULL) {
+    // Remove first element of the list.
+    InsertByPort(os_socket->port, current->next);
+  } else {
+    // Remove element from the list which is not the first one.
+    prev->next = os_socket->next;
+  }
+
+  ASSERT(os_socket->ref_count == 0);
+  delete os_socket;
+  return true;
+}
+
+
+void ListeningSocketRegistry::CloseAllSafe() {
+  MutexLocker ml(mutex_);
+  for (HashMap::Entry* p = sockets_by_fd_.Start();
+       p != NULL;
+       p = sockets_by_fd_.Next(p)) {
+    CloseOneSafe(reinterpret_cast<OSSocket*>(p->value));
+  }
+}
+
+
 bool ListeningSocketRegistry::CloseSafe(intptr_t socketfd) {
   ASSERT(!mutex_->TryLock());
-
-  SocketsIterator it = sockets_by_fd_.find(socketfd);
-  if (it != sockets_by_fd_.end()) {
-    OSSocket *os_socket = it->second;
-
-    ASSERT(os_socket->ref_count > 0);
-    os_socket->ref_count--;
-    if (os_socket->ref_count == 0) {
-      // We free the OS socket by removing it from two datastructures.
-      sockets_by_fd_.erase(socketfd);
-
-      OSSocket *prev = NULL;
-      OSSocket *current = sockets_by_port_[os_socket->port];
-      while (current != os_socket) {
-        ASSERT(current != NULL);
-        prev = current;
-        current = current->next;
-      }
-
-      if ((prev == NULL) && (current->next == NULL)) {
-        // Remove last element from the list.
-        sockets_by_port_.erase(os_socket->port);
-      } else if (prev == NULL) {
-        // Remove first element of the list.
-        sockets_by_port_[os_socket->port] = current->next;
-      } else {
-        // Remove element from the list which is not the first one.
-        prev->next = os_socket->next;
-      }
-
-      delete os_socket;
-      return true;
-    }
-    return false;
+  OSSocket* os_socket = LookupByFd(socketfd);
+  if (os_socket != NULL) {
+    return CloseOneSafe(os_socket);
   } else {
     // It should be impossible for the event handler to close something that
     // hasn't been created before.
@@ -234,6 +300,12 @@
   }
 }
 
+void FUNCTION_NAME(Socket_IsBindError)(Dart_NativeArguments args) {
+  intptr_t error_number =
+      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
+  bool is_bind_error = Socket::IsBindError(error_number);
+  Dart_SetReturnValue(args, is_bind_error ? Dart_True() : Dart_False());
+}
 
 void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) {
   RawAddr addr;
@@ -268,12 +340,11 @@
 
 
 void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
-  static bool short_socket_reads = Dart_IsVMFlagSet("short_socket_read");
   intptr_t socket =
       Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
   int64_t length = 0;
   if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
-    if (short_socket_reads) {
+    if (short_socket_read) {
       length = (length + 1) / 2;
     }
     uint8_t* buffer = NULL;
@@ -384,7 +455,6 @@
 
 
 void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) {
-  static bool short_socket_writes = Dart_IsVMFlagSet("short_socket_write");
   intptr_t socket =
       Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
   Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
@@ -394,7 +464,7 @@
   intptr_t length =
       DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
   bool short_write = false;
-  if (short_socket_writes) {
+  if (short_socket_write) {
     if (length > 1) {
       short_write = true;
     }
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index bd8ed4b..ea8dade 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -13,6 +13,8 @@
 // Declare the OS-specific types ahead of defining the generic class.
 #if defined(TARGET_OS_ANDROID)
 #include "bin/socket_android.h"
+#elif defined(TARGET_OS_FUCHSIA)
+#include "bin/socket_fuchsia.h"
 #elif defined(TARGET_OS_LINUX)
 #include "bin/socket_linux.h"
 #elif defined(TARGET_OS_MACOS)
@@ -23,12 +25,11 @@
 #error Unknown target os.
 #endif
 
-#include <map>
-
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
 #include "bin/thread.h"
 #include "bin/utils.h"
+#include "platform/hashmap.h"
 
 namespace dart {
 namespace bin {
@@ -276,6 +277,9 @@
   // specified as the port component of the passed RawAddr structure.
   static intptr_t CreateBindConnect(const RawAddr& addr,
                                     const RawAddr& source_addr);
+  // Returns true if the given error-number is because the system was not able
+  // to bind the socket to a specific IP.
+  static bool IsBindError(intptr_t error_number);
   // Creates a datagram socket which is bound. The port to bind
   // to is specified as the port component of the RawAddr structure.
   static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress);
@@ -367,40 +371,24 @@
 
 
 class ListeningSocketRegistry {
- private:
-  struct OSSocket {
-    RawAddr address;
-    int port;
-    bool v6_only;
-    bool shared;
-    int ref_count;
-    intptr_t socketfd;
-
-    // Singly linked lists of OSSocket instances which listen on the same port
-    // but on different addresses.
-    OSSocket *next;
-
-    OSSocket(RawAddr address, int port, bool v6_only, bool shared,
-             intptr_t socketfd)
-        : address(address), port(port), v6_only(v6_only), shared(shared),
-          ref_count(0), socketfd(socketfd), next(NULL) {}
-  };
-
  public:
+  ListeningSocketRegistry() :
+      sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
+      sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
+      mutex_(new Mutex()) {}
+
+  ~ListeningSocketRegistry() {
+    CloseAllSafe();
+    delete mutex_;
+    mutex_ = NULL;
+  }
+
   static void Initialize();
 
   static ListeningSocketRegistry *Instance();
 
   static void Cleanup();
 
-
-  ListeningSocketRegistry() : mutex_(new Mutex()) {}
-
-  ~ListeningSocketRegistry() {
-    delete mutex_;
-    mutex_ = NULL;
-  }
-
   // This function should be called from a dart runtime call in order to create
   // a new (potentially shared) socket.
   Dart_Handle CreateBindListen(Dart_Handle socket_object,
@@ -422,6 +410,26 @@
   Mutex *mutex() { return mutex_; }
 
  private:
+  struct OSSocket {
+    RawAddr address;
+    int port;
+    bool v6_only;
+    bool shared;
+    int ref_count;
+    intptr_t socketfd;
+
+    // Singly linked lists of OSSocket instances which listen on the same port
+    // but on different addresses.
+    OSSocket *next;
+
+    OSSocket(RawAddr address, int port, bool v6_only, bool shared,
+             intptr_t socketfd)
+        : address(address), port(port), v6_only(v6_only), shared(shared),
+          ref_count(0), socketfd(socketfd), next(NULL) {}
+  };
+
+  static const intptr_t kInitialSocketsCount = 8;
+
   OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) {
     while (current != NULL) {
       if (SocketAddress::AreAddressesEqual(current->address, addr)) {
@@ -432,13 +440,35 @@
     return NULL;
   }
 
-  std::map<intptr_t, OSSocket*> sockets_by_port_;
-  std::map<intptr_t, OSSocket*> sockets_by_fd_;
+  static bool SameIntptrValue(void* key1, void* key2) {
+    return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2);
+  }
+
+  static uint32_t GetHashmapHashFromIntptr(intptr_t i) {
+    return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF);
+  }
+
+
+  static void* GetHashmapKeyFromIntptr(intptr_t i) {
+    return reinterpret_cast<void*>(i + 1);
+  }
+
+  OSSocket* LookupByPort(intptr_t port);
+  void InsertByPort(intptr_t port, OSSocket* socket);
+  void RemoveByPort(intptr_t port);
+
+  OSSocket* LookupByFd(intptr_t fd);
+  void InsertByFd(intptr_t fd, OSSocket* socket);
+  void RemoveByFd(intptr_t fd);
+
+  bool CloseOneSafe(OSSocket* os_socket);
+  void CloseAllSafe();
+
+  HashMap sockets_by_port_;
+  HashMap sockets_by_fd_;
+
   Mutex *mutex_;
 
-  typedef std::map<intptr_t, OSSocket*>::iterator SocketsIterator;
-
- private:
   DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
 };
 
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index b3e3fc4..caddb3a 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -101,6 +101,12 @@
 }
 
 
+bool Socket::IsBindError(intptr_t error_number) {
+  return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
+      error_number == EINVAL;
+}
+
+
 intptr_t Socket::Available(intptr_t fd) {
   return FDUtils::AvailableBytes(fd);
 }
diff --git a/runtime/bin/socket_fuchsia.cc b/runtime/bin/socket_fuchsia.cc
new file mode 100644
index 0000000..b79d1c0
--- /dev/null
+++ b/runtime/bin/socket_fuchsia.cc
@@ -0,0 +1,248 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if !defined(DART_IO_DISABLED)
+
+#include "platform/globals.h"
+#if defined(TARGET_OS_FUCHSIA)
+
+#include "bin/socket.h"
+#include "bin/socket_fuchsia.h"
+
+#include "bin/file.h"
+
+namespace dart {
+namespace bin {
+
+SocketAddress::SocketAddress(struct sockaddr* sa) {
+  UNIMPLEMENTED();
+}
+
+
+bool Socket::FormatNumericAddress(const RawAddr& addr, char* address, int len) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::Initialize() {
+  UNIMPLEMENTED();
+  return true;
+}
+
+
+intptr_t Socket::CreateConnect(const RawAddr& addr) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+intptr_t Socket::CreateBindConnect(const RawAddr& addr,
+                                   const RawAddr& source_addr) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+bool Socket::IsBindError(intptr_t error_number) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+intptr_t Socket::Available(intptr_t fd) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+intptr_t Socket::RecvFrom(
+    intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+intptr_t Socket::SendTo(
+    intptr_t fd, const void* buffer, intptr_t num_bytes, const RawAddr& addr) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+intptr_t Socket::GetPort(intptr_t fd) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Socket::GetError(intptr_t fd, OSError* os_error) {
+  UNIMPLEMENTED();
+}
+
+
+int Socket::GetType(intptr_t fd) {
+  UNIMPLEMENTED();
+  return File::kOther;
+}
+
+
+intptr_t Socket::GetStdioHandle(intptr_t num) {
+  UNIMPLEMENTED();
+  return num;
+}
+
+
+AddressList<SocketAddress>* Socket::LookupAddress(const char* host,
+                                                  int type,
+                                                  OSError** os_error) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+bool Socket::ReverseLookup(const RawAddr& addr,
+                           char* host,
+                           intptr_t host_len,
+                           OSError** os_error) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+bool Socket::ListInterfacesSupported() {
+  return false;
+}
+
+
+AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
+    int type,
+    OSError** os_error) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+intptr_t ServerSocket::CreateBindListen(const RawAddr& addr,
+                                        intptr_t backlog,
+                                        bool v6_only) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+bool ServerSocket::StartAccept(intptr_t fd) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+intptr_t ServerSocket::Accept(intptr_t fd) {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+void Socket::Close(intptr_t fd) {
+  UNIMPLEMENTED();
+}
+
+
+bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::GetBroadcast(intptr_t fd, bool* enabled) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::SetBroadcast(intptr_t fd, bool enabled) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::JoinMulticast(
+    intptr_t fd, const RawAddr& addr, const RawAddr&, int interfaceIndex) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+bool Socket::LeaveMulticast(
+    intptr_t fd, const RawAddr& addr, const RawAddr&, int interfaceIndex) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
+
+#endif  // !defined(DART_IO_DISABLED)
diff --git a/runtime/bin/socket_fuchsia.h b/runtime/bin/socket_fuchsia.h
new file mode 100644
index 0000000..82f8916
--- /dev/null
+++ b/runtime/bin/socket_fuchsia.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef BIN_SOCKET_FUCHSIA_H_
+#define BIN_SOCKET_FUCHSIA_H_
+
+#if !defined(BIN_SOCKET_H_)
+#error Do not include socket_fuchsia.h directly. Use socket.h.
+#endif
+
+#endif  // BIN_SOCKET_FUCHSIA_H_
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 6393567..fc0f1e4 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -101,6 +101,12 @@
 }
 
 
+bool Socket::IsBindError(intptr_t error_number) {
+  return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
+      error_number == EINVAL;
+}
+
+
 intptr_t Socket::Available(intptr_t fd) {
   return FDUtils::AvailableBytes(fd);
 }
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 708cd3c..e54cc59 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -58,6 +58,7 @@
     return -1;
   }
   FDUtils::SetCloseOnExec(fd);
+  FDUtils::SetNonBlocking(fd);
   return fd;
 }
 
@@ -79,8 +80,6 @@
     return fd;
   }
 
-  FDUtils::SetNonBlocking(fd);
-
   return Connect(fd, addr);
 }
 
@@ -103,6 +102,12 @@
 }
 
 
+bool Socket::IsBindError(intptr_t error_number) {
+  return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
+      error_number == EINVAL;
+}
+
+
 intptr_t Socket::Available(intptr_t fd) {
   return FDUtils::AvailableBytes(fd);
 }
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 2d3ba73..0244e79 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch class RawServerSocket {
-  /* patch */ static Future<RawServerSocket> bind(address,
+@patch class RawServerSocket {
+  @patch static Future<RawServerSocket> bind(address,
                                                   int port,
                                                   {int backlog: 0,
                                                    bool v6Only: false,
@@ -13,52 +13,52 @@
 }
 
 
-patch class RawSocket {
-  /* patch */ static Future<RawSocket> connect(
+@patch class RawSocket {
+  @patch static Future<RawSocket> connect(
       host, int port, {sourceAddress}) {
     return _RawSocket.connect(host, port, sourceAddress);
   }
 }
 
 
-patch class InternetAddress {
-  /* patch */ static InternetAddress get LOOPBACK_IP_V4 {
+@patch class InternetAddress {
+  @patch static InternetAddress get LOOPBACK_IP_V4 {
     return _InternetAddress.LOOPBACK_IP_V4;
   }
 
-  /* patch */ static InternetAddress get LOOPBACK_IP_V6 {
+  @patch static InternetAddress get LOOPBACK_IP_V6 {
     return _InternetAddress.LOOPBACK_IP_V6;
   }
 
-  /* patch */ static InternetAddress get ANY_IP_V4 {
+  @patch static InternetAddress get ANY_IP_V4 {
     return _InternetAddress.ANY_IP_V4;
   }
 
-  /* patch */ static InternetAddress get ANY_IP_V6 {
+  @patch static InternetAddress get ANY_IP_V6 {
     return _InternetAddress.ANY_IP_V6;
   }
 
-  /* patch */ factory InternetAddress(String address) {
+  @patch factory InternetAddress(String address) {
     return new _InternetAddress.parse(address);
   }
 
-  /* patch */ static Future<List<InternetAddress>> lookup(
+  @patch static Future<List<InternetAddress>> lookup(
       String host, {InternetAddressType type: InternetAddressType.ANY}) {
     return _NativeSocket.lookup(host, type: type);
   }
 
-  /* patch */ static InternetAddress _cloneWithNewHost(
+  @patch static InternetAddress _cloneWithNewHost(
       InternetAddress address, String host) {
     return (address as _InternetAddress)._cloneWithNewHost(host);
   }
 }
 
-patch class NetworkInterface {
-  /* patch */ static bool get listSupported {
+@patch class NetworkInterface {
+  @patch static bool get listSupported {
     return _listSupported();
   }
 
-  /* patch */ static Future<List<NetworkInterface>> list({
+  @patch static Future<List<NetworkInterface>> list({
       bool includeLoopback: false,
       bool includeLinkLocal: false,
       InternetAddressType type: InternetAddressType.ANY}) {
@@ -431,7 +431,13 @@
             if (result is OSError) {
               // Keep first error, if present.
               if (error == null) {
-                error = createError(result, "Connection failed", address, port);
+                int errorCode = result.errorCode;
+                if (errorCode != null && socket.isBindError(errorCode)) {
+                  error = createError(result, "Bind failed", sourceAddress);
+                } else {
+                  error =
+                      createError(result, "Connection failed", address, port);
+                }
               }
               connectNext();
             } else {
@@ -1075,6 +1081,7 @@
   nativeCreateBindConnect(
       List<int> addr, int port, List<int> sourceAddr)
       native "Socket_CreateBindConnect";
+  bool isBindError(int errorNumber) native "Socket_IsBindError";
   nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only,
                          bool shared)
       native "ServerSocket_CreateBindListen";
@@ -1088,7 +1095,7 @@
   nativeGetOption(int option, int protocol) native "Socket_GetOption";
   bool nativeSetOption(int option, int protocol, value)
       native "Socket_SetOption";
-  bool nativeJoinMulticast(
+  OSError nativeJoinMulticast(
       List<int> addr, List<int> interfaceAddr, int interfaceIndex)
           native "Socket_JoinMulticast";
   bool nativeLeaveMulticast(
@@ -1353,8 +1360,8 @@
 }
 
 
-patch class ServerSocket {
-  /* patch */ static Future<ServerSocket> bind(address,
+@patch class ServerSocket {
+  @patch static Future<ServerSocket> bind(address,
                                                int port,
                                                {int backlog: 0,
                                                 bool v6Only: false,
@@ -1400,8 +1407,8 @@
 }
 
 
-patch class Socket {
-  /* patch */ static Future<Socket> connect(host, int port, {sourceAddress}) {
+@patch class Socket {
+  @patch static Future<Socket> connect(host, int port, {sourceAddress}) {
     return RawSocket.connect(host, port, sourceAddress: sourceAddress).then(
         (socket) => new _Socket(socket));
   }
@@ -1713,8 +1720,8 @@
 }
 
 
-patch class RawDatagramSocket {
-  /* patch */ static Future<RawDatagramSocket> bind(
+@patch class RawDatagramSocket {
+  @patch static Future<RawDatagramSocket> bind(
       host, int port, {bool reuseAddress: true}) {
     return _RawDatagramSocket.bind(host, port, reuseAddress);
   }
diff --git a/runtime/bin/socket_unsupported.cc b/runtime/bin/socket_unsupported.cc
index 0ea27f1..d3ecf1e 100644
--- a/runtime/bin/socket_unsupported.cc
+++ b/runtime/bin/socket_unsupported.cc
@@ -11,6 +11,10 @@
 namespace dart {
 namespace bin {
 
+bool short_socket_read = false;
+
+bool short_socket_write = false;
+
 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
   Dart_ThrowException(DartUtils::NewDartArgumentError(
       "Sockets unsupported on this platform"));
@@ -35,6 +39,12 @@
 }
 
 
+void FUNCTION_NAME(Socket_IsBindError)(Dart_NativeArguments args) {
+  Dart_ThrowException(DartUtils::NewDartArgumentError(
+      "Sockets unsupported on this platform"));
+}
+
+
 void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) {
   Dart_ThrowException(DartUtils::NewDartArgumentError(
       "Sockets unsupported on this platform"));
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index e3d366d..f76f764 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -250,6 +250,12 @@
 }
 
 
+bool Socket::IsBindError(intptr_t error_number) {
+  return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL ||
+      error_number == WSAEINVAL;
+}
+
+
 void Socket::GetError(intptr_t fd, OSError* os_error) {
   Handle* handle = reinterpret_cast<Handle*>(fd);
   os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error());
diff --git a/runtime/bin/stdio_fuchsia.cc b/runtime/bin/stdio_fuchsia.cc
new file mode 100644
index 0000000..e297499
--- /dev/null
+++ b/runtime/bin/stdio_fuchsia.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if !defined(DART_IO_DISABLED)
+
+#include "platform/globals.h"
+#if defined(TARGET_OS_FUCHSIA)
+
+#include "bin/stdio.h"
+
+namespace dart {
+namespace bin {
+
+int Stdin::ReadByte() {
+  UNIMPLEMENTED();
+  return -1;
+}
+
+
+bool Stdin::GetEchoMode() {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+void Stdin::SetEchoMode(bool enabled) {
+  UNIMPLEMENTED();
+}
+
+
+bool Stdin::GetLineMode() {
+  UNIMPLEMENTED();
+  return false;
+}
+
+
+void Stdin::SetLineMode(bool enabled) {
+  UNIMPLEMENTED();
+}
+
+
+bool Stdout::GetTerminalSize(intptr_t fd, int size[2]) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
+
+#endif  // !defined(DART_IO_DISABLED)
diff --git a/runtime/bin/stdio_patch.dart b/runtime/bin/stdio_patch.dart
index cf02819..b3dc68e 100644
--- a/runtime/bin/stdio_patch.dart
+++ b/runtime/bin/stdio_patch.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.
 
-patch class _StdIOUtils {
+@patch class _StdIOUtils {
   static Stdin _getStdioInputStream() {
     switch (_getStdioHandleType(0)) {
       case _STDIO_HANDLE_TYPE_TERMINAL:
@@ -46,14 +46,14 @@
   static _getStdioHandleType(int fd) native "File_GetStdioHandleType";
 }
 
-patch class Stdin {
-  /* patch */ int readByteSync() native "Stdin_ReadByte";
+@patch class Stdin {
+  @patch int readByteSync() native "Stdin_ReadByte";
 
-  /* patch */ bool get echoMode => _echoMode;
-  /* patch */ void set echoMode(bool enabled) { _echoMode = enabled; }
+  @patch bool get echoMode => _echoMode;
+  @patch void set echoMode(bool enabled) { _echoMode = enabled; }
 
-  /* patch */ bool get lineMode => _lineMode;
-  /* patch */ void set lineMode(bool enabled) { _lineMode = enabled; }
+  @patch bool get lineMode => _lineMode;
+  @patch void set lineMode(bool enabled) { _lineMode = enabled; }
 
   static bool get _echoMode native "Stdin_GetEchoMode";
   static void set _echoMode(bool enabled) native "Stdin_SetEchoMode";
@@ -61,8 +61,8 @@
   static void set _lineMode(bool enabled) native "Stdin_SetLineMode";
 }
 
-patch class Stdout {
-  /* patch */ bool _hasTerminal(int fd) {
+@patch class Stdout {
+  @patch bool _hasTerminal(int fd) {
     try {
       _terminalSize(fd);
       return true;
@@ -71,8 +71,8 @@
     }
   }
 
-  /* patch */ int _terminalColumns(int fd) => _terminalSize(fd)[0];
-  /* patch */ int _terminalLines(int fd) => _terminalSize(fd)[1];
+  @patch int _terminalColumns(int fd) => _terminalSize(fd)[0];
+  @patch int _terminalLines(int fd) => _terminalSize(fd)[1];
 
   static List _terminalSize(int fd) {
     var size = _getTerminalSize(fd);
diff --git a/runtime/bin/thread.h b/runtime/bin/thread.h
index 979c77f..37a4b9f 100644
--- a/runtime/bin/thread.h
+++ b/runtime/bin/thread.h
@@ -18,6 +18,8 @@
 // Declare the OS-specific types ahead of defining the generic classes.
 #if defined(TARGET_OS_ANDROID)
 #include "bin/thread_android.h"
+#elif defined(TARGET_OS_FUCHSIA)
+#include "bin/thread_fuchsia.h"
 #elif defined(TARGET_OS_LINUX)
 #include "bin/thread_linux.h"
 #elif defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/thread_fuchsia.cc b/runtime/bin/thread_fuchsia.cc
new file mode 100644
index 0000000..57f4cd0
--- /dev/null
+++ b/runtime/bin/thread_fuchsia.cc
@@ -0,0 +1,331 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_FUCHSIA)
+
+#include "bin/thread.h"
+#include "bin/thread_fuchsia.h"
+
+#include <errno.h>  // NOLINT
+#include <sys/resource.h>  // NOLINT
+#include <sys/time.h>  // NOLINT
+
+#include "platform/assert.h"
+#include "platform/utils.h"
+
+namespace dart {
+namespace bin {
+
+#define VALIDATE_PTHREAD_RESULT(result) \
+  if (result != 0) { \
+    const int kBufferSize = 1024; \
+    char error_buf[kBufferSize]; \
+    FATAL2("pthread error: %d (%s)", result, \
+           Utils::StrError(result, error_buf, kBufferSize)); \
+  }
+
+
+#ifdef DEBUG
+#define RETURN_ON_PTHREAD_FAILURE(result) \
+  if (result != 0) { \
+    const int kBufferSize = 1024; \
+    char error_buf[kBufferSize]; \
+    fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
+            __FILE__, __LINE__, result, \
+            Utils::StrError(result, error_buf, kBufferSize)); \
+    return result; \
+  }
+#else
+#define RETURN_ON_PTHREAD_FAILURE(result) \
+  if (result != 0) { \
+    return result; \
+  }
+#endif
+
+
+static void ComputeTimeSpecMicros(struct timespec* ts, int64_t micros) {
+  int64_t secs = micros / kMicrosecondsPerSecond;
+  int64_t nanos =
+      (micros - (secs * kMicrosecondsPerSecond)) * kNanosecondsPerMicrosecond;
+  int result = clock_gettime(CLOCK_MONOTONIC, ts);
+  ASSERT(result == 0);
+  ts->tv_sec += secs;
+  ts->tv_nsec += nanos;
+  if (ts->tv_nsec >= kNanosecondsPerSecond) {
+    ts->tv_sec += 1;
+    ts->tv_nsec -= kNanosecondsPerSecond;
+  }
+}
+
+
+class ThreadStartData {
+ public:
+  ThreadStartData(Thread::ThreadStartFunction function,
+                  uword parameter)
+      : function_(function), parameter_(parameter) {}
+
+  Thread::ThreadStartFunction function() const { return function_; }
+  uword parameter() const { return parameter_; }
+
+ private:
+  Thread::ThreadStartFunction function_;
+  uword parameter_;
+
+  DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
+};
+
+
+// Dispatch to the thread start function provided by the caller. This trampoline
+// is used to ensure that the thread is properly destroyed if the thread just
+// exits.
+static void* ThreadStart(void* data_ptr) {
+  ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
+
+  Thread::ThreadStartFunction function = data->function();
+  uword parameter = data->parameter();
+  delete data;
+
+  // Call the supplied thread start function handing it its parameters.
+  function(parameter);
+
+  return NULL;
+}
+
+
+int Thread::Start(ThreadStartFunction function, uword parameter) {
+  pthread_attr_t attr;
+  int result = pthread_attr_init(&attr);
+  RETURN_ON_PTHREAD_FAILURE(result);
+
+  result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+  RETURN_ON_PTHREAD_FAILURE(result);
+
+  result = pthread_attr_setstacksize(&attr, Thread::GetMaxStackSize());
+  RETURN_ON_PTHREAD_FAILURE(result);
+
+  ThreadStartData* data = new ThreadStartData(function, parameter);
+
+  pthread_t tid;
+  result = pthread_create(&tid, &attr, ThreadStart, data);
+  RETURN_ON_PTHREAD_FAILURE(result);
+
+  result = pthread_attr_destroy(&attr);
+  RETURN_ON_PTHREAD_FAILURE(result);
+
+  return 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;
+  int result = pthread_key_create(&key, NULL);
+  VALIDATE_PTHREAD_RESULT(result);
+  ASSERT(key != kUnsetThreadLocalKey);
+  return key;
+}
+
+
+void Thread::DeleteThreadLocal(ThreadLocalKey key) {
+  ASSERT(key != kUnsetThreadLocalKey);
+  int result = pthread_key_delete(key);
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+void Thread::SetThreadLocal(ThreadLocalKey key, uword value) {
+  ASSERT(key != kUnsetThreadLocalKey);
+  int result = pthread_setspecific(key, reinterpret_cast<void*>(value));
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+intptr_t Thread::GetMaxStackSize() {
+  const int kStackSize = (128 * kWordSize * KB);
+  return kStackSize;
+}
+
+
+ThreadId Thread::GetCurrentThreadId() {
+  return pthread_self();
+}
+
+
+intptr_t Thread::ThreadIdToIntPtr(ThreadId id) {
+  ASSERT(sizeof(id) == sizeof(intptr_t));
+  return static_cast<intptr_t>(id);
+}
+
+
+bool Thread::Compare(ThreadId a, ThreadId b) {
+  return (pthread_equal(a, b) != 0);
+}
+
+
+void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
+  UNIMPLEMENTED();
+}
+
+
+void Thread::InitOnce() {
+  // Nothing to be done.
+}
+
+
+Mutex::Mutex() {
+  pthread_mutexattr_t attr;
+  int result = pthread_mutexattr_init(&attr);
+  VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+  VALIDATE_PTHREAD_RESULT(result);
+#endif  // defined(DEBUG)
+
+  result = pthread_mutex_init(data_.mutex(), &attr);
+  // Verify that creating a pthread_mutex succeeded.
+  VALIDATE_PTHREAD_RESULT(result);
+
+  result = pthread_mutexattr_destroy(&attr);
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+Mutex::~Mutex() {
+  int result = pthread_mutex_destroy(data_.mutex());
+  // Verify that the pthread_mutex was destroyed.
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+void Mutex::Lock() {
+  int result = pthread_mutex_lock(data_.mutex());
+  // Specifically check for dead lock to help debugging.
+  ASSERT(result != EDEADLK);
+  ASSERT(result == 0);  // Verify no other errors.
+  // TODO(iposva): Do we need to track lock owners?
+}
+
+
+bool Mutex::TryLock() {
+  int result = pthread_mutex_trylock(data_.mutex());
+  // Return false if the lock is busy and locking failed.
+  if (result == EBUSY) {
+    return false;
+  }
+  ASSERT(result == 0);  // Verify no other errors.
+  // TODO(iposva): Do we need to track lock owners?
+  return true;
+}
+
+
+void Mutex::Unlock() {
+  // TODO(iposva): Do we need to track lock owners?
+  int result = pthread_mutex_unlock(data_.mutex());
+  // Specifically check for wrong thread unlocking to aid debugging.
+  ASSERT(result != EPERM);
+  ASSERT(result == 0);  // Verify no other errors.
+}
+
+
+Monitor::Monitor() {
+  pthread_mutexattr_t mutex_attr;
+  int result = pthread_mutexattr_init(&mutex_attr);
+  VALIDATE_PTHREAD_RESULT(result);
+
+#if defined(DEBUG)
+  result = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
+  VALIDATE_PTHREAD_RESULT(result);
+#endif  // defined(DEBUG)
+
+  result = pthread_mutex_init(data_.mutex(), &mutex_attr);
+  VALIDATE_PTHREAD_RESULT(result);
+
+  result = pthread_mutexattr_destroy(&mutex_attr);
+  VALIDATE_PTHREAD_RESULT(result);
+
+  pthread_condattr_t cond_attr;
+  result = pthread_condattr_init(&cond_attr);
+  VALIDATE_PTHREAD_RESULT(result);
+
+  result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
+  VALIDATE_PTHREAD_RESULT(result);
+
+  result = pthread_cond_init(data_.cond(), &cond_attr);
+  VALIDATE_PTHREAD_RESULT(result);
+
+  result = pthread_condattr_destroy(&cond_attr);
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+Monitor::~Monitor() {
+  int result = pthread_mutex_destroy(data_.mutex());
+  VALIDATE_PTHREAD_RESULT(result);
+
+  result = pthread_cond_destroy(data_.cond());
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+void Monitor::Enter() {
+  int result = pthread_mutex_lock(data_.mutex());
+  VALIDATE_PTHREAD_RESULT(result);
+  // TODO(iposva): Do we need to track lock owners?
+}
+
+
+void Monitor::Exit() {
+  // TODO(iposva): Do we need to track lock owners?
+  int result = pthread_mutex_unlock(data_.mutex());
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+Monitor::WaitResult Monitor::Wait(int64_t millis) {
+  return WaitMicros(millis * kMicrosecondsPerMillisecond);
+}
+
+
+Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
+  // TODO(iposva): Do we need to track lock owners?
+  Monitor::WaitResult retval = kNotified;
+  if (micros == kNoTimeout) {
+    // Wait forever.
+    int result = pthread_cond_wait(data_.cond(), data_.mutex());
+    VALIDATE_PTHREAD_RESULT(result);
+  } else {
+    struct timespec ts;
+    ComputeTimeSpecMicros(&ts, micros);
+    int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts);
+    ASSERT((result == 0) || (result == ETIMEDOUT));
+    if (result == ETIMEDOUT) {
+      retval = kTimedOut;
+    }
+  }
+  return retval;
+}
+
+
+void Monitor::Notify() {
+  // TODO(iposva): Do we need to track lock owners?
+  int result = pthread_cond_signal(data_.cond());
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+
+void Monitor::NotifyAll() {
+  // TODO(iposva): Do we need to track lock owners?
+  int result = pthread_cond_broadcast(data_.cond());
+  VALIDATE_PTHREAD_RESULT(result);
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/thread_fuchsia.h b/runtime/bin/thread_fuchsia.h
new file mode 100644
index 0000000..6168719
--- /dev/null
+++ b/runtime/bin/thread_fuchsia.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_THREAD_FUCHSIA_H_
+#define BIN_THREAD_FUCHSIA_H_
+
+#if !defined(BIN_THREAD_H_)
+#error Do not include thread_fuchsia.h directly; use thread.h instead.
+#endif
+
+#include <pthread.h>
+
+#include "platform/assert.h"
+#include "platform/globals.h"
+
+namespace dart {
+namespace bin {
+
+typedef pthread_key_t ThreadLocalKey;
+typedef pthread_t ThreadId;
+
+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));
+  }
+
+  friend class Thread;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_COPY_AND_ASSIGN(ThreadInlineImpl);
+};
+
+
+class MutexData {
+ private:
+  MutexData() {}
+  ~MutexData() {}
+
+  pthread_mutex_t* mutex() { return &mutex_; }
+
+  pthread_mutex_t mutex_;
+
+  friend class Mutex;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_COPY_AND_ASSIGN(MutexData);
+};
+
+
+class MonitorData {
+ private:
+  MonitorData() {}
+  ~MonitorData() {}
+
+  pthread_mutex_t* mutex() { return &mutex_; }
+  pthread_cond_t* cond() { return &cond_; }
+
+  pthread_mutex_t mutex_;
+  pthread_cond_t cond_;
+
+  friend class Monitor;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_COPY_AND_ASSIGN(MonitorData);
+};
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // BIN_THREAD_FUCHSIA_H_
diff --git a/runtime/bin/utils_fuchsia.cc b/runtime/bin/utils_fuchsia.cc
new file mode 100644
index 0000000..1df2aba
--- /dev/null
+++ b/runtime/bin/utils_fuchsia.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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_FUCHSIA)
+
+#include <errno.h>
+#include <magenta/syscalls.h>
+#include <magenta/types.h>
+
+#include "bin/utils.h"
+#include "platform/assert.h"
+#include "platform/utils.h"
+
+namespace dart {
+namespace bin {
+
+OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
+  set_sub_system(kSystem);
+  set_code(errno);
+  const int kBufferSize = 1024;
+  char error_buf[kBufferSize];
+  SetMessage(Utils::StrError(errno, error_buf, kBufferSize));
+}
+
+
+void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
+  set_sub_system(sub_system);
+  set_code(code);
+  if (sub_system == kSystem) {
+    const int kBufferSize = 1024;
+    char error_buf[kBufferSize];
+    SetMessage(Utils::StrError(code, error_buf, kBufferSize));
+  } else if (sub_system == kGetAddressInfo) {
+    UNIMPLEMENTED();
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+const char* StringUtils::ConsoleStringToUtf8(
+    const char* str, intptr_t len, intptr_t* result_len) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+const char* StringUtils::Utf8ToConsoleString(
+    const char* utf8, intptr_t len, intptr_t* result_len) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+char* StringUtils::ConsoleStringToUtf8(
+    char* str, intptr_t len, intptr_t* result_len) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+char* StringUtils::Utf8ToConsoleString(
+    char* utf8, intptr_t len, intptr_t* result_len) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+bool ShellUtils::GetUtf8Argv(int argc, char** argv) {
+  return false;
+}
+
+
+void TimerUtils::InitOnce() {
+}
+
+
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
+}
+
+
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+  int64_t ticks = mx_current_time();
+  return ticks / kNanosecondsPerMicrosecond;
+}
+
+
+void TimerUtils::Sleep(int64_t millis) {
+  mx_nanosleep(
+      millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond);
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // defined(TARGET_OS_FUCHSIA)
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 7686f1c..8af63b5 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -319,10 +319,11 @@
 void _sendResourceResponse(SendPort sp,
                            int tag,
                            Uri uri,
+                           Uri resolvedUri,
                            String libraryUrl,
                            dynamic data) {
   assert((data is List<int>) || (data is String));
-  var msg = new List(4);
+  var msg = new List(5);
   if (data is String) {
     // We encountered an error, flip the sign of the tag to indicate that.
     tag = -tag;
@@ -334,8 +335,9 @@
   }
   msg[0] = tag;
   msg[1] = uri.toString();
-  msg[2] = libraryUrl;
-  msg[3] = data;
+  msg[2] = resolvedUri.toString();
+  msg[3] = libraryUrl;
+  msg[4] = data;
   sp.send(msg);
 }
 
@@ -344,7 +346,7 @@
                                   Uri uri,
                                   String libraryUrl,
                                   String resolvedUri) {
-  var msg = new List(4);
+  var msg = new List(5);
   int tag = _Dart_kImportExtension;
   if (resolvedUri == null) {
     // We could not resolve the dart-ext: uri.
@@ -353,8 +355,9 @@
   }
   msg[0] = tag;
   msg[1] = uri.toString();
-  msg[2] = libraryUrl;
-  msg[3] = resolvedUri;
+  msg[2] = resolvedUri;
+  msg[3] = libraryUrl;
+  msg[4] = resolvedUri;
   sp.send(msg);
 }
 
@@ -376,18 +379,20 @@
             if (response.statusCode != 200) {
               var msg = "Failure getting $resolvedUri:\n"
                         "  ${response.statusCode} ${response.reasonPhrase}";
-              _sendResourceResponse(sp, tag, uri, libraryUrl, msg);
+              _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, msg);
             } else {
-              _sendResourceResponse(sp, tag, uri, libraryUrl,
+              _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl,
                                     builder.takeBytes());
             }
           },
           onError: (e) {
-            _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
+            _sendResourceResponse(
+                sp, tag, uri, resolvedUri, libraryUrl, e.toString());
           });
     })
     .catchError((e) {
-      _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
+      _sendResourceResponse(
+        sp, tag, uri, resolvedUri, libraryUrl, e.toString());
     });
   // It's just here to push an event on the event loop so that we invoke the
   // scheduled microtasks.
@@ -402,10 +407,10 @@
   var path = resolvedUri.toFilePath();
   var sourceFile = new File(path);
   sourceFile.readAsBytes().then((data) {
-    _sendResourceResponse(sp, tag, uri, libraryUrl, data);
+    _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, data);
   },
   onError: (e) {
-    _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
+    _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, e.toString());
   });
 }
 
@@ -426,9 +431,10 @@
       // The C++ portion of the embedder assumes UTF-8.
       throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
     }
-    _sendResourceResponse(sp, tag, uri, libraryUrl, uri.data.contentAsBytes());
+    _sendResourceResponse(
+        sp, tag, uri, resolvedUri, libraryUrl, uri.data.contentAsBytes());
   } catch (e) {
-    _sendResourceResponse(sp, tag, uri, libraryUrl,
+    _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl,
                           "Invalid data uri ($uri):\n  $e");
   }
 }
@@ -454,6 +460,7 @@
       _sendResourceResponse(sp,
                             tag,
                             uri,
+                            resolvedUri,
                             libraryUrl,
                             e.toString());
       return;
@@ -517,6 +524,7 @@
   } else {
     _sendResourceResponse(sp, tag,
                           uri,
+                          resolvedUri,
                           libraryUrl,
                           'Unknown scheme (${resolvedUri.scheme}) for '
                           '$resolvedUri');
@@ -883,7 +891,7 @@
   isolateEmbedderData.values.toList().forEach((IsolateLoaderState ils) {
     ils.cleanup();
     assert(ils.sp != null);
-    _sendResourceResponse(ils.sp, 1, null, null, message);
+    _sendResourceResponse(ils.sp, 1, null, null, null, message);
   });
 }
 
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index c8334da..4075e8d 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -105,21 +105,96 @@
   final VMService _service;
   final String _ip;
   final int _port;
-
+  final bool _originCheckDisabled;
+  final List<String> _allowedOrigins = <String>[];
   HttpServer _server;
   bool get running => _server != null;
   bool _displayMessages = false;
 
-  Server(this._service, this._ip, this._port) {
+  Server(this._service, this._ip, this._port, this._originCheckDisabled) {
     _displayMessages = (_ip != '127.0.0.1' || _port != 8181);
   }
 
-  void _requestHandler(HttpRequest request) {
-    // Allow cross origin requests with 'observatory' header.
-    request.response.headers.add('Access-Control-Allow-Origin', '*');
-    request.response.headers.add('Access-Control-Allow-Headers',
-                                 'Observatory-Version');
+  void _addOrigin(String host, String port) {
+    if (port == null) {
+      String origin = 'http://$host';
+      _allowedOrigins.add(origin);
+    } else {
+      String origin = 'http://$host:$port';
+      _allowedOrigins.add(origin);
+    }
+  }
 
+  bool _isAllowedOrigin(String origin) {
+    for (String allowedOrigin in _allowedOrigins) {
+      if (origin.startsWith(allowedOrigin)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool _originCheck(HttpRequest request) {
+    if (_originCheckDisabled) {
+      // Always allow.
+      return true;
+    }
+    // First check the web-socket specific origin.
+    List<String> origins = request.headers["Sec-WebSocket-Origin"];
+    if (origins == null) {
+      // Fall back to the general Origin field.
+      origins = request.headers["Origin"];
+    }
+    if (origins == null) {
+      // No origin sent. This is a non-browser client or a same-origin request.
+      return true;
+    }
+    for (String origin in origins) {
+      if (_isAllowedOrigin(origin)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  Future _requestHandler(HttpRequest request) async {
+    if (!_originCheck(request)) {
+      // This is a cross origin attempt to connect
+      request.response.close();
+      return;
+    }
+    if (request.method == 'PUT') {
+      // PUT requests are forwarded to DevFS for processing.
+
+      List fsNameList;
+      List fsPathList;
+      Object fsName;
+      Object fsPath;
+
+      try {
+        // Extract the fs name and fs path from the request headers.
+        fsNameList = request.headers['dev_fs_name'];
+        fsPathList = request.headers['dev_fs_path'];
+        fsName = fsNameList[0];
+        fsPath = fsPathList[0];
+      } catch (e) { /* ignore */ }
+
+      String result;
+      try {
+        result = await _service.devfs.handlePutStream(
+            fsName,
+            fsPath,
+            request.transform(GZIP.decoder));
+      } catch (e) { /* ignore */ }
+
+      if (result != null) {
+        request.response.headers.contentType =
+            HttpRequestClient.jsonContentType;
+        request.response.write(result);
+      }
+      request.response.close();
+      return;
+    }
     if (request.method != 'GET') {
       // Not a GET request. Do nothing.
       request.response.close();
@@ -130,8 +205,7 @@
           request.uri.path == '/' ? ROOT_REDIRECT_PATH : request.uri.path;
 
     if (path == WEBSOCKET_PATH) {
-      WebSocketTransformer.upgrade(request,
-                                   compression: CompressionOptions.OFF).then(
+      WebSocketTransformer.upgrade(request).then(
                                    (WebSocket webSocket) {
         new WebSocketClient(webSocket, _service);
       });
@@ -165,6 +239,9 @@
       return new Future.value(this);
     }
 
+    // Clear allowed origins.
+    _allowedOrigins.clear();
+
     var address = new InternetAddress(_ip);
     // Startup HTTP server.
     return HttpServer.bind(address, _port).then((s) {
@@ -172,6 +249,13 @@
       _server.listen(_requestHandler, cancelOnError: true);
       var ip = _server.address.address.toString();
       var port = _server.port.toString();
+      // Add the numeric ip and host name to our allowed origins.
+      _addOrigin(ip, port);
+      _addOrigin(_server.address.host.toString(), port);
+      // Explicitly add localhost and 127.0.0.1 on any port (necessary for
+      // adb port forwarding).
+      _addOrigin('127.0.0.1', null);
+      _addOrigin('localhost', null);
       if (_displayMessages) {
         print('Observatory listening on http://$ip:$port');
       }
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 3e1bee4..49e8ad7 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -19,8 +19,10 @@
 String _ip;
 // Should the HTTP server auto start?
 bool _autoStart;
-
+// Should the HTTP server run in devmode?
+bool _originCheckDisabled;
 bool _isWindows = false;
+bool _isFuchsia = false;
 var _signalWatch;
 var _signalSubscription;
 
@@ -35,7 +37,7 @@
   // Lazily create service.
   var service = new VMService();
   // Lazily create server.
-  server = new Server(service, _ip, _port);
+  server = new Server(service, _ip, _port, _originCheckDisabled);
 }
 
 Future cleanupCallback() async {
@@ -70,13 +72,72 @@
   await dir.delete(recursive: true);
 }
 
+class PendingWrite {
+  PendingWrite(this.uri, this.bytes);
+  final Completer completer = new Completer();
+  final Uri uri;
+  final List<int> bytes;
+
+  Future write() async {
+    var file = new File.fromUri(uri);
+    var parent_directory = file.parent;
+    await parent_directory.create(recursive: true);
+    var result = await file.writeAsBytes(bytes);
+    completer.complete(null);
+    WriteLimiter._writeCompleted();
+  }
+}
+
+class WriteLimiter {
+  static final List<PendingWrite> pendingWrites = new List<PendingWrite>();
+
+  // non-rooted Android devices have a very low limit for the number of
+  // open files. Artificially cap ourselves to 16.
+  static const kMaxOpenWrites = 16;
+  static int openWrites = 0;
+
+  static Future scheduleWrite(Uri path, List<int> bytes) async {
+    // Create a new pending write.
+    PendingWrite pw = new PendingWrite(path, bytes);
+    pendingWrites.add(pw);
+    _maybeWriteFiles();
+    return pw.completer.future;
+  }
+
+  static _maybeWriteFiles() {
+    while (openWrites < kMaxOpenWrites) {
+      if (pendingWrites.length > 0) {
+        PendingWrite pw = pendingWrites.removeLast();
+        pw.write();
+        openWrites++;
+      } else {
+        break;
+      }
+    }
+  }
+
+  static _writeCompleted() {
+    openWrites--;
+    assert(openWrites >= 0);
+    _maybeWriteFiles();
+  }
+}
+
 Future writeFileCallback(Uri path, List<int> bytes) async {
-  var file = await new File.fromUri(path);
-  await file.writeAsBytes(bytes);
+  return WriteLimiter.scheduleWrite(path, bytes);
+}
+
+Future writeStreamFileCallback(Uri path, Stream<List<int>> bytes) async {
+  var file = new File.fromUri(path);
+  var parent_directory = file.parent;
+  await parent_directory.create(recursive: true);
+  IOSink sink = await file.openWrite();
+  await sink.addStream(bytes);
+  await sink.close();
 }
 
 Future<List<int>> readFileCallback(Uri path) async {
-  var file = await new File.fromUri(path);
+  var file = new File.fromUri(path);
   return await file.readAsBytes();
 }
 
@@ -126,8 +187,8 @@
     // Cannot register for signals.
     return;
   }
-  if (_isWindows) {
-    // Cannot register for signals on Windows.
+  if (_isWindows || _isFuchsia) {
+    // Cannot register for signals on Windows or Fuchsia.
     return;
   }
   _signalSubscription = _signalWatch(ProcessSignal.SIGQUIT).listen(_onSignal);
@@ -139,6 +200,7 @@
   VMServiceEmbedderHooks.createTempDir = createTempDirCallback;
   VMServiceEmbedderHooks.deleteDir = deleteDirCallback;
   VMServiceEmbedderHooks.writeFile = writeFileCallback;
+  VMServiceEmbedderHooks.writeStreamFile = writeStreamFileCallback;
   VMServiceEmbedderHooks.readFile = readFileCallback;
   VMServiceEmbedderHooks.listFiles = listFilesCallback;
   // Always instantiate the vmservice object so that the exit message
diff --git a/runtime/bin/vmservice_dartium.cc b/runtime/bin/vmservice_dartium.cc
index 535fb41..cd40dd7 100644
--- a/runtime/bin/vmservice_dartium.cc
+++ b/runtime/bin/vmservice_dartium.cc
@@ -65,7 +65,8 @@
   ASSERT(Dart_IsServiceIsolate(isolate));
   if (!VmService::Setup(DEFAULT_VM_SERVICE_SERVER_IP,
                         DEFAULT_VM_SERVICE_SERVER_PORT,
-                        false /* running_precompiled */)) {
+                        false /* running_precompiled */,
+                        false /* disable origin checks */)) {
     fprintf(stderr,
             "Vmservice::Setup failed: %s\n", VmService::GetErrorMessage());
     isolate = NULL;
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index b7f4df4..871a91c 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -176,7 +176,8 @@
 
 bool VmService::Setup(const char* server_ip,
                       intptr_t server_port,
-                      bool running_precompiled) {
+                      bool running_precompiled,
+                      bool dev_mode_server) {
   Dart_Isolate isolate = Dart_CurrentIsolate();
   ASSERT(isolate != NULL);
   SetServerIPAndPort("", 0);
@@ -241,6 +242,9 @@
                          DartUtils::NewString("_autoStart"),
                          Dart_NewBoolean(auto_start));
   SHUTDOWN_ON_ERROR(result);
+  result = Dart_SetField(library,
+                         DartUtils::NewString("_originCheckDisabled"),
+                         Dart_NewBoolean(dev_mode_server));
 
   // Are we running on Windows?
 #if defined(TARGET_OS_WINDOWS)
@@ -252,6 +256,16 @@
       Dart_SetField(library, DartUtils::NewString("_isWindows"), is_windows);
   SHUTDOWN_ON_ERROR(result);
 
+  // Are we running on Fuchsia?
+#if defined(TARGET_OS_FUCHSIA)
+  Dart_Handle is_fuchsia = Dart_True();
+#else
+  Dart_Handle is_fuchsia = Dart_False();
+#endif
+  result =
+      Dart_SetField(library, DartUtils::NewString("_isFuchsia"), is_fuchsia);
+  SHUTDOWN_ON_ERROR(result);
+
   // Get _getWatchSignalInternal from dart:io.
   Dart_Handle dart_io_str = Dart_NewStringFromCString(DartUtils::kIOLibURL);
   SHUTDOWN_ON_ERROR(dart_io_str);
@@ -303,21 +317,21 @@
 Dart_Handle VmService::LoadScript(const char* name) {
   Dart_Handle uri = Dart_NewStringFromCString(kVMServiceIOLibraryUri);
   Dart_Handle source = GetSource(name);
-  return Dart_LoadScript(uri, source, 0, 0);
+  return Dart_LoadScript(uri, Dart_Null(), 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);
+  return Dart_LoadLibrary(uri, Dart_Null(), source, 0, 0);
 }
 
 
 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
   Dart_Handle uri = Dart_NewStringFromCString(name);
   Dart_Handle source = GetSource(name);
-  return Dart_LoadSource(library, uri, source, 0, 0);
+  return Dart_LoadSource(library, uri, Dart_Null(), source, 0, 0);
 }
 
 
@@ -354,7 +368,7 @@
   if (Dart_IsError(source)) {
     return source;
   }
-  return Dart_LoadSource(library, url, source, 0, 0);
+  return Dart_LoadSource(library, url, Dart_Null(), source, 0, 0);
 }
 
 
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index f373b4b..f499abf 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -18,7 +18,8 @@
 
   static bool Setup(const char* server_ip,
                     intptr_t server_port,
-                    bool running_precompiled);
+                    bool running_precompiled,
+                    bool dev_mode_server);
 
   // Error message if startup failed.
   static const char* GetErrorMessage();
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 123064c..42ba0f2 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -692,13 +692,6 @@
                                                    char** error);
 
 /**
- * An isolate interrupt callback function.
- *
- * This callback has been DEPRECATED.
- */
-typedef bool (*Dart_IsolateInterruptCallback)();
-
-/**
  * An isolate unhandled exception callback function.
  *
  * This callback has been DEPRECATED.
@@ -784,41 +777,54 @@
 typedef Dart_Handle (*Dart_GetVMServiceAssetsArchive)();
 
 /**
- * Initializes the VM.
+ * The current version of the Dart_InitializeFlags. Should be incremented every
+ * time Dart_InitializeFlags changes in a binary incompatible way.
+ */
+#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000001)
+
+/**
+ * Describes how to initialize the VM. Used with Dart_Initialize.
  *
+ * \param version Identifies the version of the struct used by the client.
+ *   should be initialized to DART_INITIALIZE_PARAMS_CURRENT_VERSION.
  * \param vm_isolate_snapshot A buffer containing a snapshot of the VM isolate
  *   or NULL if no snapshot is provided.
  * \param instructions_snapshot A buffer containing a snapshot of precompiled
  *   instructions, or NULL if no snapshot is provided.
  * \param create A function to be called during isolate creation.
  *   See Dart_IsolateCreateCallback.
- * \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.
+ */
+typedef struct {
+    int32_t version;
+    const uint8_t* vm_isolate_snapshot;
+    const uint8_t* instructions_snapshot;
+    const uint8_t* data_snapshot;
+    Dart_IsolateCreateCallback create;
+    Dart_IsolateShutdownCallback shutdown;
+    Dart_ThreadExitCallback thread_exit;
+    Dart_FileOpenCallback file_open;
+    Dart_FileReadCallback file_read;
+    Dart_FileWriteCallback file_write;
+    Dart_FileCloseCallback file_close;
+    Dart_EntropySource entropy_source;
+    Dart_GetVMServiceAssetsArchive get_service_assets;
+} Dart_InitializeParams;
+
+/**
+ * Initializes the VM.
+ *
+ * \param flags A struct containing initialization information. The version
+ *   field of the struct must be DART_INITIALIZE_PARAMS_CURRENT_VERSION.
  *
  * \return NULL if initialization is successful. Returns an error message
  *   otherwise. The caller is responsible for freeing the error message.
  */
-DART_EXPORT char* Dart_Initialize(
-    const uint8_t* vm_isolate_snapshot,
-    const uint8_t* instructions_snapshot,
-    const uint8_t* data_snapshot,
-    Dart_IsolateCreateCallback create,
-    Dart_IsolateInterruptCallback interrupt,
-    Dart_IsolateUnhandledExceptionCallback unhandled_exception,
-    Dart_IsolateShutdownCallback shutdown,
-    Dart_ThreadExitCallback thread_exit,
-    Dart_FileOpenCallback file_open,
-    Dart_FileReadCallback file_read,
-    Dart_FileWriteCallback file_write,
-    Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source,
-    Dart_GetVMServiceAssetsArchive get_service_assets);
+DART_EXPORT char* Dart_Initialize(Dart_InitializeParams* params);
 
 /**
  * Cleanup state in the VM before process termination.
@@ -1029,7 +1035,7 @@
  *
  * When the isolate is interrupted, the isolate interrupt callback
  * will be invoked with 'isolate' as the current isolate (see
- * Dart_IsolateInterruptCallback).
+ * Dart_SetIsolateEventHandler).
  *
  * \param isolate The isolate to be interrupted.
  */
@@ -1178,6 +1184,23 @@
 
 
 /**
+ * Called when the embedder has caught a top level unhandled exception error
+ * in the current isolate. Also marks the isolate as paused at exit.
+ *
+ * NOTE: It is illegal to call this twice on the same isolate.
+ *
+ * \param error The unhandled exception error.
+ */
+DART_EXPORT void Dart_SetStickyError(Dart_Handle error);
+
+
+/**
+ * Does the current isolate have a sticky error?
+ */
+DART_EXPORT bool Dart_HasStickyError();
+
+
+/**
  * Handles the next pending message for the current isolate.
  *
  * May generate an unhandled exception error.
@@ -2653,7 +2676,6 @@
  * Scripts and Libraries
  * =====================
  */
-/* TODO(turnidge): Finish documenting this section. */
 
 typedef enum {
   Dart_kCanonicalizeUrl = 0,
@@ -2662,7 +2684,43 @@
   Dart_kImportTag,
 } Dart_LibraryTag;
 
-/* TODO(turnidge): Document. */
+/**
+ * The library tag handler is a multi-purpose callback provided by the
+ * embedder to the Dart VM. The embedder implements the tag handler to
+ * provide the ability to load Dart scripts and imports.
+ *
+ * -- TAGS --
+ *
+ * Dart_kCanonicalizeUrl
+ *
+ * This tag indicates that the embedder should canonicalize 'url' with
+ * respect to 'library'.  For most embedders, the
+ * Dart_DefaultCanonicalizeUrl function is a sufficient implementation
+ * of this tag.  The return value should be a string holding the
+ * canonicalized url.
+ *
+ * Dart_kScriptTag
+ *
+ * This tag indicates that the root script should be loaded from
+ * 'url'.  The 'library' parameter will always be null.  Once the root
+ * script is loaded, the embedder should call Dart_LoadScript to
+ * install the root script in the VM.  The return value should be an
+ * error or null.
+ *
+ * Dart_kSourceTag
+ *
+ * This tag is used to load a file referenced by Dart language "part
+ * of" directive.  Once the file's source is loaded, the embedder
+ * should call Dart_LoadSource to provide the file contents to the VM.
+ * The return value should be an error or null.
+ *
+ * Dart_kImportTag
+ *
+ * This tag is used to load a script referenced by Dart language
+ * "import" directive.  Once the script is loaded, the embedder should
+ * call Dart_LoadLibrary to provide the script source to the VM.  The
+ * return value should be an error or null.
+ */
 typedef Dart_Handle (*Dart_LibraryTagHandler)(Dart_LibraryTag tag,
                                               Dart_Handle library,
                                               Dart_Handle url);
@@ -2704,18 +2762,30 @@
                                                     Dart_Handle url);
 
 /**
- * Loads the root script for the current isolate. The script can be
- * embedded in another file, for example in an html file.
+ * Called by the embedder to provide the source for the root script to
+ * the VM.  This function should be called in response to a
+ * Dart_kScriptTag tag handler request (See Dart_LibraryTagHandler,
+ * above).
  *
- * TODO(turnidge): Document.
+ * \param url The original url requested for the script.
+ *
+ * \param resolved_url The actual url which was loaded.  This parameter
+ *   is optionally provided to support isolate reloading.  A value of
+ *   Dart_Null() indicates that the resolved url was the same as the
+ *   requested url.
+ *
+ * \param source The contents of the url.
  *
  * \param line_offset is the number of text lines before the
  *   first line of the Dart script in the containing file.
  *
  * \param col_offset is the number of characters before the first character
  *   in the first line of the Dart script.
+ *
+ * \return A valid handle if no error occurs during the operation.
  */
 DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
+                                        Dart_Handle resolved_url,
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t col_offset);
@@ -2808,7 +2878,33 @@
                                                 Dart_Handle error);
 
 
+/**
+ * Called by the embedder to provide the source for an "import"
+ * directive.  This function should be called in response to a
+ * Dart_kImportTag tag handler request (See Dart_LibraryTagHandler,
+ * above).
+ *
+ * \param library The library where the "import" directive occurs.
+ *
+ * \param url The original url requested for the import.
+ *
+ * \param resolved_url The actual url which was loaded.  This parameter
+ *   is optionally provided to support isolate reloading.  A value of
+ *   Dart_Null() indicates that the resolved url was the same as the
+ *   requested url.
+ *
+ * \param source The contents of the url.
+ *
+ * \param line_offset is the number of text lines before the
+ *   first line of the Dart script in the containing file.
+ *
+ * \param col_offset is the number of characters before the first character
+ *   in the first line of the Dart script.
+ *
+ * \return A valid handle if no error occurs during the operation.
+ */
 DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle url,
+                                         Dart_Handle resolved_url,
                                          Dart_Handle source,
                                          intptr_t line_offset,
                                          intptr_t column_offset);
@@ -2829,16 +2925,33 @@
                                                   Dart_Handle prefix);
 
 /**
- * Loads a source string into a library.
+ * Called by the embedder to provide the source for a "part of"
+ * directive.  This function should be called in response to a
+ * Dart_kSourceTag tag handler request (See Dart_LibraryTagHandler,
+ * above).
  *
- * \param library A library
- * \param url A url identifying the origin of the source
- * \param source A string of Dart source
+ * \param library The library where the "part of" directive occurs.
+ *
+ * \param url The original url requested for the part.
+ *
+ * \param resolved_url The actual url which was loaded.  This parameter
+ *   is optionally provided to support isolate reloading.  A value of
+ *   Dart_Null() indicates that the resolved url was the same as the
+ *   requested url.
+ *
+ * \param source The contents of the url.
+ *
+ * \param line_offset is the number of text lines before the
+ *   first line of the Dart script in the containing file.
+ *
+ * \param col_offset is the number of characters before the first character
+ *   in the first line of the Dart script.
  *
  * \return A valid handle if no error occurs during the operation.
  */
 DART_EXPORT Dart_Handle Dart_LoadSource(Dart_Handle library,
                                         Dart_Handle url,
+                                        Dart_Handle resolved_url,
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset);
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 961c444..edf8918 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -898,6 +898,26 @@
 
 /*
  * ========
+ * Reload support
+ * ========
+ *
+ * These functions are used to implement reloading in the Dart VM.
+ * This is an experimental feature, so embedders should be prepared
+ * for these functions to change.
+ */
+
+/**
+ * A callback which determines whether the file at some url has been
+ * modified since some time.  If the file cannot be found, true should
+ * be returned.
+ */
+typedef bool (*Dart_FileModifiedCallback)(const char* url, int64_t since);
+
+DART_EXPORT Dart_Handle Dart_SetFileModifiedCallback(
+    Dart_FileModifiedCallback file_modified_callback);
+
+/*
+ * ========
  * Timeline
  * ========
  */
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index 94f29f1..e62524b 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -10,8 +10,8 @@
 
 const _GROWABLE_ARRAY_MARKER = const _GrowableArrayMarker();
 
-patch class List<E> {
-  /* patch */ factory List([int length = _GROWABLE_ARRAY_MARKER]) {
+@patch class List<E> {
+  @patch factory List([int length = _GROWABLE_ARRAY_MARKER]) {
     if (identical(length, _GROWABLE_ARRAY_MARKER)) {
       return new _GrowableList<E>(0);
     }
@@ -20,7 +20,7 @@
     return new _List<E>(length);
   }
 
-  /* patch */ factory List.filled(int length, E fill, {bool growable: false}) {
+  @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 = growable ? new _GrowableList<E>(length) : new _List<E>(length);
@@ -32,7 +32,7 @@
     return result;
   }
 
-  /* patch */ factory List.from(Iterable elements, { bool growable: true }) {
+  @patch factory List.from(Iterable elements, { bool growable: true }) {
     if (elements is EfficientLength) {
       int length = elements.length;
       var list = growable ? new _GrowableList<E>(length) : new _List<E>(length);
@@ -54,7 +54,7 @@
     return makeListFixedLength(list);
   }
 
-  /* patch */ factory List.unmodifiable(Iterable elements) {
+  @patch factory List.unmodifiable(Iterable elements) {
     List result = new List<E>.from(elements, growable: false);
     return makeFixedListUnmodifiable(result);
   }
diff --git a/runtime/lib/async_patch.dart b/runtime/lib/async_patch.dart
index 346e50d..c048ce8 100644
--- a/runtime/lib/async_patch.dart
+++ b/runtime/lib/async_patch.dart
@@ -188,4 +188,4 @@
   }
 }
 
-patch void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow";
+@patch void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow";
diff --git a/runtime/lib/bigint.dart b/runtime/lib/bigint.dart
index c21b04a..0c562d7 100644
--- a/runtime/lib/bigint.dart
+++ b/runtime/lib/bigint.dart
@@ -1206,9 +1206,9 @@
     return r_used;
   }
 
-  int get _identityHashCode {
-    return this;
-  }
+  int get hashCode => this;
+  int get _identityHashCode => this;
+
   int operator ~() {
     return _not()._toValidInt();
   }
diff --git a/runtime/lib/bool_patch.dart b/runtime/lib/bool_patch.dart
index 274b153..5b5f4ff 100644
--- a/runtime/lib/bool_patch.dart
+++ b/runtime/lib/bool_patch.dart
@@ -4,14 +4,12 @@
 
 // Dart core library.
 
-patch class bool {
+@patch class bool {
 
-  /* patch */ const factory bool.fromEnvironment(String name,
-                                                 {bool defaultValue: false})
+  @patch const factory bool.fromEnvironment(String name,
+                                            {bool defaultValue: false})
       native "Bool_fromEnvironment";
 
-  int get _identityHashCode {
-    return this ? 1231 : 1237;
-  }
-  int get hashCode => _identityHashCode;
+  int get hashCode => this ? 1231 : 1237;
+  int get _identityHashCode => this ? 1231 : 1237;
 }
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index ccb4190..ed76535 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.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.
 
-patch class HashMap<K, V> {
-  /* patch */ factory HashMap({ bool equals(K key1, K key2),
-                                int hashCode(K key),
-                                bool isValidKey(potentialKey) }) {
+@patch class HashMap<K, V> {
+  @patch factory HashMap({ bool equals(K key1, K key2),
+                                 int hashCode(K key),
+                                 bool isValidKey(potentialKey) }) {
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
@@ -32,7 +32,7 @@
     return new _CustomHashMap<K, V>(equals, hashCode, isValidKey);
   }
 
-  /* patch */ factory HashMap.identity() = _IdentityHashMap<K, V>;
+  @patch factory HashMap.identity() = _IdentityHashMap<K, V>;
 
   Set<K> _newKeySet();
 }
@@ -518,10 +518,10 @@
   }
 }
 
-patch class HashSet<E> {
-  /* patch */ factory HashSet({ bool equals(E e1, E e2),
-                                int hashCode(E e),
-                                bool isValidKey(potentialKey) }) {
+@patch class HashSet<E> {
+  @patch factory HashSet({ bool equals(E e1, E e2),
+                           int hashCode(E e),
+                           bool isValidKey(potentialKey) }) {
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
@@ -548,7 +548,7 @@
     return new _CustomHashSet<E>(equals, hashCode, isValidKey);
   }
 
-  /* patch */ factory HashSet.identity() = _IdentityHashSet<E>;
+  @patch factory HashSet.identity() = _IdentityHashSet<E>;
 }
 
 class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> {
@@ -901,7 +901,7 @@
 /**
  * A hash-based map that iterates keys and values in key insertion order.
  */
-patch class LinkedHashMap<K, V> {
+@patch class LinkedHashMap<K, V> {
   /// Holds a double-linked list of entries in insertion order.
   /// The fields have the same name as the ones in [_LinkedHashMapEntry],
   /// and this map is itself used as the head entry of the list.
@@ -910,9 +910,9 @@
   var _nextEntry;
   var _previousEntry;
 
-  /* patch */ factory LinkedHashMap({ bool equals(K key1, K key2),
-                                      int hashCode(K key),
-                                      bool isValidKey(potentialKey) }) {
+  @patch factory LinkedHashMap({ bool equals(K key1, K key2),
+                                       int hashCode(K key),
+                                       bool isValidKey(potentialKey) }) {
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
@@ -939,14 +939,14 @@
     return new _CompactLinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
   }
 
-  /* patch */ factory LinkedHashMap.identity() =
+  @patch factory LinkedHashMap.identity() =
       _CompactLinkedIdentityHashMap<K, V>;
 }
 
-patch class LinkedHashSet<E> {
-  /* patch */ factory LinkedHashSet({ bool equals(E e1, E e2),
-                                      int hashCode(E e),
-                                      bool isValidKey(potentialKey) }) {
+@patch class LinkedHashSet<E> {
+  @patch factory LinkedHashSet({ bool equals(E e1, E e2),
+                                       int hashCode(E e),
+                                       bool isValidKey(potentialKey) }) {
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
@@ -973,6 +973,6 @@
     return new _CompactLinkedCustomHashSet<E>(equals, hashCode, isValidKey);
   }
 
-  /* patch */ factory LinkedHashSet.identity() =
+  @patch factory LinkedHashSet.identity() =
       _CompactLinkedIdentityHashSet<E>;
 }
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart
index d4acc18a..25a8dc5 100644
--- a/runtime/lib/convert_patch.dart
+++ b/runtime/lib/convert_patch.dart
@@ -6,7 +6,7 @@
 
 // JSON conversion.
 
-patch _parseJson(String json, reviver(var key, var value)) {
+@patch _parseJson(String json, reviver(var key, var value)) {
   _BuildJsonListener listener;
   if (reviver == null) {
     listener = new _BuildJsonListener();
@@ -21,8 +21,8 @@
   return listener.result;
 }
 
-patch class Utf8Decoder {
-  /* patch */
+@patch class Utf8Decoder {
+  @patch
   Converter<List<int>, dynamic/*=T*/> fuse/*<T>*/(
       Converter<String, dynamic/*=T*/> next) {
     if (next is JsonDecoder) {
@@ -34,7 +34,7 @@
   }
 
   // Allow intercepting of UTF-8 decoding when built-in lists are passed.
-  /* patch */
+  @patch
   static String _convertIntercepted(
       bool allowMalformed, List<int> codeUnits, int start, int end) {
     return null;  // This call was not intercepted.
@@ -1376,8 +1376,8 @@
   }
 }
 
-patch class JsonDecoder {
-  /* patch */ StringConversionSink startChunkedConversion(Sink<Object> sink) {
+@patch class JsonDecoder {
+  @patch StringConversionSink startChunkedConversion(Sink<Object> sink) {
     return new _JsonStringDecoderSink(this._reviver, sink);
   }
 }
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 13f7513..f06c98b 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -11,13 +11,9 @@
 // The members of this class are cloned and added to each class that
 // represents an enum type.
 class _EnumHelper {
-  // Declare the list of enum value names private. When this field is
-  // cloned into a user-defined enum class, the field will be inaccessible
-  // because of the library-specific name suffix. The toString() function
-  // below can access it because it uses the same name suffix.
-  static const List<String> _enum_names = null;
-  String toString() => _enum_names[index];
-  int get hashCode => _enum_names[index].hashCode;
+  String _name;
+  String toString() => _name;
+  int get hashCode => _name.hashCode;
 }
 
 // _SyncIterable and _syncIterator are used by the compiler to
@@ -79,6 +75,6 @@
   }
 }
 
-patch class StackTrace {
-  /* patch */ static StackTrace get current native "StackTrace_current";
+@patch class StackTrace {
+  @patch static StackTrace get current native "StackTrace_current";
 }
diff --git a/runtime/lib/date_patch.dart b/runtime/lib/date_patch.dart
index 1ecf812..d1fced2 100644
--- a/runtime/lib/date_patch.dart
+++ b/runtime/lib/date_patch.dart
@@ -4,7 +4,7 @@
 // Dart core library.
 
 // VM implementation of DateTime.
-patch class DateTime {
+@patch class DateTime {
   // Natives.
   // The natives have been moved up here to work around Issue 10401.
   static int _getCurrentMicros() native "DateTime_currentTimeMicros";
@@ -30,17 +30,17 @@
 
   List __parts;
 
-  /* patch */ DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
-                                                  {bool isUtc: false})
+  @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})
+  @patch DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+                                             {bool isUtc: false})
       : this._withValue(microsecondsSinceEpoch, isUtc: isUtc);
 
-  /* patch */ DateTime._internal(int year,
+  @patch DateTime._internal(int year,
                                  int month,
                                  int day,
                                  int hour,
@@ -57,17 +57,17 @@
     if (isUtc == null) throw new ArgumentError();
   }
 
-  /* patch */ DateTime._now()
+  @patch DateTime._now()
       : isUtc = false,
         _value = _getCurrentMicros() {
   }
 
-  /* patch */ String get timeZoneName {
+  @patch String get timeZoneName {
     if (isUtc) return "UTC";
     return _timeZoneName(microsecondsSinceEpoch);
   }
 
-  /* patch */ Duration get timeZoneOffset {
+  @patch Duration get timeZoneOffset {
     if (isUtc) return new Duration();
     int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch);
     return new Duration(seconds: offsetInSeconds);
@@ -165,42 +165,42 @@
     return __parts;
   }
 
-  /* patch */ DateTime add(Duration duration) {
+  @patch DateTime add(Duration duration) {
     return new DateTime._withValue(
         _value + duration.inMicroseconds, isUtc: isUtc);
   }
 
-  /* patch */ DateTime subtract(Duration duration) {
+  @patch DateTime subtract(Duration duration) {
     return new DateTime._withValue(
         _value - duration.inMicroseconds, isUtc: isUtc);
   }
 
-  /* patch */ Duration difference(DateTime other) {
+  @patch Duration difference(DateTime other) {
     return new Duration(microseconds: _value - other._value);
   }
 
-  /* patch */ int get millisecondsSinceEpoch =>
+  @patch int get millisecondsSinceEpoch =>
       _value ~/ Duration.MICROSECONDS_PER_MILLISECOND;
 
-  /* patch */ int get microsecondsSinceEpoch => _value;
+  @patch int get microsecondsSinceEpoch => _value;
 
-  /* patch */ int get microsecond => _parts[_MICROSECOND_INDEX];
+  @patch int get microsecond => _parts[_MICROSECOND_INDEX];
 
-  /* patch */ int get millisecond => _parts[_MILLISECOND_INDEX];
+  @patch int get millisecond => _parts[_MILLISECOND_INDEX];
 
-  /* patch */ int get second => _parts[_SECOND_INDEX];
+  @patch int get second => _parts[_SECOND_INDEX];
 
-  /* patch */ int get minute => _parts[_MINUTE_INDEX];
+  @patch int get minute => _parts[_MINUTE_INDEX];
 
-  /* patch */ int get hour => _parts[_HOUR_INDEX];
+  @patch int get hour => _parts[_HOUR_INDEX];
 
-  /* patch */ int get day => _parts[_DAY_INDEX];
+  @patch int get day => _parts[_DAY_INDEX];
 
-  /* patch */ int get weekday => _parts[_WEEKDAY_INDEX];
+  @patch int get weekday => _parts[_WEEKDAY_INDEX];
 
-  /* patch */ int get month => _parts[_MONTH_INDEX];
+  @patch int get month => _parts[_MONTH_INDEX];
 
-  /* patch */ int get year => _parts[_YEAR_INDEX];
+  @patch int get year => _parts[_YEAR_INDEX];
 
   /**
    * Returns the amount of microseconds in UTC that represent the same values
@@ -244,7 +244,7 @@
   }
 
   /// Converts the given broken down date to microseconds.
-  /* patch */ static int _brokenDownDateToValue(
+  @patch static int _brokenDownDateToValue(
       int year, int month, int day,
       int hour, int minute, int second, int millisecond, int microsecond,
       bool isUtc) {
diff --git a/runtime/lib/deferred_load_patch.dart b/runtime/lib/deferred_load_patch.dart
index 800fdef..5c8a597 100644
--- a/runtime/lib/deferred_load_patch.dart
+++ b/runtime/lib/deferred_load_patch.dart
@@ -4,8 +4,8 @@
 
 final Set<String> _loadedLibraries = new Set<String>();
 
-patch class DeferredLibrary {
-  /* patch */ Future<Null> load() {
+@patch class DeferredLibrary {
+  @patch Future<Null> load() {
     // Dummy implementation that should eventually be replaced by real
     // implementation.
     Future future =
diff --git a/runtime/lib/developer.cc b/runtime/lib/developer.cc
index a2811ee..57a1a4c 100644
--- a/runtime/lib/developer.cc
+++ b/runtime/lib/developer.cc
@@ -34,14 +34,19 @@
 
 DEFINE_NATIVE_ENTRY(Developer_inspect, 1) {
   GET_NATIVE_ARGUMENT(Instance, inspectee, arguments->NativeArgAt(0));
+#ifndef PRODUCT
   if (FLAG_support_service) {
     Service::SendInspectEvent(isolate, inspectee);
   }
+#endif  // !PRODUCT
   return inspectee.raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Developer_log, 8) {
+#if defined(PRODUCT)
+  return Object::null();
+#else
   if (!FLAG_support_service) {
     return Object::null();
   }
@@ -63,10 +68,14 @@
                         error,
                         stack_trace);
   return Object::null();
+#endif  // PRODUCT
 }
 
 
 DEFINE_NATIVE_ENTRY(Developer_postEvent, 2) {
+#if defined(PRODUCT)
+  return Object::null();
+#else
   if (!FLAG_support_service) {
     return Object::null();
   }
@@ -74,19 +83,27 @@
   GET_NON_NULL_NATIVE_ARGUMENT(String, event_data, arguments->NativeArgAt(1));
   Service::SendExtensionEvent(isolate, event_kind, event_data);
   return Object::null();
+#endif  // PRODUCT
 }
 
 
 DEFINE_NATIVE_ENTRY(Developer_lookupExtension, 1) {
+#if defined(PRODUCT)
+  return Object::null();
+#else
   if (!FLAG_support_service) {
     return Object::null();
   }
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0));
   return isolate->LookupServiceExtensionHandler(name);
+#endif  // PRODUCT
 }
 
 
 DEFINE_NATIVE_ENTRY(Developer_registerExtension, 2) {
+#if defined(PRODUCT)
+  return Object::null();
+#else
   if (!FLAG_support_service) {
     return Object::null();
   }
@@ -100,6 +117,7 @@
     isolate->RegisterServiceExtensionHandler(name, handler);
   }
   return Object::null();
+#endif  // PRODUCT
 }
 
 }  // namespace dart
diff --git a/runtime/lib/developer.dart b/runtime/lib/developer.dart
index f7b45f0..ec3d38b 100644
--- a/runtime/lib/developer.dart
+++ b/runtime/lib/developer.dart
@@ -4,19 +4,19 @@
 
 import 'dart:isolate';
 
-patch bool debugger({bool when: true,
+@patch bool debugger({bool when: true,
                      String message}) native "Developer_debugger";
 
-patch Object inspect(Object object) native "Developer_inspect";
+@patch Object inspect(Object object) native "Developer_inspect";
 
-patch void log(String message,
-               {DateTime time,
-                int sequenceNumber,
-                int level: 0,
-                String name: '',
-                Zone zone,
-                Object error,
-                StackTrace stackTrace}) {
+@patch void log(String message,
+                {DateTime time,
+                 int sequenceNumber,
+                 int level: 0,
+                 String name: '',
+                 Zone zone,
+                 Object error,
+                 StackTrace stackTrace}) {
   if (message is! String) {
     throw new ArgumentError(message, "message", "Must be a String");
   }
@@ -52,13 +52,13 @@
      Object error,
      StackTrace stackTrace) native "Developer_log";
 
-patch void _postEvent(String eventKind, String eventData)
+@patch void _postEvent(String eventKind, String eventData)
     native "Developer_postEvent";
 
-patch ServiceExtensionHandler _lookupExtension(String method)
+@patch ServiceExtensionHandler _lookupExtension(String method)
     native "Developer_lookupExtension";
 
-patch _registerExtension(String method, ServiceExtensionHandler handler)
+@patch _registerExtension(String method, ServiceExtensionHandler handler)
     native "Developer_registerExtension";
 
 // This code is only invoked when there is no other Dart code on the stack.
diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart
index cbf955d..34d7803 100644
--- a/runtime/lib/double.dart
+++ b/runtime/lib/double.dart
@@ -8,10 +8,12 @@
 
   Type get runtimeType => double;
 
-  int get _identityHashCode {
-    if (isNaN || isInfinite) return 0;
-    return toInt();
-  }
+  // TODO: Make a stared static method for hashCode and _identityHashCode
+  //       when semantics are corrected as described in:
+  //       https://github.com/dart-lang/sdk/issues/2884
+  int get hashCode => (isNaN || isInfinite) ?  0 : toInt();
+  int get _identityHashCode => (isNaN || isInfinite) ?  0 : toInt();
+
   double operator +(num other) {
     return _add(other.toDouble());
   }
@@ -275,4 +277,11 @@
       return LESS;
     }
   }
+
+  static const int _FRACTIONAL_BITS = // Bits to keep after the decimal point.
+      const int.fromEnvironment("doubleFractionalBits", defaultValue: 20);
+  static const double _BIAS = 1.5 * (1 << (52 - _FRACTIONAL_BITS));
+
+  // Returns this with only _FRACTIONAL_BITS bits after the decimal point.
+  double get p => this + _BIAS - _BIAS;
 }
diff --git a/runtime/lib/double_patch.dart b/runtime/lib/double_patch.dart
index f33122a..b0b7054 100644
--- a/runtime/lib/double_patch.dart
+++ b/runtime/lib/double_patch.dart
@@ -5,7 +5,7 @@
 
 // VM implementation of double.
 
-patch class double {
+@patch class double {
 
   static double _nativeParse(String str,
                              int start, int end) native "Double_parse";
@@ -101,8 +101,8 @@
     return _nativeParse(str, start, end);
   }
 
-  /* patch */ static double parse(String str,
-                                  [double onError(String str)]) {
+  @patch static double parse(String str,
+                                   [double onError(String str)]) {
     var result = _parse(str);
     if (result == null) {
       if (onError == null) throw new FormatException("Invalid double", str);
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index faf342b..89ade45 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -5,16 +5,16 @@
 import 'dart:_internal' as internal;
 import 'dart:convert' show JSON;
 
-patch class Error {
-  /* patch */ static String _objectToString(Object object) {
+@patch class Error {
+  @patch static String _objectToString(Object object) {
     return Object._toString(object);
   }
 
-  /* patch */ static String _stringToSafeString(String string) {
+  @patch static String _stringToSafeString(String string) {
     return JSON.encode(string);
   }
 
-  /* patch */ StackTrace get stackTrace => _stackTrace;
+  @patch StackTrace get stackTrace => _stackTrace;
 
   StackTrace _stackTrace;
 }
@@ -95,12 +95,12 @@
   final String _errorMsg;
 }
 
-patch class FallThroughError {
+@patch class FallThroughError {
   FallThroughError._create(this._url, this._line);
 
   static _throwNew(int case_clause_pos) native "FallThroughError_throwNew";
 
-  /* patch */ String toString() {
+  @patch String toString() {
     return "'$_url': Switch case fall-through at line $_line.";
   }
 
@@ -116,26 +116,26 @@
   final String _msg;
 }
 
-patch class UnsupportedError {
+@patch class UnsupportedError {
   static _throwNew(String msg) {
     throw new UnsupportedError(msg);
   }
 }
 
-patch class CyclicInitializationError {
+@patch class CyclicInitializationError {
   static _throwNew(String variableName) {
     throw new CyclicInitializationError(variableName);
   }
 }
 
-patch class AbstractClassInstantiationError {
+@patch class AbstractClassInstantiationError {
   AbstractClassInstantiationError._create(
       this._className, this._url, this._line);
 
   static _throwNew(int case_clause_pos, String className)
       native "AbstractClassInstantiationError_throwNew";
 
-  /* patch */ String toString() {
+  @patch String toString() {
     return "Cannot instantiate abstract class $_className: "
            "_url '$_url' line $_line";
   }
@@ -146,7 +146,7 @@
   int _line;
 }
 
-patch class NoSuchMethodError {
+@patch class NoSuchMethodError {
   // The compiler emits a call to _throwNew when it cannot resolve a static
   // method at compile time. The receiver is actually the literal class of the
   // unresolved method.
@@ -284,7 +284,7 @@
     return "$msg\n\n";
   }
 
-  /* patch */ String toString() {
+  @patch String toString() {
     StringBuffer actual_buf = new StringBuffer();
     int i = 0;
     if (_arguments == null) {
diff --git a/runtime/lib/expando_patch.dart b/runtime/lib/expando_patch.dart
index df0234d..ac5f706 100644
--- a/runtime/lib/expando_patch.dart
+++ b/runtime/lib/expando_patch.dart
@@ -2,15 +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.
 
-patch class Expando<T> {
-  /* patch */ Expando([String this.name])
+@patch class Expando<T> {
+  @patch Expando([String this.name])
       : _data = new List(_minSize),
         _used = 0;
 
   static const _minSize = 8;
   static final _deletedEntry = new _WeakProperty(null, null);
 
-  /* patch */ T operator[](Object object) {
+  @patch T operator[](Object object) {
     _checkType(object);
 
     var mask = _size - 1;
@@ -31,7 +31,7 @@
     return null;
   }
 
-  /* patch */ void operator[]=(Object object, T value) {
+  @patch void operator[]=(Object object, T value) {
     _checkType(object);
 
     var mask = _size - 1;
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index b7424f5..4241762 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -47,6 +47,19 @@
         const Object& receiver_b = Object::Handle(context_b.At(0));
         if (receiver_a.raw() == receiver_b.raw()) return Bool::True().raw();
       }
+    } else if (func_a.IsImplicitInstanceClosureFunction() &&
+               func_b.IsImplicitInstanceClosureFunction()) {
+      // TODO(rmacnak): Patch existing tears off during reload instead.
+      const Context& context_a = Context::Handle(receiver.context());
+      const Context& context_b = Context::Handle(
+          Closure::Cast(other).context());
+      const Object& receiver_a = Object::Handle(context_a.At(0));
+      const Object& receiver_b = Object::Handle(context_b.At(0));
+      if ((receiver_a.raw() == receiver_b.raw()) &&
+          (func_a.name() == func_b.name()) &&
+          (func_a.Owner() == func_b.Owner())) {
+        return Bool::True().raw();
+      }
     }
   }
   return Bool::False().raw();
diff --git a/runtime/lib/function_patch.dart b/runtime/lib/function_patch.dart
index c94c78b..5acd4f9 100644
--- a/runtime/lib/function_patch.dart
+++ b/runtime/lib/function_patch.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.
 
-patch class Function {
+@patch class Function {
   static _apply(List arguments, List names)
       native "Function_apply";
 
-  /* patch */ static apply(Function function,
-                           List positionalArguments,
-                           [Map<Symbol, dynamic> namedArguments]) {
+  @patch static apply(Function function,
+                      List positionalArguments,
+                      [Map<Symbol, dynamic> namedArguments]) {
     int numPositionalArguments = 1 +  // Function is first implicit argument.
         (positionalArguments != null ? positionalArguments.length : 0);
     int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 016a454..9e942e4 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -104,12 +104,6 @@
     return new _GrowableList<T>.withData(data);
   }
 
-  factory _GrowableList.from(Iterable<T> other) {
-    List<T> result = new _GrowableList<T>();
-    result.addAll(other);
-    return result;
-  }
-
   factory _GrowableList.withData(_List data)
     native "GrowableList_allocate";
 
@@ -118,8 +112,19 @@
   int get length native "GrowableList_getLength";
 
   void set length(int new_length) {
-    int new_capacity = (new_length == 0) ? _kDefaultCapacity : new_length;
-    if (new_capacity > _capacity) {
+    int old_capacity = _capacity;
+    int new_capacity = new_length;
+    if (new_length == 0) {
+      // Ensure that we use _kDefaultCapacity only when the old_capacity
+      // is greater than _kDefaultCapacity otherwise we end up growing the
+      // the array.
+      if (old_capacity < _kDefaultCapacity) {
+        new_capacity = old_capacity;
+      } else {
+        new_capacity = _kDefaultCapacity;
+      }
+    }
+    if (new_capacity > old_capacity) {
       _grow(new_capacity);
       _setLength(new_length);
       return;
@@ -209,8 +214,7 @@
   T removeLast() {
     var len = length - 1;
     var elem = this[len];
-    this[len] = null;
-    _setLength(len);
+    this.length = len;
     return elem;
   }
 
diff --git a/runtime/lib/identical_patch.dart b/runtime/lib/identical_patch.dart
index 172478f..6aaa1fc 100644
--- a/runtime/lib/identical_patch.dart
+++ b/runtime/lib/identical_patch.dart
@@ -2,6 +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.
 
-patch bool identical(Object a, Object b) native "Identical_comparison";
+@patch bool identical(Object a, Object b) native "Identical_comparison";
 
-patch int identityHashCode(Object object) => object._identityHashCode;
+@patch int identityHashCode(Object object) => object._identityHashCode;
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index b86b71c..0c5b119 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -408,8 +408,8 @@
     throw new UnsupportedError(
         "_Smi can only be allocated by the VM");
   }
-  int get _identityHashCode => this;
   int get hashCode => this;
+  int get _identityHashCode => this;
   int operator ~() native "Smi_bitNegate";
   int get bitLength native "Smi_bitLength";
 
@@ -608,8 +608,8 @@
     throw new UnsupportedError(
         "_Mint can only be allocated by the VM");
   }
-  int get _identityHashCode => this;
   int get hashCode => this;
+  int get _identityHashCode => this;
   int operator ~() native "Mint_bitNegate";
   int get bitLength native "Mint_bitLength";
 
diff --git a/runtime/lib/integers_patch.dart b/runtime/lib/integers_patch.dart
index 19cc787..67db176 100644
--- a/runtime/lib/integers_patch.dart
+++ b/runtime/lib/integers_patch.dart
@@ -7,10 +7,10 @@
 
 import 'dart:_internal' as internal;
 
-patch class int {
+@patch class int {
 
-  /* patch */ const factory int.fromEnvironment(String name,
-                                                {int defaultValue})
+  @patch const factory int.fromEnvironment(String name,
+                                           {int defaultValue})
       native "Integer_fromEnvironment";
 
 
@@ -42,9 +42,9 @@
     return sign * result;
   }
 
-  /* patch */ static int parse(String source,
-                               { int radix,
-                                 int onError(String str) }) {
+  @patch static int parse(String source,
+                          { int radix,
+                            int onError(String str) }) {
     if (source == null) throw new ArgumentError("The source must not be null");
     if (source.isEmpty) return _throwFormatException(onError, source, 0, radix);
     if (radix == null || radix == 10) {
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 3089830..24f31de 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.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.
 
-patch List makeListFixedLength(List growableList)
+@patch List makeListFixedLength(List growableList)
     native "Internal_makeListFixedLength";
 
-patch List makeFixedListUnmodifiable(List fixedLengthList)
+@patch List makeFixedListUnmodifiable(List fixedLengthList)
     native "Internal_makeFixedListUnmodifiable";
 
 class VMLibraryHooks {
@@ -32,7 +32,7 @@
   static var platformScript;
 }
 
-patch class CodeUnits {
+@patch class CodeUnits {
   static final int cid = ClassID.getID(new CodeUnits(""));
 }
 
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 4dd89c0..7e4579a 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -5,15 +5,15 @@
 import "dart:collection" show HashMap;
 import "dart:_internal";
 
-patch class ReceivePort {
-  /* patch */ factory ReceivePort() = _ReceivePortImpl;
+@patch class ReceivePort {
+  @patch factory ReceivePort() = _ReceivePortImpl;
 
-  /* patch */ factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) =
+  @patch factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) =
       _ReceivePortImpl.fromRawReceivePort;
 }
 
-patch class Capability {
-  /* patch */ factory Capability() = _CapabilityImpl;
+@patch class Capability {
+  @patch factory Capability() = _CapabilityImpl;
 }
 
 class _CapabilityImpl implements Capability {
@@ -31,7 +31,7 @@
   _get_hashcode() native "CapabilityImpl_get_hashcode";
 }
 
-patch class RawReceivePort {
+@patch class RawReceivePort {
   /**
    * Opens a long-lived port for receiving messages.
    *
@@ -39,7 +39,7 @@
    * can not be paused. The data-handler must be set before the first
    * event is received.
    */
-  /* patch */ factory RawReceivePort([void handler(event)]) {
+  @patch factory RawReceivePort([void handler(event)]) {
     _RawReceivePortImpl result = new _RawReceivePortImpl();
     result.handler = handler;
     return result;
@@ -268,13 +268,13 @@
   port.sendPort.send(null);
 }
 
-patch class Isolate {
+@patch class Isolate {
   static final _currentIsolate = _getCurrentIsolate();
   static final _rootUri = _getCurrentRootUri();
 
-  /* patch */ static Isolate get current => _currentIsolate;
+  @patch static Isolate get current => _currentIsolate;
 
-  /* patch */ static Future<Uri> get packageRoot {
+  @patch static Future<Uri> get packageRoot {
     var hook = VMLibraryHooks.packageRootUriFuture;
     if (hook == null) {
       throw new UnsupportedError("Isolate.packageRoot");
@@ -282,7 +282,7 @@
     return hook();
   }
 
-  /* patch */ static Future<Uri> get packageConfig {
+  @patch static Future<Uri> get packageConfig {
     var hook = VMLibraryHooks.packageConfigUriFuture;
     if (hook == null) {
       throw new UnsupportedError("Isolate.packageConfig");
@@ -290,7 +290,7 @@
     return hook();
   }
 
-  /* patch */ static Future<Uri> resolvePackageUri(Uri packageUri) {
+  @patch static Future<Uri> resolvePackageUri(Uri packageUri) {
     var hook = VMLibraryHooks.resolvePackageUriFuture;
     if (hook == null) {
       throw new UnsupportedError("Isolate.resolvePackageUri");
@@ -303,7 +303,7 @@
       (VMLibraryHooks.packageConfigUriFuture != null) &&
       (VMLibraryHooks.resolvePackageUriFuture != null);
 
-  /* patch */ static Future<Isolate> spawn(
+  @patch static Future<Isolate> spawn(
       void entryPoint(message), var message,
       {bool paused: false, bool errorsAreFatal,
        SendPort onExit, SendPort onError}) async {
@@ -340,7 +340,7 @@
     }
   }
 
-  /* patch */ static Future<Isolate> spawnUri(
+  @patch static Future<Isolate> spawnUri(
       Uri uri, List<String> args, var message,
       {bool paused: false,
        SendPort onExit,
@@ -478,7 +478,7 @@
 
   static void _sendOOB(port, msg) native "Isolate_sendOOB";
 
-  /* patch */ void _pause(Capability resumeCapability) {
+  @patch void _pause(Capability resumeCapability) {
     var msg = new List(4)
         ..[0] = 0  // Make room for OOB message type.
         ..[1] = _PAUSE
@@ -487,7 +487,7 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void resume(Capability resumeCapability) {
+  @patch void resume(Capability resumeCapability) {
     var msg = new List(4)
         ..[0] = 0  // Make room for OOB message type.
         ..[1] = _RESUME
@@ -496,8 +496,8 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void addOnExitListener(SendPort responsePort,
-                                     {Object response}) {
+  @patch void addOnExitListener(SendPort responsePort,
+                                {Object response}) {
     var msg = new List(4)
         ..[0] = 0  // Make room for OOB message type.
         ..[1] = _ADD_EXIT
@@ -506,7 +506,7 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void removeOnExitListener(SendPort responsePort) {
+  @patch void removeOnExitListener(SendPort responsePort) {
     var msg = new List(3)
         ..[0] = 0  // Make room for OOB message type.
         ..[1] = _DEL_EXIT
@@ -514,7 +514,7 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void setErrorsFatal(bool errorsAreFatal) {
+  @patch void setErrorsFatal(bool errorsAreFatal) {
     var msg = new List(4)
       ..[0] = 0  // Make room for OOB message type.
       ..[1] = _ERROR_FATAL
@@ -523,7 +523,7 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void kill({int priority: BEFORE_NEXT_EVENT}) {
+  @patch void kill({int priority: BEFORE_NEXT_EVENT}) {
     var msg = new List(4)
         ..[0] = 0  // Make room for OOB message type.
         ..[1] = _KILL
@@ -532,8 +532,8 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void ping(SendPort responsePort, {Object response,
-                                                int priority: IMMEDIATE}) {
+  @patch void ping(SendPort responsePort, {Object response,
+                                           int priority: IMMEDIATE}) {
     var msg = new List(5)
         ..[0] = 0  // Make room for OOM message type.
         ..[1] = _PING
@@ -543,7 +543,7 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void addErrorListener(SendPort port) {
+  @patch void addErrorListener(SendPort port) {
     var msg = new List(3)
         ..[0] = 0  // Make room for OOB message type.
         ..[1] = _ADD_ERROR
@@ -551,7 +551,7 @@
     _sendOOB(controlPort, msg);
   }
 
-  /* patch */ void removeErrorListener(SendPort port) {
+  @patch void removeErrorListener(SendPort port) {
     var msg = new List(3)
         ..[0] = 0  // Make room for OOB message type.
         ..[1] = _DEL_ERROR
diff --git a/runtime/lib/map_patch.dart b/runtime/lib/map_patch.dart
index 8a8359a..6e2f14d 100644
--- a/runtime/lib/map_patch.dart
+++ b/runtime/lib/map_patch.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.
 
-patch class Map<K, V> {
+@patch class Map<K, V> {
   // Factory constructing a Map from a parser generated Map literal.
   // [elements] contains n key-value pairs.
   // The keys are at position 2*n and are already type checked by the parser
@@ -17,9 +17,9 @@
     return map;
   }
 
-  /* patch */ factory Map.unmodifiable(Map other) {
+  @patch factory Map.unmodifiable(Map other) {
     return new UnmodifiableMapView<K, V>(new Map.from(other));
   }
 
-  /* patch */ factory Map() = LinkedHashMap<K, V>;
+  @patch factory Map() = LinkedHashMap<K, V>;
 }
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index 4f0b852..1be57ac 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.dart
@@ -8,7 +8,7 @@
 
 // If [x] is an [int] and [exponent] is a non-negative [int], the result is
 // an [int], otherwise the result is a [double].
-patch num pow(num x, num exponent) {
+@patch num pow(num x, num exponent) {
   if ((x is int) && (exponent is int) && (exponent >= 0)) {
     return _intPow(x, exponent);
   }
@@ -23,7 +23,7 @@
   if (exponent == 1.0) return base;
   if (exponent == 2.0) return base * base;
   if (exponent == 3.0) return base * base * base;
-  
+
   if (base == 1.0) return 1.0;
 
   if (base.isNaN || exponent.isNaN) {
@@ -56,16 +56,16 @@
   return result;
 }
 
-patch double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
-patch double sin(num value) => _sin(value.toDouble());
-patch double cos(num value) => _cos(value.toDouble());
-patch double tan(num value) => _tan(value.toDouble());
-patch double acos(num value) => _acos(value.toDouble());
-patch double asin(num value) => _asin(value.toDouble());
-patch double atan(num value) => _atan(value.toDouble());
-patch double sqrt(num value) => _sqrt(value.toDouble());
-patch double exp(num value) => _exp(value.toDouble());
-patch double log(num value) => _log(value.toDouble());
+@patch double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
+@patch double sin(num value) => _sin(value.toDouble());
+@patch double cos(num value) => _cos(value.toDouble());
+@patch double tan(num value) => _tan(value.toDouble());
+@patch double acos(num value) => _acos(value.toDouble());
+@patch double asin(num value) => _asin(value.toDouble());
+@patch double atan(num value) => _atan(value.toDouble());
+@patch double sqrt(num value) => _sqrt(value.toDouble());
+@patch double exp(num value) => _exp(value.toDouble());
+@patch double log(num value) => _log(value.toDouble());
 
 double _atan2(double a, double b) native "Math_atan2";
 double _sin(double x) native "Math_sin";
@@ -80,9 +80,9 @@
 
 
 // TODO(iposva): Handle patch methods within a patch class correctly.
-patch class Random {
+@patch class Random {
 
-  /*patch*/ factory Random([int seed]) {
+  @patch factory Random([int seed]) {
     var state = _Random._setupSeed((seed == null) ? _Random._nextSeed() : seed);
     // Crank a couple of times to distribute the seed bits a bit further.
     return new _Random._withState(state).._nextState()
@@ -91,7 +91,7 @@
                                         .._nextState();
   }
 
-  /*patch*/ factory Random.secure() {
+  @patch factory Random.secure() {
     return new _SecureRandom();
   }
 }
diff --git a/runtime/lib/mirrors_patch.dart b/runtime/lib/mirrors_patch.dart
index e80dd47..2e2da5b 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/runtime/lib/mirrors_patch.dart
@@ -7,7 +7,7 @@
 /**
  * Returns a [MirrorSystem] for the current isolate.
  */
-patch MirrorSystem currentMirrorSystem() {
+@patch MirrorSystem currentMirrorSystem() {
   return _Mirrors.currentMirrorSystem();
 }
 
@@ -17,7 +17,7 @@
  * This only works if this mirror system is associated with the
  * current running isolate.
  */
-patch InstanceMirror reflect(Object reflectee) {
+@patch InstanceMirror reflect(Object reflectee) {
   return _Mirrors.reflect(reflectee);
 }
 
@@ -27,16 +27,16 @@
  *
  * This only works with objects local to the current isolate.
  */
-patch ClassMirror reflectClass(Type key) {
+@patch ClassMirror reflectClass(Type key) {
   return _Mirrors.reflectClass(key);
 }
 
-patch TypeMirror reflectType(Type key) {
+@patch TypeMirror reflectType(Type key) {
   return _Mirrors.reflectType(key);
 }
 
-patch class MirrorSystem {
-  /* patch */ LibraryMirror findLibrary(Symbol libraryName) {
+@patch class MirrorSystem {
+  @patch LibraryMirror findLibrary(Symbol libraryName) {
     var candidates =
         libraries.values.where((lib) => lib.simpleName == libraryName);
     if (candidates.length == 1) {
@@ -50,11 +50,11 @@
     throw new Exception("There is no library named '${getName(libraryName)}'");
   }
 
-  /* patch */ static String getName(Symbol symbol) {
+  @patch static String getName(Symbol symbol) {
     return internal.Symbol.getUnmangledName(symbol);
   }
 
-  /* patch */ static Symbol getSymbol(String name, [LibraryMirror library]) {
+  @patch static Symbol getSymbol(String name, [LibraryMirror library]) {
     if ((library != null && library is! _LocalLibraryMirror) ||
         ((name.length > 0) && (name[0] == '_') && (library == null))) {
       throw new ArgumentError(library);
diff --git a/runtime/lib/null_patch.dart b/runtime/lib/null_patch.dart
index 61972d1..312804e 100644
--- a/runtime/lib/null_patch.dart
+++ b/runtime/lib/null_patch.dart
@@ -4,17 +4,15 @@
 
 // Dart core library.
 
-patch class Null {
+@patch class Null {
 
   factory Null._uninstantiable() {
     throw new UnsupportedError("class Null cannot be instantiated");
   }
 
   static const _HASH_CODE = 2011; // The year Dart was announced and a prime.
-  int get _identityHashCode => _HASH_CODE;
   int get hashCode => _HASH_CODE;
+  int get _identityHashCode => _HASH_CODE;
 
-  String toString() {
-    return 'null';
-  }
+  String toString() => 'null';
 }
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index b450038..e1b7a71 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -39,9 +39,12 @@
 
 
 DEFINE_NATIVE_ENTRY(Object_getHash, 1) {
-  const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0));
+  // Please note that no handle is created for the argument.
+  // This is safe since the argument is only used in a tail call.
+  // The performance benefit is more than 5% when using hashCode.
   Heap* heap = isolate->heap();
-  return Smi::New(heap->GetHash(instance.raw()));
+  ASSERT(arguments->NativeArgAt(0)->IsDartInstance());
+  return Smi::New(heap->GetHash(arguments->NativeArgAt(0)));
 }
 
 
@@ -163,6 +166,37 @@
   return Bool::Get(negate.value() ? !is_instance_of : is_instance_of).raw();
 }
 
+DEFINE_NATIVE_ENTRY(Object_simpleInstanceOf, 2) {
+  // This native is only called when the right hand side passes
+  // simpleInstanceOfType and it is a non-negative test.
+  const Instance& instance =
+      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
+  const AbstractType& type =
+      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(1));
+  const TypeArguments& instantiator_type_arguments =
+      TypeArguments::Handle(TypeArguments::null());
+  ASSERT(type.IsFinalized());
+  ASSERT(!type.IsMalformed());
+  ASSERT(!type.IsMalbounded());
+  Error& bound_error = Error::Handle(zone, Error::null());
+  const bool is_instance_of = instance.IsInstanceOf(type,
+                                                    instantiator_type_arguments,
+                                                    &bound_error);
+  if (!is_instance_of && !bound_error.IsNull()) {
+    // Throw a dynamic type error only if the instanceof test fails.
+    DartFrameIterator iterator;
+    StackFrame* caller_frame = iterator.NextFrame();
+    ASSERT(caller_frame != NULL);
+    const TokenPosition location = caller_frame->GetTokenPos();
+    String& bound_error_message = String::Handle(
+        zone, String::New(bound_error.ToErrorCString()));
+    Exceptions::CreateAndThrowTypeError(
+        location, AbstractType::Handle(zone), AbstractType::Handle(zone),
+        Symbols::Empty(), bound_error_message);
+    UNREACHABLE();
+  }
+  return Bool::Get(is_instance_of).raw();
+}
 
 DEFINE_NATIVE_ENTRY(Object_instanceOfNum, 2) {
   const Instance& instance =
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index 7c4f5f5..0af593d 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.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.
 
-patch class Object {
+@patch class Object {
 
   // The VM has its own implementation of equals.
   bool operator ==(other) native "Object_equals";
@@ -15,22 +15,24 @@
   static _getHash(obj) native "Object_getHash";
   static _setHash(obj, hash) native "Object_setHash";
 
-  /* patch */ int get hashCode => _identityHashCode;
-
-  int get _identityHashCode {
-    var result = _getHash(this);
+  // Shared static implentation for hashCode and _identityHashCode.
+  static int _objectHashCode(obj) {
+    var result = _getHash(obj);
     if (result == 0) {
       // We want the hash to be a Smi value greater than 0.
       result = _hashCodeRnd.nextInt(0x40000000);
       while (result == 0) {
         result = _hashCodeRnd.nextInt(0x40000000);
       }
-      _setHash(this, result);
+      _setHash(obj, result);
     }
     return result;
   }
 
-  /* patch */ String toString() native "Object_toString";
+  @patch int get hashCode => _objectHashCode(this);
+  int get _identityHashCode => _objectHashCode(this);
+
+  @patch String toString() native "Object_toString";
   // A statically dispatched version of Object.toString.
   static String _toString(obj) native "Object_toString";
 
@@ -41,7 +43,7 @@
                 Map<String, dynamic> namedArguments)
       native "Object_noSuchMethod";
 
-  /* patch */ noSuchMethod(Invocation invocation) {
+  @patch noSuchMethod(Invocation invocation) {
     return _noSuchMethod(invocation.isMethod,
                          internal.Symbol.getName(invocation.memberName),
                          invocation._type,
@@ -49,13 +51,18 @@
                          _symbolMapToStringMap(invocation.namedArguments));
   }
 
-  /* patch */ Type get runtimeType native "Object_runtimeType";
+  @patch Type get runtimeType native "Object_runtimeType";
 
   // Call this function instead of inlining instanceof, thus collecting
   // type feedback and reducing code size of unoptimized code.
   bool _instanceOf(instantiator_type_arguments, type, bool negate)
       native "Object_instanceOf";
 
+  // Group of functions for implementing fast simple instance of.
+  bool _simpleInstanceOf(type) native "Object_simpleInstanceOf";
+  bool _simpleInstanceOfTrue(type) => true;
+  bool _simpleInstanceOfFalse(type) => false;
+
   bool _instanceOfDouble(bool negate) native "Object_instanceOfDouble";
   bool _instanceOfNum(bool negate) native "Object_instanceOfNum";
   bool _instanceOfInt(bool negate) native "Object_instanceOfInt";
diff --git a/runtime/lib/print_patch.dart b/runtime/lib/print_patch.dart
index 539294a..3df38d1 100644
--- a/runtime/lib/print_patch.dart
+++ b/runtime/lib/print_patch.dart
@@ -6,7 +6,7 @@
 // string is a line, but it may contain "\n" characters.
 typedef void _PrintClosure(String line);
 
-patch void printToConsole(String line) {
+@patch void printToConsole(String line) {
   _printClosure(line);
 }
 
diff --git a/runtime/lib/profiler.dart b/runtime/lib/profiler.dart
index 94d11ef..2a085c2 100644
--- a/runtime/lib/profiler.dart
+++ b/runtime/lib/profiler.dart
@@ -4,11 +4,11 @@
 
 import 'dart:_internal';
 
-patch class UserTag {
-  /* patch */ factory UserTag(String label) {
+@patch class UserTag {
+  @patch factory UserTag(String label) {
     return new _UserTag(label);
   }
-  /* patch */ static UserTag get defaultTag => _getDefaultTag();
+  @patch static UserTag get defaultTag => _getDefaultTag();
 }
 
 
@@ -18,7 +18,7 @@
   UserTag makeCurrent() native "UserTag_makeCurrent";
 }
 
-patch UserTag getCurrentTag() => _getCurrentTag();
+@patch UserTag getCurrentTag() => _getCurrentTag();
 UserTag _getCurrentTag() native "Profiler_getCurrentTag";
 
 UserTag _getDefaultTag() native "UserTag_defaultTag";
diff --git a/runtime/lib/regexp_patch.dart b/runtime/lib/regexp_patch.dart
index d8e622a..7e8bc19 100644
--- a/runtime/lib/regexp_patch.dart
+++ b/runtime/lib/regexp_patch.dart
@@ -4,10 +4,10 @@
 
 import "dart:collection" show LinkedList, LinkedListEntry;
 
-patch class RegExp {
-  /* patch */ factory RegExp(String source,
-                             {bool multiLine: false,
-                              bool caseSensitive: true}) {
+@patch class RegExp {
+  @patch factory RegExp(String source,
+                              {bool multiLine: false,
+                               bool caseSensitive: true}) {
     _RegExpHashKey key = new _RegExpHashKey(
         source, multiLine, caseSensitive);
     _RegExpHashValue value = _cache[key];
diff --git a/runtime/lib/resource_patch.dart b/runtime/lib/resource_patch.dart
index 0643516..76a7a9c 100644
--- a/runtime/lib/resource_patch.dart
+++ b/runtime/lib/resource_patch.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch class Resource {
-  /* patch */ const factory Resource(String uri) = _Resource;
+@patch class Resource {
+  @patch const factory Resource(String uri) = _Resource;
 }
 
 class _Resource implements Resource {
diff --git a/runtime/lib/schedule_microtask_patch.dart b/runtime/lib/schedule_microtask_patch.dart
index f08de2b..739f1f8 100644
--- a/runtime/lib/schedule_microtask_patch.dart
+++ b/runtime/lib/schedule_microtask_patch.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch class _AsyncRun {
-  /* patch */ static void _scheduleImmediate(void callback()) {
+@patch class _AsyncRun {
+  @patch static void _scheduleImmediate(void callback()) {
     if (_ScheduleImmediate._closure == null) {
       throw new UnsupportedError("Microtasks are not supported");
     }
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index a63d66d..12d6058 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -25,7 +25,7 @@
         skip_frames--;
       } else {
         code = frame->LookupDartCode();
-        offset = Smi::New(frame->pc() - code.EntryPoint());
+        offset = Smi::New(frame->pc() - code.PayloadStart());
         code_list.Add(code);
         pc_offset_list.Add(offset);
       }
diff --git a/runtime/lib/stopwatch_patch.dart b/runtime/lib/stopwatch_patch.dart
index e16005c..2560243 100644
--- a/runtime/lib/stopwatch_patch.dart
+++ b/runtime/lib/stopwatch_patch.dart
@@ -4,15 +4,15 @@
 
 // A VM patch of the stopwatch part of dart:core.
 
-patch class Stopwatch {
-  /* patch */ static void _initTicker() {
+@patch class Stopwatch {
+  @patch static void _initTicker() {
     if (_frequency == null) {
       _frequency = _computeFrequency();
     }
   }
 
   // Returns the current clock tick.
-  /* patch */ static int _now() native "Stopwatch_now";
+  @patch static int _now() native "Stopwatch_now";
 
   // Returns the frequency of clock ticks in Hz.
   static int _computeFrequency() native "Stopwatch_frequency";
diff --git a/runtime/lib/string_buffer_patch.dart b/runtime/lib/string_buffer_patch.dart
index 401d258..80dddd5 100644
--- a/runtime/lib/string_buffer_patch.dart
+++ b/runtime/lib/string_buffer_patch.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.
 
-patch class StringBuffer {
+@patch class StringBuffer {
   static const int _BUFFER_SIZE = 64;
   static const int _PARTS_TO_COMPACT = 128;
   static const int _PARTS_TO_COMPACT_SIZE_LIMIT = _PARTS_TO_COMPACT * 8;
@@ -48,20 +48,20 @@
   int _bufferCodeUnitMagnitude = 0;
 
   /// Creates the string buffer with an initial content.
-  /* patch */ StringBuffer([Object content = ""]) {
+  @patch StringBuffer([Object content = ""]) {
     write(content);
   }
 
-  /* patch */ int get length => _partsCodeUnits + _bufferPosition;
+  @patch int get length => _partsCodeUnits + _bufferPosition;
 
-  /* patch */ void write(Object obj) {
+  @patch void write(Object obj) {
     String str = '$obj';
     if (str.isEmpty) return;
     _consumeBuffer();
     _addPart(str);
   }
 
-  /* patch */ void writeCharCode(int charCode) {
+  @patch void writeCharCode(int charCode) {
     if (charCode <= 0xFFFF) {
       if (charCode < 0) {
         throw new RangeError.range(charCode, 0, 0x10FFFF);
@@ -81,7 +81,7 @@
     }
   }
 
-  /* patch */ void writeAll(Iterable objects, [String separator = ""]) {
+  @patch void writeAll(Iterable objects, [String separator = ""]) {
     Iterator iterator = objects.iterator;
     if (!iterator.moveNext()) return;
     if (separator.isEmpty) {
@@ -97,19 +97,19 @@
     }
   }
 
-  /* patch */ void writeln([Object obj = ""]) {
+  @patch void writeln([Object obj = ""]) {
     write(obj);
     write("\n");
   }
 
   /** Makes the buffer empty. */
-  /* patch */ void clear() {
+  @patch void clear() {
     _parts = null;
     _partsCodeUnits = _bufferPosition = _bufferCodeUnitMagnitude = 0;
   }
 
   /** Returns the contents of buffer as a string. */
-  /* patch */ String toString() {
+  @patch String toString() {
     _consumeBuffer();
     return (_partsCodeUnits == 0) ?
         "" :
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 4352245..17962df 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -7,16 +7,16 @@
 const int _maxUtf16 = 0xffff;
 const int _maxUnicode = 0x10ffff;
 
-patch class String {
-  /* patch */ factory String.fromCharCodes(Iterable<int> charCodes,
-                                           [int start = 0, int end]) {
+@patch class String {
+  @patch factory String.fromCharCodes(Iterable<int> charCodes,
+                                      [int start = 0, int end]) {
     if (charCodes is! Iterable) throw new ArgumentError.value(charCodes, "charCodes");
     if (start is! int) throw new ArgumentError.value(start, "start");
     if (end != null && end is! int) throw new ArgumentError.value(end, "end");
     return _StringBase.createFromCharCodes(charCodes, start, end, null);
   }
 
-  /* patch */ factory String.fromCharCode(int charCode) {
+  @patch factory String.fromCharCode(int charCode) {
     if (charCode >= 0) {
       if (charCode <= 0xff) {
         return _OneByteString._allocate(1).._setAt(0, charCode);
@@ -37,8 +37,8 @@
     throw new RangeError.range(charCode, 0, 0x10ffff);
   }
 
-  /* patch */ const factory String.fromEnvironment(String name,
-                                                   {String defaultValue})
+  @patch const factory String.fromEnvironment(String name,
+                                              {String defaultValue})
       native "String_fromEnvironment";
 }
 
diff --git a/runtime/lib/symbol_patch.dart b/runtime/lib/symbol_patch.dart
index 1a1b2bc..ee52cfc 100644
--- a/runtime/lib/symbol_patch.dart
+++ b/runtime/lib/symbol_patch.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.
 
-patch class Symbol {
-  /* patch */ const Symbol(String name)
+@patch class Symbol {
+  @patch const Symbol(String name)
       : this._name = name;
 
-  /* patch */ toString() => 'Symbol("${getUnmangledName(this)}")';
+  @patch toString() => 'Symbol("${getUnmangledName(this)}")';
 
   static getUnmangledName(Symbol symbol) {
     String string = Symbol.getName(symbol);
@@ -52,7 +52,7 @@
     return result.toString();
   }
 
-  /* patch */ int get hashCode {
+  @patch int get hashCode {
     const arbitraryPrime = 664597;
     return 0x1fffffff & (arbitraryPrime * _name.hashCode);
   }
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 6923e6f..300d6e3 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -16,12 +16,14 @@
 // Native implementations for the dart:developer library.
 
 DEFINE_NATIVE_ENTRY(Timeline_isDartStreamEnabled, 0) {
+#ifndef PRODUCT
   if (!FLAG_support_timeline) {
     return Bool::False().raw();
   }
   if (Timeline::GetDartStream()->enabled()) {
     return Bool::True().raw();
   }
+#endif  // !PRODUCT
   return Bool::False().raw();
 }
 
diff --git a/runtime/lib/timeline.dart b/runtime/lib/timeline.dart
index df43dec..da5760e 100644
--- a/runtime/lib/timeline.dart
+++ b/runtime/lib/timeline.dart
@@ -4,33 +4,33 @@
 
 import 'dart:_internal';
 
-patch bool _isDartStreamEnabled() native "Timeline_isDartStreamEnabled";
+@patch bool _isDartStreamEnabled() native "Timeline_isDartStreamEnabled";
 
-patch int _getTraceClock() native "Timeline_getTraceClock";
+@patch int _getTraceClock() native "Timeline_getTraceClock";
 
-patch int _getThreadCpuClock() native "Timeline_getThreadCpuClock";
+@patch int _getThreadCpuClock() native "Timeline_getThreadCpuClock";
 
-patch int _getNextAsyncId() native "Timeline_getNextAsyncId";
+@patch int _getNextAsyncId() native "Timeline_getNextAsyncId";
 
-patch int _getIsolateNum() native "Timeline_getIsolateNum";
+@patch int _getIsolateNum() native "Timeline_getIsolateNum";
 
-patch void _reportTaskEvent(
-    int start,
-    int taskId,
-    String phase,
-    String category,
-    String name,
-    String argumentsAsJson) native "Timeline_reportTaskEvent";
+@patch void _reportTaskEvent(
+     int start,
+     int taskId,
+     String phase,
+     String category,
+     String name,
+     String argumentsAsJson) native "Timeline_reportTaskEvent";
 
-patch void _reportCompleteEvent(
-    int start,
-    int end,
-    String category,
-    String name,
-    String argumentsAsJson) native "Timeline_reportCompleteEvent";
+@patch void _reportCompleteEvent(
+     int start,
+     int end,
+     String category,
+     String name,
+     String argumentsAsJson) native "Timeline_reportCompleteEvent";
 
-patch void _reportInstantEvent(
-    int start,
-    String category,
-    String name,
-    String argumentsAsJson) native "Timeline_reportInstantEvent";
+@patch void _reportInstantEvent(
+     int start,
+     String category,
+     String name,
+     String argumentsAsJson) native "Timeline_reportInstantEvent";
diff --git a/runtime/lib/timer_patch.dart b/runtime/lib/timer_patch.dart
index f975daa..2351d1b 100644
--- a/runtime/lib/timer_patch.dart
+++ b/runtime/lib/timer_patch.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch class Timer {
-  /*patch*/ static Timer _createTimer(Duration duration, void callback()) {
+@patch class Timer {
+  @patch static Timer _createTimer(Duration duration, void callback()) {
     // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively.
     if (_TimerFactory._factory == null) {
       _TimerFactory._factory = VMLibraryHooks.timerFactory;
@@ -16,7 +16,7 @@
     return _TimerFactory._factory(milliseconds, (_) { callback(); }, false);
   }
 
-  /*patch*/ static Timer _createPeriodicTimer(Duration duration,
+  @patch static Timer _createPeriodicTimer(Duration duration,
                                               void callback(Timer timer)) {
     // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively.
     if (_TimerFactory._factory == null) {
diff --git a/runtime/lib/uri_patch.dart b/runtime/lib/uri_patch.dart
index 2664b9b..0ce6b11 100644
--- a/runtime/lib/uri_patch.dart
+++ b/runtime/lib/uri_patch.dart
@@ -15,16 +15,18 @@
 // value for Uri.base.
 _UriBaseClosure _uriBaseClosure = _unsupportedUriBase;
 
-patch class Uri {
+@patch class Uri {
+  @patch static Uri get base => _uriBaseClosure();
+}
+
+@patch class _Uri {
   static final bool _isWindowsCached = _isWindowsPlatform;
 
-  /* patch */ static bool get _isWindows => _isWindowsCached;
-
-  /* patch */ static Uri get base => _uriBaseClosure();
-
   static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
 
-  /* patch */ static String _uriEncode(List<int> canonicalTable,
+  @patch static bool get _isWindows => _isWindowsCached;
+
+  @patch static String _uriEncode(List<int> canonicalTable,
                                        String text,
                                        Encoding encoding,
                                        bool spaceToPlus) {
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 831b9b8..b4a8b14 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -13,6 +13,7 @@
 #include "vm/native_entry.h"
 #include "vm/object.h"
 #include "vm/port.h"
+#include "vm/service_event.h"
 #include "vm/service_isolate.h"
 #include "vm/symbols.h"
 
@@ -415,8 +416,8 @@
 
   intptr_t archive_size = archive.Length();
 
-  const Array& result_list = Array::Handle(thread->zone(),
-    Array::New(2 * archive_size));
+  Dart_Handle result_list = Dart_NewList(2 * archive_size);
+  ASSERT(!Dart_IsError(result_list));
 
   intptr_t idx = 0;
   while (archive.HasMore()) {
@@ -437,17 +438,53 @@
     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));
+    Dart_ListSetAt(result_list, idx, dart_filename);
+    Dart_ListSetAt(result_list, (idx + 1), dart_contents);
     idx += 2;
   }
-
-  return result_list.raw();
+  return Api::UnwrapArrayHandle(thread->zone(), result_list).raw();
 #else
   return Object::null();
 #endif
 }
 
+
+
+DEFINE_NATIVE_ENTRY(VMService_spawnUriNotify, 2) {
+#ifndef PRODUCT
+  if (!FLAG_support_service) {
+    return Object::null();
+  }
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, result, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, token, arguments->NativeArgAt(1));
+
+  if (result.IsSendPort()) {
+    Dart_Port id = SendPort::Cast(result).Id();
+    Isolate* isolate = PortMap::GetIsolate(id);
+    if (isolate != NULL) {
+      ServiceEvent spawn_event(isolate, ServiceEvent::kIsolateSpawn);
+      spawn_event.set_spawn_token(&token);
+      Service::HandleEvent(&spawn_event);
+    } else {
+      // There is no isolate at the control port anymore.  Must have
+      // died already.
+      ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn);
+      const String& error = String::Handle(String::New(
+          "spawned isolate exited before notification completed"));
+      spawn_event.set_spawn_token(&token);
+      spawn_event.set_spawn_error(&error);
+      Service::HandleEvent(&spawn_event);
+    }
+  } else {
+    // The isolate failed to spawn.
+    ASSERT(result.IsString());
+    ServiceEvent spawn_event(NULL, ServiceEvent::kIsolateSpawn);
+    spawn_event.set_spawn_token(&token);
+    spawn_event.set_spawn_error(&String::Cast(result));
+    Service::HandleEvent(&spawn_event);
+  }
+#endif  // PRODUCT
+  return Object::null();
+}
+
 }  // namespace dart
diff --git a/runtime/lib/vmservice_patch.dart b/runtime/lib/vmservice_patch.dart
index e0a85ae..9e2dae6 100644
--- a/runtime/lib/vmservice_patch.dart
+++ b/runtime/lib/vmservice_patch.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.
 
-patch class Asset {
+@patch class Asset {
   /// Call to request assets from the embedder.
-  /* patch */ static HashMap<String, Asset> request() {
+  @patch static HashMap<String, Asset> request() {
     HashMap<String, Asset> assets = new HashMap<String, Asset>();
     Uint8List tarBytes = _requestAssets();
     if (tarBytes == null) {
@@ -21,16 +21,18 @@
 
 List _decodeAssets(Uint8List data) native "VMService_DecodeAssets";
 
-patch bool sendIsolateServiceMessage(SendPort sp, List m)
+@patch bool sendIsolateServiceMessage(SendPort sp, List m)
     native "VMService_SendIsolateServiceMessage";
-patch void sendRootServiceMessage(List m)
+@patch void sendRootServiceMessage(List m)
     native "VMService_SendRootServiceMessage";
-patch void sendObjectRootServiceMessage(List m)
+@patch void sendObjectRootServiceMessage(List m)
     native "VMService_SendObjectRootServiceMessage";
-patch void _onStart() native "VMService_OnStart";
-patch void _onExit() native "VMService_OnExit";
-patch void onServerAddressChange(String address)
+@patch void _onStart() native "VMService_OnStart";
+@patch void _onExit() native "VMService_OnExit";
+@patch void onServerAddressChange(String address)
     native "VMService_OnServerAddressChange";
-patch bool _vmListenStream(String streamId) native "VMService_ListenStream";
-patch void _vmCancelStream(String streamId) native "VMService_CancelStream";
-patch Uint8List _requestAssets() native "VMService_RequestAssets";
+@patch bool _vmListenStream(String streamId) native "VMService_ListenStream";
+@patch void _vmCancelStream(String streamId) native "VMService_CancelStream";
+@patch Uint8List _requestAssets() native "VMService_RequestAssets";
+@patch void _spawnUriNotify(obj, String token)
+    native "VMService_spawnUriNotify";
diff --git a/runtime/observatory/HACKING.md b/runtime/observatory/HACKING.md
index af74bda..e8c5500 100644
--- a/runtime/observatory/HACKING.md
+++ b/runtime/observatory/HACKING.md
@@ -69,7 +69,7 @@
 ```
 Start the script:
 ```
-$ dart --observe clock.dart
+$ dart --disable-service-origin-check --observe clock.dart
 ```
 
 ## Code Reviews
diff --git a/runtime/observatory/lib/allocation_profile.dart b/runtime/observatory/lib/allocation_profile.dart
new file mode 100644
index 0000000..8086276
--- /dev/null
+++ b/runtime/observatory/lib/allocation_profile.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library allocation_profiler;
+
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/service.dart' as S;
+
+part 'src/allocation_profile/allocation_profile.dart';
diff --git a/runtime/observatory/lib/app.dart b/runtime/observatory/lib/app.dart
index 15e802d..0b85c8b 100644
--- a/runtime/observatory/lib/app.dart
+++ b/runtime/observatory/lib/app.dart
@@ -7,11 +7,12 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:html';
-import 'dart:math' as math;
 
 import 'package:logging/logging.dart';
 import 'package:observatory/service_html.dart';
 import 'package:observatory/elements.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/repositories.dart';
 import 'package:observatory/tracer.dart';
 import 'package:observatory/utils.dart';
 import 'package:polymer/polymer.dart';
@@ -20,9 +21,10 @@
 export 'package:observatory/utils.dart';
 
 part 'src/app/application.dart';
+part 'src/app/event.dart';
 part 'src/app/location_manager.dart';
+part 'src/app/notification.dart';
 part 'src/app/page.dart';
 part 'src/app/settings.dart';
-part 'src/app/target_manager.dart';
 part 'src/app/view_model.dart';
 part 'src/app/analytics.dart';
diff --git a/runtime/observatory/lib/cpu_profile.dart b/runtime/observatory/lib/cpu_profile.dart
index c8a2b53..ccc53c5 100644
--- a/runtime/observatory/lib/cpu_profile.dart
+++ b/runtime/observatory/lib/cpu_profile.dart
@@ -4,7 +4,9 @@
 
 library cpu_profiler;
 
+import 'dart:async';
 import 'dart:typed_data';
+import 'package:observatory/models.dart' as M;
 import 'package:observatory/service.dart';
 import 'package:observatory/utils.dart';
 
diff --git a/runtime/observatory/lib/debugger.dart b/runtime/observatory/lib/debugger.dart
index 628b2a9..c62ce0b 100644
--- a/runtime/observatory/lib/debugger.dart
+++ b/runtime/observatory/lib/debugger.dart
@@ -5,6 +5,7 @@
 library debugger;
 
 import 'dart:async';
+import 'package:observatory/models.dart' as M;
 import 'package:observatory/service.dart';
 
 part 'src/debugger/debugger.dart';
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index 9ee5cf2..05f13ab 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -2,60 +2,246 @@
 
 // Export elements.
 export 'package:observatory/src/elements/action_link.dart';
-export 'package:observatory/src/elements/class_ref.dart';
-export 'package:observatory/src/elements/class_tree.dart';
+export 'package:observatory/src/elements/class_ref_as_value.dart';
 export 'package:observatory/src/elements/class_view.dart';
-export 'package:observatory/src/elements/code_ref.dart';
 export 'package:observatory/src/elements/code_view.dart';
-export 'package:observatory/src/elements/context_ref.dart';
 export 'package:observatory/src/elements/context_view.dart';
-export 'package:observatory/src/elements/cpu_profile.dart';
-export 'package:observatory/src/elements/curly_block.dart';
+export 'package:observatory/src/elements/cpu_profile_table.dart';
 export 'package:observatory/src/elements/debugger.dart';
 export 'package:observatory/src/elements/error_view.dart';
 export 'package:observatory/src/elements/eval_box.dart';
 export 'package:observatory/src/elements/eval_link.dart';
-export 'package:observatory/src/elements/field_ref.dart';
 export 'package:observatory/src/elements/field_view.dart';
-export 'package:observatory/src/elements/flag_list.dart';
-export 'package:observatory/src/elements/function_ref.dart';
 export 'package:observatory/src/elements/function_view.dart';
-export 'package:observatory/src/elements/general_error.dart';
 export 'package:observatory/src/elements/heap_map.dart';
-export 'package:observatory/src/elements/heap_profile.dart';
 export 'package:observatory/src/elements/heap_snapshot.dart';
 export 'package:observatory/src/elements/icdata_view.dart';
-export 'package:observatory/src/elements/instance_ref.dart';
 export 'package:observatory/src/elements/instance_view.dart';
-export 'package:observatory/src/elements/instructions_view.dart';
-export 'package:observatory/src/elements/io_view.dart';
 export 'package:observatory/src/elements/isolate_reconnect.dart';
-export 'package:observatory/src/elements/isolate_ref.dart';
 export 'package:observatory/src/elements/isolate_summary.dart';
 export 'package:observatory/src/elements/isolate_view.dart';
 export 'package:observatory/src/elements/json_view.dart';
-export 'package:observatory/src/elements/library_ref.dart';
+export 'package:observatory/src/elements/library_ref_as_value.dart';
 export 'package:observatory/src/elements/library_view.dart';
 export 'package:observatory/src/elements/logging.dart';
 export 'package:observatory/src/elements/megamorphiccache_view.dart';
 export 'package:observatory/src/elements/metrics.dart';
-export 'package:observatory/src/elements/nav_bar.dart';
 export 'package:observatory/src/elements/object_common.dart';
 export 'package:observatory/src/elements/object_view.dart';
 export 'package:observatory/src/elements/objectpool_view.dart';
 export 'package:observatory/src/elements/objectstore_view.dart';
-export 'package:observatory/src/elements/observatory_application.dart';
 export 'package:observatory/src/elements/observatory_element.dart';
 export 'package:observatory/src/elements/persistent_handles.dart';
 export 'package:observatory/src/elements/ports.dart';
 export 'package:observatory/src/elements/script_inset.dart';
-export 'package:observatory/src/elements/script_ref.dart';
 export 'package:observatory/src/elements/script_view.dart';
 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';
 export 'package:observatory/src/elements/vm_view.dart';
+
+import 'dart:async';
+
+import 'package:observatory/src/elements/allocation_profile.dart';
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/class_ref_wrapper.dart';
+import 'package:observatory/src/elements/class_tree.dart';
+import 'package:observatory/src/elements/code_ref.dart';
+import 'package:observatory/src/elements/code_ref_wrapper.dart';
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/context_ref_wrapper.dart';
+import 'package:observatory/src/elements/containers/virtual_collection.dart';
+import 'package:observatory/src/elements/containers/virtual_tree.dart';
+import 'package:observatory/src/elements/cpu_profile.dart';
+import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/curly_block_wrapper.dart';
+import 'package:observatory/src/elements/error_ref.dart';
+import 'package:observatory/src/elements/error_ref_wrapper.dart';
+import 'package:observatory/src/elements/field_ref.dart';
+import 'package:observatory/src/elements/field_ref_wrapper.dart';
+import 'package:observatory/src/elements/flag_list.dart';
+import 'package:observatory/src/elements/function_ref.dart';
+import 'package:observatory/src/elements/function_ref_wrapper.dart';
+import 'package:observatory/src/elements/general_error.dart';
+import 'package:observatory/src/elements/icdata_ref.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/instance_ref_wrapper.dart';
+import 'package:observatory/src/elements/isolate_reconnect.dart';
+import 'package:observatory/src/elements/isolate_ref.dart';
+import 'package:observatory/src/elements/isolate_ref_wrapper.dart';
+import 'package:observatory/src/elements/isolate/counter_chart.dart';
+import 'package:observatory/src/elements/isolate/shared_summary.dart';
+import 'package:observatory/src/elements/isolate/shared_summary_wrapper.dart';
+import 'package:observatory/src/elements/library_ref.dart';
+import 'package:observatory/src/elements/library_ref_wrapper.dart';
+import 'package:observatory/src/elements/local_var_descriptors_ref.dart';
+import 'package:observatory/src/elements/megamorphiccache_ref.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/class_menu.dart';
+import 'package:observatory/src/elements/nav/class_menu_wrapper.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/isolate_menu_wrapper.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import 'package:observatory/src/elements/nav/library_menu_wrapper.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/menu_wrapper.dart';
+import 'package:observatory/src/elements/nav/menu_item.dart';
+import 'package:observatory/src/elements/nav/menu_item_wrapper.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/notify_wrapper.dart';
+import 'package:observatory/src/elements/nav/notify_event.dart';
+import 'package:observatory/src/elements/nav/notify_exception.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/refresh_wrapper.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/top_menu_wrapper.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu_wrapper.dart';
+import 'package:observatory/src/elements/observatory_application.dart';
+import 'package:observatory/src/elements/objectpool_ref.dart';
+import 'package:observatory/src/elements/pc_descriptors_ref.dart';
+import 'package:observatory/src/elements/sample_buffer_control.dart';
+import 'package:observatory/src/elements/script_ref.dart';
+import 'package:observatory/src/elements/script_ref_wrapper.dart';
+import 'package:observatory/src/elements/sentinel_value.dart';
+import 'package:observatory/src/elements/source_link.dart';
+import 'package:observatory/src/elements/source_link_wrapper.dart';
+import 'package:observatory/src/elements/stack_trace_tree_config.dart';
+import 'package:observatory/src/elements/token_stream_ref.dart';
+import 'package:observatory/src/elements/unknown_ref.dart';
+import 'package:observatory/src/elements/view_footer.dart';
+import 'package:observatory/src/elements/vm_connect_target.dart';
+import 'package:observatory/src/elements/vm_connect.dart';
+
+export 'package:observatory/src/elements/helpers/rendering_queue.dart';
+
+export 'package:observatory/src/elements/allocation_profile.dart';
+export 'package:observatory/src/elements/class_ref.dart';
+export 'package:observatory/src/elements/class_tree.dart';
+export 'package:observatory/src/elements/code_ref.dart';
+export 'package:observatory/src/elements/containers/virtual_collection.dart';
+export 'package:observatory/src/elements/containers/virtual_tree.dart';
+export 'package:observatory/src/elements/context_ref.dart';
+export 'package:observatory/src/elements/cpu_profile.dart';
+export 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
+export 'package:observatory/src/elements/curly_block.dart';
+export 'package:observatory/src/elements/error_ref.dart';
+export 'package:observatory/src/elements/field_ref.dart';
+export 'package:observatory/src/elements/flag_list.dart';
+export 'package:observatory/src/elements/function_ref.dart';
+export 'package:observatory/src/elements/general_error.dart';
+export 'package:observatory/src/elements/icdata_ref.dart';
+export 'package:observatory/src/elements/instance_ref.dart';
+export 'package:observatory/src/elements/isolate_reconnect.dart';
+export 'package:observatory/src/elements/isolate_ref.dart';
+export 'package:observatory/src/elements/isolate/counter_chart.dart';
+export 'package:observatory/src/elements/isolate/shared_summary.dart';
+export 'package:observatory/src/elements/library_ref.dart';
+export 'package:observatory/src/elements/local_var_descriptors_ref.dart';
+export 'package:observatory/src/elements/megamorphiccache_ref.dart';
+export 'package:observatory/src/elements/nav/bar.dart';
+export 'package:observatory/src/elements/nav/class_menu.dart';
+export 'package:observatory/src/elements/nav/isolate_menu.dart';
+export 'package:observatory/src/elements/nav/library_menu.dart';
+export 'package:observatory/src/elements/nav/menu.dart';
+export 'package:observatory/src/elements/nav/menu_item.dart';
+export 'package:observatory/src/elements/nav/notify.dart';
+export 'package:observatory/src/elements/nav/notify_event.dart';
+export 'package:observatory/src/elements/nav/notify_exception.dart';
+export 'package:observatory/src/elements/nav/refresh.dart';
+export 'package:observatory/src/elements/nav/top_menu.dart';
+export 'package:observatory/src/elements/nav/vm_menu.dart';
+export 'package:observatory/src/elements/observatory_application.dart';
+export 'package:observatory/src/elements/objectpool_ref.dart';
+export 'package:observatory/src/elements/pc_descriptors_ref.dart';
+export 'package:observatory/src/elements/sample_buffer_control.dart';
+export 'package:observatory/src/elements/script_ref.dart';
+export 'package:observatory/src/elements/sentinel_value.dart';
+export 'package:observatory/src/elements/source_link.dart';
+export 'package:observatory/src/elements/stack_trace_tree_config.dart';
+export 'package:observatory/src/elements/token_stream_ref.dart';
+export 'package:observatory/src/elements/unknown_ref.dart';
+export 'package:observatory/src/elements/view_footer.dart';
+export 'package:observatory/src/elements/vm_connect_target.dart';
+export 'package:observatory/src/elements/vm_connect.dart';
+
+// Even though this function does not invoke any asynchronous operation
+// it is marked as async to allow future backward compatible changes.
+Future initElements() async {
+  AllocationProfileElement.tag.ensureRegistration();
+  ClassRefElement.tag.ensureRegistration();
+  ClassRefElementWrapper.tag.ensureRegistration();
+  ClassTreeElement.tag.ensureRegistration();
+  CodeRefElement.tag.ensureRegistration();
+  CodeRefElementWrapper.tag.ensureRegistration();
+  ContextRefElement.tag.ensureRegistration();
+  ContextRefElementWrapper.tag.ensureRegistration();
+  CpuProfileElement.tag.ensureRegistration();
+  CpuProfileVirtualTreeElement.tag.ensureRegistration();
+  CurlyBlockElement.tag.ensureRegistration();
+  CurlyBlockElementWrapper.tag.ensureRegistration();
+  ErrorRefElement.tag.ensureRegistration();
+  ErrorRefElementWrapper.tag.ensureRegistration();
+  FieldRefElement.tag.ensureRegistration();
+  FieldRefElementWrapper.tag.ensureRegistration();
+  FlagListElement.tag.ensureRegistration();
+  FunctionRefElement.tag.ensureRegistration();
+  FunctionRefElementWrapper.tag.ensureRegistration();
+  GeneralErrorElement.tag.ensureRegistration();
+  ICDataRefElement.tag.ensureRegistration();
+  InstanceRefElement.tag.ensureRegistration();
+  InstanceRefElementWrapper.tag.ensureRegistration();
+  IsolateCounterChartElement.tag.ensureRegistration();
+  IsolateReconnectElement.tag.ensureRegistration();
+  IsolateRefElement.tag.ensureRegistration();
+  IsolateRefElementWrapper.tag.ensureRegistration();
+  IsolateSharedSummaryElement.tag.ensureRegistration();
+  IsolateSharedSummaryElementWrapper.tag.ensureRegistration();
+  LibraryRefElement.tag.ensureRegistration();
+  LibraryRefElementWrapper.tag.ensureRegistration();
+  LocalVarDescriptorsRefElement.tag.ensureRegistration();
+  MegamorphicCacheRefElement.tag.ensureRegistration();
+  NavBarElement.tag.ensureRegistration();
+  NavClassMenuElement.tag.ensureRegistration();
+  NavClassMenuElementWrapper.tag.ensureRegistration();
+  NavIsolateMenuElement.tag.ensureRegistration();
+  NavIsolateMenuElementWrapper.tag.ensureRegistration();
+  NavLibraryMenuElement.tag.ensureRegistration();
+  NavLibraryMenuElementWrapper.tag.ensureRegistration();
+  NavMenuElement.tag.ensureRegistration();
+  NavMenuElementWrapper.tag.ensureRegistration();
+  NavMenuItemElement.tag.ensureRegistration();
+  NavMenuItemElementWrapper.tag.ensureRegistration();
+  NavNotifyElement.tag.ensureRegistration();
+  NavNotifyElementWrapper.tag.ensureRegistration();
+  NavNotifyEventElement.tag.ensureRegistration();
+  NavNotifyExceptionElement.tag.ensureRegistration();
+  NavRefreshElement.tag.ensureRegistration();
+  NavRefreshElementWrapper.tag.ensureRegistration();
+  NavTopMenuElement.tag.ensureRegistration();
+  NavTopMenuElementWrapper.tag.ensureRegistration();
+  NavVMMenuElement.tag.ensureRegistration();
+  NavVMMenuElementWrapper.tag.ensureRegistration();
+  ObservatoryApplicationElement.tag.ensureRegistration();
+  ObjectPoolRefElement.tag.ensureRegistration();
+  PcDescriptorsRefElement.tag.ensureRegistration();
+  ScriptRefElement.tag.ensureRegistration();
+  SampleBufferControlElement.tag.ensureRegistration();
+  ScriptRefElement.tag.ensureRegistration();
+  ScriptRefElementWrapper.tag.ensureRegistration();
+  SentinelValueElement.tag.ensureRegistration();
+  SourceLinkElement.tag.ensureRegistration();
+  SourceLinkElementWrapper.tag.ensureRegistration();
+  StackTraceTreeConfigElement.tag.ensureRegistration();
+  TokenStreamRefElement.tag.ensureRegistration();
+  UnknownObjectRefElement.tag.ensureRegistration();
+  ViewFooterElement.tag.ensureRegistration();
+  VirtualCollectionElement.tag.ensureRegistration();
+  VirtualTreeElement.tag.ensureRegistration();
+  VMConnectElement.tag.ensureRegistration();
+  VirtualCollectionElement.tag.ensureRegistration();
+  VirtualTreeElement.tag.ensureRegistration();
+  VMConnectTargetElement.tag.ensureRegistration();
+}
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 52b59b4..b022a12 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -1,53 +1,34 @@
 <link rel="import" href="src/elements/action_link.html">
-<link rel="import" href="src/elements/class_ref.html">
-<link rel="import" href="src/elements/class_tree.html">
+<link rel="import" href="src/elements/class_ref_as_value.html">
 <link rel="import" href="src/elements/class_view.html">
-<link rel="import" href="src/elements/code_ref.html">
 <link rel="import" href="src/elements/code_view.html">
-<link rel="import" href="src/elements/cpu_profile.html">
-<link rel="import" href="src/elements/curly_block.html">
+<link rel="import" href="src/elements/cpu_profile_table.html">
 <link rel="import" href="src/elements/debugger.html">
 <link rel="import" href="src/elements/error_view.html">
 <link rel="import" href="src/elements/eval_box.html">
 <link rel="import" href="src/elements/eval_link.html">
-<link rel="import" href="src/elements/field_ref.html">
 <link rel="import" href="src/elements/field_view.html">
-<link rel="import" href="src/elements/flag_list.html">
-<link rel="import" href="src/elements/function_ref.html">
 <link rel="import" href="src/elements/function_view.html">
-<link rel="import" href="src/elements/general_error.html">
 <link rel="import" href="src/elements/heap_map.html">
-<link rel="import" href="src/elements/instance_ref.html">
 <link rel="import" href="src/elements/instance_view.html">
-<link rel="import" href="src/elements/io_view.html">
 <link rel="import" href="src/elements/icdata_view.html">
-<link rel="import" href="src/elements/instructions_view.html">
-<link rel="import" href="src/elements/isolate_reconnect.html">
-<link rel="import" href="src/elements/isolate_ref.html">
 <link rel="import" href="src/elements/isolate_summary.html">
 <link rel="import" href="src/elements/isolate_view.html">
 <link rel="import" href="src/elements/json_view.html">
-<link rel="import" href="src/elements/library_ref.html">
+<link rel="import" href="src/elements/library_ref_as_value.html">
 <link rel="import" href="src/elements/library_view.html">
 <link rel="import" href="src/elements/logging.html">
 <link rel="import" href="src/elements/megamorphiccache_view.html">
 <link rel="import" href="src/elements/metrics.html">
-<link rel="import" href="src/elements/nav_bar.html">
 <link rel="import" href="src/elements/object_common.html">
 <link rel="import" href="src/elements/object_view.html">
 <link rel="import" href="src/elements/objectpool_view.html">
 <link rel="import" href="src/elements/objectstore_view.html">
-<link rel="import" href="src/elements/observatory_application.html">
-<link rel="import" href="src/elements/observatory_element.html">
 <link rel="import" href="src/elements/persistent_handles.html">
 <link rel="import" href="src/elements/ports.html">
 <link rel="import" href="src/elements/script_inset.html">
-<link rel="import" href="src/elements/script_ref.html">
 <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/service_view.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">
 <link rel="import" href="src/elements/vm_view.html">
diff --git a/runtime/observatory/lib/models.dart b/runtime/observatory/lib/models.dart
new file mode 100644
index 0000000..2a48dd9
--- /dev/null
+++ b/runtime/observatory/lib/models.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.
+
+library models;
+
+import 'dart:async';
+
+part 'src/models/exceptions.dart';
+
+part 'src/models/objects/allocation_profile.dart';
+part 'src/models/objects/breakpoint.dart';
+part 'src/models/objects/bound_field.dart';
+part 'src/models/objects/class.dart';
+part 'src/models/objects/code.dart';
+part 'src/models/objects/context.dart';
+part 'src/models/objects/error.dart';
+part 'src/models/objects/event.dart';
+part 'src/models/objects/extension_data.dart';
+part 'src/models/objects/field.dart';
+part 'src/models/objects/flag.dart';
+part 'src/models/objects/frame.dart';
+part 'src/models/objects/function.dart';
+part 'src/models/objects/guarded.dart';
+part 'src/models/objects/heap_space.dart';
+part 'src/models/objects/icdata.dart';
+part 'src/models/objects/instance.dart';
+part 'src/models/objects/isolate.dart';
+part 'src/models/objects/library.dart';
+part 'src/models/objects/local_var_descriptors.dart';
+part 'src/models/objects/map_association.dart';
+part 'src/models/objects/megamorphiccache.dart';
+part 'src/models/objects/notification.dart';
+part 'src/models/objects/object.dart';
+part 'src/models/objects/objectpool.dart';
+part 'src/models/objects/pc_descriptors.dart';
+part 'src/models/objects/sample_profile.dart';
+part 'src/models/objects/script.dart';
+part 'src/models/objects/sentinel.dart';
+part 'src/models/objects/source_location.dart';
+part 'src/models/objects/target.dart';
+part 'src/models/objects/token_stream.dart';
+part 'src/models/objects/timeline_event.dart';
+part 'src/models/objects/unknown.dart';
+part 'src/models/objects/vm.dart';
+
+part 'src/models/repositories/allocation_profile.dart';
+part 'src/models/repositories/class.dart';
+part 'src/models/repositories/event.dart';
+part 'src/models/repositories/flag.dart';
+part 'src/models/repositories/instance.dart';
+part 'src/models/repositories/notification.dart';
+part 'src/models/repositories/sample_profile.dart';
+part 'src/models/repositories/script.dart';
+part 'src/models/repositories/target.dart';
diff --git a/runtime/observatory/lib/repositories.dart b/runtime/observatory/lib/repositories.dart
new file mode 100644
index 0000000..d566041
--- /dev/null
+++ b/runtime/observatory/lib/repositories.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library repositories;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:html';
+import 'package:observatory/allocation_profile.dart';
+import 'package:observatory/cpu_profile.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/service.dart' as S;
+import 'package:observatory/service_common.dart' as SC;
+import 'package:observatory/utils.dart';
+
+part 'src/repositories/allocation_profile.dart';
+part 'src/repositories/class.dart';
+part 'src/repositories/event.dart';
+part 'src/repositories/flag.dart';
+part 'src/repositories/instance.dart';
+part 'src/repositories/notification.dart';
+part 'src/repositories/sample_profile.dart';
+part 'src/repositories/script.dart';
+part 'src/repositories/settings.dart';
+part 'src/repositories/target.dart';
diff --git a/runtime/observatory/lib/service.dart b/runtime/observatory/lib/service.dart
index cb6f317..c3775a3 100644
--- a/runtime/observatory/lib/service.dart
+++ b/runtime/observatory/lib/service.dart
@@ -11,6 +11,7 @@
 
 import 'package:logging/logging.dart';
 import 'package:observatory/cpu_profile.dart';
+import 'package:observatory/models.dart' as M;
 import 'package:observatory/object_graph.dart';
 import 'package:observatory/tracer.dart';
 import 'package:observe/observe.dart';
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index ba55349..cd146ee 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -9,13 +9,14 @@
 import 'dart:typed_data';
 
 import 'package:logging/logging.dart';
+import 'package:observatory/models.dart' as M;
 import 'package:observatory/service.dart';
 
 // Export the service library.
 export 'package:observatory/service.dart';
 
 /// Description of a VM target.
-class WebSocketVMTarget {
+class WebSocketVMTarget implements M.Target {
   // Last time this VM has been connected to.
   int lastConnectionTime = 0;
   bool get hasEverConnected => lastConnectionTime > 0;
@@ -90,6 +91,8 @@
   bool _hasFinishedConnect = false;
   Utf8Decoder _utf8Decoder = const Utf8Decoder();
 
+  String get displayName => '${name}@${target.name}';
+
   CommonWebSocket _webSocket;
 
   CommonWebSocketVM(this.target, this._webSocket) {
diff --git a/runtime/observatory/lib/src/allocation_profile/allocation_profile.dart b/runtime/observatory/lib/src/allocation_profile/allocation_profile.dart
new file mode 100644
index 0000000..739597b
--- /dev/null
+++ b/runtime/observatory/lib/src/allocation_profile/allocation_profile.dart
@@ -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.
+
+part of allocation_profiler;
+
+class AllocationProfile implements M.AllocationProfile {
+  static const _lastServiceGC = 'dateLastServiceGC';
+  final DateTime lastServiceGC;
+  static const _lastAccumulatorReset = 'dateLastAccumulatorReset';
+  final DateTime lastAccumulatorReset;
+  final S.HeapSpace newSpace;
+  final S.HeapSpace oldSpace;
+  final Iterable<ClassHeapStats> members;
+
+  AllocationProfile(S.ServiceMap map)
+    : lastAccumulatorReset = _intString2DateTime(map[_lastAccumulatorReset]),
+      lastServiceGC = _intString2DateTime(map[_lastServiceGC]),
+      oldSpace = new S.HeapSpace()..update(map['heaps']['old']),
+      newSpace = new S.HeapSpace()..update(map['heaps']['new']),
+      members = map['members'].map(_convertMember).toList();
+
+  static DateTime _intString2DateTime(String milliseconds) {
+    if ((milliseconds == null) || milliseconds == '') {
+      return null;
+    }
+    return new DateTime.fromMillisecondsSinceEpoch(int.parse(milliseconds));
+  }
+
+  static ClassHeapStats _convertMember(S.ServiceMap map) {
+    assert(map['type'] == 'ClassHeapStats');
+    return new ClassHeapStats(map);
+  }
+}
+
+class ClassHeapStats implements M.ClassHeapStats {
+  final S.Class clazz;
+  final S.Allocations newSpace;
+  final S.Allocations oldSpace;
+  final int promotedInstances;
+  final int promotedBytes;
+
+  ClassHeapStats(S.ServiceMap map)
+    : clazz = map['class'],
+      oldSpace = new S.Allocations()..update(map['old']),
+      newSpace = new S.Allocations()..update(map['new']),
+      promotedInstances = map['promotedInstances'],
+      promotedBytes = map['promotedBytes'];
+}
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index be95803..3ab1142 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -4,19 +4,14 @@
 
 part of app;
 
-class Notification {
-  Notification.fromEvent(this.event);
-  Notification.fromException(this.exception, this.stacktrace);
-
-  ServiceEvent event;
-  var exception;
-  var stacktrace;
-}
-
 /// The observatory application. Instances of this are created and owned
 /// by the observatory_application custom element.
 class ObservatoryApplication extends Observable {
   static ObservatoryApplication app;
+  final RenderingQueue queue = new RenderingQueue();
+  final TargetRepository targets = new TargetRepository();
+  final EventRepository events = new EventRepository();
+  final NotificationRepository notifications = new NotificationRepository();
   final _pageRegistry = new List<Page>();
   LocationManager _locationManager;
   LocationManager get locationManager => _locationManager;
@@ -24,24 +19,22 @@
   VM _vm;
   VM get vm => _vm;
 
-  set vm(VM vm) {
+  _setVM(VM vm) {
     if (_vm == vm) {
       // Do nothing.
       return;
     }
     if (_vm != null) {
+      _gcSubscription = null;
       // Disconnect from current VM.
-      notifications.clear();
+      notifications.deleteAll();
       _vm.disconnect();
     }
     if (vm != null) {
       Logger.root.info('Registering new VM callbacks');
 
       vm.onConnect.then((_) {
-        if (vm is WebSocketVM) {
-          targets.add(vm.target);
-        }
-        _removeDisconnectEvents();
+        notifications.deleteDisconnectEvents();
       });
 
       vm.onDisconnect.then((String reason) {
@@ -49,24 +42,40 @@
           // This disconnect event occured *after* a new VM was installed.
           return;
         }
-        notifications.add(
-            new Notification.fromEvent(
-                new ServiceEvent.connectionClosed(reason)));
+        events.add(new ConnectionClosedEvent(new DateTime.now(), reason));
       });
 
+      // TODO(cbernaschina) smart connection of streams in the events object.
+      vm.listenEventStream(VM.kVMStream, _onEvent);
       vm.listenEventStream(VM.kIsolateStream, _onEvent);
       vm.listenEventStream(VM.kDebugStream, _onEvent);
     }
     _vm = vm;
   }
-  final TargetManager targets;
+
+  StreamSubscription _gcSubscription;
+
+  Future startGCEventListener() async {
+    if (_gcSubscription != null || _vm == null) {
+      return;
+    }
+    _gcSubscription = await _vm.listenEventStream(VM.kGCStream, _onEvent);
+  }
+
+  Future stopGCEventListener() async {
+    if (_gcSubscription == null) {
+      return;
+    }
+    _gcSubscription.cancel();
+    _gcSubscription = null;
+  }
+
+
   @reflectable final ObservatoryApplicationElement rootElement;
 
   TraceViewElement _traceView = null;
 
   @reflectable ServiceObject lastErrorOrException;
-  @observable ObservableList<Notification> notifications =
-      new ObservableList<Notification>();
 
   void _initOnce() {
     assert(app == null);
@@ -77,57 +86,87 @@
     locationManager._visit();
   }
 
-  void removePauseEvents(Isolate isolate) {
-    notifications.removeWhere((notification) {
-        var event = notification.event;
-        return (event != null &&
-                event.isolate == isolate &&
-                event.isPauseEvent);
-      });
+  void _deletePauseEvents(e) {
+    notifications.deletePauseEvents(isolate: e.isolate);
+  }
+  void _addNotification(M.Event e) {
+    notifications.add(new EventNotification(e));
   }
 
   void _onEvent(ServiceEvent event) {
     assert(event.kind != ServiceEvent.kNone);
 
+    M.Event e;
+
     switch(event.kind) {
       case ServiceEvent.kVMUpdate:
+        e = new VMUpdateEvent(event.timestamp, event.vm);
+        break;
       case ServiceEvent.kIsolateStart:
+        e = new IsolateStartEvent(event.timestamp, event.isolate);
+        break;
       case ServiceEvent.kIsolateRunnable:
+        e = new IsolateRunnableEvent(event.timestamp, event.isolate);
+        break;
       case ServiceEvent.kIsolateUpdate:
-      case ServiceEvent.kBreakpointAdded:
-      case ServiceEvent.kBreakpointResolved:
-      case ServiceEvent.kBreakpointRemoved:
-      case ServiceEvent.kDebuggerSettingsUpdate:
-        // Ignore for now.
+        e = new IsolateUpdateEvent(event.timestamp, event.isolate);
         break;
-
       case ServiceEvent.kIsolateReload:
-        notifications.add(new Notification.fromEvent(event));
+        e = new IsolateReloadEvent(event.timestamp, event.isolate, event.error);
         break;
-
       case ServiceEvent.kIsolateExit:
+        e = new IsolateExitEvent(event.timestamp, event.isolate);
+        break;
+      case ServiceEvent.kBreakpointAdded:
+        e = new BreakpointAddedEvent(event.timestamp, event.isolate,
+            event.breakpoint);
+        break;
+      case ServiceEvent.kBreakpointResolved:
+        e = new BreakpointResolvedEvent(event.timestamp, event.isolate,
+            event.breakpoint);
+        break;
+      case ServiceEvent.kBreakpointRemoved:
+        e = new BreakpointRemovedEvent(event.timestamp, event.isolate,
+          event.breakpoint);
+        break;
+      case ServiceEvent.kDebuggerSettingsUpdate:
+        e = new DebuggerSettingsUpdateEvent(event.timestamp, event.isolate);
+        break;
       case ServiceEvent.kResume:
-        removePauseEvents(event.isolate);
+        e = new ResumeEvent(event.timestamp, event.isolate, event.topFrame);
         break;
-
       case ServiceEvent.kPauseStart:
+        e = new PauseStartEvent(event.timestamp, event.isolate);
+        break;
       case ServiceEvent.kPauseExit:
+        e = new PauseExitEvent(event.timestamp, event.isolate);
+        break;
       case ServiceEvent.kPauseBreakpoint:
+        e = new PauseBreakpointEvent(event.timestamp, event.isolate,
+            event.pauseBreakpoints, event.topFrame, event.atAsyncSuspension,
+            event.breakpoint);
+        break;
       case ServiceEvent.kPauseInterrupted:
+        e = new PauseInterruptedEvent(event.timestamp, event.isolate,
+            event.topFrame, event.atAsyncSuspension);
+        break;
       case ServiceEvent.kPauseException:
-        removePauseEvents(event.isolate);
-        notifications.add(new Notification.fromEvent(event));
+        e = new PauseExceptionEvent(event.timestamp, event.isolate,
+            event.topFrame, event.exception);
         break;
-
       case ServiceEvent.kInspect:
-        notifications.add(new Notification.fromEvent(event));
+        e = new InspectEvent(event.timestamp, event.isolate,
+            event.inspectee);
         break;
-
+      case ServiceEvent.kGC:
+        e = new GCEvent(event.timestamp, event.isolate);
+        break;
       default:
         // Ignore unrecognized events.
         Logger.root.severe('Unrecognized event: $event');
-        break;
+        return;
     }
+    events.add(e);
   }
 
   void _registerPages() {
@@ -212,23 +251,37 @@
     currentPage = page;
   }
 
-  ObservatoryApplication(this.rootElement) :
-      targets = new TargetManager() {
+  ObservatoryApplication(this.rootElement) {
     _locationManager = new LocationManager(this);
-    vm = new WebSocketVM(targets.defaultTarget);
+    targets.onChange.listen((e) {
+      if (targets.current == null) return _setVM(null);
+      if ((_vm as WebSocketVM)?.target != targets.current) {
+        _setVM(new WebSocketVM(targets.current));
+      }
+    });
+    _setVM(new WebSocketVM(targets.current));
     _initOnce();
-  }
 
-  void _removeDisconnectEvents() {
-    notifications.removeWhere((notification) {
-        var event = notification.event;
-        return (event != null &&
-                event.kind == ServiceEvent.kConnectionClosed);
-      });
+    // delete pause events.
+    events.onIsolateExit.listen(_deletePauseEvents);
+    events.onResume.listen(_deletePauseEvents);
+    events.onPauseStart.listen(_deletePauseEvents);
+    events.onPauseExit.listen(_deletePauseEvents);
+    events.onPauseBreakpoint.listen(_deletePauseEvents);
+    events.onPauseInterrupted.listen(_deletePauseEvents);
+    events.onPauseException.listen(_deletePauseEvents);
+
+    // show notification for an event.
+    events.onIsolateReload.listen(_addNotification);
+    events.onPauseExit.listen(_addNotification);
+    events.onPauseBreakpoint.listen(_addNotification);
+    events.onPauseInterrupted.listen(_addNotification);
+    events.onPauseException.listen(_addNotification);
+    events.onInspect.listen(_addNotification);
   }
 
   loadCrashDump(Map crashDump) {
-    this.vm = new FakeVM(crashDump['result']);
+    _setVM(new FakeVM(crashDump['result']));
     app.locationManager.go('#/vm');
   }
 
@@ -242,7 +295,7 @@
 
     // TODO(turnidge): Report this failure via analytics.
     Logger.root.warning('Caught exception: ${e}\n${st}');
-    notifications.add(new Notification.fromException(e, st));
+    notifications.add(new ExceptionNotification(e, stacktrace: st));
   }
 
   // This map keeps track of which curly-blocks have been expanded by the user.
diff --git a/runtime/observatory/lib/src/app/event.dart b/runtime/observatory/lib/src/app/event.dart
new file mode 100644
index 0000000..9e6f9e9
--- /dev/null
+++ b/runtime/observatory/lib/src/app/event.dart
@@ -0,0 +1,254 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 app;
+
+class VMUpdateEvent implements M.VMUpdateEvent {
+  final DateTime timestamp;
+  final M.VMRef vm;
+  VMUpdateEvent(this.timestamp, this.vm) {
+    assert(timestamp != null);
+    assert(vm != null);
+  }
+}
+
+class IsolateStartEvent implements M.IsolateStartEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  IsolateStartEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class IsolateRunnableEvent implements M.IsolateRunnableEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  IsolateRunnableEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class IsolateExitEvent implements M.IsolateExitEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  IsolateExitEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class IsolateUpdateEvent implements M.IsolateUpdateEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  IsolateUpdateEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class IsolateReloadEvent implements M.IsolateReloadEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.ErrorRef error;
+  IsolateReloadEvent(this.timestamp, this.isolate, this.error) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(error != null);
+  }
+}
+
+class ServiceExtensionAddedEvent implements M.ServiceExtensionAddedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final String extensionRPC;
+  ServiceExtensionAddedEvent(this.timestamp, this.isolate, this.extensionRPC) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(extensionRPC != null);
+  }
+}
+
+class DebuggerSettingsUpdateEvent implements M.DebuggerSettingsUpdateEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  DebuggerSettingsUpdateEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class PauseStartEvent implements M.PauseStartEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  PauseStartEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class PauseExitEvent implements M.PauseExitEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  PauseExitEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class PauseBreakpointEvent implements M.PauseBreakpointEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final Iterable<M.Breakpoint> pauseBreakpoints;
+  final M.Frame topFrame;
+  final bool atAsyncSuspension;
+  /// [optional]
+  final M.Breakpoint breakpoint;
+  PauseBreakpointEvent(this.timestamp, this.isolate,
+      Iterable<M.Breakpoint> pauseBreakpoints, this.topFrame,
+      this.atAsyncSuspension, [this.breakpoint])
+    : pauseBreakpoints = new List.unmodifiable(pauseBreakpoints){
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(pauseBreakpoints != null);
+    assert(topFrame != null);
+    assert(atAsyncSuspension != null);
+  }
+}
+
+class PauseInterruptedEvent implements M.PauseInterruptedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Frame topFrame;
+  final bool atAsyncSuspension;
+  PauseInterruptedEvent(this.timestamp, this.isolate, this.topFrame,
+      this.atAsyncSuspension) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(atAsyncSuspension != null);
+  }
+}
+
+class PauseExceptionEvent implements M.PauseExceptionEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Frame topFrame;
+  final M.InstanceRef exception;
+  PauseExceptionEvent(this.timestamp, this.isolate, this.topFrame,
+      this.exception) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(topFrame != null);
+    assert(exception != null);
+  }
+}
+
+class ResumeEvent implements M.ResumeEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Frame topFrame;
+  ResumeEvent(this.timestamp, this.isolate, this.topFrame) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class BreakpointAddedEvent implements M.BreakpointAddedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Breakpoint breakpoint;
+  BreakpointAddedEvent(this.timestamp, this.isolate, this.breakpoint) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(breakpoint != null);
+  }
+}
+
+class BreakpointResolvedEvent implements M.BreakpointResolvedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Breakpoint breakpoint;
+  BreakpointResolvedEvent(this.timestamp, this.isolate, this.breakpoint) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(breakpoint != null);
+  }
+}
+
+class BreakpointRemovedEvent implements M.BreakpointRemovedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Breakpoint breakpoint;
+  BreakpointRemovedEvent(this.timestamp, this.isolate, this.breakpoint) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(breakpoint != null);
+  }
+}
+
+class InspectEvent implements M.InspectEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.InstanceRef inspectee;
+  InspectEvent(this.timestamp, this.isolate, this.inspectee) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(inspectee != null);
+  }
+}
+
+class NoneEvent implements M.NoneEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  NoneEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class GCEvent implements M.GCEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  GCEvent(this.timestamp, this.isolate) {
+    assert(timestamp != null);
+    assert(isolate != null);
+  }
+}
+
+class ExtensionEvent implements M.ExtensionEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final String extensionKind;
+  final M.ExtensionData extensionData;
+  ExtensionEvent(this.timestamp, this.isolate, this.extensionKind,
+      this.extensionData) {
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(extensionKind != null);
+    assert(extensionData != null);
+  }
+}
+
+class TimelineEventsEvent implements M.TimelineEventsEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final Iterable<M.TimelineEvent> timelineEvents;
+  TimelineEventsEvent(this.timestamp, this.isolate,
+      Iterable<M.TimelineEvent> timelineEvents)
+    : timelineEvents = new List.unmodifiable(timelineEvents){
+    assert(timestamp != null);
+    assert(isolate != null);
+    assert(timelineEvents != null);
+  }
+}
+
+class ConnectionClosedEvent implements M.ConnectionClosedEvent {
+  final DateTime timestamp;
+  final String reason;
+  ConnectionClosedEvent(this.timestamp, this.reason) {
+    assert(timestamp != null);
+    assert(reason != null);
+  }
+}
diff --git a/runtime/observatory/lib/src/app/location_manager.dart b/runtime/observatory/lib/src/app/location_manager.dart
index 577cb92..aadf653 100644
--- a/runtime/observatory/lib/src/app/location_manager.dart
+++ b/runtime/observatory/lib/src/app/location_manager.dart
@@ -54,6 +54,11 @@
   /// Update the application location. After this function returns,
   /// [uri] and [debugArguments] will be updated.
   _updateApplicationLocation(String url) {
+    if (url == makeLink('/vm-connect')) {
+      // When we go to the vm-connect page, drop all notifications.
+      _app.notifications.deleteAll();
+    }
+
     // Chop off leading '#'.
     if (url.startsWith('#')) {
       url = url.substring(1);
@@ -93,8 +98,8 @@
                        ? '/vm-connect' : '/isolate-reconnect');
         var parameters = {};
         parameters.addAll(_uri.queryParameters);
-        parameters['originalPath'] = _uri.path;
-        parameters['originalIsolateId'] = parameters['isolateId'];
+        parameters['originalUri'] = _uri.toString();
+        parameters['isolateId'] = parameters['isolateId'];
         var generatedUri = new Uri(path: newPath, queryParameters: parameters);
         go(makeLink(generatedUri.toString()), true);
         return;
@@ -115,11 +120,6 @@
       url = makeLink('/vm-connect');
     }
 
-    if (url == makeLink('/vm-connect')) {
-      // When we go to the vm-connect page, drop all notifications.
-      _app.notifications.clear();
-    }
-
     if (addToBrowserHistory) {
       _addToBrowserHistory(url);
     }
diff --git a/runtime/observatory/lib/src/app/notification.dart b/runtime/observatory/lib/src/app/notification.dart
new file mode 100644
index 0000000..140e0dc
--- /dev/null
+++ b/runtime/observatory/lib/src/app/notification.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of app;
+
+class ExceptionNotification implements M.ExceptionNotification {
+  final Exception exception;
+  /// [optional]
+  final StackTrace stacktrace;
+  ExceptionNotification(this.exception, {this.stacktrace});
+}
+
+class EventNotification implements M.EventNotification {
+  final M.Event event;
+  EventNotification(this.event);
+}
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index 7f51a8e..bd2fe17 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -4,6 +4,11 @@
 
 part of app;
 
+AllocationProfileRepository _allocationProfileRepository
+    = new AllocationProfileRepository();
+IsolateSampleProfileRepository _isolateSampleProfileRepository
+    = new IsolateSampleProfileRepository();
+
 class IsolateNotFound implements Exception {
   String isolateId;
   IsolateNotFound(this.isolateId);
@@ -18,7 +23,7 @@
   final ObservatoryApplication app;
   final ObservableMap<String, String> internalArguments =
       new ObservableMap<String, String>();
-  @observable ObservatoryElement element;
+  @observable HtmlElement element;
 
   Page(this.app);
 
@@ -47,17 +52,10 @@
   bool canVisit(Uri uri);
 }
 
-/// A [SimplePage] matches a single uri path and displays a single element.
-class SimplePage extends Page {
+/// A [MatchingPage] matches a single uri path.
+abstract class MatchingPage extends Page {
   final String path;
-  final String elementTagName;
-  SimplePage(this.path, this.elementTagName, app) : super(app);
-
-  void onInstall() {
-    if (element == null) {
-      element = new Element.tag(elementTagName);
-    }
-  }
+  MatchingPage(this.path, app) : super(app);
 
   void _visit(Uri uri) {
     assert(uri != null);
@@ -77,6 +75,18 @@
   bool canVisit(Uri uri) => uri.path == path;
 }
 
+/// A [SimplePage] matches a single uri path and displays a single element.
+class SimplePage extends MatchingPage {
+  final String elementTagName;
+  SimplePage(String path, this.elementTagName, app) : super(path, app);
+
+  void onInstall() {
+    if (element == null) {
+      element = new Element.tag(elementTagName);
+    }
+  }
+}
+
 /// Error page for unrecognized paths.
 class ErrorPage extends Page {
   ErrorPage(app) : super(app);
@@ -84,7 +94,7 @@
   void onInstall() {
     if (element == null) {
       // Lazily create page.
-      element = new Element.tag('general-error');
+      element = new GeneralErrorElement(app.notifications, queue: app.queue);
     }
   }
 
@@ -92,17 +102,7 @@
     assert(element != null);
     assert(canVisit(uri));
 
-    /*
-    if (uri.path == '') {
-      // Nothing requested.
-      return;
-    }
-    */
-
-    if (element != null) {
-      GeneralErrorElement serviceElement = element;
-      serviceElement.message = "Path '${uri.path}' not found";
-    }
+    (element as GeneralErrorElement).message = "Path '${uri.path}' not found";
   }
 
   /// Catch all.
@@ -111,14 +111,14 @@
 
 /// Top-level vm info page.
 class VMPage extends SimplePage {
-  VMPage(app) : super('vm', 'service-view', app);
+  VMPage(app) : super('vm', 'vm-view', app);
 
   void _visit(Uri uri) {
     super._visit(uri);
     app.vm.reload().then((vm) {
       if (element != null) {
-        ServiceObjectViewElement serviceElement = element;
-        serviceElement.object = vm;
+        VMViewElement serviceElement = element;
+        serviceElement.vm = vm;
       }
     }).catchError((e, stack) {
       Logger.root.severe('VMPage visit error: $e');
@@ -131,16 +131,16 @@
 class FlagsPage extends SimplePage {
   FlagsPage(app) : super('flags', 'flag-list', app);
 
+  @override
+  onInstall() {
+    element = new FlagListElement(app.vm,
+                                  app.events,
+                                  new FlagsRepository(app.vm),
+                                  app.notifications);
+  }
+
   void _visit(Uri uri) {
     super._visit(uri);
-    app.vm.getFlagList().then((flags) {
-      if (element != null) {
-        FlagListElement serviceElement = element;
-        serviceElement.flagList = flags;
-      }
-    }).catchError((e, stack) {
-      Logger.root.severe('FlagsPage visit error: $e\n$stack');
-    });
   }
 }
 
@@ -172,14 +172,23 @@
 class ClassTreePage extends SimplePage {
   ClassTreePage(app) : super('class-tree', 'class-tree', app);
 
+  final DivElement container = new DivElement();
+
+  @override
+  void onInstall() {
+    element = container;
+  }
+
   void _visit(Uri uri) {
     super._visit(uri);
     getIsolate(uri).then((isolate) {
-      if (element != null) {
-        /// Update the page.
-        ClassTreeElement page = element;
-        page.isolate = isolate;
-      }
+      container.children = [
+        new ClassTreeElement(app.vm,
+                             isolate,
+                             app.events,
+                             app.notifications,
+                             new ClassRepository(isolate))
+      ];
     });
   }
 }
@@ -217,19 +226,28 @@
   }
 }
 
-class CpuProfilerPage extends SimplePage {
-  CpuProfilerPage(app) : super('profiler', 'cpu-profile', app);
+class CpuProfilerPage extends MatchingPage {
+  CpuProfilerPage(app) : super('profiler', app);
+
+  DivElement container = new DivElement();
 
   void _visit(Uri uri) {
     super._visit(uri);
     getIsolate(uri).then((isolate) {
-      if (element != null) {
-        /// Update the page.
-        CpuProfileElement page = element;
-        page.isolate = isolate;
-      }
+      container.children = [
+        new CpuProfileElement(isolate.vm, isolate, app.events,
+                              app.notifications,
+                              _isolateSampleProfileRepository)
+      ];
     });
   }
+
+  void onInstall() {
+    if (element == null) {
+      element = container;
+    }
+    assert(element != null);
+  }
 }
 
 class TableCpuProfilerPage extends SimplePage {
@@ -253,20 +271,34 @@
   }
 }
 
-class AllocationProfilerPage extends SimplePage {
-  AllocationProfilerPage(app)
-      : super('allocation-profiler', 'heap-profile', app);
+class AllocationProfilerPage extends MatchingPage {
+  AllocationProfilerPage(app) : super('allocation-profiler', app);
+
+  DivElement container = new DivElement();
 
   void _visit(Uri uri) {
     super._visit(uri);
     getIsolate(uri).then((isolate) {
-      if (element != null) {
-        /// Update the page.
-        HeapProfileElement page = element;
-        page.isolate = isolate;
-      }
+      container.children = [
+        new AllocationProfileElement(isolate.vm, isolate, app.events,
+                                     app.notifications,
+                                     _allocationProfileRepository,
+                                     queue: app.queue)
+      ];
     });
   }
+
+  void onInstall() {
+    if (element == null) {
+      element = container;
+    }
+    app.startGCEventListener();
+  }
+
+  void onUninstall() {
+    super.onUninstall();
+    app.stopGCEventListener();
+  }
 }
 
 class PortsPage extends SimplePage {
@@ -370,7 +402,11 @@
 
   void onInstall() {
     if (element == null) {
-      element = new Element.tag('vm-connect');
+      element = new VMConnectElement(
+            ObservatoryApplication.app.targets,
+            ObservatoryApplication.app.loadCrashDump,
+            ObservatoryApplication.app.notifications,
+            queue: ObservatoryApplication.app.queue);
     }
     assert(element != null);
   }
@@ -386,15 +422,19 @@
 class IsolateReconnectPage extends Page {
   IsolateReconnectPage(app) : super(app);
 
+  DivElement container = new DivElement();
+
   void onInstall() {
-    if (element == null) {
-      element = new Element.tag('isolate-reconnect');
-    }
-    assert(element != null);
+    element = container;
   }
 
   void _visit(Uri uri) {
     app.vm.reload();
+    container.children = [
+      new IsolateReconnectElement(app.vm, app.events, app.notifications,
+                                  uri.queryParameters['isolateId'],
+                                  Uri.parse(uri.queryParameters['originalUri']))
+    ];
     assert(element != null);
     assert(canVisit(uri));
   }
diff --git a/runtime/observatory/lib/src/app/target_manager.dart b/runtime/observatory/lib/src/app/target_manager.dart
deleted file mode 100644
index 6620db0..0000000
--- a/runtime/observatory/lib/src/app/target_manager.dart
+++ /dev/null
@@ -1,130 +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.
-
-part of app;
-
-class ChromiumTargetLister {
-  /// Fetch the list of chromium [NetworkVMTargets].
-  static Future<List<WebSocketVMTarget>> fetch(String networkAddress) {
-    if (networkAddress == null) {
-      return new Future.error(null);
-    }
-    var encoded = Uri.encodeComponent(networkAddress);
-    var url = '/crdptargets/$encoded';
-    return HttpRequest.getString(url).then((String responseText) {
-      var list = JSON.decode(responseText);
-      if (list == null) {
-        return list;
-      }
-      for (var i = 0; i < list.length; i++) {
-        list[i] = new WebSocketVMTarget.fromMap(list[i]);
-      }
-      return list;
-    }).catchError((e) {
-      // An error occured while getting the list of Chrome targets.
-      // We eagerly request the list of targets, meaning this error can occur
-      // regularly. By catching it and dropping it, we avoid spamming errors
-      // on the console.
-    });
-  }
-}
-
-class TargetManager extends Observable {
-  static const _historyKey = 'history';
-  final SettingsGroup _settings = new SettingsGroup('targetManager');
-  final List history = new ObservableList();
-  WebSocketVMTarget defaultTarget;
-
-  String _networkAddressOfDefaultTarget() {
-    if (Utils.runningInJavaScript()) {
-      // We are running as JavaScript, use the same host that Observatory has
-      // been loaded from.
-      return 'ws://${window.location.host}/ws';
-    } else {
-      // Otherwise, assume we are running from Dart Editor and want to connect
-      // to the default host.
-      return 'ws://localhost:8181/ws';
-    }
-  }
-  TargetManager() {
-    _restore();
-    // Add a default standalone VM target.
-    defaultTarget = findOrMake(_networkAddressOfDefaultTarget());
-    assert(defaultTarget != null);
-    add(defaultTarget);
-  }
-
-  void clearHistory() {
-    history.clear();
-    _store();
-  }
-
-  WebSocketVMTarget findOrMake(String networkAddress) {
-    var target;
-    target = _find(networkAddress);
-    if (target != null) {
-      return target;
-    }
-    target = new WebSocketVMTarget(networkAddress);
-    return target;
-  }
-
-  /// Find by networkAddress.
-  WebSocketVMTarget _find(String networkAddress) {
-    var r;
-    history.forEach((item) {
-      if ((item.networkAddress == networkAddress) && (item.chrome == false)) {
-        r = item;
-      }
-    });
-    return r;
-  }
-
-  void add(WebSocketVMTarget item) {
-    if (item.chrome) {
-      // We don't store chrome tabs.
-      return;
-    }
-    if (history.contains(item)) {
-      return;
-    }
-    // Not inserting duplicates.
-    assert(_find(item.networkAddress) == null);
-    history.add(item);
-    _sort();
-    _store();
-  }
-
-  void remove(WebSocketVMTarget target) {
-    history.remove(target);
-    _sort();
-    _store();
-  }
-
-  void _sort() {
-    this.history.sort((WebSocketVMTarget a, WebSocketVMTarget b) {
-      return b.lastConnectionTime.compareTo(a.lastConnectionTime);
-    });
-  }
-
-  /// After making a change, update settings.
-  void _store() {
-    _sort();
-    _settings.set(_historyKey,  history);
-  }
-
-  /// Read settings from data store.
-  void _restore() {
-    this.history.clear();
-    var loaded = _settings.get(_historyKey);
-    if (loaded == null) {
-      return;
-    }
-    for (var i = 0; i < loaded.length; i++) {
-      loaded[i] = new WebSocketVMTarget.fromMap(loaded[i]);
-    }
-    this.history.addAll(loaded);
-    _sort();
-  }
-}
diff --git a/runtime/observatory/lib/src/app/view_model.dart b/runtime/observatory/lib/src/app/view_model.dart
index 76033eb..94edb49 100644
--- a/runtime/observatory/lib/src/app/view_model.dart
+++ b/runtime/observatory/lib/src/app/view_model.dart
@@ -4,389 +4,6 @@
 
 part of app;
 
-abstract class VirtualTreeRow {
-  // Number of ems each subtree is indented.
-  static const subtreeIndent = 2.0;
-
-  static const redColor = '#F44336';
-  static const blueColor = '#3F51B5';
-  static const purpleColor = '#673AB7';
-  static const greenColor = '#4CAF50';
-  static const orangeColor = '#FF9800';
-  static const lightGrayColor = '#FAFAFA';
-
-  List backgroundColors = const [
-    purpleColor,
-    redColor,
-    greenColor,
-    blueColor,
-    orangeColor,
-  ];
-
-  final VirtualTree tree;
-  final List<VirtualTreeRow> children = [];
-  final List<StreamSubscription> _listeners = [];
-  final int depth;
-  bool _expanded = false;
-
-  VirtualTreeRow(this.tree, this.depth);
-
-  bool get expanded => _expanded;
-
-  set expanded(bool expanded) {
-    var changed = _expanded != expanded;
-    _expanded = expanded;
-    if (!changed) {
-      return;
-    }
-    if (_expanded) {
-      _expand();
-    } else {
-      _collapse();
-    }
-  }
-
-  Element makeColorBar(int depth) {
-    var element = new SpanElement();
-    element.style.paddingLeft = '2px';
-    element.style.paddingRight = '2px';
-    element.style.flexBasis = '2px';
-    element.style.height = '${tree.rowHeight}px';
-    element.style.minHeight = '${tree.rowHeight}px';
-    if (depth > 0) {
-      var colorIndex = (depth - 1) % backgroundColors.length;
-      element.style.backgroundColor = backgroundColors[colorIndex];
-    }
-    return element;
-  }
-
-  Element makeExpander() {
-    SpanElement element = new SpanElement();
-    element.style.flexBasis = '2em';
-    if (!hasChildren()) {
-      element.style.visibility = 'hidden';
-    } else {
-      element.style.visibility = 'visible';
-      element.children.add(expanded ?
-          new Element.tag('icon-expand-more') :
-          new Element.tag('icon-chevron-right'));
-    }
-    _listeners.add(element.onClick.listen((e) {
-      e.stopPropagation();
-      toggle();
-    }));
-    return element;
-  }
-
-  Element makeIndenter(int depth, {colored: true}) {
-    SpanElement element = new SpanElement();
-    element.style.paddingLeft = '${subtreeIndent * depth}em';
-    element.style.flexBasis = '${subtreeIndent * depth}em';
-    element.style.height = '${tree.rowHeight}px';
-    element.style.minHeight = '${tree.rowHeight}px';
-    if (colored) {
-      if (depth > 0) {
-        var colorIndex = (depth - 1) % backgroundColors.length;
-        element.style.backgroundColor = backgroundColors[colorIndex];
-      }
-    }
-    return element;
-  }
-
-  Element makeText(String text, {String toolTip,
-                                 String flexBasis: '4.5em',
-                                 String cssClass}) {
-    SpanElement element = new SpanElement();
-    element.text = text;
-    if (toolTip != null) {
-      element.title = toolTip;
-    }
-    if (flexBasis != null) {
-      element.style.flexBasis = flexBasis;
-    }
-    if (cssClass != null) {
-      element.classes.add(cssClass);
-    }
-    return element;
-  }
-
-  Element makeGap({double ems: 0.5}) {
-    SpanElement element = new SpanElement();
-    var flexBasis = '${ems}em';
-    element.style.flexBasis = flexBasis;
-    return element;
-  }
-
-  void _cleanupListeners() {
-    for (var listener in _listeners) {
-      listener.cancel();
-    }
-    _listeners.clear();
-  }
-
-  void _expand() {
-    onShow();
-    tree._onExpand(this);
-    if (children.length == 1) {
-      children[0]._expand();
-    }
-    _expanded = true;
-  }
-
-  void _collapse() {
-    _expanded = false;
-    for (var i = 0; i < children.length; i++) {
-      if (children[i].expanded) {
-        children[i]._collapse();
-      }
-    }
-    tree._onCollapse(this);
-  }
-
-  void toggle() {
-    expanded = !expanded;
-  }
-
-  void _render(DivElement rowDiv) {
-    rowDiv.style.display = 'flex';
-    rowDiv.style.alignItems = 'center';
-    _cleanupListeners();
-    onShow();
-    onRender(rowDiv);
-  }
-
-  /// Called when you should render into [rowDiv].
-  void onRender(DivElement rowDiv);
-
-  // Called when this row is visible.
-  void onShow();
-
-  // Return the number of children this node has.
-  int get childCount => 0;
-
-  // Return true if this node can be expanded.
-  bool hasChildren() => childCount > 0;
-
-  // Called when this row is not visible.
-  void onHide() {
-    _cleanupListeners();
-  }
-}
-
-class VirtualTree {
-  final int rowHeight;
-  final List<VirtualTreeRow> rows = [];
-  final DivElement root;
-  final Stopwatch _clock = new Stopwatch();
-
-  DivElement _treeHeightElement;
-  DivElement _tree;
-
-  StreamSubscription _scrollSubscription;
-  StreamSubscription _resizeSubscription;
-
-  // Height of [root] in pixels.
-  int viewHeight;
-
-  // Number of pixels view can be scrolled before a redraw occurs.
-  int redrawThresholdPixels;
-
-  // Number of rows visible at any given time.
-  int numVisibleRows;
-  // Number of rows above the current view that are in the dom.
-  int extraRowsAbove;
-  // Number of rows below the current view that are in the dom.
-  int extraRowsBelow;
-
-  // The scroll top of the last scroll event.
-  int lastPaintScrollTop;
-
-  // The starting row of the last paint.
-  int lastPaintStartingRow = 0;
-
-  bool paintScheduled = false;
-
-  bool scrolled = false;
-
-  static const scrollStopThresholdMilliseconds = 100;
-
-  VirtualTree(this.rowHeight, this.root) {
-    _clock.start();
-    _install();
-    _resize();
-    _schedulePaint(0);
-  }
-
-  void uninstall() => _uninstall();
-
-  void refresh() {
-    _resize();
-    _schedulePaint(lastPaintStartingRow);
-  }
-
-  // Clear the tree.
-  void clear() {
-    rows.clear();
-    _resize();
-  }
-
-  void _onExpand(VirtualTreeRow parent) {
-    int index = rows.indexOf(parent);
-    if (index == -1) {
-      return;
-    }
-    rows.insertAll(index + 1, parent.children);
-    refresh();
-  }
-
-  void _onCollapse(VirtualTreeRow parent) {
-    int index = rows.indexOf(parent);
-    if (index == -1) {
-      return;
-    }
-    int start = index + 1;
-    int end = start + parent.children.length;
-    rows.removeRange(start, end);
-    refresh();
-  }
-
-  void _resize() {
-    if (viewHeight != root.offsetHeight) {
-      viewHeight = root.offsetHeight;
-      numVisibleRows = (viewHeight ~/ rowHeight) + 1;
-      extraRowsAbove = numVisibleRows ~/ 2;
-      extraRowsBelow = numVisibleRows - extraRowsAbove;
-      redrawThresholdPixels =
-          math.min(extraRowsAbove, extraRowsBelow) * rowHeight;
-    }
-    _treeHeightElement.style.height = '${_treeHeight()}px';
-  }
-
-  int _treeHeight() {
-    return rows.length * rowHeight;
-  }
-
-  int _pixelsFromLastScroll(int currentScrollTop) {
-    if (lastPaintScrollTop == null) {
-      return currentScrollTop;
-    }
-
-    return (currentScrollTop - lastPaintScrollTop).abs();
-  }
-
-  int _pixelToRow(int pixelY) {
-    int result = pixelY ~/ rowHeight;
-    return result;
-  }
-
-  void _install() {
-    // This element controls the height of the tree's scrollable region.
-    // It is one pixel wide and the height is set to rowHeight * numRows.
-    _treeHeightElement = new DivElement();
-    _treeHeightElement.style.position = 'absolute';
-    _treeHeightElement.style.top = '0';
-    _treeHeightElement.style.left = '0';
-    _treeHeightElement.style.width = '1px';
-
-    // This element holds the visible tree rows and the height controlling
-    // element. It takes the full width and height of its parent element.
-    _tree = new DivElement();
-    _tree.children.add(_treeHeightElement);
-    _tree.style.width = '100%';
-    _tree.style.height = '100%';
-    _tree.style.position = 'relative';
-    _tree.style.overflow = 'auto';
-
-    // Listen for scroll events on the tree.
-    _scrollSubscription = _tree.onScroll.listen(_onScroll);
-
-    root.children.add(_tree);
-
-    // Listen for resize events.
-    _resizeSubscription = window.onResize.listen((_) {
-      _resize();
-      _schedulePaint(lastPaintStartingRow);
-    });
-  }
-
-  void _uninstall() {
-    root.children.clear();
-    _scrollSubscription?.cancel();
-    _scrollSubscription = null;
-    _resizeSubscription?.cancel();
-    _resizeSubscription = null;
-  }
-
-  void _onScroll(Event scrollEvent) {
-    Element target = scrollEvent.target;
-    int scrollTop = target.scrollTop;
-    if (_pixelsFromLastScroll(scrollTop) > redrawThresholdPixels) {
-      _schedulePaint(lastPaintStartingRow);
-      scrolled = true;
-    }
-    scrollEvent.preventDefault();
-  }
-
-  void _schedulePaint(int startingRow) {
-    if (paintScheduled) {
-      return;
-    }
-    paintScheduled = true;
-    window.requestAnimationFrame(
-        (timestamp) => _onRenderFrame(timestamp, startingRow));
-  }
-
-  void _onRenderFrame(int timestamp, int startingRow) {
-    paintScheduled = false;
-    _paint(startingRow);
-  }
-
-  void _paint(int startingRow) {
-    if (scrolled) {
-      startingRow = math.max(_pixelToRow(_tree.scrollTop), 0);
-      scrolled = false;
-    }
-    lastPaintScrollTop = _tree.scrollTop;
-    lastPaintStartingRow = startingRow;
-
-    int endingRow =
-        math.min(rows.length, startingRow + numVisibleRows + extraRowsBelow);
-
-    startingRow =
-        math.max(0, startingRow - extraRowsAbove);
-
-    print('PAINT $startingRow $endingRow');
-
-    for (int i = startingRow; i < endingRow; i++) {
-      // We add 1 because _tree.children[0] contains the height control element.
-      int cacheIndex = (i - startingRow) + 1;
-      DivElement row;
-      if (cacheIndex < _tree.children.length) {
-        // re-use existing row.
-        row = _tree.children[cacheIndex];
-        row.children.clear();
-      } else {
-        // Allocate a new row.
-        row = new DivElement();
-        row.style.position = 'absolute';
-        row.style.height = '${rowHeight}px';
-        row.style.maxHeight = '${rowHeight}px';
-        row.style.margin = '0';
-        row.style.width = '100%';
-        row.style.left = '0';
-        _tree.children.add(row);
-      }
-      row.style.top = '${(i * rowHeight)}px';
-      // Render the row.
-      rows[i]._render(row);
-    }
-    int necessaryChildren = (endingRow - startingRow) + 1;
-    while (_tree.children.length > necessaryChildren) {
-      _tree.children.removeLast();
-    }
-  }
-}
-
 abstract class TableTreeRow extends Observable {
   static const arrowRight = '\u2192';
   static const arrowDownRight = '\u21b3';
diff --git a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
index fb63fba..f96f5db 100644
--- a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
+++ b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
@@ -4,8 +4,9 @@
 
 part of cpu_profiler;
 
-abstract class CallTreeNode {
-  final List<CallTreeNode> children;
+abstract class CallTreeNode<NodeT extends M.CallTreeNode>
+    implements M.CallTreeNode {
+  final List<NodeT> children;
   final int count;
   double get percentage => _percentage;
   double _percentage = 0.0;
@@ -18,7 +19,8 @@
   CallTreeNode(this.children, this.count);
 }
 
-class CodeCallTreeNode extends CallTreeNode {
+class CodeCallTreeNode extends CallTreeNode<CodeCallTreeNode>
+    implements M.CodeCallTreeNode {
   final ProfileCode profileCode;
 
   Object get profileData => profileCode;
@@ -32,14 +34,15 @@
   }
 }
 
-class CallTree {
+class CallTree<NodeT extends CallTreeNode> {
   final bool inclusive;
-  final CallTreeNode root;
+  final NodeT root;
 
   CallTree(this.inclusive, this.root);
 }
 
-class CodeCallTree extends CallTree {
+class CodeCallTree extends CallTree<CodeCallTreeNode>
+    implements M.CodeCallTree {
   CodeCallTree(bool inclusive, CodeCallTreeNode root)
       : super(inclusive, root) {
     _setCodePercentage(null, root);
@@ -133,7 +136,7 @@
       if (!profileCode.code.isDartCode) {
         continue;
       }
-      if (profileCode.code.kind == CodeKind.Stub) {
+      if (profileCode.code.kind == M.CodeKind.stub) {
         continue;
       }
       if (!profileCode.code.isOptimized) {
@@ -150,7 +153,7 @@
       if (!profileCode.code.isDartCode) {
         continue;
       }
-      if (profileCode.code.kind == CodeKind.Stub) {
+      if (profileCode.code.kind == M.CodeKind.stub) {
         continue;
       }
       // If the code's function isn't this function.
@@ -305,7 +308,7 @@
   }
 }
 
-class FunctionCallTree extends CallTree {
+class FunctionCallTree extends CallTree implements M.FunctionCallTree {
   FunctionCallTree(bool inclusive, FunctionCallTreeNode root)
       : super(inclusive, root) {
     _setFunctionPercentage(null, root);
@@ -370,7 +373,7 @@
   InlineIntervalTick(this.startAddress);
 }
 
-class ProfileCode {
+class ProfileCode implements M.ProfileCode {
   final CpuProfile profile;
   final Code code;
   int exclusiveTicks;
@@ -418,9 +421,9 @@
 
     code.profile = this;
 
-    if (code.kind == CodeKind.Stub) {
+    if (code.kind == M.CodeKind.stub) {
       attributes.add('stub');
-    } else if (code.kind == CodeKind.Dart) {
+    } else if (code.kind == M.CodeKind.dart) {
       if (code.isNative) {
         attributes.add('ffi');  // Not to be confused with a C function.
       } else {
@@ -434,9 +437,9 @@
       } else {
         attributes.add('unoptimized');
       }
-    } else if (code.kind == CodeKind.Tag) {
+    } else if (code.kind == M.CodeKind.tag) {
       attributes.add('tag');
-    } else if (code.kind == CodeKind.Native) {
+    } else if (code.kind == M.CodeKind.native) {
       attributes.add('native');
     }
     inclusiveTicks = int.parse(data['inclusiveTicks']);
@@ -488,7 +491,7 @@
   }
 }
 
-class ProfileFunction {
+class ProfileFunction implements M.ProfileFunction {
   final CpuProfile profile;
   final ServiceFunction function;
   // List of compiled code objects containing this function.
@@ -537,7 +540,7 @@
   // Does this function have an unoptimized version of itself?
   bool hasUnoptimizedCode() {
     for (var profileCode in profileCodes) {
-      if (profileCode.code.kind == CodeKind.Stub) {
+      if (profileCode.code.kind == M.CodeKind.stub) {
         continue;
       }
       if (!profileCode.code.isDartCode) {
@@ -553,7 +556,7 @@
   // Has this function been inlined in another function?
   bool isInlined() {
     for (var profileCode in profileCodes) {
-      if (profileCode.code.kind == CodeKind.Stub) {
+      if (profileCode.code.kind == M.CodeKind.stub) {
         continue;
       }
       if (!profileCode.code.isDartCode) {
@@ -568,13 +571,13 @@
   }
 
   void _addKindBasedAttributes(Set<String> attribs) {
-    if (function.kind == FunctionKind.kTag) {
+    if (function.kind == M.FunctionKind.tag) {
       attribs.add('tag');
-    } else if (function.kind == FunctionKind.kStub) {
+    } else if (function.kind == M.FunctionKind.stub) {
       attribs.add('stub');
-    } else if (function.kind == FunctionKind.kNative) {
+    } else if (function.kind == M.FunctionKind.native) {
       attribs.add('native');
-    } else if (function.kind.isSynthetic()) {
+    } else if (M.isSyntheticFunction(function.kind)) {
       attribs.add('synthetic');
     } else if (function.isNative) {
       attribs.add('ffi');  // Not to be confused with a C function.
@@ -640,9 +643,7 @@
 
 
 // TODO(johnmccutchan): Rename to SampleProfile
-class CpuProfile {
-  final double MICROSECONDS_PER_SECOND = 1000000.0;
-  final double displayThreshold = 0.0002; // 0.02%.
+class CpuProfile extends M.SampleProfile {
 
   Isolate isolate;
 
@@ -660,20 +661,24 @@
   final List<ProfileFunction> functions = new List<ProfileFunction>();
   bool _builtFunctionCalls = false;
 
-  CodeCallTree loadCodeTree(String name) {
-    if (name == 'inclusive') {
-      return _loadCodeTree(true, tries['inclusiveCodeTrie']);
-    } else {
-      return _loadCodeTree(false, tries['exclusiveCodeTrie']);
+  CodeCallTree loadCodeTree(M.ProfileTreeDirection direction) {
+    switch (direction) {
+      case M.ProfileTreeDirection.inclusive:
+        return _loadCodeTree(true, tries['inclusiveCodeTrie']);
+      case M.ProfileTreeDirection.exclusive:
+        return _loadCodeTree(false, tries['exclusiveCodeTrie']);
     }
+    throw new Exception('Unknown ProfileTreeDirection');
   }
 
-  FunctionCallTree loadFunctionTree(String name) {
-    if (name == 'inclusive') {
-      return _loadFunctionTree(true, tries['inclusiveFunctionTrie']);
-    } else {
-      return _loadFunctionTree(false, tries['exclusiveFunctionTrie']);
+  FunctionCallTree loadFunctionTree(M.ProfileTreeDirection direction) {
+    switch (direction) {
+      case M.ProfileTreeDirection.inclusive:
+        return _loadFunctionTree(true, tries['inclusiveFunctionTrie']);
+      case M.ProfileTreeDirection.exclusive:
+        return _loadFunctionTree(false, tries['exclusiveFunctionTrie']);
     }
+    throw new Exception('Unknown ProfileTreeDirection');
   }
 
   buildCodeCallerAndCallees() {
@@ -681,7 +686,7 @@
       return;
     }
     _builtCodeCalls = true;
-    var tree = loadCodeTree('inclusive');
+    var tree = loadCodeTree(M.ProfileTreeDirection.inclusive);
     tree._recordCallerAndCallees();
   }
 
@@ -690,7 +695,7 @@
       return;
     }
     _builtFunctionCalls = true;
-    var tree = loadFunctionTree('inclusive');
+    var tree = loadFunctionTree(M.ProfileTreeDirection.inclusive);
     tree._markFunctionCalls();
   }
 
@@ -707,44 +712,87 @@
     _builtFunctionCalls = false;
   }
 
-  load(Isolate isolate, ServiceMap profile) {
-    clear();
-    if ((isolate == null) || (profile == null)) {
-      return;
-    }
+  Future load(Isolate isolate, ServiceMap profile) async {
+    await loadProgress(isolate, profile).last;
+  }
 
-    this.isolate = isolate;
-    isolate.resetCachedProfileData();
+  static Future sleep([Duration duration = const Duration(microseconds: 0)]) {
+    final Completer completer = new Completer();
+    new Timer(duration, () => completer.complete() );
+    return completer.future;
+  }
 
-    sampleCount = profile['sampleCount'];
-    samplePeriod = profile['samplePeriod'];
-    sampleRate = (MICROSECONDS_PER_SECOND / samplePeriod);
-    stackDepth = profile['stackDepth'];
-    timeSpan = profile['timeSpan'];
+  Stream<double> loadProgress(Isolate isolate, ServiceMap profile) {
+    var progress = new StreamController<double>.broadcast();
 
-    // Process code table.
-    for (var codeRegion in profile['codes']) {
-      Code code = codeRegion['code'];
-      assert(code != null);
-      codes.add(new ProfileCode.fromMap(this, code, codeRegion));
-    }
+    (() async {
+      final Stopwatch watch = new Stopwatch();
+      watch.start();
+      int count = 0;
+      var needToUpdate = () {
+        count++;
+        if (((count % 256) == 0) && (watch.elapsedMilliseconds > 16)) {
+          watch.reset();
+          return true;
+        }
+        return false;
+      };
+      var signal = (double p) {
+        progress.add(p);
+        return sleep();
+      };
+      try {
+        clear();
+        progress.add(0.0);
+        if ((isolate == null) || (profile == null)) {
+          return;
+        }
 
-    // Process function table.
-    for (var profileFunction in profile['functions']) {
-      ServiceFunction function = profileFunction['function'];
-      assert(function != null);
-      functions.add(
-          new ProfileFunction.fromMap(this, function, profileFunction));
-    }
+        this.isolate = isolate;
+        isolate.resetCachedProfileData();
 
-    tries['exclusiveCodeTrie'] =
-        new Uint32List.fromList(profile['exclusiveCodeTrie']);
-    tries['inclusiveCodeTrie'] =
-        new Uint32List.fromList(profile['inclusiveCodeTrie']);
-    tries['exclusiveFunctionTrie'] =
-        new Uint32List.fromList(profile['exclusiveFunctionTrie']);
-    tries['inclusiveFunctionTrie'] =
-        new Uint32List.fromList(profile['inclusiveFunctionTrie']);
+        sampleCount = profile['sampleCount'];
+        samplePeriod = profile['samplePeriod'];
+        sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod);
+        stackDepth = profile['stackDepth'];
+        timeSpan = profile['timeSpan'];
+
+        num length = profile['codes'].length +
+                        profile['functions'].length;
+
+        // Process code table.
+        for (var codeRegion in profile['codes']) {
+          if (needToUpdate()) {
+            await signal(count * 100.0 / length);
+          }
+          Code code = codeRegion['code'];
+          assert(code != null);
+          codes.add(new ProfileCode.fromMap(this, code, codeRegion));
+        }
+        // Process function table.
+        for (var profileFunction in profile['functions']) {
+          if (needToUpdate()) {
+            await signal(count * 100 / length);
+          }
+          ServiceFunction function = profileFunction['function'];
+          assert(function != null);
+          functions.add(
+              new ProfileFunction.fromMap(this, function, profileFunction));
+        }
+
+        tries['exclusiveCodeTrie'] =
+            new Uint32List.fromList(profile['exclusiveCodeTrie']);
+        tries['inclusiveCodeTrie'] =
+            new Uint32List.fromList(profile['inclusiveCodeTrie']);
+        tries['exclusiveFunctionTrie'] =
+            new Uint32List.fromList(profile['exclusiveFunctionTrie']);
+        tries['inclusiveFunctionTrie'] =
+            new Uint32List.fromList(profile['inclusiveFunctionTrie']);
+      } finally {
+        progress.close();
+      }
+    }());
+    return progress.stream;
   }
 
   // Data shared across calls to _read*TrieNode.
@@ -918,12 +966,10 @@
   }
 
   int approximateMillisecondsForCount(count) {
-    var MICROSECONDS_PER_MILLISECOND = 1000.0;
-    return (count * samplePeriod) ~/ MICROSECONDS_PER_MILLISECOND;
+    return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND;
   }
 
   double approximateSecondsForCount(count) {
-    var MICROSECONDS_PER_SECOND = 1000000.0;
-    return (count * samplePeriod) / MICROSECONDS_PER_SECOND;
+    return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND;
   }
 }
diff --git a/runtime/observatory/lib/src/debugger/debugger_location.dart b/runtime/observatory/lib/src/debugger/debugger_location.dart
index ac3a9bf..d1b4054 100644
--- a/runtime/observatory/lib/src/debugger/debugger_location.dart
+++ b/runtime/observatory/lib/src/debugger/debugger_location.dart
@@ -233,7 +233,7 @@
         for (var cls in classes) {
           assert(cls.loaded);
           for (var function in cls.functions) {
-            if (function.kind == FunctionKind.kConstructor) {
+            if (function.kind == M.FunctionKind.constructor) {
               // Constructor names are class-qualified.
               if (match.group(0) == function.name) {
                 functions.add(function);
@@ -314,7 +314,7 @@
         var completions = [];
         for (var cls in classes) {
           for (var function in cls.functions) {
-            if (function.kind == FunctionKind.kConstructor) {
+            if (function.kind == M.FunctionKind.constructor) {
               if (function.name.startsWith(match.group(0))) {
                 completions.add(function.name);
               }
diff --git a/runtime/observatory/lib/src/elements/action_link.html b/runtime/observatory/lib/src/elements/action_link.html
index 46ced34..2bb0133 100644
--- a/runtime/observatory/lib/src/elements/action_link.html
+++ b/runtime/observatory/lib/src/elements/action_link.html
@@ -1,8 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
 
-<polymer-element name="action-link" extends="observatory-element">
+<polymer-element name="action-link">
   <template>
     <style>
       .idle {
diff --git a/runtime/observatory/lib/src/elements/allocation_profile.dart b/runtime/observatory/lib/src/elements/allocation_profile.dart
new file mode 100644
index 0000000..45e4d9f
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/allocation_profile.dart
@@ -0,0 +1,583 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:charted/charted.dart';
+import "package:charted/charts/charts.dart";
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/containers/virtual_collection.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/utils.dart';
+
+enum _SortingField {
+  accumulatedSize,
+  accumulatedInstances,
+  currentSize,
+  currentInstances,
+  newAccumulatedSize,
+  newAccumulatedInstances,
+  newCurrentSize,
+  newCurrentInstances,
+  oldAccumulatedSize,
+  oldAccumulatedInstances,
+  oldCurrentSize,
+  oldCurrentInstances,
+  className,
+}
+
+enum _SortingDirection {
+  ascending,
+  descending
+}
+
+class AllocationProfileElement  extends HtmlElement implements Renderable {
+  static const tag = const Tag<AllocationProfileElement>('allocation-profile',
+                                            dependencies: const [
+                                              ClassRefElement.tag,
+                                              NavBarElement.tag,
+                                              NavTopMenuElement.tag,
+                                              NavVMMenuElement.tag,
+                                              NavIsolateMenuElement.tag,
+                                              NavMenuElement.tag,
+                                              NavRefreshElement.tag,
+                                              NavNotifyElement.tag,
+                                              VirtualCollectionElement.tag
+                                            ]);
+
+  RenderingScheduler<AllocationProfileElement> _r;
+
+  Stream<RenderedEvent<AllocationProfileElement>> get onRendered =>
+      _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.AllocationProfileRepository _repository;
+  M.AllocationProfile _profile;
+  bool _autoRefresh = false;
+  StreamSubscription _gcSubscription;
+  _SortingField _sortingField =
+      _SortingField.className;
+  _SortingDirection _sortingDirection =
+      _SortingDirection.ascending;
+
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+
+  factory AllocationProfileElement(M.VM vm, M.IsolateRef isolate,
+                                   M.EventRepository events,
+                                   M.NotificationRepository notifications,
+                                   M.AllocationProfileRepository repository,
+                                   {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(repository != null);
+    AllocationProfileElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._repository = repository;
+    return e;
+  }
+
+  AllocationProfileElement.created() : super.created();
+
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+    _refresh();
+    _gcSubscription = _events.onGCEvent.listen((e) {
+      if (_autoRefresh && (e.isolate.id == _isolate.id)) {
+        _refresh();
+      }
+    });
+  }
+
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+    _gcSubscription.cancel();
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavMenuElement('allocation profile', last: true,
+              link: Uris.profiler(_isolate), queue: _r.queue),
+          new NavRefreshElement(label: 'Download', disabled: _profile == null,
+              queue: _r.queue)
+            ..onRefresh.listen((_) => _downloadCSV()),
+          new NavRefreshElement(label: 'Reset Accumulator', queue: _r.queue)
+            ..onRefresh.listen((_) => _refresh(reset: true)),
+          new NavRefreshElement(label: 'GC', queue: _r.queue)
+            ..onRefresh.listen((_) => _refresh(gc: true)),
+          new NavRefreshElement(queue: _r.queue)
+            ..onRefresh.listen((_) => _refresh()),
+          new DivElement()..classes = const ['nav-option']
+            ..children = [
+              new CheckboxInputElement()
+                ..id = 'allocation-profile-auto-refresh'
+                ..checked = _autoRefresh
+                ..onChange.listen((_) => _autoRefresh = !_autoRefresh),
+              new LabelElement()
+                ..htmlFor = 'allocation-profile-auto-refresh'
+                ..text = 'Auto-refresh on GC'
+            ],
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = 'Allocation Profile',
+          new HRElement()
+        ]
+    ];
+    if (_profile == null) {
+      children.addAll([
+        new DivElement()..classes = const ['content-centered-big']
+          ..children = [
+            new HeadingElement.h2()..text = 'Loading...'
+          ]
+      ]);
+    } else {
+      final newChartHost = new DivElement()..classes = const ['host'];
+      final newChartLegend = new DivElement()..classes = const ['legend'];
+      final oldChartHost = new DivElement()..classes = const ['host'];
+      final oldChartLegend = new DivElement()..classes = const ['legend'];
+      children.addAll([
+        new DivElement()..classes = const ['content-centered-big']
+          ..children = [
+            new DivElement()..classes = const ['memberList']
+              ..children = [
+                new DivElement()..classes = const ['memberItem']
+                  ..children = [
+                    new DivElement()..classes = const ['memberName']
+                      ..text = 'last forced GC at',
+                    new DivElement()..classes = const ['memberValue']
+                      ..text = _profile.lastServiceGC == null ? '---'
+                                 : '${_profile.lastServiceGC}',
+                  ],
+                new DivElement()..classes = const ['memberItem']
+                  ..children = [
+                    new DivElement()..classes = const ['memberName']
+                      ..text = 'last accumulator reset at',
+                    new DivElement()..classes = const ['memberValue']
+                      ..text = _profile.lastAccumulatorReset == null ? '---'
+                                 : '${_profile.lastAccumulatorReset}',
+                  ]
+              ],
+            new HRElement(),
+          ],
+        new DivElement()..classes = const ['content-centered-big']
+          ..children = [
+            new DivElement()..classes = const ['heap-space', 'left']
+              ..children = [
+                new HeadingElement.h2()..text = 'New Generation',
+                new BRElement(),
+                new DivElement()..classes = const ['memberList']
+                  ..children = _createSpaceMembers(_profile.newSpace),
+                new BRElement(),
+                new DivElement()..classes = const ['chart']
+                  ..children = [newChartLegend, newChartHost]
+              ],
+            new DivElement()..classes = const ['heap-space', 'right']
+              ..children = [
+                new HeadingElement.h2()..text = 'Old Generation',
+                new BRElement(),
+                new DivElement()..classes = const ['memberList']
+                  ..children = _createSpaceMembers(_profile.oldSpace),
+                new BRElement(),
+                new DivElement()..classes = const ['chart']
+                  ..children = [oldChartLegend, oldChartHost]
+              ],
+            new BRElement(), new HRElement()
+          ],
+        new DivElement()..classes = const ['collection']
+          ..children = [
+            new VirtualCollectionElement(
+              _createCollectionLine,
+              _updateCollectionLine,
+              createHeader: _createCollectionHeader,
+              items: _profile.members.toList()..sort(_createSorter()),
+              queue: _r.queue)
+          ]
+      ]);
+      _renderGraph(newChartHost, newChartLegend, _profile.newSpace);
+      _renderGraph(oldChartHost, oldChartLegend, _profile.oldSpace);
+    }
+  }
+
+  _createSorter() {
+    var getter;
+    switch (_sortingField) {
+      case _SortingField.accumulatedSize:
+        getter = _getAccumulatedSize;
+        break;
+      case _SortingField.accumulatedInstances:
+        getter = _getAccumulatedInstances;
+        break;
+      case _SortingField.currentSize:
+        getter = _getCurrentSize;
+        break;
+      case _SortingField.currentInstances:
+        getter = _getCurrentInstances;
+        break;
+      case _SortingField.newAccumulatedSize:
+        getter = _getNewAccumulatedSize;
+        break;
+      case _SortingField.newAccumulatedInstances:
+        getter = _getNewAccumulatedInstances;
+        break;
+      case _SortingField.newCurrentSize:
+        getter = _getNewCurrentSize;
+        break;
+      case _SortingField.newCurrentInstances:
+        getter = _getNewCurrentInstances;
+        break;
+      case _SortingField.oldAccumulatedSize:
+        getter = _getOldAccumulatedSize;
+        break;
+      case _SortingField.oldAccumulatedInstances:
+        getter = _getOldAccumulatedInstances;
+        break;
+      case _SortingField.oldCurrentSize:
+        getter = _getOldCurrentSize;
+        break;
+      case _SortingField.oldCurrentInstances:
+        getter = _getOldCurrentInstances;
+        break;
+      case _SortingField.className:
+        getter = (M.ClassHeapStats s) => s.clazz.name;
+        break;
+    }
+    switch (_sortingDirection) {
+      case _SortingDirection.ascending:
+        return (a, b) => getter(a).compareTo(getter(b));
+      case _SortingDirection.descending:
+        return (a, b) => getter(b).compareTo(getter(a));
+    }
+  }
+
+  static Element _createCollectionLine() =>
+    new DivElement()
+      ..classes = const ['collection-item']
+      ..children = [
+        new SpanElement()..classes = const ['bytes']
+          ..text = '0B',
+        new SpanElement()..classes = const ['instances']
+          ..text = '0',
+        new SpanElement()..classes = const ['bytes']
+          ..text = '0B',
+        new SpanElement()..classes = const ['instances']
+          ..text = '0',
+        new SpanElement()..classes = const ['bytes']
+          ..text = '0B',
+        new SpanElement()..classes = const ['instances']
+          ..text = '0',
+        new SpanElement()..classes = const ['bytes']
+          ..text = '0B',
+        new SpanElement()..classes = const ['instances']
+          ..text = '0',
+        new SpanElement()..classes = const ['bytes']
+          ..text = '0B',
+        new SpanElement()..classes = const ['instances']
+          ..text = '0',
+        new SpanElement()..classes = const ['bytes']
+          ..text = '0B',
+        new SpanElement()..classes = const ['instances']
+          ..text = '0',
+        new SpanElement()..classes = const ['name']
+      ];
+
+  Element _createCollectionHeader() =>
+    new DivElement()
+      ..children = [
+        new DivElement()
+          ..classes = const ['collection-item']
+          ..children = [
+            new SpanElement()..classes = const ['group']
+              ..text = 'Accumulated',
+            new SpanElement()..classes = const ['group']
+              ..text = 'Current',
+            new SpanElement()..classes = const ['group']
+              ..text = '(NEW) Accumulated',
+            new SpanElement()..classes = const ['group']
+              ..text = '(NEW) Current',
+            new SpanElement()..classes = const ['group']
+              ..text = '(OLD) Accumulated',
+            new SpanElement()..classes = const ['group']
+              ..text = '(OLD) Current',
+          ],
+        new DivElement()
+          ..classes = const ['collection-item']
+          ..children = [
+            _createHeaderButton(const ['bytes'], 'Size',
+                                _SortingField.accumulatedSize,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['instances'], 'Instances',
+                                _SortingField.accumulatedInstances,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['bytes'], 'Size',
+                                _SortingField.currentSize,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['instances'], 'Instances',
+                                _SortingField.currentInstances,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['bytes'], 'Size',
+                                _SortingField.newAccumulatedSize,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['instances'], 'Instances',
+                                _SortingField.newAccumulatedInstances,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['bytes'], 'Size',
+                                _SortingField.newCurrentSize,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['instances'], 'Instances',
+                                _SortingField.newCurrentInstances,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['bytes'], 'Size',
+                                _SortingField.oldAccumulatedSize,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['instances'], 'Instances',
+                                _SortingField.oldAccumulatedInstances,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['bytes'], 'Size',
+                                _SortingField.oldCurrentSize,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['instances'], 'Instances',
+                                _SortingField.oldCurrentInstances,
+                                _SortingDirection.descending),
+            _createHeaderButton(const ['name'], 'Class',
+                                _SortingField.className,
+                                _SortingDirection.ascending)
+          ],
+      ];
+
+  ButtonElement _createHeaderButton(List<String> classes,
+                                    String text,
+                                    _SortingField field,
+                                    _SortingDirection direction) =>
+      new ButtonElement()..classes = classes
+          ..text = _sortingField != field ? text :
+                     _sortingDirection == _SortingDirection.ascending
+                     ? '$textâ–¼' : '$textâ–²'
+          ..onClick.listen((_) => _setSorting(field, direction));
+
+
+  void _setSorting(_SortingField field,
+                   _SortingDirection defaultDirection) {
+    if (_sortingField == field) {
+      switch (_sortingDirection) {
+        case _SortingDirection.descending:
+          _sortingDirection = _SortingDirection.ascending;
+          break;
+        case _SortingDirection.ascending:
+          _sortingDirection = _SortingDirection.descending;
+          break;
+      }
+    } else {
+      _sortingDirection = defaultDirection;
+      _sortingField = field;
+    }
+    _r.dirty();
+  }
+
+  void _updateCollectionLine(Element e, M.ClassHeapStats item,
+      index) {
+    e.children[0].text = Utils.formatSize(_getAccumulatedSize(item));
+    e.children[1].text = '${_getAccumulatedInstances(item)}';
+    e.children[2].text = Utils.formatSize(_getCurrentSize(item));
+    e.children[3].text = '${_getCurrentInstances(item)}';
+    e.children[4].text = Utils.formatSize(_getNewAccumulatedSize(item));
+    e.children[5].text = '${_getNewAccumulatedInstances(item)}';
+    e.children[6].text = Utils.formatSize(_getNewCurrentSize(item));
+    e.children[7].text = '${_getNewCurrentInstances(item)}';
+    e.children[8].text = Utils.formatSize(_getOldAccumulatedSize(item));
+    e.children[9].text = '${_getOldAccumulatedInstances(item)}';
+    e.children[10].text = Utils.formatSize(_getOldCurrentSize(item));
+    e.children[11].text = '${_getOldCurrentInstances(item)}';
+    e.children[12] = new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
+                      ..classes = ['name'];
+  }
+
+  static List<Element> _createSpaceMembers(M.HeapSpace space) {
+    final used = '${Utils.formatSize(space.used)}'
+                 ' of '
+                 '${Utils.formatSize(space.capacity)}';
+    final ext = '${Utils.formatSize(space.external)}';
+    final collections = '${space.collections}';
+    final avgCollectionTime =
+      '${Utils.formatDurationInMilliseconds(space.avgCollectionTime)} ms';
+    final totalCollectionTime =
+      '${Utils.formatDurationInSeconds(space.totalCollectionTime)} secs';
+    final avgCollectionPeriod =
+      '${Utils.formatDurationInMilliseconds(space.avgCollectionPeriod)} ms';
+    return [
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']..text = 'used',
+          new DivElement()..classes = ['memberValue']
+            ..text = used
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'external',
+          new DivElement()..classes = ['memberValue']
+            ..text = ext
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+          ..text = 'collections',
+          new DivElement()..classes = ['memberValue']
+            ..text = collections
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'average collection time',
+          new DivElement()..classes = ['memberValue']
+            ..text = avgCollectionTime
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'cumulative collection time',
+          new DivElement()..classes = ['memberValue']
+            ..text = totalCollectionTime
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'average time between collections',
+          new DivElement()..classes = ['memberValue']
+            ..text = avgCollectionPeriod
+        ]
+    ];
+  }
+
+  static final _columns = [
+      new ChartColumnSpec(label: 'Type', type: ChartColumnSpec.TYPE_STRING),
+      new ChartColumnSpec(label: 'Size', formatter: (v) => v.toString())
+  ];
+
+  static void _renderGraph(Element host, Element legend, M.HeapSpace space) {
+    final series = [new ChartSeries("Work", [1], new PieChartRenderer(
+      sortDataByValue: false
+    ))];
+    final rect = host.getBoundingClientRect();
+    final minSize = new Rect.size(rect.width, rect.height);
+    final config = new ChartConfig(series, [0])
+        ..minimumSize = minSize
+        ..legend = new ChartLegend(legend, showValues: true);
+    final data = new ChartData(_columns, [
+      ['Used', space.used],
+      ['Free', space.capacity - space.used],
+      ['External', space.external]
+    ]);
+
+    new LayoutArea(host, data, config, state: new ChartState(),
+        autoUpdate: true)
+      ..draw();
+  }
+
+  Future _refresh({bool gc: false, bool reset: false}) async {
+    _profile = null;
+    _r.dirty();
+    _profile = await _repository.get(_isolate, gc: gc, reset: reset);
+    _r.dirty();
+  }
+
+  void _downloadCSV() {
+    assert(_profile != null);
+    final header = ['"Accumulator Size"',
+                    '"Accumulator Instances"',
+                    '"Current Size"',
+                    '"Current Instances"',
+                    '"(NEW) Accumulator Size"',
+                    '"(NEW) Accumulator Instances"',
+                    '"(NEW) Current Size"',
+                    '"(NEW) Current Instances"',
+                    '"(OLD) Accumulator Size"',
+                    '"(OLD) Accumulator Instances"',
+                    '"(OLD) Current Size"',
+                    '"(OLD) Current Instances"',
+                    'Class'
+                    ].join(';') + '\n';
+    AnchorElement tl = document.createElement('a');
+    tl..attributes['href'] = 'data:text/plain;charset=utf-8,' +
+        Uri.encodeComponent(header +
+                            (_profile.members.toList()..sort(_createSorter()))
+                                    .map(_csvOut).join('\n'))
+      ..attributes['download'] = 'heap-profile.csv'
+      ..click();
+  }
+
+  static _csvOut(M.ClassHeapStats s) {
+    return [
+      _getAccumulatedSize(s),
+      _getAccumulatedInstances(s),
+      _getCurrentSize(s),
+      _getCurrentInstances(s),
+      _getNewAccumulatedSize(s),
+      _getNewAccumulatedInstances(s),
+      _getNewCurrentSize(s),
+      _getNewCurrentInstances(s),
+      _getOldAccumulatedSize(s),
+      _getOldAccumulatedInstances(s),
+      _getOldCurrentSize(s),
+      _getOldCurrentInstances(s),
+      s.clazz.name
+    ].join(';');
+  }
+
+  static int _getAccumulatedSize(M.ClassHeapStats s) =>
+      s.newSpace.accumulated.bytes + s.oldSpace.accumulated.bytes;
+  static int _getAccumulatedInstances(M.ClassHeapStats s) =>
+      s.newSpace.accumulated.instances + s.oldSpace.accumulated.instances;
+  static int _getCurrentSize(M.ClassHeapStats s) =>
+      s.newSpace.current.bytes + s.oldSpace.current.bytes;
+  static int _getCurrentInstances(M.ClassHeapStats s) =>
+      s.newSpace.current.instances + s.oldSpace.current.instances;
+  static int _getNewAccumulatedSize(M.ClassHeapStats s) =>
+      s.newSpace.accumulated.bytes;
+  static int _getNewAccumulatedInstances(M.ClassHeapStats s) =>
+      s.newSpace.accumulated.instances;
+  static int _getNewCurrentSize(M.ClassHeapStats s) =>
+      s.newSpace.current.bytes;
+  static int _getNewCurrentInstances(M.ClassHeapStats s) =>
+      s.newSpace.current.instances;
+  static int _getOldAccumulatedSize(M.ClassHeapStats s) =>
+      s.oldSpace.accumulated.bytes;
+  static int _getOldAccumulatedInstances(M.ClassHeapStats s) =>
+      s.oldSpace.accumulated.instances;
+  static int _getOldCurrentSize(M.ClassHeapStats s) =>
+      s.oldSpace.current.bytes;
+  static int _getOldCurrentInstances(M.ClassHeapStats s) =>
+      s.oldSpace.current.instances;
+}
diff --git a/runtime/observatory/lib/src/elements/class_ref.dart b/runtime/observatory/lib/src/elements/class_ref.dart
index b8895c6..8596d73 100644
--- a/runtime/observatory/lib/src/elements/class_ref.dart
+++ b/runtime/observatory/lib/src/elements/class_ref.dart
@@ -2,35 +2,56 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library class_ref_element;
-
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
-import 'service_ref.dart';
+import 'dart:html';
 import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 
-@CustomTag('class-ref')
-class ClassRefElement extends ServiceRefElement {
-  @observable bool asValue = false;
+class ClassRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ClassRefElement>('class-ref-wrapped');
+
+  RenderingScheduler<ClassRefElement> _r;
+
+  Stream<RenderedEvent<ClassRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.ClassRef _class;
+
+  M.IsolateRef get isolate => _isolate;
+  M.ClassRef get cls => _class;
+
+  factory ClassRefElement(M.IsolateRef isolate, M.ClassRef cls,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(cls != null);
+    ClassRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._class = cls;
+    return e;
+  }
 
   ClassRefElement.created() : super.created();
 
-  String makeExpandKey(String key) {
-    return '${expandKey}/${key}';
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
   }
 
-  dynamic expander() {
-    return expandEvent;
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
   }
 
-  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();
-    }
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _class))
+        ..text = _class.name
+    ];
   }
-}
\ 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
deleted file mode 100644
index c3ddec7..0000000
--- a/runtime/observatory/lib/src/elements/class_ref.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<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">
-    <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_ref_as_value.dart b/runtime/observatory/lib/src/elements/class_ref_as_value.dart
new file mode 100644
index 0000000..7e129f8
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/class_ref_as_value.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library class_ref_as_value_element;
+
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+import 'service_ref.dart';
+import 'dart:async';
+
+@CustomTag('class-ref-as-value')
+class ClassRefAsValueElement extends ServiceRefElement {
+
+  ClassRefAsValueElement.created() : super.created();
+
+  String makeExpandKey(String key) {
+    return '${expandKey}/${key}';
+  }
+
+  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();
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/class_ref_as_value.html b/runtime/observatory/lib/src/elements/class_ref_as_value.html
new file mode 100644
index 0000000..a148981
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/class_ref_as_value.html
@@ -0,0 +1,30 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="service_ref.html">
+
+<polymer-element name="class-ref-as-value">
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <style>
+      .indented {
+        margin-left: 1.5em;
+        font: 400 14px 'Montserrat', sans-serif;
+        line-height: 150%;
+      }
+    </style><!--
+    --><class-ref ref="{{ ref }}"></class-ref><!--
+    --><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>
+</polymer-element>
+
+<script type="application/dart" src="class_ref_as_value.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/class_ref_wrapper.dart b/runtime/observatory/lib/src/elements/class_ref_wrapper.dart
new file mode 100644
index 0000000..8d9c3fc
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/class_ref_wrapper.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart' show Class;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class ClassRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<ClassRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<ClassRefElementWrapper>('class-ref');
+
+  Class _class;
+  Class get ref => _class;
+  void set ref(Class ref) {
+    _class = ref;
+    render();
+  }
+
+  ClassRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) return;
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        class-ref-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        class-ref-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new ClassRefElement(_class.isolate, _class,
+          queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/class_tree.dart b/runtime/observatory/lib/src/elements/class_tree.dart
index 16f6928..6fefdfd 100644
--- a/runtime/observatory/lib/src/elements/class_tree.dart
+++ b/runtime/observatory/lib/src/elements/class_tree.dart
@@ -4,150 +4,182 @@
 
 library class_tree_element;
 
-import 'observatory_element.dart';
-import 'dart:async';
 import 'dart:html';
-import 'package:logging/logging.dart';
-import 'package:observatory/app.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/containers/virtual_tree.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
 
-class ClassTreeRow extends TableTreeRow {
-  @reflectable final Isolate isolate;
-  @reflectable final Class cls;
-  ClassTreeRow(this.isolate, this.cls, TableTree tree, ClassTreeRow parent)
-      : super(tree, parent) {
+
+class ClassTreeElement extends HtmlElement implements Renderable{
+  static const tag = const Tag<ClassTreeElement>('class-tree',
+                     dependencies: const [ClassRefElement.tag,
+                                          NavBarElement.tag,
+                                          NavIsolateMenuElement.tag,
+                                          NavMenuElement.tag,
+                                          NavNotifyElement.tag,
+                                          NavTopMenuElement.tag,
+                                          NavVMMenuElement.tag,
+                                          VirtualTreeElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<ClassTreeElement>> get onRendered => _r.onRendered;
+
+  M.VMRef _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.ClassRepository _classes;
+  M.Class _object;
+  final _subclasses = <String, Iterable<M.Class>>{};
+  final _mixins = <String, List<M.Instance>>{};
+
+  factory ClassTreeElement(M.VMRef vm, M.IsolateRef isolate,
+                           M.EventRepository events,
+                           M.NotificationRepository notifications,
+                           M.ClassRepository classes,
+                           {RenderingQueue queue}) {
+    assert(vm != null);
     assert(isolate != null);
-    assert(cls != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(classes != null);
+    ClassTreeElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._classes = classes;
+    return e;
   }
 
-  void _addChildren(List<Class> subclasses) {
-    for (var subclass in subclasses) {
-      if (subclass.isPatch) {
-        continue;
-      }
-      if (subclass.mixin != null) {
-        _addChildren(subclass.subclasses);
-      } else {
-        var row = new ClassTreeRow(isolate, subclass, tree, this);
-        children.add(row);
-      }
-    }
-  }
-
-  Future _addMixins(Class cls) async {
-    var classCell = flexColumns[0];
-    if (cls.superclass == null) {
-      return;
-    }
-    bool first = true;
-    while (cls.superclass != null && cls.superclass.mixin != null) {
-      cls = cls.superclass;
-      await cls.mixin.load();
-      var span = new SpanElement();
-      span.style.alignSelf = 'center';
-      span.style.whiteSpace = 'pre';
-      if (first) {
-        span.text = ' with ';
-      } else {
-        span.text = ', ';
-      }
-      classCell.children.add(span);
-      var mixinRef = new Element.tag('class-ref');
-      mixinRef.ref = cls.mixin.typeClass;
-      mixinRef.style.alignSelf = 'center';
-      classCell.children.add(mixinRef);
-      first = false;
-    }
-  }
-
-  Future _addClass(Class cls) async {
-    var classCell = flexColumns[0];
-    classCell.style.justifyContent = 'flex-start';
-    var classRef = new Element.tag('class-ref');
-    classRef.ref = cls;
-    classRef.style.alignSelf = 'center';
-    classCell.children.add(classRef);
-    if (cls.superclass != null && cls.superclass.mixin != null) {
-      await _addMixins(cls);
-    }
-    if (cls.subclasses.isNotEmpty) {
-      var span = new SpanElement();
-      span.style.paddingLeft = '.5em';
-      span.style.alignSelf = 'center';
-      int subclassCount = _indirectSubclassCount(cls) - 1;
-      if (subclassCount > 1) {
-        span.text = '($subclassCount subclasses)';
-      } else {
-        span.text = '($subclassCount subclass)';
-      }
-      classCell.children.add(span);
-    }
-  }
-
-  void onShow() {
-    super.onShow();
-    if (children.length == 0) {
-      _addChildren(cls.subclasses);
-    }
-    _addClass(cls);
-  }
-
-  static int _indirectSubclassCount(var cls) {
-    int count = 0;
-    if (cls.mixin == null) {
-      // Don't count synthetic mixin classes in subclass count.
-      count++;
-    }
-    for (var subclass in cls.subclasses) {
-      count += _indirectSubclassCount(subclass);
-    }
-    return count;
-  }
-
-  bool hasChildren() {
-    return cls.subclasses.isNotEmpty;
-  }
-}
-
-
-@CustomTag('class-tree')
-class ClassTreeElement extends ObservatoryElement {
-  @observable Isolate isolate;
-
-  TableTree tree;
-
   ClassTreeElement.created() : super.created();
 
   @override
   void attached() {
     super.attached();
-    var tableBody = shadowRoot.querySelector('#tableTreeBody');
-    assert(tableBody != null);
-    tree = new TableTree(tableBody, 1);
-    if (isolate != null) {
-      _update(isolate.objectClass);
+    _refresh();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  VirtualTreeElement _tree;
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavMenuElement('class hierarchy', link: Uris.classTree(_isolate),
+                             last: true, queue: _r.queue),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()
+        ..classes = ['content-centered']
+        ..children = [
+          new HeadingElement.h1()..text = 'Class Hierarchy',
+          new BRElement(), new HRElement(),
+          _object == null ? (new HeadingElement.h2()..text = 'Loading...')
+                          : _createTree()
+        ]
+    ];
+  }
+
+  Element _createTree() {
+    _tree = new VirtualTreeElement(_create, _update, _children,
+                                   items: [_object], queue: _r.queue);
+    _tree.expand(_object, autoExpandSingleChildNodes: true);
+    return _tree;
+  }
+
+  Future _refresh() async {
+    _object = null;
+    _subclasses.clear();
+    _mixins.clear();
+    _object = await _register(await _classes.getObject());
+    _r.dirty();
+  }
+
+  Future<M.Class> _register(M.Class cls) async {
+    _subclasses[cls.id] = await Future.wait(
+      (await Future.wait(cls.subclasses.map(_getActualChildrens)))
+      .expand((f) => f)
+      .map(_register)
+    );
+    return cls;
+  }
+
+  Future<Iterable<M.Class>> _getActualChildrens(M.ClassRef ref) async {
+    var cls = await _classes.get(ref.id);
+    if (cls.isPatch) {
+      return const [];
+    }
+    if (cls.mixin == null) {
+      return [cls];
+    }
+    return (await Future.wait(cls.subclasses.map(_getActualChildrens)))
+      .expand((f) => f)
+      ..forEach((subcls) {
+        _mixins[subcls.id] = (_mixins[subcls.id] ?? [])..add(cls.mixin);
+      });
+  }
+
+  static Element _create(toggle) {
+    return new DivElement()..classes = ['class-tree-item']
+        ..children = [
+          new SpanElement()..classes = ['lines'],
+          new ButtonElement()..classes = ['expander']
+            ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+          new SpanElement()..classes = ['name']
+        ];
+  }
+
+  void _update(HtmlElement el, M.Class cls, int index) {
+    virtualTreeUpdateLines(el.children[0], index);
+    if (cls.subclasses.isEmpty) {
+      el.children[1].text = '';
+    } else {
+      el.children[1].text = _tree.isExpanded(cls) ? 'â–¼' : 'â–º';
+    }
+    el.children[2].children = [
+      new ClassRefElement(_isolate, cls, queue: _r.queue)
+    ];
+    if (_mixins[cls.id] != null) {
+      el.children[2].children.addAll(_createMixins(_mixins[cls.id]));
     }
   }
 
-  isolateChanged(oldValue) {
-    isolate.getClassHierarchy().then((objectClass) {
-      _update(objectClass);
-    });
+  List<Element> _createMixins(List<M.Instance> types) {
+    final  children = types.expand((type) => [
+      new SpanElement()..text = ', ',
+      type.typeClass == null
+          ? (new SpanElement()..text = type.name.split('<').first)
+          : new ClassRefElement(_isolate, type.typeClass, queue: _r.queue)
+    ]).toList();
+    children.first.text = ' with ';
+    return children;
   }
 
-  void _update(Class root) {
-    try {
-      var rootRow = new ClassTreeRow(isolate, root, tree, null);
-      rootRow.children.add(new ClassTreeRow(isolate, root, tree, rootRow));
-      tree.initialize(rootRow);
-    } catch (e, stackTrace) {
-      Logger.root.warning('_update', e, stackTrace);
-    }
-    // Check if we only have one node at the root and expand it.
-    if (tree.rows.length == 1) {
-      tree.toggle(tree.rows[0]);
-    }
-    notifyPropertyChange(#tree, null, tree);
+  Iterable<M.Class> _children(M.Class cls) {
+    return _subclasses[cls.id];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/class_tree.html b/runtime/observatory/lib/src/elements/class_tree.html
deleted file mode 100644
index c1e9635..0000000
--- a/runtime/observatory/lib/src/elements/class_tree.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="class_ref.html">
-
-<polymer-element name="class-tree" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-      .table {
-        border-spacing: 0px;
-        width: 100%;
-        margin-bottom: 20px
-        vertical-align: middle;
-      }
-
-      tr {
-        background-color: #FFFFFF;
-      }
-
-      tr:hover {
-        background-color: #FAFAFA;
-      }
-
-      th {
-        text-align: left;
-      }
-    </style>
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
-      <nav-menu link="{{ makeLink('/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">
-        <tbody id="tableTreeBody"></tbody>
-      </table>
-    </div>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="class_tree.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index b1ac3fc..b101fbf 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -6,9 +6,13 @@
 
 import 'dart:async';
 import 'observatory_element.dart';
-import 'package:observatory/cpu_profile.dart';
+import 'sample_buffer_control.dart';
+import 'stack_trace_tree_config.dart';
+import 'cpu_profile/virtual_tree.dart';
 import 'package:observatory/elements.dart';
+import 'package:observatory/models.dart' as M;
 import 'package:observatory/service.dart';
+import 'package:observatory/repositories.dart';
 import 'package:polymer/polymer.dart';
 
 @CustomTag('class-view')
@@ -21,6 +25,8 @@
   SampleBufferControlElement sampleBufferControlElement;
   StackTraceTreeConfigElement stackTraceTreeConfigElement;
   CpuProfileVirtualTreeElement cpuProfileTreeElement;
+  ClassSampleProfileRepository repository = new ClassSampleProfileRepository();
+
 
   ClassViewElement.created() : super.created();
 
@@ -59,66 +65,62 @@
 
   void attached() {
     super.attached();
-    sampleBufferControlElement =
-        shadowRoot.querySelector('#sampleBufferControl');
-    assert(sampleBufferControlElement != null);
-    sampleBufferControlElement.onSampleBufferUpdate = onSampleBufferChange;
-    sampleBufferControlElement.state =
-        SampleBufferControlElement.kNotLoadedState;
-    stackTraceTreeConfigElement =
-        shadowRoot.querySelector('#stackTraceTreeConfig');
-    assert(stackTraceTreeConfigElement != null);
-    stackTraceTreeConfigElement.onTreeConfigChange = onTreeConfigChange;
-    stackTraceTreeConfigElement.show = false;
-    stackTraceTreeConfigElement.showFilter = false;
-    cpuProfileTreeElement = shadowRoot.querySelector('#cpuProfileTree');
-    assert(cpuProfileTreeElement != null);
-    cpuProfileTreeElement.profile = sampleBufferControlElement.profile;
-    cpuProfileTreeElement.show = false;
     cls.fields.forEach((field) => field.reload());
-    sampleBufferControlElement.allocationProfileClass = cls;
   }
 
-  Future refresh() {
+  Future refresh() async {
     instances = null;
     retainedBytes = null;
     mostRetained = null;
-    var loads = [];
-    loads.add(cls.reload());
-    cls.fields.forEach((field) => loads.add(field.reload()));
-    return Future.wait(loads);
+    await cls.reload();
+    await Future.wait(cls.fields.map((field) => field.reload()));
   }
 
-  onSampleBufferChange(CpuProfile sampleBuffer) {
-    stackTraceTreeConfigElement.show = sampleBuffer.sampleCount > 0;
-    cpuProfileTreeElement.show = sampleBuffer.sampleCount > 0;
-    cpuProfileTreeElement.render();
-  }
-
-  onTreeConfigChange(String modeSelector,
-                     String directionSelector,
-                     String filter) {
-    ProfileTreeDirection direction = ProfileTreeDirection.Exclusive;
-    if (directionSelector != 'Up') {
-      direction = ProfileTreeDirection.Inclusive;
-    }
-    ProfileTreeMode mode = ProfileTreeMode.Function;
-    if (modeSelector == 'Code') {
-      mode = ProfileTreeMode.Code;
-    }
-    cpuProfileTreeElement.direction = direction;
-    cpuProfileTreeElement.mode = mode;
-    cpuProfileTreeElement.render();
-  }
+  M.SampleProfileTag _tag = M.SampleProfileTag.none;
 
   Future refreshAllocationProfile() async {
-    return sampleBufferControlElement.reload(cls.isolate);
+    shadowRoot.querySelector('#sampleBufferControl').children = const [];
+    shadowRoot.querySelector('#stackTraceTreeConfig').children = const [];
+    shadowRoot.querySelector('#cpuProfileTree').children = const [];
+    final stream = repository.get(cls, _tag);
+    var progress = (await stream.first).progress;
+    shadowRoot.querySelector('#sampleBufferControl')..children = [
+      new SampleBufferControlElement(progress, stream, queue: app.queue,
+          selectedTag: _tag)
+        ..onTagChange.listen((e) {
+          _tag = e.element.selectedTag;
+          refreshAllocationProfile();
+        })
+    ];
+    if (M.isSampleProcessRunning(progress.status)) {
+      progress = (await stream.last).progress;
+    }
+    if (progress.status == M.SampleProfileLoadingStatus.loaded) {
+      shadowRoot.querySelector('#stackTraceTreeConfig')..children = [
+        new StackTraceTreeConfigElement(
+          queue: app.queue)
+          ..showFilter = false
+          ..onModeChange.listen((e) {
+            cpuProfileTreeElement.mode = e.element.mode;
+          })
+          ..onDirectionChange.listen((e) {
+            cpuProfileTreeElement.direction = e.element.direction;
+          })
+      ];
+      shadowRoot.querySelector('#cpuProfileTree')..children = [
+        cpuProfileTreeElement = new CpuProfileVirtualTreeElement(cls.isolate,
+          progress.profile, queue: app.queue)
+      ];
+    }
   }
 
   Future toggleAllocationTrace() {
     if (cls == null) {
       return new Future(refresh);
     }
+    if (cls.traceAllocations) {
+      refreshAllocationProfile();
+    }
     return cls.setTraceAllocations(!cls.traceAllocations).whenComplete(refresh);
   }
 }
diff --git a/runtime/observatory/lib/src/elements/class_view.html b/runtime/observatory/lib/src/elements/class_view.html
index 086b96b..14af953 100644
--- a/runtime/observatory/lib/src/elements/class_view.html
+++ b/runtime/observatory/lib/src/elements/class_view.html
@@ -1,20 +1,10 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="action_link.html">
-<link rel="import" href="cpu_profile.html">
-<link rel="import" href="curly_block.html">
 <link rel="import" href="eval_box.html">
 <link rel="import" href="eval_link.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="library_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="script_inset.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="class-view" extends="observatory-element">
+<polymer-element name="class-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -25,6 +15,7 @@
       <class-nav-menu cls="{{ cls }}" last="{{ true }}"></class-nav-menu>
       <nav-refresh callback="{{ refreshAllocationProfile }}" label="Refresh Allocation Profile"></nav-refresh>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
@@ -264,15 +255,11 @@
           </div>
         </template>
       </div>
-      <sample-buffer-control id="sampleBufferControl"></sample-buffer-control>
+      <div id="sampleBufferControl"></div>
       <br>
-      <stack-trace-tree-config id="stackTraceTreeConfig"></stack-trace-tree-config>
+      <div id="stackTraceTreeConfig"></div>
       <br>
-      <div class="flex-row centered">
-        <div class="flex-item-90-percent outlined" style="margin: 16px; margin-left: 8px; margin-right: 8px">
-          <cpu-profile-virtual-tree id="cpuProfileTree"></cpu-profile-virtual-tree>
-        </div>
-      </div>
+      <div id="cpuProfileTree"></div>
     </div>
 
     <div class="content-centered-big">
diff --git a/runtime/observatory/lib/src/elements/code_ref.dart b/runtime/observatory/lib/src/elements/code_ref.dart
index 88464de..61917a8 100644
--- a/runtime/observatory/lib/src/elements/code_ref.dart
+++ b/runtime/observatory/lib/src/elements/code_ref.dart
@@ -4,31 +4,59 @@
 
 library code_ref_element;
 
-import 'package:polymer/polymer.dart';
-import 'service_ref.dart';
-import 'package:observatory/service.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, CodeRef, isSyntheticCode;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 
-@CustomTag('code-ref')
-class CodeRefElement extends ServiceRefElement {
-  CodeRefElement.created() : super.created();
+class CodeRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<CodeRefElement>('code-ref-wrapped');
 
-  Code get code => ref;
+  RenderingScheduler<CodeRefElement> _r;
 
-  refChanged(oldValue) {
-    super.refChanged(oldValue);
-    _updateShadowDom();
+  Stream<RenderedEvent<CodeRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.CodeRef _code;
+
+  M.IsolateRef get isolate => _isolate;
+  M.CodeRef get code => _code;
+
+  factory CodeRefElement(M.IsolateRef isolate, M.CodeRef code,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(code != null);
+    CodeRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._code = code;
+    return e;
   }
 
-  void _updateShadowDom() {
-    clearShadowRoot();
-    if (code == null) {
-      return;
-    }
-    var name = (code.isOptimized ? '*' : '') + code.name;
-    if (code.isDartCode) {
-      insertLinkIntoShadowRoot(name, url, hoverText);
-    } else {
-      insertTextSpanIntoShadowRoot(name);
-    }
+  CodeRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    final name = (_code.isOptimized ? '*' : '') + _code.name;
+    children = [
+      new AnchorElement(href: M.isSyntheticCode(_code.kind) ? null
+          : Uris.inspect(_isolate, object: _code))
+        ..text = name
+    ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/code_ref.html b/runtime/observatory/lib/src/elements/code_ref.html
deleted file mode 100644
index c20fdb5..0000000
--- a/runtime/observatory/lib/src/elements/code_ref.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="service_ref.html">
-
-<polymer-element name="code-ref" extends="service-ref">
-  <template><link rel="stylesheet" href="css/shared.css"></template>
-</polymer-element>
-
-<script type="application/dart" src="code_ref.dart"></script>
\ No newline at end of file
diff --git a/runtime/observatory/lib/src/elements/code_ref_wrapper.dart b/runtime/observatory/lib/src/elements/code_ref_wrapper.dart
new file mode 100644
index 0000000..f630f33
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/code_ref_wrapper.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart' show Code;
+import 'package:observatory/src/elements/code_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class CodeRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<CodeRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<CodeRefElementWrapper>('code-ref');
+
+  Code _code;
+
+  Code get ref => _code;
+
+  void set ref(Code value) {
+    _code = value;
+    render();
+  }
+
+  CodeRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        code-ref-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        code-ref-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new CodeRefElement(_code.isolate, _code,
+          queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/code_view.html b/runtime/observatory/lib/src/elements/code_view.html
index 95f71e2..0f76214 100644
--- a/runtime/observatory/lib/src/elements/code_view.html
+++ b/runtime/observatory/lib/src/elements/code_view.html
@@ -1,12 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="code-view" extends="observatory-element">
+<polymer-element name="code-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -59,6 +53,7 @@
       <nav-menu link="{{ makeLink('/inspect', code) }}" anchor="{{ code.name }}" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
       <nav-refresh callback="{{ refreshTicks }}" label="Refresh Ticks"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
     <div class="content">
       <template if="{{ code.isDartCode && code.isOptimized }}">
diff --git a/runtime/observatory/lib/src/elements/containers/virtual_collection.dart b/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
new file mode 100644
index 0000000..b6f91b9
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
@@ -0,0 +1,168 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+
+typedef HtmlElement VirtualCollectionCreateCallback();
+typedef void VirtualCollectionUpdateCallback(HtmlElement el, dynamic item,
+    int index);
+
+class VirtualCollectionElement extends HtmlElement implements Renderable {
+  static const tag =
+      const Tag<VirtualCollectionElement>('virtual-collection');
+
+  RenderingScheduler<VirtualCollectionElement> _r;
+
+  Stream<RenderedEvent<VirtualCollectionElement>> get onRendered =>
+      _r.onRendered;
+
+  VirtualCollectionCreateCallback _create;
+  VirtualCollectionCreateCallback _createHeader;
+  VirtualCollectionUpdateCallback _update;
+  double _itemHeight;
+  int _top;
+  double _height;
+  List _items;
+  StreamSubscription _onScrollSubscription;
+  StreamSubscription _onResizeSubscription;
+
+  List get items => _items;
+
+  set items(Iterable value) {
+    _items = new List.unmodifiable(value);
+    _top = null;
+    _r.dirty();
+  }
+
+
+  factory VirtualCollectionElement(VirtualCollectionCreateCallback create,
+      VirtualCollectionUpdateCallback update, {Iterable items: const [],
+      VirtualCollectionCreateCallback createHeader,
+      RenderingQueue queue}) {
+    assert(create != null);
+    assert(update != null);
+    assert(items != null);
+    VirtualCollectionElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._create = create;
+    e._createHeader = createHeader;
+    e._update = update;
+    e._items = new List.unmodifiable(items);
+    return e;
+  }
+
+  VirtualCollectionElement.created() : super.created();
+
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+    _top = null;
+    _itemHeight = null;
+    _onScrollSubscription = onScroll.listen(_onScroll);
+    _onResizeSubscription = window.onResize.listen(_onResize);
+  }
+
+ @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = const [];
+    _onScrollSubscription.cancel();
+    _onResizeSubscription.cancel();
+  }
+
+  final DivElement _header = new DivElement()..classes = const ['header'];
+  final DivElement _scroller = new DivElement()..classes = const ['scroller'];
+  final DivElement _shifter = new DivElement()..classes = const ['shifter'];
+
+  dynamic getItemFromElement(HtmlElement element) {
+    final el_index = _shifter.children.indexOf(element);
+    if (el_index < 0) {
+      return null;
+    }
+    final item_index =
+      _top + el_index - (_shifter.children.length * _inverse_preload).floor();
+    if (0 <= item_index && item_index < items.length) {
+      return _items[item_index];
+    }
+    return null;
+  }
+
+  /// The preloaded element before and after the visible area are:
+  /// 1/preload_size of the number of items in the visble area.
+  /// See shared.css for the "top:-25%;".
+  static const int _preload = 2;
+  /// L = length of all the elements loaded
+  /// l = length of the visible area
+  ///
+  /// L = l + 2 * l / _preload
+  /// l = L * _preload / (_preload + 2)
+  ///
+  /// tail = l / _preload = L * 1 / (_preload + 2) = L * _inverse_preload
+  static const double _inverse_preload = 1 / (_preload + 2);
+
+  void render() {
+    if (children.isEmpty) {
+      children = [
+        _scroller
+          ..children = [
+            _shifter
+              ..children = [_create()]
+          ],
+      ];
+      if (_createHeader != null) {
+        _header.children = [_createHeader()];
+        _scroller.children.insert(0, _header);
+      }
+      _itemHeight = _shifter.children[0].getBoundingClientRect().height;
+      _height = getBoundingClientRect().height;
+    }
+    final top = (scrollTop / _itemHeight).floor();
+
+    _header.style.top = '${scrollTop}px';
+    _scroller.style.height = '${_itemHeight*(_items.length)}px';
+    final tail_length = (_height / _itemHeight / _preload).ceil();
+    final length = tail_length * 2 + tail_length * _preload;
+
+    if (_shifter.children.length < length) {
+      while (_shifter.children.length != length) {
+        var e = _create();
+        e..style.display = 'hidden';
+        _shifter.children.add(e);
+      }
+      _top = null; // force update;
+    }
+
+    if ((_top == null) || ((top - _top).abs() >= tail_length)) {
+      _shifter.style.top = '${_itemHeight*(top-tail_length)}px';
+      int i = top - tail_length;
+      for (final HtmlElement e in _shifter.children) {
+        if (0 <= i && i < _items.length) {
+          e..style.display = null;
+          _update(e, _items[i], i);
+        } else {
+          e.style.display = 'hidden';
+        }
+        i++;
+      }
+      _top = top;
+    }
+  }
+
+  void _onScroll(_) {
+    _r.dirty();
+  }
+
+  void _onResize(_) {
+    final newHeight = getBoundingClientRect().height;
+    if (newHeight > _height) {
+      _height = newHeight;
+      _r.dirty();
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/containers/virtual_tree.dart b/runtime/observatory/lib/src/elements/containers/virtual_tree.dart
new file mode 100644
index 0000000..4df0dd7
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/containers/virtual_tree.dart
@@ -0,0 +1,160 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:math' as Math;
+import 'package:observatory/src/elements/containers/virtual_collection.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+
+typedef HtmlElement VirtualTreeCreateCallback(
+    toggle({bool autoToggleSingleChildNodes, bool autoToggleWholeTree}));
+typedef void VirtualTreeUpdateCallback(HtmlElement el, dynamic item, int depth);
+typedef Iterable<dynamic> VritualTreeGetChildrenCallback(dynamic value);
+
+void virtualTreeUpdateLines(SpanElement element, int n) {
+  n = Math.max(0, n);
+  while (element.children.length > n) {
+    element.children.removeLast();
+  }
+  while (element.children.length < n) {
+    element.children.add(new SpanElement());
+  }
+}
+
+class VirtualTreeElement extends HtmlElement implements Renderable {
+  static const tag =
+      const Tag<VirtualTreeElement>('virtual-tree', dependencies: const [
+        VirtualCollectionElement.tag
+      ]);
+
+  RenderingScheduler<VirtualTreeElement> _r;
+
+  Stream<RenderedEvent<VirtualTreeElement>> get onRendered => _r.onRendered;
+
+  VritualTreeGetChildrenCallback _children;
+  List _items;
+  List _depths;
+  final Set _expanded = new Set();
+
+  List get items => _items;
+
+  set items(Iterable value) {
+    _items = new List.unmodifiable(value);
+    _expanded.clear();
+    _r.dirty();
+  }
+
+  factory VirtualTreeElement(VirtualTreeCreateCallback create,
+      VirtualTreeUpdateCallback update, VritualTreeGetChildrenCallback children,
+      {Iterable items: const [], RenderingQueue queue}) {
+    assert(create != null);
+    assert(update != null);
+    assert(children != null);
+    assert(items != null);
+    VirtualTreeElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._children = children;
+    e._collection = new VirtualCollectionElement(() {
+      var element;
+      return element = create(({bool autoToggleSingleChildNodes: false,
+          bool autoToggleWholeTree: false}) {
+        var item = e._collection.getItemFromElement(element);
+        if (e.isExpanded(item)) {
+          e.collapse(item, autoCollapseWholeTree: autoToggleWholeTree,
+              autoCollapseSingleChildNodes: autoToggleSingleChildNodes);
+        } else {
+          e.expand(item, autoExpandWholeTree: autoToggleWholeTree,
+              autoExpandSingleChildNodes: autoToggleSingleChildNodes);
+        }
+      });
+    }, (HtmlElement el, dynamic item, int index) {
+      update(el, item, e._depths[index]);
+    }, queue: queue);
+    e._items = new List.unmodifiable(items);
+    return e;
+  }
+
+  VirtualTreeElement.created() : super.created();
+
+  bool isExpanded(item) {
+    return _expanded.contains(item);
+  }
+
+  void expand(item, {bool autoExpandSingleChildNodes : false,
+      bool autoExpandWholeTree: false}) {
+    if (_expanded.add(item)) _r.dirty();
+    if (autoExpandWholeTree) {
+      for (final child in _children(item)) {
+        expand(child, autoExpandWholeTree: true);
+      }
+    } else if (autoExpandSingleChildNodes) {
+      var children = _children(item);
+      while (children.length == 1) {
+        _expanded.add(children.first);
+        children = _children(children.first);
+      }
+    }
+  }
+
+  void collapse(item, {bool autoCollapseSingleChildNodes : false,
+      bool autoCollapseWholeTree: false}) {
+    if (_expanded.remove(item)) _r.dirty();
+    if (autoCollapseWholeTree) {
+      for (final child in _children(item)) {
+        collapse(child, autoCollapseWholeTree: true);
+      }
+    } else if (autoCollapseSingleChildNodes) {
+      var children = _children(item);
+      while (children.length == 1) {
+        _expanded.remove(children.first);
+        children = _children(children.first);
+      }
+    }
+  }
+
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+  }
+
+ @override
+  detached() {
+    super.detached(); _r.disable(notify: true);
+    children = const [];
+  }
+
+  VirtualCollectionElement _collection;
+
+  void render() {
+    if (children.length == 0) {
+      children = [_collection];
+    }
+    Iterable _toList(item) {
+      if (isExpanded(item)) {
+        Iterable children = _children(item);
+        if (children.isNotEmpty) {
+          return [item]..addAll(children.expand(_toList));
+        }
+      }
+      return [item];
+    }
+    _collection.items = _items.expand(_toList);
+    var depth = 0;
+    Iterable _toDepth(item) {
+      if (isExpanded(item)) {
+        Iterable children = _children(item);
+        if (children.isNotEmpty) {
+          depth++;
+          return children.expand(_toDepth).toList()
+              ..insert(0, --depth);
+        }
+      }
+      return [depth];
+    }
+    _depths = _items.expand(_toDepth).toList();
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/context_ref.dart b/runtime/observatory/lib/src/elements/context_ref.dart
index 7f020ec..7a64172 100644
--- a/runtime/observatory/lib/src/elements/context_ref.dart
+++ b/runtime/observatory/lib/src/elements/context_ref.dart
@@ -2,32 +2,60 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library context_ref_element;
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, ContextRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 
-import 'package:polymer/polymer.dart';
-import 'package:observatory/service.dart';
-import 'service_ref.dart';
+class ContextRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ContextRefElement>('context-ref-wrapped');
 
-@CustomTag('context-ref')
-class ContextRefElement extends ServiceRefElement {
-  ContextRefElement.created() : super.created();
+  RenderingScheduler<ContextRefElement> _r;
 
-  // TODO(turnidge): This is here to workaround vm/dart2js differences.
-  dynamic expander() {
-    return expandEvent;
+  Stream<RenderedEvent<ContextRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.ContextRef _context;
+
+  M.IsolateRef get isolate => _isolate;
+  M.ContextRef get context => _context;
+
+  factory ContextRefElement(M.IsolateRef isolate, M.ContextRef context,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(context != null);
+    ContextRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._context = context;
+    return e;
   }
 
-  void expandEvent(bool expand, Function onDone) {
-    assert(ref is Context);
-    if (expand) {
-      ref.reload().then((result) {
-        ref = result;
-        notifyPropertyChange(#ref, 0, 1);
-      }).whenComplete(onDone);
-    } else {
-      Context refMap = ref;
-      refMap.variables = null;
-      onDone();
-    }
+  ContextRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _context))
+        ..children = [
+          new SpanElement()..classes = ['empathize']..text = 'Context',
+          new SpanElement()..text = ' (${_context.length})'
+        ]
+    ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/context_ref.html b/runtime/observatory/lib/src/elements/context_ref.html
deleted file mode 100644
index 82e313d..0000000
--- a/runtime/observatory/lib/src/elements/context_ref.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<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="context-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <span>
-      <a on-click="{{ goto }}" _href="{{ url }}"><em>Context</em> ({{ ref.length }})</a>
-      <curly-block callback="{{ expander() }}">
-        <div class="memberList">
-          <div class="memberItem">
-            <div class="memberName">parent</div>
-            <div class="memberValue">
-              <any-service-ref ref="{{ ref.parentContext }}"></any-service-ref>
-            </div>
-          </div>
-          <template repeat="{{ index in ref.variables.asMap().keys }}">
-            <div class="memberItem">
-              <div class="memberName">[{{ index }}]</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ ref.variables[index]['value'] }}">
-                </any-service-ref>
-              </div>
-            </div>
-          </template>
-        </div>
-      </curly-block>
-    </span>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="context_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/context_ref_wrapper.dart b/runtime/observatory/lib/src/elements/context_ref_wrapper.dart
new file mode 100644
index 0000000..b950d32
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/context_ref_wrapper.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart' show Context;
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class ContextRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<ContextRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<ContextRefElementWrapper>('context-ref');
+
+  Context _context;
+  Context get ref => _context;
+  void set ref(Context ref) {
+    _context = ref;
+    render();
+  }
+
+  ContextRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) return;
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        context-ref-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        context-ref-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }
+        context-ref-wrapped .empathize {
+          font-style: italic;
+        }''',
+      new ContextRefElement(_context.isolate, _context,
+          queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/context_view.html b/runtime/observatory/lib/src/elements/context_view.html
index 44972f3..b31ed92 100644
--- a/runtime/observatory/lib/src/elements/context_view.html
+++ b/runtime/observatory/lib/src/elements/context_view.html
@@ -1,15 +1,7 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="object_common.html">
-<link rel="import" href="context_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="context-view" extends="observatory-element">
+<polymer-element name="context-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -20,6 +12,7 @@
       <class-nav-menu cls="{{ context.clazz }}"></class-nav-menu>
       <nav-menu link="." anchor="instance" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <template if="{{ !context.isError }}">
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 305706a..014fd80 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -6,1570 +6,168 @@
 
 import 'dart:async';
 import 'dart:html';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:observatory/app.dart';
-import 'package:observatory/cpu_profile.dart';
-import 'package:observatory/elements.dart';
-import 'package:polymer/polymer.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/sample_buffer_control.dart';
+import 'package:observatory/src/elements/stack_trace_tree_config.dart';
 
-List<String> sorted(Set<String> attributes) {
-  var list = attributes.toList();
-  list.sort();
-  return list;
-}
+class CpuProfileElement  extends HtmlElement implements Renderable {
+  static const tag = const Tag<CpuProfileElement>('cpu-profile',
+                                            dependencies: const [
+                                              NavBarElement.tag,
+                                              NavTopMenuElement.tag,
+                                              NavVMMenuElement.tag,
+                                              NavIsolateMenuElement.tag,
+                                              NavMenuElement.tag,
+                                              NavRefreshElement.tag,
+                                              NavNotifyElement.tag,
+                                              SampleBufferControlElement.tag,
+                                              StackTraceTreeConfigElement.tag,
+                                              CpuProfileVirtualTreeElement.tag,
+                                            ]);
 
-abstract class ProfileTreeRow<T> extends TableTreeRow {
-  final CpuProfile profile;
-  final T node;
-  final String selfPercent;
-  final String percent;
-  bool _infoBoxShown = false;
-  HtmlElement infoBox;
-  HtmlElement infoButton;
+  RenderingScheduler<CpuProfileElement> _r;
 
-  ProfileTreeRow(TableTree tree, TableTreeRow parent,
-                 this.profile, this.node, double selfPercent, double percent)
-      : super(tree, parent),
-        selfPercent = Utils.formatPercentNormalized(selfPercent),
-        percent = Utils.formatPercentNormalized(percent);
+  Stream<RenderedEvent<CpuProfileElement>> get onRendered => _r.onRendered;
 
-  static _addToMemberList(DivElement memberList, Map<String, String> items) {
-    items.forEach((k, v) {
-      var item = new DivElement();
-      item.classes.add('memberItem');
-      var name = new DivElement();
-      name.classes.add('memberName');
-      name.text = k;
-      var value = new DivElement();
-      value.classes.add('memberValue');
-      value.text = v;
-      item.children.add(name);
-      item.children.add(value);
-      memberList.children.add(item);
-    });
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.IsolateSampleProfileRepository _profiles;
+  Stream<M.SampleProfileLoadingProgressEvent> _progressStream;
+  M.SampleProfileLoadingProgress _progress;
+  M.SampleProfileTag _tag = M.SampleProfileTag.none;
+  ProfileTreeMode _mode = ProfileTreeMode.function;
+  M.ProfileTreeDirection _direction = M.ProfileTreeDirection.exclusive;
+  String _filter = '';
+
+
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+  M.IsolateSampleProfileRepository get profiles => _profiles;
+  M.VMRef get vm => _vm;
+
+  factory CpuProfileElement(M.VM vm, M.IsolateRef isolate,
+                            M.EventRepository events,
+                            M.NotificationRepository notifications,
+                            M.IsolateSampleProfileRepository profiles,
+                            {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(profiles != null);
+    CpuProfileElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._profiles = profiles;
+    return e;
   }
 
-  makeInfoBox() {
-    if (infoBox != null) {
-      return;
-    }
-    infoBox = new DivElement();
-    infoBox.classes.add('infoBox');
-    infoBox.classes.add('shadow');
-    infoBox.style.display = 'none';
-    listeners.add(infoBox.onClick.listen((e) => e.stopPropagation()));
-  }
-
-  makeInfoButton() {
-    infoButton = new SpanElement();
-    infoButton.style.marginLeft = 'auto';
-    infoButton.style.marginRight = '1em';
-    infoButton.children.add(new Element.tag('icon-info-outline'));
-    listeners.add(infoButton.onClick.listen((event) {
-      event.stopPropagation();
-      toggleInfoBox();
-    }));
-  }
-
-  static const attributes = const {
-    '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'],
-    'stub': const ['S', null, 'Stub'],
-    'synthetic' : const ['?', null, 'Synthetic'],
-  };
-
-  HtmlElement newAttributeBox(String attribute) {
-    List attributeDetails = attributes[attribute];
-    if (attributeDetails == null) {
-      print('could not find attribute $attribute');
-      return null;
-    }
-    var element = new SpanElement();
-    element.style.border = 'solid 2px #ECECEC';
-    element.style.height = '100%';
-    element.style.display = 'inline-block';
-    element.style.textAlign = 'center';
-    element.style.minWidth = '1.5em';
-    element.style.fontWeight = 'bold';
-    if (attributeDetails[1] != null) {
-      element.style.backgroundColor = attributeDetails[1];
-    }
-    element.text = attributeDetails[0];
-    element.title = attributeDetails[2];
-    return element;
-  }
-
-  onHide() {
-    super.onHide();
-    infoBox = null;
-    infoButton = null;
-  }
-
-  showInfoBox() {
-    if ((infoButton == null) || (infoBox == null)) {
-      return;
-    }
-    _infoBoxShown = true;
-    infoBox.style.display = 'block';
-    infoButton.children.clear();
-    infoButton.children.add(new Element.tag('icon-info'));
-  }
-
-  hideInfoBox() {
-    _infoBoxShown = false;
-    if ((infoButton == null) || (infoBox == null)) {
-      return;
-    }
-    infoBox.style.display = 'none';
-    infoButton.children.clear();
-    infoButton.children.add(new Element.tag('icon-info-outline'));
-  }
-
-  toggleInfoBox() {
-   if (_infoBoxShown) {
-     hideInfoBox();
-   } else {
-     showInfoBox();
-   }
-  }
-
-  hideAllInfoBoxes() {
-    final List<ProfileTreeRow> rows = tree.rows;
-    for (var row in rows) {
-      row.hideInfoBox();
-    }
-  }
-
-  onClick(MouseEvent e) {
-    e.stopPropagation();
-    if (e.altKey) {
-      bool show = !_infoBoxShown;
-      hideAllInfoBoxes();
-      if (show) {
-        showInfoBox();
-      }
-      return;
-    }
-    super.onClick(e);
-  }
-
-  HtmlElement newCodeRef(ProfileCode code) {
-    var codeRef = new Element.tag('code-ref');
-    codeRef.ref = code.code;
-    return codeRef;
-  }
-
-  HtmlElement newFunctionRef(ProfileFunction function) {
-    var ref = new Element.tag('function-ref');
-    ref.ref = function.function;
-    return ref;
-  }
-
-  HtmlElement hr() {
-    var element = new HRElement();
-    return element;
-  }
-
-  HtmlElement div(String text) {
-    var element = new DivElement();
-    element.text = text;
-    return element;
-  }
-
-  HtmlElement br() {
-    return new BRElement();
-  }
-
-  HtmlElement span(String text) {
-    var element = new SpanElement();
-    element.style.minWidth = '1em';
-    element.text = text;
-    return element;
-  }
-}
-
-class CodeProfileTreeRow extends ProfileTreeRow<CodeCallTreeNode> {
-  CodeProfileTreeRow(TableTree tree, CodeProfileTreeRow parent,
-                     CpuProfile profile, CodeCallTreeNode node)
-      : super(tree, parent, profile, node,
-              node.profileCode.normalizedExclusiveTicks,
-              node.percentage) {
-    // fill out attributes.
-  }
-
-  bool hasChildren() => node.children.length > 0;
-
-  void onShow() {
-    super.onShow();
-
-    if (children.length == 0) {
-      for (var childNode in node.children) {
-        var row = new CodeProfileTreeRow(tree, this, profile, childNode);
-        children.add(row);
-      }
-    }
-
-    // Fill in method column.
-    var methodColumn = flexColumns[0];
-    methodColumn.style.justifyContent = 'flex-start';
-    methodColumn.style.position = 'relative';
-
-    // Percent.
-    var percentNode = new DivElement();
-    percentNode.text = percent;
-    percentNode.style.minWidth = '5em';
-    percentNode.style.textAlign = 'right';
-    percentNode.title = 'Executing: $selfPercent';
-    methodColumn.children.add(percentNode);
-
-    // Gap.
-    var gap = new SpanElement();
-    gap.style.minWidth = '1em';
-    methodColumn.children.add(gap);
-
-    // Code link.
-    var codeRef = newCodeRef(node.profileCode);
-    codeRef.style.alignSelf = 'center';
-    methodColumn.children.add(codeRef);
-
-    gap = new SpanElement();
-    gap.style.minWidth = '1em';
-    methodColumn.children.add(gap);
-
-    for (var attribute in sorted(node.attributes)) {
-      methodColumn.children.add(newAttributeBox(attribute));
-    }
-
-    makeInfoBox();
-    methodColumn.children.add(infoBox);
-
-    infoBox.children.add(span('Code '));
-    infoBox.children.add(newCodeRef(node.profileCode));
-    infoBox.children.add(span(' '));
-    for (var attribute in sorted(node.profileCode.attributes)) {
-      infoBox.children.add(newAttributeBox(attribute));
-    }
-    infoBox.children.add(br());
-    infoBox.children.add(br());
-    var memberList = new DivElement();
-    memberList.classes.add('memberList');
-    infoBox.children.add(br());
-    infoBox.children.add(memberList);
-    ProfileTreeRow._addToMemberList(memberList, {
-        'Exclusive ticks' : node.profileCode.formattedExclusiveTicks,
-        'Cpu time' : node.profileCode.formattedCpuTime,
-        'Inclusive ticks' : node.profileCode.formattedInclusiveTicks,
-        'Call stack time' : node.profileCode.formattedOnStackTime,
-    });
-
-    makeInfoButton();
-    methodColumn.children.add(infoButton);
-
-    // Fill in self column.
-    var selfColumn = flexColumns[1];
-    selfColumn.style.position = 'relative';
-    selfColumn.style.alignItems = 'center';
-    selfColumn.text = selfPercent;
-  }
-}
-
-class FunctionProfileTreeRow extends ProfileTreeRow<FunctionCallTreeNode> {
-  FunctionProfileTreeRow(TableTree tree, FunctionProfileTreeRow parent,
-                         CpuProfile profile, FunctionCallTreeNode node)
-      : super(tree, parent, profile, node,
-              node.profileFunction.normalizedExclusiveTicks,
-              node.percentage) {
-    // fill out attributes.
-  }
-
-  bool hasChildren() => node.children.length > 0;
-
-  onShow() {
-    super.onShow();
-    if (children.length == 0) {
-      for (var childNode in node.children) {
-        var row = new FunctionProfileTreeRow(tree, this, profile, childNode);
-        children.add(row);
-      }
-    }
-
-    var methodColumn = flexColumns[0];
-    methodColumn.style.justifyContent = 'flex-start';
-
-    var codeAndFunctionColumn = new DivElement();
-    codeAndFunctionColumn.classes.add('flex-column');
-    codeAndFunctionColumn.style.justifyContent = 'center';
-    codeAndFunctionColumn.style.width = '100%';
-    methodColumn.children.add(codeAndFunctionColumn);
-
-    var functionRow = new DivElement();
-    functionRow.classes.add('flex-row');
-    functionRow.style.position = 'relative';
-    functionRow.style.justifyContent = 'flex-start';
-    codeAndFunctionColumn.children.add(functionRow);
-
-    // Insert the parent percentage
-    var parentPercent = new SpanElement();
-    parentPercent.text = percent;
-    parentPercent.style.minWidth = '4em';
-    parentPercent.style.alignSelf = 'center';
-    parentPercent.style.textAlign = 'right';
-    parentPercent.title = 'Executing: $selfPercent';
-    functionRow.children.add(parentPercent);
-
-    // Gap.
-    var gap = new SpanElement();
-    gap.style.minWidth = '1em';
-    gap.text = ' ';
-    functionRow.children.add(gap);
-
-    var functionRef = new Element.tag('function-ref');
-    functionRef.ref = node.profileFunction.function;
-    functionRef.style.alignSelf = 'center';
-    functionRow.children.add(functionRef);
-
-    gap = new SpanElement();
-    gap.style.minWidth = '1em';
-    gap.text = ' ';
-    functionRow.children.add(gap);
-
-    for (var attribute in sorted(node.attributes)) {
-      functionRow.children.add(newAttributeBox(attribute));
-    }
-
-    makeInfoBox();
-    functionRow.children.add(infoBox);
-
-    if (node.profileFunction.function.kind.hasDartCode()) {
-      infoBox.children.add(div('Code for current node'));
-      infoBox.children.add(br());
-      var totalTicks = node.totalCodesTicks;
-      var numCodes = node.codes.length;
-      for (var i = 0; i < numCodes; i++) {
-        var codeRowSpan = new DivElement();
-        codeRowSpan.style.paddingLeft = '1em';
-        infoBox.children.add(codeRowSpan);
-        var nodeCode = node.codes[i];
-        var ticks = nodeCode.ticks;
-        var percentage = Utils.formatPercent(ticks, totalTicks);
-        var percentageSpan = new SpanElement();
-        percentageSpan.style.display = 'inline-block';
-        percentageSpan.text = '$percentage';
-        percentageSpan.style.minWidth = '5em';
-        percentageSpan.style.textAlign = 'right';
-        codeRowSpan.children.add(percentageSpan);
-        var codeRef = new Element.tag('code-ref');
-        codeRef.ref = nodeCode.code.code;
-        codeRef.style.marginLeft = '1em';
-        codeRef.style.marginRight = 'auto';
-        codeRef.style.width = '100%';
-        codeRowSpan.children.add(codeRef);
-      }
-      infoBox.children.add(hr());
-    }
-    infoBox.children.add(span('Function '));
-    infoBox.children.add(newFunctionRef(node.profileFunction));
-    infoBox.children.add(span(' '));
-    for (var attribute in sorted(node.profileFunction.attributes)) {
-      infoBox.children.add(newAttributeBox(attribute));
-    }
-    var memberList = new DivElement();
-    memberList.classes.add('memberList');
-    infoBox.children.add(br());
-    infoBox.children.add(br());
-    infoBox.children.add(memberList);
-    infoBox.children.add(br());
-    ProfileTreeRow._addToMemberList(memberList, {
-        'Exclusive ticks' : node.profileFunction.formattedExclusiveTicks,
-        'Cpu time' : node.profileFunction.formattedCpuTime,
-        'Inclusive ticks' : node.profileFunction.formattedInclusiveTicks,
-        'Call stack time' : node.profileFunction.formattedOnStackTime,
-    });
-
-    if (node.profileFunction.function.kind.hasDartCode()) {
-      infoBox.children.add(div('Code containing function'));
-      infoBox.children.add(br());
-      var totalTicks = profile.sampleCount;
-      var codes = node.profileFunction.profileCodes;
-      var numCodes = codes.length;
-      for (var i = 0; i < numCodes; i++) {
-        var codeRowSpan = new DivElement();
-        codeRowSpan.style.paddingLeft = '1em';
-        infoBox.children.add(codeRowSpan);
-        var profileCode = codes[i];
-        var code = profileCode.code;
-        var ticks = profileCode.inclusiveTicks;
-        var percentage = Utils.formatPercent(ticks, totalTicks);
-        var percentageSpan = new SpanElement();
-        percentageSpan.style.display = 'inline-block';
-        percentageSpan.text = '$percentage';
-        percentageSpan.style.minWidth = '5em';
-        percentageSpan.style.textAlign = 'right';
-        percentageSpan.title = 'Inclusive ticks';
-        codeRowSpan.children.add(percentageSpan);
-        var codeRef = new Element.tag('code-ref');
-        codeRef.ref = code;
-        codeRef.style.marginLeft = '1em';
-        codeRef.style.marginRight = 'auto';
-        codeRef.style.width = '100%';
-        codeRowSpan.children.add(codeRef);
-      }
-    }
-
-    makeInfoButton();
-    methodColumn.children.add(infoButton);
-
-    // Fill in self column.
-    var selfColumn = flexColumns[1];
-    selfColumn.style.position = 'relative';
-    selfColumn.style.alignItems = 'center';
-    selfColumn.text = selfPercent;
-  }
-}
-
-@CustomTag('sample-buffer-control')
-class SampleBufferControlElement extends ObservatoryElement {
-  SampleBufferControlElement.created() : super.created() {
-    _stopWatch.start();
-  }
-
-  Future<CpuProfile> reload(Isolate isolate) async {
-    profile.clear();
-    if (isolate == null) {
-      _update(profile);
-      // Notify listener.
-      onSampleBufferUpdate(profile);
-      return profile;
-    }
-    profileVM = isolate.vm.profileVM;
-    if (tagSelector == null) {
-      // Set default value.
-      tagSelector = profileVM ? 'UserVM' : 'None';
-    }
-    await _changeState(kFetchingState);
-    try {
-      var response;
-      if (allocationProfileClass != null) {
-        response =
-            await allocationProfileClass.getAllocationSamples(tagSelector);
-      } else {
-        var params = { 'tags': tagSelector };
-        response = await isolate.invokeRpc('_getCpuProfile', params);
-      }
-      await _changeState(kLoadingState);
-      profile.load(isolate, response);
-      profile.buildFunctionCallerAndCallees();
-      _update(profile);
-      await _changeState(kLoadedState);
-      // Notify listener.
-      onSampleBufferUpdate(profile);
-      return profile;
-    } catch (e, st) {
-      if (e is ServerRpcException) {
-        ServerRpcException se = e;
-        if (se.code == ServerRpcException.kFeatureDisabled) {
-          await _changeState(kDisabledState);
-          return profile;
-        }
-      }
-      await _changeState(kExceptionState, e, st);
-      rethrow;
-    }
-  }
-
-  Future _changeState(String newState, [exception, stackTrace]) {
-    if ((newState == kDisabledState) ||
-        (newState == kFetchingState) ||
-        (newState == kExceptionState)) {
-      loadTime = '';
-      fetchTime = '';
-    } else if (newState == kLoadingState) {
-      fetchTime = formatTimeMilliseconds(_stopWatch.elapsedMilliseconds);
-      loadTime = '';
-    } else if (newState == kLoadedState) {
-      loadTime = formatTimeMilliseconds(_stopWatch.elapsedMilliseconds);
-    }
-    state = newState;
-    this.exception = exception;
-    this.stackTrace = stackTrace;
-    _stopWatch.reset();
-    return window.animationFrame;
-  }
-
-  _update(CpuProfile sampleBuffer) {
-    sampleCount = profile.sampleCount.toString();
-    refreshTime = new DateTime.now().toString();
-    stackDepth = profile.stackDepth.toString();
-    sampleRate = profile.sampleRate.toStringAsFixed(0);
-    if (profile.sampleCount == 0) {
-      timeSpan = '0s';
-    } else {
-      timeSpan = formatTime(profile.timeSpan);
-    }
-  }
-
-  void tagSelectorChanged(oldValue) {
-    reload(profile.isolate);
-  }
-
-  Function onSampleBufferUpdate;
-  @observable bool showTagSelector = true;
-  @observable bool profileVM = false;
-  @observable String sampleCount = '';
-  @observable String refreshTime = '';
-  @observable String sampleRate = '';
-  @observable String stackDepth = '';
-  @observable String timeSpan = '';
-  @observable String fetchTime = '';
-  @observable String loadTime = '';
-  @observable String tagSelector;
-  @observable String state = kFetchingState;
-  @observable var exception;
-  @observable var stackTrace;
-
-  static const kDisabledState = 'kDisabled';
-  static const kExceptionState = 'Exception';
-  static const kFetchingState = 'kFetching';
-  static const kLoadedState = 'kLoaded';
-  static const kLoadingState = 'kLoading';
-  static const kNotLoadedState = 'kNotLoaded';
-
-  Isolate isolate;
-  Class allocationProfileClass;
-
-  final CpuProfile profile = new CpuProfile();
-  final Stopwatch _stopWatch = new Stopwatch();
-}
-
-@CustomTag('stack-trace-tree-config')
-class StackTraceTreeConfigElement extends ObservatoryElement {
-  StackTraceTreeConfigElement.created() : super.created();
-
-  attached() {
-    super.attached();
-    var filterElement = shadowRoot.querySelector('#filterInput');
-    keyDownSubscription = filterElement.onKeyDown.listen(_onKeyDown);
-    blurSubscription = filterElement.onBlur.listen(_onBlur);
-  }
-
-  detached() {
-    super.detached();
-    keyDownSubscription?.cancel();
-    blurSubscription?.cancel();
-  }
-
-  void _onKeyDown(KeyboardEvent keyEvent) {
-    if (keyEvent.keyCode == 13) {
-      // On enter, update the filter string.
-      filterString =
-          (shadowRoot.querySelector('#filterInput') as InputElement).value;
-      if (onTreeConfigChange == null) {
-        return;
-      }
-      onTreeConfigChange(modeSelector, directionSelector, filterString);
-    }
-  }
-
-  void _onBlur(Event event) {
-    // Input box has lost focus, update the display to match the active
-    // filter string.
-    (shadowRoot.querySelector('#filterInput') as InputElement).value =
-        filterString;
-  }
-
-  void modeSelectorChanged(oldValue) {
-    if (onTreeConfigChange == null) {
-      return;
-    }
-    onTreeConfigChange(modeSelector, directionSelector, filterString);
-  }
-
-  void directionSelectorChanged(oldValue) {
-    if (onTreeConfigChange == null) {
-      return;
-    }
-    onTreeConfigChange(modeSelector, directionSelector, filterString);
-  }
-
-  Function onTreeConfigChange;
-  StreamSubscription keyDownSubscription;
-  StreamSubscription blurSubscription;
-  @observable bool show = true;
-  @observable bool showModeSelector = true;
-  @observable bool showDirectionSelector = true;
-  @observable bool showFilter = true;
-  @observable String modeSelector = 'Function';
-  @observable String directionSelector = 'Up';
-  @observable String filterString;
-}
-
-class FunctionCallTreeNodeRow extends VirtualTreeRow {
-  final CpuProfile profile;
-  final FunctionCallTreeNode node;
-  String selfPercent;
-  String totalPercent;
-  String percent;
-
-  static const kHotThreshold = 0.05;  // 5%.
-  static const kMediumThreshold = 0.02;  // 2%.
-
-  double _percent(bool self) {
-    if (self) {
-      return node.profileFunction.normalizedExclusiveTicks;
-    } else {
-      return node.profileFunction.normalizedInclusiveTicks;
-    }
-  }
-
-  bool isHot(bool self) => _percent(self) > kHotThreshold;
-  bool isMedium(bool self) => _percent(self) > kMediumThreshold;
-
-  String rowClass(bool self) {
-    if (isHot(self)) {
-      return 'hotProfile';
-    } else if (isMedium(self)) {
-      return 'mediumProfile';
-    } else {
-      return 'coldProfile';
-    }
-  }
-
-  FunctionCallTreeNodeRow(VirtualTree tree,
-                          int depth,
-                          this.profile,
-                          FunctionCallTreeNode node)
-      : node = node,
-        super(tree, depth) {
-    if ((node.profileFunction.function.kind == FunctionKind.kTag) &&
-        (node.profileFunction.normalizedExclusiveTicks == 0) &&
-        (node.profileFunction.normalizedInclusiveTicks == 0)) {
-    selfPercent = '';
-    totalPercent = '';
-    } else {
-      selfPercent = Utils.formatPercentNormalized(
-          node.profileFunction.normalizedExclusiveTicks);
-      totalPercent = Utils.formatPercentNormalized(
-          node.profileFunction.normalizedInclusiveTicks);
-    }
-    percent = Utils.formatPercentNormalized(node.percentage);
-  }
-
-  void onRender(DivElement rowDiv) {
-    rowDiv.children.add(makeGap(ems:0.1));
-    rowDiv.children.add(
-        makeText(totalPercent,
-                 toolTip: 'global % on stack'));
-    rowDiv.children.add(makeGap());
-    rowDiv.children.add(
-        makeText(selfPercent,
-                 toolTip: 'global % executing'));
-    rowDiv.children.add(makeGap());
-    rowDiv.children.add(makeIndenter(depth, colored: false));
-    rowDiv.children.add(makeColorBar(depth));
-    rowDiv.children.add(makeGap(ems: 1.0));
-    rowDiv.children.add(makeExpander());
-    rowDiv.children.add(
-        makeText(percent, toolTip: 'tree node %', flexBasis: null));
-    rowDiv.children.add(makeGap(ems: 0.5));
-    functionRef.ref = node.profileFunction.function;
-    rowDiv.children.add(functionRef);
-  }
-
-  var functionRef = new Element.tag('function-ref');
-
-  int get childCount => node.children.length;
-
-  void onShow() {
-    if (children.length > 0) {
-      return;
-    }
-    for (var childNode in node.children) {
-      var row = new FunctionCallTreeNodeRow(tree, depth + 1, profile, childNode);
-      children.add(row);
-    }
-  }
-}
-
-
-class CodeCallTreeNodeRow extends VirtualTreeRow {
-  final CpuProfile profile;
-  final CodeCallTreeNode node;
-  String selfPercent;
-  String totalPercent;
-  String percent;
-
-  static const kHotThreshold = 0.05;  // 5%.
-  static const kMediumThreshold = 0.02;  // 2%.
-
-  double _percent(bool self) {
-    if (self) {
-      return node.profileCode.normalizedExclusiveTicks;
-    } else {
-      return node.profileCode.normalizedInclusiveTicks;
-    }
-  }
-
-  bool isHot(bool self) => _percent(self) > kHotThreshold;
-  bool isMedium(bool self) => _percent(self) > kMediumThreshold;
-
-  String rowClass(bool self) {
-    if (isHot(self)) {
-      return 'hotProfile';
-    } else if (isMedium(self)) {
-      return 'mediumProfile';
-    } else {
-      return 'coldProfile';
-    }
-  }
-
-  CodeCallTreeNodeRow(VirtualTree tree,
-                      int depth,
-                      this.profile,
-                      CodeCallTreeNode node)
-      : node = node,
-        super(tree, depth) {
-    if ((node.profileCode.code.kind == CodeKind.Tag) &&
-        (node.profileCode.normalizedExclusiveTicks == 0) &&
-        (node.profileCode.normalizedInclusiveTicks == 0)) {
-      selfPercent = '';
-      totalPercent = '';
-    } else {
-      selfPercent = Utils.formatPercentNormalized(
-          node.profileCode.normalizedExclusiveTicks);
-      totalPercent = Utils.formatPercentNormalized(
-          node.profileCode.normalizedInclusiveTicks);
-    }
-    percent = Utils.formatPercentNormalized(node.percentage);
-  }
-
-  void onRender(DivElement rowDiv) {
-    rowDiv.children.add(makeGap(ems:0.1));
-    rowDiv.children.add(
-        makeText(totalPercent,
-                 toolTip: 'global % on stack'));
-    rowDiv.children.add(makeGap());
-    rowDiv.children.add(
-        makeText(selfPercent,
-                 toolTip: 'global % executing'));
-    rowDiv.children.add(makeGap());
-    rowDiv.children.add(makeIndenter(depth, colored: false));
-    rowDiv.children.add(makeColorBar(depth));
-    rowDiv.children.add(makeGap(ems: 1.0));
-    rowDiv.children.add(makeExpander());
-    rowDiv.children.add(
-        makeText(percent, toolTip: 'tree node %', flexBasis: null));
-    rowDiv.children.add(makeGap(ems: 0.5));
-    codeRef.ref = node.profileCode.code;
-    rowDiv.children.add(codeRef);
-  }
-
-  var codeRef = new Element.tag('code-ref');
-
-  int get childCount => node.children.length;
-
-  void onShow() {
-    if (children.length > 0) {
-      return;
-    }
-    for (var childNode in node.children) {
-      var row = new CodeCallTreeNodeRow(tree, depth + 1, profile, childNode);
-      children.add(row);
-    }
-  }
-}
-
-/// Displays a CpuProfile
-@CustomTag('cpu-profile')
-class CpuProfileElement extends ObservatoryElement {
-  CpuProfileElement.created() : super.created() {
-    _updateTask = new Task(update);
-    _renderTask = new Task(render);
-  }
-
-  attached() {
-    super.attached();
-    sampleBufferControlElement =
-        shadowRoot.querySelector('#sampleBufferControl');
-    assert(sampleBufferControlElement != null);
-    sampleBufferControlElement.onSampleBufferUpdate = onSampleBufferChange;
-    stackTraceTreeConfigElement =
-        shadowRoot.querySelector('#stackTraceTreeConfig');
-    assert(stackTraceTreeConfigElement != null);
-    stackTraceTreeConfigElement.onTreeConfigChange = onTreeConfigChange;
-    cpuProfileVirtualTreeElement = shadowRoot.querySelector('#cpuProfileVirtualTree');
-    assert(cpuProfileVirtualTreeElement != null);
-    cpuProfileVirtualTreeElement.profile = sampleBufferControlElement.profile;
-    _resizeSubscription = window.onResize.listen((_) => _updateSize());
-    _updateTask.queue();
-    _updateSize();
-  }
-
-  detached() {
-    super.detached();
-    if (_resizeSubscription != null) {
-      _resizeSubscription.cancel();
-    }
-  }
-
-  _updateSize() {
-    var applySize = (e) {
-      Rectangle rect = e.getBoundingClientRect();
-      final totalHeight = window.innerHeight;
-      final bottomMargin = 200;
-      final mainHeight = totalHeight - bottomMargin;
-      e.style.setProperty('height', '${mainHeight}px');
-    };
-    HtmlElement e2 = $['cpuProfileVirtualTree'];
-    applySize(e2);
-  }
-
-  isolateChanged(oldValue) {
-    _updateTask.queue();
-  }
-
-  update() {
-    if (sampleBufferControlElement != null) {
-      sampleBufferControlElement.reload(isolate);
-    }
-  }
-
-  onSampleBufferChange(CpuProfile sampleBuffer) {
-    _renderTask.queue();
-  }
-
-  onTreeConfigChange(String modeSelector,
-                     String directionSelector,
-                     String filterString) {
-    ProfileTreeDirection direction = ProfileTreeDirection.Exclusive;
-    if (directionSelector != 'Up') {
-      direction = ProfileTreeDirection.Inclusive;
-    }
-    ProfileTreeMode mode = ProfileTreeMode.Function;
-    if (modeSelector == 'Code') {
-      mode = ProfileTreeMode.Code;
-    }
-    // Clear the filter.
-    cpuProfileVirtualTreeElement.filter = null;
-    if (filterString != null) {
-      filterString = filterString.trim();
-      if (filterString.isNotEmpty) {
-        cpuProfileVirtualTreeElement.filter = (CallTreeNode node) {
-          return node.name.contains(filterString);
-        };
-      }
-    }
-    cpuProfileVirtualTreeElement.direction = direction;
-    cpuProfileVirtualTreeElement.mode = mode;
-    _renderTask.queue();
-  }
-
-  Future clearCpuProfile() async {
-    await isolate.invokeRpc('_clearCpuProfile', { });
-    _updateTask.queue();
-    return new Future.value(null);
-  }
-
-  Future refresh() {
-    _updateTask.queue();
-    return new Future.value(null);
-  }
-
-  render() {
-    cpuProfileVirtualTreeElement.render();
-  }
-
-  @published Isolate isolate;
-
-  StreamSubscription _resizeSubscription;
-  Task _updateTask;
-  Task _renderTask;
-  SampleBufferControlElement sampleBufferControlElement;
-  StackTraceTreeConfigElement stackTraceTreeConfigElement;
-  CpuProfileVirtualTreeElement cpuProfileVirtualTreeElement;
-}
+  CpuProfileElement.created() : super.created();
 
-class NameSortedTable extends SortedTable {
-  NameSortedTable(columns) : super(columns);
   @override
-  dynamic getSortKeyFor(int row, int col) {
-    if (col == FUNCTION_COLUMN) {
-      // Use name as sort key.
-      return rows[row].values[col].name;
-    }
-    return super.getSortKeyFor(row, col);
-  }
-
-  SortedTableRow rowFromIndex(int tableIndex) {
-    final modelIndex = sortedRows[tableIndex];
-    return rows[modelIndex];
-  }
-
-  static const FUNCTION_SPACER_COLUMNS = const [];
-  static const FUNCTION_COLUMN = 2;
-  TableRowElement _makeFunctionRow() {
-    var tr = new TableRowElement();
-    var cell;
-
-    // Add percentage.
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-
-    // Add function ref.
-    cell = tr.insertCell(-1);
-    var functionRef = new Element.tag('function-ref');
-    cell.children.add(functionRef);
-
-    return tr;
-  }
-
-  static const CALL_SPACER_COLUMNS = const [];
-  static const CALL_FUNCTION_COLUMN = 1;
-  TableRowElement _makeCallRow() {
-    var tr = new TableRowElement();
-    var cell;
-
-    // Add percentage.
-    cell = tr.insertCell(-1);
-    // Add function ref.
-    cell = tr.insertCell(-1);
-    var functionRef = new Element.tag('function-ref');
-    cell.children.add(functionRef);
-    return tr;
-  }
-
-  _updateRow(TableRowElement tr,
-             int rowIndex,
-             List spacerColumns,
-             int refColumn) {
-    var row = rows[rowIndex];
-    // Set reference
-    var ref = tr.children[refColumn].children[0];
-    ref.ref = row.values[refColumn];
-
-    for (var i = 0; i < row.values.length; i++) {
-      if (spacerColumns.contains(i) || (i == refColumn)) {
-        // Skip spacer columns.
-        continue;
-      }
-      var cell = tr.children[i];
-      cell.title = row.values[i].toString();
-      cell.text = getFormattedValue(rowIndex, i);
-    }
-  }
-
-  _updateTableView(HtmlElement table,
-                   HtmlElement makeEmptyRow(),
-                   void onRowClick(TableRowElement tr),
-                   List spacerColumns,
-                   int refColumn) {
-    assert(table != null);
-
-    // Resize DOM table.
-    if (table.children.length > sortedRows.length) {
-      // Shrink the table.
-      var deadRows = table.children.length - sortedRows.length;
-      for (var i = 0; i < deadRows; i++) {
-        table.children.removeLast();
-      }
-    } else if (table.children.length < sortedRows.length) {
-      // Grow table.
-      var newRows = sortedRows.length - table.children.length;
-      for (var i = 0; i < newRows; i++) {
-        var row = makeEmptyRow();
-        row.onClick.listen((e) {
-          e.stopPropagation();
-          e.preventDefault();
-          onRowClick(row);
-        });
-        table.children.add(row);
-      }
-    }
-
-    assert(table.children.length == sortedRows.length);
-
-    // Fill table.
-    for (var i = 0; i < sortedRows.length; i++) {
-      var rowIndex = sortedRows[i];
-      var tr = table.children[i];
-      _updateRow(tr, rowIndex, spacerColumns, refColumn);
-    }
-  }
-}
-
-@CustomTag('cpu-profile-table')
-class CpuProfileTableElement extends ObservatoryElement {
-  CpuProfileTableElement.created() : super.created() {
-    _updateTask = new Task(update);
-    _renderTask = new Task(render);
-    var columns = [
-        new SortedTableColumn.withFormatter('Executing (%)',
-                                            Utils.formatPercentNormalized),
-        new SortedTableColumn.withFormatter('In stack (%)',
-                                            Utils.formatPercentNormalized),
-        new SortedTableColumn('Method'),
-    ];
-    profileTable = new NameSortedTable(columns);
-    profileTable.sortColumnIndex = 0;
-
-    columns = [
-        new SortedTableColumn.withFormatter('Callees (%)',
-                                            Utils.formatPercentNormalized),
-        new SortedTableColumn('Method')
-    ];
-    profileCalleesTable = new NameSortedTable(columns);
-    profileCalleesTable.sortColumnIndex = 0;
-
-    columns = [
-        new SortedTableColumn.withFormatter('Callers (%)',
-                                            Utils.formatPercentNormalized),
-        new SortedTableColumn('Method')
-    ];
-    profileCallersTable = new NameSortedTable(columns);
-    profileCallersTable.sortColumnIndex = 0;
-  }
-
   attached() {
     super.attached();
-    sampleBufferControlElement =
-        shadowRoot.querySelector('#sampleBufferControl');
-    assert(sampleBufferControlElement != null);
-    sampleBufferControlElement.onSampleBufferUpdate = onSampleBufferChange;
-    // Disable the tag selector- we always want no tags.
-    sampleBufferControlElement.tagSelector = 'None';
-    sampleBufferControlElement.showTagSelector = false;
-    stackTraceTreeConfigElement =
-        shadowRoot.querySelector('#stackTraceTreeConfig');
-    assert(stackTraceTreeConfigElement != null);
-    stackTraceTreeConfigElement.onTreeConfigChange = onTreeConfigChange;
-    stackTraceTreeConfigElement.modeSelector = 'Function';
-    stackTraceTreeConfigElement.showModeSelector = false;
-    stackTraceTreeConfigElement.directionSelector = 'Down';
-    stackTraceTreeConfigElement.showDirectionSelector = false;
-    cpuProfileTreeElement = shadowRoot.querySelector('#cpuProfileTree');
-    assert(cpuProfileTreeElement != null);
-    cpuProfileTreeElement.profile = sampleBufferControlElement.profile;
-    _updateTask.queue();
-    _resizeSubscription = window.onResize.listen((_) => _updateSize());
-    _updateSize();
+    _r.enable();
+    _request();
   }
 
+  @override
   detached() {
     super.detached();
-    if (_resizeSubscription != null) {
-      _resizeSubscription.cancel();
-    }
-  }
-
-  _updateSize() {
-    HtmlElement e = $['main'];
-    final totalHeight = window.innerHeight;
-    final top = e.offset.top;
-    final bottomMargin = 32;
-    final mainHeight = totalHeight - top - bottomMargin;
-    e.style.setProperty('height', '${mainHeight}px');
-  }
-
-  isolateChanged(oldValue) {
-    _updateTask.queue();
-  }
-
-  update() {
-    _clearView();
-    if (sampleBufferControlElement != null) {
-      sampleBufferControlElement.reload(isolate).whenComplete(checkParameters);
-    }
-  }
-
-  onSampleBufferChange(CpuProfile sampleBuffer) {
-    _renderTask.queue();
-  }
-
-  onTreeConfigChange(String modeSelector,
-                     String directionSelector,
-                     String filterString) {
-    ProfileTreeDirection direction = ProfileTreeDirection.Exclusive;
-    if (directionSelector != 'Up') {
-      direction = ProfileTreeDirection.Inclusive;
-    }
-    ProfileTreeMode mode = ProfileTreeMode.Function;
-    if (modeSelector == 'Code') {
-      mode = ProfileTreeMode.Code;
-    }
-    cpuProfileTreeElement.direction = direction;
-    cpuProfileTreeElement.mode = mode;
-    _renderTask.queue();
-  }
-
-  Future clearCpuProfile() async {
-    await isolate.invokeRpc('_clearCpuProfile', { });
-    _updateTask.queue();
-    return new Future.value(null);
-  }
-
-  Future refresh() {
-    _updateTask.queue();
-    return new Future.value(null);
-  }
-
-  render() {
-    _updateView();
-  }
-
-  checkParameters() {
-    if (isolate == null) {
-      return;
-    }
-    var functionId = app.locationManager.uri.queryParameters['functionId'];
-    var functionName =
-        app.locationManager.uri.queryParameters['functionName'];
-    if (functionId == '') {
-      // Fallback to searching by name.
-      _focusOnFunction(_findFunction(functionName));
-    } else {
-      if (functionId == null) {
-        _focusOnFunction(null);
-        return;
-      }
-      isolate.getObject(functionId).then((func) => _focusOnFunction(func));
-    }
-  }
-
-  _clearView() {
-    profileTable.clearRows();
-    _renderTable();
-  }
-
-  _updateView() {
-    _buildFunctionTable();
-    _renderTable();
-    _updateFunctionTreeView();
-  }
-
-  int _findFunctionRow(ServiceFunction function) {
-    for (var i = 0; i < profileTable.sortedRows.length; i++) {
-      var rowIndex = profileTable.sortedRows[i];
-      var row = profileTable.rows[rowIndex];
-      if (row.values[NameSortedTable.FUNCTION_COLUMN] == function) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  _scrollToFunction(ServiceFunction function) {
-    TableSectionElement tableBody = $['profile-table'];
-    var row = _findFunctionRow(function);
-    if (row == -1) {
-      return;
-    }
-    tableBody.children[row].classes.remove('shake');
-    // trigger reflow.
-    tableBody.children[row].offsetHeight;
-    tableBody.children[row].scrollIntoView(ScrollAlignment.CENTER);
-    tableBody.children[row].classes.add('shake');
-    // Focus on clicked function.
-    _focusOnFunction(function);
-  }
-
-  _clearFocusedFunction() {
-    TableSectionElement tableBody = $['profile-table'];
-    // Clear current focus.
-    if (focusedRow != null) {
-      tableBody.children[focusedRow].classes.remove('focused');
-    }
-    focusedRow = null;
-    focusedFunction = null;
-  }
-
-  ServiceFunction _findFunction(String functionName) {
-    for (var func in profile.functions) {
-      if (func.function.name == functionName) {
-        return func.function;
-      }
-    }
-    return null;
-  }
-
-  _focusOnFunction(ServiceFunction function) {
-    if (focusedFunction == function) {
-      // Do nothing.
-      return;
-    }
-
-    _clearFocusedFunction();
-
-    if (function == null) {
-      _updateFunctionTreeView();
-      _clearCallTables();
-      return;
-    }
-
-    var row = _findFunctionRow(function);
-    if (row == -1) {
-      _updateFunctionTreeView();
-      _clearCallTables();
-      return;
-    }
-
-    focusedRow = row;
-    focusedFunction = function;
-
-    TableSectionElement tableBody = $['profile-table'];
-    tableBody.children[focusedRow].classes.add('focused');
-    _updateFunctionTreeView();
-    _buildCallersTable(focusedFunction);
-    _buildCalleesTable(focusedFunction);
-  }
-
-  _onRowClick(TableRowElement tr) {
-    var tableBody = $['profile-table'];
-    var row = profileTable.rowFromIndex(tableBody.children.indexOf(tr));
-    var function = row.values[NameSortedTable.FUNCTION_COLUMN];
-    app.locationManager.goReplacingParameters(
-        {
-          'functionId': function.id,
-          'functionName': function.vmName
-        }
-    );
-  }
-
-  _renderTable() {
-    profileTable._updateTableView($['profile-table'],
-                                  profileTable._makeFunctionRow,
-                                  _onRowClick,
-                                  NameSortedTable.FUNCTION_SPACER_COLUMNS,
-                                  NameSortedTable.FUNCTION_COLUMN);
-  }
-
-  _buildFunctionTable() {
-    for (var func in profile.functions) {
-      if ((func.exclusiveTicks == 0) && (func.inclusiveTicks == 0)) {
-        // Skip.
-        continue;
-      }
-      var row = [
-        func.normalizedExclusiveTicks,
-        func.normalizedInclusiveTicks,
-        func.function,
-      ];
-      profileTable.addRow(new SortedTableRow(row));
-    }
-    profileTable.sort();
-  }
-
-  _renderCallTable(TableSectionElement view,
-                   NameSortedTable model,
-                   void onRowClick(TableRowElement tr)) {
-    model._updateTableView(view,
-                           model._makeCallRow,
-                           onRowClick,
-                           NameSortedTable.CALL_SPACER_COLUMNS,
-                           NameSortedTable.CALL_FUNCTION_COLUMN);
-  }
-
-  _buildCallTable(Map<ProfileFunction, int> calls,
-                  NameSortedTable model) {
-    model.clearRows();
-    if (calls == null) {
-      return;
-    }
-    var sum = 0;
-    calls.values.forEach((i) => sum += i);
-    calls.forEach((func, count) {
-      var row = [
-          count / sum,
-          func.function,
-      ];
-      model.addRow(new SortedTableRow(row));
-    });
-    model.sort();
-  }
-
-  _clearCallTables() {
-    _buildCallersTable(null);
-    _buildCalleesTable(null);
-  }
-
-  _onCallersClick(TableRowElement tr) {
-    var table = $['callers-table'];
-    final row = profileCallersTable.rowFromIndex(table.children.indexOf(tr));
-    var function = row.values[NameSortedTable.CALL_FUNCTION_COLUMN];
-    _scrollToFunction(function);
-  }
-
-  _buildCallersTable(ServiceFunction function) {
-    var calls = (function != null) ? function.profile.callers : null;
-    var table = $['callers-table'];
-    _buildCallTable(calls, profileCallersTable);
-    _renderCallTable(table, profileCallersTable, _onCallersClick);
-  }
-
-  _onCalleesClick(TableRowElement tr) {
-    var table = $['callees-table'];
-    final row = profileCalleesTable.rowFromIndex(table.children.indexOf(tr));
-    var function = row.values[NameSortedTable.CALL_FUNCTION_COLUMN];
-    _scrollToFunction(function);
-  }
-
-  _buildCalleesTable(ServiceFunction function) {
-    var calls = (function != null) ? function.profile.callees : null;
-    var table = $['callees-table'];
-    _buildCallTable(calls, profileCalleesTable);
-    _renderCallTable(table, profileCalleesTable, _onCalleesClick);
-  }
-
-  _changeSort(Element target, NameSortedTable table) {
-    if (target is TableCellElement) {
-      if (table.sortColumnIndex != target.cellIndex) {
-        table.sortColumnIndex = target.cellIndex;
-        table.sortDescending = true;
-      } else {
-        table.sortDescending = !profileTable.sortDescending;
-      }
-      table.sort();
-    }
-  }
-
-  changeSortProfile(Event e, var detail, Element target) {
-    _changeSort(target, profileTable);
-    _renderTable();
-  }
-
-  changeSortCallers(Event e, var detail, Element target) {
-    _changeSort(target, profileCallersTable);
-    _renderCallTable($['callers-table'], profileCallersTable, _onCallersClick);
-  }
-
-  changeSortCallees(Event e, var detail, Element target) {
-    _changeSort(target, profileCalleesTable);
-    _renderCallTable($['callees-table'], profileCalleesTable, _onCalleesClick);
-  }
-
-  //////
-  ///
-  /// Function tree.
-  ///
-  TableTree functionTree;
-  _updateFunctionTreeView() {
-    cpuProfileTreeElement.filter = (FunctionCallTreeNode node) {
-      return node.profileFunction.function == focusedFunction;
-    };
-    cpuProfileTreeElement.render();
-  }
-
-  @published Isolate isolate;
-  @observable NameSortedTable profileTable;
-  @observable NameSortedTable profileCallersTable;
-  @observable NameSortedTable profileCalleesTable;
-  @observable ServiceFunction focusedFunction;
-  @observable int focusedRow;
-
-
-  StreamSubscription _resizeSubscription;
-  Task _updateTask;
-  Task _renderTask;
-
-  CpuProfile get profile => sampleBufferControlElement.profile;
-  SampleBufferControlElement sampleBufferControlElement;
-  StackTraceTreeConfigElement stackTraceTreeConfigElement;
-  CpuProfileVirtualTreeElement cpuProfileTreeElement;
-}
-
-enum ProfileTreeDirection {
-  Exclusive,
-  Inclusive
-}
-
-enum ProfileTreeMode {
-  Code,
-  Function,
-}
-
-@CustomTag('cpu-profile-virtual-tree')
-class CpuProfileVirtualTreeElement extends ObservatoryElement {
-  ProfileTreeDirection direction = ProfileTreeDirection.Exclusive;
-  ProfileTreeMode mode = ProfileTreeMode.Function;
-  CpuProfile profile;
-  VirtualTree virtualTree;
-  CallTreeNodeFilter filter;
-  StreamSubscription _resizeSubscription;
-  @observable bool show = true;
-
-  CpuProfileVirtualTreeElement.created() : super.created();
-
-  attached() {
-    super.attached();
-    _resizeSubscription = window.onResize.listen((_) => _updateSize());
-  }
-
-  detached() {
-    super.detached();
-    _resizeSubscription?.cancel();
+    _r.disable(notify: true);
+    children = [];
   }
 
   void render() {
-    _updateView();
-  }
-
-  showChanged(oldValue) {
-    if (show) {
-      virtualTree?.root?.style?.display = 'block';
-    } else {
-      virtualTree?.root?.style?.display = 'none';
-    }
-  }
-
-  void _updateView() {
-    _updateSize();
-    virtualTree?.clear();
-    virtualTree?.uninstall();
-    virtualTree = null;
-    bool exclusive = direction == ProfileTreeDirection.Exclusive;
-    if (mode == ProfileTreeMode.Code) {
-      _buildCodeTree(exclusive);
-    } else {
-      assert(mode == ProfileTreeMode.Function);
-      _buildFunctionTree(exclusive);
-    }
-    virtualTree?.refresh();
-  }
-
-  void _updateSize() {
-    var treeBody = shadowRoot.querySelector('#tree');
-    assert(treeBody != null);
-    int windowHeight = window.innerHeight - 32;
-    treeBody.style.height = '${windowHeight}px';
-  }
-
-  void _buildFunctionTree(bool exclusive) {
-    var treeBody = shadowRoot.querySelector('#tree');
-    assert(treeBody != null);
-    virtualTree = new VirtualTree(32, treeBody);
-    if (profile == null) {
+    var content = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavMenuElement('cpu profile', link: Uris.profiler(_isolate),
+              last: true, queue: _r.queue),
+          new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen(_refresh),
+          new NavRefreshElement(label: 'Clear', queue: _r.queue)
+              ..onRefresh.listen(_clearCpuProfile),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+    ];
+    if (_progress == null) {
+      children = content;
       return;
     }
-    var tree = profile.loadFunctionTree(exclusive ? 'exclusive' : 'inclusive');
-    if (tree == null) {
-      return;
+    content.add(new SampleBufferControlElement(_progress, _progressStream,
+      selectedTag: _tag, queue: _r.queue)
+      ..onTagChange.listen((e) {
+        _tag = e.element.selectedTag;
+        _request();
+    }));
+    if (_progress.status == M.SampleProfileLoadingStatus.loaded) {
+      CpuProfileVirtualTreeElement tree;
+      content.addAll([
+        new BRElement(),
+        new StackTraceTreeConfigElement(mode: _mode, direction: _direction,
+          filter: _filter, queue: _r.queue)
+            ..onModeChange.listen((e) {
+              _mode = tree.mode = e.element.mode;
+            })
+            ..onFilterChange.listen((e) {
+              _filter = e.element.filter.trim();
+              tree.filter = _filter.isNotEmpty
+                ? (node) { return node.name.contains(_filter); }
+                : null;
+            })
+            ..onDirectionChange.listen((e) {
+              _direction = tree.direction = e.element.direction;
+            }),
+        new BRElement(),
+        tree = new CpuProfileVirtualTreeElement(_isolate, _progress.profile,
+            queue: _r.queue)
+      ]);
     }
-    if (filter != null) {
-      tree = tree.filtered(filter);
-    }
-    for (var child in tree.root.children) {
-      virtualTree.rows.add(
-          new FunctionCallTreeNodeRow(virtualTree, 0, profile, child));
-    }
-    if (virtualTree.rows.length == 1) {
-      virtualTree.rows[0].expanded = true;
+    children = content;
+  }
+
+  Future _request({bool clear: false, bool forceFetch: false}) async {
+    _progress = null;
+    _progressStream = _profiles.get(isolate, _tag, clear: clear,
+        forceFetch: forceFetch);
+    _r.dirty();
+    _progress = (await _progressStream.first).progress;
+    _r.dirty();
+    if (M.isSampleProcessRunning(_progress.status)) {
+      _progress = (await _progressStream.last).progress;
+      _r.dirty();
     }
   }
 
-  void _buildCodeTree(bool exclusive) {
-    var treeBody = shadowRoot.querySelector('#tree');
-    assert(treeBody != null);
-    virtualTree = new VirtualTree(32, treeBody);
-    if (profile == null) {
-      return;
-    }
-    var tree = profile.loadCodeTree(exclusive ? 'exclusive' : 'inclusive');
-    if (tree == null) {
-      return;
-    }
-    if (filter != null) {
-      tree = tree.filtered(filter);
-    }
-    for (var child in tree.root.children) {
-      virtualTree.rows.add(
-          new CodeCallTreeNodeRow(virtualTree, 0, profile, child));
-    }
-    if (virtualTree.rows.length == 1) {
-      virtualTree.rows[0].expanded = true;
-    }
-  }
-}
-
-@CustomTag('cpu-profile-tree')
-class CpuProfileTreeElement extends ObservatoryElement {
-  ProfileTreeDirection direction = ProfileTreeDirection.Exclusive;
-  ProfileTreeMode mode = ProfileTreeMode.Function;
-  CpuProfile profile;
-  TableTree codeTree;
-  TableTree functionTree;
-  CallTreeNodeFilter functionFilter;
-  @observable bool show = true;
-
-  CpuProfileTreeElement.created() : super.created();
-
-  void render() {
-    _updateView();
+  Future _clearCpuProfile(RefreshEvent e) async {
+    e.element.disabled = true;
+    await _request(clear: true);
+    e.element.disabled = false;
   }
 
-  showChanged(oldValue) {
-    var treeTable = shadowRoot.querySelector('#treeTable');
-    assert(treeTable != null);
-    treeTable.style.display = show ? 'table' : 'none';
-  }
-
-  void _updateView() {
-    if (functionTree != null) {
-      functionTree.clear();
-      functionTree = null;
-    }
-    if (codeTree != null) {
-      codeTree.clear();
-      codeTree = null;
-    }
-    bool exclusive = direction == ProfileTreeDirection.Exclusive;
-    if (mode == ProfileTreeMode.Code) {
-      _buildCodeTree(exclusive);
-    } else {
-      assert(mode == ProfileTreeMode.Function);
-      _buildFunctionTree(exclusive);
-    }
-  }
-
-  void _buildFunctionTree(bool exclusive) {
-    if (functionTree == null) {
-      var tableBody = shadowRoot.querySelector('#treeBody');
-      assert(tableBody != null);
-      functionTree = new TableTree(tableBody, 2);
-    }
-    if (profile == null) {
-      return;
-    }
-    var tree = profile.loadFunctionTree(exclusive ? 'exclusive' : 'inclusive');
-    if (tree == null) {
-      return;
-    }
-    if (functionFilter != null) {
-      tree = tree.filtered(functionFilter);
-    }
-    var rootRow =
-        new FunctionProfileTreeRow(functionTree, null, profile, tree.root);
-    functionTree.initialize(rootRow);
-  }
-
-  void _buildCodeTree(bool exclusive) {
-    if (codeTree == null) {
-      var tableBody = shadowRoot.querySelector('#treeBody');
-      assert(tableBody != null);
-      codeTree = new TableTree(tableBody, 2);
-    }
-    if (profile == null) {
-      return;
-    }
-    var tree = profile.loadCodeTree(exclusive ? 'exclusive' : 'inclusive');
-    if (tree == null) {
-      return;
-    }
-    var rootRow = new CodeProfileTreeRow(codeTree, null, profile, tree.root);
-    codeTree.initialize(rootRow);
+  Future _refresh(e) async {
+    e.element.disabled = true;
+    await _request(forceFetch: true);
+    e.element.disabled = false;
   }
 }
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.html b/runtime/observatory/lib/src/elements/cpu_profile.html
deleted file mode 100644
index 50db2db..0000000
--- a/runtime/observatory/lib/src/elements/cpu_profile.html
+++ /dev/null
@@ -1,519 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="code_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="sliding_checkbox.html">
-<link rel="import" href="view_footer.html">
-
-<polymer-element name="sample-buffer-control" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-    .statusMessage {
-      font-size: 150%;
-      font-weight: bold;
-    }
-
-    .statusBox {
-      height: 100%;
-      padding: 1em;
-    }
-
-    .center {
-      align-items: center;
-      justify-content: center;
-    }
-
-    .notice {
-      background-color: #fcf8e3;
-    }
-
-    .red {
-      background-color: #f2dede;
-    }
-    </style>
-    <div class="content-centered-big">
-      <template if="{{ state != 'kNotLoaded' }}">
-        <h2>Sample buffer</h2>
-        <hr>
-      </template>
-      <template if="{{ state == 'kFetching' }}">
-        <div class="statusBox shadow center">
-          <div class="statusMessage">Fetching profile from VM...</div>
-        </div>
-      </template>
-      <template if="{{ state == 'kLoading' }}">
-        <div class="statusBox shadow center">
-          <div class="statusMessage">Loading profile...</div>
-        </div>
-      </template>
-      <template if="{{ state == 'kDisabled' }}">
-        <div class="statusBox shadow center">
-          <div>
-            <h1>Profiling is disabled</h1>
-            <br>
-            Perhaps the <b>profile</b> flag has been disabled for this VM.
-            <br><br>
-            See all
-            <a on-click="{{ goto }}" _href="{{ gotoLink('/flags') }}">vm flags</a>
-          </div>
-        </div>
-      </template>
-      <template if="{{ state == 'kException' }}">
-        <div class="statusBox shadow center">
-          <div class="statusMessage">
-            <h1>Profiling is disabled due to unexpected exception:</h1>
-            <br>
-            <pre>{{ exception.toString() }}</pre>
-            <br>
-            <h1>Stack trace:</h1>
-            <br>
-            <pre>{{ stackTrace.toString() }}</pre>
-          </div>
-        </div>
-      </template>
-      <template if="{{ state == 'kLoaded' }}">
-        <div class="memberList">
-          <div class="memberItem">
-            <div class="memberName">Refreshed at </div>
-            <div class="memberValue">{{ refreshTime }} (fetched in {{ fetchTime  }}) (loaded in {{ loadTime }})</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Profile contains</div>
-            <div class="memberValue">{{ sampleCount }} samples (spanning {{ timeSpan }})</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Sampling</div>
-            <div class="memberValue">{{ stackDepth }} stack frames @ {{ sampleRate }} Hz</div>
-          </div>
-          <template if="{{ showTagSelector }}">
-            <div class="memberItem">
-              <div class="memberName">Tag Order</div>
-              <div class="memberValue">
-                <template if="{{ profileVM }}">
-                  <select value="{{tagSelector}}">
-                    <option value="UserVM">User &gt; VM</option>
-                    <option value="UserOnly">User</option>
-                    <option value="VMUser">VM &gt; User</option>
-                    <option value="VMOnly">VM</option>
-                    <option value="None">None</option>
-                  </select>
-                </template>
-                <template if="{{ !profileVM }}">
-                  <select value="{{tagSelector}}">
-                    <option value="UserOnly">User</option>
-                    <option value="None">None</option>
-                  </select>
-                </template>
-              </div>
-            </div>
-          </template>
-        </div>
-      </template>
-    </div>
-  </template>
-</polymer-element>
-
-<polymer-element name="stack-trace-tree-config" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-    .statusBox {
-      height: 100%;
-      padding: 0.5em;
-    }
-    .row {
-      display: flex;
-    }
-    </style>
-    <div class="content-centered-big">
-      <template if="{{ show }}">
-        <h2>Tree display</h2>
-        <hr>
-        <div class="row">
-          <div>
-            <div class="memberList">
-              <template if="{{ showModeSelector }}">
-                <div class="memberItem">
-                  <div class="memberName">Mode</div>
-                  <div class="memberValue">
-                    <select value="{{modeSelector}}">
-                      <option value="Code">Code</option>
-                      <option value="Function">Function</option>
-                    </select>
-                  </div>
-                </div>
-              </template>
-              <template if="{{ showDirectionSelector }}">
-                <div class="memberItem">
-                  <div class="memberName">Call Tree Direction</div>
-                  <span class="memberValue">
-                    <select value="{{directionSelector}}">
-                      <option value="Down">Top down</option>
-                      <option value="Up">Bottom up</option>
-                    </select>
-                    <template if="{{ directionSelector == 'Down' }}">
-                      <span>
-                        Tree is rooted at "main". Child nodes are callees.
-                      </span>
-                    </template>
-                    <template if="{{ directionSelector == 'Up' }}">
-                      <span>
-                        Tree is rooted at executing function / code. Child nodes are callers.
-                      </span>
-                    </template>
-                  </span>
-                </div>
-              </template>
-              <template if="{{ showFilter }}">
-                <div class="memberItem">
-                  <div title="case-sensitive substring match" class="memberName">Call Tree Filter</div>
-                  <span class="memberValue">
-                    <input type="text" placeholder="Search filter" id="filterInput">
-                  </span>
-                </div>
-              </template>
-            </div>
-          </div>
-        </div>
-      </template>
-    </div>
-  </template>
-</polymer-element>
-
-<polymer-element name="cpu-profile-tree" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-    .infoBox {
-      position: absolute;
-      top: 100%;
-      left: 0%;
-      z-index: 999;
-      opacity: 1;
-      padding: 1em;
-      background-color: #ffffff;
-      border-left: solid 2px #ECECEC;
-      border-bottom: solid 2px #ECECEC;
-      border-right: solid 2px #ECECEC;
-    }
-    .full-width {
-      width: 100%;
-    }
-    .tree {
-      border-spacing: 0px;
-      width: 100%;
-      margin-bottom: 20px
-      vertical-align: middle;
-    }
-    .tree tbody tr {
-      animation: fadeIn 0.5s;
-      -moz-animation: fadeIn 0.5s;
-      -webkit-animation: fadeIn 0.5s;
-    }
-    .tree tbody tr:hover {
-      background-color: #FAFAFA;
-    }
-    .tree tr td:first-child,
-    .tree tr th:first-child {
-      width: 100%;
-    }
-    .tree thead > tr > th {
-      padding: 8px;
-      vertical-align: bottom;
-      text-align: left;
-      border-bottom: 1px solid #ddd;
-    }
-    tr {
-      background-color: #FFFFFF;
-    }
-    tbody tr {
-      animation: fadeIn 0.5s;
-      -moz-animation: fadeIn 0.5s;
-      -webkit-animation: fadeIn 0.5s;
-    }
-    tbody tr:hover {
-      background-color: #FAFAFA;
-    }
-    tr td:first-child,
-    tr th:first-child {
-      width: 100%;
-    }
-    </style>
-    <table id="treeTable" class="full-width tree">
-      <thead id="treeHeader">
-      <tr>
-        <th>Method</th>
-        <th>Executing</th>
-      </tr>
-      </thead>
-      <tbody id="treeBody">
-      </tbody>
-    </table>
-  </template>
-</polymer-element>
-
-<polymer-element name="cpu-profile-virtual-tree" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-    .full {
-      height: 50%;
-      width: 100%;
-    }
-    .coldProfile {
-      background-color: #aea;
-    }
-    .mediumProfile {
-      background-color: #fe9;
-    }
-    .hotProfile {
-      background-color: #faa;
-    }
-    </style>
-    <div id="tree" class="full"></div>
-  </template>
-</polymer-element>
-
-
-<polymer-element name="cpu-profile-table" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
-      <nav-menu link="{{ makeLink('/profiler-table', isolate) }}" anchor="cpu profile (table)" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-refresh callback="{{ clearCpuProfile }}" label="Clear"></nav-refresh>
-    </nav-bar>
-    <style>
-      /* general */
-      .well {
-        background-color: #ECECEC;
-        padding: 0.2em;
-      }
-      .center {
-        align-items: center;
-        justify-content: center;
-      }
-
-      /* status messages */
-      .statusMessage {
-        font-size: 150%;
-        font-weight: bold;
-      }
-      .statusBox {
-        height: 100%;
-        padding: 1em;
-      }
-
-      /* tables */
-      .table {
-        border-collapse: collapse!important;
-        table-layout: fixed;
-        height: 100%;
-      }
-      .th, .td {
-        padding: 8px;
-        vertical-align: top;
-      }
-      .table thead > tr > th {
-        vertical-align: bottom;
-        text-align: left;
-        border-bottom:2px solid #ddd;
-      }
-      .spacer {
-        width: 16px;
-      }
-      .left-border-spacer {
-        width: 16px;
-        border-left: 1px solid;
-      }
-      .clickable {
-        color: #0489c3;
-        text-decoration: none;
-        cursor: pointer;
-        min-width: 8em;
-      }
-      .clickable:hover {
-        text-decoration: underline;
-        cursor: pointer;
-      }
-      tr:hover:not(.focused) > td {
-        background-color: #FAFAFA;
-      }
-      .focused {
-        background-color: #F4C7C3;
-      }
-      .scroll {
-        overflow: scroll;
-      }
-      .outlined {
-        -webkit-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
-        -moz-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
-        box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
-        margin: 4px;
-      }
-      .centered {
-        margin-left: auto;
-        margin-right: auto;
-        justify-content: center;
-      }
-      .full-height {
-        height: 100%;
-      }
-      .mostly-full-height {
-        height: 80%;
-      }
-      .full-width {
-        width: 100%;
-      }
-      .focused-function-label {
-        flex: 0 1 auto;
-        margin-left: auto;
-        margin-right: auto;
-        justify-content: center;
-      }
-      .call-table {
-        flex: 1 1 auto;
-      }
-
-      .tree {
-        border-spacing: 0px;
-        width: 100%;
-        margin-bottom: 20px
-        vertical-align: middle;
-      }
-
-      .tree tbody tr {
-        animation: fadeIn 0.5s;
-        -moz-animation: fadeIn 0.5s;
-        -webkit-animation: fadeIn 0.5s;
-      }
-
-      .tree tbody tr:hover {
-        background-color: #FAFAFA;
-      }
-
-      .tree tr td:first-child,
-      .tree tr th:first-child {
-        width: 100%;
-      }
-
-      .tree thead > tr > th {
-        padding: 8px;
-        vertical-align: bottom;
-        text-align: left;
-        border-bottom: 1px solid #ddd;
-      }
-
-    </style>
-    <sample-buffer-control id="sampleBufferControl"></sample-buffer-control>
-    <br>
-    <hr>
-    <div id="main" class="flex-row centered">
-      <div class="flex-item-45-percent full-height outlined scroll">
-        <table id="main-table" class="flex-item-100-percent table">
-          <thead>
-          <tr>
-            <th on-click="{{changeSortProfile}}" class="clickable" title="Executing (%)">{{ profileTable.getColumnLabel(0) }}</th>
-            <th on-click="{{changeSortProfile}}" class="clickable" title="In stack (%)">{{ profileTable.getColumnLabel(1) }}</th>
-            <th on-click="{{changeSortProfile}}" class="clickable" title="Method">{{ profileTable.getColumnLabel(2) }}</th>
-          </tr>
-          </thead>
-          <tbody id="profile-table">
-          </tbody>
-        </table>
-      </div>
-      <div class="flex-item-45-percent full-height outlined">
-        <div class="flex-column full-height">
-          <div class="focused-function-label">
-            <template if="{{ focusedFunction != null }}">
-              <span>Focused on: </span>
-              <function-ref ref="{{ focusedFunction }}"></function-ref>
-            </template>
-            <template if="{{ focusedFunction == null }}">
-              <span>No focused function</span>
-            </template>
-          </div>
-          <hr>
-          <div class="call-table scroll">
-            <table class="full-width table">
-              <thead>
-              <tr>
-                <th on-click="{{changeSortCallers}}" class="clickable" title="Callers (%)">{{ profileCallersTable.getColumnLabel(0) }}</th>
-                <th on-click="{{changeSortCallers}}" class="clickable" title="Method">{{ profileCallersTable.getColumnLabel(1) }}</th>
-              </tr>
-              </thead>
-              <tbody id="callers-table">
-              </tbody>
-            </table>
-          </div>
-          <hr>
-          <div class="call-table scroll">
-            <table class="full-width table">
-              <thead>
-              <tr>
-                <th on-click="{{changeSortCallees}}" class="clickable" title="Callees (%)">{{ profileCalleesTable.getColumnLabel(0) }}</th>
-                <th on-click="{{changeSortCallees}}" class="clickable" title="Method">{{ profileCalleesTable.getColumnLabel(1) }}</th>
-              </tr>
-              </thead>
-              <tbody id="callees-table">
-              </tbody>
-            </table>
-          </div>
-        </div>
-      </div>
-    </div>
-    <br>
-    <stack-trace-tree-config id="stackTraceTreeConfig"></stack-trace-tree-config>
-    <br>
-    <div class="content-centered-big">
-      <div class="focused-function-label">
-        <template if="{{ focusedFunction != null }}">
-          <span>Filtered tree: </span>
-          <function-ref ref="{{ focusedFunction }}"></function-ref>
-        </template>
-        <template if="{{ focusedFunction == null }}">
-          <span>No focused function</span>
-        </template>
-      </div>
-    </div>
-    <br>
-    <br>
-    <div class="flex-row centered">
-      <div class="flex-item-90-percent outlined" style="margin: 16px; margin-left: 8px; margin-right: 8px">
-        <cpu-profile-virtual-tree id="cpuProfileTree"></cpu-profile-virtual-tree>
-      </div>
-    </div>
-  </template>
-</polymer-element>
-
-<polymer-element name="cpu-profile" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
-      <nav-menu link="{{ makeLink('/profiler', isolate) }}" anchor="cpu profile" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-refresh callback="{{ clearCpuProfile }}" label="Clear"></nav-refresh>
-    </nav-bar>
-    <style>
-      .tableWell {
-        background-color: #ECECEC;
-        padding: 0.2em;
-      }
-    </style>
-    <sample-buffer-control id="sampleBufferControl"></sample-buffer-control>
-    <br>
-    <stack-trace-tree-config id="stackTraceTreeConfig"></stack-trace-tree-config>
-    <br>
-    <cpu-profile-virtual-tree id="cpuProfileVirtualTree"></cpu-profile-virtual-tree>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="cpu_profile.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
new file mode 100644
index 0000000..236b395
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
@@ -0,0 +1,179 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:math' as Math;
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/stack_trace_tree_config.dart'
+  show ProfileTreeMode;
+import 'package:observatory/src/elements/code_ref.dart';
+import 'package:observatory/src/elements/containers/virtual_tree.dart';
+import 'package:observatory/src/elements/function_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/utils.dart';
+
+export 'package:observatory/src/elements/stack_trace_tree_config.dart'
+  show ProfileTreeMode;
+
+class CpuProfileVirtualTreeElement extends HtmlElement implements Renderable {
+  static const tag =
+      const Tag<CpuProfileVirtualTreeElement>('cpu-profile-virtual-tree');
+
+  RenderingScheduler<CpuProfileVirtualTreeElement> _r;
+
+  Stream<RenderedEvent<CpuProfileVirtualTreeElement>> get onRendered =>
+                                                                  _r.onRendered;
+
+  M.ProfileTreeDirection _direction;
+  ProfileTreeMode _mode;
+  M.IsolateRef _isolate;
+  M.SampleProfile _profile;
+  M.CallTreeNodeFilter _filter;
+
+  M.ProfileTreeDirection get direction => _direction;
+  ProfileTreeMode get mode => _mode;
+  M.IsolateRef get isolate => _isolate;
+  M.SampleProfile get profile => _profile;
+  M.CallTreeNodeFilter get filter => _filter;
+
+  set direction(M.ProfileTreeDirection value) =>
+      _direction = _r.checkAndReact(_direction, value);
+  set mode(ProfileTreeMode value) => _mode = _r.checkAndReact(_mode, value);
+  set filter(M.CallTreeNodeFilter value) =>
+      _filter = _r.checkAndReact(_filter, value);
+
+  factory CpuProfileVirtualTreeElement(M.IsolateRef isolate,
+      M.SampleProfile profile, {ProfileTreeMode mode: ProfileTreeMode.function,
+      M.ProfileTreeDirection direction: M.ProfileTreeDirection.exclusive,
+      RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(profile != null);
+    assert(mode != null);
+    assert(direction != null);
+    CpuProfileVirtualTreeElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._profile = profile;
+    e._mode = mode;
+    e._direction = direction;
+    return e;
+  }
+
+  CpuProfileVirtualTreeElement.created() : super.created();
+
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+  }
+
+ @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  VirtualTreeElement _tree;
+
+  void render() {
+    var tree;
+    var update;
+    switch (mode) {
+      case ProfileTreeMode.code:
+        tree = _profile.loadCodeTree(_direction);
+        update = _updateCodeRow;
+        break;
+      case ProfileTreeMode.function:
+        tree = _profile.loadFunctionTree(_direction);
+        update = _updateFunctionRow;
+        break;
+      default:
+        throw new Exception('Unknown ProfileTreeMode: $mode');
+    }
+    if (tree == null) {
+      children = [
+        new HeadingElement.h1()..text = 'No Results'
+      ];
+      return;
+    }
+    if (filter != null) {
+      tree = tree.filtered(filter);
+    }
+    _tree = new VirtualTreeElement(_createRow, update, _getChildren,
+      items: tree.root.children, queue: _r.queue);
+    if (tree.root.children.length == 1) {
+      _tree.expand(tree.root.children.first, autoExpandSingleChildNodes: true);
+    }
+    children = [_tree];
+  }
+
+  static Element _createRow(toggle) {
+    return new DivElement()
+      ..classes = const ['tree-item']
+      ..children = [
+        new SpanElement()..classes = const ['inclusive']
+          ..title = 'global % on stack',
+        new SpanElement()..classes = const ['exclusive']
+          ..title = 'global % executing',
+        new SpanElement()..classes = const ['lines'],
+        new ButtonElement()..classes = const ['expander']
+          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+        new SpanElement()..classes = const ['percentage']
+          ..title = 'tree node %',
+        new SpanElement()..classes = const ['name']
+      ];
+  }
+
+  static _getChildren(M.CallTreeNode node) => node.children;
+
+  void _updateFunctionRow(HtmlElement element, M.FunctionCallTreeNode item,
+      int depth) {
+    element.children[0].text = Utils.formatPercentNormalized(
+        item.profileFunction.normalizedInclusiveTicks);
+    element.children[1].text = Utils.formatPercentNormalized(
+        item.profileFunction.normalizedExclusiveTicks);
+    _updateLines(element.children[2].children, depth);
+    if (item.children.isNotEmpty) {
+      element.children[3].text = _tree.isExpanded(item) ? 'â–¼' : 'â–º';
+    } else {
+      element.children[3].text = '';
+    }
+    element.children[4].text = Utils.formatPercentNormalized(
+        item.percentage);
+    element.children[5] = new FunctionRefElement(_isolate,
+            item.profileFunction.function, queue: _r.queue)
+            ..classes = const ['name'];
+  }
+
+  void _updateCodeRow(HtmlElement element, M.CodeCallTreeNode item, int depth) {
+    element.children[0].text = Utils.formatPercentNormalized(
+        item.profileCode.normalizedInclusiveTicks);
+    element.children[1].text = Utils.formatPercentNormalized(
+        item.profileCode.normalizedExclusiveTicks);
+    _updateLines(element.children[2].children, depth);
+    if (item.children.isNotEmpty) {
+      element.children[3].text = _tree.isExpanded(item) ? 'â–¼' : 'â–º';
+    } else {
+      element.children[3].text = '';
+    }
+    element.children[4].text = Utils.formatPercentNormalized(
+        item.percentage);
+    element.children[5] = new CodeRefElement(_isolate,
+        item.profileCode.code, queue: _r.queue)
+        ..classes = const ['name'];
+  }
+
+  static _updateLines(List<Element> lines, int n) {
+    n = Math.max(0, n);
+    while (lines.length > n) {
+      lines.removeLast();
+    }
+    while (lines.length < n) {
+      lines.add(new SpanElement());
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/cpu_profile_table.dart b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
new file mode 100644
index 0000000..2a76e17
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
@@ -0,0 +1,929 @@
+// 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 cpu_profile_table_element;
+
+import 'dart:async';
+import 'dart:html';
+import 'observatory_element.dart';
+import 'sample_buffer_control.dart';
+import 'stack_trace_tree_config.dart';
+import 'cpu_profile/virtual_tree.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/app.dart';
+import 'package:observatory/cpu_profile.dart';
+import 'package:observatory/elements.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/repositories.dart';
+import 'package:polymer/polymer.dart';
+
+List<String> sorted(Set<String> attributes) {
+  var list = attributes.toList();
+  list.sort();
+  return list;
+}
+
+abstract class ProfileTreeRow<T> extends TableTreeRow {
+  final CpuProfile profile;
+  final T node;
+  final String selfPercent;
+  final String percent;
+  bool _infoBoxShown = false;
+  HtmlElement infoBox;
+  HtmlElement infoButton;
+
+  ProfileTreeRow(TableTree tree, TableTreeRow parent,
+                 this.profile, this.node, double selfPercent, double percent)
+      : super(tree, parent),
+        selfPercent = Utils.formatPercentNormalized(selfPercent),
+        percent = Utils.formatPercentNormalized(percent);
+
+  static _addToMemberList(DivElement memberList, Map<String, String> items) {
+    items.forEach((k, v) {
+      var item = new DivElement();
+      item.classes.add('memberItem');
+      var name = new DivElement();
+      name.classes.add('memberName');
+      name.text = k;
+      var value = new DivElement();
+      value.classes.add('memberValue');
+      value.text = v;
+      item.children.add(name);
+      item.children.add(value);
+      memberList.children.add(item);
+    });
+  }
+
+  makeInfoBox() {
+    if (infoBox != null) {
+      return;
+    }
+    infoBox = new DivElement();
+    infoBox.classes.add('infoBox');
+    infoBox.classes.add('shadow');
+    infoBox.style.display = 'none';
+    listeners.add(infoBox.onClick.listen((e) => e.stopPropagation()));
+  }
+
+  makeInfoButton() {
+    infoButton = new SpanElement();
+    infoButton.style.marginLeft = 'auto';
+    infoButton.style.marginRight = '1em';
+    infoButton.children.add(new Element.tag('icon-info-outline'));
+    listeners.add(infoButton.onClick.listen((event) {
+      event.stopPropagation();
+      toggleInfoBox();
+    }));
+  }
+
+  static const attributes = const {
+    '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'],
+    'stub': const ['S', null, 'Stub'],
+    'synthetic' : const ['?', null, 'Synthetic'],
+  };
+
+  HtmlElement newAttributeBox(String attribute) {
+    List attributeDetails = attributes[attribute];
+    if (attributeDetails == null) {
+      print('could not find attribute $attribute');
+      return null;
+    }
+    var element = new SpanElement();
+    element.style.border = 'solid 2px #ECECEC';
+    element.style.height = '100%';
+    element.style.display = 'inline-block';
+    element.style.textAlign = 'center';
+    element.style.minWidth = '1.5em';
+    element.style.fontWeight = 'bold';
+    if (attributeDetails[1] != null) {
+      element.style.backgroundColor = attributeDetails[1];
+    }
+    element.text = attributeDetails[0];
+    element.title = attributeDetails[2];
+    return element;
+  }
+
+  onHide() {
+    super.onHide();
+    infoBox = null;
+    infoButton = null;
+  }
+
+  showInfoBox() {
+    if ((infoButton == null) || (infoBox == null)) {
+      return;
+    }
+    _infoBoxShown = true;
+    infoBox.style.display = 'block';
+    infoButton.children.clear();
+    infoButton.children.add(new Element.tag('icon-info'));
+  }
+
+  hideInfoBox() {
+    _infoBoxShown = false;
+    if ((infoButton == null) || (infoBox == null)) {
+      return;
+    }
+    infoBox.style.display = 'none';
+    infoButton.children.clear();
+    infoButton.children.add(new Element.tag('icon-info-outline'));
+  }
+
+  toggleInfoBox() {
+   if (_infoBoxShown) {
+     hideInfoBox();
+   } else {
+     showInfoBox();
+   }
+  }
+
+  hideAllInfoBoxes() {
+    final List<ProfileTreeRow> rows = tree.rows;
+    for (var row in rows) {
+      row.hideInfoBox();
+    }
+  }
+
+  onClick(MouseEvent e) {
+    e.stopPropagation();
+    if (e.altKey) {
+      bool show = !_infoBoxShown;
+      hideAllInfoBoxes();
+      if (show) {
+        showInfoBox();
+      }
+      return;
+    }
+    super.onClick(e);
+  }
+
+  HtmlElement newCodeRef(ProfileCode code) {
+    var codeRef = new Element.tag('code-ref');
+    codeRef.ref = code.code;
+    return codeRef;
+  }
+
+  HtmlElement newFunctionRef(ProfileFunction function) {
+    var ref = new Element.tag('function-ref');
+    ref.ref = function.function;
+    return ref;
+  }
+
+  HtmlElement hr() {
+    var element = new HRElement();
+    return element;
+  }
+
+  HtmlElement div(String text) {
+    var element = new DivElement();
+    element.text = text;
+    return element;
+  }
+
+  HtmlElement br() {
+    return new BRElement();
+  }
+
+  HtmlElement span(String text) {
+    var element = new SpanElement();
+    element.style.minWidth = '1em';
+    element.text = text;
+    return element;
+  }
+}
+
+class CodeProfileTreeRow extends ProfileTreeRow<CodeCallTreeNode> {
+  CodeProfileTreeRow(TableTree tree, CodeProfileTreeRow parent,
+                     CpuProfile profile, CodeCallTreeNode node)
+      : super(tree, parent, profile, node,
+              node.profileCode.normalizedExclusiveTicks,
+              node.percentage) {
+    // fill out attributes.
+  }
+
+  bool hasChildren() => node.children.length > 0;
+
+  void onShow() {
+    super.onShow();
+
+    if (children.length == 0) {
+      for (var childNode in node.children) {
+        var row = new CodeProfileTreeRow(tree, this, profile, childNode);
+        children.add(row);
+      }
+    }
+
+    // Fill in method column.
+    var methodColumn = flexColumns[0];
+    methodColumn.style.justifyContent = 'flex-start';
+    methodColumn.style.position = 'relative';
+
+    // Percent.
+    var percentNode = new DivElement();
+    percentNode.text = percent;
+    percentNode.style.minWidth = '5em';
+    percentNode.style.textAlign = 'right';
+    percentNode.title = 'Executing: $selfPercent';
+    methodColumn.children.add(percentNode);
+
+    // Gap.
+    var gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    methodColumn.children.add(gap);
+
+    // Code link.
+    var codeRef = newCodeRef(node.profileCode);
+    codeRef.style.alignSelf = 'center';
+    methodColumn.children.add(codeRef);
+
+    gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    methodColumn.children.add(gap);
+
+    for (var attribute in sorted(node.attributes)) {
+      methodColumn.children.add(newAttributeBox(attribute));
+    }
+
+    makeInfoBox();
+    methodColumn.children.add(infoBox);
+
+    infoBox.children.add(span('Code '));
+    infoBox.children.add(newCodeRef(node.profileCode));
+    infoBox.children.add(span(' '));
+    for (var attribute in sorted(node.profileCode.attributes)) {
+      infoBox.children.add(newAttributeBox(attribute));
+    }
+    infoBox.children.add(br());
+    infoBox.children.add(br());
+    var memberList = new DivElement();
+    memberList.classes.add('memberList');
+    infoBox.children.add(br());
+    infoBox.children.add(memberList);
+    ProfileTreeRow._addToMemberList(memberList, {
+        'Exclusive ticks' : node.profileCode.formattedExclusiveTicks,
+        'Cpu time' : node.profileCode.formattedCpuTime,
+        'Inclusive ticks' : node.profileCode.formattedInclusiveTicks,
+        'Call stack time' : node.profileCode.formattedOnStackTime,
+    });
+
+    makeInfoButton();
+    methodColumn.children.add(infoButton);
+
+    // Fill in self column.
+    var selfColumn = flexColumns[1];
+    selfColumn.style.position = 'relative';
+    selfColumn.style.alignItems = 'center';
+    selfColumn.text = selfPercent;
+  }
+}
+
+class FunctionProfileTreeRow extends ProfileTreeRow<FunctionCallTreeNode> {
+  FunctionProfileTreeRow(TableTree tree, FunctionProfileTreeRow parent,
+                         CpuProfile profile, FunctionCallTreeNode node)
+      : super(tree, parent, profile, node,
+              node.profileFunction.normalizedExclusiveTicks,
+              node.percentage) {
+    // fill out attributes.
+  }
+
+  bool hasChildren() => node.children.length > 0;
+
+  onShow() {
+    super.onShow();
+    if (children.length == 0) {
+      for (var childNode in node.children) {
+        var row = new FunctionProfileTreeRow(tree, this, profile, childNode);
+        children.add(row);
+      }
+    }
+
+    var methodColumn = flexColumns[0];
+    methodColumn.style.justifyContent = 'flex-start';
+
+    var codeAndFunctionColumn = new DivElement();
+    codeAndFunctionColumn.classes.add('flex-column');
+    codeAndFunctionColumn.style.justifyContent = 'center';
+    codeAndFunctionColumn.style.width = '100%';
+    methodColumn.children.add(codeAndFunctionColumn);
+
+    var functionRow = new DivElement();
+    functionRow.classes.add('flex-row');
+    functionRow.style.position = 'relative';
+    functionRow.style.justifyContent = 'flex-start';
+    codeAndFunctionColumn.children.add(functionRow);
+
+    // Insert the parent percentage
+    var parentPercent = new SpanElement();
+    parentPercent.text = percent;
+    parentPercent.style.minWidth = '4em';
+    parentPercent.style.alignSelf = 'center';
+    parentPercent.style.textAlign = 'right';
+    parentPercent.title = 'Executing: $selfPercent';
+    functionRow.children.add(parentPercent);
+
+    // Gap.
+    var gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    gap.text = ' ';
+    functionRow.children.add(gap);
+
+    var functionRef = new Element.tag('function-ref');
+    functionRef.ref = node.profileFunction.function;
+    functionRef.style.alignSelf = 'center';
+    functionRow.children.add(functionRef);
+
+    gap = new SpanElement();
+    gap.style.minWidth = '1em';
+    gap.text = ' ';
+    functionRow.children.add(gap);
+
+    for (var attribute in sorted(node.attributes)) {
+      functionRow.children.add(newAttributeBox(attribute));
+    }
+
+    makeInfoBox();
+    functionRow.children.add(infoBox);
+
+    if (M.hasDartCode(node.profileFunction.function.kind)) {
+      infoBox.children.add(div('Code for current node'));
+      infoBox.children.add(br());
+      var totalTicks = node.totalCodesTicks;
+      var numCodes = node.codes.length;
+      for (var i = 0; i < numCodes; i++) {
+        var codeRowSpan = new DivElement();
+        codeRowSpan.style.paddingLeft = '1em';
+        infoBox.children.add(codeRowSpan);
+        var nodeCode = node.codes[i];
+        var ticks = nodeCode.ticks;
+        var percentage = Utils.formatPercent(ticks, totalTicks);
+        var percentageSpan = new SpanElement();
+        percentageSpan.style.display = 'inline-block';
+        percentageSpan.text = '$percentage';
+        percentageSpan.style.minWidth = '5em';
+        percentageSpan.style.textAlign = 'right';
+        codeRowSpan.children.add(percentageSpan);
+        var codeRef = new Element.tag('code-ref');
+        codeRef.ref = nodeCode.code.code;
+        codeRef.style.marginLeft = '1em';
+        codeRef.style.marginRight = 'auto';
+        codeRef.style.width = '100%';
+        codeRowSpan.children.add(codeRef);
+      }
+      infoBox.children.add(hr());
+    }
+    infoBox.children.add(span('Function '));
+    infoBox.children.add(newFunctionRef(node.profileFunction));
+    infoBox.children.add(span(' '));
+    for (var attribute in sorted(node.profileFunction.attributes)) {
+      infoBox.children.add(newAttributeBox(attribute));
+    }
+    var memberList = new DivElement();
+    memberList.classes.add('memberList');
+    infoBox.children.add(br());
+    infoBox.children.add(br());
+    infoBox.children.add(memberList);
+    infoBox.children.add(br());
+    ProfileTreeRow._addToMemberList(memberList, {
+        'Exclusive ticks' : node.profileFunction.formattedExclusiveTicks,
+        'Cpu time' : node.profileFunction.formattedCpuTime,
+        'Inclusive ticks' : node.profileFunction.formattedInclusiveTicks,
+        'Call stack time' : node.profileFunction.formattedOnStackTime,
+    });
+
+    if (M.hasDartCode(node.profileFunction.function.kind)) {
+      infoBox.children.add(div('Code containing function'));
+      infoBox.children.add(br());
+      var totalTicks = profile.sampleCount;
+      var codes = node.profileFunction.profileCodes;
+      var numCodes = codes.length;
+      for (var i = 0; i < numCodes; i++) {
+        var codeRowSpan = new DivElement();
+        codeRowSpan.style.paddingLeft = '1em';
+        infoBox.children.add(codeRowSpan);
+        var profileCode = codes[i];
+        var code = profileCode.code;
+        var ticks = profileCode.inclusiveTicks;
+        var percentage = Utils.formatPercent(ticks, totalTicks);
+        var percentageSpan = new SpanElement();
+        percentageSpan.style.display = 'inline-block';
+        percentageSpan.text = '$percentage';
+        percentageSpan.style.minWidth = '5em';
+        percentageSpan.style.textAlign = 'right';
+        percentageSpan.title = 'Inclusive ticks';
+        codeRowSpan.children.add(percentageSpan);
+        var codeRef = new Element.tag('code-ref');
+        codeRef.ref = code;
+        codeRef.style.marginLeft = '1em';
+        codeRef.style.marginRight = 'auto';
+        codeRef.style.width = '100%';
+        codeRowSpan.children.add(codeRef);
+      }
+    }
+
+    makeInfoButton();
+    methodColumn.children.add(infoButton);
+
+    // Fill in self column.
+    var selfColumn = flexColumns[1];
+    selfColumn.style.position = 'relative';
+    selfColumn.style.alignItems = 'center';
+    selfColumn.text = selfPercent;
+  }
+}
+
+class NameSortedTable extends SortedTable {
+  NameSortedTable(columns) : super(columns);
+  @override
+  dynamic getSortKeyFor(int row, int col) {
+    if (col == FUNCTION_COLUMN) {
+      // Use name as sort key.
+      return rows[row].values[col].name;
+    }
+    return super.getSortKeyFor(row, col);
+  }
+
+  SortedTableRow rowFromIndex(int tableIndex) {
+    final modelIndex = sortedRows[tableIndex];
+    return rows[modelIndex];
+  }
+
+  static const FUNCTION_SPACER_COLUMNS = const [];
+  static const FUNCTION_COLUMN = 2;
+  TableRowElement _makeFunctionRow() {
+    var tr = new TableRowElement();
+    var cell;
+
+    // Add percentage.
+    cell = tr.insertCell(-1);
+    cell = tr.insertCell(-1);
+
+    // Add function ref.
+    cell = tr.insertCell(-1);
+    var functionRef = new Element.tag('function-ref');
+    cell.children.add(functionRef);
+
+    return tr;
+  }
+
+  static const CALL_SPACER_COLUMNS = const [];
+  static const CALL_FUNCTION_COLUMN = 1;
+  TableRowElement _makeCallRow() {
+    var tr = new TableRowElement();
+    var cell;
+
+    // Add percentage.
+    cell = tr.insertCell(-1);
+    // Add function ref.
+    cell = tr.insertCell(-1);
+    var functionRef = new Element.tag('function-ref');
+    cell.children.add(functionRef);
+    return tr;
+  }
+
+  _updateRow(TableRowElement tr,
+             int rowIndex,
+             List spacerColumns,
+             int refColumn) {
+    var row = rows[rowIndex];
+    // Set reference
+    var ref = tr.children[refColumn].children[0];
+    ref.ref = row.values[refColumn];
+
+    for (var i = 0; i < row.values.length; i++) {
+      if (spacerColumns.contains(i) || (i == refColumn)) {
+        // Skip spacer columns.
+        continue;
+      }
+      var cell = tr.children[i];
+      cell.title = row.values[i].toString();
+      cell.text = getFormattedValue(rowIndex, i);
+    }
+  }
+
+  _updateTableView(HtmlElement table,
+                   HtmlElement makeEmptyRow(),
+                   void onRowClick(TableRowElement tr),
+                   List spacerColumns,
+                   int refColumn) {
+    assert(table != null);
+
+    // Resize DOM table.
+    if (table.children.length > sortedRows.length) {
+      // Shrink the table.
+      var deadRows = table.children.length - sortedRows.length;
+      for (var i = 0; i < deadRows; i++) {
+        table.children.removeLast();
+      }
+    } else if (table.children.length < sortedRows.length) {
+      // Grow table.
+      var newRows = sortedRows.length - table.children.length;
+      for (var i = 0; i < newRows; i++) {
+        var row = makeEmptyRow();
+        row.onClick.listen((e) {
+          e.stopPropagation();
+          e.preventDefault();
+          onRowClick(row);
+        });
+        table.children.add(row);
+      }
+    }
+
+    assert(table.children.length == sortedRows.length);
+
+    // Fill table.
+    for (var i = 0; i < sortedRows.length; i++) {
+      var rowIndex = sortedRows[i];
+      var tr = table.children[i];
+      _updateRow(tr, rowIndex, spacerColumns, refColumn);
+    }
+  }
+}
+
+@CustomTag('cpu-profile-table')
+class CpuProfileTableElement extends ObservatoryElement {
+
+
+  CpuProfileTableElement.created() : super.created() {
+    _updateTask = new Task(update);
+    _renderTask = new Task(render);
+    var columns = [
+        new SortedTableColumn.withFormatter('Executing (%)',
+                                            Utils.formatPercentNormalized),
+        new SortedTableColumn.withFormatter('In stack (%)',
+                                            Utils.formatPercentNormalized),
+        new SortedTableColumn('Method'),
+    ];
+    profileTable = new NameSortedTable(columns);
+    profileTable.sortColumnIndex = 0;
+
+    columns = [
+        new SortedTableColumn.withFormatter('Callees (%)',
+                                            Utils.formatPercentNormalized),
+        new SortedTableColumn('Method')
+    ];
+    profileCalleesTable = new NameSortedTable(columns);
+    profileCalleesTable.sortColumnIndex = 0;
+
+    columns = [
+        new SortedTableColumn.withFormatter('Callers (%)',
+                                            Utils.formatPercentNormalized),
+        new SortedTableColumn('Method')
+    ];
+    profileCallersTable = new NameSortedTable(columns);
+    profileCallersTable.sortColumnIndex = 0;
+  }
+
+  attached() {
+    super.attached();
+    _updateTask.queue();
+    _resizeSubscription = window.onResize.listen((_) => _updateSize());
+    _updateSize();
+  }
+
+  detached() {
+    super.detached();
+    if (_resizeSubscription != null) {
+      _resizeSubscription.cancel();
+    }
+  }
+
+  _updateSize() {
+    HtmlElement e = $['main'];
+    final totalHeight = window.innerHeight;
+    final top = e.offset.top;
+    final bottomMargin = 32;
+    final mainHeight = totalHeight - top - bottomMargin;
+    e.style.setProperty('height', '${mainHeight}px');
+  }
+
+  isolateChanged(oldValue) {
+    _updateTask.queue();
+  }
+
+  update() async {
+    _clearView();
+    if (isolate == null) {
+      return;
+    }
+    final stream = _repository.get(isolate, M.SampleProfileTag.none);
+    var progress = (await stream.first).progress;
+    shadowRoot.querySelector('#sampleBufferControl').children = [
+      sampleBufferControlElement =
+        new SampleBufferControlElement(progress, stream, showTag: false,
+          selectedTag: M.SampleProfileTag.none, queue: app.queue)
+    ];
+    if (M.isSampleProcessRunning(progress.status)) {
+      progress = (await stream.last).progress;
+    }
+    if (progress.status == M.SampleProfileLoadingStatus.loaded) {
+      _profile = progress.profile;
+      shadowRoot.querySelector('#stackTraceTreeConfig').children = [
+        stackTraceTreeConfigElement =
+            new StackTraceTreeConfigElement(showMode: false,
+                showDirection: false, mode: ProfileTreeMode.function,
+                direction: M.ProfileTreeDirection.exclusive, queue: app.queue)
+              ..onModeChange.listen((e) {
+                cpuProfileTreeElement.mode = e.element.mode;
+                _renderTask.queue();
+              })
+              ..onDirectionChange.listen((e) {
+                cpuProfileTreeElement.direction = e.element.direction;
+                _renderTask.queue();
+              })
+              ..onFilterChange.listen((e) =>_renderTask.queue())
+      ];
+      shadowRoot.querySelector('#cpuProfileTree').children = [
+        cpuProfileTreeElement =
+            new CpuProfileVirtualTreeElement(isolate, _profile,
+                queue: app.queue)
+      ];
+    }
+    _renderTask.queue();
+  }
+
+  Future clearCpuProfile() async {
+    await isolate.invokeRpc('_clearCpuProfile', { });
+    _updateTask.queue();
+    return new Future.value(null);
+  }
+
+  Future refresh() {
+    _updateTask.queue();
+    return new Future.value(null);
+  }
+
+  render() {
+    _updateView();
+  }
+
+  checkParameters() {
+    if (isolate == null) {
+      return;
+    }
+    var functionId = app.locationManager.uri.queryParameters['functionId'];
+    var functionName =
+        app.locationManager.uri.queryParameters['functionName'];
+    if (functionId == '') {
+      // Fallback to searching by name.
+      _focusOnFunction(_findFunction(functionName));
+    } else {
+      if (functionId == null) {
+        _focusOnFunction(null);
+        return;
+      }
+      isolate.getObject(functionId).then((func) => _focusOnFunction(func));
+    }
+  }
+
+  _clearView() {
+    profileTable.clearRows();
+    _renderTable();
+  }
+
+  _updateView() {
+    _buildFunctionTable();
+    _renderTable();
+    _updateFunctionTreeView();
+  }
+
+  int _findFunctionRow(ServiceFunction function) {
+    for (var i = 0; i < profileTable.sortedRows.length; i++) {
+      var rowIndex = profileTable.sortedRows[i];
+      var row = profileTable.rows[rowIndex];
+      if (row.values[NameSortedTable.FUNCTION_COLUMN] == function) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  _scrollToFunction(ServiceFunction function) {
+    TableSectionElement tableBody = $['profile-table'];
+    var row = _findFunctionRow(function);
+    if (row == -1) {
+      return;
+    }
+    tableBody.children[row].classes.remove('shake');
+    // trigger reflow.
+    tableBody.children[row].offsetHeight;
+    tableBody.children[row].scrollIntoView(ScrollAlignment.CENTER);
+    tableBody.children[row].classes.add('shake');
+    // Focus on clicked function.
+    _focusOnFunction(function);
+  }
+
+  _clearFocusedFunction() {
+    TableSectionElement tableBody = $['profile-table'];
+    // Clear current focus.
+    if (focusedRow != null) {
+      tableBody.children[focusedRow].classes.remove('focused');
+    }
+    focusedRow = null;
+    focusedFunction = null;
+  }
+
+  ServiceFunction _findFunction(String functionName) {
+    for (var func in _profile.functions) {
+      if (func.function.name == functionName) {
+        return func.function;
+      }
+    }
+    return null;
+  }
+
+  _focusOnFunction(ServiceFunction function) {
+    if (focusedFunction == function) {
+      // Do nothing.
+      return;
+    }
+
+    _clearFocusedFunction();
+
+    if (function == null) {
+      _updateFunctionTreeView();
+      _clearCallTables();
+      return;
+    }
+
+    var row = _findFunctionRow(function);
+    if (row == -1) {
+      _updateFunctionTreeView();
+      _clearCallTables();
+      return;
+    }
+
+    focusedRow = row;
+    focusedFunction = function;
+
+    TableSectionElement tableBody = $['profile-table'];
+    tableBody.children[focusedRow].classes.add('focused');
+    _updateFunctionTreeView();
+    _buildCallersTable(focusedFunction);
+    _buildCalleesTable(focusedFunction);
+  }
+
+  _onRowClick(TableRowElement tr) {
+    var tableBody = $['profile-table'];
+    var row = profileTable.rowFromIndex(tableBody.children.indexOf(tr));
+    var function = row.values[NameSortedTable.FUNCTION_COLUMN];
+    app.locationManager.goReplacingParameters(
+        {
+          'functionId': function.id,
+          'functionName': function.vmName
+        }
+    );
+  }
+
+  _renderTable() {
+    profileTable._updateTableView($['profile-table'],
+                                  profileTable._makeFunctionRow,
+                                  _onRowClick,
+                                  NameSortedTable.FUNCTION_SPACER_COLUMNS,
+                                  NameSortedTable.FUNCTION_COLUMN);
+  }
+
+  _buildFunctionTable() {
+    for (var func in _profile.functions) {
+      if ((func.exclusiveTicks == 0) && (func.inclusiveTicks == 0)) {
+        // Skip.
+        continue;
+      }
+      var row = [
+        func.normalizedExclusiveTicks,
+        func.normalizedInclusiveTicks,
+        func.function,
+      ];
+      profileTable.addRow(new SortedTableRow(row));
+    }
+    profileTable.sort();
+  }
+
+  _renderCallTable(TableSectionElement view,
+                   NameSortedTable model,
+                   void onRowClick(TableRowElement tr)) {
+    model._updateTableView(view,
+                           model._makeCallRow,
+                           onRowClick,
+                           NameSortedTable.CALL_SPACER_COLUMNS,
+                           NameSortedTable.CALL_FUNCTION_COLUMN);
+  }
+
+  _buildCallTable(Map<ProfileFunction, int> calls,
+                  NameSortedTable model) {
+    model.clearRows();
+    if (calls == null) {
+      return;
+    }
+    var sum = 0;
+    calls.values.forEach((i) => sum += i);
+    calls.forEach((func, count) {
+      var row = [
+          count / sum,
+          func.function,
+      ];
+      model.addRow(new SortedTableRow(row));
+    });
+    model.sort();
+  }
+
+  _clearCallTables() {
+    _buildCallersTable(null);
+    _buildCalleesTable(null);
+  }
+
+  _onCallersClick(TableRowElement tr) {
+    var table = $['callers-table'];
+    final row = profileCallersTable.rowFromIndex(table.children.indexOf(tr));
+    var function = row.values[NameSortedTable.CALL_FUNCTION_COLUMN];
+    _scrollToFunction(function);
+  }
+
+  _buildCallersTable(ServiceFunction function) {
+    var calls = (function != null) ? function.profile.callers : null;
+    var table = $['callers-table'];
+    _buildCallTable(calls, profileCallersTable);
+    _renderCallTable(table, profileCallersTable, _onCallersClick);
+  }
+
+  _onCalleesClick(TableRowElement tr) {
+    var table = $['callees-table'];
+    final row = profileCalleesTable.rowFromIndex(table.children.indexOf(tr));
+    var function = row.values[NameSortedTable.CALL_FUNCTION_COLUMN];
+    _scrollToFunction(function);
+  }
+
+  _buildCalleesTable(ServiceFunction function) {
+    var calls = (function != null) ? function.profile.callees : null;
+    var table = $['callees-table'];
+    _buildCallTable(calls, profileCalleesTable);
+    _renderCallTable(table, profileCalleesTable, _onCalleesClick);
+  }
+
+  _changeSort(Element target, NameSortedTable table) {
+    if (target is TableCellElement) {
+      if (table.sortColumnIndex != target.cellIndex) {
+        table.sortColumnIndex = target.cellIndex;
+        table.sortDescending = true;
+      } else {
+        table.sortDescending = !profileTable.sortDescending;
+      }
+      table.sort();
+    }
+  }
+
+  changeSortProfile(Event e, var detail, Element target) {
+    _changeSort(target, profileTable);
+    _renderTable();
+  }
+
+  changeSortCallers(Event e, var detail, Element target) {
+    _changeSort(target, profileCallersTable);
+    _renderCallTable($['callers-table'], profileCallersTable, _onCallersClick);
+  }
+
+  changeSortCallees(Event e, var detail, Element target) {
+    _changeSort(target, profileCalleesTable);
+    _renderCallTable($['callees-table'], profileCalleesTable, _onCalleesClick);
+  }
+
+  //////
+  ///
+  /// Function tree.
+  ///
+  TableTree functionTree;
+  _updateFunctionTreeView() {
+    if (cpuProfileTreeElement == null) {
+      return;
+    }
+    cpuProfileTreeElement.filter = (FunctionCallTreeNode node) {
+      return node.profileFunction.function == focusedFunction;
+    };
+  }
+
+  @published Isolate isolate;
+  @observable NameSortedTable profileTable;
+  @observable NameSortedTable profileCallersTable;
+  @observable NameSortedTable profileCalleesTable;
+  @observable ServiceFunction focusedFunction;
+  @observable int focusedRow;
+
+
+  StreamSubscription _resizeSubscription;
+  Task _updateTask;
+  Task _renderTask;
+
+  IsolateSampleProfileRepository _repository =
+      new IsolateSampleProfileRepository();
+  CpuProfile _profile;
+  SampleBufferControlElement sampleBufferControlElement;
+  StackTraceTreeConfigElement stackTraceTreeConfigElement;
+  CpuProfileVirtualTreeElement cpuProfileTreeElement;
+}
diff --git a/runtime/observatory/lib/src/elements/cpu_profile_table.html b/runtime/observatory/lib/src/elements/cpu_profile_table.html
new file mode 100644
index 0000000..b95c0bc
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/cpu_profile_table.html
@@ -0,0 +1,218 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+
+<polymer-element name="cpu-profile-table">
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <nav-bar>
+      <top-nav-menu></top-nav-menu>
+      <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
+      <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
+      <nav-menu link="{{ makeLink('/profiler-table', isolate) }}" anchor="cpu profile (table)" last="{{ true }}"></nav-menu>
+      <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-refresh callback="{{ clearCpuProfile }}" label="Clear"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
+    </nav-bar>
+    <style>
+      /* general */
+      .well {
+        background-color: #ECECEC;
+        padding: 0.2em;
+      }
+      .center {
+        align-items: center;
+        justify-content: center;
+      }
+
+      /* status messages */
+      .statusMessage {
+        font-size: 150%;
+        font-weight: bold;
+      }
+      .statusBox {
+        height: 100%;
+        padding: 1em;
+      }
+
+      /* tables */
+      .table {
+        border-collapse: collapse!important;
+        table-layout: fixed;
+        height: 100%;
+      }
+      .th, .td {
+        padding: 8px;
+        vertical-align: top;
+      }
+      .table thead > tr > th {
+        vertical-align: bottom;
+        text-align: left;
+        border-bottom:2px solid #ddd;
+      }
+      .spacer {
+        width: 16px;
+      }
+      .left-border-spacer {
+        width: 16px;
+        border-left: 1px solid;
+      }
+      .clickable {
+        color: #0489c3;
+        text-decoration: none;
+        cursor: pointer;
+        min-width: 8em;
+      }
+      .clickable:hover {
+        text-decoration: underline;
+        cursor: pointer;
+      }
+      tr:hover:not(.focused) > td {
+        background-color: #FAFAFA;
+      }
+      .focused {
+        background-color: #F4C7C3;
+      }
+      .scroll {
+        overflow: scroll;
+      }
+      .outlined {
+        -webkit-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
+        -moz-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
+        box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
+        margin: 4px;
+      }
+      .centered {
+        margin-left: auto;
+        margin-right: auto;
+        justify-content: center;
+      }
+      .full-height {
+        height: 100%;
+      }
+      .mostly-full-height {
+        height: 80%;
+      }
+      .full-width {
+        width: 100%;
+      }
+      .focused-function-label {
+        flex: 0 1 auto;
+        margin-left: auto;
+        margin-right: auto;
+        justify-content: center;
+      }
+      .call-table {
+        flex: 1 1 auto;
+      }
+
+      .tree {
+        border-spacing: 0px;
+        width: 100%;
+        margin-bottom: 20px
+        vertical-align: middle;
+      }
+
+      .tree tbody tr {
+        animation: fadeIn 0.5s;
+        -moz-animation: fadeIn 0.5s;
+        -webkit-animation: fadeIn 0.5s;
+      }
+
+      .tree tbody tr:hover {
+        background-color: #FAFAFA;
+      }
+
+      .tree tr td:first-child,
+      .tree tr th:first-child {
+        width: 100%;
+      }
+
+      .tree thead > tr > th {
+        padding: 8px;
+        vertical-align: bottom;
+        text-align: left;
+        border-bottom: 1px solid #ddd;
+      }
+
+    </style>
+    <div id="sampleBufferControl"></div>
+    <br>
+    <hr>
+    <div id="main" class="flex-row centered">
+      <div class="flex-item-45-percent full-height outlined scroll">
+        <table id="main-table" class="flex-item-100-percent table">
+          <thead>
+          <tr>
+            <th on-click="{{changeSortProfile}}" class="clickable" title="Executing (%)">{{ profileTable.getColumnLabel(0) }}</th>
+            <th on-click="{{changeSortProfile}}" class="clickable" title="In stack (%)">{{ profileTable.getColumnLabel(1) }}</th>
+            <th on-click="{{changeSortProfile}}" class="clickable" title="Method">{{ profileTable.getColumnLabel(2) }}</th>
+          </tr>
+          </thead>
+          <tbody id="profile-table">
+          </tbody>
+        </table>
+      </div>
+      <div class="flex-item-45-percent full-height outlined">
+        <div class="flex-column full-height">
+          <div class="focused-function-label">
+            <template if="{{ focusedFunction != null }}">
+              <span>Focused on: </span>
+              <function-ref ref="{{ focusedFunction }}"></function-ref>
+            </template>
+            <template if="{{ focusedFunction == null }}">
+              <span>No focused function</span>
+            </template>
+          </div>
+          <hr>
+          <div class="call-table scroll">
+            <table class="full-width table">
+              <thead>
+              <tr>
+                <th on-click="{{changeSortCallers}}" class="clickable" title="Callers (%)">{{ profileCallersTable.getColumnLabel(0) }}</th>
+                <th on-click="{{changeSortCallers}}" class="clickable" title="Method">{{ profileCallersTable.getColumnLabel(1) }}</th>
+              </tr>
+              </thead>
+              <tbody id="callers-table">
+              </tbody>
+            </table>
+          </div>
+          <hr>
+          <div class="call-table scroll">
+            <table class="full-width table">
+              <thead>
+              <tr>
+                <th on-click="{{changeSortCallees}}" class="clickable" title="Callees (%)">{{ profileCalleesTable.getColumnLabel(0) }}</th>
+                <th on-click="{{changeSortCallees}}" class="clickable" title="Method">{{ profileCalleesTable.getColumnLabel(1) }}</th>
+              </tr>
+              </thead>
+              <tbody id="callees-table">
+              </tbody>
+            </table>
+          </div>
+        </div>
+      </div>
+    </div>
+    <br>
+    <div id="stackTraceTreeConfig"></div>
+    <br>
+    <div class="content-centered-big">
+      <div class="focused-function-label">
+        <template if="{{ focusedFunction != null }}">
+          <span>Filtered tree: </span>
+          <function-ref ref="{{ focusedFunction }}"></function-ref>
+        </template>
+        <template if="{{ focusedFunction == null }}">
+          <span>No focused function</span>
+        </template>
+      </div>
+    </div>
+    <br>
+    <br>
+    <div class="flex-row centered">
+      <div class="flex-item-90-percent outlined" style="margin: 16px; margin-left: 8px; margin-right: 8px">
+        <div id="cpuProfileTree"></div>
+      </div>
+    </div>
+  </template>
+</polymer-element>
+
+<script type="application/dart" src="cpu_profile.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css
index 3442d98..aeb5827 100644
--- a/runtime/observatory/lib/src/elements/css/shared.css
+++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -7,6 +7,10 @@
   box-sizing: border-box;
 }
 
+body {
+  padding-top: 56px;
+}
+
 .content {
   padding-left: 10%;
   font: 400 14px 'Montserrat', sans-serif;
@@ -57,12 +61,12 @@
   white-space: nowrap;
 }
 
-a {
+a[href] {
   color: #0489c3;
   text-decoration: none;
 }
 
-a:hover {
+a[href]:hover {
   text-decoration: underline;
 }
 
@@ -298,6 +302,17 @@
               0 2px 5px 0 rgba(0, 0, 0, 0.26);
 }
 
+input.textbox {
+  width: 20em;
+  font: 400 16px 'Montserrat', sans-serif;
+}
+
+select, button, input {
+  border-radius: 0px;
+  border-style: solid;
+  border-width: 1px;
+}
+
 @-webkit-keyframes fadeIn {
   0%   { opacity: 0; }
   100% { opacity: 1; }
@@ -354,3 +369,737 @@
   animation: shake 0.5s;
   -webkit-animation: shake 0.5s;
 }
+
+/* allocation-profile */
+
+allocation-profile .heap-space {
+  display: inline-block;
+  width: 50%;
+}
+
+allocation-profile .heap-space.right,
+allocation-profile .heap-space.right .memberList,
+allocation-profile .heap-space.right .legend * {
+  direction: rtl;
+}
+
+allocation-profile .heap-space.right * {
+  direction: ltr;
+  text-align: right;
+}
+
+allocation-profile div.chart {
+  display: block;
+  position: relative;
+  height: 150px;
+}
+allocation-profile div.chart > div.host {
+  display: inline-block;
+  position: absolute;
+  bottom: 0px;
+  top: 0;
+}
+allocation-profile div.chart > div.legend {
+  position: absolute;
+  width: 150px;
+  top: 25px;
+  bottom: 0;
+  overflow-y: auto;
+}
+allocation-profile .heap-space.left div.host {
+  left: 200px;
+  width: 180px;
+}
+allocation-profile .heap-space.right div.host {
+  right: 150px;
+  width: 180px;
+}
+allocation-profile .heap-space.left div.legend {
+  left: 0;
+}
+allocation-profile .heap-space.right div.legend {
+  right: 0;
+}
+
+allocation-profile .collection {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  top: 560px;
+}
+
+allocation-profile .collection-item {
+  box-sizing: border-box;
+  line-height: 20px;
+  margin-left: 5%;
+  margin-right: 5%;
+}
+
+allocation-profile .header .collection-item:last-child {
+  margin-bottom: -3px;
+  border-bottom: solid 1px #AAAAAA;
+}
+
+allocation-profile .header .collection-item span {
+  font-weight: bolder;
+}
+
+allocation-profile .collection-item :nth-child(2n+2).group,
+allocation-profile .collection-item :nth-child(4n+3).bytes,
+allocation-profile .collection-item :nth-child(4n+3).instances,
+allocation-profile .collection-item :nth-child(4n+4).bytes,
+allocation-profile .collection-item :nth-child(4n+4).instances {
+  background-color: #EEEEEE;
+}
+
+allocation-profile .collection-item:hover :nth-child(2n+2).group,
+allocation-profile .collection-item:hover :nth-child(4n+3).bytes,
+allocation-profile .collection-item:hover :nth-child(4n+3).instances,
+allocation-profile .collection-item:hover :nth-child(4n+4).bytes,
+allocation-profile .collection-item:hover :nth-child(4n+4).instances {
+  background-color: #afd5fd;
+}
+
+allocation-profile .header .collection-item :nth-child(2n+2).group,
+allocation-profile .header .collection-item :nth-child(4n+3).bytes,
+allocation-profile .header .collection-item :nth-child(4n+3).instances,
+allocation-profile .header .collection-item :nth-child(4n+4).bytes,
+allocation-profile .header .collection-item :nth-child(4n+4).instances {
+  background-color: #DDDDDD;
+}
+
+allocation-profile .scroller .collection-item:hover {
+  background-color: #d2e7fe;
+}
+
+allocation-profile .collection-item .group {
+  background-color: white;
+  display: inline-block;
+  width: 12em;
+  text-align: right;
+  padding-right: 0.5em;
+  line-height: 20px;
+  border-right: solid 1px #AAAAAA;
+}
+
+allocation-profile .collection-item .bytes {
+  background-color: white;
+  display: inline-block;
+  width: 6em;
+  text-align: right;
+  line-height: 20px;
+  padding-right: 0.5em;
+}
+
+allocation-profile .collection-item .instances {
+  background-color: white;
+  display: inline-block;
+  width: 6em;
+  text-align: right;
+  padding-right: 0.5em;
+  line-height: 20px;
+  border-right: solid 1px #AAAAAA;
+}
+
+allocation-profile .collection-item .name {
+  background-color: white;
+  padding-left: 0.5em;
+}
+
+allocation-profile .collection-item > button,
+allocation-profile .collection-item > button:active {
+  background-color: transparent;
+  color: #0489c3;
+  border-style: none;
+}
+
+allocation-profile .collection-item > button:hover {
+  text-decoration: underline;
+}
+
+/* class-ref */
+/* TODO(cbernaschina) fix class-ref-wrapped to class-ref when wrapper
+removed */
+
+class-ref-wrapped > a[href]:hover {
+    text-decoration: underline;
+}
+class-ref-wrapped > a[href] {
+    color: #0489c3;
+    text-decoration: none;
+}
+
+/* code-ref */
+/* TODO(cbernaschina) fix code-ref-wrapped to code-ref when wrapper
+removed */
+
+code-ref-wrapped > a[href]:hover {
+  text-decoration: underline;
+}
+code-ref-wrapped > a[href] {
+  color: #0489c3;
+  text-decoration: none;
+}
+
+/* class-tree */
+
+class-tree {
+  position: relative;
+  display: block;
+  height: 100%;
+}
+
+class-tree virtual-tree {
+  position: absolute;
+  height: auto;
+  top: 60px;
+  bottom: 0;
+  left: 0;
+  right: 0;
+}
+
+class-tree virtual-tree .class-tree-item {
+  line-height: 25px;
+  height: 25px;
+  padding-left: 10%;
+  padding-right: 10%;
+}
+
+class-tree virtual-tree .class-tree-item .name {
+  margin-left: 0.5em;
+}
+
+/* cpu-profile */
+
+cpu-profile {
+  position: relative;
+  display: block;
+  height: 100%;
+}
+
+cpu-profile > cpu-profile-virtual-tree {
+  position: absolute;
+  height: auto;
+  top: 320px;
+  bottom: 0;
+  left: 0;
+  right: 0;
+}
+
+/* cpu-profile-virtual-tree */
+
+cpu-profile-virtual-tree {
+  display: block;
+  height: 600px;
+}
+
+cpu-profile-virtual-tree .tree-item {
+  box-sizing: border-box;
+  line-height: 30px;
+  height: 30px;
+  padding-left: 5%;
+  padding-right: 5%;
+}
+
+cpu-profile-virtual-tree .tree-item > .inclusive,
+cpu-profile-virtual-tree .tree-item > .exclusive,
+cpu-profile-virtual-tree .tree-item > .percentage {
+  display: inline-block;
+  text-align: right;
+  width: 4em;
+  margin-left: 0.25em;
+  margin-right: 0.25em;
+}
+
+cpu-profile-virtual-tree .tree-item > .exclusive {
+  margin-right: 1.5em;
+}
+
+cpu-profile-virtual-tree .tree-item > .name {
+  display: inline;
+  margin-left: 0.5em;
+}
+
+/* error-ref */
+/* TODO(cbernaschina) fix error-ref-wrapped to error-ref when wrapper
+removed */
+
+error-ref-wrapped > pre {
+  background-color: #f5f5f5;
+  border: 1px solid #ccc;
+  padding: 10px;
+  font-family: consolas, courier, monospace;
+  font-size: 1em;
+  line-height: 1.2em;
+  white-space: pre;
+}
+
+/* flag-list */
+
+flag-list .comment {
+  color: #aaa;
+}
+
+flag-list .flag {
+  padding: 3px 0;
+}
+
+flag-list .name {
+  font-weight: bold;
+  margin-right: 0.7em;
+}
+
+flag-list .value {
+  margin-left: 0.7em;
+}
+
+/* function-ref */
+/* TODO(cbernaschina) fix function-ref-wrapped to function-ref when wrapper
+removed */
+
+function-ref-wrapped > a[href]:hover {
+  text-decoration: underline;
+}
+function-ref-wrapped > a[href] {
+  color: #0489c3;
+  text-decoration: none;
+}
+
+/* instance-ref */
+/* TODO(cbernaschina) fix instance-ref-wrapped to instance-ref when wrapper
+removed */
+
+instance-ref-wrapped .empathize {
+  font-style: italic;
+}
+instance-ref-wrapped .indent {
+  margin-left: 1.5em;
+  font: 400 14px 'Montserrat', sans-serif;
+  line-height: 150%;
+}
+instance-ref-wrapped .stackTraceBox {
+  margin-left: 1.5em;
+  background-color: #f5f5f5;
+  border: 1px solid #ccc;
+  padding: 10px;
+  font-family: consolas, courier, monospace;
+  font-size: 12px;
+  white-space: pre;
+  overflow-x: auto;
+}
+
+/* isolate-counter-chart */
+
+isolate-counter-chart {
+  display: block;
+  position: relative;
+  height: 300px;
+  min-width: 350px;
+}
+isolate-counter-chart > div.host {
+  position: absolute;
+  left: 0;
+  bottom: 20px;
+  top: 5px;
+  right: 250px;
+}
+isolate-counter-chart > div.legend {
+  position: absolute;
+  width: 250px;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  overflow-y: auto;
+}
+
+/* isolate-reconnect */
+
+isolate-reconnect div.doubleSpaced {
+  line-height: 2em;
+}
+
+/* isolate-ref */
+/* TODO(cbernaschina) fix isolate-ref-wrapped to isolate-ref when wrapper
+removed */
+
+isolate-ref-wrapped > a[href]:hover {
+  text-decoration: underline;
+}
+isolate-ref-wrapped > a[href] {
+  color: #0489c3;
+  text-decoration: none;
+}
+
+/* isolate-shared-summary */
+/* TODO(cbernaschina) fix isolate-shared-summary-wrapped
+to isolate-shared-summary when wrapper removed */
+
+isolate-shared-summary,
+isolate-shared-summary-wrapped {
+  display: block;
+  height: 300px;
+  position: relative;
+}
+isolate-shared-summary-wrapped > .menu {
+  float: right;
+  top: 0;
+  right: 0;
+}
+isolate-shared-summary-wrapped > isolate-counter-chart {
+  position: absolute;
+  left: 0;
+  top: 0;
+  right: 230px;
+  clear: both;
+}
+isolate-shared-summary-wrapped .errorBox {
+  background-color: #f5f5f5;
+  border: 1px solid #ccc;
+  padding: 2em;
+  font-family: consolas, courier, monospace;
+  font-size: 1em;
+  line-height: 1.2em;
+  white-space: pre;
+}
+
+/* library-ref */
+/* TODO(cbernaschina) fix library-ref-wrapped to library-ref when wrapper
+removed */
+
+library-ref-wrapped > a[href]:hover {
+  text-decoration: underline;
+}
+library-ref-wrapped > a[href] {
+  color: #0489c3;
+  text-decoration: none;
+}
+
+.nav-option {
+  float: right;
+  margin: 3px;
+  padding: 8px;
+}
+
+.nav-option label {
+  color: white;
+}
+
+/* nav-notify */
+/* TODO(cbernaschina) fix nav-notify-wrapped to nav-notify when wrapper
+removed */
+nav-notify-wrapped > div {
+  float: right;
+}
+nav-notify-wrapped > div > div {
+  display: block;
+  position: absolute;
+  top: 98%;
+  right: 0;
+  margin: 0;
+  padding: 0;
+  width: auto;
+  z-index: 1000;
+  background: none;
+}
+
+/* nav-exception & nav-event */
+
+nav-exception > div, nav-event > div {
+  position: relative;
+  padding: 16px;
+  margin-top: 10px;
+  margin-right: 10px;
+  padding-right: 25px;
+  width: 500px;
+  color: #ddd;
+  background: rgba(0,0,0,.6);
+  border: solid 2px white;
+  box-shadow: 0 0 5px black;
+  border-radius: 5px;
+  animation: fadein 1s;
+}
+
+nav-exception *, nav-event * {
+  color: #ddd;
+  font-size: 12px;
+}
+
+nav-exception > div > a, nav-event > div > a {
+  color: white;
+  text-decoration: none;
+}
+
+nav-exception > div > a:hover, nav-event > div > a:hover {
+  text-decoration: underline;
+}
+
+nav-exception > div > div {
+  margin-left:20px;
+  white-space: pre
+}
+
+nav-exception > div > button, nav-event > div > button {
+  background: transparent;
+  border: none;
+  position: absolute;
+  display: block;
+  top: 4px;
+  right: 4px;
+  height: 18px;
+  width: 18px;
+  line-height: 16px;
+  border-radius: 9px;
+  color: white;
+  font-size: 18px;
+  cursor: pointer;
+  text-align: center;
+}
+
+nav-exception > div > button:hover, nav-event > div > button:hover {
+  background: rgba(255,255,255,0.5);
+}
+
+/* nav-refresh */
+/* TODO(cbernaschina) fix nav-refresh-wrapped to nav-refresh when wrapper
+removed */
+
+nav-refresh-wrapped > li > button {
+  color: #000;
+  margin: 3px;
+  padding: 8px;
+  border-width: 2px;
+  line-height: 13px;
+  font-size: 13px;
+  font: 400 'Montserrat', sans-serif;
+}
+nav-refresh-wrapped > li > button[disabled] {
+  color: #aaa;
+  cursor: wait;
+}
+nav-refresh-wrapped > li {
+  float: right;
+  margin: 0;
+}
+
+/* observatory-application */
+
+observatory-application {
+  display: block;
+  height: 100%;
+}
+
+observatory-application > div {
+  display: block;
+  height: 100%;
+}
+
+/* script-ref */
+/* TODO(cbernaschina) fix script-ref-wrapped to script-ref when wrapper
+removed */
+
+script-ref-wrapped > a[href]:hover {
+    text-decoration: underline;
+}
+
+script-ref-wrapped > a[href] {
+    color: #0489c3;
+    text-decoration: none;
+}
+
+/* source-link */
+/* TODO(cbernaschina) fix source-link-wrapped to source-link when wrapper
+removed */
+
+source-link-wrapped > a[href]:hover {
+    text-decoration: underline;
+}
+
+source-link-wrapped > a[href] {
+    color: #0489c3;
+    text-decoration: none;
+}
+
+
+/* observatory-application */
+
+observatory-application {
+  display: block;
+  height: 100%;
+}
+
+observatory-application > div {
+  display: block;
+  height: 100%;
+}
+
+/* sample-buffer-control */
+
+sample-buffer-control {
+  white-space: nowrap;
+}
+
+sample-buffer-control .statusMessage {
+  font-size: 150%;
+  font-weight: bold;
+}
+
+sample-buffer-control .statusBox {
+  height: 100%;
+  padding: 1em;
+}
+
+sample-buffer-control .center {
+  align-items: center;
+  justify-content: center;
+}
+
+sample-buffer-control .notice {
+  background-color: #fcf8e3;
+}
+
+sample-buffer-control .red {
+  background-color: #f2dede;
+}
+
+sample-buffer-control .shadow {
+  box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.16),
+              0 2px 5px 0 rgba(0, 0, 0, 0.26);
+}
+
+/* stack-trace-tree-config */
+
+stack-trace-tree-config {
+  white-space: nowrap;
+}
+
+/* view-footer */
+
+view-footer {
+  padding: 1em;
+  padding-top: 10.3em;
+  float: right;
+  align-content: right;
+}
+
+view-footer > a {
+  margin-bottom: 0.17em;
+  font-size: 90%;
+  float: right;
+  clear: both;
+  display: block;
+}
+
+/* virtual-collection */
+
+virtual-collection {
+  position: relative;
+  display: block;
+  overflow-y: auto;
+  width: 100%;
+  height: 100%;
+}
+
+virtual-collection .header {
+  background: white;
+  position: relative;
+  display: inline-block;
+  min-width: 100%;
+  z-index: +1;
+}
+
+virtual-collection .scroller {
+  overflow: hidden;
+  background: transparent;
+  display: inline-block;
+  min-width: 100%;
+}
+
+virtual-collection .shifter {
+  background: transparent;
+  position: relative;
+  display: inline-block;
+  min-width: 100%;
+}
+
+virtual-collection .header > *,
+virtual-collection .shifter > * {
+  display: inline-block;
+  min-width: 100%;
+  white-space: nowrap;
+}
+
+/* virtual-tree */
+
+virtual-tree .expander {
+  display: inline-block;
+  text-align: center;
+  font-weight: bold;
+  font-size: 18px;
+  width: 19px;
+  border: none;
+  background-color: transparent;
+}
+
+virtual-tree .expander:focus {
+  outline: none;
+}
+
+virtual-tree .lines,
+virtual-tree .lines > span {
+  display: inline-block;
+  vertical-align: top;
+  height: 100%;
+  line-height: 100%;
+}
+
+virtual-tree .lines:before,
+virtual-tree .lines > span:before {
+  display: inline-block;
+  content: '';
+}
+
+virtual-tree .lines > span {
+  width: 3px;
+  margin-left: 8px;
+  margin-right: 8px;
+}
+
+virtual-tree .lines > span:nth-child(5n) {
+  background-color: #673AB7;
+}
+
+virtual-tree .lines > span:nth-child(5n+1) {
+  background-color: #F44336;
+}
+
+virtual-tree .lines > span:nth-child(5n+2) {
+  background-color: #4CAF50;
+}
+
+virtual-tree .lines > span:nth-child(5n+3) {
+  background-color: #3F51B5;
+}
+
+virtual-tree .lines > span:nth-child(5n+4) {
+  background-color: #FF9800;
+}
+
+/* vm-connect-target */
+
+vm-connect-target > button.delete-button {
+  margin-left: 0.28em;
+  padding: 4px;
+  background: transparent;
+  border: none !important;
+}
+
+vm-connect-target > button.delete-button:hover {
+  background: #ff0000;
+}
+
+/* vm-connect */
+
+vm-connect ul {
+  list-style-type: none;
+}
diff --git a/runtime/observatory/lib/src/elements/curly_block.dart b/runtime/observatory/lib/src/elements/curly_block.dart
index 004a02e..9eadd76 100644
--- a/runtime/observatory/lib/src/elements/curly_block.dart
+++ b/runtime/observatory/lib/src/elements/curly_block.dart
@@ -4,52 +4,104 @@
 
 library curly_block_element;
 
-import 'package:polymer/polymer.dart';
-import 'observatory_element.dart';
+import 'dart:async';
+import 'dart:html';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 
-@CustomTag('curly-block')
-class CurlyBlockElement extends ObservatoryElement {
-  CurlyBlockElement.created() : super.created();
+class CurlyBlockToggleEvent {
+  final CurlyBlockElement control;
 
-  @observable bool expanded = false;
-  @observable bool busy = false;
-  @published var callback = null;
-  @published bool expand = false;
-  @published String expandKey;
+  CurlyBlockToggleEvent(this.control);
+}
 
-  void expandChanged(oldValue) {
-    expanded = expand;
+class CurlyBlockElement extends HtmlElement implements Renderable {
+  static final StyleElement _style = () {
+      var style = new StyleElement();
+      style.text = '''span.curly-block {
+                        color: #0489c3;
+                        cursor: pointer;
+                      }
+                      span.curly-block.disabled {
+                        color: white;
+                        cursor: wait;
+                      }''';
+      return style;
+  }();
+
+  static const tag = const Tag<CurlyBlockElement>('curly-block-wrapped');
+
+  RenderingScheduler<CurlyBlockElement> _r;
+
+  final StreamController<CurlyBlockToggleEvent> _onToggle =
+      new StreamController<CurlyBlockToggleEvent>.broadcast();
+  Stream<CurlyBlockToggleEvent> get onToggle => _onToggle.stream;
+  Stream<RenderedEvent<CurlyBlockElement>> get onRendered => _r.onRendered;
+
+  bool _expanded;
+  bool _disabled;
+
+  bool get expanded => _expanded;
+  set expanded(bool value) {
+    if (_expanded != value) _onToggle.add(new CurlyBlockToggleEvent(this));
+    _expanded = _r.checkAndReact(_expanded, value);
+  }
+  bool get disabled => _disabled;
+  set disabled(bool value) => _disabled = _r.checkAndReact(_disabled, value);
+
+  factory CurlyBlockElement({bool expanded: false, bool disabled: false,
+      RenderingQueue queue}) {
+    assert(expanded != null);
+    assert(disabled != null);
+    CurlyBlockElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._expanded = expanded;
+    e._disabled = disabled;
+    return e;
   }
 
-  void expandKeyChanged(oldValue) {
-    if (expandKey != null) {
-      var value = app.expansions[expandKey];
-      if (value != null) {
-        if (expanded != value) {
-          toggleExpand(null, null, null);
-        }
-      }
-    }
+  CurlyBlockElement.created() : super.created() { createShadowRoot(); }
+
+  @override
+  void attached() { super.attached(); _r.enable(); }
+
+  @override
+  void detached() {
+    super.detached(); _r.disable(notify: true);
+    shadowRoot.children = [];
   }
 
-  void doneCallback() {
-    expanded = !expanded;
-    if (expandKey != null) {
-      app.expansions[expandKey] = expanded;
-    }
-    busy = false;
-  }
-
-  void toggleExpand(var event, var b, var c) {
-    assert(callback == null || expand == false);
-    if (busy) {
+  void toggle() {
+    if (disabled) {
+      _r.scheduleNotification();
       return;
     }
-    busy = true;
-    if (callback != null) {
-      callback(!expanded, doneCallback);
+    expanded = !expanded;
+  }
+
+  void render() {
+    List<Element> children = [
+      _style.clone(true),
+      new SpanElement()..text = '{'
+    ];
+    SpanElement label = new SpanElement()
+      ..classes = disabled ? ['curly-block', 'disabled'] : ['curly-block']
+      ..innerHtml = expanded ?
+        '&nbsp;&nbsp;&#8863;&nbsp;&nbsp;' : '&nbsp;&nbsp;&#8862;&nbsp;&nbsp;';
+    if (disabled) {
+      children.add(label);
     } else {
-      doneCallback();
+      children.add(new AnchorElement()
+        ..onClick.listen((_) { toggle(); })
+        ..children = [label]);
     }
+    if (expanded) {
+      children.addAll([
+        new BRElement(),
+        new ContentElement()
+      ]);
+    }
+    children.add(new SpanElement()..text = '}');
+    shadowRoot.children = children;
   }
 }
diff --git a/runtime/observatory/lib/src/elements/curly_block.html b/runtime/observatory/lib/src/elements/curly_block.html
deleted file mode 100644
index d1702a2..0000000
--- a/runtime/observatory/lib/src/elements/curly_block.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="observatory_element.html">
-
-<polymer-element name="curly-block" extends="observatory-element">
-  <template>
-    <style>
-      .idle {
-        display: inline-block;
-        color: #0489c3;
-        cursor: pointer;
-      }
-      .busy {
-        display: inline-block;
-        color: white;
-        cursor: wait;
-      }
-    </style>
-    <template if="{{ expanded }}">
-      <template if="{{ busy }}">
-        {<div class="busy">&nbsp;&nbsp;&#8863;&nbsp;&nbsp;</div>
-        <br>
-        <content></content>
-        }
-      </template>
-      <template if="{{ !busy }}">
-        {<a on-click="{{ toggleExpand }}"><div class="idle">&nbsp;&nbsp;&#8863;&nbsp;&nbsp;</div></a>
-        <br>
-        <content></content>
-        }
-      </template>
-    </template>
-
-    <template if="{{ !expanded }}">
-      <template if="{{ busy }}">
-        {<div class="busy">&nbsp;&nbsp;&#8862;&nbsp;&nbsp;</div>}
-      </template>
-      <template if="{{ !busy }}">
-        {<a on-click="{{ toggleExpand }}"><div class="idle">&nbsp;&nbsp;&#8862;&nbsp;&nbsp;</div></a>}
-      </template>
-    </template>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="curly_block.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/curly_block_wrapper.dart b/runtime/observatory/lib/src/elements/curly_block_wrapper.dart
new file mode 100644
index 0000000..4e2519a
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/curly_block_wrapper.dart
@@ -0,0 +1,102 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+typedef _callback();
+typedef CurlyBlockToggleCallback(bool a, _callback b);
+
+@bindable
+class CurlyBlockElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<CurlyBlockElementWrapper>(const {
+      'expand': #expand, 'busy': #busy, 'expandKey': #expandKey,
+      'callback': #callback
+    });
+
+  static const tag = const Tag<CurlyBlockElementWrapper>('curly-block');
+
+  bool _expand;
+  bool get expand => _expand;
+  set expand(bool expanded) {
+    _expand = !(expanded == null || expanded == false);
+    render();
+  }
+
+  bool _busy;
+  bool get busy => _busy;
+  set busy(bool busy) {
+    _busy = !(busy == null || busy == false);
+    render();
+  }
+
+  String _expandKey;
+  String get expandKey => _expandKey;
+  set expandKey(String expandKey) {
+    _expandKey = expandKey;
+    if (expandKey != null) {
+      var value = application.expansions[expandKey];
+      if (value != null && expand != value) {
+
+      }
+    }
+    render();
+  }
+
+  CurlyBlockToggleCallback _callback;
+  CurlyBlockToggleCallback get callback => _callback;
+  set callback(CurlyBlockToggleCallback callback) {
+    _callback = callback;
+    render();
+  }
+
+  CurlyBlockElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    _expand = !_isFalseOrNull(getAttribute('expand'));
+    _busy = !_isFalseOrNull(getAttribute('busy'));
+    _expandKey = getAttribute('expandKey');
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [
+      new CurlyBlockElement(expanded: expand, disabled: busy,
+                                 queue: ObservatoryApplication.app.queue)
+        ..children = [new ContentElement()]
+        ..onToggle.listen(_toggle)
+    ];
+  }
+
+  ObservatoryApplication get application => ObservatoryApplication.app;
+
+  void _toggle(CurlyBlockToggleEvent e) {
+    _expand = e.control.expanded;
+    if (callback != null) {
+      busy = true;
+      callback(expand, () {
+        if (expandKey != null) {
+          application.expansions[expandKey] = expand;
+        }
+        busy = false;
+      });
+    } else {
+      application.expansions[expandKey] = expand;
+    }
+  }
+
+  bool _isFalseOrNull(String value) {
+    return value == null || value == false;
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index 61a8989..4ced2d6 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -8,7 +8,6 @@
 import 'dart:html';
 import 'dart:math';
 import 'observatory_element.dart';
-import 'nav_bar.dart';
 import 'package:observatory/app.dart';
 import 'package:observatory/cli.dart';
 import 'package:observatory/debugger.dart';
@@ -2005,7 +2004,8 @@
     var cmdDiv = $['commandDiv'];
 
     // For now, force navbar height to 40px in the debugger.
-    int navbarHeight = NavBarElement.height;
+    // TODO (cbernaschina) check if this is needed.
+    const navbarHeight = 40;
     int splitterHeight = splitterDiv.clientHeight;
     int cmdHeight = cmdDiv.clientHeight;
 
@@ -2255,7 +2255,8 @@
     if (varsDiv == null) {
       return minTop;
     }
-    const navbarHeight = NavBarElement.height;
+    // TODO (cbernaschina) check if this is needed.
+    const navbarHeight = 40;
     const bottomPad = 6;
     var parent = varsDiv.parent.getBoundingClientRect();
     var varsHeight = varsDiv.clientHeight;
diff --git a/runtime/observatory/lib/src/elements/debugger.html b/runtime/observatory/lib/src/elements/debugger.html
index 20e2e4d..42fb892 100644
--- a/runtime/observatory/lib/src/elements/debugger.html
+++ b/runtime/observatory/lib/src/elements/debugger.html
@@ -1,10 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="eval_link.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="script_inset.html">
-<link rel="import" href="script_ref.html">
 
 <!-- TODO(turnidge): Use core-icon once core_elements work properly in
      devtools -->
@@ -72,7 +68,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="debugger-page" extends="observatory-element">
+<polymer-element name="debugger-page">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -109,11 +105,13 @@
     </style>
 
     <div class="container">
-      <nav-bar id="navbarDiv" notifyOnPause="{{ false }}">
+      <nav-bar id="navbarDiv" >
         <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('/debugger', isolate) }}" anchor="debugger" last="{{ true }}"></nav-menu>
+        <nav-notify notifications="{{ app.notifications }}"
+                                      notifyOnPause="{{ false }}"></nav-notify>
       </nav-bar>
       <div id="stackDiv" class="stack">
         <debugger-stack id="stackElement" isolate="{{ isolate }}"></debugger-stack>
@@ -132,7 +130,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="debugger-stack" extends="observatory-element">
+<polymer-element name="debugger-stack">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -183,7 +181,7 @@
 </polymer-element>
 
 
-<polymer-element name="debugger-frame" extends="observatory-element">
+<polymer-element name="debugger-frame">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -299,7 +297,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="debugger-message" extends="observatory-element">
+<polymer-element name="debugger-message">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -404,7 +402,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="debugger-console" extends="observatory-element">
+<polymer-element name="debugger-console">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -443,7 +441,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="debugger-input" extends="observatory-element">
+<polymer-element name="debugger-input">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
diff --git a/runtime/observatory/lib/src/elements/error_ref.dart b/runtime/observatory/lib/src/elements/error_ref.dart
index d69726b..55685ed 100644
--- a/runtime/observatory/lib/src/elements/error_ref.dart
+++ b/runtime/observatory/lib/src/elements/error_ref.dart
@@ -1,13 +1,53 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 library error_ref_element;
 
-import 'package:polymer/polymer.dart';
-import 'service_ref.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart'
+  show ErrorRef;
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 
-@CustomTag('error-ref')
-class ErrorRefElement extends ServiceRefElement {
+class ErrorRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ErrorRefElement>('error-ref-wrapped');
+
+  RenderingScheduler<ErrorRefElement> _r;
+
+  Stream<RenderedEvent<ErrorRefElement>> get onRendered => _r.onRendered;
+
+  ErrorRef _error;
+  
+  ErrorRef get error => _error;
+
+  factory ErrorRefElement(ErrorRef error, {RenderingQueue queue}) {
+    assert(error != null);
+    ErrorRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler<ErrorRefElement>(e, queue: queue);
+    e._error = error;
+    return e;
+  }
+
   ErrorRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [
+      new PreElement()..text = error.message
+    ];
+  }
 }
diff --git a/runtime/observatory/lib/src/elements/error_ref.html b/runtime/observatory/lib/src/elements/error_ref.html
deleted file mode 100644
index 57de134..0000000
--- a/runtime/observatory/lib/src/elements/error_ref.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<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="error-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-      .errorBox {
-        background-color: #f5f5f5;
-        border: 1px solid #ccc;
-        padding: 10px;
-        font-family: consolas, courier, monospace;
-        font-size: 1em;
-        line-height: 1.2em;
-        white-space: pre;
-      }
-    </style>
-    <span>
-      <pre class="errorBox">{{ ref.message }}</pre>
-    </span>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="error_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/error_ref_wrapper.dart b/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
new file mode 100644
index 0000000..50f8b9a
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/src/elements/error_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+class ErrorRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<ErrorRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<ErrorRefElementWrapper>('error-ref');
+
+  DartError _error;
+
+  DartError get ref => _error;
+
+  void set ref(DartError value) {
+    _error = value;
+    render();
+  }
+
+  ErrorRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_error == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        error-ref-wrapped > pre {
+          background-color: #f5f5f5;
+          border: 1px solid #ccc;
+          padding: 10px;
+          font-family: consolas, courier, monospace;
+          font-size: 1em;
+          line-height: 1.2em;
+          white-space: pre;
+        }
+        ''',
+      new ErrorRefElement(_error, queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/error_view.html b/runtime/observatory/lib/src/elements/error_view.html
index 818ba1e..aa40472 100644
--- a/runtime/observatory/lib/src/elements/error_view.html
+++ b/runtime/observatory/lib/src/elements/error_view.html
@@ -1,13 +1,11 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="error-view" extends="observatory-element">
+<polymer-element name="error-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
       <top-nav-menu last="{{ true }}"></top-nav-menu>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
     <div class="content-centered">
       <h1>{{ error.kind }}</h1>
diff --git a/runtime/observatory/lib/src/elements/eval_box.html b/runtime/observatory/lib/src/elements/eval_box.html
index f01a995..8f9929f 100644
--- a/runtime/observatory/lib/src/elements/eval_box.html
+++ b/runtime/observatory/lib/src/elements/eval_box.html
@@ -1,9 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="error_ref.html">
-<link rel="import" href="observatory_element.html">
 
-<polymer-element name="eval-box" extends="observatory-element">
+<polymer-element name="eval-box">
   <template>
     <style>
       .textbox {
diff --git a/runtime/observatory/lib/src/elements/eval_link.html b/runtime/observatory/lib/src/elements/eval_link.html
index 1fdb584..d90370e 100644
--- a/runtime/observatory/lib/src/elements/eval_link.html
+++ b/runtime/observatory/lib/src/elements/eval_link.html
@@ -1,9 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="error_ref.html">
-<link rel="import" href="observatory_element.html">
 
-<polymer-element name="eval-link" extends="observatory-element">
+<polymer-element name="eval-link">
   <template>
     <style>
       .idle {
diff --git a/runtime/observatory/lib/src/elements/field_ref.dart b/runtime/observatory/lib/src/elements/field_ref.dart
index 355282b..f86c0f2 100644
--- a/runtime/observatory/lib/src/elements/field_ref.dart
+++ b/runtime/observatory/lib/src/elements/field_ref.dart
@@ -2,12 +2,90 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library field_ref_element;
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
 
-import 'package:polymer/polymer.dart';
-import 'service_ref.dart';
+class FieldRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<FieldRefElement>('field-ref-wrapped',
+                                                dependencies: const [
+                                                  InstanceRefElement.tag
+                                                ]);
 
-@CustomTag('field-ref')
-class FieldRefElement extends ServiceRefElement {
+  RenderingScheduler<FieldRefElement> _r;
+
+  Stream<RenderedEvent<FieldRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.FieldRef _field;
+  M.InstanceRepository _instances;
+
+  M.IsolateRef get isolate => _isolate;
+  M.FieldRef get field => _field;
+
+  factory FieldRefElement(M.IsolateRef isolate, M.FieldRef field,
+      M.InstanceRepository instances, {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(field != null);
+    assert(instances != null);
+    FieldRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._field = field;
+    e._instances = instances;
+    return e;
+  }
+
   FieldRefElement.created() : super.created();
-}
\ No newline at end of file
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    var header = '';
+    if (_field.isStatic) {
+      if (_field.dartOwner is M.ClassRef) {
+        header += 'static ';
+      } else {
+        header += 'top-level ';
+      }
+    }
+    if (_field.isFinal) {
+      header += 'final ';
+    } else if (_field.isConst) {
+      header += 'const ';
+    } else if (_field.declaredType.name == 'dynamic'){
+      header += 'var ';
+    }
+    if (_field.declaredType.name == 'dynamic') {
+      children = [
+        new SpanElement()..text = header,
+        new AnchorElement(href: Uris.inspect(_isolate, object: _field))
+          ..text = _field.name
+      ];
+    }else {
+      children = [
+        new SpanElement()..text = header,
+        new InstanceRefElement(_isolate, _field.declaredType, _instances,
+            queue: _r.queue),
+        new SpanElement()..text = ' ',
+        new AnchorElement(href: Uris.inspect(_isolate, object: _field))
+          ..text = _field.name
+      ];
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/field_ref.html b/runtime/observatory/lib/src/elements/field_ref.html
deleted file mode 100644
index 762362a..0000000
--- a/runtime/observatory/lib/src/elements/field_ref.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="service_ref.html">
-
-<polymer-element name="field-ref" extends="service-ref">
-  <template>
-  <link rel="stylesheet" href="css/shared.css">
-    <span>
-      <template if="{{ ref.isStatic] }}">static</template>
-      <template if="{{ ref.isFinal }}">final</template>
-      <template if="{{ ref.isConst }}">const</template>
-      <template if="{{ (ref.declaredType.name == 'dynamic' &&
-                        !ref.isFinal && !ref.isConst) }}">var</template>
-      <template if="{{ (ref.declaredType.name != 'dynamic') }}">
-      <instance-ref ref="{{ ref.declaredType }}"></instance-ref>
-      </template>
-      <a on-click="{{ goto }}" title="{{ hoverText }}" _href="{{ url }}">{{ name }}</a>
-    </span>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="field_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/field_ref_wrapper.dart b/runtime/observatory/lib/src/elements/field_ref_wrapper.dart
new file mode 100644
index 0000000..aded8f4
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/field_ref_wrapper.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show Field;
+import 'package:observatory/src/elements/field_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class FieldRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<FieldRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<FieldRefElementWrapper>('field-ref');
+
+  Field _field;
+  Field get ref => _field;
+  void set ref(Field ref) {
+    _field = ref;
+    render();
+  }
+
+  FieldRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) return;
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        field-ref-wrapped a[href]:hover {
+            text-decoration: underline;
+        }
+        field-ref-wrapped a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new FieldRefElement(_field.isolate, _field,
+                          new InstanceRepository(_field.isolate),
+                          queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/field_view.html b/runtime/observatory/lib/src/elements/field_view.html
index d9cdefd..1ed32f9 100644
--- a/runtime/observatory/lib/src/elements/field_view.html
+++ b/runtime/observatory/lib/src/elements/field_view.html
@@ -1,13 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="library_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="field-view" extends="observatory-element">
+<polymer-element name="field-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -20,6 +13,7 @@
       </template>
       <nav-menu link="{{ makeLink('/inspect', field) }}" anchor="{{ field.name }}" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
@@ -65,7 +59,8 @@
               <template if="{{ field.guardClass == 'unknown' }}">
                 none
               </template>
-              <template if="{{ field.guardClass != 'unknown' &&
+              <template if="{{ field.guardClass != null &&
+                            field.guardClass != 'unknown' &&
                             field.guardClass != 'dynamic' }}">
                 <class-ref ref="{{ field.guardClass }}"></class-ref>
                 <template if="{{ field.guardNullable }}">
diff --git a/runtime/observatory/lib/src/elements/flag_list.dart b/runtime/observatory/lib/src/elements/flag_list.dart
index f2d1cfc..1fdb3d5 100644
--- a/runtime/observatory/lib/src/elements/flag_list.dart
+++ b/runtime/observatory/lib/src/elements/flag_list.dart
@@ -4,35 +4,150 @@
 
 library flag_list_element;
 
+import 'dart:html';
 import 'dart:async';
-import 'package:polymer/polymer.dart';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-@CustomTag('flag-list')
-class FlagListElement extends ObservatoryElement {
-  @published ServiceMap flagList;
+class FlagListElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<FlagListElement>('flag-list',
+                     dependencies: const [NavBarElement.tag,
+                                          NavMenuElement.tag,
+                                          NavNotifyElement.tag,
+                                          NavRefreshElement.tag,
+                                          NavTopMenuElement.tag,
+                                          NavVMMenuElement.tag,
+                                          ViewFooterElement.tag,]);
 
-  void flagListChanged(oldValue) {
-    modifiedFlags =
-        flagList['flags'].where((flag) => flag['modified']).toList();
-    unmodifiedFlags =
-        flagList['flags'].where((flag) => !flag['modified']).toList();
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<FlagListElement>> get onRendered => _r.onRendered;
+
+  M.VMRef _vm;
+  M.EventRepository _events;
+  M.FlagsRepository _repository;
+  M.NotificationRepository _notifications;
+  Iterable<M.Flag> _flags;
+
+  M.VMRef get vm => _vm;
+
+  factory FlagListElement(M.VMRef vm,
+                          M.EventRepository events,
+                          M.FlagsRepository repository,
+                          M.NotificationRepository notifications,
+                          {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(events != null);
+    assert(repository != null);
+    assert(notifications != null);
+    FlagListElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._events = events;
+    e._repository = repository;
+    e._notifications = notifications;
+    return e;
   }
 
-  @observable List<ServiceMap> modifiedFlags = new List<ServiceMap>();
-  @observable List<ServiceMap> unmodifiedFlags = new List<ServiceMap>();
-
   FlagListElement.created() : super.created();
 
-  Future refresh() {
-    return flagList.reload();
+  @override
+  void attached() {
+    super.attached();
+    _refresh();
+    _r.enable();
   }
-}
 
-@CustomTag('flag-item')
-class FlagItemElement extends ObservatoryElement {
-  @published ObservableMap flag;
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
 
-  FlagItemElement.created() : super.created();
+  void render() {
+    final content = <Element>[];
+    if (_flags == null) {
+      content.add(new HeadingElement.h1()..text = 'Loading Flags...');
+    } else {
+      final modified = _flags.where(_isModified);
+      final unmodified = _flags.where(_isUnmodified);
+
+      if (modified.isNotEmpty) {
+        content.add(new HeadingElement.h1()..text = 'Modified Flags');
+        content.add(new BRElement());
+        content.addAll(modified.expand(_renderFlag));
+        content.add(new HRElement());
+      }
+
+      content.add(new HeadingElement.h1()..text = 'Unmodified Flags');
+      content.add(new BRElement());
+
+      if (unmodified.isEmpty) {
+        content.add(new HeadingElement.h2()..text = 'None');
+      } else {
+        content.addAll(unmodified.expand(_renderFlag));
+      }
+    }
+
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavMenuElement('flags', link: Uris.flags(), last: true,
+                             queue: _r.queue),
+          new NavRefreshElement(queue: _r.queue)
+            ..onRefresh.listen((e) async {
+              e.element.disabled = true;
+              try {
+                await _refresh();
+              } finally {
+                e.element.disabled = false;
+              }
+            }),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()
+        ..classes = ['content-centered']
+        ..children = content,
+      new ViewFooterElement(queue: _r.queue)
+    ];
+  }
+
+  Future _refresh() {
+    return _repository.list().then((flags) {
+      _flags = flags;
+      _r.dirty();
+    });
+  }
+
+  static bool _isModified(M.Flag flag) => flag.modified;
+  static bool _isUnmodified(M.Flag flag) => !flag.modified;
+
+  static List<Element> _renderFlag(M.Flag flag) {
+    return [
+      new SpanElement()..classes = const ['comment']
+        ..text = '// ${flag.comment}',
+      new DivElement()..classes = flag.modified ? const ['flag', 'modified']
+                                                : const ['flag', 'unmodified']
+        ..children = [
+          new SpanElement()..classes = const ['name']
+            ..text = flag.name,
+          new SpanElement()..text = '=',
+          new SpanElement()..classes = const ['value']
+            ..text = flag.valueAsString ?? 'NULL'
+        ],
+      new BRElement(),
+    ];
+  }
 }
diff --git a/runtime/observatory/lib/src/elements/flag_list.html b/runtime/observatory/lib/src/elements/flag_list.html
deleted file mode 100644
index 9a39cbb..0000000
--- a/runtime/observatory/lib/src/elements/flag_list.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="view_footer.html">
-
-<polymer-element name="flag-list" extends="observatory-element">
-  <template>
-    <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>
-
-    <div class="content-centered">
-      <template if="{{ modifiedFlags.isNotEmpty }}">
-        <h1>Modified Flags</h1>
-        <br>
-        <template repeat="{{ flag in modifiedFlags }}">
-          <flag-item flag="{{ flag }}"></flag-item>
-          <br>
-        </template>
-        <hr>
-      </template>
-
-      <h1>Unmodified Flags</h1>
-      <br>
-      <template if="{{ unmodifiedFlags.isEmpty }}">
-        <em>None</em>
-      </template>
-      <template if="{{ unmodifiedFlags.isNotEmpty }}">
-        <template repeat="{{ flag in unmodifiedFlags }}">
-          <flag-item flag="{{ flag }}"></flag-item>
-          <br>
-        </template>
-      </template>
-    </div>
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<polymer-element name="flag-item" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <span style="color:#aaa">// {{ flag['comment'] }}</span>
-    <div style="padding: 3px 0">
-      <b>{{ flag['name'] }}</b>
-      &nbsp;=&nbsp;
-      {{ flag['valueAsString'] }}
-    </div>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="flag_list.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/function_ref.dart b/runtime/observatory/lib/src/elements/function_ref.dart
index d91a512..204169d 100644
--- a/runtime/observatory/lib/src/elements/function_ref.dart
+++ b/runtime/observatory/lib/src/elements/function_ref.dart
@@ -5,45 +5,82 @@
 library function_ref_element;
 
 import 'dart:html';
-import 'package:polymer/polymer.dart';
-import 'package:observatory/service.dart';
-import 'service_ref.dart';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, FunctionRef, isSyntheticFunction, ClassRef, ObjectRef;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 
-@CustomTag('function-ref')
-class FunctionRefElement extends ServiceRefElement {
-  @published bool qualified = true;
+class FunctionRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<FunctionRefElement>('function-ref-wrapped');
+
+  RenderingScheduler<FunctionRefElement> _r;
+
+  Stream<RenderedEvent<FunctionRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.FunctionRef _function;
+  bool _qualified;
+
+  M.IsolateRef get isolate => _isolate;
+  M.FunctionRef get function => _function;
+  bool get qualified => _qualified;
+
+  factory FunctionRefElement(M.IsolateRef isolate, M.FunctionRef function,
+      {bool qualified: true, RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(function != null);
+    assert(qualified != null);
+    FunctionRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._function = function;
+    e._qualified = qualified;
+    return e;
+  }
 
   FunctionRefElement.created() : super.created();
 
-  refChanged(oldValue) {
-    super.refChanged(oldValue);
-    _updateShadowDom();
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
   }
 
-  ServiceFunction get function => ref;
-  void _updateShadowDom() {
-    clearShadowRoot();
-    if (ref == null) {
-      return;
-    }
-    if (!function.kind.isDart()) {
-      insertTextSpanIntoShadowRoot(name);
-      return;
-    }
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    var content = <Element>[
+      new AnchorElement(href: M.isSyntheticFunction(function.kind) ? null
+        : Uris.inspect(_isolate, object: _function))
+        ..text = _function.name
+    ];
     if (qualified) {
-      if (function.dartOwner is ServiceFunction) {
-        var functionRef = new Element.tag('function-ref');
-        functionRef.ref = function.dartOwner;
-        functionRef.qualified = true;
-        shadowRoot.children.add(functionRef);
-        insertTextSpanIntoShadowRoot('.');
-      } else if (function.dartOwner is Class) {
-        var classRef = new Element.tag('class-ref');
-        classRef.ref = function.dartOwner;
-        shadowRoot.children.add(classRef);
-        insertTextSpanIntoShadowRoot('.');
+      M.ObjectRef owner = _function.dartOwner;
+      while (owner is M.FunctionRef) {
+        M.FunctionRef function = (owner as M.FunctionRef);
+        content.addAll([
+          new SpanElement()..text = '.',
+          new AnchorElement(href: M.isSyntheticFunction(function.kind) ? null
+            : Uris.inspect(_isolate, object: function))
+            ..text = function.name
+        ]);
+        owner = function.dartOwner;
+      }
+      if (owner is M.ClassRef) {
+        content.addAll([
+          new SpanElement()..text = '.',
+          new ClassRefElement(_isolate, owner, queue: _r.queue)
+        ]);
       }
     }
-    insertLinkIntoShadowRoot(name, url, hoverText);
+    children = content.reversed.toList(growable: false);
   }
 }
diff --git a/runtime/observatory/lib/src/elements/function_ref.html b/runtime/observatory/lib/src/elements/function_ref.html
deleted file mode 100644
index c9499b3..0000000
--- a/runtime/observatory/lib/src/elements/function_ref.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="service_ref.html">
-
-<polymer-element name="function-ref" extends="service-ref">
-  <template><link rel="stylesheet" href="css/shared.css"></template>
-</polymer-element>
-
-<script type="application/dart" src="function_ref.dart"></script>
\ No newline at end of file
diff --git a/runtime/observatory/lib/src/elements/function_ref_wrapper.dart b/runtime/observatory/lib/src/elements/function_ref_wrapper.dart
new file mode 100644
index 0000000..dbde827
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/function_ref_wrapper.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart' show ServiceFunction;
+import 'package:observatory/src/elements/function_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class FunctionRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<FunctionRefElementWrapper>(const {
+      'ref': #ref, 'qualified': #qualified
+    });
+
+  static const tag = const Tag<FunctionRefElementWrapper>('function-ref');
+
+  bool _qualified = true;
+  ServiceFunction _function;
+
+  bool get qualified => _qualified;
+  ServiceFunction get ref => _function;
+
+  void set qualified(bool value) {
+    _qualified = value;
+    render();
+  }
+  void set ref(ServiceFunction value) {
+    _function = value;
+    render();
+  }
+
+  FunctionRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        class-ref-wrapped > a[href]:hover,
+        function-ref-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        class-ref-wrapped > a[href],
+        function-ref-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new FunctionRefElement(_function.isolate, _function, qualified: qualified,
+        queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
index a087382..a196455 100644
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ b/runtime/observatory/lib/src/elements/function_view.html
@@ -1,15 +1,7 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="code_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="library_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="script_inset.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="function-view" extends="observatory-element">
+<polymer-element name="function-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -22,6 +14,7 @@
       </template>
       <nav-menu link="{{ makeLink('/inspect', function) }}" anchor="{{ function.name }}" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
diff --git a/runtime/observatory/lib/src/elements/general_error.dart b/runtime/observatory/lib/src/elements/general_error.dart
index d47ec04..943ba3c 100644
--- a/runtime/observatory/lib/src/elements/general_error.dart
+++ b/runtime/observatory/lib/src/elements/general_error.dart
@@ -1,16 +1,76 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 library general_error_element;
 
-import 'observatory_element.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
 
-/// Displays an error message
-@CustomTag('general-error')
-class GeneralErrorElement extends ObservatoryElement {
-  @published String message;
+class GeneralErrorElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<GeneralErrorElement>('general-error',
+                     dependencies: const [NavBarElement.tag,
+                                          NavTopMenuElement.tag,
+                                          NavNotifyElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<GeneralErrorElement>> get onRendered => _r.onRendered;
+
+  M.NotificationRepository _notifications;
+  String _message;
+
+  String get message => _message;
+
+  set message(String value) => _message = _r.checkAndReact(_message, value);
+
+
+  factory GeneralErrorElement(M.NotificationRepository notifications,
+                           {String message: '', RenderingQueue queue}) {
+    assert(notifications != null);
+    assert(message != null);
+    GeneralErrorElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._message = message;
+    e._notifications = notifications;
+    return e;
+  }
 
   GeneralErrorElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(last: true, queue: _r.queue),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()..classes = ['content-centered']
+        ..children = [
+          new HeadingElement.h1()..text = 'Error',
+          new BRElement(),
+          new DivElement()..classes = ['well']
+            ..text = message
+        ]
+    ];
+  }
 }
diff --git a/runtime/observatory/lib/src/elements/general_error.html b/runtime/observatory/lib/src/elements/general_error.html
deleted file mode 100644
index ef1e004..0000000
--- a/runtime/observatory/lib/src/elements/general_error.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<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="general-error" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-    </nav-bar>
-    <div class="content-centered">
-      <h1>Error</h1>
-      <br>
-      <div class="well">{{ message }}</div>
-    </div>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="general_error.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/heap_map.html b/runtime/observatory/lib/src/elements/heap_map.html
index 8c95e22..d68aed2 100644
--- a/runtime/observatory/lib/src/elements/heap_map.html
+++ b/runtime/observatory/lib/src/elements/heap_map.html
@@ -1,10 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="heap-map" extends="observatory-element">
+<polymer-element name="heap-map">
 <template>
   <link rel="stylesheet" href="css/shared.css">
   <style>
@@ -30,6 +26,7 @@
     <isolate-nav-menu isolate="{{ fragmentation.isolate }}"></isolate-nav-menu>
     <nav-menu link="{{ makeLink('/heap-map', fragmentation.isolate) }}" anchor="heap map" last="{{ true }}"></nav-menu>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <nav-notify notifications="{{ app.notifications }}"></nav-notify>
   </nav-bar>
   <div class="hover">
     <p style="text-align:center">{{ status }}</p>
diff --git a/runtime/observatory/lib/src/elements/heap_profile.dart b/runtime/observatory/lib/src/elements/heap_profile.dart
deleted file mode 100644
index 9e5b142..0000000
--- a/runtime/observatory/lib/src/elements/heap_profile.dart
+++ /dev/null
@@ -1,405 +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 heap_profile_element;
-
-import 'dart:async';
-import 'dart:html';
-import 'observatory_element.dart';
-import 'package:charted/charted.dart';
-import 'package:observatory/app.dart';
-import 'package:observatory/service.dart';
-import 'package:observatory/elements.dart';
-import 'package:polymer/polymer.dart';
-
-class ClassSortedTable extends SortedTable {
-
-  ClassSortedTable(columns) : super(columns);
-
-  @override
-  dynamic getSortKeyFor(int row, int col) {
-    if (col == 0) {
-      // Use class name as sort key.
-      return rows[row].values[col].name;
-    }
-    return super.getSortKeyFor(row, col);
-  }
-}
-
-@CustomTag('heap-profile')
-class HeapProfileElement extends ObservatoryElement {
-  @observable String lastServiceGC = '---';
-  @observable String lastAccumulatorReset = '---';
-
-  // Pie chart of new space usage.
-  var _newPieChart;
-  final _newPieChartRows = [];
-  // Pie chart of old space usage.
-  var _oldPieChart;
-  final _oldPieChartRows = [];
-
-  @observable ClassSortedTable classTable;
-  var _classTableBody;
-
-  @published bool autoRefresh = false;
-  var _subscriptionFuture;
-
-  @published Isolate isolate;
-  @observable ServiceMap profile;
-
-  final _pieChartColumns = [
-      new ChartColumnSpec(label: 'Type', type: ChartColumnSpec.TYPE_STRING),
-      new ChartColumnSpec(label: 'Size', formatter: (v) => v.toString())
-  ];
-
-  HeapProfileElement.created() : super.created() {
-    _initPieChartData(_newPieChartRows);
-    _initPieChartData(_oldPieChartRows);
-
-    // Create class table model.
-    var columns = [
-      new SortedTableColumn('Class'),
-      new SortedTableColumn(''),  // Spacer column.
-      new SortedTableColumn.withFormatter('Accumulated Size (New)',
-                                          Utils.formatSize),
-      new SortedTableColumn.withFormatter('Accumulated Instances',
-                                          Utils.formatCommaSeparated),
-      new SortedTableColumn.withFormatter('Current Size',
-                                          Utils.formatSize),
-      new SortedTableColumn.withFormatter('Current Instances',
-                                          Utils.formatCommaSeparated),
-      new SortedTableColumn(''),  // Spacer column.
-      new SortedTableColumn.withFormatter('Accumulator Size (Old)',
-                                          Utils.formatSize),
-      new SortedTableColumn.withFormatter('Accumulator Instances',
-                                          Utils.formatCommaSeparated),
-      new SortedTableColumn.withFormatter('Current Size',
-                                          Utils.formatSize),
-      new SortedTableColumn.withFormatter('Current Instances',
-                                          Utils.formatCommaSeparated)
-    ];
-    classTable = new ClassSortedTable(columns);
-    // By default, start with accumulated new space bytes.
-    classTable.sortColumnIndex = 2;
-  }
-
-  LayoutArea _makePieChart(String id, List rows) {
-    var wrapper = shadowRoot.querySelector(id);
-    var areaHost = wrapper.querySelector('.chart-host');
-    assert(areaHost != null);
-    var legendHost = wrapper.querySelector('.chart-legend-host');
-    assert(legendHost != null);
-    var series = new ChartSeries(id, [1], new PieChartRenderer(
-      sortDataByValue: false
-    ));
-    var config = new ChartConfig([series], [0]);
-    config.minimumSize = new Rect(300, 300);
-    config.legend = new ChartLegend(legendHost, showValues: true);
-    var data = new ChartData(_pieChartColumns, rows);
-    var area = new LayoutArea(areaHost,
-                              data,
-                              config,
-                              state: new ChartState(),
-                              autoUpdate: false);
-    area.addChartBehavior(new Hovercard());
-    area.addChartBehavior(new AxisLabelTooltip());
-    return area;
-  }
-
-  @override
-  void attached() {
-    super.attached();
-    _newPieChart = _makePieChart('#new-pie-chart', _newPieChartRows);
-    _oldPieChart = _makePieChart('#old-pie-chart', _oldPieChartRows);
-    _classTableBody = shadowRoot.querySelector('#classTableBody');
-    _subscriptionFuture =
-        app.vm.listenEventStream(VM.kGCStream, _onEvent);
-  }
-
-  @override
-  void detached() {
-    cancelFutureSubscription(_subscriptionFuture);
-    _subscriptionFuture = null;
-    super.detached();
-  }
-
-  // Keep at most one outstanding auto-refresh RPC.
-  bool refreshAutoPending = false;
-  bool refreshAutoQueued = false;
-
-  void _onEvent(ServiceEvent event) {
-    assert(event.kind == 'GC');
-    if (autoRefresh) {
-      if (!refreshAutoPending) {
-        refreshAuto();
-      } else {
-        // Remember to refresh once more, to ensure latest profile.
-        refreshAutoQueued = true;
-      }
-    }
-  }
-
-  void refreshAuto() {
-    refreshAutoPending = true;
-    refreshAutoQueued = false;
-    refresh().then((_) {
-      refreshAutoPending = false;
-      // Keep refreshing if at least one GC event was received while waiting.
-      if (refreshAutoQueued) {
-        refreshAuto();
-      }
-    }).catchError(app.handleException);
-  }
-
-  static const _USED_INDEX = 0;
-  static const _FREE_INDEX = 1;
-  static const _EXTERNAL_INDEX = 2;
-
-  static const _VALUE_INDEX = 1;
-
-  void _initPieChartData(List rows) {
-    rows.add(['Used', 0]);
-    rows.add(['Free', 0]);
-    rows.add(['External', 0]);
-  }
-
-  void _updatePieChartData(List rows, HeapSpace space) {
-    rows[_USED_INDEX][_VALUE_INDEX] = space.used;
-    rows[_FREE_INDEX][_VALUE_INDEX] = space.capacity - space.used;
-    rows[_EXTERNAL_INDEX][_VALUE_INDEX] = space.external;
-  }
-
-  void _updatePieCharts() {
-    assert(profile != null);
-    _updatePieChartData(_newPieChartRows, isolate.newSpace);
-    _updatePieChartData(_oldPieChartRows, isolate.oldSpace);
-  }
-
-  void _updateClasses() {
-    for (ServiceMap clsAllocations in profile['members']) {
-      Class cls = clsAllocations['class'];
-      if (cls == null) {
-        continue;
-      }
-      cls.newSpace.update(clsAllocations['new']);
-      cls.oldSpace.update(clsAllocations['old']);
-    }
-  }
-
-  void _updateClassTable() {
-    classTable.clearRows();
-    for (ServiceMap clsAllocations in profile['members']) {
-      Class cls = clsAllocations['class'];
-      if (cls == null) {
-        continue;
-      }
-      if (cls.hasNoAllocations) {
-        // If a class has no allocations, don't display it.
-        continue;
-      }
-      var row = [cls,
-                 '',  // Spacer column.
-                 cls.newSpace.accumulated.bytes,
-                 cls.newSpace.accumulated.instances,
-                 cls.newSpace.current.bytes,
-                 cls.newSpace.current.instances,
-                 '', // Spacer column.
-                 cls.oldSpace.accumulated.bytes,
-                 cls.oldSpace.accumulated.instances,
-                 cls.oldSpace.current.bytes,
-                 cls.oldSpace.current.instances];
-      classTable.addRow(new SortedTableRow(row));
-    }
-    classTable.sort();
-  }
-
-  void _addClassTableDomRow() {
-    assert(_classTableBody != null);
-    var tr = new TableRowElement();
-
-    // Add class ref.
-    var cell = tr.insertCell(-1);
-    ClassRefElement classRef = new Element.tag('class-ref');
-    cell.children.add(classRef);
-
-    // Add spacer.
-    cell = tr.insertCell(-1);
-    cell.classes.add('left-border-spacer');
-
-    // Add new space.
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-
-    // Add spacer.
-    cell = tr.insertCell(-1);
-    cell.classes.add('left-border-spacer');
-
-    // Add old space.
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-
-    // Add row to table.
-    _classTableBody.children.add(tr);
-  }
-
-  void _fillClassTableDomRow(TableRowElement tr, int rowIndex) {
-    const SPACER_COLUMNS = const [1, 6];
-
-    var row = classTable.rows[rowIndex];
-    // Add class ref.
-    ClassRefElement classRef = tr.children[0].children[0];
-    classRef.ref = row.values[0];
-
-    for (var i = 1; i < row.values.length; i++) {
-      if (SPACER_COLUMNS.contains(i)) {
-        // Skip spacer columns.
-        continue;
-      }
-      var cell = tr.children[i];
-      cell.title = row.values[i].toString();
-      cell.text = classTable.getFormattedValue(rowIndex, i);
-      if (i > 1) {  // Numbers.
-        cell.style.textAlign = 'right';
-        cell.style.paddingLeft = '1em';
-      }
-    }
-  }
-
-  void _updateClassTableInDom() {
-    assert(_classTableBody != null);
-    // Resize DOM table.
-    if (_classTableBody.children.length > classTable.sortedRows.length) {
-      // Shrink the table.
-      var deadRows =
-          _classTableBody.children.length - classTable.sortedRows.length;
-      for (var i = 0; i < deadRows; i++) {
-        _classTableBody.children.removeLast();
-      }
-    } else if (_classTableBody.children.length < classTable.sortedRows.length) {
-      // Grow table.
-      var newRows =
-          classTable.sortedRows.length - _classTableBody.children.length;
-      for (var i = 0; i < newRows; i++) {
-        _addClassTableDomRow();
-      }
-    }
-    assert(_classTableBody.children.length == classTable.sortedRows.length);
-    // Fill table.
-    for (var i = 0; i < classTable.sortedRows.length; i++) {
-      var rowIndex = classTable.sortedRows[i];
-      var tr = _classTableBody.children[i];
-      _fillClassTableDomRow(tr, rowIndex);
-    }
-  }
-
-  void _drawCharts() {
-    _newPieChart.draw();
-    _oldPieChart.draw();
-  }
-
-  @observable void changeSort(Event e, var detail, Element target) {
-    if (target is TableCellElement) {
-      if (classTable.sortColumnIndex != target.cellIndex) {
-        classTable.sortColumnIndex = target.cellIndex;
-        classTable.sortDescending = true;
-      } else {
-        classTable.sortDescending = !classTable.sortDescending;
-      }
-      classTable.sort();
-      _updateClassTableInDom();
-    }
-  }
-
-  void isolateChanged(oldValue) {
-    if (isolate == null) {
-      profile = null;
-      return;
-    }
-    isolate.invokeRpc('_getAllocationProfile', {})
-      .then(_update)
-      .catchError(app.handleException);
-  }
-
-  Future refresh() {
-    if (isolate == null) {
-      return new Future.value(null);
-    }
-    return isolate.invokeRpc('_getAllocationProfile', {})
-        .then(_update);
-  }
-
-  Future refreshGC() {
-    if (isolate == null) {
-      return new Future.value(null);
-    }
-    return isolate.invokeRpc('_getAllocationProfile', { 'gc': 'full' })
-        .then(_update);
-  }
-
-  Future resetAccumulator() {
-    if (isolate == null) {
-      return new Future.value(null);
-    }
-    return isolate.invokeRpc('_getAllocationProfile', { 'reset': 'true' })
-        .then(_update);
-  }
-
-  void _update(ServiceMap newProfile) {
-    profile = newProfile;
-  }
-
-  void profileChanged(oldValue) {
-    if (profile == null) {
-      return;
-    }
-    isolate.updateHeapsFromMap(profile['heaps']);
-    var millis = int.parse(profile['dateLastAccumulatorReset']);
-    if (millis != 0) {
-      lastAccumulatorReset =
-              new DateTime.fromMillisecondsSinceEpoch(millis).toString();
-    }
-    millis = int.parse(profile['dateLastServiceGC']);
-    if (millis != 0) {
-      lastServiceGC =
-              new DateTime.fromMillisecondsSinceEpoch(millis).toString();
-    }
-    _updatePieCharts();
-    _updateClasses();
-    _updateClassTable();
-    _updateClassTableInDom();
-    _drawCharts();
-    notifyPropertyChange(#formattedAverage, 0, 1);
-    notifyPropertyChange(#formattedTotalCollectionTime, 0, 1);
-    notifyPropertyChange(#formattedCollections, 0, 1);
-  }
-
-  @observable String formattedAverage(bool newSpace) {
-    if (profile == null) {
-      return '';
-    }
-    var heap = newSpace ? isolate.newSpace : isolate.oldSpace;
-    var avg = ((heap.totalCollectionTimeInSeconds * 1000.0) / heap.collections);
-    return '${avg.toStringAsFixed(2)} ms';
-  }
-
-  @observable String formattedCollections(bool newSpace) {
-    if (profile == null) {
-      return '';
-    }
-    var heap = newSpace ? isolate.newSpace : isolate.oldSpace;
-    return heap.collections.toString();
-  }
-
-  @observable String formattedTotalCollectionTime(bool newSpace) {
-    if (profile == null) {
-      return '';
-    }
-    var heap = newSpace ? isolate.newSpace : isolate.oldSpace;
-    return '${Utils.formatSeconds(heap.totalCollectionTimeInSeconds)} secs';
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/heap_profile.html b/runtime/observatory/lib/src/elements/heap_profile.html
deleted file mode 100644
index 5e05d55..0000000
--- a/runtime/observatory/lib/src/elements/heap_profile.html
+++ /dev/null
@@ -1,212 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="view_footer.html">
-
-<polymer-element name="heap-profile" extends="observatory-element">
-<template>
-  <link rel="stylesheet" href="css/shared.css">
-  <style>
-    .table {
-      border-collapse: collapse!important;
-      margin-bottom: 20px
-      table-layout: fixed;
-    }
-    .table td:nth-of-type(1) {
-      width: 30%;
-    }
-    .th, .td {
-      padding: 8px;
-      vertical-align: top;
-    }
-    .table thead > tr > th {
-      vertical-align: bottom;
-      text-align: left;
-      border-bottom:2px solid #ddd;
-    }
-    .spacer {
-      width: 16px;
-    }
-    .left-border-spacer {
-      width: 16px;
-      border-left: 1px solid;
-    }
-    .clickable {
-      color: #0489c3;
-      text-decoration: none;
-      cursor: pointer;
-    }
-    .clickable:hover {
-      text-decoration: underline;
-      cursor: pointer;
-    }
-    #classtable tr:hover > td {
-      background-color: #F4C7C3;
-    }
-    .nav-option {
-      color: white;
-      float: right;
-      margin: 3px;
-      padding: 8px;
-    }
-  </style>
-  <link rel="stylesheet" href="../../../../packages/charted/charts/themes/quantum_theme.css">
-  <style>
-.chart-wrapper {
-}
-
-.chart-host-wrapper {
-height: 200px;
-}
-.chart-legend-host {
-max-height: 200px;
-overflow-x: auto;
-overflow-y: auto;
-}
-  </style>
-  <nav-bar>
-    <top-nav-menu></top-nav-menu>
-    <vm-nav-menu vm="{{ profile.isolate.vm }}"></vm-nav-menu>
-    <isolate-nav-menu isolate="{{ profile.isolate }}"></isolate-nav-menu>
-    <nav-menu link="{{ makeLink('/allocation-profiler', profile.isolate) }}" anchor="allocation profile" last="{{ true }}"></nav-menu>
-    <nav-refresh callback="{{ resetAccumulator }}" label="Reset Accumulator"></nav-refresh>
-    <nav-refresh callback="{{ refreshGC }}" label="GC"></nav-refresh>
-    <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    <div class="nav-option">
-      <input type="checkbox" checked="{{ autoRefresh }}">Auto-refresh on GC
-    </div>
-  </nav-bar>
-  <div class="content">
-    <h1>Allocation Profile</h1>
-    <br>
-    <div class="memberList">
-      <div class="memberItem">
-        <div class="memberName">last forced GC at</div>
-        <div class="memberValue">{{ lastServiceGC }}</div>
-      </div>
-      <div class="memberItem">
-        <div class="memberName">last accumulator reset at</div>
-        <div class="memberValue">{{ lastAccumulatorReset }}</div>
-      </div>
-    </div>
-  </div>
-  <hr>
-  <div class="content-centered-big">
-    <div class="flex-row">
-      <div id="newSpace" class="flex-item-50-percent">
-        <h2>New Generation</h2>
-        <br>
-        <div class="memberList">
-          <div class="memberItem">
-            <div class="memberName">used</div>
-            <div class="memberValue">
-              {{ isolate.newSpace.used | formatSize }}
-              of
-              {{ isolate.newSpace.capacity | formatSize }}
-            </div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">external</div>
-            <div class="memberValue">
-              {{ isolate.newSpace.external | formatSize }}
-            </div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">collections</div>
-            <div class="memberValue">{{ formattedCollections(true) }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">average collection time</div>
-            <div class="memberValue">{{ formattedAverage(true) }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">cumulative collection time</div>
-            <div class="memberValue">{{ formattedTotalCollectionTime(true) }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">average time between collections</div>
-            <div class="memberValue">{{ isolate.newSpace.averageCollectionPeriodInMillis.toStringAsFixed(2) }} ms</div>
-          </div>
-        </div>
-        <br>
-        <div class="chart-wrapper" id="new-pie-chart">
-          <div class="chart-host-wrapper">
-              <div class="chart-legend-host"></div>
-              <div class="chart-host"></div>
-          </div>
-        </div>
-      </div>
-      <div id="oldSpace" class="flex-item-50-percent">
-        <h2>Old Generation</h2>
-        <br>
-        <div class="memberList">
-          <div class="memberItem">
-            <div class="memberName">used</div>
-            <div class="memberValue">
-              {{ isolate.oldSpace.used | formatSize }}
-              of
-              {{ isolate.oldSpace.capacity | formatSize }}
-            </div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">external</div>
-            <div class="memberValue">
-              {{ isolate.oldSpace.external | formatSize }}
-            </div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">collections</div>
-            <div class="memberValue">{{ formattedCollections(false) }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">average collection time</div>
-            <div class="memberValue">{{ formattedAverage(false) }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">cumulative collection time</div>
-            <div class="memberValue">{{ formattedTotalCollectionTime(false) }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">average time between collections</div>
-            <div class="memberValue">{{ isolate.oldSpace.averageCollectionPeriodInMillis.toStringAsFixed(2) }} ms</div>
-          </div>
-        </div>
-        <br>
-        <div class="chart-wrapper" id="old-pie-chart">
-          <div class="chart-host-wrapper">
-              <div class="chart-host"></div>
-              <div class="chart-legend-host"></div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-  <br>
-  <hr>
-  <div class="content-centered-big">
-    <table id="classtable" class="flex-item-100-percent table">
-      <thead id="classTableHead">
-        <tr>
-          <th on-click="{{changeSort}}" class="clickable" title="Class">{{ classTable.getColumnLabel(0) }}</th>
-          <th class="spacer"></th>
-          <th on-click="{{changeSort}}" class="clickable" title="New Accumulated Size">{{ classTable.getColumnLabel(2) }}</th>
-          <th on-click="{{changeSort}}" class="clickable" title="New Accumulated Instances">{{ classTable.getColumnLabel(3) }}</th>
-          <th on-click="{{changeSort}}" class="clickable" title="New Current Size">{{ classTable.getColumnLabel(4) }}</th>
-          <th on-click="{{changeSort}}" class="clickable" title="New Current Instances">{{ classTable.getColumnLabel(5) }}</th>
-          <th class="spacer"></th>
-          <th on-click="{{changeSort}}" class="clickable" title="Old Accumulated Size">{{ classTable.getColumnLabel(7) }}</th>
-          <th on-click="{{changeSort}}" class="clickable" title="Old Accumulated Instances">{{ classTable.getColumnLabel(8) }}</th>
-          <th on-click="{{changeSort}}" class="clickable" title="Old Current Size">{{ classTable.getColumnLabel(9) }}</th>
-          <th on-click="{{changeSort}}" class="clickable" title="Old Current Instances">{{ classTable.getColumnLabel(10) }}</th>
-        </tr>
-      </thead>
-      <tbody id="classTableBody">
-      </tbody>
-    </table>
-    <view-footer></view-footer>
-  </div>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="heap_profile.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 4894e9f..fbfb9eb 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:html';
+import 'class_ref_wrapper.dart';
 import 'observatory_element.dart';
 import 'package:observatory/app.dart';
 import 'package:observatory/service.dart';
@@ -162,7 +163,7 @@
     gap.style.display = 'inline-block';
     firstColumn.children.add(gap);
 
-    ClassRefElement classRef = new Element.tag("class-ref");
+    ClassRefElementWrapper classRef = new Element.tag("class-ref");
     classRef.ref = isolate.getClassByCid(vertex.cid);
     classRef.style.alignSelf = 'center';
     firstColumn.children.add(classRef);
@@ -296,7 +297,7 @@
       rootName.text = '<root>';
       firstColumn.children.add(rootName);
     } else {
-      ClassRefElement classRef = new Element.tag("class-ref");
+      ClassRefElementWrapper classRef = new Element.tag("class-ref");
       classRef.ref = isolate.getClassByCid(v.cid);
       classRef.style.alignSelf = 'center';
       firstColumn.children.add(classRef);
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.html b/runtime/observatory/lib/src/elements/heap_snapshot.html
index d593f97..46e73d5 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.html
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.html
@@ -1,10 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="heap-snapshot" extends="observatory-element">
+<polymer-element name="heap-snapshot">
 <template>
   <link rel="stylesheet" href="css/shared.css">
   <nav-bar>
@@ -13,6 +9,7 @@
     <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
     <nav-menu link="{{ makeLink('/heap-snapshot', isolate) }}" anchor="heap snapshot" last="{{ true }}"></nav-menu>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <nav-notify notifications="{{ app.notifications }}"></nav-notify>
   </nav-bar>
   <style>
       /* general */
diff --git a/runtime/observatory/lib/src/elements/helpers/any_ref.dart b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
new file mode 100644
index 0000000..d59018f
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/code_ref.dart';
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/error_ref.dart';
+import 'package:observatory/src/elements/field_ref.dart';
+import 'package:observatory/src/elements/function_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/icdata_ref.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/megamorphiccache_ref.dart';
+import 'package:observatory/src/elements/library_ref.dart';
+import 'package:observatory/src/elements/local_var_descriptors_ref.dart';
+import 'package:observatory/src/elements/objectpool_ref.dart';
+import 'package:observatory/src/elements/pc_descriptors_ref.dart';
+import 'package:observatory/src/elements/script_ref.dart';
+import 'package:observatory/src/elements/sentinel_value.dart';
+import 'package:observatory/src/elements/token_stream_ref.dart';
+import 'package:observatory/src/elements/unknown_ref.dart';
+
+Element anyRef(M.Isolate isolate, ref, M.InstanceRepository instances,
+    {RenderingQueue queue}) {
+  if (ref is M.Guarded) {
+    return anyRef(isolate, ref.asSentinel ?? ref.asValue, instances,
+        queue: queue);
+  } else if (ref is M.ClassRef) {
+    return new ClassRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.CodeRef) {
+    return new CodeRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.ContextRef) {
+    return new ContextRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.Error ) {
+    return new ErrorRefElement(ref, queue: queue);
+  } else if (ref is M.FieldRef) {
+    return new FieldRefElement(isolate, ref, instances, queue: queue);
+  }  else if (ref is M.FunctionRef) {
+    return new FunctionRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.ICDataRef) {
+    return new ICDataRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.InstanceRef) {
+    return new InstanceRefElement(isolate, ref, instances, queue: queue);
+  } else if (ref is M.LibraryRef) {
+    return new LibraryRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.LocalVarDescriptorsRef) {
+    return new LocalVarDescriptorsRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.MegamorphicCacheRef) {
+    return new MegamorphicCacheRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.ObjectPoolRef) {
+    return new ObjectPoolRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.PcDescriptorsRef) {
+    return new PcDescriptorsRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.Sentinel) {
+    return new SentinelValueElement(ref, queue: queue);
+  } else if (ref is M.ScriptRef) {
+    return new ScriptRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.TokenStreamRef) {
+    return new TokenStreamRefElement(isolate, ref, queue: queue);
+  } else if (ref is M.UnknownObjectRef) {
+    return new UnknownObjectRefElement(isolate, ref, queue: queue);
+  } else {
+    return null;
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/helpers/rendering_queue.dart b/runtime/observatory/lib/src/elements/helpers/rendering_queue.dart
new file mode 100644
index 0000000..707de23
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/helpers/rendering_queue.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:collection';
+import 'dart:async';
+
+/// A generic rendering task that can be scheduled.
+abstract class RenderingTask {
+  /// Rendering synchronous callback.
+  void render();
+}
+
+/// A generic synchronization system for rendering operations.
+abstract class RenderingBarrier {
+  /// Future to the next synchronization barrier (ms from application start).
+  Future<num> get next;
+}
+
+/// Synchronization system based on the AnimationFrame.
+class NextAnimationFrameBarrier implements RenderingBarrier {
+  Future<num> get next => window.animationFrame;
+}
+
+/// MOCK synchronization system for manual barrier triggering.
+class RenderingBarrierMock implements RenderingBarrier {
+  final StreamController<num> _stream = new StreamController<num>.broadcast();
+  num _ms = 0;
+
+  Future<num> get next => _stream.stream.first;
+
+  /// Trigger the next barrier with an optional numer of ms elapsed.
+  void triggerRenderingBarrier({num step: 20}) {
+    assert(step != null);
+    _stream.add(_ms += step);
+  }
+}
+
+/// RenderingTask queuing and synchronization system.
+class RenderingQueue {
+  final RenderingBarrier _barrier;
+  final Queue<RenderingTask> _queue = new Queue<RenderingTask>();
+
+  bool get isEmpty => _queue.isEmpty;
+  bool get isNotEmpty => _queue.isNotEmpty;
+
+  /// Creates a RenderingQueue with the default synchronization barrier.
+  RenderingQueue() : this.fromBarrier(new NextAnimationFrameBarrier());
+
+  /// Creates a RenderingQueue with a custom synchronization barrier.
+  RenderingQueue.fromBarrier(this._barrier) {
+    assert(this._barrier != null);
+  }
+
+  /// Add a task to the queue.
+  /// If the current rendering phase is running it will be executed during this
+  /// rendering cycle, otherwise it will be queued for the next one.
+  void enqueue(RenderingTask r) {
+    assert(r != null);
+    // If no task are in the queue there is no rendering phase scheduled.
+    if (isEmpty) _render();
+    _queue.addLast(r);
+  }
+
+  Future _render() async {
+    await _barrier.next;
+    while (_queue.isNotEmpty) {
+      _queue.first.render();
+      _queue.removeFirst();
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart b/runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart
new file mode 100644
index 0000000..d5ba83d
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/helpers/rendering_scheduler.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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:observatory/src/elements/helpers/rendering_queue.dart';
+export 'package:observatory/src/elements/helpers/rendering_queue.dart';
+
+/// A generic renderable object.
+abstract class Renderable {
+  void render();
+}
+
+/// Event related to a Renderable rendering phase.
+class RenderedEvent<T> {
+  /// Renderable to which the event is related
+  final T element;
+  /// Is another rendering scheduled for this element.
+  final bool otherRenderScheduled;
+
+  RenderedEvent(this.element, this.otherRenderScheduled) {
+    assert(element != null);
+    assert(otherRenderScheduled != null);
+  }
+}
+
+/// Scheduler for rendering operations.
+class RenderingScheduler<T extends Renderable> implements RenderingTask {
+  bool _enabled = false;
+  bool _dirty = false;
+  bool _renderingScheduled = false;
+  bool _notificationScheduled = false;
+  /// Element managed by this scheduler.
+  final T element;
+  /// Queue used for rendering operations.
+  final RenderingQueue queue;
+  /// Does the element need a new rendering cycle.
+  bool get isDirty => _dirty;
+  /// Is the scheduler enabled.
+  bool get isEnabled => _enabled;
+
+  final StreamController<RenderedEvent<T>> _onRendered =
+      new StreamController<RenderedEvent<T>>.broadcast();
+  Stream<RenderedEvent<T>> get onRendered => _onRendered.stream;
+
+  /// Creates a new scheduler for an element.
+  /// If no queue is provided it will create a new default configured queue.
+  factory RenderingScheduler(T element, {RenderingQueue queue}) {
+    assert(element != null);
+    if (queue == null) { queue = new RenderingQueue(); }
+    return new RenderingScheduler<T>._(element, queue);
+  }
+
+  RenderingScheduler._(this.element, this.queue);
+
+  /// Enable the scheduler.
+  /// New dirty or schedule request will be considered.
+  void enable() {
+    if (_enabled) return;
+    _enabled = true;
+    scheduleRendering();
+  }
+
+  /// Disable the scheduler.
+  /// New dirty or schedule request will be discarded.
+  /// [optional] notify: send a final RenderEvent.
+  void disable({bool notify: false}) {
+    assert(notify != null);
+    if (!_enabled) return;
+    _enabled = false;
+    if (notify) scheduleNotification();
+  }
+
+  /// Set the object as dirty. A rendering will be scheduled.
+  void dirty() {
+    if (_dirty) return;
+    _dirty = true;
+    scheduleRendering();
+  }
+
+  /// Checks for modification during attribute set.
+  /// If value changes a new rendering is scheduled.
+  /// set attr(T v) => _attr = _r.checkAndReact(_attr, v);
+  dynamic checkAndReact(dynamic oldValue, dynamic newValue) {
+    if (oldValue != newValue) dirty();
+    else scheduleNotification();
+    return newValue;
+  }
+
+  /// Schedules a new rendering phase.
+  void scheduleRendering() {
+    if (_renderingScheduled) return;
+    if (!_enabled) return;
+    queue.enqueue(this);
+    _renderingScheduled = true;
+  }
+
+  /// Renders the element (if the scheduler is enabled).
+  /// It will clear the dirty flag.
+  void render() {
+    if (!_enabled) return;
+    _dirty = false;
+    element.render();
+    _renderingScheduled = false;
+    scheduleNotification();
+    if (_dirty) scheduleRendering();
+  }
+
+  /// Schedules a notification.
+  void scheduleNotification() {
+    if (_notificationScheduled) return;
+    _notify();
+    _notificationScheduled = true;
+  }
+
+  Future _notify() async {
+    _onRendered.add(new RenderedEvent<T>(element, _dirty));
+    _notificationScheduled = false;
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/helpers/tag.dart b/runtime/observatory/lib/src/elements/helpers/tag.dart
new file mode 100644
index 0000000..177e238
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/helpers/tag.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+/// Utility class for Custom Tags registration.
+class Tag<T extends HtmlElement> {
+  /// Tag name.
+  final String name;
+  /// Dependend tags that need to be registred for this tag to work properly.
+  final Iterable<Tag> dependencies;
+
+  const Tag(this.name, {this.dependencies : const []});
+
+  static final Map<Type, String> _tagByClass = <Type, String>{};
+  static final Map<String, Type> _classByTag = <String, Type>{};
+
+  /// Ensures that the Tag and all the dependencies are registered.
+  void ensureRegistration() {
+    if (!_tagByClass.containsKey(T) && !_classByTag.containsKey(name)) {
+      document.registerElement(name, T);
+      _tagByClass[T] = name;
+      _classByTag[name] = T;
+      dependencies.forEach((tag) => tag.ensureRegistration());
+    }
+    var tag = _tagByClass[T];
+    if (tag != name) {
+      throw new ArgumentError('Class $T is already registered to tag ${tag}');
+    }
+    var c = _classByTag[name];
+    if (c != T) {
+      throw new ArgumentError('Tag $name is already registered by class ${c}');
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/helpers/uris.dart b/runtime/observatory/lib/src/elements/helpers/uris.dart
new file mode 100644
index 0000000..b243f78
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/helpers/uris.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:observatory/models.dart' as M;
+
+/// Utility class for URIs generation.
+abstract class Uris {
+  static String _isolatePage(String path, M.IsolateRef isolate,
+      {M.ObjectRef object}) {
+    final parameters = { 'isolateId': isolate.id };
+    if (object != null) parameters['objectId'] = object.id;
+    return '#' + new Uri(path: path, queryParameters: parameters).toString();
+  }
+
+  static String allocationProfiler(M.IsolateRef isolate)
+      => _isolatePage('/allocation-profiler', isolate);
+  static String classTree(M.IsolateRef isolate)
+      => _isolatePage('/class-tree', isolate);
+  static String cpuProfiler(M.IsolateRef isolate)
+      => _isolatePage('/profiler', isolate);
+  static String cpuProfilerTable(M.IsolateRef isolate)
+      => _isolatePage('/profiler-table', isolate);
+  static String debugger(M.IsolateRef isolate)
+      => _isolatePage('/debugger', isolate);
+  static String flags() => '#/flags';
+  static String heapMap(M.IsolateRef isolate)
+      => _isolatePage('/heap-map', isolate);
+  static String heapSnapshot(M.IsolateRef isolate)
+      => _isolatePage('/heap-snapshot', isolate);
+  static String inspect(M.IsolateRef isolate, {M.ObjectRef object, int pos}) {
+    if (pos == null) {
+      return _isolatePage('/inspect', isolate, object: object);
+    }
+    return _isolatePage('/inspect', isolate, object: object) + '---pos=${pos}';
+  }
+  static String logging(M.IsolateRef isolate)
+      => _isolatePage('/logging', isolate);
+  static String metrics(M.IsolateRef isolate)
+      => _isolatePage('/metrics', isolate);
+  static String persistentHandles(M.IsolateRef isolate)
+      => _isolatePage('/persistent-handles', isolate);
+  static String ports(M.IsolateRef isolate)
+      => _isolatePage('/ports', isolate);
+  static String profiler(M.IsolateRef isolate)
+      => _isolatePage('/profiler', isolate);
+  static String vm() => '#/vm';
+  static String vmConnect() => '#/vm-connect';
+}
diff --git a/runtime/observatory/lib/src/elements/icdata_ref.dart b/runtime/observatory/lib/src/elements/icdata_ref.dart
new file mode 100644
index 0000000..10b015a
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/icdata_ref.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, ICDataRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class ICDataRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ICDataRefElement>('icdata-ref');
+
+  RenderingScheduler<ICDataRefElement> _r;
+
+  Stream<RenderedEvent<ICDataRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.ICDataRef _icdata;
+
+  M.IsolateRef get isolate => _isolate;
+  M.ICDataRef get icdata => _icdata;
+
+  factory ICDataRefElement(M.IsolateRef isolate, M.ICDataRef icdata,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(icdata != null);
+    ICDataRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._icdata = icdata;
+    return e;
+  }
+
+  ICDataRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _icdata))
+        ..children = [
+          new SpanElement()..classes = ['emphatize']
+            ..text = 'ICData',
+          new SpanElement()..text = ' (${_icdata.selector})'
+        ]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/icdata_view.html b/runtime/observatory/lib/src/elements/icdata_view.html
index d31f14f..60f5b6e 100644
--- a/runtime/observatory/lib/src/elements/icdata_view.html
+++ b/runtime/observatory/lib/src/elements/icdata_view.html
@@ -1,16 +1,10 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
 <link rel="import" href="error_view.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="inbound_reference.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="object_common.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="eval_link.html">
 
-<polymer-element name="icdata-view" extends="observatory-element">
+<polymer-element name="icdata-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -19,6 +13,7 @@
       <isolate-nav-menu isolate="{{ icData.isolate }}"></isolate-nav-menu>
       <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
@@ -29,7 +24,7 @@
       <div class="memberList">
         <div class="memberItem">
           <div class="memberName">selector</div>
-          <div class="memberValue"> 
+          <div class="memberValue">
             {{ icData.selector }}
           </div>
         </div>
@@ -54,7 +49,7 @@
       </div>
 
     </div>
-  
+
     <hr>
     <view-footer></view-footer>
   </template>
diff --git a/runtime/observatory/lib/src/elements/inbound_reference.html b/runtime/observatory/lib/src/elements/inbound_reference.html
index 4ca13c3..2c3ce90 100644
--- a/runtime/observatory/lib/src/elements/inbound_reference.html
+++ b/runtime/observatory/lib/src/elements/inbound_reference.html
@@ -1,10 +1,7 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="curly_block.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="service_ref.html">
 
-<polymer-element name="inbound-reference" extends="service-ref">
+<polymer-element name="inbound-reference">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <div>
diff --git a/runtime/observatory/lib/src/elements/instance_ref.dart b/runtime/observatory/lib/src/elements/instance_ref.dart
index cbf5eae..861aede 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.dart
+++ b/runtime/observatory/lib/src/elements/instance_ref.dart
@@ -2,72 +2,341 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library instance_ref_element;
-
+import 'dart:html';
 import 'dart:async';
-import 'package:polymer/polymer.dart';
-import 'package:observatory/service.dart';
-import 'service_ref.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/field_ref.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/sentinel_value.dart';
 
-@CustomTag('instance-ref')
-class InstanceRefElement extends ServiceRefElement {
+class InstanceRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<InstanceRefElement>('instance-ref-wrapped');
+
+  RenderingScheduler<InstanceRefElement> _r;
+
+  Stream<RenderedEvent<InstanceRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.InstanceRef _instance;
+  M.InstanceRepository _instances;
+  M.Instance _loadedInstance;
+  bool _expanded = false;
+
+  M.IsolateRef get isolate => _isolate;
+  M.InstanceRef get instance => _instance;
+
+  factory InstanceRefElement(M.IsolateRef isolate, M.InstanceRef instance,
+      M.InstanceRepository instances, {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(instance != null);
+    assert(instances != null);
+    InstanceRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._instance = instance;
+    e._instances = instances;
+    return e;
+  }
+
   InstanceRefElement.created() : super.created();
 
-  String get hoverText {
-    if (ref != null) {
-      if (ref.type == 'Sentinel') {
-        if (ref.id == 'objects/optimized-out') {
-          return 'This object is no longer needed and has been removed by the optimizing compiler.';
-        } else if (ref.id == 'objects/collected') {
-          return 'This object has been reclaimed by the garbage collector.';
-        } else if (ref.id == 'objects/expired') {
-          return 'The handle to this object has expired.  Consider refreshing the page.';
-        } else if (ref.id == 'objects/not-initialized') {
-          return 'This object will be initialized once it is accessed by the program.';
-        } else if (ref.id == 'objects/being-initialized') {
-          return 'This object is currently being initialized.';
-        }
-      }
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    final content = _createLink();
+
+    if (_hasValue()) {
+      content.addAll([
+        new SpanElement()..text = ' ',
+        new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
+          ..children = [
+            new DivElement()..classes = ['indent']
+              ..children = _createValue()
+          ]
+          ..onToggle.listen((e) async {
+            _expanded = e.control.expanded;
+            if (_expanded) {
+              e.control.disabled = true;
+              await _refresh();
+              e.control.disabled = false;
+            }
+          })
+      ]);
     }
-    return super.hoverText;
+
+    children = content;
   }
 
-  // TODO(turnidge): This is here to workaround vm/dart2js differences.
-  dynamic expander() {
-    return expandEvent;
+  Future _refresh() async {
+    _loadedInstance = await _instances.get(_instance.id);
+    _r.dirty();
   }
 
-  void expandEvent(bool expand, Function onDone) {
-    assert(ref is Instance);
-    if (expand) {
-      ref.reload().then((result) {
-        if (result.valueAsString != null) {
-          result.name = result.valueAsString;
-          result.vmName = result.valueAsString;
-        }
-        ref = result;
-        notifyPropertyChange(#ref, 0, 1);
-      }).whenComplete(onDone);
+  List<Element> _createShowMoreButton() {
+    if (_loadedInstance.count == null) {
+      return [];
+    }
+    final count = _loadedInstance.count;
+    final button = new ButtonElement()
+      ..text = 'show next ${count}';
+    button.onClick.listen((_) async {
+      button.disabled = true;
+      _loadedInstance = await _instances.get(_instance.id, count: count * 2);
+      _r.dirty();
+    });
+    return [button];
+  }
+
+  List<Element> _createLink() {
+    switch (_instance.kind) {
+      case M.InstanceKind.vNull:
+      case M.InstanceKind.bool:
+      case M.InstanceKind.int:
+      case M.InstanceKind.double:
+      case M.InstanceKind.float32x4:
+      case M.InstanceKind.float64x2:
+      case M.InstanceKind.int32x4:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..text = _instance.valueAsString
+        ];
+      case M.InstanceKind.string:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..text = asStringLiteral(_instance.valueAsString,
+                _instance.valueAsStringIsTruncated)
+        ];
+      case M.InstanceKind.type:
+      case M.InstanceKind.typeRef:
+      case M.InstanceKind.typeParameter:
+      case M.InstanceKind.boundedType:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..text = _instance.name
+        ];
+      case M.InstanceKind.closure:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..children = [
+              new SpanElement()..classes = ['empathize']..text = 'Closure',
+              new SpanElement()..text = _instance.closureFunction.name
+            ]
+        ];
+      case M.InstanceKind.regExp:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..children = [
+              new SpanElement()..classes = ['empathize']
+                ..text = _instance.clazz.name,
+              new SpanElement()..text = _instance.pattern.name
+            ]
+        ];
+      case M.InstanceKind.stackTrace:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..text = _instance.clazz.name,
+          new CurlyBlockElement(queue: _r.queue)
+            ..children = [
+              new DivElement()..classes = ['stackTraceBox']
+                ..text = _instance.valueAsString
+            ]
+        ];
+      case M.InstanceKind.plainInstance:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..classes = ['empathize']
+            ..text = _instance.clazz.name
+        ];
+      case M.InstanceKind.list:
+      case M.InstanceKind.map:
+      case M.InstanceKind.uint8ClampedList:
+      case M.InstanceKind.uint8List:
+      case M.InstanceKind.uint16List:
+      case M.InstanceKind.uint32List:
+      case M.InstanceKind.uint64List:
+      case M.InstanceKind.int8List:
+      case M.InstanceKind.int16List:
+      case M.InstanceKind.int32List:
+      case M.InstanceKind.int64List:
+      case M.InstanceKind.float32List:
+      case M.InstanceKind.float64List:
+      case M.InstanceKind.int32x4List:
+      case M.InstanceKind.float32x4List:
+      case M.InstanceKind.float64x2List:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..children = [
+              new SpanElement()..classes = ['empathize']
+                ..text = _instance.clazz.name,
+              new SpanElement()..text = ' (${_instance.length})'
+            ]
+        ];
+      case M.InstanceKind.mirrorReference:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..classes = ['empathize']
+            ..text = _instance.clazz.name
+        ];
+      case M.InstanceKind.weakProperty:
+        return [
+          new AnchorElement(href: Uris.inspect(_isolate, object: _instance))
+            ..classes = ['empathize']
+            ..text = _instance.clazz.name
+        ];
+    }
+    throw new Exception('Unkown InstanceKind: ${_instance.kind}');
+  }
+
+  bool _hasValue() {
+    switch (_instance.kind) {
+      case M.InstanceKind.plainInstance:
+      case M.InstanceKind.mirrorReference:
+      case M.InstanceKind.weakProperty:
+        return true;
+      case M.InstanceKind.list:
+      case M.InstanceKind.map:
+      case M.InstanceKind.uint8ClampedList:
+      case M.InstanceKind.uint8List:
+      case M.InstanceKind.uint16List:
+      case M.InstanceKind.uint32List:
+      case M.InstanceKind.uint64List:
+      case M.InstanceKind.int8List:
+      case M.InstanceKind.int16List:
+      case M.InstanceKind.int32List:
+      case M.InstanceKind.int64List:
+      case M.InstanceKind.float32List:
+      case M.InstanceKind.float64List:
+      case M.InstanceKind.int32x4List:
+      case M.InstanceKind.float32x4List:
+      case M.InstanceKind.float64x2List:
+        return _instance.length > 0;
+      default:
+        return false;
+    }
+  }
+  List<Element> _createValue() {
+    if (_loadedInstance == null) {
+      return [new SpanElement()..text = 'Loading...'];
+    }
+    switch (_instance.kind) {
+      case M.InstanceKind.plainInstance:
+        return _loadedInstance.fields.map((f) =>
+          new DivElement()
+            ..children = [
+              new FieldRefElement(_isolate, f.decl, _instances,
+                  queue: _r.queue),
+              new SpanElement()..text = ' = ',
+              f.value.isSentinel
+                ? new SentinelValueElement(f.value.asSentinel, queue: _r.queue)
+                : new InstanceRefElement(_isolate, f.value.asValue, _instances,
+                    queue: _r.queue)
+            ]).toList();
+      case M.InstanceKind.list:
+        var index = 0;
+        return _loadedInstance.elements.map((e) =>
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = '[ ${index++} ] : ',
+              e.isSentinel
+                ? new SentinelValueElement(e.asSentinel, queue: _r.queue)
+                : anyRef(_isolate, e.asValue, _instances, queue: _r.queue)
+                // should be:
+                // new InstanceRefElement(_isolate, e.asValue, _instances,
+                //                        queue: _r.queue)
+                // in some situations we obtain values that are not InstanceRef.
+            ]).toList()..addAll(_createShowMoreButton());
+      case M.InstanceKind.map:
+        return _loadedInstance.associations.map((a) =>
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = '[ ',
+              a.key.isSentinel
+                ? new SentinelValueElement(a.key.asSentinel, queue: _r.queue)
+                : new InstanceRefElement(_isolate, a.key.asValue, _instances,
+                    queue: _r.queue),
+              new SpanElement()..text = ' ] : ',
+              a.value.isSentinel
+                ? new SentinelValueElement(a.value.asSentinel, queue: _r.queue)
+                : new InstanceRefElement(_isolate, a.value.asValue, _instances,
+                    queue: _r.queue)
+            ]).toList()..addAll(_createShowMoreButton());
+      case M.InstanceKind.uint8ClampedList:
+      case M.InstanceKind.uint8List:
+      case M.InstanceKind.uint16List:
+      case M.InstanceKind.uint32List:
+      case M.InstanceKind.uint64List:
+      case M.InstanceKind.int8List:
+      case M.InstanceKind.int16List:
+      case M.InstanceKind.int32List:
+      case M.InstanceKind.int64List:
+      case M.InstanceKind.float32List:
+      case M.InstanceKind.float64List:
+      case M.InstanceKind.int32x4List:
+      case M.InstanceKind.float32x4List:
+      case M.InstanceKind.float64x2List:
+        var index = 0;
+        return _loadedInstance.typedElements
+          .map((e) => new DivElement()..text = '[ ${index++} ] : $e')
+          .toList()..addAll(_createShowMoreButton());
+      case M.InstanceKind.mirrorReference:
+        return [
+          new SpanElement()..text = '<referent> : ',
+          new InstanceRefElement(_isolate, _loadedInstance.referent, _instances,
+              queue: _r.queue)
+        ];
+      case M.InstanceKind.weakProperty:
+        return [
+          new SpanElement()..text = '<key> : ',
+          new InstanceRefElement(_isolate, _loadedInstance.key, _instances,
+              queue: _r.queue),
+          new BRElement(),
+          new SpanElement()..text = '<value> : ',
+          new InstanceRefElement(_isolate, _loadedInstance.value, _instances,
+            queue: _r.queue),
+        ];
+      default:
+        return [];
+    }
+  }
+
+  static String asStringLiteral(String value, [bool wasTruncated=false]) {
+    var result = new List();
+    result.add("'".codeUnitAt(0));
+    for (int codeUnit in value.codeUnits) {
+      if (codeUnit == '\n'.codeUnitAt(0)) result.addAll('\\n'.codeUnits);
+      else if (codeUnit == '\r'.codeUnitAt(0)) result.addAll('\\r'.codeUnits);
+      else if (codeUnit == '\f'.codeUnitAt(0)) result.addAll('\\f'.codeUnits);
+      else if (codeUnit == '\b'.codeUnitAt(0)) result.addAll('\\b'.codeUnits);
+      else if (codeUnit == '\t'.codeUnitAt(0)) result.addAll('\\t'.codeUnits);
+      else if (codeUnit == '\v'.codeUnitAt(0)) result.addAll('\\v'.codeUnits);
+      else if (codeUnit == '\$'.codeUnitAt(0)) result.addAll('\\\$'.codeUnits);
+      else if (codeUnit == '\\'.codeUnitAt(0)) result.addAll('\\\\'.codeUnits);
+      else if (codeUnit == "'".codeUnitAt(0)) result.addAll("'".codeUnits);
+      else if (codeUnit < 32) {
+         var escapeSequence = "\\u" + codeUnit.toRadixString(16).padLeft(4, "0");
+         result.addAll(escapeSequence.codeUnits);
+      } else result.add(codeUnit);
+    }
+    if (wasTruncated) {
+      result.addAll("...".codeUnits);
     } else {
-      Instance refMap = ref;
-      refMap.fields = null;
-      refMap.elements = null;
-      onDone();
+      result.add("'".codeUnitAt(0));
     }
-  }
-
-  String makeExpandKey(String key) {
-    return '${expandKey}/${key}';
-  }
-
-  Future showMore() async {
-    Instance instance = ref;
-    if (instance.isList) {
-      await instance.reload(count: instance.elements.length * 2);
-    } else if (instance.isMap) {
-      await instance.reload(count: instance.associations.length * 2);
-    } else if (instance.isTypedData) {
-      await instance.reload(count: instance.typedElements.length * 2);
-    }
+    return new String.fromCharCodes(result);
   }
 }
diff --git a/runtime/observatory/lib/src/elements/instance_ref.html b/runtime/observatory/lib/src/elements/instance_ref.html
deleted file mode 100644
index 311732b..0000000
--- a/runtime/observatory/lib/src/elements/instance_ref.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<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="instance-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-      .indented {
-        margin-left: 1.5em;
-        font: 400 14px 'Montserrat', sans-serif;
-        line-height: 150%;
-      }
-      .stackTraceBox {
-        margin-left: 1.5em;
-        background-color: #f5f5f5;
-        border: 1px solid #ccc;
-        padding: 10px;
-        font-family: consolas, courier, monospace;
-        font-size: 12px;
-        white-space: pre;
-        overflow-x: auto;
-      }
-    </style>
-    <span>
-      <template if="{{ ref.isSentinel }}">
-        <span title="{{ hoverText }}">{{ ref.valueAsString }}</span>
-      </template>
-
-      <template if="{{ ref.isBool || ref.isInt ||
-                       ref.isDouble || ref.isSimdValue ||
-                       ref.isNull }}">
-        <a on-click="{{ goto }}" _href="{{ url }}">{{ ref.valueAsString }}</a>
-      </template>
-
-      <template if="{{ ref.isStackTrace }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em></a>
-        <curly-block expandKey="{{ expandKey }}">
-          <div class="stackTraceBox">{{ ref.valueAsString }}</div>
-        </curly-block>
-      </template>
-
-      <template if="{{ ref.isString }}">
-        <a on-click="{{ goto }}" _href="{{ url }}">{{ asStringLiteral(ref.valueAsString, ref.valueAsStringIsTruncated) }}</a>
-      </template>
-
-
-      <template if="{{ ref.isAbstractType }}">
-        <a on-click="{{ goto }}" _href="{{ url }}">{{ ref.name }}</a>
-      </template>
-
-      <template if="{{ ref.isClosure }}">
-        <a on-click="{{ goto }}" _href="{{ url }}">
-          <em>Closure</em> ({{ ref.function.qualifiedName }})
-        </a>
-      </template>
-
-      <template if="{{ ref.isRegExp }}">
-        <a on-click="{{ goto }}" _href="{{ url }}">
-          <em>{{ ref.clazz.name }}</em> ({{ ref.pattern.valueAsString }})
-        </a>
-      </template>
-
-      <template if="{{ ref.isPlainInstance }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em></a>
-        <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
-          <div class="indented">
-            <template repeat="{{ field in ref.fields }}">
-              {{ field['decl'].name }}&nbsp;:&nbsp;
-              <any-service-ref ref="{{ field['value'] }}"
-                               expandKey="{{ makeExpandKey(field['decl'].name) }}">
-              </any-service-ref><br>
-            </template>
-          </div>
-        </curly-block>
-      </template>
-
-      <template if="{{ ref.isList }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em> ({{ ref.length }})</a>
-        <curly-block callback="{{ expander() }}"
-                     expandKey="{{ expandKey }}">
-          <div class="indented">
-            <template repeat="{{ index in ref.elements.asMap().keys }}">
-              [ {{ index }} ]&nbsp;&nbsp;
-              <any-service-ref ref="{{ ref.elements[index] }}"
-                               expandKey="{{ makeExpandKey(index.toString()) }}">
-              </any-service-ref><br>
-            </template>
-            <template if="{{ ref.length != ref.elements.length }}">
-              <div>
-                <action-link callback="{{ showMore }}"
-                             label="show next {{ref.elements.length}}">
-                </action-link>
-              </div>
-            </template>
-          </div>
-        </curly-block>
-      </template>
-
-      <template if="{{ ref.isMap }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em> ({{ ref.length }})</a>
-        <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
-          <div class="indented">
-            <template repeat="{{ association in ref.associations }}">
-              [ <any-service-ref ref="{{ association['key'] }}"
-                                expandKey="{{ makeExpandKey('key') }}">
-              </any-service-ref> ]&nbsp;&nbsp;
-              <any-service-ref ref="{{ association['value'] }}"
-                                 expandKey="{{ makeExpandKey('value') }}">
-              </any-service-ref><br>
-            </template>
-            <template if="{{ ref.length != ref.associations.length }}">
-              <action-link callback="{{ showMore }}"
-                           label="show next {{ref.associations.length}}">
-              </action-link>
-            </template>
-          </div>
-        </curly-block>
-      </template>
-
-      <template if="{{ ref.isTypedData }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em> ({{ ref.length }})</a>
-        <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
-          <div class="indented">
-            <template repeat="{{ index in ref.typedElements.asMap().keys }}">
-              [ {{ index }} ]&nbsp;&nbsp;
-              {{ ref.typedElements[index].toString() }}<br>
-            </template>
-            <template if="{{ ref.length != ref.typedElements.length }}">
-              <action-link callback="{{ showMore }}"
-                           label="show next {{ref.typedElements.length}}">
-              </action-link>
-            </template>
-          </div>
-        </curly-block>
-      </template>
-
-      <template if="{{ ref.isMirrorReference }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em></a>
-        <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
-          <div class="indented">
-            &lt;referent&gt;&nbsp;:&nbsp;
-            <any-service-ref ref="{{ ref.referent }}"
-                             expandKey="{{ makeExpandKey('referent') }}">
-            </any-service-ref>
-          </div>
-        </curly-block>
-      </template>
-
-      <template if="{{ ref.isWeakProperty }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em></a>
-        <curly-block callback="{{ expander() }}" expandKey="{{ expandKey }}">
-          <div class="indented">
-            &lt;key&gt;&nbsp;:&nbsp;
-            <any-service-ref ref="{{ ref.key }}"
-                             expandKey="{{ makeExpandKey('key') }}">
-            </any-service-ref><br>
-            &lt;value&gt;&nbsp;:&nbsp;
-            <any-service-ref ref="{{ ref.value }}"
-                             expandKey="{{ makeExpandKey('value') }}">
-            </any-service-ref><br>
-          </div>
-        </curly-block>
-      </template>
-    </span>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="instance_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/instance_ref_wrapper.dart b/runtime/observatory/lib/src/elements/instance_ref_wrapper.dart
new file mode 100644
index 0000000..98b37eb
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/instance_ref_wrapper.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show Instance;
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class InstanceRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<InstanceRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<InstanceRefElementWrapper>('instance-ref');
+
+  Instance _instance;
+  Instance get ref => _instance;
+  void set ref(Instance ref) {
+    _instance = ref;
+    render();
+  }
+
+  InstanceRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) return;
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        instance-ref-wrapped a[href]:hover {
+            text-decoration: underline;
+        }
+        instance-ref-wrapped a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }
+        instance-ref-wrapped .empathize {
+          font-style: italic;
+        }
+        instance-ref-wrapped .indent {
+          margin-left: 1.5em;
+          font: 400 14px 'Montserrat', sans-serif;
+          line-height: 150%;
+        }
+        instance-ref-wrapped .stackTraceBox {
+          margin-left: 1.5em;
+          background-color: #f5f5f5;
+          border: 1px solid #ccc;
+          padding: 10px;
+          font-family: consolas, courier, monospace;
+          font-size: 12px;
+          white-space: pre;
+          overflow-x: auto;
+        }''',
+      new InstanceRefElement(_instance.isolate, _instance,
+                             new InstanceRepository(_instance.isolate),
+                             queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index 5e98824..54e5637 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -1,19 +1,11 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
 <link rel="import" href="error_view.html">
 <link rel="import" href="eval_box.html">
 <link rel="import" href="eval_link.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="inbound_reference.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="object_common.html">
-<link rel="import" href="context_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="instance-view" extends="observatory-element">
+<polymer-element name="instance-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -24,6 +16,7 @@
       <class-nav-menu cls="{{ instance.clazz }}"></class-nav-menu>
       <nav-menu link="." anchor="instance" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <template if="{{ instance.isError }}">
@@ -199,10 +192,10 @@
               <template repeat="{{ field in instance.fields }}">
                 <div class="memberItem">
                   <div class="memberName">
-                    <field-ref ref="{{ field['decl'] }}"></field-ref>
+                    <field-ref ref="{{ field.decl }}"></field-ref>
                   </div>
                   <div class="memberValue">
-                    <any-service-ref ref="{{ field['value'] }}"></any-service-ref>
+                    <any-service-ref ref="{{ field.value }}"></any-service-ref>
                   </div>
                 </div>
               </template>
@@ -242,10 +235,10 @@
               <template repeat="{{ association in instance.associations }}">
                 <div class="memberItem">
                   <div class="memberValue">
-                    [<any-service-ref ref="{{ association['key'] }}"></any-service-ref>]
+                    [<any-service-ref ref="{{ association.key }}"></any-service-ref>]
                   </div>
                   <div class="memberValue">
-                    <any-service-ref ref="{{ association['value'] }}"></any-service-ref>
+                    <any-service-ref ref="{{ association.value }}"></any-service-ref>
                   </div>
                 </div>
               </template>
diff --git a/runtime/observatory/lib/src/elements/instructions_view.dart b/runtime/observatory/lib/src/elements/instructions_view.dart
deleted file mode 100644
index e5c1fb2..0000000
--- a/runtime/observatory/lib/src/elements/instructions_view.dart
+++ /dev/null
@@ -1,21 +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 instructions_view;
-
-import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
-
-@CustomTag('instructions-view')
-class InstructionsViewElement extends ObservatoryElement {
-  @published Instructions instructions;
-
-  InstructionsViewElement.created() : super.created();
-
-  Future refresh() {
-    return instructions.reload();
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/instructions_view.html b/runtime/observatory/lib/src/elements/instructions_view.html
deleted file mode 100644
index feb108c..0000000
--- a/runtime/observatory/lib/src/elements/instructions_view.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="inbound_reference.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="object_common.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="eval_link.html">
-
-<polymer-element name="instructions-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ instructions.isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ instructions.isolate }}"></isolate-nav-menu>
-      <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <object-common object="{{ instructions }}"></object-common>
-
-      <br><br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">code</div>
-          <div class="memberValue">
-            <any-service-ref ref="{{ instructions.code }}"></any-service-ref>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">objectPool</div>
-          <div class="memberValue">
-            <any-service-ref ref="{{ instructions.objectPool }}"></any-service-ref>
-          </div>
-        </div>
-      </div>
-
-    </div>
-  
-    <hr>
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="instructions_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/io_view.dart b/runtime/observatory/lib/src/elements/io_view.dart
deleted file mode 100644
index 7fdade6..0000000
--- a/runtime/observatory/lib/src/elements/io_view.dart
+++ /dev/null
@@ -1,283 +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 io_view_element;
-
-import 'dart:async';
-import 'observatory_element.dart';
-import 'service_ref.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
-
-@CustomTag('io-view')
-class IOViewElement extends ObservatoryElement {
-  @published ServiceMap io;
-
-  IOViewElement.created() : super.created();
-
-  Future refresh() {
-    return io.reload();
-  }
-}
-
-@CustomTag('io-ref')
-class IORefElement extends ServiceRefElement {
-  IORefElement.created() : super.created();
-}
-
-@CustomTag('io-http-server-list-view')
-class IOHttpServerListViewElement extends ObservatoryElement {
-  @published ServiceMap list;
-
-  IOHttpServerListViewElement.created() : super.created();
-
-  Future refresh() {
-    return list.reload();
-  }
-}
-
-@CustomTag('io-http-server-ref')
-class IOHttpServerRefElement extends ServiceRefElement {
-  IOHttpServerRefElement.created() : super.created();
-}
-
-@CustomTag('io-http-server-view')
-class IOHttpServerViewElement extends ObservatoryElement {
-  // TODO(ajohnsen): Create a HttpServer object.
-  @published ServiceMap httpServer;
-  Timer _updateTimer;
-
-  IOHttpServerViewElement.created() : super.created();
-
-  Future refresh() {
-    return httpServer.reload();
-  }
-
-  void _updateHttpServer() {
-    refresh().then((_) {
-      if (_updateTimer != null) {
-        _updateTimer = new Timer(new Duration(seconds: 1), _updateHttpServer);
-      }
-    });
-  }
-
-  @override
-  void attached() {
-    super.attached();
-    // Start a timer to update the isolate summary once a second.
-    _updateTimer = new Timer(new Duration(seconds: 1), _updateHttpServer);
-  }
-
-  @override
-  void detached() {
-    super.detached();
-    if (_updateTimer != null) {
-      _updateTimer.cancel();
-      _updateTimer = null;
-    }
-  }
-}
-
-@CustomTag('io-http-server-connection-view')
-class IOHttpServerConnectionViewElement extends ObservatoryElement {
-  @published ServiceMap connection;
-  Timer _updateTimer;
-
-  IOHttpServerConnectionViewElement.created() : super.created();
-
-  Future refresh() {
-    return connection.reload();
-  }
-
-  void _updateHttpServer() {
-    refresh().then((_) {
-      if (_updateTimer != null) {
-        _updateTimer = new Timer(new Duration(seconds: 1), _updateHttpServer);
-      }
-    });
-  }
-
-  @override
-  void attached() {
-    super.attached();
-    // Start a timer to update the isolate summary once a second.
-    _updateTimer = new Timer(new Duration(seconds: 1), _updateHttpServer);
-  }
-
-  @override
-  void detached() {
-    super.detached();
-    if (_updateTimer != null) {
-      _updateTimer.cancel();
-      _updateTimer = null;
-    }
-  }
-}
-
-@CustomTag('io-http-server-connection-ref')
-class IOHttpServerConnectionRefElement extends ServiceRefElement {
-  IOHttpServerConnectionRefElement.created() : super.created();
-}
-
-@CustomTag('io-socket-ref')
-class IOSocketRefElement extends ServiceRefElement {
-  IOSocketRefElement.created() : super.created();
-}
-
-@CustomTag('io-socket-list-view')
-class IOSocketListViewElement extends ObservatoryElement {
-  @published ServiceMap list;
-
-  IOSocketListViewElement.created() : super.created();
-
-  Future refresh() {
-    return list.reload();
-  }
-}
-
-@CustomTag('io-socket-view')
-class IOSocketViewElement extends ObservatoryElement {
-  @published Socket socket;
-
-  IOSocketViewElement.created() : super.created();
-
-  Future refresh() {
-    return socket.reload();
-  }
-}
-
-@CustomTag('io-web-socket-ref')
-class IOWebSocketRefElement extends ServiceRefElement {
-  IOWebSocketRefElement.created() : super.created();
-}
-
-@CustomTag('io-web-socket-list-view')
-class IOWebSocketListViewElement extends ObservatoryElement {
-  @published ServiceMap list;
-
-  IOWebSocketListViewElement.created() : super.created();
-
-  Future refresh() {
-    return list.reload();
-  }
-}
-
-@CustomTag('io-web-socket-view')
-class IOWebSocketViewElement extends ObservatoryElement {
-  @published ServiceMap webSocket;
-
-  IOWebSocketViewElement.created() : super.created();
-
-  Future refresh() {
-    return webSocket.reload();
-  }
-}
-
-@CustomTag('io-random-access-file-list-view')
-class IORandomAccessFileListViewElement extends ObservatoryElement {
-  @published ServiceMap list;
-
-  IORandomAccessFileListViewElement.created() : super.created();
-
-  Future refresh() {
-    return list.reload();
-  }
-}
-
-@CustomTag('io-random-access-file-ref')
-class IORandomAccessFileRefElement extends ServiceRefElement {
-  IORandomAccessFileRefElement.created() : super.created();
-}
-
-@CustomTag('io-random-access-file-view')
-class IORandomAccessFileViewElement extends ObservatoryElement {
-  // TODO(ajohnsen): Create a RandomAccessFile object.
-  @published ServiceMap file;
-  Timer _updateTimer;
-
-  IORandomAccessFileViewElement.created() : super.created();
-
-  Future refresh() {
-    return file.reload();
-  }
-
-  void _updateFile() {
-    refresh().then((_) {
-      if (_updateTimer != null) {
-        _updateTimer = new Timer(new Duration(seconds: 1), _updateFile);
-      }
-    }).catchError(app.handleException);
-  }
-
-  @override
-  void attached() {
-    super.attached();
-    // Start a timer to update the isolate summary once a second.
-    _updateTimer = new Timer(new Duration(seconds: 1), _updateFile);
-  }
-
-  @override
-  void detached() {
-    super.detached();
-    if (_updateTimer != null) {
-      _updateTimer.cancel();
-      _updateTimer = null;
-    }
-  }
-}
-
-@CustomTag('io-process-list-view')
-class IOProcessListViewElement extends ObservatoryElement {
-  @published ServiceMap list;
-
-  IOProcessListViewElement.created() : super.created();
-
-  Future refresh() {
-    return list.reload();
-  }
-}
-
-@CustomTag('io-process-ref')
-class IOProcessRefElement extends ServiceRefElement {
-  // Only display the process name when small is set.
-  @published bool small = false;
-  IOProcessRefElement.created() : super.created();
-}
-
-@CustomTag('io-process-view')
-class IOProcessViewElement extends ObservatoryElement {
-  // TODO(ajohnsen): Create a Process object.
-  @published ServiceMap process;
-  Timer _updateTimer;
-
-  IOProcessViewElement.created() : super.created();
-
-  Future refresh() {
-    return process.reload();
-  }
-
-  void _updateFile() {
-    refresh().then((_) {
-      if (_updateTimer != null) {
-        _updateTimer = new Timer(new Duration(seconds: 1), _updateFile);
-      }
-    }).catchError(app.handleException);
-  }
-
-  @override
-  void attached() {
-    super.attached();
-    // Start a timer to update the isolate summary once a second.
-    _updateTimer = new Timer(new Duration(seconds: 1), _updateFile);
-  }
-
-  @override
-  void detached() {
-    super.detached();
-    if (_updateTimer != null) {
-      _updateTimer.cancel();
-      _updateTimer = null;
-    }
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/io_view.html b/runtime/observatory/lib/src/elements/io_view.html
deleted file mode 100644
index fcc8399..0000000
--- a/runtime/observatory/lib/src/elements/io_view.html
+++ /dev/null
@@ -1,589 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="service_ref.html">
-
-<polymer-element name="io-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>dart:io</h1>
-
-      <br>
-
-      <ul class="list-group">
-        <li class="list-group-item">
-          <a on-click="{{ goto }}" _href="{{gotoLink('io/http/servers', isolate)}}">HTTP Servers</a>
-        </li>
-      </ul>
-
-      <br>
-
-      <ul class="list-group">
-        <li class="list-group-item">
-          <a on-click="{{ goto }}" _href="{{gotoLink('io/sockets', isolate)}}">Sockets</a>
-        </li>
-      </ul>
-
-      <br>
-
-      <ul class="list-group">
-        <li class="list-group-item">
-          <a on-click="{{ goto }}" _href="{{gotoLink('io/websockets', isolate)}}">WebSockets</a>
-        </li>
-      </ul>
-
-      <br>
-
-      <ul class="list-group">
-        <li class="list-group-item">
-          <a on-click="{{ goto }}" _href="{{gotoLink('io/file/randomaccessfiles', isolate)}}">Random Access Files</a>
-        </li>
-      </ul>
-
-      <br>
-
-      <ul class="list-group">
-        <li class="list-group-item">
-          <a on-click="{{ goto }}" _href="{{gotoLink('io/processes', isolate)}}">Processes</a>
-        </li>
-      </ul>
-
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <template if="{{ ref.type == 'Socket' }}">
-      <io-socket-ref ref="{{ ref }}"></io-socket-ref>
-    </template>
-    <template if="{{ ref.type == 'HttpServerConnection' }}">
-      <io-http-server-connection-ref ref="{{ ref }}"></io-http-server-connection-ref>
-    </template>
-    <template if="{{ ref.type == 'HttpServer' }}">
-      <io-http-server-ref ref="{{ ref }}"></io-http-server-ref>
-    </template>
-    <template if="{{ ref.type == 'WebSocket' }}">
-      <io-web-socket-ref ref="{{ ref }}"></io-web-socket-ref>
-    </template>
-    <template if="{{ ref.type == 'Process' }}">
-      <io-process-ref ref="{{ ref }}"></io-process-ref>
-    </template>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-http-server-list-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>HttpServers</h1>
-
-      <br>
-
-      <ul class="list-group">
-        <template repeat="{{ httpServer in list['members'] }}">
-          <li class="list-group-item">
-            <io-http-server-ref ref="{{ httpServer }}"></io-http-server-ref>
-          </li>
-        </template>
-      </ul>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-http-server-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-http-server-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>HttpServer</h1>
-
-      <br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">Socket</div>
-          <div class="memberValue"><io-socket-ref ref="{{ httpServer['socket'] }}"></io-socket-ref></div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Address</div>
-          <div class="memberValue">{{ httpServer['address'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Port</div>
-          <div class="memberValue">{{ httpServer['port'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Active connections</div>
-          <ul class="list-group">
-            <template repeat="{{ connection in httpServer['active'] }}">
-              <li class="list-group-item">
-                <io-http-server-connection-ref ref="{{ connection }}"></io-http-server-connection-ref>
-              </li>
-            </template>
-          </ul>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Idle connections</div>
-          <ul class="list-group">
-            <template repeat="{{ connection in httpServer['idle'] }}">
-              <li class="list-group-item">
-                <io-http-server-connection-ref ref="{{ connection }}"></io-http-server-connection-ref>
-              </li>
-            </template>
-          </ul>
-        </div>
-      </div>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-http-server-connection-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <a _href="{{ url }}">{{ name }}</a>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-http-server-connection-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>HttpConnection</h1>
-
-      <br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">Socket</div>
-          <div class="memberValue"><io-socket-ref ref="{{ connection['socket'] }}"></io-socket-ref></div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">State</div>
-          <div class="memberValue">{{ connection['state'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Server</div>
-          <div class="memberValue"><io-http-server-ref ref="{{ connection['server'] }}"></io-http-server-ref></div>
-        </div>
-      </div>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-socket-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-socket-list-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>Sockets</h1>
-
-      <br>
-
-      <ul class="list-group">
-        <template repeat="{{ socket in list['members'] }}">
-          <li class="list-group-item">
-            <io-socket-ref ref="{{ socket }}"></io-socket-ref>
-          </li>
-        </template>
-      </ul>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-socket-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <!-- Pipe Socket -->
-      <template if="{{ socket.isPipe }}">
-        <h1>Pipe Socket</h1>
-        <div class="memberList">
-          <template if="{{ socket.socketOwner != null }}">
-            <div class="memberItem">
-              <div class="memberName">Owner</div>
-              <div class="memberValue"><io-ref ref="{{ socket.socketOwner }}"></io-ref></div>
-            </div>
-          </template>
-          <div class="memberItem">
-            <div class="memberName">File descriptor</div>
-            <div class="memberValue">{{ socket.fd }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Read Closed</div>
-            <div class="memberValue">{{ socket.readClosed }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Write Closed</div>
-            <div class="memberValue">{{ socket.writeClosed }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Closing</div>
-            <div class="memberValue">{{ socket.closing }}</div>
-          </div>
-        </div>
-      </template>
-      <!-- Network Socket -->
-      <template if="{{ !socket.isPipe }}">
-        <h1>Network Socket</h1>
-        <div class="memberList">
-          <template if="{{ socket.socketOwner != null }}">
-            <div class="memberItem">
-              <div class="memberName">Owner</div>
-              <div class="memberValue"><io-ref ref="{{ socket.socketOwner }}"></io-ref></div>
-            </div>
-          </template>
-          <div class="memberItem">
-            <div class="memberName">Local Address</div>
-            <div class="memberValue">{{ socket.localAddress }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Local Port</div>
-            <div class="memberValue">{{ socket.localPort }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Remote Address</div>
-            <div class="memberValue">{{ socket.remoteAddress }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Remote Port</div>
-            <div class="memberValue">{{ socket.remotePort }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">File descriptor</div>
-            <div class="memberValue">{{ socket.fd }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Read Closed</div>
-            <div class="memberValue">{{ socket.readClosed }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Write Closed</div>
-            <div class="memberValue">{{ socket.writeClosed }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Closing</div>
-            <div class="memberValue">{{ socket.closing }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Listening</div>
-            <div class="memberValue">{{ socket.listening }}</div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">Protocol</div>
-            <div class="memberValue">{{ socket.protocol }}</div>
-          </div>
-        </div>
-      </template>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-web-socket-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-web-socket-list-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>WebSockets</h1>
-
-      <br>
-
-      <ul class="list-group">
-        <template repeat="{{ webSocket in list['members'] }}">
-          <li class="list-group-item">
-            <io-web-socket-ref ref="{{ webSocket }}"></io-web-socket-ref>
-          </li>
-        </template>
-      </ul>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-web-socket-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>WebSocket</h1>
-
-      <br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">Socket</div>
-          <div class="memberValue"><io-socket-ref ref="{{ webSocket['socket'] }}"></io-socket-ref></div>
-        </div>
-      </div>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-random-access-file-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-random-access-file-list-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>Random Access Files</h1>
-
-      <br>
-
-      <ul class="list-group">
-        <template repeat="{{ file in list['members'] }}">
-          <li class="list-group-item">
-            <io-random-access-file-ref ref="{{ file }}"></io-random-access-file-ref>
-          </li>
-        </template>
-      </ul>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-random-access-file-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>Random Access File</h1>
-
-      <br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">Path</div>
-          <div class="memberValue">{{ file['name'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Pending Operation</div>
-          <div class="memberValue">{{ file['asyncDispatched'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">File Descriptor</div>
-          <div class="memberValue">{{ file['fd'] }}</div>
-        </div>
-      </div>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-process-list-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>Processes</h1>
-
-      <br>
-
-      <ul class="list-group">
-        <template repeat="{{ process in list['members'] }}">
-          <li class="list-group-item">
-            <io-process-ref ref="{{ process }}"></io-process-ref>
-          </li>
-        </template>
-      </ul>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-process-ref" extends="service-ref">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <template if="{{ small }}">
-      <a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
-    </template>
-    <template if="{{ !small }}">
-      <a on-click="{{ goto }}" _href="{{ url }}">({{ ref['pid'] }}) {{ name }} {{ ref['arguments'] }}</a>
-    </template>
-  </template>
-</polymer-element>
-
-<polymer-element name="io-process-view" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    </nav-bar>
-
-    <div class="content">
-      <h1>Process</h1>
-
-      <br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">Path</div>
-          <div class="memberValue">{{ process['name'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Pid</div>
-          <div class="memberValue">{{ process['pid'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Arguments</div>
-          <div class="memberValue">{{ process['arguments'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Started</div>
-          <div class="memberValue">{{ process['started'] }}</div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">Working Directory</div>
-          <div class="memberValue">{{ process['workingDirectory'] }}</div>
-        </div>
-        <template if="{{ process['stdin'] != null }}">
-          <div class="memberItem">
-            <div class="memberName">stdin</div>
-            <div class="memberValue">
-              <io-socket-ref ref="{{ process['stdin'] }}"></io-socket-ref>
-            </div>
-          </div>
-        </template>
-        <template if="{{ process['stdout'] != null }}">
-          <div class="memberItem">
-            <div class="memberName">stdout</div>
-            <div class="memberValue">
-              <io-socket-ref ref="{{ process['stdout'] }}"></io-socket-ref>
-            </div>
-          </div>
-        </template>
-        <template if="{{ process['stderr'] != null }}">
-          <div class="memberItem">
-            <div class="memberName">stderr</div>
-            <div class="memberValue">
-              <io-socket-ref ref="{{ process['stderr'] }}"></io-socket-ref>
-            </div>
-          </div>
-        </template>
-      </div>
-
-      <br>
-
-      <h2>Environment</h2>
-      <div class="well">
-        <div class="monospace break-wrap">
-          <template repeat="{{ variable in process['environment'] }}">
-            {{ variable }}
-            <br>
-          </template>
-        </div>
-      </div>
-    </div>
-    <br>
-    <hr>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="io_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
new file mode 100644
index 0000000..14bc7ef
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:charted/charted.dart';
+import "package:charted/charts/charts.dart";
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+
+class IsolateCounterChartElement extends HtmlElement implements Renderable {
+  static const tag =
+    const Tag<IsolateCounterChartElement>('isolate-counter-chart');
+
+  RenderingScheduler<IsolateCounterChartElement> _r;
+
+  Stream<RenderedEvent<IsolateCounterChartElement>> get onRendered =>
+      _r.onRendered;
+
+  Map _counters;
+  StreamSubscription _subscription;
+
+  factory IsolateCounterChartElement(Map counters, {RenderingQueue queue}) {
+    assert(counters != null);
+    IsolateCounterChartElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._counters = counters;
+    return e;
+  }
+
+  IsolateCounterChartElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+    _subscription = window.onResize.listen((_) => _r.dirty());
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+    _subscription.cancel();
+  }
+
+  static final _columns = [
+    new ChartColumnSpec(label: 'Type', type: ChartColumnSpec.TYPE_STRING),
+    new ChartColumnSpec(label: 'Percent', formatter: (v) => v.toString())
+  ];
+
+  final _series = [new ChartSeries("Work", const [1], new PieChartRenderer(
+    sortDataByValue: false
+  ))];
+
+  void render() {
+    final areaHost = new DivElement()..classes = const ['host'];
+    final  legendHost = new DivElement()..classes = const ['legend'];
+    children = [areaHost, legendHost];
+    final rect = areaHost.getBoundingClientRect();
+    final minSize = new Rect.size(rect.width, rect.height);
+    final config = new ChartConfig(_series, const [0])
+        ..minimumSize = minSize
+        ..legend = new ChartLegend(legendHost, showValues: true);
+    final data = new ChartData(_columns, _counters.keys
+          .map((key) => [key, double.parse(_counters[key].split('%')[0])])
+          .toList());
+
+    new LayoutArea(areaHost, data, config, state: new ChartState(),
+        autoUpdate: false)
+      ..addChartBehavior(new Hovercard())
+      ..addChartBehavior(new AxisLabelTooltip())
+      ..draw();
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/isolate/shared_summary.dart b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
new file mode 100644
index 0000000..51fdc28
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/utils.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/isolate/counter_chart.dart';
+
+class IsolateSharedSummaryElement extends HtmlElement implements Renderable {
+  static const tag =
+    const Tag<IsolateSharedSummaryElement>('isolate-shared-summary-wrapped',
+                                           dependencies: const [
+                                             IsolateCounterChartElement.tag
+                                           ]);
+
+  RenderingScheduler<IsolateSharedSummaryElement> _r;
+
+  Stream<RenderedEvent<IsolateSharedSummaryElement>> get onRendered =>
+      _r.onRendered;
+
+  M.Isolate _isolate;
+
+  factory IsolateSharedSummaryElement(M.Isolate isolate,
+                                      {RenderingQueue queue}) {
+    assert(isolate != null);
+    IsolateSharedSummaryElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    return e;
+  }
+
+  IsolateSharedSummaryElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [];
+    if (_isolate.error != null) {
+      children = [
+        new PreElement()..classes = const ["errorBox"]
+          ..text = _isolate.error.message
+      ];
+    }
+    final newHeapUsed = Utils.formatSize(_isolate.newSpace.used);
+    final newHeapCapacity = Utils.formatSize(_isolate.newSpace.capacity);
+    final oldHeapUsed = Utils.formatSize(_isolate.oldSpace.used);
+    final oldHeapCapacity = Utils.formatSize(_isolate.oldSpace.capacity);
+    children.addAll([
+      new DivElement()..classes = ['menu']
+        ..children = [
+          new DivElement()..classes = const ['memberList']
+            ..children = [
+              new DivElement()..classes = const ['memberItem']
+                ..children = [
+                  new DivElement()..classes = const ['memberName']
+                    ..text = 'new heap',
+                  new DivElement()..classes = const ['memberValue']
+                    ..text = '$newHeapUsed of $newHeapCapacity',
+                ],
+              new DivElement()..classes = const ['memberItem']
+                ..children = [
+                  new DivElement()..classes = const ['memberName']
+                    ..text = 'old heap',
+                  new DivElement()..classes = const ['memberValue']
+                    ..text = '$oldHeapUsed of $oldHeapCapacity',
+                ]
+            ],
+          new BRElement(),
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.debugger(_isolate))
+                ..text = 'debug'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.classTree(_isolate))
+                ..text = 'class hierarchy'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.cpuProfiler(_isolate))
+                ..text = 'cpu profile'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.cpuProfilerTable(_isolate))
+                ..text = 'cpu profile (table)'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.allocationProfiler(_isolate))
+                ..text = 'allocation profile'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.heapMap(_isolate))
+                ..text = 'heap map'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.metrics(_isolate))
+                ..text = 'metrics'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.heapSnapshot(_isolate))
+                ..text = 'heap snapshot'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.persistentHandles(_isolate))
+                ..text = 'persistent handles'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.ports(_isolate))
+                ..text = 'ports'
+            ],
+          new DivElement()
+            ..children = [
+              new SpanElement()..text = 'see ',
+              new AnchorElement(href: Uris.logging(_isolate))
+                ..text = 'logging'
+            ]
+      ],
+      new IsolateCounterChartElement(_isolate.counters, queue: _r.queue)
+    ]);
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart b/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
new file mode 100644
index 0000000..72b86c2
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
@@ -0,0 +1,167 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/isolate/shared_summary.dart';
+
+@bindable
+class IsolateSharedSummaryElementWrapper extends HtmlElement {
+  static const binder = const Binder<IsolateSharedSummaryElementWrapper>(const {
+      'isolate': #isolate
+    });
+
+  static const tag =
+      const Tag<IsolateSharedSummaryElementWrapper>('isolate-shared-summary');
+
+  IsolateSharedSummaryElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  Isolate _isolate;
+  StreamSubscription _subscription;
+
+  Isolate get isolate => _isolate;
+
+  void set isolate(Isolate value) {
+    _isolate = value;
+    _detached();
+    _attached();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    _attached();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _detached();
+  }
+
+  void _attached() {
+    if (_isolate != null) {
+      _subscription = _isolate.changes.listen((_) { render(); });
+    }
+    render();
+  }
+
+  void _detached() {
+    _subscription?.cancel();
+    _subscription = null;
+  }
+
+  void render() {
+    if (_isolate == null) {
+      return;
+    }
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        a[href] {
+          color: #0489c3;
+          text-decoration: none;
+        }
+        a[href]:hover {
+          text-decoration: underline;
+        }
+        .memberList {
+          display: table;
+        }
+        .memberItem {
+          display: table-row;
+        }
+        .memberName, .memberValue {
+          display: table-cell;
+          vertical-align: top;
+          padding: 3px 0 3px 1em;
+          font: 400 14px 'Montserrat', sans-serif;
+        }
+        isolate-shared-summary-wrapped {
+          display: block;
+          height: 300px;
+          position: relative;
+        }
+        isolate-shared-summary-wrapped > .menu {
+          float: right;
+          top: 0;
+          right: 0;
+        }
+        isolate-shared-summary-wrapped > isolate-counter-chart {
+          position: absolute;
+          left: 0;
+          top: 0;
+          right: 230px;
+          clear: both;
+        }
+        isolate-shared-summary-wrapped .errorBox {
+          background-color: #f5f5f5;
+          border: 1px solid #ccc;
+          padding: 2em;
+          font-family: consolas, courier, monospace;
+          font-size: 1em;
+          line-height: 1.2em;
+          white-space: pre;
+        }
+        isolate-counter-chart {
+          display: block;
+          position: relative;
+          height: 300px;
+          min-width: 350px;
+        }
+        isolate-counter-chart > div.host {
+          position: absolute;
+          left: 0;
+          bottom: 20px;
+          top: 5px;
+          right: 250px;
+        }
+        isolate-counter-chart > div.legend {
+          position: absolute;
+          width: 250px;
+          top: 0;
+          right: 0;
+          bottom: 0;
+          overflow-y: auto;
+        }
+        .type-pie-rdr > .chart-legend-color {
+          border-radius: 6px;
+        }
+        .chart-legend-row, .chart-legend-more {
+          width: 100%;
+          display: flex;
+          font-size: 14px;
+          margin-bottom: 16px;
+          position: relative;
+          cursor: default;
+        }
+        .chart-legend-row:hover, .chart-legend-more:hover {
+          font-weight: bold;
+        }
+        .chart-legend-color, .chart-legend-more-color {
+          width: 12px;
+          height: 12px;
+          margin: auto 8px;
+          border-radius: 2px;
+        }
+        .chart-legend-label {
+          overflow: hidden;
+          text-overflow: ellipsis;
+          max-width: 120px;
+          flex: 1;
+        }
+        ''',
+      new IsolateSharedSummaryElement(_isolate,
+                                      queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/isolate_reconnect.dart b/runtime/observatory/lib/src/elements/isolate_reconnect.dart
index 01edf8f..465bc0c 100644
--- a/runtime/observatory/lib/src/elements/isolate_reconnect.dart
+++ b/runtime/observatory/lib/src/elements/isolate_reconnect.dart
@@ -4,24 +4,111 @@
 
 library isolate_reconnect_element;
 
-import 'package:polymer/polymer.dart';
-import 'observatory_element.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-@CustomTag('isolate-reconnect')
-class IsolateReconnectElement extends ObservatoryElement {
-  IsolateReconnectElement.created() : super.created();
+class IsolateReconnectElement extends HtmlElement implements Renderable{
+  static const tag = const Tag<IsolateReconnectElement>('isolate-reconnect',
+                     dependencies: const [NavBarElement.tag,
+                                          NavTopMenuElement.tag,
+                                          NavNotifyElement.tag,
+                                          ViewFooterElement.tag]);
 
-  get missingIsolateId {
-    return app.locationManager.uri.queryParameters['originalIsolateId'];
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<IsolateReconnectElement>> get onRendered =>
+      _r.onRendered;
+
+  M.VM _vm;
+  String _missing;
+  Uri _uri;
+  M.EventRepository _events;
+  StreamSubscription _subscription;
+
+  M.VM get vm  => _vm;
+  String get missing => _missing;
+  Uri get uri => _uri;
+
+  M.NotificationRepository _notifications;
+  factory IsolateReconnectElement(M.VM vm, M.EventRepository events,
+      M.NotificationRepository notifications, String missing, Uri uri,
+      {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(events != null);
+    assert(missing != null);
+    assert(uri != null);
+    assert(notifications != null);
+    IsolateReconnectElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._events = events;
+    e._missing = missing;
+    e._uri = uri;
+    e._notifications = notifications;
+    return e;
   }
 
-  linkToContinueIn(isolate) {
-    var parameters = new Map.from(app.locationManager.uri.queryParameters);
-    parameters['isolateId'] = isolate.id;
-    parameters.remove('originalIsolateId');
-    var path = parameters.remove('originalPath');
-    path = "/$path";
-    var generatedUri = new Uri(path: path, queryParameters: parameters);
-    return app.locationManager.makeLink(generatedUri.toString());
+  IsolateReconnectElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _subscription = _events.onVMUpdate.listen((e) {
+      _vm = e.vm;
+      _r.dirty();
+    });
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+    _subscription.cancel();
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(last: true, queue: _r.queue),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()
+        ..classes = ['content-centered']
+        ..children = [
+          new HeadingElement.h1()..text = 'Isolate $_missing no longer exists',
+          new BRElement(), new HRElement(),
+          new DivElement()..classes = ['memberList']
+            ..children = (_vm.isolates.map((isolate) {
+              final query = new Map.from(_uri.queryParameters);
+              query['isolateId'] = isolate.id;
+              final href = new Uri(path: _uri.path, queryParameters: query);
+              return new DivElement()..classes = ['memberItem', 'doubleSpaced']
+                ..children = [
+                  new SpanElement()..text = 'Continue in ',
+                  new AnchorElement(href: '#$href')..classes = ['isolate-link']
+                    ..text = '${isolate.id} (${isolate.name})'
+                ];
+            }).toList()..add(
+              new DivElement()..classes = ['memberItem', 'doubleSpaced']
+                ..children = [
+                  new SpanElement()..text = 'Go to ',
+                  new AnchorElement(href: Uris.vm())
+                    ..text = 'isolates summary',
+                ]
+            ))
+        ],
+      new ViewFooterElement(queue: _r.queue)
+    ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/isolate_reconnect.html b/runtime/observatory/lib/src/elements/isolate_reconnect.html
deleted file mode 100644
index 9674038..0000000
--- a/runtime/observatory/lib/src/elements/isolate_reconnect.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<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="isolate-reconnect" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-      .doubleSpaced {
-	line-height: 2em;
-      }
-    </style>
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-    </nav-bar>
-
-    <div class="content-centered">
-      <h1 class="doubleSpaced">Isolate {{ missingIsolateId }} no longer exists</h1>
-      <div class="memberList">
-         <template repeat="{{ i in app.vm.isolates }}">
-           <div class="memberItem doubleSpaced">
-             Continue in <a _href="{{ linkToContinueIn(i) }}">{{ i.id }} ({{ i.name }})</a>
-           </div>
-         </template>
-         <div class="memberItem doubleSpaced">
-           Go to <a _href="{{ gotoLink('/vm') }}">isolates summary</a>
-         </div>
-      </div>
-    </div>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="isolate_reconnect.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/isolate_ref.dart b/runtime/observatory/lib/src/elements/isolate_ref.dart
index 730a438..4440001 100644
--- a/runtime/observatory/lib/src/elements/isolate_ref.dart
+++ b/runtime/observatory/lib/src/elements/isolate_ref.dart
@@ -4,10 +4,63 @@
 
 library isolate_ref_element;
 
-import 'package:polymer/polymer.dart';
-import 'service_ref.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, EventRepository;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 
-@CustomTag('isolate-ref')
-class IsolateRefElement extends ServiceRefElement {
+class IsolateRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<IsolateRefElement>('isolate-ref-wrapped');
+
+  RenderingScheduler<IsolateRefElement> _r;
+
+  Stream<RenderedEvent<IsolateRefElement>> get onRendered => _r.onRendered;
+
+
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  StreamSubscription _updatesSubscription;
+
+  M.IsolateRef get isolate => _isolate;
+
+  factory IsolateRefElement(M.IsolateRef isolate, M.EventRepository events,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(events != null);
+    IsolateRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._events = events;
+    return e;
+  }
+
   IsolateRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _updatesSubscription = _events.onIsolateUpdate
+      .where((e) => e.isolate.id == isolate.id)
+      .listen((e) { _isolate = e.isolate; _r.dirty(); });
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+    _updatesSubscription.cancel();
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(isolate))
+        ..text = 'Isolate ${isolate.number} (${isolate.name})'
+        ..classes = ['isolate-ref']
+    ];
+  }
 }
diff --git a/runtime/observatory/lib/src/elements/isolate_ref.html b/runtime/observatory/lib/src/elements/isolate_ref.html
deleted file mode 100644
index edfb3ea..0000000
--- a/runtime/observatory/lib/src/elements/isolate_ref.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="service_ref.html">
-<polymer-element name="isolate-ref" extends="service-ref">
-<template><link rel="stylesheet" href="css/shared.css">
-  <a on-click="{{ goto }}" _href="{{ url }}">Isolate {{ ref.number }} ({{ ref.name }})</a>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="isolate_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/isolate_ref_wrapper.dart b/runtime/observatory/lib/src/elements/isolate_ref_wrapper.dart
new file mode 100644
index 0000000..6c9547b
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/isolate_ref_wrapper.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart' show Isolate;
+import 'package:observatory/src/elements/isolate_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class IsolateRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<IsolateRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<IsolateRefElementWrapper>('isolate-ref');
+
+  Isolate _isolate;
+
+  Isolate get ref => _isolate;
+
+  void set ref(Isolate value) {
+    _isolate = value;
+    render();
+  }
+
+  IsolateRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        isolate-ref-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        isolate-ref-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new IsolateRefElement(_isolate, app.events, queue: app.queue)
+    ];
+  }
+
+  ObservatoryApplication get app => ObservatoryApplication.app;
+}
diff --git a/runtime/observatory/lib/src/elements/isolate_summary.dart b/runtime/observatory/lib/src/elements/isolate_summary.dart
index b0b2e06..b41befd 100644
--- a/runtime/observatory/lib/src/elements/isolate_summary.dart
+++ b/runtime/observatory/lib/src/elements/isolate_summary.dart
@@ -4,10 +4,7 @@
 
 library isolate_summary_element;
 
-import 'dart:html';
 import 'observatory_element.dart';
-import 'package:charted/charted.dart';
-import "package:charted/charts/charts.dart";
 import 'package:observatory/service.dart';
 import 'package:polymer/polymer.dart';
 
@@ -31,88 +28,3 @@
 
   @published Isolate isolate;
 }
-
-@CustomTag('isolate-shared-summary')
-class IsolateSharedSummaryElement extends ObservatoryElement {
-  IsolateSharedSummaryElement.created() : super.created();
-
-  @published Isolate isolate;
-}
-
-class CounterChart {
-  final HtmlElement _wrapper;
-  HtmlElement _areaHost;
-  HtmlElement _legendHost;
-  LayoutArea _area;
-  ChartData _data;
-  final _columns = [
-      new ChartColumnSpec(label: 'Type', type: ChartColumnSpec.TYPE_STRING),
-      new ChartColumnSpec(label: 'Percent', formatter: (v) => v.toString())
-  ];
-
-  CounterChart(this._wrapper) {
-    assert(_wrapper != null);
-    _areaHost = _wrapper.querySelector('.chart-host');
-    assert(_areaHost != null);
-    _areaHost.clientWidth;
-    _legendHost = _wrapper.querySelector('.chart-legend-host');
-    assert(_legendHost != null);
-    var series = new ChartSeries("Work", [1], new PieChartRenderer(
-      sortDataByValue: false
-    ));
-    var config = new ChartConfig([series], [0]);
-    config.minimumSize = new Rect(200, 200);
-    config.legend = new ChartLegend(_legendHost, showValues: true);
-    _data = new ChartData(_columns, []);
-    _area = new LayoutArea(_areaHost,
-                           _data,
-                           config,
-                           state: new ChartState(),
-                           autoUpdate: false);
-    _area.addChartBehavior(new Hovercard());
-    _area.addChartBehavior(new AxisLabelTooltip());
-  }
-
-  void update(Map counters) {
-    var rows = [];
-    for (var key in counters.keys) {
-      var value = double.parse(counters[key].split('%')[0]);
-      rows.add([key, value]);
-    }
-    _area.data = new ChartData(_columns, rows);
-    _area.draw();
-  }
-}
-
-@CustomTag('isolate-counter-chart')
-class IsolateCounterChartElement extends ObservatoryElement {
-  IsolateCounterChartElement.created() : super.created();
-
-  @published ObservableMap counters;
-  CounterChart chart;
-
-  attached() {
-    super.attached();
-    chart =
-        new CounterChart(shadowRoot.querySelector('#isolate-counter-chart'));
-  }
-
-  detached() {
-    super.detached();
-    var host = shadowRoot.querySelector('#isolate-counter-chart-host');
-    host.children.clear();
-    var legendHost =
-        shadowRoot.querySelector('#isolate-counter-chart-legend-host');
-    legendHost.children.clear();
-  }
-
-  void countersChanged(oldValue) {
-    if (counters == null) {
-      return;
-    }
-    if (chart == null) {
-      return;
-    }
-    chart.update(counters);
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/isolate_summary.html b/runtime/observatory/lib/src/elements/isolate_summary.html
index c089da9..3c4924d 100644
--- a/runtime/observatory/lib/src/elements/isolate_summary.html
+++ b/runtime/observatory/lib/src/elements/isolate_summary.html
@@ -1,11 +1,8 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="action_link.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="isolate_ref.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="script_inset.html">
-<link rel="import" href="script_ref.html">
-<polymer-element name="isolate-summary" extends="observatory-element">
+
+<polymer-element name="isolate-summary">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <div class="flex-row">
@@ -24,7 +21,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="isolate-run-state" extends="observatory-element">
+<polymer-element name="isolate-run-state">
   <template>
     <template if="{{ isolate.paused }}">
       <strong title="{{ isolate.pauseEvent.timestamp.toString() }}">paused</strong>
@@ -44,7 +41,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="isolate-location" extends="observatory-element">
+<polymer-element name="isolate-location">
   <template>
     <template if="{{ isolate.pauseEvent != null }}">
       <template if="{{ isolate.pauseEvent.kind == 'PauseStart' }}">
@@ -88,146 +85,4 @@
   </template>
 </polymer-element>
 
-<polymer-element name="isolate-shared-summary" extends="observatory-element">
-  <template>
-    <style>
-      .errorBox {
-        background-color: #f5f5f5;
-        border: 1px solid #ccc;
-        padding: 2em;
-        font-family: consolas, courier, monospace;
-        font-size: 1em;
-        line-height: 1.2em;
-        white-space: pre;
-      }
-    </style>
-    <link rel="stylesheet" href="css/shared.css">
-    <template if="{{ isolate.error != null }}">
-      <div class="content-centered">
-        <pre class="errorBox">{{ isolate.error.message }}</pre>
-        <br>
-      </div>
-    </template>
-    <div class="flex-row">
-      <div style="flex:2">
-        <isolate-counter-chart counters="{{ isolate.counters }}"></isolate-counter-chart>
-      </div>
-      <div style="flex:1">
-        <div class="memberList">
-          <div class="memberItem">
-            <div class="memberName">new heap</div>
-            <div class="memberValue">
-              {{ isolate.newSpace.used | formatSize }}
-              of
-              {{ isolate.newSpace.capacity | formatSize }}
-            </div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">old heap</div>
-            <div class="memberValue">
-              {{ isolate.oldSpace.used | formatSize }}
-              of
-              {{ isolate.oldSpace.capacity | formatSize }}
-            </div>
-          </div>
-        </div>
-        <br>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/debugger', isolate) }}">debugger</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/class-tree', isolate) }}">class hierarchy</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/profiler', isolate) }}">cpu profile</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/profiler-table', isolate) }}">cpu profile (table)</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/allocation-profiler', isolate) }}">allocation profile</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/heap-map', isolate) }}">heap map</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/metrics', isolate) }}">metrics</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/heap-snapshot', isolate) }}">heap snapshot</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/persistent-handles', isolate) }}">persistent handles</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/ports', isolate) }}">ports</a>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberValue">
-            See <a on-click="{{ goto }}" _href="{{ gotoLink('/logging', isolate) }}">logging</a>
-          </div>
-        </div>
-        <!-- Temporarily disabled until UI for dart:io is acceptable.
-        <template if="{{ isolate.ioEnabled }}">
-          <div class="memberItem">
-            <div class="memberValue">
-              See <a on-click="{{ goto }}" href="{{ gotoLink('/io', isolate) }}">dart:io</a>
-            </div>
-          </div>
-        </template>
-        -->
-      </div>
-    </div>
-  </template>
-</polymer-element>
-
-<polymer-element name="isolate-counter-chart" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="../../../../packages/charted/charts/themes/quantum_theme.css">
-    <style>
-.chart-wrapper {
-}
-.chart-host-wrapper {
-  display: flex;
-  flex-direction: row;
-  max-height: 250px;
-}
-.chart-host {
-  flex: 1;
-}
-.chart-legend-host {
-  flex: 1;
-  overflow-x: auto;
-  overflow-y: auto;
-}
-    </style>
-    <div class="chart-wrapper" id="isolate-counter-chart">
-      <div class="chart-host-wrapper">
-        <div class="chart-host" id="isolate-counter-chart-host"></div>
-        <div class="chart-legend-host" id="isolate-counter-chart-legend-host"></div>
-      </div>
-  </div>
-  </template>
-</polymer-element>
-
 <script type="application/dart" src="isolate_summary.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/isolate_view.html b/runtime/observatory/lib/src/elements/isolate_view.html
index e7777a7..16d3150 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.html
+++ b/runtime/observatory/lib/src/elements/isolate_view.html
@@ -1,17 +1,10 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="action_link.html">
-<link rel="import" href="curly_block.html">
 <link rel="import" href="eval_box.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="isolate_summary.html">
-<link rel="import" href="library_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="script_inset.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="isolate-view" extends="observatory-element">
+<polymer-element name="isolate-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -29,6 +22,7 @@
       <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
       <isolate-nav-menu isolate="{{ isolate }}" last="{{ true }}"></isolate-nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content-centered">
diff --git a/runtime/observatory/lib/src/elements/json_view.html b/runtime/observatory/lib/src/elements/json_view.html
index 4ef479b..ea4b63f 100644
--- a/runtime/observatory/lib/src/elements/json_view.html
+++ b/runtime/observatory/lib/src/elements/json_view.html
@@ -1,10 +1,10 @@
 <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="json-view" extends="observatory-element">
+
+<polymer-element name="json-view">
   <template>
     <nav-bar>
       <top-nav-menu last="{{ true }}"></top-nav-menu>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
       <pre>{{ mapAsString }}</pre>
   </template>
diff --git a/runtime/observatory/lib/src/elements/library_ref.dart b/runtime/observatory/lib/src/elements/library_ref.dart
index 4f65a39..be8918b 100644
--- a/runtime/observatory/lib/src/elements/library_ref.dart
+++ b/runtime/observatory/lib/src/elements/library_ref.dart
@@ -4,33 +4,58 @@
 
 library library_ref_element;
 
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
-import 'service_ref.dart';
+import 'dart:html';
 import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, LibraryRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 
-@CustomTag('library-ref')
-class LibraryRefElement extends ServiceRefElement {
-  @observable bool asValue = false;
+class LibraryRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<LibraryRefElement>('library-ref-wrapped');
+
+  RenderingScheduler<LibraryRefElement> _r;
+
+  Stream<RenderedEvent<LibraryRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.LibraryRef _library;
+
+  M.IsolateRef get isolate => _isolate;
+  M.LibraryRef get library => _library;
+
+  factory LibraryRefElement(M.IsolateRef isolate, M.LibraryRef library,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(library != null);
+    LibraryRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._library = library;
+    return e;
+  }
 
   LibraryRefElement.created() : super.created();
 
-  String makeExpandKey(String key) {
-    return '${expandKey}/${key}';
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
   }
 
-  dynamic expander() {
-    return expandEvent;
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
   }
 
-  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();
-    }
+  void render() {
+    final name = _library.name;
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _library))
+        ..text = (name == null || name.isEmpty) ? 'unnamed' : name
+    ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/library_ref.html b/runtime/observatory/lib/src/elements/library_ref.html
deleted file mode 100644
index a4313c1..0000000
--- a/runtime/observatory/lib/src/elements/library_ref.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<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">
-    <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/library_ref_as_value.dart b/runtime/observatory/lib/src/elements/library_ref_as_value.dart
new file mode 100644
index 0000000..6de3313
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/library_ref_as_value.dart
@@ -0,0 +1,34 @@
+// 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 library_ref_as_value_element;
+
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+import 'service_ref.dart';
+import 'dart:async';
+
+@CustomTag('library-ref-as-value')
+class LibraryRefAsValueElement extends ServiceRefElement {
+  LibraryRefAsValueElement.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_as_value.html b/runtime/observatory/lib/src/elements/library_ref_as_value.html
new file mode 100644
index 0000000..49dc900
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/library_ref_as_value.html
@@ -0,0 +1,30 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="service_ref.html">
+
+<polymer-element name="library-ref-as-value">
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <style>
+      .indented {
+      margin-left: 1.5em;
+      font: 400 14px 'Montserrat', sans-serif;
+      line-height: 150%;
+      }
+    </style>
+    <library-ref ref="{{ ref }}"></library-ref>
+    <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>
+</polymer-element>
+
+<script type="application/dart" src="library_ref_as_value.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/library_ref_wrapper.dart b/runtime/observatory/lib/src/elements/library_ref_wrapper.dart
new file mode 100644
index 0000000..0a2caf4
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/library_ref_wrapper.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart' show Library;
+import 'package:observatory/src/elements/library_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class LibraryRefElementWrapper extends HtmlElement {
+
+  static const binder = const Binder<LibraryRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<LibraryRefElementWrapper>('library-ref');
+
+  Library _library;
+  Library get ref => _library;
+  void set ref(Library ref) { _library = ref; render(); }
+
+  LibraryRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (ref == null) return;
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        library-ref-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        library-ref-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new LibraryRefElement(_library.isolate, _library,
+          queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/library_view.html b/runtime/observatory/lib/src/elements/library_view.html
index 51d2da8..e18e2e6 100644
--- a/runtime/observatory/lib/src/elements/library_view.html
+++ b/runtime/observatory/lib/src/elements/library_view.html
@@ -1,17 +1,7 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="curly_block.html">
 <link rel="import" href="eval_box.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="library_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="library-view" extends="observatory-element">
+<polymer-element name="library-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
 
@@ -21,6 +11,7 @@
       <isolate-nav-menu isolate="{{ library.isolate }}"></isolate-nav-menu>
       <library-nav-menu library="{{ library }}" last="{{ true }}"></library-nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
diff --git a/runtime/observatory/lib/src/elements/local_var_descriptors_ref.dart b/runtime/observatory/lib/src/elements/local_var_descriptors_ref.dart
new file mode 100644
index 0000000..4ca623d
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/local_var_descriptors_ref.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, LocalVarDescriptorsRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class LocalVarDescriptorsRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<LocalVarDescriptorsRefElement>('var-ref');
+
+  RenderingScheduler<LocalVarDescriptorsRefElement> _r;
+
+  Stream<RenderedEvent<LocalVarDescriptorsRefElement>> get onRendered =>
+      _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.LocalVarDescriptorsRef _localVar;
+
+  M.IsolateRef get isolate => _isolate;
+  M.LocalVarDescriptorsRef get localVar => _localVar;
+
+  factory LocalVarDescriptorsRefElement(M.IsolateRef isolate,
+      M.LocalVarDescriptorsRef localVar, {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(localVar != null);
+    LocalVarDescriptorsRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._localVar = localVar;
+    return e;
+  }
+
+  LocalVarDescriptorsRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    final text = (_localVar.name == null || _localVar.name == '')
+      ? 'LocalVarDescriptors'
+      : _localVar.name;
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _localVar))
+        ..text = text
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/logging.html b/runtime/observatory/lib/src/elements/logging.html
index a3a36a1..fc74304 100644
--- a/runtime/observatory/lib/src/elements/logging.html
+++ b/runtime/observatory/lib/src/elements/logging.html
@@ -1,12 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="code_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="sliding_checkbox.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="logging-page" extends="observatory-element">
+<polymer-element name="logging-page">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -63,6 +57,7 @@
       <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
       <nav-menu link="{{ makeLink('/logging', isolate) }}" anchor="logging" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ clear }}" label="Clear"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
     <div id="page" class="content-centered-big">
       <span>Show messages with severity <select id="severityLevelSelector" value="{{ severityLevel }}"></select> and higher</span>
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_ref.dart b/runtime/observatory/lib/src/elements/megamorphiccache_ref.dart
new file mode 100644
index 0000000..9554008
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_ref.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, MegamorphicCacheRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class MegamorphicCacheRefElement extends HtmlElement implements Renderable {
+  static const tag =
+      const Tag<MegamorphicCacheRefElement>('megamorphic-cache-ref-wrapped');
+
+  RenderingScheduler<MegamorphicCacheRefElement> _r;
+
+  Stream<RenderedEvent<MegamorphicCacheRefElement>> get onRendered =>
+      _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.MegamorphicCacheRef _cache;
+
+  M.IsolateRef get isolate => _isolate;
+  M.MegamorphicCacheRef get cache => _cache;
+
+  factory MegamorphicCacheRefElement(M.IsolateRef isolate,
+      M.MegamorphicCacheRef cache, {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(cache != null);
+    MegamorphicCacheRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._cache = cache;
+    return e;
+  }
+
+  MegamorphicCacheRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _cache))
+        ..children = [
+          new SpanElement()..classes = ['emphatize']
+            ..text = 'MegarmorphicCache',
+          new SpanElement()..text = ' (${_cache.selector})'
+        ]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.html b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
index 0454e0d..f25ab3d 100644
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.html
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
@@ -1,16 +1,10 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
 <link rel="import" href="error_view.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="inbound_reference.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="object_common.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="eval_link.html">
 
-<polymer-element name="megamorphiccache-view" extends="observatory-element">
+<polymer-element name="megamorphiccache-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -19,6 +13,7 @@
       <isolate-nav-menu isolate="{{ megamorphicCache.isolate }}"></isolate-nav-menu>
       <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
@@ -41,7 +36,7 @@
         </div>
         <div class="memberItem">
           <div class="memberName">mask</div>
-          <div class="memberValue"> 
+          <div class="memberValue">
             {{ megamorphicCache.mask }}
           </div>
         </div>
@@ -54,7 +49,7 @@
       </div>
 
     </div>
-  
+
     <hr>
     <view-footer></view-footer>
   </template>
diff --git a/runtime/observatory/lib/src/elements/metrics.html b/runtime/observatory/lib/src/elements/metrics.html
index a6a0411..a82cea0 100644
--- a/runtime/observatory/lib/src/elements/metrics.html
+++ b/runtime/observatory/lib/src/elements/metrics.html
@@ -1,8 +1,6 @@
 <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="metrics-page" extends="observatory-element">
+<polymer-element name="metrics-page">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -23,6 +21,7 @@
       <nav-menu link="{{ makeLink('/metrics', isolate) }}" anchor="metrics" last="{{ true }}"></nav-menu>
 
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
     <div class="flex-row">
       <div class="flex-item-20-percent">
@@ -65,7 +64,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="metric-details" extends="observatory-element">
+<polymer-element name="metric-details">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <div class="content-centered">
@@ -124,7 +123,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="metrics-graph" extends="observatory-element">
+<polymer-element name="metrics-graph">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <link rel="stylesheet" href="../../../../packages/charted/charts/themes/quantum_theme.css">
diff --git a/runtime/observatory/lib/src/elements/nav/bar.dart b/runtime/observatory/lib/src/elements/nav/bar.dart
new file mode 100644
index 0000000..b175ba6
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/bar.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+
+class NavBarElement extends HtmlElement implements Renderable {
+  static final StyleElement _style = () {
+      var style = new StyleElement();
+      style.text = 'nav.nav-bar {'
+                     'line-height: normal;'
+                     'position: fixed;'
+                     'top: 0;'
+                     'width: 100%;'
+                     'z-index: 1000;'
+                     '}'
+                   'nav.nav-bar > ul {'
+                     'display: inline-table;'
+                     'position: relative;'
+                     'list-style: none;'
+                     'padding-left: 0;'
+                     'margin: 0;'
+                     'width: 100%;'
+                     'z-index: 1000;'
+                     'font: 400 16px \'Montserrat\', sans-serif;'
+                     'color: white;'
+                     'background-color: #0489c3;'
+                   '}';
+      return style;
+  }();
+
+  static const tag = const Tag<NavBarElement>('nav-bar');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavBarElement>> get onRendered => _r.onRendered;
+
+  factory NavBarElement({RenderingQueue queue}) {
+    NavBarElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    return e;
+  }
+
+  NavBarElement.created() : super.created() {
+    // TODO(cbernaschina) remove when no more needed.
+    _r = new RenderingScheduler(this);
+    createShadowRoot();
+  }
+
+  @override
+  void attached() { super.attached(); _r.enable(); }
+
+  @override
+  void detached() {
+    super.detached(); _r.disable(notify: true);
+    shadowRoot.children = [];
+  }
+
+  void render() {
+    shadowRoot.children = [
+      _style.clone(true),
+      document.createElement('nav')
+        ..classes = ['nav-bar']
+        ..children = [
+          new UListElement()
+            ..children = [
+              new ContentElement()
+            ],
+        ],
+      new DivElement()
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/class_menu.dart b/runtime/observatory/lib/src/elements/nav/class_menu.dart
new file mode 100644
index 0000000..d8ed510
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/class_menu.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M show IsolateRef, ClassRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+
+class NavClassMenuElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavClassMenuElement>('nav-class-menu',
+                     dependencies: const [NavMenuElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavClassMenuElement>> get onRendered => _r.onRendered;
+
+  bool _last;
+  M.IsolateRef _isolate;
+  M.ClassRef _cls;
+  bool get last => _last;
+  M.IsolateRef get isolate => _isolate;
+  M.ClassRef get cls => _cls;
+  set last(bool value) => _last = _r.checkAndReact(_last, value);
+
+  factory NavClassMenuElement(M.IsolateRef isolate, M.ClassRef cls,
+      {bool last: false, RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(cls != null);
+    assert(last != null);
+    NavClassMenuElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._cls = cls;
+    e._last = last;
+    return e;
+  }
+
+  NavClassMenuElement.created() : super.created() { createShadowRoot(); }
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    shadowRoot.children = [];
+  }
+
+  void render() {
+    shadowRoot.children = [
+      new NavMenuElement(cls.name, last: last, queue: _r.queue,
+          link: Uris.inspect(isolate, object: cls))
+        ..children = [new ContentElement()]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/class_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/class_menu_wrapper.dart
new file mode 100644
index 0000000..42a65de
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/class_menu_wrapper.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/class_menu.dart';
+
+@bindable
+class NavClassMenuElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavClassMenuElementWrapper>(const {
+      'last': #last, 'cls': #cls
+    });
+
+  static const tag =
+    const Tag<NavClassMenuElementWrapper>('class-nav-menu');
+
+  bool _last = false;
+  Class _cls;
+
+  bool get last => _last;
+  Class get cls => _cls;
+  
+  set last(bool value) {
+    _last = value;
+    render();
+  }
+  set cls(Class value) {
+    _cls = value;
+    render();
+  }
+
+  NavClassMenuElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _last = _getBoolAttribute('last');
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_cls == null || _last == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new NavClassMenuElement(cls.isolate, cls, last: last,
+                                 queue: ObservatoryApplication.app.queue)
+        ..children = [new ContentElement()]
+    ];
+  }
+
+  bool _getBoolAttribute(String name) {
+    final String value = getAttribute(name);
+    return !(value == null || value == 'false');
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/isolate_menu.dart b/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
new file mode 100644
index 0000000..d9f82c9
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, EventRepository;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/menu_item.dart';
+
+class NavIsolateMenuElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavIsolateMenuElement>('nav-isolate-menu',
+                     dependencies: const [NavMenuElement.tag,
+                                          NavMenuItemElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavIsolateMenuElement>> get onRendered => _r.onRendered;
+
+  bool _last;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  StreamSubscription _updatesSubscription;
+
+  bool get last => _last;
+  M.IsolateRef get isolate => _isolate;
+
+  set last(bool value) => _last = _r.checkAndReact(_last, value);
+
+  factory NavIsolateMenuElement(M.IsolateRef isolate,
+      M.EventRepository events, {bool last: false,
+      RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(events != null);
+    assert(last != null);
+    NavIsolateMenuElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._last = last;
+    e._events = events;
+    return e;
+  }
+
+  NavIsolateMenuElement.created() : super.created() {
+    _r = new RenderingScheduler(this);
+    createShadowRoot();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    _updatesSubscription = _events.onIsolateUpdate
+      .where((e) => e.isolate.id == isolate.id)
+      .listen((e) { _isolate = e.isolate; _r.dirty(); });
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    shadowRoot.children = [];
+    assert(_updatesSubscription != null);
+    _updatesSubscription.cancel();
+    _updatesSubscription = null;
+  }
+
+  void render() {
+    shadowRoot.children = [
+      new NavMenuElement(isolate.name, last: last, queue: _r.queue,
+          link: Uris.inspect(isolate))
+        ..children = [
+          new NavMenuItemElement('debugger', queue: _r.queue,
+              link: Uris.debugger(isolate)),
+          new NavMenuItemElement('class hierarchy', queue: _r.queue,
+              link: Uris.classTree(isolate)),
+          new NavMenuItemElement('cpu profile', queue: _r.queue,
+              link: Uris.cpuProfiler(isolate)),
+          new NavMenuItemElement('cpu profile (table)', queue: _r.queue,
+              link: Uris.cpuProfilerTable(isolate)),
+          new NavMenuItemElement('allocation profile', queue: _r.queue,
+              link: Uris.allocationProfiler(isolate)),
+          new NavMenuItemElement('heap map', queue: _r.queue,
+              link: Uris.heapMap(isolate)),
+          new NavMenuItemElement('metrics', queue: _r.queue,
+              link: Uris.metrics(isolate)),
+          new NavMenuItemElement('heap snapshot', queue: _r.queue,
+              link: Uris.heapSnapshot(isolate)),
+          new NavMenuItemElement('persistent handles', queue: _r.queue,
+              link: Uris.persistentHandles(isolate)),
+          new NavMenuItemElement('ports', queue: _r.queue,
+              link: Uris.ports(isolate)),
+          new NavMenuItemElement('logging', queue: _r.queue,
+              link: Uris.logging(isolate)),
+          new ContentElement()
+        ]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/isolate_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/isolate_menu_wrapper.dart
new file mode 100644
index 0000000..ff4e1ed
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/isolate_menu_wrapper.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+
+@bindable
+class NavIsolateMenuElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavIsolateMenuElementWrapper>(const {
+      'last':  #last, 'isolate': #isolate
+    });
+
+  static const tag =
+    const Tag<NavIsolateMenuElementWrapper>('isolate-nav-menu');
+
+  bool _last = false;
+  Isolate _isolate;
+  
+  bool get last => _last;
+  Isolate get isolate => _isolate;
+
+  set last(bool value) {
+    _last = value;
+    render();
+  }
+  set isolate(Isolate value) {
+    _isolate = value;
+    render();
+  }
+
+  NavIsolateMenuElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _last = _getBoolAttribute('last');
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_isolate == null || _last == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new NavIsolateMenuElement(_isolate, app.events, last: _last,
+          queue: app.queue)
+        ..children = [new ContentElement()]
+    ];
+  }
+
+  ObservatoryApplication get app => ObservatoryApplication.app;
+
+  bool _getBoolAttribute(String name) {
+    final String value = getAttribute(name);
+    return !(value == null || value == 'false');
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/library_menu.dart b/runtime/observatory/lib/src/elements/nav/library_menu.dart
new file mode 100644
index 0000000..36160d6
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/library_menu.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M show IsolateRef, LibraryRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+
+class NavLibraryMenuElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavLibraryMenuElement>('nav-library-menu',
+                     dependencies: const [NavMenuElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavLibraryMenuElement>> get onRendered => _r.onRendered;
+
+  bool _last;
+  M.IsolateRef _isolate;
+  M.LibraryRef _library;
+
+  bool get last => _last;
+  M.IsolateRef get isolate => _isolate;
+  M.LibraryRef get library => _library;
+  
+  set last(bool value) => _last = _r.checkAndReact(_last, value);
+
+  factory NavLibraryMenuElement(M.IsolateRef isolate, M.LibraryRef library,
+      {bool last: false, RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(library != null);
+    assert(last != null);
+    NavLibraryMenuElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._library = library;
+    e._last = last;
+    return e;
+  }
+
+  NavLibraryMenuElement.created() : super.created() { createShadowRoot(); }
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    shadowRoot.children = [];
+  }
+
+  void render() {
+    shadowRoot.children = [
+      new NavMenuElement(library.name, last: last, queue: _r.queue,
+                link: Uris.inspect(isolate, object: library).toString())
+        ..children = [new ContentElement()]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/library_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/library_menu_wrapper.dart
new file mode 100644
index 0000000..8db0347
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/library_menu_wrapper.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+
+@bindable
+class NavLibraryMenuElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavLibraryMenuElementWrapper>(const {
+      'last': #last, 'library': #library
+    });
+
+  static const tag =
+    const Tag<NavLibraryMenuElementWrapper>('library-nav-menu');
+
+  bool _last = false;
+  Library _library;
+
+  bool get last => _last;
+  Library get library => _library;
+  
+  set last(bool value) {
+    _last = value;
+    render();
+  }
+  set library(Library value) {
+    _library = value;
+    render();
+  }
+
+  NavLibraryMenuElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _last = _getBoolAttribute('last');
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_library == null || _last == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new NavLibraryMenuElement(library.isolate, library, last: last,
+                                 queue: ObservatoryApplication.app.queue)
+        ..children = [new ContentElement()]
+    ];
+  }
+
+  bool _getBoolAttribute(String name) {
+    final String value = getAttribute(name);
+    return !(value == null || value == 'false');
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/menu.dart b/runtime/observatory/lib/src/elements/nav/menu.dart
new file mode 100644
index 0000000..2624ad7
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/menu.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+
+class NavMenuElement extends HtmlElement implements Renderable {
+  static final StyleElement _style = () {
+      var style = new StyleElement();
+      style.text = '''li.nav-menu_label, li.nav-menu_spacer {
+                        float: left;
+                      }
+                      li.nav-menu_label > a, li.nav-menu_spacer {
+                        display: block;
+                        padding: 12px 8px;
+                        color: White;
+                        text-decoration: none;
+                      }
+                      li.nav-menu_label:hover {
+                        background: #455;
+                      }
+                      li.nav-menu_label > ul {
+                        display: none;
+                        position: absolute;
+                        top: 98%;
+                        list-style: none;
+                        margin: 0;
+                        padding: 0;
+                        width: auto;
+                        z-index: 1000;
+                        font: 400 16px \'Montserrat\', sans-serif;
+                        color: white;
+                        background: #567;
+                      }
+                      li.nav-menu_label > ul:after {
+                        content: ""; clear: both; display: block;
+                      }
+                      li.nav-menu_label:hover > ul {
+                        display: block;
+                      }''';
+      return style;
+  }();
+
+  static const tag = const Tag<NavMenuElement>('nav-menu-wrapped');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavMenuElement>> get onRendered => _r.onRendered;
+
+  String _label;
+  String _link;
+  bool _last;
+
+  String get label => _label;
+  String get link => _link;
+  bool get last => _last;
+  
+  set label(String value) => _label = _r.checkAndReact(_label, value);
+  set link(String value) => _link = _r.checkAndReact(_link, value);
+  set last(bool value) => _last = _r.checkAndReact(_link, value);
+
+  factory NavMenuElement(String label, {String link, bool last: false,
+                             RenderingQueue queue}) {
+    assert(label != null);
+    assert(last != null);
+    NavMenuElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._label = label;
+    e._link = link;
+    e._last = last;
+    return e;
+  }
+
+  NavMenuElement.created() : super.created() { createShadowRoot(); }
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    shadowRoot.children = [];
+  }
+
+  void render() {
+    List<Element> children = [
+      _style.clone(true),
+      new LIElement()
+        ..classes = ['nav-menu_label']
+        ..children = [
+          new AnchorElement(href: link)
+            ..text = label,
+          new UListElement()
+            ..children = [
+              new ContentElement()
+            ]
+        ]
+    ];
+    if (!last) {
+      children.add(
+        new LIElement()
+          ..classes = ['nav-menu_spacer']
+          ..innerHtml = '&gt;'
+      );
+    }
+    shadowRoot.children = children;
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/menu_item.dart b/runtime/observatory/lib/src/elements/nav/menu_item.dart
new file mode 100644
index 0000000..03ced3d
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/menu_item.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+
+class NavMenuItemElement extends HtmlElement implements Renderable {
+  static final StyleElement _style = () {
+      var style = new StyleElement();
+      style.text = '''li.nav-menu-item {
+                        float: none;
+                        border-top: 1px solid #677;
+                        border-bottom: 1px solid #556; position: relative;
+                      }
+                      li.nav-menu-item:hover {
+                        background: #455;
+                      }
+                      li.nav-menu-item > a {
+                        display: block;
+                        padding: 12px 12px;
+                        color: white;
+                        text-decoration: none;
+                      }
+                      li.nav-menu-item > ul {
+                        display: none;
+                        position: absolute;
+                        top:0;
+                        left: 100%;
+                        list-style: none;
+                        padding: 0;
+                        margin-left: 0;
+                        width: auto;
+                        z-index: 1000;
+                        font: 400 16px \'Montserrat\', sans-serif;
+                        color: white;
+                        background: #567;
+                      }
+                      li.nav-menu-item > ul:after {
+                        content: ""; clear: both; display: block;
+                      }
+                      li.nav-menu-item:hover > ul {
+                        display: block;
+                      }''';
+      return style;
+  }();
+
+  static const tag = const Tag<NavMenuItemElement>('nav-menu-item-wrapped');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavMenuItemElement>> get onRendered => _r.onRendered;
+
+  String _label;
+  String _link;
+
+  String get label => _label;
+  String get link => _link;
+  
+  set label(String value) => _label = _r.checkAndReact(_label, value);
+  set link(String value) => _link = _r.checkAndReact(_link, value);
+
+
+  factory NavMenuItemElement(String label, {String link,
+                             RenderingQueue queue}) {
+    assert(label != null);
+    NavMenuItemElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._label = label;
+    e._link = link;
+    return e;
+  }
+
+  NavMenuItemElement.created() : super.created() { createShadowRoot(); }
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    shadowRoot.children = [];
+  }
+
+  void render() {
+    shadowRoot.children = [
+      _style.clone(true),
+      new LIElement()
+        ..classes = ['nav-menu-item']
+        ..children = [
+          new AnchorElement(href: link)
+            ..text = label,
+          new UListElement()
+            ..children = [
+              new ContentElement()
+            ]
+        ]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/menu_item_wrapper.dart b/runtime/observatory/lib/src/elements/nav/menu_item_wrapper.dart
new file mode 100644
index 0000000..e00699c
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/menu_item_wrapper.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.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/menu_item.dart';
+
+@bindable
+class NavMenuItemElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavMenuItemElementWrapper>(const {
+      'anchor': #anchor, 'link': #link
+    });
+
+  static const tag =
+    const Tag<NavMenuItemElementWrapper>('nav-menu-item');
+
+  String _anchor;
+  String _link;
+
+  String get anchor => _anchor;
+  String get link => _link;
+  
+  set anchor(String value) {
+    _anchor = value;
+    render();
+  }
+  set link(String value) {
+    _link = value;
+    render();
+  }
+
+  NavMenuItemElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _anchor = getAttribute('anchor');
+    _link = getAttribute('link');
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_anchor == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new NavMenuItemElement(_anchor, link: '#$link',
+                                 queue: ObservatoryApplication.app.queue)
+        ..children = [new ContentElement()]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/menu_wrapper.dart
new file mode 100644
index 0000000..3b287fe
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/menu_wrapper.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+
+@bindable
+class NavMenuElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavMenuElementWrapper>(const {
+      'anchor': #anchor, 'link': #link, 'last': #last
+    });
+
+  static const tag =
+    const Tag<NavMenuElementWrapper>('nav-menu');
+
+  String _anchor = '---';
+  String _link;
+  bool _last = false;
+
+  String get anchor => _anchor;
+  String get link => _link;
+  bool get last => _last;
+  
+  set anchor(String value) {
+    _anchor = value;
+    render();
+  }
+  set link(String value) {
+    _link = value;
+    render();
+  }
+  set last(bool value) {
+    _last = value;
+    render();
+  }
+
+  NavMenuElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _anchor = getAttribute('anchor');
+    _link = getAttribute('link');
+    _last = _getBoolAttribute('last');
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_anchor == null || _last == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new NavMenuElement(_anchor, link: '#$_link', last: last,
+                                 queue: ObservatoryApplication.app.queue)
+        ..children = [new ContentElement()]
+    ];
+  }
+
+  bool _getBoolAttribute(String name) {
+    final String value = getAttribute(name);
+    return !(value == null || value == 'false');
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/notify.dart b/runtime/observatory/lib/src/elements/nav/notify.dart
new file mode 100644
index 0000000..1566a04
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/notify.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/nav/notify_event.dart';
+import 'package:observatory/src/elements/nav/notify_exception.dart';
+
+class NavNotifyElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavNotifyElement>('nav-notify-wrapped',
+          dependencies: const [ NavNotifyEventElement.tag,
+                                NavNotifyExceptionElement.tag ]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavNotifyElement>> get onRendered => _r.onRendered;
+
+  M.NotificationRepository _repository;
+  StreamSubscription _subscription;
+
+  bool _notifyOnPause;
+
+  bool get notifyOnPause => _notifyOnPause;
+  
+  set notifyOnPause(bool value) =>
+      _notifyOnPause = _r.checkAndReact(_notifyOnPause, value);
+
+  factory NavNotifyElement(M.NotificationRepository repository,
+                           {bool notifyOnPause: true, RenderingQueue queue}) {
+    assert(repository != null);
+    assert(notifyOnPause != null);
+    NavNotifyElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._repository = repository;
+    e._notifyOnPause = notifyOnPause;
+    return e;
+  }
+
+  NavNotifyElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _subscription = _repository.onChange.listen((_) => _r.dirty());
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+    _subscription.cancel();
+  }
+
+  void render() {
+    children = [
+      new DivElement()
+        ..children = [
+          new DivElement()
+            ..children = _repository.list()
+              .where(_filter).map(_toElement).toList()
+        ]
+    ];
+  }
+
+  bool _filter(M.Notification notification) {
+    if (!_notifyOnPause && notification is M.EventNotification) {
+      return !M.Event.isPauseEvent(notification.event);
+    }
+    return true;
+  }
+
+  HtmlElement _toElement(M.Notification notification) {
+    if (notification is M.EventNotification) {
+      return new NavNotifyEventElement(notification.event, queue: _r.queue)
+          ..onDelete.listen((_) => _repository.delete(notification));
+    } else if (notification is M.ExceptionNotification) {
+      return new NavNotifyExceptionElement(
+              notification.exception, stacktrace: notification.stacktrace,
+              queue: _r.queue)
+          ..onDelete.listen((_) => _repository.delete(notification));
+    } else {
+      assert(false);
+      return new DivElement()..text = 'Invalid Notification Type';
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/notify_event.dart b/runtime/observatory/lib/src/elements/nav/notify_event.dart
new file mode 100644
index 0000000..b46236e
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/notify_event.dart
@@ -0,0 +1,233 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class EventDeleteEvent{
+  final M.Event event;
+  EventDeleteEvent(this.event);
+}
+
+class NavNotifyEventElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavNotifyEventElement>('nav-event');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavNotifyEventElement>> get onRendered => _r.onRendered;
+
+  final StreamController<EventDeleteEvent> _onDelete =
+      new StreamController<EventDeleteEvent>.broadcast();
+  Stream<EventDeleteEvent> get onDelete => _onDelete.stream;
+
+  M.Event _event;
+  
+  M.Event get event => _event;
+
+  factory NavNotifyEventElement(M.Event event, {RenderingQueue queue}) {
+    assert(event != null);
+    NavNotifyEventElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._event = event;
+    return e;
+  }
+
+  NavNotifyEventElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [];
+    List<Element> content;
+    if (event is M.PauseStartEvent) {
+      content = _managePauseStartEvent(event as M.PauseStartEvent);
+    } else if (event is M.PauseExitEvent) {
+      content = _managePauseExitEvent(event as M.PauseExitEvent);
+    } else if (event is M.PauseBreakpointEvent) {
+      content = _managePauseBreakpointEvent(event as M.PauseBreakpointEvent);
+    } else if (event is M.PauseInterruptedEvent) {
+      content = _managePauseInterruptedEvent(event as M.PauseInterruptedEvent);
+    } else if (event is M.PauseExceptionEvent) {
+      content = _managePauseExceptionEvent(event as M.PauseExceptionEvent);
+    } else if (event is M.NoneEvent) {
+      content = _manageNoneEvent(event as M.NoneEvent);
+    } else if (event is M.ConnectionClosedEvent) {
+      content = _manageConnectionClosedEvent(event as M.ConnectionClosedEvent);
+    } else if (event is M.InspectEvent) {
+      content = _manageInspectEvent(event as M.InspectEvent);
+    } else if (event is M.IsolateReloadEvent) {
+      content = _manageIsolateReloadEvent(event as M.IsolateReloadEvent);
+    } else {
+      return;
+    }
+    children = [
+      new DivElement()
+        ..children = []
+        ..children.addAll(content)
+        ..children.add(new ButtonElement()..innerHtml = '&times;'
+            ..onClick.map(_toEvent).listen(_delete))
+    ];
+  }
+
+  static List<Element> _managePauseStartEvent(M.PauseStartEvent event) {
+    return [
+      new SpanElement()..text = 'Isolate ',
+      new AnchorElement(
+        href: Uris.inspect(event.isolate))
+        ..text = event.isolate.name,
+      new SpanElement()..text = ' is paused at isolate start',
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(
+        href: Uris.debugger(event.isolate))
+        ..text = 'debug',
+      new SpanElement()..text = ']'
+    ];
+  }
+
+  static List<Element> _managePauseExitEvent(M.PauseExitEvent event) {
+    return [
+      new SpanElement()..text = 'Isolate ',
+      new AnchorElement(
+        href: Uris.inspect(event.isolate))
+        ..text = event.isolate.name,
+      new SpanElement()..text = ' is paused at isolate exit',
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(
+        href: Uris.debugger(event.isolate))
+        ..text = 'debug',
+      new SpanElement()..text = ']'
+    ];
+  }
+
+  static List<Element> _managePauseBreakpointEvent(M.PauseBreakpointEvent event) {
+    String message = ' is paused';
+    if (event.breakpoint != null) {
+       message += ' at breakpoint ${event.breakpoint.number}';
+    }
+    return [
+      new SpanElement()..text = 'Isolate ',
+      new AnchorElement(
+        href: Uris.inspect(event.isolate))
+        ..text = event.isolate.name,
+      new SpanElement()
+        ..text = message,
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(
+        href: Uris.debugger(event.isolate))
+        ..text = 'debug',
+      new SpanElement()..text = ']'
+    ];
+  }
+
+  static List<Element> _managePauseInterruptedEvent(M.PauseInterruptedEvent event) {
+    return [
+      new SpanElement()..text = 'Isolate ',
+      new AnchorElement(
+        href: Uris.inspect(event.isolate))
+        ..text = event.isolate.name,
+      new SpanElement()
+        ..text = ' is paused',
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(
+        href: Uris.debugger(event.isolate))
+        ..text = 'debug',
+      new SpanElement()..text = ']'
+    ];
+  }
+
+  static List<Element> _managePauseExceptionEvent(M.PauseExceptionEvent event) {
+    return [
+      new SpanElement()..text = 'Isolate ',
+      new AnchorElement(
+        href: Uris.inspect(event.isolate))
+        ..text = event.isolate.name,
+      new SpanElement()
+        ..text = ' is paused due to exception',
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(
+        href: Uris.debugger(event.isolate))
+        ..text = 'debug',
+      new SpanElement()..text = ']'
+    ];
+  }
+
+  static List<Element> _manageNoneEvent(M.NoneEvent event) {
+    return [
+      new SpanElement()..text = 'Isolate ',
+      new AnchorElement(
+        href: Uris.inspect(event.isolate))
+        ..text = event.isolate.name,
+      new SpanElement()
+        ..text = ' is paused',
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(
+        href: Uris.debugger(event.isolate))
+        ..text = 'debug',
+      new SpanElement()..text = ']'
+    ];
+  }
+
+  static List<Element> _manageConnectionClosedEvent(M.ConnectionClosedEvent event) {
+    return [
+      new SpanElement()..text = 'Disconnected from VM: ${event.reason}',
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(href: Uris.vmConnect())..text = 'Connect to a VM',
+      new SpanElement()..text = ']'
+    ];
+  }
+
+  static List<Element> _manageInspectEvent(M.InspectEvent event) {
+    return [
+      new SpanElement()..text = 'Inspect ${event.inspectee.id}',
+      new BRElement(), new BRElement(), new SpanElement()..text = '[',
+      new AnchorElement(href: Uris.inspect(event.isolate,
+          object: event.inspectee))
+        ..text = 'Inspect',
+      new SpanElement()..text = ']'
+      // TODO(cbernaschina) add InstanceRefElement back.
+      //new InstanceRefElement()..instance = event.inspectee
+    ];
+  }
+
+  static List<Element> _manageIsolateReloadEvent(M.IsolateReloadEvent event) {
+    if (event.error != null) {
+      return [
+        new SpanElement()..text = 'Isolate reload failed:',
+        new BRElement(), new BRElement(),
+        new DivElement()
+          ..classes = ["indent", "error"]
+          ..text = event.error.message.toString()
+      ];
+    } else {
+      return [new SpanElement()..text = 'Isolate reload'];
+    }
+  }
+
+  EventDeleteEvent _toEvent(_) {
+    return new EventDeleteEvent(_event);
+  }
+
+  void _delete(EventDeleteEvent e) {
+    _onDelete.add(e);
+  }
+
+  void delete() {
+    _onDelete.add(new EventDeleteEvent(_event));
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/notify_exception.dart b/runtime/observatory/lib/src/elements/nav/notify_exception.dart
new file mode 100644
index 0000000..0e92bda
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/notify_exception.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.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/models.dart' show ConnectionException;
+
+
+class ExceptionDeleteEvent{
+  final Exception exception;
+  final StackTrace stacktrace;
+
+  ExceptionDeleteEvent(this.exception, {this.stacktrace});
+}
+
+class NavNotifyExceptionElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavNotifyExceptionElement>('nav-exception');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavNotifyExceptionElement>> get onRendered =>
+                                                                  _r.onRendered;
+
+  final StreamController<ExceptionDeleteEvent> _onDelete =
+      new StreamController<ExceptionDeleteEvent>.broadcast();
+  Stream<ExceptionDeleteEvent> get onDelete => _onDelete.stream;
+
+  Exception _exception;
+  StackTrace _stacktrace;
+  
+  Exception get exception => _exception;
+  StackTrace get stacktrace => _stacktrace;
+
+  factory NavNotifyExceptionElement(Exception exception,
+      {StackTrace stacktrace: null, RenderingQueue queue}) {
+    assert(exception != null);
+    NavNotifyExceptionElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._exception = exception;
+    e._stacktrace = stacktrace;
+    return e;
+  }
+
+  NavNotifyExceptionElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    if (exception is ConnectionException) {
+      renderConnectionException();
+    } else {
+      renderGenericException();
+    }
+  }
+
+  void renderConnectionException() {
+    children = [
+      new DivElement()
+        ..children = [
+        new SpanElement()..text = 'The request cannot be completed because the '
+                                  'VM is currently disconnected',
+        new BRElement(), new BRElement(),
+        new SpanElement()..text = '[',
+        new AnchorElement(href: Uris.vmConnect())
+          ..text = 'Connect to a different VM',
+        new SpanElement()..text = ']',
+        new ButtonElement()..innerHtml = '&times;'
+          ..onClick.map(_toEvent).listen(_delete)
+      ]
+    ];
+  }
+
+  void renderGenericException() {
+    List<Node> content;
+    content = [
+      new SpanElement()..text = 'Unexpected exception:',
+      new BRElement(), new BRElement(),
+      new DivElement()..text = exception.toString(),
+      new BRElement()
+    ];
+    if (stacktrace != null) {
+      content.addAll([
+        new SpanElement()..text = 'Stacktrace:',
+        new BRElement(), new BRElement(),
+        new DivElement()..text = stacktrace.toString(),
+        new BRElement()
+      ]);
+    }
+    content.addAll([
+      new SpanElement()..text = '[',
+      new AnchorElement(href: Uris.vmConnect())
+        ..text = 'Connect to a different VM',
+      new SpanElement()..text = ']',
+      new ButtonElement()..innerHtml = '&times;'
+        ..onClick.map(_toEvent).listen(_delete)
+    ]);
+    children = [
+      new DivElement()
+        ..children = content
+    ];
+  }
+
+  ExceptionDeleteEvent _toEvent(_) {
+    return new ExceptionDeleteEvent(exception, stacktrace: stacktrace);
+  }
+
+  void _delete(ExceptionDeleteEvent e) {
+    _onDelete.add(e);
+  }
+
+  void delete() {
+    _onDelete.add(new ExceptionDeleteEvent(exception, stacktrace: stacktrace));
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/notify_wrapper.dart b/runtime/observatory/lib/src/elements/nav/notify_wrapper.dart
new file mode 100644
index 0000000..58dbf39
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/notify_wrapper.dart
@@ -0,0 +1,131 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+
+@bindable
+class NavNotifyElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavNotifyElementWrapper>(const {
+      'notifications': #notifications, 'notifyOnPause': #notifyOnPause
+    });
+
+  static const tag = const Tag<NavNotifyElementWrapper>('nav-notify');
+
+  NotificationRepository _notifications;
+  bool _notifyOnPause = true;
+
+  NotificationRepository get notifications => _notifications;
+  bool get notifyOnPause => _notifyOnPause;
+  
+  set notifications(NotificationRepository value) {
+    _notifications = value;
+    render();
+  }
+  set notifyOnPause(bool value) {
+    _notifyOnPause = value;
+    render();
+  }
+
+  NavNotifyElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_notifications == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''nav-notify-wrapped > div {
+          float: right;
+        }
+        nav-notify-wrapped > div > div {
+          display: block;
+          position: absolute;
+          top: 98%;
+          right: 0;
+          margin: 0;
+          padding: 0;
+          width: auto;
+          z-index: 1000;
+          background: none;
+        }
+
+        /* nav-exception & nav-event */
+
+        nav-exception > div, nav-event > div {
+          position: relative;
+          padding: 16px;
+          margin-top: 10px;
+          margin-right: 10px;
+          padding-right: 25px;
+          width: 500px;
+          color: #ddd;
+          background: rgba(0,0,0,.6);
+          border: solid 2px white;
+          box-shadow: 0 0 5px black;
+          border-radius: 5px;
+          animation: fadein 1s;
+        }
+
+        nav-exception *, nav-event * {
+          color: #ddd;
+          font-size: 12px;
+        }
+
+        nav-exception > div > a, nav-event > div > a {
+          color: white;
+          text-decoration: none;
+        }
+
+        nav-exception > div > a:hover, nav-event > div > a:hover {
+          text-decoration: underline;
+        }
+
+        nav-exception > div > div {
+          margin-left:20px;
+          white-space: pre
+        }
+
+        nav-exception > div > button, nav-event > div > button {
+          background: transparent;
+          border: none;
+          position: absolute;
+          display: block;
+          top: 4px;
+          right: 4px;
+          height: 18px;
+          width: 18px;
+          line-height: 16px;
+          border-radius: 9px;
+          color: white;
+          font-size: 18px;
+          cursor: pointer;
+          text-align: center;
+        }
+
+        nav-exception > div > button:hover, nav-event > div > button:hover {
+          background: rgba(255,255,255,0.5);
+        }''',
+      new NavNotifyElement(_notifications, notifyOnPause: notifyOnPause,
+                                 queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/refresh.dart b/runtime/observatory/lib/src/elements/nav/refresh.dart
new file mode 100644
index 0000000..da40abd
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/refresh.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+
+class RefreshEvent {
+  final NavRefreshElement element;
+  RefreshEvent(this.element);
+}
+
+class NavRefreshElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavRefreshElement>('nav-refresh-wrapped');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavRefreshElement>> get onRendered => _r.onRendered;
+
+  final StreamController<RefreshEvent> _onRefresh =
+                                new StreamController<RefreshEvent>.broadcast();
+  Stream<RefreshEvent> get onRefresh => _onRefresh.stream;
+
+  bool _disabled;
+  String _label;
+
+  bool get disabled => _disabled;
+  String get label => _label;
+  
+  set disabled(bool value) => _disabled = _r.checkAndReact(_disabled, value);
+  set label(String value) => _label = _r.checkAndReact(_label, value);
+
+  factory NavRefreshElement({String label: 'Refresh', bool disabled: false,
+                             RenderingQueue queue}) {
+    assert(label != null);
+    assert(disabled != null);
+    NavRefreshElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._label = label;
+    e._disabled = disabled;
+    return e;
+  }
+
+  NavRefreshElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [
+      new LIElement()
+        ..children = [
+          new ButtonElement()
+            ..text = label
+            ..disabled = disabled
+            ..onClick.map(_toEvent).listen(_refresh)
+        ]
+    ];
+  }
+
+  RefreshEvent _toEvent(_) {
+    return new RefreshEvent(this);
+  }
+
+  void _refresh(RefreshEvent e) {
+    if (_disabled) return;
+    _onRefresh.add(e);
+  }
+
+  void refresh() {
+    if (_disabled) return;
+    _refresh(new RefreshEvent(this));
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/refresh_wrapper.dart b/runtime/observatory/lib/src/elements/nav/refresh_wrapper.dart
new file mode 100644
index 0000000..1989a10
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/refresh_wrapper.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+
+@bindable
+class NavRefreshElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavRefreshElementWrapper>(const {
+      'callback': #callback, 'label': #label
+    });
+
+  static const tag = const Tag<NavRefreshElementWrapper>('nav-refresh');
+
+  Function _callback;
+  String _label;
+  
+  Function get callback => _callback;
+  String get label => _label;
+
+  set callback(Function value) {
+    _callback = value;
+    render();
+  }
+  set label(String value) {
+    _label = value;
+    render();
+  }
+
+  NavRefreshElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _label = getAttribute('label') ?? 'Refresh';
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_callback == null || _label == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''nav-refresh-wrapped > li > button {
+          color: #000;
+          margin: 3px;
+          padding: 8px;
+          border-width: 2px;
+          line-height: 13px;
+          font: 400 13px 'Montserrat', sans-serif;
+        }
+        nav-refresh-wrapped > li > button[disabled] {
+          color: #aaa;
+          cursor: wait;
+        }
+        nav-refresh-wrapped > li {
+          float: right;
+          margin: 0;
+        }''',
+      new NavRefreshElement(label: _label,
+                            queue: ObservatoryApplication.app.queue)
+        ..onRefresh.listen((event) async{
+          event.element.disabled = true;
+          try {
+            var future = callback();
+            if (future is Future) await future;
+          } finally {
+            event.element.disabled = false;
+          }
+        })
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/top_menu.dart b/runtime/observatory/lib/src/elements/nav/top_menu.dart
new file mode 100644
index 0000000..f4c6fa1
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/top_menu.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.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/menu_item.dart';
+
+class NavTopMenuElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavTopMenuElement>('nav-top-menu',
+                     dependencies: const [NavMenuElement.tag,
+                                          NavMenuItemElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavTopMenuElement>> get onRendered => _r.onRendered;
+
+  bool _last;
+  
+  bool get last => _last;
+
+  set last(bool value) => _last = _r.checkAndReact(_last, value);
+
+  factory NavTopMenuElement({bool last: false, RenderingQueue queue}) {
+    assert(last != null);
+    NavTopMenuElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._last = last;
+    return e;
+  }
+
+  NavTopMenuElement.created() : super.created() { createShadowRoot(); }
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    shadowRoot.children = [];
+  }
+
+  void render() {
+    shadowRoot.children = [
+      new NavMenuElement('Observatory', link: Uris.vm(), last: last,
+                         queue: _r.queue)
+        ..children = [
+          new NavMenuItemElement('Connect to a VM', link: Uris.vmConnect(),
+                                 queue: _r.queue),
+          new ContentElement()
+        ]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/top_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/top_menu_wrapper.dart
new file mode 100644
index 0000000..db99fff
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/top_menu_wrapper.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+
+@bindable
+class NavTopMenuElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavTopMenuElementWrapper>(const {
+      'last': #last
+    });
+
+  static const tag = const Tag<NavTopMenuElementWrapper>('top-nav-menu');
+
+  bool _last = false;
+  
+  bool get last => _last;
+
+  set last(bool value) {
+    _last = value;
+    render();
+  }
+
+  NavTopMenuElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _last = _getBoolAttribute('last');
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_last == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new NavTopMenuElement(last: last, queue: ObservatoryApplication.app.queue)
+        ..children = [new ContentElement()]
+    ];
+  }
+
+  bool _getBoolAttribute(String name) {
+    final String value = getAttribute(name);
+    return !(value == null || value == 'false');
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/vm_menu.dart b/runtime/observatory/lib/src/elements/nav/vm_menu.dart
new file mode 100644
index 0000000..e4351af
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/vm_menu.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show VM, EventRepository;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/menu_item.dart';
+
+class NavVMMenuElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<NavVMMenuElement>('nav-vm-menu',
+                     dependencies: const [NavMenuElement.tag,
+                                          NavMenuItemElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<NavVMMenuElement>> get onRendered => _r.onRendered;
+
+  bool _last;
+  M.VM _vm;
+  M.EventRepository _events;
+  StreamSubscription _updatesSubscription;
+
+
+  bool get last => _last;
+  M.VM get vm => _vm;
+
+  set last(bool value) => _last = _r.checkAndReact(_last, value);
+
+  factory NavVMMenuElement(M.VM vm, M.EventRepository events, {bool last: false,
+    RenderingQueue queue}) {
+    assert(vm != null);
+    assert(events != null);
+    assert(last != null);
+    NavVMMenuElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._events = events;
+    e._last = last;
+    return e;
+  }
+
+  NavVMMenuElement.created() : super.created() { createShadowRoot(); }
+
+  @override
+  void attached() {
+    super.attached();
+    _updatesSubscription = _events.onVMUpdate
+        .listen((e) { _vm = e.vm; _r.dirty(); });
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    shadowRoot.children = [];
+    _r.disable(notify: true);
+    _updatesSubscription.cancel();
+  }
+
+  void render() {
+    shadowRoot.children = [
+      new NavMenuElement(vm.displayName, link: Uris.vm(), last: last,
+          queue: _r.queue)
+        ..children = (
+          _vm.isolates.map((isolate) {
+            return new NavMenuItemElement(isolate.name, queue: _r.queue,
+                link: Uris.inspect(isolate));
+          }).toList()
+          ..add(new ContentElement())
+        )
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav/vm_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/vm_menu_wrapper.dart
new file mode 100644
index 0000000..ef8bf3d
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/nav/vm_menu_wrapper.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service.dart';
+import 'package:observatory/service_common.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+
+@bindable
+class NavVMMenuElementWrapper extends HtmlElement {
+  static const binder = const Binder<NavVMMenuElementWrapper>(const {
+      'last': #last, 'vm': #vm
+    });
+
+  static const tag = const Tag<NavVMMenuElementWrapper>('vm-nav-menu');
+
+  bool _last = false;
+  VM _vm;
+
+  bool get last => _last;
+  VM get vm => _vm;
+
+  set last(bool value) {
+    _last = value;
+    render(); }
+  set vm(VM value) {
+    _vm = value;
+    render();
+  }
+
+  NavVMMenuElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    _last = _getBoolAttribute('last');
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_vm == null || _last == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new NavVMMenuElement(vm, app.events, last: last,
+          queue: app.queue)
+        ..children = [new ContentElement()]
+    ];
+  }
+
+  ObservatoryApplication get app => ObservatoryApplication.app;
+
+  bool _getBoolAttribute(String name) {
+    final String value = getAttribute(name);
+    return !(value == null || value == 'false');
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/nav_bar.dart b/runtime/observatory/lib/src/elements/nav_bar.dart
deleted file mode 100644
index 3999db87..0000000
--- a/runtime/observatory/lib/src/elements/nav_bar.dart
+++ /dev/null
@@ -1,164 +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 nav_bar_element;
-
-import 'dart:async';
-import 'dart:html' hide Notification;
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:observatory/app.dart' show Notification;
-import 'package:polymer/polymer.dart';
-
-
-@CustomTag('nav-bar')
-class NavBarElement extends ObservatoryElement {
-  @published bool notifyOnPause = true;
-  @published bool pad = true;
-
-  // Desired nav var height in pixels.
-  static const height = 40;
-
-  NavBarElement.created() : super.created();
-}
-
-@CustomTag('nav-menu')
-class NavMenuElement extends ObservatoryElement {
-  @published String link = '#';
-  @published String anchor = '---';
-  @published bool last = false;
-
-  NavMenuElement.created() : super.created();
-}
-
-@CustomTag('nav-menu-item')
-class NavMenuItemElement extends ObservatoryElement {
-  @published String link = '#';
-  @published String anchor = '---';
-
-  NavMenuItemElement.created() : super.created();
-}
-
-typedef Future RefreshCallback();
-
-@CustomTag('nav-refresh')
-class NavRefreshElement extends ObservatoryElement {
-  @published RefreshCallback callback;
-  @published bool active = false;
-  @published String label = 'Refresh';
-
-  NavRefreshElement.created() : super.created();
-
-  void buttonClick(Event e, var detail, Node target) {
-    if (active) {
-      return;
-    }
-    active = true;
-    if (callback != null) {
-      callback()
-        .catchError(app.handleException)
-        .whenComplete(refreshDone);
-    }
-  }
-
-  void refreshDone() {
-    active = false;
-  }
-}
-
-@CustomTag('top-nav-menu')
-class TopNavMenuElement extends ObservatoryElement {
-  @published bool last = false;
-
-  TopNavMenuElement.created() : super.created();
-}
-
-@CustomTag('vm-nav-menu')
-class VMNavMenuElement extends ObservatoryElement {
-  @published bool last = false;
-  @published VM vm;
-
-  String nameAndAddress(name, target) {
-    if (name != null && target != null) {
-      return '${name}@${target.networkAddress}';
-    } else {
-      return '<initializing>';
-    }
-  }
-
-  VMNavMenuElement.created() : super.created();
-}
-
-@CustomTag('isolate-nav-menu')
-class IsolateNavMenuElement extends ObservatoryElement {
-  @published bool last = false;
-  @published Isolate isolate;
-
-  IsolateNavMenuElement.created() : super.created();
-}
-
-@CustomTag('library-nav-menu')
-class LibraryNavMenuElement extends ObservatoryElement {
-  @published Library library;
-  @published bool last = false;
-
-  LibraryNavMenuElement.created() : super.created();
-}
-
-@CustomTag('class-nav-menu')
-class ClassNavMenuElement extends ObservatoryElement {
-  @published Class cls;
-  @published bool last = false;
-
-  ClassNavMenuElement.created() : super.created();
-}
-
-@CustomTag('nav-notify')
-class NavNotifyElement extends ObservatoryElement {
-  @published ObservableList<Notification> notifications;
-  @published bool notifyOnPause = true;
-
-  NavNotifyElement.created() : super.created();
-}
-
-@CustomTag('nav-notify-event')
-class NavNotifyEventElement extends ObservatoryElement {
-  @published ObservableList<Notification> notifications;
-  @published Notification notification;
-  @published ServiceEvent event;
-  @published bool notifyOnPause = true;
-
-  void closeItem(MouseEvent e, var detail, Element target) {
-    notifications.remove(notification);
-  }
-
-  NavNotifyEventElement.created() : super.created();
-}
-
-@CustomTag('nav-notify-exception')
-class NavNotifyExceptionElement extends ObservatoryElement {
-  @published ObservableList<Notification> notifications;
-  @published Notification notification;
-  @published var exception;
-  @published var stacktrace;
-
-  exceptionChanged() {
-    notifyPropertyChange(#isNetworkError, true, false);
-    notifyPropertyChange(#isUnexpectedError, true, false);
-  }
-
-  @observable get isNetworkError {
-    return (exception is NetworkRpcException);
-  }
-
-  @observable get isUnexpectedError {
-    return (exception is! NetworkRpcException);
-  }
-
-  void closeItem(MouseEvent e, var detail, Element target) {
-    notifications.remove(notification);
-  }
-
-  NavNotifyExceptionElement.created() : super.created();
-}
diff --git a/runtime/observatory/lib/src/elements/nav_bar.html b/runtime/observatory/lib/src/elements/nav_bar.html
deleted file mode 100644
index c97b1d1..0000000
--- a/runtime/observatory/lib/src/elements/nav_bar.html
+++ /dev/null
@@ -1,486 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="action_link.html">
-<link rel="import" href="observatory_element.html">
-
-<polymer-element name="nav-bar" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-      nav {
-        position: fixed;
-        width: 100%;
-        z-index: 1000;
-      }
-      nav ul {
-        display: inline-table;
-        position: relative;
-        list-style: none;
-        padding-left: 0;
-        margin-left: 0;
-        width: 100%;
-        z-index: 1000;
-        font: 400 16px 'Montserrat', sans-serif;
-        color: white;
-        background-color: #0489c3;
-      }
-      nav ul:after {
-        content: ""; clear: both; display: block;
-      }
-      .vertical-spacer {
-        height: 40px;
-        background-color: #0489c3;
-      }
-    </style>
-    <nav>
-      <ul>
-        <nav-notify notifications="{{ app.notifications }}"
-                    notifyOnPause="{{ notifyOnPause }}"></nav-notify>
-        <content></content>
-      </ul>
-    </nav>
-    <div class="vertical-spacer">
-    </div>
-    <template if="{{ pad }}">
-      <br>
-    </template>
-  </template>
-</polymer-element>
-
-<polymer-element name="nav-menu" extends="observatory-element">
-  <template>
-    <style>
-      .menu, .spacer {
-        float: left;
-      }
-      .menu a, .spacer {
-        display: block;
-        padding: 12px 8px;
-        color: White;
-        text-decoration: none;
-      }
-      .menu:hover {
-        background: #455;
-      }
-      .menu ul {
-        display: none;
-        position: absolute;
-        top: 98%;
-        list-style: none;
-        margin: 0;
-        padding: 0;
-        width: auto;
-        z-index: 1000;
-        font: 400 16px 'Montserrat', sans-serif;
-        color: white;
-        background: #567;
-      }
-      .menu ul:after {
-        content: ""; clear: both; display: block;
-      }
-      .menu:hover > ul {
-        display: block;
-      }
-    </style>
-
-    <li class="menu">
-      <a on-click="{{ goto }}" _href="{{ gotoLink(link) }}">{{ anchor }}</a>
-      <ul><content></content></ul>
-    </li>
-    <template if="{{ !last }}">
-      <li class="spacer">&gt;</li>
-    </template>
-
-  </template>
-</polymer-element>
-
-<polymer-element name="nav-menu-item" extends="observatory-element">
-  <template>
-    <style>
-      li {
-        float: none;
-        border-top: 1px solid #677;
-        border-bottom: 1px solid #556; position: relative;
-      }
-      li:hover {
-        background: #455;
-      }
-      li ul {
-        display: none;
-        position: absolute;
-        top:0;
-        left: 100%;
-        list-style: none;
-        padding: 0;
-        margin-left: 0;
-        width: auto;
-        z-index: 1000;
-        font: 400 16px 'Montserrat', sans-serif;
-        color: white;
-        background: #567;
-      }
-      li ul:after {
-        content: ""; clear: both; display: block;
-      }
-      li:hover > ul {
-        display: block;
-      }
-      li a {
-        display: block;
-        padding: 12px 12px;
-        color: white;
-        text-decoration: none;
-      }
-    </style>
-    <li><a on-click="{{ goto }}" _href="{{ gotoLink(link) }}">{{ anchor }}</a>
-      <ul><content></content></ul>
-    </li>
-  </template>
-</polymer-element>
-
-<polymer-element name="nav-refresh" extends="observatory-element">
-  <template>
-    <style>
-      .active {
-        color: #aaa;
-        cursor: wait;
-      }
-      .idle {
-        color: #000;
-      }
-      li {
-        float: right;
-        margin: 0;
-      }
-      li button {
-        margin: 3px;
-        padding: 8px;
-      }
-    </style>
-    <li>
-      <template if="{{ active }}">
-        <button class="active" on-click="{{ buttonClick }}">{{ label }}</button>
-      </template>
-      <template if="{{ !active }}">
-        <button class="idle" on-click="{{ buttonClick }}">{{ label }}</button>
-      </template>
-    </li>
-  </template>
-</polymer-element>
-
-<polymer-element name="top-nav-menu">
-  <template>
-    <nav-menu link="/vm" anchor="Observatory" last="{{ last }}">
-      <nav-menu-item link="/vm-connect" anchor="Connect to a VM"></nav-menu-item>
-      <content></content>
-    </nav-menu>
-  </template>
-</polymer-element>
-
-<polymer-element name="vm-nav-menu">
-  <template>
-    <nav-menu link="/vm" anchor="{{ nameAndAddress(vm.name, vm.target) }}" last="{{ last }}">
-      <template repeat="{{ isolate in vm.isolates }}">
-        <nav-menu-item link="{{ makeLink('/inspect', isolate) }}"
-	               anchor="{{ isolate.name }}"></nav-menu-item>
-      </template>
-      <content></content>
-    </nav-menu>
-  </template>
-</polymer-element>
-
-<polymer-element name="isolate-nav-menu" extends="observatory-element">
-  <template>
-    <nav-menu link="{{ makeLink('/inspect', isolate) }}" anchor="{{ isolate.name }}" last="{{ last }}">
-      <nav-menu-item link="{{ makeLink('/debugger', isolate) }}"
-                     anchor="debugger"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/class-tree', isolate) }}"
-                     anchor="class hierarchy"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/profiler', isolate) }}"
-                     anchor="cpu profile"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/profiler-table', isolate) }}"
-                     anchor="cpu profile (table)"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/allocation-profiler', isolate) }}"
-                     anchor="allocation profile"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/heap-map', isolate) }}"
-                     anchor="heap map"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/metrics', isolate) }}"
-                     anchor="metrics"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/heap-snapshot', isolate) }}"
-                     anchor="heap snapshot"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/persistent-handles', isolate) }}"
-                     anchor="persistent handles"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/ports', isolate) }}"
-                     anchor="ports"></nav-menu-item>
-      <nav-menu-item link="{{ makeLink('/logging', isolate) }}"
-                     anchor="logging"></nav-menu-item>
-      <content></content>
-    </nav-menu>
-  </template>
-</polymer-element>
-
-<polymer-element name="library-nav-menu" extends="observatory-element">
-  <template>
-    <nav-menu link="{{ makeLink('/inspect', library) }}"
-              anchor="{{ library.name }}" last="{{ last }}">
-      <content></content>
-    </nav-menu>
-  </template>
-</polymer-element>
-
-<polymer-element name="class-nav-menu" extends="observatory-element">
-  <template>
-    <nav-menu link="{{ makeLink('/inspect', cls) }}"
-              anchor="{{ cls.name }}" last="{{ last }}">
-      <content></content>
-    </nav-menu>
-  </template>
-</polymer-element>
-
-<polymer-element name="nav-notify" extends="observatory-element">
-  <template>
-    <style>
-      .menu {
-        float: right;
-      }
-      .menu .list {
-        display: block;
-        position: absolute;
-        top: 98%;
-        right: 0;
-        margin: 0;
-        padding: 0;
-        width: auto;
-        z-index: 1000;
-        font: 400 12px 'Montserrat', sans-serif;
-        color: white;
-        background: none;
-      }
-    </style>
-
-    <div class="menu">
-      <div class="list">
-        <template repeat="{{ notification in notifications }}">
-          <template if="{{ notification.event != null }}">
-            <nav-notify-event notifications="{{ notifications }}"
-                              notification="{{ notification }}"
-                              event="{{ notification.event }}"
-                              notifyOnPause="{{ notifyOnPause }}">
-            </nav-notify-event>
-          </template>
-          <template if="{{ notification.exception != null }}">
-            <nav-notify-exception notifications="{{ notifications }}"
-                              notification="{{ notification }}"
-                              exception="{{ notification.exception }}"
-                              stacktrace="{{ notification.stacktrace }}">
-            </nav-notify-exception>
-          </template>
-        </template>
-      </div>
-    </div>
-  </template>
-</polymer-element>
-
-<polymer-element name="nav-notify-event" extends="observatory-element">
-  <template>
-    <style>
-      .item {
-        position: relative;
-        padding: 16px;
-        margin-top: 10px;
-        margin-right: 10px;
-        padding-right: 25px;
-        width: 250px;
-        color: #ddd;
-        background: rgba(0,0,0,.6);
-        border: solid 2px white;
-        box-shadow: 0 0 5px black;
-        border-radius: 5px;
-        animation: fadein 1s;
-      }
-
-      .wide-item {
-        width: 50vw;
-      }
-
-      @keyframes fadein {
-        from { opacity: 0; }
-        to   { opacity: 1; }
-      }
-
-      a.link {
-        color: white;
-        text-decoration: none;
-      }
-      a.link:hover {
-        text-decoration: underline;
-      }
-
-      a.boxclose {
-        position: absolute;
-        display: block;
-        top: 4px;
-        right: 4px;
-        height: 18px;
-        width: 18px;
-        line-height: 16px;
-        border-radius: 9px;
-        color: white;
-        font-size: 18px;
-        cursor: pointer;
-        text-align: center;
-      }
-      a.boxclose:hover {
-        background: rgba(255,255,255,0.5);
-      }
-      .error {
-        white-space: pre;
-      }
-    </style>
-    <template if="{{ event != null }}">
-      <template if="{{ notifyOnPause && event.isPauseEvent }}">
-        <div class="item">
-          Isolate
-          <a class="link" on-click="{{ goto }}"
-             _href="{{ gotoLink('/inspect', event.isolate) }}">{{ event.isolate.name }}</a>
-          is paused
-          <template if="{{ event.kind == 'PauseStart' }}">
-            at isolate start
-          </template>
-          <template if="{{ event.kind == 'PauseExit' }}">
-            at isolate exit
-          </template>
-          <template if="{{ event.breakpoint != null }}">
-            at breakpoint {{ event.breakpoint.number }}
-          </template>
-          <template if="{{ event.kind == 'PauseException' }}">
-            due to exception
-          </template>
-
-          <br><br>
-          [<a class="link" on-click="{{ goto }}"
-              _href="{{ gotoLink('/debugger', event.isolate) }}">debug</a>]
-
-          <a class="boxclose" on-click="{{ closeItem }}">&times;</a>
-        </div>
-      </template>
-      <template if="{{ event.kind == 'ConnectionClosed' }}">
-        <div class="item">
-          Disconnected from VM: {{ event.reason }}
-          <br><br>
-          [<a class="link" on-click="{{ goto }}"
-              _href="{{ gotoLink('/vm-connect') }}">Connect to a VM</a>]
-          <a class="boxclose" on-click="{{ closeItem }}">&times;</a>
-        </div>
-      </template>
-      <template if="{{ event.kind == 'Inspect' }}">
-        <div class="item">
-          Inspect <any-service-ref ref="{{ event.inspectee }}"></any-service-ref>
-          <br><br>
-          <a class="boxclose" on-click="{{ closeItem }}">&times;</a>
-        </div>
-      </template>
-      <template if="{{ event.kind == 'IsolateReload' }}">
-        <div class="wide-item item">
-          Isolate reload
-          <template if="{{ event.reloadError != null }}">
-            failed:
-            <br>
-            <br>
-            <div class="indent error">{{ event.reloadError.message.toString() }}</div><br>
-          </template>
-          <template if="{{ event.reloadError == null }}">
-            succeeded
-          </template>
-          <a class="boxclose" on-click="{{ closeItem }}">&times;</a>
-        </div>
-      </template>
-    </template>
-  </template>
-</polymer-element>
-
-
-<polymer-element name="nav-notify-exception" extends="observatory-element">
-  <template>
-    <style>
-      .item {
-        position: relative;
-        padding: 16px;
-        margin-top: 10px;
-        margin-right: 10px;
-        padding-right: 25px;
-        width: 500px;
-        color: #ddd;
-        background: rgba(0,0,0,.6);
-        border: solid 2px white;
-        box-shadow: 0 0 5px black;
-        border-radius: 5px;
-        animation: fadein 1s;
-      }
-
-      @keyframes fadein {
-        from { opacity: 0; }
-        to   { opacity: 1; }
-      }
-
-      a.link {
-        color: white;
-        text-decoration: none;
-      }
-      a.link:hover {
-        text-decoration: underline;
-      }
-      .indent {
-        margin-left:20px;
-      }
-
-      a.boxclose {
-        position: absolute;
-        display: block;
-        top: 4px;
-        right: 4px;
-        height: 18px;
-        width: 18px;
-        line-height: 16px;
-        border-radius: 9px;
-        color: white;
-        font-size: 18px;
-        cursor: pointer;
-        text-align: center;
-      }
-      a.boxclose:hover {
-        background: rgba(255,255,255,0.5);
-      }
-      .stacktrace {
-        white-space: pre
-      }
-    </style>
-    <template if="{{ isUnexpectedError }}">
-      <!-- TODO(turnidge): Add a file-a-bug link to this notification -->
-      <div class="item">
-        Unexpected exception:<br><br>
-        <div class="indent">{{ exception.toString() }}</div><br>
-        <template if="{{ stacktrace != null }}">
-          Stacktrace:<br><br>
-          <div class="indent stacktrace">{{ stacktrace.toString() }}</div>
-          <br>
-        </template>
-        [<a class="link" on-click="{{ goto }}"
-            _href="{{ gotoLink('vm-connect') }}">Connect to a different VM</a>]
-        <a class="boxclose" on-click="{{ closeItem }}">&times;</a>
-    </div>
-    </template>
-    <template if="{{ isNetworkError }}">
-      <div class="item">
-        The request cannot be completed because the VM is currently
-        disconnected.
-        <br><br>
-        [<a class="link" on-click="{{ goto }}"
-            _href="{{ gotoLink('vm-connect') }}">Connect to a different VM</a>]
-        <a class="boxclose" on-click="{{ closeItem }}">&times;</a>
-    </div>
-    </template>
-  </template>
-</polymer-element>
-
-
-<script type="application/dart" src="nav_bar.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/object_common.html b/runtime/observatory/lib/src/elements/object_common.html
index 14311e0..38bbe21 100644
--- a/runtime/observatory/lib/src/elements/object_common.html
+++ b/runtime/observatory/lib/src/elements/object_common.html
@@ -1,15 +1,9 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
 <link rel="import" href="error_view.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="inbound_reference.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="eval_link.html">
 
-<polymer-element name="object-common" extends="observatory-element">
+<polymer-element name="object-common">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <div class="memberList">
@@ -69,7 +63,7 @@
             </template>
             <template repeat="{{ element in path['elements'] }}">
             <div class="memberItem">
-              <div class="memberName">[{{ element['index']}}]</div>
+              <div class="memberName">[{{ path['elements'].indexOf(element) }}]</div>
               <div class="memberValue">
                 <template if="{{ element['parentField'] != null }}">
                   from <any-service-ref ref="{{ element['parentField'] }}"></any-service-ref> of
@@ -77,6 +71,9 @@
                 <template if="{{ element['parentListIndex'] != null }}">
                   from [{{ element['parentListIndex'] }}] of
                 </template>
+                <template if="{{ element['parentMapKey'] != null }}">
+                  from [<any-service-ref ref="{{ element['parentMapKey'] }}"></any-service-ref>] of
+                </template>
                 <template if="{{ element['_parentWordOffset'] != null }}">
                   from word[{{ element['_parentWordOffset'] }}] of
                 </template>
diff --git a/runtime/observatory/lib/src/elements/object_view.html b/runtime/observatory/lib/src/elements/object_view.html
index eff9e49..9be06e8 100644
--- a/runtime/observatory/lib/src/elements/object_view.html
+++ b/runtime/observatory/lib/src/elements/object_view.html
@@ -1,16 +1,10 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
 <link rel="import" href="error_view.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="inbound_reference.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="object_common.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="eval_link.html">
 
-<polymer-element name="object-view" extends="observatory-element">
+<polymer-element name="object-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -19,6 +13,7 @@
       <isolate-nav-menu isolate="{{ object.isolate }}"></isolate-nav-menu>
       <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
diff --git a/runtime/observatory/lib/src/elements/objectpool_ref.dart b/runtime/observatory/lib/src/elements/objectpool_ref.dart
new file mode 100644
index 0000000..f26d436
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/objectpool_ref.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, ObjectPoolRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class ObjectPoolRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ObjectPoolRefElement>('object-pool-ref');
+
+  RenderingScheduler<ObjectPoolRefElement> _r;
+
+  Stream<RenderedEvent<ObjectPoolRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.ObjectPoolRef _pool;
+
+  M.IsolateRef get isolate => _isolate;
+  M.ObjectPoolRef get pool => _pool;
+
+  factory ObjectPoolRefElement(M.IsolateRef isolate, M.ObjectPoolRef pool,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(pool != null);
+    ObjectPoolRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._pool = pool;
+    return e;
+  }
+
+  ObjectPoolRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _pool))
+        ..children = [
+          new SpanElement()..classes = ['emphatize']
+            ..text = 'ObjectPool',
+          new SpanElement()..text = ' (${_pool.length})'
+        ]
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.html b/runtime/observatory/lib/src/elements/objectpool_view.html
index 4177eea..236fb84 100644
--- a/runtime/observatory/lib/src/elements/objectpool_view.html
+++ b/runtime/observatory/lib/src/elements/objectpool_view.html
@@ -1,16 +1,10 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
 <link rel="import" href="error_view.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="inbound_reference.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="object_common.html">
-<link rel="import" href="nav_bar.html">
 <link rel="import" href="eval_link.html">
 
-<polymer-element name="objectpool-view" extends="observatory-element">
+<polymer-element name="objectpool-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -19,6 +13,7 @@
       <isolate-nav-menu isolate="{{ pool.isolate }}"></isolate-nav-menu>
       <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content">
@@ -48,7 +43,7 @@
       </div>
 
     </div>
-  
+
     <hr>
     <view-footer></view-footer>
   </template>
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.html b/runtime/observatory/lib/src/elements/objectstore_view.html
index a8d4d02..1cdeb76 100644
--- a/runtime/observatory/lib/src/elements/objectstore_view.html
+++ b/runtime/observatory/lib/src/elements/objectstore_view.html
@@ -1,17 +1,7 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="class_ref.html">
-<link rel="import" href="curly_block.html">
 <link rel="import" href="eval_box.html">
-<link rel="import" href="field_ref.html">
-<link rel="import" href="function_ref.html">
-<link rel="import" href="instance_ref.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="library_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="objectstore-view" extends="observatory-element">
+<polymer-element name="objectstore-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
 
@@ -20,6 +10,7 @@
       <vm-nav-menu vm="{{ objectStore.isolate.vm }}"></vm-nav-menu>
       <isolate-nav-menu isolate="{{ objectStore.isolate }}" last="{{ true }}"></isolate-nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content-centered-big">
diff --git a/runtime/observatory/lib/src/elements/observatory_application.dart b/runtime/observatory/lib/src/elements/observatory_application.dart
index 4acdc65..0e85692 100644
--- a/runtime/observatory/lib/src/elements/observatory_application.dart
+++ b/runtime/observatory/lib/src/elements/observatory_application.dart
@@ -4,22 +4,24 @@
 
 library observatory_application_element;
 
-import 'observatory_element.dart';
+import 'dart:html';
 import 'package:observatory/app.dart';
-import 'package:polymer/polymer.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
 
 /// Main application tag. Responsible for instantiating an instance of
 /// [ObservatoryApplication] which is passed declaratively to all child
 /// elements.
-@CustomTag('observatory-application')
-class ObservatoryApplicationElement extends ObservatoryElement {
+class ObservatoryApplicationElement extends HtmlElement {
+  static const tag =
+      const Tag<ObservatoryApplicationElement>('observatory-application');
+
   ObservatoryApplication app;
 
   ObservatoryApplicationElement.created() : super.created();
 
   @override
-  void domReady() {
-    super.domReady();
+  void attached() {
+    super.attached();
     app = new ObservatoryApplication(this);
   }
 }
diff --git a/runtime/observatory/lib/src/elements/observatory_application.html b/runtime/observatory/lib/src/elements/observatory_application.html
deleted file mode 100644
index 73a2615..0000000
--- a/runtime/observatory/lib/src/elements/observatory_application.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="service_view.html">
-<polymer-element name="observatory-application" extends="observatory-element">
-  <!-- This element explicitly manages its child elements -->
-</polymer-element>
-
-<script type="application/dart" src="observatory_application.dart"></script>
\ No newline at end of file
diff --git a/runtime/observatory/lib/src/elements/observatory_element.dart b/runtime/observatory/lib/src/elements/observatory_element.dart
index 164f079..a661ccf 100644
--- a/runtime/observatory/lib/src/elements/observatory_element.dart
+++ b/runtime/observatory/lib/src/elements/observatory_element.dart
@@ -11,7 +11,6 @@
 import 'package:polymer/polymer.dart';
 
 /// Base class for all Observatory custom elements.
-@CustomTag('observatory-element')
 class ObservatoryElement extends PolymerElement {
   ObservatoryElement.created() : super.created();
 
diff --git a/runtime/observatory/lib/src/elements/observatory_element.html b/runtime/observatory/lib/src/elements/observatory_element.html
deleted file mode 100644
index dce89dc..0000000
--- a/runtime/observatory/lib/src/elements/observatory_element.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="observatory-element">
-</polymer-element>
-
-<script type="application/dart" src="observatory_element.dart"></script>
\ No newline at end of file
diff --git a/runtime/observatory/lib/src/elements/pc_descriptors_ref.dart b/runtime/observatory/lib/src/elements/pc_descriptors_ref.dart
new file mode 100644
index 0000000..9ba1e40
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/pc_descriptors_ref.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, PcDescriptorsRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class PcDescriptorsRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<PcDescriptorsRefElement>('pc-ref-wrapped');
+
+  RenderingScheduler<PcDescriptorsRefElement> _r;
+
+  Stream<RenderedEvent<PcDescriptorsRefElement>> get onRendered =>
+    _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.PcDescriptorsRef _descriptors;
+
+  M.IsolateRef get isolate => _isolate;
+  M.PcDescriptorsRef get descriptors => _descriptors;
+
+  factory PcDescriptorsRefElement(M.IsolateRef isolate,
+      M.PcDescriptorsRef descriptors, {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(descriptors != null);
+    PcDescriptorsRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._descriptors = descriptors;
+    return e;
+  }
+
+  PcDescriptorsRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    final text = (_descriptors.name == null || _descriptors.name == '')
+      ? 'PcDescriptors'
+      : _descriptors.name;
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _descriptors))
+        ..text = text
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/persistent_handles.html b/runtime/observatory/lib/src/elements/persistent_handles.html
index 9005494..af92aa7 100644
--- a/runtime/observatory/lib/src/elements/persistent_handles.html
+++ b/runtime/observatory/lib/src/elements/persistent_handles.html
@@ -1,8 +1,6 @@
 <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="persistent-handles-page" extends="observatory-element">
+<polymer-element name="persistent-handles-page">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -56,6 +54,7 @@
       <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
       <nav-menu link="{{ makeLink('/persistent-handles', isolate) }}" anchor="persistent handles" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
     <div class="content-centered-big">
       <template if="{{ persistentHandles.isEmpty }}">
diff --git a/runtime/observatory/lib/src/elements/ports.html b/runtime/observatory/lib/src/elements/ports.html
index d5b3152..af2adfb 100644
--- a/runtime/observatory/lib/src/elements/ports.html
+++ b/runtime/observatory/lib/src/elements/ports.html
@@ -1,8 +1,6 @@
 <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="ports-page" extends="observatory-element">
+<polymer-element name="ports-page">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <style>
@@ -22,6 +20,7 @@
       <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
       <nav-menu link="{{ makeLink('/ports', isolate) }}" anchor="ports" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
     <div class="content">
       <h1>Ports ({{ports.length}})</h1>
diff --git a/runtime/observatory/lib/src/elements/sample_buffer_control.dart b/runtime/observatory/lib/src/elements/sample_buffer_control.dart
new file mode 100644
index 0000000..dde5eb8
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/sample_buffer_control.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/utils.dart';
+
+class SampleBufferControlChangedElement {
+  final SampleBufferControlElement element;
+  SampleBufferControlChangedElement(this.element);
+}
+
+class SampleBufferControlElement extends HtmlElement implements Renderable {
+  static const tag =
+      const Tag<SampleBufferControlElement>('sample-buffer-control');
+
+  RenderingScheduler<SampleBufferControlElement> _r;
+
+  Stream<RenderedEvent<SampleBufferControlElement>> get onRendered =>
+                                                                  _r.onRendered;
+
+  StreamController<SampleBufferControlChangedElement> _onTagChange =
+      new StreamController<SampleBufferControlChangedElement>.broadcast();
+  Stream<SampleBufferControlChangedElement> get onTagChange =>
+      _onTagChange.stream;
+
+  Stream<M.SampleProfileLoadingProgressEvent> _progressStream;
+  M.SampleProfileLoadingProgress _progress;
+  M.SampleProfileTag _tag;
+  bool _showTag = false;
+  bool _profileVM = false;
+  StreamSubscription _subscription;
+
+  M.SampleProfileLoadingProgress get progress => _progress;
+  M.SampleProfileTag get selectedTag => _tag;
+  bool get showTag => _showTag;
+  bool get profileVM => _profileVM;
+
+  set selectedTag(M.SampleProfileTag value) =>
+      _tag = _r.checkAndReact(_tag, value);
+  set showTag(bool value) => _showTag = _r.checkAndReact(_showTag, value);
+  set profileVM(bool value) => _profileVM = _r.checkAndReact(_profileVM, value);
+
+
+  factory SampleBufferControlElement(M.SampleProfileLoadingProgress progress,
+      Stream<M.SampleProfileLoadingProgressEvent> progressStream,
+      {M.SampleProfileTag selectedTag: M.SampleProfileTag.none,
+      bool showTag: true, RenderingQueue queue}) {
+    assert(progress != null);
+    assert(progressStream != null);
+    assert(selectedTag != null);
+    assert(showTag != null);
+    SampleBufferControlElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._progress = progress;
+    e._progressStream = progressStream;
+    e._tag = selectedTag;
+    e._showTag = showTag;
+    return e;
+  }
+
+  SampleBufferControlElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+    _subscription = _progressStream.listen((e) {
+      _progress = e.progress;
+      _r.dirty();
+    });
+  }
+
+  @override
+  void detached() {
+    super.detached(); _r.disable(notify: true);
+    children = const [];
+    _subscription.cancel();
+  }
+
+  void render() {
+    var content = <Element>[
+      new HeadingElement.h2()..text = 'Sample buffer',
+      new HRElement()
+    ];
+    switch (_progress.status) {
+      case M.SampleProfileLoadingStatus.fetching :
+        content.addAll(_createStatusMessage('Fetching profile from VM...'));
+        break;
+      case M.SampleProfileLoadingStatus.loading :
+        content.addAll(_createStatusMessage('Loading profile...',
+            progress: _progress.progress));
+        break;
+      case M.SampleProfileLoadingStatus.disabled :
+        content.addAll(_createDisabledMessage());
+        break;
+      case M.SampleProfileLoadingStatus.loaded:
+        content.addAll(_createStatusReport());
+        break;
+    }
+    children = [
+      new DivElement()..classes = ['content-centered-big']
+        ..children = content
+    ];
+  }
+
+  static List<Element> _createStatusMessage(String message,
+      {double progress: 0.0}) {
+    return [new DivElement()..classes = ['statusBox', 'shadow', 'center']
+      ..children = [
+        new DivElement()..classes = ['statusMessage']
+          ..text = message,
+        new DivElement()..style.background = '#0489c3'
+          ..style.width = '$progress%'
+          ..style.height = '15px'
+          ..style.borderRadius = '4px'
+      ]
+    ];
+  }
+
+  static List<Element> _createDisabledMessage() {
+    return [new DivElement()..classes = ['statusBox' 'shadow' 'center']
+      ..children = [
+        new DivElement()
+          ..children = [
+            new HeadingElement.h1()
+            ..text = 'Profiling is disabled',
+            new BRElement(),
+            new DivElement()
+              ..innerHtml = 'Perhaps the <b>profile</b> '
+                            'flag has been disabled for this VM.',
+            new BRElement(),
+            new SpanElement()..text = 'See all',
+            new AnchorElement(href: Uris.flags())..text = 'vm flags'
+          ]
+      ]
+    ];
+  }
+
+  List<Element> _createStatusReport() {
+    final fetchT = Utils.formatDurationInSeconds(_progress.fetchingTime);
+    final loadT = Utils.formatDurationInSeconds(_progress.loadingTime);
+    final sampleCount = _progress.profile.sampleCount;
+    final refreshT = new DateTime.now();
+    final stackDepth = _progress.profile.stackDepth;
+    final sampleRate = _progress.profile.sampleRate.toStringAsFixed(0);
+    final timeSpan = _progress.profile.sampleCount == 0 ? '0s'
+        : Utils.formatTimePrecise(_progress.profile.timeSpan);
+
+    var content = <Element>[
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'Refreshed at',
+          new DivElement()..classes = ['memberValue']
+            ..text = '$refreshT (fetched in ${fetchT}s) (loaded in ${loadT}s)'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'Profile contains ',
+          new DivElement()..classes = ['memberValue']
+            ..text = '$sampleCount samples (spanning $timeSpan)'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'Sampling',
+          new DivElement()..classes = ['memberValue']
+            ..text = '$stackDepth stack frames @ ${sampleRate}Hz'
+        ],
+    ];
+    if (_showTag) {
+      content.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'Tag Order',
+            new DivElement()..classes = ['memberValue']
+              ..children = _createTagSelect()
+          ]
+      );
+    }
+    return [
+      new DivElement()..classes = ['memberList']
+        ..children = content
+    ];
+  }
+
+  List<Element> _createTagSelect() {
+    var values = M.SampleProfileTag.values;
+    if (!_profileVM) {
+      values = const [M.SampleProfileTag.userOnly, M.SampleProfileTag.none];
+    }
+    var s;
+    return [
+      s = new SelectElement()..classes = ['tag-select']
+        ..value = tagToString(_tag)
+        ..children = values.map((tag) {
+            return new OptionElement(value : tagToString(tag),
+                selected: _tag == tag)
+              ..text = tagToString(tag);
+          }).toList(growable: false)
+        ..onChange.listen((_) {
+            _tag = values[s.selectedIndex];
+          })
+        ..onChange.map(_toEvent).listen(_triggerModeChange),
+    ];
+  }
+
+  static String tagToString(M.SampleProfileTag tag) {
+    switch (tag) {
+      case M.SampleProfileTag.userVM: return 'User > VM';
+      case M.SampleProfileTag.userOnly: return 'User';
+      case M.SampleProfileTag.vmUser: return 'VM > User';
+      case M.SampleProfileTag.vmOnly: return 'VM';
+      case M.SampleProfileTag.none: return 'None';
+    }
+    throw new Exception('Unknown tagToString');
+  }
+
+  SampleBufferControlChangedElement _toEvent(_) {
+    return new SampleBufferControlChangedElement(this);
+  }
+
+  void _triggerModeChange(e) => _onTagChange.add(e);
+}
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 5776bc4..fbbef3a 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -8,8 +8,8 @@
 import 'dart:html';
 import 'dart:math';
 import 'observatory_element.dart';
-import 'nav_bar.dart';
 import 'service_ref.dart';
+import 'package:observatory/models.dart' as M;
 import 'package:observatory/service.dart';
 import 'package:observatory/utils.dart';
 import 'package:polymer/polymer.dart';
@@ -930,8 +930,8 @@
     for (var func in script.library.functions) {
       if ((func.location != null) &&
           (func.location.script == script) &&
-          (func.kind != FunctionKind.kImplicitGetterFunction) &&
-          (func.kind != FunctionKind.kImplicitSetterFunction)) {
+          (func.kind != M.FunctionKind.implicitGetter) &&
+          (func.kind != M.FunctionKind.implicitSetter)) {
         // We annotate a field declaration with the field instead of the
         // implicit getter or setter.
         var a = new FunctionDeclarationAnnotation(func, inspectLink(func));
@@ -942,8 +942,8 @@
       for (var func in cls.functions) {
         if ((func.location != null) &&
             (func.location.script == script) &&
-            (func.kind != FunctionKind.kImplicitGetterFunction) &&
-            (func.kind != FunctionKind.kImplicitSetterFunction)) {
+            (func.kind != M.FunctionKind.implicitGetter) &&
+            (func.kind != M.FunctionKind.implicitSetter)) {
           // We annotate a field declaration with the field instead of the
           // implicit getter or setter.
           var a = new FunctionDeclarationAnnotation(func, inspectLink(func));
@@ -984,7 +984,8 @@
       return 5;
     }
     const padding = 5;
-    const navbarHeight = NavBarElement.height;
+    // TODO (cbernaschina) check if this is needed.
+    const navbarHeight = 40;
     var rect = getBoundingClientRect();
     var buttonHeight = element.clientHeight;
     return min(max(0, navbarHeight - rect.top) + padding,
diff --git a/runtime/observatory/lib/src/elements/script_inset.html b/runtime/observatory/lib/src/elements/script_inset.html
index dd21155..c8ea9df 100644
--- a/runtime/observatory/lib/src/elements/script_inset.html
+++ b/runtime/observatory/lib/src/elements/script_inset.html
@@ -1,5 +1,5 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="observatory_element.html">
+
 
 <polymer-element name="icon-refresh" noscript>
   <template>
@@ -27,7 +27,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="script-inset" extends="observatory-element">
+<polymer-element name="script-inset">
   <template>
     <style>
       a {
diff --git a/runtime/observatory/lib/src/elements/script_ref.dart b/runtime/observatory/lib/src/elements/script_ref.dart
index c11f26d..67ae388 100644
--- a/runtime/observatory/lib/src/elements/script_ref.dart
+++ b/runtime/observatory/lib/src/elements/script_ref.dart
@@ -4,69 +4,58 @@
 
 library script_ref_element;
 
-import 'package:polymer/polymer.dart';
-import 'package:observatory/service.dart';
-import 'service_ref.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M show IsolateRef, ScriptRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 
-@CustomTag('script-ref')
-class ScriptRefElement extends ServiceRefElement {
-  @published int pos;
+class ScriptRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ScriptRefElement>('script-ref-wrapped');
 
-  String get hoverText {
-    if (ref == null) {
-      return super.hoverText;
-    }
-    return ref.vmName;
-  }
+  RenderingScheduler _r;
 
-  void posChanged(oldValue) {
-    _updateProperties(null);
-  }
+  Stream<RenderedEvent<ScriptRefElement>> get onRendered => _r.onRendered;
 
-  void _updateProperties(_) {
-    if (ref != null && ref.loaded) {
-      notifyPropertyChange(#name, 0, 1);
-      notifyPropertyChange(#url, 0, 1);
-    }
-  }
 
-  String get name {
-    if (ref == null) {
-      return super.name;
-    }
-    if ((pos != null) && (pos >= 0)) {
-      if (ref.loaded) {
-        // Script is loaded, get the line number.
-        Script script = ref;
-        return '${super.name}:${script.tokenToLine(pos)}:'
-            '${script.tokenToCol(pos)}';
-      } else {
-        ref.load().then(_updateProperties);
-      }
-    }
-    return super.name;
-  }
+  M.IsolateRef _isolate;
+  M.ScriptRef _script;
 
-  String get url {
-    if (ref == null) {
-      return super.url;
-    }
-    if ((pos != null) && (pos >= 0)) {
-      if (ref.loaded) {
-        return '${super.url}---pos=${pos}';
-      } else {
-        ref.load().then(_updateProperties);
-      }
-    }
-    return super.url;
+  M.IsolateRef get isolate => _isolate;
+  M.ScriptRef get script => _script;
+
+  factory ScriptRefElement(M.IsolateRef isolate, M.ScriptRef script,
+                           {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(script != null);
+    ScriptRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._script = script;
+    return e;
   }
 
   ScriptRefElement.created() : super.created();
-}
 
-@CustomTag('source-link')
-class SourceLinkElement extends PolymerElement {
-  SourceLinkElement.created() : super.created();
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
 
-  @published SourceLocation location;
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(isolate, object: script))
+        ..title = script.uri
+        ..text = script.uri.split('/').last
+    ];
+  }
 }
diff --git a/runtime/observatory/lib/src/elements/script_ref.html b/runtime/observatory/lib/src/elements/script_ref.html
deleted file mode 100644
index ccbb177..0000000
--- a/runtime/observatory/lib/src/elements/script_ref.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="service_ref.html">
-
-<polymer-element name="script-ref" extends="service-ref">
-<template>
-  <link rel="stylesheet" href="css/shared.css">
-  <a on-click="{{ goto }}" title="{{ hoverText }}" _href="{{ url }}">{{ name }}</a>
-</template>
-</polymer-element>
-
-<polymer-element name="source-link">
-<template>
-  <template if="{{ location != null }}">
-    <script-ref ref="{{ location.script }}"
-                pos="{{ location.tokenPos }}"></script-ref>
-  </template>
-</template>
-</polymer-element>
-
-
-<script type="application/dart" src="script_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/script_ref_wrapper.dart b/runtime/observatory/lib/src/elements/script_ref_wrapper.dart
new file mode 100644
index 0000000..8f0e343
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/script_ref_wrapper.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/service_html.dart' show Script;
+import 'package:observatory/src/elements/script_ref.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class ScriptRefElementWrapper extends HtmlElement {
+  static const binder = const Binder<ScriptRefElementWrapper>(const {
+      'ref': #ref
+    });
+
+  static const tag = const Tag<ScriptRefElementWrapper>('script-ref');
+
+  Script _script;
+
+  Script get ref => _script;
+
+  set ref(Script value) {
+    _script = value;
+    render();
+  }
+
+  ScriptRefElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  Future render() async {
+    shadowRoot.children = [];
+    if (_script == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        script-ref-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        script-ref-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new ScriptRefElement(_script.isolate, _script,
+                                 queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/script_view.html b/runtime/observatory/lib/src/elements/script_view.html
index e5aec18..b732128 100644
--- a/runtime/observatory/lib/src/elements/script_view.html
+++ b/runtime/observatory/lib/src/elements/script_view.html
@@ -1,10 +1,7 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
 <link rel="import" href="script_inset.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="script-view" extends="observatory-element">
+<polymer-element name="script-view">
 <template>
   <link rel="stylesheet" href="css/shared.css">
   <nav-bar>
@@ -14,6 +11,7 @@
     <library-nav-menu library="{{ script.library }}"></library-nav-menu>
     <nav-menu link="{{ makeLink('/inspect', script) }}" anchor="{{ script.name }}" last="{{ true }}"></nav-menu>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <nav-notify notifications="{{ app.notifications }}"></nav-notify>
   </nav-bar>
 
   <div class="content-centered-big">
diff --git a/runtime/observatory/lib/src/elements/sentinel_value.dart b/runtime/observatory/lib/src/elements/sentinel_value.dart
new file mode 100644
index 0000000..70f6489
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/sentinel_value.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M show Sentinel, SentinelKind;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+
+class SentinelValueElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<SentinelValueElement>('sentinel-value');
+
+  RenderingScheduler<SentinelValueElement> _r;
+
+  Stream<RenderedEvent<SentinelValueElement>> get onRendered => _r.onRendered;
+
+  M.Sentinel _sentinel;
+
+  M.Sentinel get sentinel => _sentinel;
+
+  factory SentinelValueElement(M.Sentinel sentinel, {RenderingQueue queue}) {
+    assert(sentinel != null);
+    SentinelValueElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._sentinel = sentinel;
+    return e;
+  }
+
+  SentinelValueElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    text = '';
+    title = '';
+  }
+
+  void render() {
+    text = _sentinel.valueAsString;
+    title = _sentinelKindToDescription(_sentinel.kind);
+  }
+
+  static String _sentinelKindToDescription(M.SentinelKind kind) {
+    switch (kind) {
+      case M.SentinelKind.collected:
+        return 'This object has been reclaimed by the garbage collector.';
+      case M.SentinelKind.expired:
+        return 'The handle to this object has expired. '
+               'Consider refreshing the page.';
+      case M.SentinelKind.notInitialized:
+        return 'This object will be initialized once it is accessed by '
+               'the program.';
+      case M.SentinelKind.initializing:
+        return 'This object is currently being initialized.';
+      case M.SentinelKind.optimizedOut:
+        return 'This object is no longer needed and has been removed by the '
+               'optimizing compiler.';
+      case M.SentinelKind.free:
+        return '';
+    }
+    throw new Exception('Unknown SentinelKind: $kind');
+  }
+
+}
diff --git a/runtime/observatory/lib/src/elements/service_ref.dart b/runtime/observatory/lib/src/elements/service_ref.dart
index e9aad6d..7a93447 100644
--- a/runtime/observatory/lib/src/elements/service_ref.dart
+++ b/runtime/observatory/lib/src/elements/service_ref.dart
@@ -8,13 +8,12 @@
 
 import 'package:logging/logging.dart';
 import 'package:observatory/service.dart';
+import 'package:observatory/repositories.dart';
 import 'package:polymer/polymer.dart';
 
-import 'class_ref.dart';
-import 'library_ref.dart';
+import 'helpers/any_ref.dart';
 import 'observatory_element.dart';
 
-@CustomTag('service-ref')
 class ServiceRefElement extends ObservatoryElement {
   @published ServiceObject ref;
   @published bool internal = false;
@@ -88,62 +87,6 @@
   @published bool asValue = false;
   AnyServiceRefElement.created() : super.created();
 
-  Element _constructElementForRef() {
-    var type = ref.type;
-    switch (type) {
-     case 'Class':
-        ClassRefElement element = new Element.tag('class-ref');
-        element.ref = ref;
-        element.asValue = asValue;
-        return element;
-      case 'Code':
-        ServiceRefElement element = new Element.tag('code-ref');
-        element.ref = ref;
-        return element;
-      case 'Context':
-        ServiceRefElement element = new Element.tag('context-ref');
-        element.ref = ref;
-        return element;
-      case 'Error':
-        ServiceRefElement element = new Element.tag('error-ref');
-        element.ref = ref;
-        return element;
-      case 'Field':
-        ServiceRefElement element = new Element.tag('field-ref');
-        element.ref = ref;
-        return element;
-      case 'Function':
-        ServiceRefElement element = new Element.tag('function-ref');
-        element.ref = ref;
-        return element;
-      case 'Library':
-        LibraryRefElement element = new Element.tag('library-ref');
-        element.ref = ref;
-        element.asValue = asValue;
-        return element;
-      case 'Object':
-        ServiceRefElement element = new Element.tag('object-ref');
-        element.ref = ref;
-        return element;
-      case 'Script':
-        ServiceRefElement element = new Element.tag('script-ref');
-        element.ref = ref;
-        return element;
-      case 'Instance':
-      case 'Sentinel':
-        ServiceRefElement element = new Element.tag('instance-ref');
-        element.ref = ref;
-        if (expandKey != null) {
-          element.expandKey = expandKey;
-        }
-        return element;
-      default:
-        SpanElement element = new Element.tag('span');
-        element.text = "<<Unknown service ref: $ref>>";
-        return element;
-    }
-  }
-
   refChanged(oldValue) {
     // Remove the current view.
     children.clear();
@@ -151,17 +94,74 @@
       Logger.root.info('Viewing null object.');
       return;
     }
-    var type = ref.type;
-    var element = _constructElementForRef();
+    var obj;
+    if (ref is Guarded) {
+      var g = ref as Guarded;
+      obj = g.asValue ?? g.asSentinel;
+    } else {
+      obj = ref;
+    }
+    var element;
+    switch (obj.type) {
+      case 'Class':
+        if (asValue) {
+          element = new Element.tag('class-ref-as-value');
+          element.ref = obj;
+        } else {
+          element = new Element.tag('class-ref');
+          element.ref = obj;
+        }
+        break;
+      case 'Code':
+        element = new Element.tag('code-ref');
+        element.ref = obj;
+        break;
+      case 'Context':
+        element = new Element.tag('context-ref');
+        element.ref = obj;
+        break;
+      case 'Error':
+        element = new Element.tag('error-ref');
+        element.ref = obj;
+        break;
+      case 'Field':
+        element = new Element.tag('field-ref');
+        element.ref = obj;
+        break;
+      case 'Function':
+        element = new Element.tag('function-ref');
+        element.ref = obj;
+        break;
+      case 'Instance':
+        element = new Element.tag('instance-ref');
+        element.ref = obj;
+        break;
+      case 'Library':
+        if (asValue) {
+          element =
+              new Element.tag('library-ref-as-value');
+          element.ref = obj;
+        } else {
+          element =
+              new Element.tag('library-ref');
+          element.ref = obj;
+        }
+        break;
+      case 'Script':
+        element = new Element.tag('script-ref');
+        element.ref = obj;
+        break;
+      default:
+        element = anyRef(obj.isolate, obj,
+            new InstanceRepository(obj.isolate), queue: app.queue);
+        break;
+    }
     if (element == null) {
-      Logger.root.info('Unable to find a ref element for \'${type}\'');
+      Logger.root.info('Unable to find a ref element for \'${ref.type}\'');
+      element = new Element.tag('span');
+      element.text = "<<Unknown service ref: $ref>>";
       return;
     }
     children.add(element);
   }
 }
-
-@CustomTag('object-ref')
-class ObjectRefElement extends ServiceRefElement {
-  ObjectRefElement.created() : super.created();
-}
diff --git a/runtime/observatory/lib/src/elements/service_ref.html b/runtime/observatory/lib/src/elements/service_ref.html
index 17ce4c5..d401cc8 100644
--- a/runtime/observatory/lib/src/elements/service_ref.html
+++ b/runtime/observatory/lib/src/elements/service_ref.html
@@ -1,62 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="observatory_element.html">
 
-<polymer-element name="service-ref" extends="observatory-element">
-</polymer-element>
-
-<polymer-element name="any-service-ref" extends="observatory-element">
-</polymer-element>
-
-<polymer-element name="object-ref" extends="service-ref">
-  <template><link rel="stylesheet" href="css/shared.css">
-
-    <template if="{{ ref.isObjectPool }}">
-      <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 || ref.isMegamorphicCache }}">
-      <a on-click="{{ goto }}" _href="{{ url }}">
-        <em>{{ ref.vmType }}</em> ({{ ref.selector }})
-      </a>
-    </template>
-    <template if="{{ ref.isInstructions }}">
-      <a on-click="{{ goto }}" _href="{{ url }}">
-        <em>{{ ref.vmType }}</em> ({{ ref.code.name }})
-      </a>
-    </template>
-    <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>
-      <template if="{{ !nameIsEmpty }}">
-        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ name }}</em></a>
-      </template>
-    </template>
-  </template>
+<polymer-element name="any-service-ref">
 </polymer-element>
 
 <script type="application/dart" src="service_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/service_view.dart b/runtime/observatory/lib/src/elements/service_view.dart
index c9924a6..a8aa312 100644
--- a/runtime/observatory/lib/src/elements/service_view.dart
+++ b/runtime/observatory/lib/src/elements/service_view.dart
@@ -22,10 +22,6 @@
   ObservatoryElement _constructElementForObject() {
     var type = object.type;
     switch (type) {
-      case 'AllocationProfile':
-        HeapProfileElement element = new Element.tag('heap-profile');
-        element.profile = object;
-        return element;
       case 'Class':
         ClassViewElement element = new Element.tag('class-view');
         element.cls = object;
@@ -46,10 +42,6 @@
         FieldViewElement element = new Element.tag('field-view');
         element.field = object;
         return element;
-      case 'FlagList':
-        FlagListElement element = new Element.tag('flag-list');
-        element.flagList = object;
-        return element;
       case 'Function':
         FunctionViewElement element = new Element.tag('function-view');
         element.function = object;
@@ -58,25 +50,6 @@
         HeapMapElement element = new Element.tag('heap-map');
         element.fragmentation = object;
         return element;
-      case 'IO':
-        IOViewElement element = new Element.tag('io-view');
-        element.io = object;
-        return element;
-      case 'HttpServerList':
-        IOHttpServerListViewElement element =
-            new Element.tag('io-http-server-list-view');
-        element.list = object;
-        return element;
-      case 'HttpServer':
-        IOHttpServerViewElement element =
-            new Element.tag('io-http-server-view');
-        element.httpServer = object;
-        return element;
-      case 'HttpServerConnection':
-        IOHttpServerConnectionViewElement element =
-            new Element.tag('io-http-server-connection-view');
-        element.connection = object;
-        return element;
       case 'Object':
         return (object) {
           switch (object.vmType) {
@@ -84,11 +57,6 @@
               ICDataViewElement element = new Element.tag('icdata-view');
               element.icData = object;
               return element;
-            case 'Instructions':
-              InstructionsViewElement element =
-                  new Element.tag('instructions-view');
-              element.instructions = object;
-              return element;
             case 'MegamorphicCache':
               MegamorphicCacheViewElement element =
                   new Element.tag('megamorphiccache-view');
@@ -104,24 +72,6 @@
               return element;
           }
         }(object);
-      case 'SocketList':
-        IOSocketListViewElement element =
-            new Element.tag('io-socket-list-view');
-        element.list = object;
-        return element;
-      case 'Socket':
-        IOSocketViewElement element = new Element.tag('io-socket-view');
-        element.socket = object;
-        return element;
-      case 'WebSocketList':
-        IOWebSocketListViewElement element =
-            new Element.tag('io-web-socket-list-view');
-        element.list = object;
-        return element;
-      case 'WebSocket':
-        IOWebSocketViewElement element = new Element.tag('io-web-socket-view');
-        element.webSocket = object;
-        return element;
       case 'Isolate':
         IsolateViewElement element = new Element.tag('isolate-view');
         element.isolate = object;
@@ -130,25 +80,6 @@
         LibraryViewElement element = new Element.tag('library-view');
         element.library = object;
         return element;
-      case 'ProcessList':
-        IOProcessListViewElement element =
-            new Element.tag('io-process-list-view');
-        element.list = object;
-        return element;
-      case 'Process':
-        IOProcessViewElement element = new Element.tag('io-process-view');
-        element.process = object;
-        return element;
-      case 'RandomAccessFileList':
-        IORandomAccessFileListViewElement element =
-            new Element.tag('io-random-access-file-list-view');
-        element.list = object;
-        return element;
-      case 'RandomAccessFile':
-        IORandomAccessFileViewElement element =
-            new Element.tag('io-random-access-file-view');
-        element.file = object;
-        return element;
       case 'Script':
         ScriptViewElement element = new Element.tag('script-view');
         element.script = object;
diff --git a/runtime/observatory/lib/src/elements/service_view.html b/runtime/observatory/lib/src/elements/service_view.html
index 723248f..23c5597 100644
--- a/runtime/observatory/lib/src/elements/service_view.html
+++ b/runtime/observatory/lib/src/elements/service_view.html
@@ -2,25 +2,22 @@
 <link rel="import" href="class_view.html">
 <link rel="import" href="code_view.html">
 <link rel="import" href="context_view.html">
-<link rel="import" href="cpu_profile.html">
 <link rel="import" href="error_view.html">
 <link rel="import" href="field_view.html">
 <link rel="import" href="function_view.html">
 <link rel="import" href="heap_map.html">
-<link rel="import" href="heap_profile.html">
 <link rel="import" href="instance_view.html">
 <link rel="import" href="library_view.html">
 <link rel="import" href="heap_snapshot.html">
-<link rel="import" href="observatory_element.html">
+
 <link rel="import" href="script_view.html">
 <link rel="import" href="vm_view.html">
-<link rel="import" href="view_footer.html">
-<polymer-element name="service-view" extends="observatory-element">
+<polymer-element name="service-view">
   <!-- This element explicitly manages the child elements to avoid setting
        an observable property on the old element to an invalid type. -->
 </polymer-element>
 
-<polymer-element name="trace-view" extends="observatory-element">
+<polymer-element name="trace-view">
    <template>
     <link rel="stylesheet" href="css/shared.css">
 
@@ -48,7 +45,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="map-viewer" extends="observatory-element">
+<polymer-element name="map-viewer">
   <template>
     <link rel="stylesheet" href="css/shared.css">
 
@@ -80,7 +77,7 @@
   </template>
 </polymer-element>
 
-<polymer-element name="list-viewer" extends="observatory-element">
+<polymer-element name="list-viewer">
   <template>
     <link rel="stylesheet" href="css/shared.css">
 
diff --git a/runtime/observatory/lib/src/elements/shims/binding.dart b/runtime/observatory/lib/src/elements/shims/binding.dart
new file mode 100644
index 0000000..c5425c4
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/shims/binding.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:core';
+import 'dart:html';
+import 'dart:js';
+@MirrorsUsed(metaTargets: const [BindableAnnotation])
+import 'dart:mirrors';
+import 'package:js/js.dart';
+import 'package:js_util/js_util.dart';
+import 'package:polymer/polymer.dart';
+
+const BindableAnnotation bindable = const BindableAnnotation();
+class BindableAnnotation {
+  const BindableAnnotation();
+}
+
+
+///This is a temporary bridge between Polymer Bindings and the wrapper entities.
+class Binder<T extends HtmlElement> {
+  final Map<String, Symbol> attributes;
+
+  const Binder(Map<String, Symbol> attributes)
+      : attributes = attributes;
+
+  registerCallback(T element) {
+    assert(element != null);
+    setValue(element, 'bind', allowInteropCaptureThis(_callback));
+  }
+
+  void _callback(_this, name, value, [other]) {
+    final setter = attributes[name];
+    if (setter == null) return;
+    Bindable bindable;
+    if (identical(1, 1.0)) { // dart2js
+      bindable = getValue(getValue(value, '__dartBindable'), 'o') as Bindable;
+    } else { // vm
+      bindable = getValue(value, '__dartBindable');
+    }
+    var obj = reflect(_this);
+    obj.setField(setter, bindable.value);
+    bindable.open((value) {
+      obj.setField(setter, value);
+    });
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/sliding_checkbox.dart b/runtime/observatory/lib/src/elements/sliding_checkbox.dart
deleted file mode 100644
index 760fd11..0000000
--- a/runtime/observatory/lib/src/elements/sliding_checkbox.dart
+++ /dev/null
@@ -1,21 +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 sliding_checkbox_element;
-
-import 'dart:html';
-import 'package:polymer/polymer.dart';
-
-@CustomTag('sliding-checkbox')
-class SlidingCheckboxElement extends PolymerElement {
-  SlidingCheckboxElement.created() : super.created();
-  @published bool checked;
-  @published String checkedText;
-  @published String uncheckedText;
-
-  void change(Event e, var details, Node target) {
-    CheckboxInputElement input = shadowRoot.querySelector('#slide-switch');
-    checked = input.checked;
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/sliding_checkbox.html b/runtime/observatory/lib/src/elements/sliding_checkbox.html
deleted file mode 100644
index cdb4f78..0000000
--- a/runtime/observatory/lib/src/elements/sliding_checkbox.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="sliding-checkbox">
-  <template>
-    <style>
-      .switch {
-        position: relative;
-        width: 121px;
-        -webkit-user-select: none;
-        -moz-user-select: none;
-        -ms-user-select: none;
-      }
-      .hide {
-        display: none;
-      }
-      .label {
-        display: block;
-        overflow: hidden;
-        cursor: pointer;
-        border: 2px solid #999999;
-        border-radius: 15px;
-      }
-      .content {
-        width: 200%;
-        margin-left: -100%;
-        -moz-transition: margin 0.3s ease-in 0s;
-        -webkit-transition: margin 0.3s ease-in 0s;
-        -o-transition: margin 0.3s ease-in 0s;
-        transition: margin 0.3s ease-in 0s;
-      }
-      .content:before, .content:after {
-        float: left;
-        width: 50%;
-        height: 30px;
-        padding: 0;
-        line-height: 30px;
-        color: white;
-        font: 400 14px 'Montserrat', sans-serif;
-        -moz-box-sizing: border-box;
-        -webkit-box-sizing: border-box;
-        box-sizing: border-box;
-      }
-      .content:before {
-        content: {{ checkedText }};
-        padding-left: 10px;
-        background-color: #0489C3;
-      }
-      .content:after {
-        content: {{ uncheckedText }};
-        padding-right: 10px;
-        background-color: #EEEEEE;
-        color: #999999;
-        text-align: right;
-      }
-      .dot {
-        width: 14px;
-        margin: 8px;
-        background: #FFFFFF;
-        border: 2px solid #999999;
-        border-radius: 15px;
-        position: absolute;
-        top: 0;
-        bottom: 0;
-        right: 87px;
-        -moz-transition: all 0.3s ease-in 0s;
-        -webkit-transition: all 0.3s ease-in 0s;
-        -o-transition: all 0.3s ease-in 0s;
-        transition: all 0.3s ease-in 0s;
-      }
-      :checked + .label .content {
-        margin-left: 0;
-      }
-      :checked + .label .dot {
-        right: 0px;
-      }
-    </style>
-    <div class="switch">
-      <input type="checkbox"
-             class="hide"
-             id="slide-switch"
-             on-change="{{ change }}">
-      <label class="label" for="slide-switch">
-        <div class="content"></div>
-        <div class="dot"></div>
-      </label>
-    </div>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="sliding_checkbox.dart"></script>
\ No newline at end of file
diff --git a/runtime/observatory/lib/src/elements/source_link.dart b/runtime/observatory/lib/src/elements/source_link.dart
new file mode 100644
index 0000000..110b8e1
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/source_link.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. 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_link_element;
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart'
+  show IsolateRef, SourceLocation, Script, ScriptRepository;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class SourceLinkElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<SourceLinkElement>('source-link-wrapped');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<SourceLinkElement>> get onRendered => _r.onRendered;
+
+  IsolateRef _isolate;
+  SourceLocation _location;
+  Script _script;
+  ScriptRepository _repository;
+
+  IsolateRef get isolate => _isolate;
+  SourceLocation get location => _location;
+
+  factory SourceLinkElement(IsolateRef isolate, SourceLocation location,
+      ScriptRepository repository, {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(location != null);
+    SourceLinkElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._location = location;
+    e._repository = repository;
+    return e;
+  }
+
+  SourceLinkElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _repository.get(_location.script.id).then((script) {
+      _script = script;
+      _r.dirty();
+    });
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  Future render() async {
+    if (_script == null) {
+      children = [new SpanElement()..text = '<LOADING>'];
+    } else {
+      String label = _script.uri.split('/').last;
+      int token = _location.tokenPos;
+      int line = _script.tokenToLine(token);
+      int column = _script.tokenToCol(token);
+      children = [
+        new AnchorElement(
+            href: Uris.inspect(isolate, object: _script, pos: token))
+          ..title = _script.uri
+          ..text = '${label}:${line}:${column}'
+      ];
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/source_link_wrapper.dart b/runtime/observatory/lib/src/elements/source_link_wrapper.dart
new file mode 100644
index 0000000..20221ea
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/source_link_wrapper.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart' show ScriptRepository;
+import 'package:observatory/service_html.dart' show SourceLocation;
+import 'package:observatory/src/elements/source_link.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class SourceLinkElementWrapper extends HtmlElement {
+  static const binder = const Binder<SourceLinkElementWrapper>(const {
+      'location' : #location
+    });
+
+  static const tag = const Tag<SourceLinkElementWrapper>('source-link');
+
+  SourceLocation _location;
+  SourceLocation get location => location;
+  set location(SourceLocation value) {
+    _location = value;
+    render();
+  }
+
+  SourceLinkElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  Future render() async {
+    shadowRoot.children = [];
+    if (_location == null) {
+      return;
+    }
+
+    ScriptRepository repository = new ScriptRepository(_location.isolate);
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        source-link-wrapped > a[href]:hover {
+            text-decoration: underline;
+        }
+        source-link-wrapped > a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }''',
+      new SourceLinkElement(_location.isolate, _location, repository,
+                            queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/stack_trace_tree_config.dart b/runtime/observatory/lib/src/elements/stack_trace_tree_config.dart
new file mode 100644
index 0000000..b1f2f4e
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/stack_trace_tree_config.dart
@@ -0,0 +1,228 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+
+enum ProfileTreeMode {
+  code,
+  function,
+}
+
+class StackTraceTreeConfigChangedEvent {
+  final StackTraceTreeConfigElement element;
+  StackTraceTreeConfigChangedEvent(this.element);
+}
+
+class StackTraceTreeConfigElement extends HtmlElement implements Renderable {
+  static const tag =
+      const Tag<StackTraceTreeConfigElement>('stack-trace-tree-config');
+
+  RenderingScheduler<StackTraceTreeConfigElement> _r;
+
+  Stream<RenderedEvent<StackTraceTreeConfigElement>> get onRendered =>
+                                                                  _r.onRendered;
+
+  StreamController<StackTraceTreeConfigChangedEvent> _onModeChange =
+      new StreamController<StackTraceTreeConfigChangedEvent>.broadcast();
+  StreamController<StackTraceTreeConfigChangedEvent> _onDirectionChange =
+      new StreamController<StackTraceTreeConfigChangedEvent>.broadcast();
+  StreamController<StackTraceTreeConfigChangedEvent> _onFilterChange =
+      new StreamController<StackTraceTreeConfigChangedEvent>.broadcast();
+  Stream<StackTraceTreeConfigChangedEvent> get onModeChange =>
+      _onModeChange.stream;
+  Stream<StackTraceTreeConfigChangedEvent> get onDirectionChange =>
+      _onDirectionChange.stream;
+  Stream<StackTraceTreeConfigChangedEvent> get onFilterChange =>
+      _onFilterChange.stream;
+
+  bool _showMode;
+  bool _showDirection;
+  bool _showFilter;
+  ProfileTreeMode _mode;
+  M.ProfileTreeDirection _direction;
+  String _filter;
+
+  bool get showMode => _showMode;
+  bool get showDirection => _showDirection;
+  bool get showFilter => _showFilter;
+  ProfileTreeMode get mode => _mode;
+  M.ProfileTreeDirection get direction => _direction;
+  String get filter => _filter;
+
+  set showMode(bool value) => _showMode = _r.checkAndReact(_showMode, value);
+  set showDirection(bool value) =>
+      _showDirection = _r.checkAndReact(_showDirection, value);
+  set showFilter(bool value) =>
+      _showFilter = _r.checkAndReact(_showFilter, value);
+  set mode(ProfileTreeMode value) => _mode = _r.checkAndReact(_mode, value);
+  set direction(M.ProfileTreeDirection value) =>
+      _direction = _r.checkAndReact(_direction, value);
+  set filter(String value) => _filter = _r.checkAndReact(_filter, value);
+
+  factory StackTraceTreeConfigElement({bool showMode: true,
+      bool showDirection: true, bool showFilter: true, String filter: '',
+      ProfileTreeMode mode: ProfileTreeMode.function,
+      M.ProfileTreeDirection direction: M.ProfileTreeDirection.exclusive,
+      RenderingQueue queue}) {
+    assert(showMode != null);
+    assert(showDirection != null);
+    assert(showFilter != null);
+    assert(mode != null);
+    assert(direction != null);
+    assert(filter != null);
+    StackTraceTreeConfigElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._showMode = showMode;
+    e._showDirection = showDirection;
+    e._showFilter = showFilter;
+    e._mode = mode;
+    e._direction = direction;
+    e._filter = filter;
+    return e;
+  }
+
+  StackTraceTreeConfigElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached(); _r.disable(notify: true);
+    children = const [];
+  }
+
+  void render() {
+    children = [
+      new DivElement()..classes = ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = 'Tree display',
+          new HRElement(),
+          new DivElement()..classes = ['row']
+            ..children = [
+              new DivElement()..classes = ['memberList']
+                ..children = _createMembers()
+            ]
+        ]
+    ];
+  }
+
+  List<Element> _createMembers() {
+    var members = <Element>[];
+    if (_showMode) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']..text = 'Mode',
+            new DivElement()..classes = ['memberValue']
+              ..children = _createModeSelect()
+          ]
+      );
+    }
+    if (_showDirection) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'Call Tree Direction',
+            new SpanElement()..classes = ['memberValue']
+              ..children = _createDirectionSelect()
+          ]
+      );
+    }
+    if (showFilter) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'Call Tree Filter'
+              ..title = 'case-sensitive substring match',
+            new SpanElement()..classes = ['memberValue']
+              ..children = _createFilter()
+          ]
+      );
+    }
+    return members;
+  }
+
+  List<Element> _createModeSelect() {
+    var s;
+    return [
+      s = new SelectElement()..classes = ['mode-select']
+        ..value = modeToString(_mode)
+        ..children = ProfileTreeMode.values.map((mode) {
+            return new OptionElement(value : modeToString(mode),
+                selected: _mode == mode)
+              ..text = modeToString(mode);
+          }).toList(growable: false)
+        ..onChange.listen((_) {
+            _mode = ProfileTreeMode.values[s.selectedIndex];
+          })
+        ..onChange.map(_toEvent).listen(_triggerModeChange),
+    ];
+  }
+
+  List<Element> _createDirectionSelect() {
+    var s;
+    return [
+      s = new SelectElement()..classes = ['direction-select']
+        ..value = directionToString(_direction)
+        ..children = M.ProfileTreeDirection.values.map((direction) {
+            return new OptionElement(value: directionToString(direction),
+                selected: _direction == direction)
+              ..text = directionToString(direction);
+          }).toList(growable: false)
+        ..onChange.listen((_) {
+            _direction = M.ProfileTreeDirection.values[s.selectedIndex];
+          })
+        ..onChange.map(_toEvent).listen(_triggerDirectionChange),
+      new SpanElement()..text = 'Tree is rooted at ' +
+          (_direction == 'Down' ? '"main"' : 'function / code') +
+          '. Child nodes are callers.'
+    ];
+  }
+
+  List<Element> _createFilter(){
+    var t;
+    return [
+      t = new TextInputElement()..placeholder = 'Search filter'
+          ..value = filter
+          ..onChange.listen((_) { _filter = t.value; })
+          ..onChange.map(_toEvent).listen(_triggerFilterChange)
+    ];
+  }
+
+  static String modeToString(ProfileTreeMode mode) {
+    switch (mode) {
+      case ProfileTreeMode.code: return 'Code';
+      case ProfileTreeMode.function: return 'Function';
+    }
+    throw new Exception('Unknown ProfileTreeMode');
+  }
+
+  static String directionToString(M.ProfileTreeDirection direction) {
+    switch (direction) {
+      case M.ProfileTreeDirection.inclusive: return 'Top down';
+      case M.ProfileTreeDirection.exclusive: return 'Bottom up';
+    }
+    throw new Exception('Unknown ProfileTreeDirection');
+  }
+
+  StackTraceTreeConfigChangedEvent _toEvent(_) {
+    return new StackTraceTreeConfigChangedEvent(this);
+  }
+
+  void _triggerModeChange(e) => _onModeChange.add(e);
+  void _triggerDirectionChange(e) => _onDirectionChange.add(e);
+  void _triggerFilterChange(e) => _onFilterChange.add(e);
+
+
+}
diff --git a/runtime/observatory/lib/src/elements/timeline_page.html b/runtime/observatory/lib/src/elements/timeline_page.html
index 433c242..df9e0b4 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.html
+++ b/runtime/observatory/lib/src/elements/timeline_page.html
@@ -1,8 +1,6 @@
 <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">
+<polymer-element name="timeline-page">
   <template>
     <link rel="stylesheet" href="css/shared.css">
     <nav-bar>
@@ -13,6 +11,7 @@
       <nav-refresh callback="{{ clear }}" label="Clear"></nav-refresh>
       <nav-refresh callback="{{ saveTimeline }}" label="Save"></nav-refresh>
       <nav-refresh callback="{{ loadTimeline }}" label="Load"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
     <div id="control" class="content-centered-big">
       <h2>Timeline settings</h2>
diff --git a/runtime/observatory/lib/src/elements/token_stream_ref.dart b/runtime/observatory/lib/src/elements/token_stream_ref.dart
new file mode 100644
index 0000000..8fcaac6
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/token_stream_ref.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, TokenStreamRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class TokenStreamRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<TokenStreamRefElement>('token-stream-ref');
+
+  RenderingScheduler<TokenStreamRefElement> _r;
+
+  Stream<RenderedEvent<TokenStreamRefElement>> get onRendered => _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.TokenStreamRef _token;
+
+  M.IsolateRef get isolate => _isolate;
+  M.TokenStreamRef get token => _token;
+
+  factory TokenStreamRefElement(M.IsolateRef isolate, M.TokenStreamRef token,
+      {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(token != null);
+    TokenStreamRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._token = token;
+    return e;
+  }
+
+  TokenStreamRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    final text = (_token.name == null || _token.name == '')
+      ? 'TokenStream'
+      : _token.name;
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _token))
+        ..text = text
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/unknown_ref.dart b/runtime/observatory/lib/src/elements/unknown_ref.dart
new file mode 100644
index 0000000..cc4d278
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/unknown_ref.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M
+  show IsolateRef, UnknownObjectRef;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class UnknownObjectRefElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<UnknownObjectRefElement>('unknown-ref');
+
+  RenderingScheduler<UnknownObjectRefElement> _r;
+
+  Stream<RenderedEvent<UnknownObjectRefElement>> get onRendered =>
+      _r.onRendered;
+
+  M.IsolateRef _isolate;
+  M.UnknownObjectRef _obj;
+
+  M.IsolateRef get isolate => _isolate;
+  M.UnknownObjectRef get obj => _obj;
+
+  factory UnknownObjectRefElement(M.IsolateRef isolate,
+      M.UnknownObjectRef obj, {RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(obj != null);
+    UnknownObjectRefElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._obj = obj;
+    return e;
+  }
+
+  UnknownObjectRefElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.inspect(_isolate, object: _obj))
+        ..text = _obj.vmType
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/view_footer.dart b/runtime/observatory/lib/src/elements/view_footer.dart
index a182511..3e7dcd1 100644
--- a/runtime/observatory/lib/src/elements/view_footer.dart
+++ b/runtime/observatory/lib/src/elements/view_footer.dart
@@ -4,10 +4,50 @@
 
 library view_footer_element;
 
-import 'package:polymer/polymer.dart';
-import 'observatory_element.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 
-@CustomTag('view-footer')
-class ViewFooterElement extends ObservatoryElement {
-  ViewFooterElement.created() : super.created();
+class ViewFooterElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ViewFooterElement>('view-footer');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<ViewFooterElement>> get onRendered => _r.onRendered;
+
+  factory ViewFooterElement({RenderingQueue queue}) {
+    ViewFooterElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    return e;
+  }
+
+  ViewFooterElement.created() : super.created() {
+    // TODO(cbernaschina) remove this when polymer is removed.
+    _r = new RenderingScheduler(this);
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [
+        new AnchorElement()
+          ..href = 'https://www.dartlang.org/tools/observatory'
+          ..text = 'View documentation',
+        new AnchorElement()
+          ..href = 'https://github.com/dart-lang/sdk/issues/new?title=Observatory:&amp;body=Observatory%20Feedback'
+          ..text = 'File a bug report'
+    ];
+  }
 }
diff --git a/runtime/observatory/lib/src/elements/view_footer.html b/runtime/observatory/lib/src/elements/view_footer.html
deleted file mode 100644
index 59862b5..0000000
--- a/runtime/observatory/lib/src/elements/view_footer.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="observatory_element.html">
-
-<polymer-element name="view-footer" extends="observatory-element">
-  <template><link rel="stylesheet" href="css/shared.css">
-    <br><br><br><br>
-    <br><br><br><br>
-    <div align="right" style="padding: 1em">
-    <p>
-      <a href="https://www.dartlang.org/tools/observatory/" style="font-size:90%">
-	View documentation
-      </a>
-    </p>
-    <p>
-      <a href="https://github.com/dart-lang/sdk/issues/new?title=Observatory:&amp;body=Observatory%20Feedback" style="font-size:90%">
-        File a bug report
-      </a>
-    </p>
-   </div>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="view_footer.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart
index 5d42edc..a322e91 100644
--- a/runtime/observatory/lib/src/elements/vm_connect.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -4,102 +4,181 @@
 
 library vm_connect_element;
 
-import 'dart:convert';
 import 'dart:html';
+import 'dart:async';
+import 'dart:convert';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/view_footer.dart';
+import 'package:observatory/src/elements/vm_connect_target.dart';
 
-import 'observatory_element.dart';
-import 'package:observatory/app.dart';
-import 'package:observatory/elements.dart';
-import 'package:observatory/service_html.dart';
-import 'package:polymer/polymer.dart';
+typedef void CrashDumpLoadCallback(Map dump);
 
-void _connectToVM(ObservatoryApplication app, WebSocketVMTarget target) {
-  app.vm = new WebSocketVM(target);
-}
+class VMConnectElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<VMConnectElement>('vm-connect',
+                     dependencies: const [NavBarElement.tag,
+                                          NavTopMenuElement.tag,
+                                          NavNotifyElement.tag,
+                                          ViewFooterElement.tag,
+                                          VMConnectTargetElement.tag]);
 
-@CustomTag('vm-connect-target')
-class VMConnectTargetElement extends ObservatoryElement {
-  @published WebSocketVMTarget target;
+  RenderingScheduler _r;
 
-  VMConnectTargetElement.created() : super.created();
+  Stream<RenderedEvent<VMConnectElement>> get onRendered => _r.onRendered;
 
-  bool get isCurrentTarget {
-    if (app.vm == null) {
-      return false;
-    }
-    return (app.vm as WebSocketVM).target == target;
+  CrashDumpLoadCallback _loadDump;
+  M.NotificationRepository _notifications;
+  M.TargetRepository _targets;
+  StreamSubscription _targetsSubscription;
+
+  String _address;
+
+  factory VMConnectElement(M.TargetRepository targets,
+                           CrashDumpLoadCallback loadDump,
+                           M.NotificationRepository notifications,
+                           {String address: '', RenderingQueue queue}) {
+    assert(address != null);
+    assert(loadDump != null);
+    assert(notifications != null);
+    assert(targets != null);
+    VMConnectElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._address = address;
+    e._loadDump = loadDump;
+    e._notifications = notifications;
+    e._targets = targets;
+    return e;
   }
 
-  void connectToVm(MouseEvent event, var detail, Element node) {
-    if (event.button > 0 || event.metaKey || event.ctrlKey ||
-        event.shiftKey || event.altKey) {
-      // Not a left-click or a left-click with a modifier key:
-      // Let browser handle.
-      return;
-    }
-    event.preventDefault();
-    WebSocketVM currentVM = app.vm;
-    if ((currentVM == null) ||
-        currentVM.isDisconnected ||
-        (currentVM.target != target)) {
-      _connectToVM(app, target);
-    }
-    var href = node.attributes['href'];
-    app.locationManager.go(href);
-  }
-
-  void deleteVm(MouseEvent event, var detail, Element node) {
-    app.targets.remove(target);
-  }
-}
-
-@CustomTag('vm-connect')
-class VMConnectElement extends ObservatoryElement {
-  @published String standaloneVmAddress = '';
-
-  VMConnectElement.created() : super.created() {
-  }
-
-  void _connect(WebSocketVMTarget target) {
-    _connectToVM(app, target);
-    app.locationManager.goForwardingParameters('/vm');
-  }
+  VMConnectElement.created() : super.created();
 
   @override
   void attached() {
     super.attached();
-    var fileInput = shadowRoot.querySelector('#crashDumpFile');
-    fileInput.onChange.listen(_onCrashDumpFileChange);
+    _targetsSubscription = _targets.onChange.listen((_) => _r.dirty());
+    _r.enable();
   }
 
-  String _normalizeStandaloneAddress(String networkAddress) {
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+    _targetsSubscription.cancel();
+  }
+
+  void render() {
+    final host = window.location.hostname;
+    final port = window.location.port;
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(last: true, queue: _r.queue),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()
+        ..classes = ['content-centered']
+        ..children = [
+          new HeadingElement.h1()..text = 'Connect to a Dart VM',
+          new BRElement(), new HRElement(),
+          new DivElement()
+            ..classes = ['flex-row']
+            ..children = [
+              new DivElement()
+                ..classes = ['flex-item-40-percent']
+                ..children = [
+                  new HeadingElement.h2()..text = 'WebSocket',
+                  new BRElement(),
+                  new UListElement()
+                    ..children = _targets.list().map((target) {
+                      return new LIElement()
+                        ..children = [new VMConnectTargetElement(target,
+                          current: target == _targets.current, queue: _r.queue)
+                          ..onConnect.listen(_connect)
+                          ..onDelete.listen(_delete)
+                        ];
+                      }).toList(),
+                  new HRElement(),
+                  new FormElement()
+                    ..autocomplete = 'on'
+                    ..children = [
+                      _createAddressBox(),
+                      new SpanElement()..text = ' ',
+                      new ButtonElement()
+                        ..classes = ['vm_connect']
+                        ..text = 'Connect'
+                        ..onClick.listen((e) {
+                          e.preventDefault(); _create(); }),
+                    ],
+                  new BRElement(),
+                  new PreElement()
+                    ..classes = ['well']
+                    ..text = 'Run Standalone with: \'--observe\'',
+                  new HRElement()
+                ],
+              new DivElement()
+                ..classes = ['flex-item-20-percent'],
+              new DivElement()
+                ..classes = ['flex-item-40-percent']
+                ..children = [
+                  new HeadingElement.h2()..text = 'Crash dump',
+                  new BRElement(),
+                  _createCrushDumpLoader(),
+                  new BRElement(), new BRElement(),
+                  new PreElement()
+                    ..classes = ['well']
+                    ..text = 'Request a crash dump with:\n'
+                      '\'curl $host:$port/_getCrashDump > dump.json\'',
+                  new HRElement()
+                ]
+            ],
+        ],
+      new ViewFooterElement(queue: _r.queue)
+    ];
+  }
+
+  TextInputElement _createAddressBox() {
+    var textbox = new TextInputElement()
+      ..classes = ['textbox']
+      ..placeholder = 'localhost:8181'
+      ..value = _address
+      ..onKeyUp
+        .where((e) => e.key == '\n')
+        .listen((e) { e.preventDefault(); _create(); });
+    textbox.onInput.listen((e) {
+      _address = textbox.value;
+    });
+    return textbox;
+  }
+
+  FileUploadInputElement _createCrushDumpLoader() {
+    FileUploadInputElement e = new FileUploadInputElement()
+      ..id = 'crashDumpFile';
+    e.onChange.listen((_) {
+      var reader = new FileReader();
+      reader.readAsText(e.files[0]);
+      reader.onLoad.listen((_) {
+        var crashDump = JSON.decode(reader.result);
+        _loadDump(crashDump);
+      });
+    });
+    return e;
+  }
+  void _create() {
+    if (_address == null || _address.isEmpty) return;
+    _targets.add(_normalizeStandaloneAddress(_address));
+  }
+  void _connect(TargetEvent e) => _targets.setCurrent(e.target);
+  void _delete(TargetEvent e) => _targets.delete(e.target);
+
+  static String _normalizeStandaloneAddress(String networkAddress) {
     if (networkAddress.startsWith('ws://')) {
       return networkAddress;
     }
     return 'ws://${networkAddress}/ws';
   }
-
-  void connectStandalone(Event e, var detail, Node target) {
-    // Prevent any form action.
-    e.preventDefault();
-    if (standaloneVmAddress == null) {
-      return;
-    }
-    if (standaloneVmAddress.isEmpty) {
-      return;
-    }
-    var targetAddress = _normalizeStandaloneAddress(standaloneVmAddress);
-    var target = app.targets.findOrMake(targetAddress);
-    _connect(target);
-  }
-
-  _onCrashDumpFileChange(e) {
-    var fileInput = shadowRoot.querySelector('#crashDumpFile');
-    var reader = new FileReader();
-    reader.readAsText(fileInput.files[0]);
-    reader.onLoad.listen((_) {
-      var crashDump = JSON.decode(reader.result);
-      app.loadCrashDump(crashDump);
-    });
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/vm_connect.html b/runtime/observatory/lib/src/elements/vm_connect.html
deleted file mode 100644
index 0bae096..0000000
--- a/runtime/observatory/lib/src/elements/vm_connect.html
+++ /dev/null
@@ -1,87 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="view_footer.html">
-
-<polymer-element name="vm-connect-target" extends="observatory-element">
-  <template>
-    <style>
-      .delete-button {
-        padding: 4px;
-        background: transparent;
-        border: none !important;
-      }
-      .delete-button:hover {
-        background: #ff0000;
-      }
-    </style>
-    <link rel="stylesheet" href="css/shared.css">
-    <span>
-      <template if="{{ isCurrentTarget }}">
-        <a on-click="{{ connectToVm }}" _href="{{ gotoLinkForwardingParameters('/vm') }}">{{ target.name }} (Connected)</a>
-      </template>
-      <template if="{{ !isCurrentTarget }}">
-        <a on-click="{{ connectToVm }}" _href="{{ gotoLinkForwardingParameters('/vm') }}">{{ target.name }}</a>
-      </template>
-      <button class="delete-button" on-click="{{ deleteVm }}">&#10006; Remove</button>
-    </span>
-  </template>
-</polymer-element>
-
-<polymer-element name="vm-connect" extends="observatory-element">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-      .textbox {
-        width: 20em;
-        font: 400 16px 'Montserrat', sans-serif;
-      }
-    </style>
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-    </nav-bar>
-
-    <div class="content-centered">
-      <h1>Connect to a Dart VM</h1>
-      <br>
-      <hr>
-      <div class="flex-row">
-        <div class="flex-item-40-percent">
-          <h2>WebSocket</h2>
-          <br>
-          <ul>
-            <template repeat="{{ target in app.targets.history }}">
-              <template if="{{ target.standalone }}">
-                <li><vm-connect-target target="{{ target }}"></vm-connect-target></li>
-              </template>
-            </template>
-          </ul>
-          <hr>
-          <form autocomplete="on">
-            <input class="textbox" placeholder="localhost:8181" type="text" value="{{ standaloneVmAddress }}">
-            <input class="button" type="submit" value="Connect" on-click="{{ connectStandalone }}">
-          </form>
-          <br>
-          <pre class="well">Run Standalone with: '--observe'</pre>
-          <hr>
-        </div>
-
-        <div class="flex-item-20-percent"></div>
-        <div class="flex-item-40-percent">
-          <h2>Crash dump</h2>
-          <br>
-          <input type="file" id="crashDumpFile">
-          <br>
-          <br>
-          <pre class="well">Request a crash dump with:
-'curl localhost:8181/_getCrashDump > dump.json'</pre>
-          <hr>
-        </div>
-      </div>
-    </div>
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="vm_connect.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/vm_connect_target.dart b/runtime/observatory/lib/src/elements/vm_connect_target.dart
new file mode 100644
index 0000000..43a0cec
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/vm_connect_target.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:observatory/models.dart' as M show Target;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+
+class TargetEvent {
+  final M.Target target;
+
+  TargetEvent(this.target);
+}
+
+class VMConnectTargetElement extends HtmlElement implements Renderable {
+
+  static const tag =
+    const Tag<VMConnectTargetElement>('vm-connect-target');
+
+  RenderingScheduler<VMConnectTargetElement> _r;
+
+  Stream<RenderedEvent<VMConnectTargetElement>> get onRendered => _r.onRendered;
+
+  final StreamController<TargetEvent> _onConnect =
+      new StreamController<TargetEvent>.broadcast();
+  Stream<TargetEvent> get onConnect => _onConnect.stream;
+  final StreamController<TargetEvent> _onDelete =
+      new StreamController<TargetEvent>.broadcast();
+  Stream<TargetEvent> get onDelete => _onDelete.stream;
+
+  M.Target _target;
+  bool _current;
+
+  M.Target get target => _target;
+  bool get current => _current;
+
+  factory VMConnectTargetElement(M.Target target, {bool current: false,
+      RenderingQueue queue}) {
+    assert(target != null);
+    assert(current != null);
+    VMConnectTargetElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._target = target;
+    e._current = current;
+    return e;
+  }
+
+  VMConnectTargetElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void connect() {
+    _connect(new TargetEvent(target));
+  }
+
+  void delete() {
+    _delete(new TargetEvent(target));
+  }
+
+  void render() {
+    children = [
+      new AnchorElement(href: Uris.vm())
+        ..text = current ? '${target.name} (Connected)' : '${target.name}'
+        ..onClick.where(_filter).map(_toEvent).listen(_connect),
+      new ButtonElement()
+        ..text = '✖ Remove' ..classes = ['delete-button']
+        ..onClick.map(_toEvent).listen(_delete)
+    ];
+  }
+
+  void _connect(TargetEvent e) {
+    _onConnect.add(e);
+  }
+
+  void _delete(TargetEvent e) {
+    _onDelete.add(e);
+  }
+
+  TargetEvent _toEvent(_) {
+    return new TargetEvent(target);
+  }
+
+  static bool _filter(MouseEvent event) {
+    return !(event.button > 0 || event.metaKey || event.ctrlKey ||
+        event.shiftKey || event.altKey);
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/vm_ref.dart b/runtime/observatory/lib/src/elements/vm_ref.dart
deleted file mode 100644
index 56fab8a..0000000
--- a/runtime/observatory/lib/src/elements/vm_ref.dart
+++ /dev/null
@@ -1,13 +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 vm_ref_element;
-
-import 'package:polymer/polymer.dart';
-import 'service_ref.dart';
-
-@CustomTag('vm-ref')
-class VMRefElement extends ServiceRefElement {
-  VMRefElement.created() : super.created();
-}
diff --git a/runtime/observatory/lib/src/elements/vm_ref.html b/runtime/observatory/lib/src/elements/vm_ref.html
deleted file mode 100644
index e7cb8e4..0000000
--- a/runtime/observatory/lib/src/elements/vm_ref.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="service_ref.html">
-
-<polymer-element name="vm-ref" extends="service-ref">
-  <template><link rel="stylesheet" href="css/shared.css">
-    <a on-click="{{ goto }}" _href="{{ url }}">{{ ref.name }}</a>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="vm_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/vm_view.html b/runtime/observatory/lib/src/elements/vm_view.html
index 2934009..1a5481b 100644
--- a/runtime/observatory/lib/src/elements/vm_view.html
+++ b/runtime/observatory/lib/src/elements/vm_view.html
@@ -1,15 +1,8 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="curly_block.html">
 <link rel="import" href="eval_box.html">
-<link rel="import" href="function_ref.html">
 <link rel="import" href="isolate_summary.html">
-<link rel="import" href="library_ref.html">
-<link rel="import" href="nav_bar.html">
-<link rel="import" href="observatory_element.html">
-<link rel="import" href="script_ref.html">
-<link rel="import" href="view_footer.html">
 
-<polymer-element name="vm-view" extends="observatory-element">
+<polymer-element name="vm-view">
   <template>
     <link rel="stylesheet" href="css/shared.css">
 
@@ -17,6 +10,7 @@
       <top-nav-menu last="{{ false }}"></top-nav-menu>
       <vm-nav-menu vm="{{ vm }}" last="{{ true }}"></vm-nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
+      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
     <div class="content-centered">
@@ -51,6 +45,10 @@
           <div class="memberName">pid</div>
           <div class="memberValue">{{ vm.pid }}</div>
         </div>
+        <div class="memberItem">
+          <div class="memberName">peak memory</div>
+          <div class="memberValue">{{ vm.maxRSS }}</div>
+        </div>
         <br>
         <div class="memberItem">
           <div class="memberValue">
diff --git a/runtime/observatory/lib/src/models/exceptions.dart b/runtime/observatory/lib/src/models/exceptions.dart
new file mode 100644
index 0000000..81a7ba7
--- /dev/null
+++ b/runtime/observatory/lib/src/models/exceptions.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class BasicException implements Exception {
+  String get message;
+}
+
+abstract class ConnectionException implements BasicException {}
+
+abstract class ResponseException implements BasicException {}
+
+abstract class RequestException implements BasicException {}
+
+abstract class ParseErrorException implements RequestException {}
+
+abstract class InvalidRequestException implements RequestException {}
+
+abstract class MethodNotFoundException implements RequestException {}
+
+abstract class InvalidParamsException implements RequestException {}
+
+abstract class InternalErrorException implements RequestException {}
+
+abstract class FeatureDisabledException implements RequestException {}
+
+abstract class CannotAddBreakpointException implements RequestException {}
+
+abstract class StreamAlreadySubscribedException implements RequestException {}
+
+abstract class StreamNotSubscribedException implements RequestException {}
+
+abstract class IsolateMustBeRunnableException implements RequestException {}
+
+abstract class IsolateMustBePausedException implements RequestException {}
+
+abstract class IsolateIsReloadingException implements RequestException {}
+
+abstract class FileSystemAlreadyExistsException implements RequestException {}
+
+abstract class FileSystemDoesNotExistException implements RequestException {}
+
+abstract class FileDoesNotExistException implements RequestException {}
+
+abstract class IsolateReloadFailedException implements RequestException {}
+
+abstract class UnknownException implements RequestException {}
diff --git a/runtime/observatory/lib/src/models/objects/allocation_profile.dart b/runtime/observatory/lib/src/models/objects/allocation_profile.dart
new file mode 100644
index 0000000..f9e17a5
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/allocation_profile.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class AllocationProfile {
+  DateTime get lastServiceGC;
+  DateTime get lastAccumulatorReset;
+  HeapSpace get newSpace;
+  HeapSpace get oldSpace;
+  Iterable<ClassHeapStats> get members;
+}
+
+
+abstract class ClassHeapStats {
+  ClassRef get clazz;
+  Allocations get newSpace;
+  Allocations get oldSpace;
+  int get promotedInstances;
+  int get promotedBytes;
+}
+
+abstract class Allocations {
+  AllocationCount get accumulated;
+  AllocationCount get current;
+}
+
+abstract class AllocationCount {
+  int get instances;
+  int get bytes;
+}
diff --git a/runtime/observatory/lib/src/models/objects/bound_field.dart b/runtime/observatory/lib/src/models/objects/bound_field.dart
new file mode 100644
index 0000000..cf2a38f
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/bound_field.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class BoundField {
+  FieldRef get decl;
+  Guarded<InstanceRef> get value;
+}
diff --git a/runtime/observatory/lib/src/models/objects/breakpoint.dart b/runtime/observatory/lib/src/models/objects/breakpoint.dart
new file mode 100644
index 0000000..daf1277
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/breakpoint.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 models;
+
+abstract class Breakpoint extends Object {
+  /// A number identifying this breakpoint to the user.
+  int get number;
+
+  /// Has this breakpoint been assigned to a specific program location?
+  bool get resolved;
+}
diff --git a/runtime/observatory/lib/src/models/objects/class.dart b/runtime/observatory/lib/src/models/objects/class.dart
new file mode 100644
index 0000000..ae8e241
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/class.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.
+
+part of models;
+
+abstract class ClassRef extends ObjectRef {
+  /// The name of this class.
+  String get name;
+}
+
+abstract class Class extends Object implements ClassRef {
+  /// The error which occurred during class finalization, if it exists.
+  /// [optional]
+  ErrorRef get error;
+
+  /// Is this an abstract class?
+  bool get isAbstract;
+
+  /// Is this a const class?
+  bool get isConst;
+
+  /// [internal]
+  bool get isPatch;
+
+  /// The library which contains this class.
+  LibraryRef get library;
+
+  /// The location of this class in the source code.[optional]
+  SourceLocation get location;
+
+  /// The superclass of this class, if any. [optional]
+  ClassRef get superclass;
+
+  /// The supertype for this class, if any.
+  ///
+  /// The value will be of the kind: Type. [optional]
+  InstanceRef get superType;
+
+  /// A list of interface types for this class.
+  ///
+  /// The values will be of the kind: Type.
+  Iterable<InstanceRef> get interfaces;
+
+  /// The mixin type for this class, if any.
+  ///
+  /// The value will be of the kind: Type. [optional]
+  InstanceRef get mixin;
+
+  /// A list of fields in this class. Does not include fields from
+  /// superclasses.
+  //List<FieldRef> get fields;
+
+  /// A list of functions in this class. Does not include functions
+  /// from superclasses.
+  //List<FunctionRef> get functions;
+
+  // A list of subclasses of this class.
+  Iterable<ClassRef> get subclasses;
+}
diff --git a/runtime/observatory/lib/src/models/objects/code.dart b/runtime/observatory/lib/src/models/objects/code.dart
new file mode 100644
index 0000000..ddc759d
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/code.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+enum CodeKind {
+  dart,
+  native,
+  stub,
+  tag,
+  collected
+}
+
+bool isSyntheticCode(CodeKind kind) {
+  switch (kind) {
+    case CodeKind.collected:
+    case CodeKind.native:
+    case CodeKind.tag:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool isDartCode(CodeKind kind) => !isSyntheticCode(kind);
+
+abstract class CodeRef extends ObjectRef {
+  /// The name of this class.
+  String get name;
+
+  // What kind of code object is this?
+  CodeKind get kind;
+
+  bool get isOptimized;
+}
+
+abstract class Code extends Object implements CodeRef {
+}
diff --git a/runtime/observatory/lib/src/models/objects/context.dart b/runtime/observatory/lib/src/models/objects/context.dart
new file mode 100644
index 0000000..46d0a12
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/context.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.
+
+part of models;
+
+abstract class ContextRef extends ObjectRef {
+  /// The number of variables in this context.
+  int get length;
+}
+
+abstract class Context extends Object implements ContextRef {
+  /// [optional] The enclosing context for this context.
+  Context get parentContext;
+
+  // The variables in this context object.
+  //Iterable<ContextElement> get variables;
+}
diff --git a/runtime/observatory/lib/src/models/objects/error.dart b/runtime/observatory/lib/src/models/objects/error.dart
new file mode 100644
index 0000000..8b36aed
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/error.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 models;
+
+enum ErrorKind {
+  /// The isolate has encountered an unhandled Dart exception.
+  unhandledException,
+  /// The isolate has encountered a Dart language error in the program.
+  languageError,
+  /// The isolate has encounted an internal error. These errors should be
+  /// reported as bugs.
+  internalError,
+  /// The isolate has been terminated by an external source.
+  terminationError
+}
+
+abstract class ErrorRef extends ObjectRef {
+  String get id;
+  ErrorKind get kind;
+  String get message;
+}
+
+abstract class Error extends Object implements ErrorRef {
+
+}
diff --git a/runtime/observatory/lib/src/models/objects/event.dart b/runtime/observatory/lib/src/models/objects/event.dart
new file mode 100644
index 0000000..33dfc63
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/event.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 models;
+
+abstract class Event {
+  /// The timestamp (in milliseconds since the epoch) associated with this
+  /// event. For some isolate pause events, the timestamp is from when the
+  /// isolate was paused. For other events, the timestamp is from when the
+  /// event was created.
+  DateTime get timestamp;
+  static bool isPauseEvent(Event event) {
+    return event is PauseStartEvent || event is PauseExitEvent ||
+        event is PauseBreakpointEvent || event is PauseInterruptedEvent ||
+        event is PauseExceptionEvent || event is NoneEvent;
+  }
+}
+
+abstract class VMEvent extends Event {
+  /// The vm with which this event is associated.
+  VMRef get vm;
+}
+
+abstract class VMUpdateEvent extends VMEvent {}
+
+abstract class IsolateEvent extends Event {
+  /// The isolate with which this event is associated.
+  IsolateRef get isolate;
+}
+
+abstract class IsolateStartEvent extends IsolateEvent {}
+
+abstract class IsolateRunnableEvent extends IsolateEvent {}
+
+abstract class IsolateExitEvent extends IsolateEvent {}
+
+abstract class IsolateUpdateEvent extends IsolateEvent {}
+
+abstract class IsolateReloadEvent extends IsolateEvent {
+  ErrorRef get error;
+}
+
+abstract class ServiceExtensionAddedEvent extends IsolateEvent {
+  /// The RPC name of the extension that was added.
+  String get extensionRPC;
+}
+
+abstract class DebugEvent extends Event {
+  /// The isolate with which this event is associated.
+  IsolateRef get isolate;
+}
+
+abstract class DebuggerSettingsUpdateEvent extends DebugEvent {}
+
+abstract class PauseStartEvent extends DebugEvent {}
+
+abstract class PauseExitEvent extends DebugEvent {}
+
+abstract class PauseBreakpointEvent extends DebugEvent {
+  /// [optional] The breakpoint at which we are currently paused.
+  Breakpoint get breakpoint;
+  /// The list of breakpoints at which we are currently paused
+  /// for a PauseBreakpoint event.
+  ///
+  /// This list may be empty. For example, while single-stepping, the
+  /// VM sends a PauseBreakpoint event with no breakpoints.
+  ///
+  /// If there is more than one breakpoint set at the program position,
+  /// then all of them will be provided.
+  Iterable<Breakpoint> get pauseBreakpoints;
+  /// The top stack frame associated with this event.
+  Frame get topFrame;
+  bool get atAsyncSuspension;
+}
+
+abstract class PauseInterruptedEvent extends DebugEvent {
+  /// [optional] The top stack frame associated with this event. There will be
+  /// no top frame if the isolate is idle (waiting in the message loop).
+  Frame get topFrame;
+  /// Is the isolate paused at an await, yield, or yield* statement?
+  bool get atAsyncSuspension;
+}
+
+abstract class PauseExceptionEvent extends DebugEvent {
+  /// The top stack frame associated with this event.
+  Frame get topFrame;
+  /// The exception associated with this event
+  InstanceRef get exception;
+}
+
+abstract class ResumeEvent extends DebugEvent {
+  /// [optional] The top stack frame associated with this event. It is provided
+  /// at all times except for the initial resume event that is delivered when an
+  /// isolate begins execution.
+  Frame get topFrame;
+}
+
+abstract class BreakpointAddedEvent extends DebugEvent {
+  /// The breakpoint which was added.
+  Breakpoint get breakpoint;
+}
+
+abstract class BreakpointResolvedEvent extends DebugEvent {
+  /// The breakpoint which was resolved.
+  Breakpoint get breakpoint;
+}
+
+abstract class BreakpointRemovedEvent extends DebugEvent {
+  /// The breakpoint which was removed.
+  Breakpoint get breakpoint;
+}
+
+abstract class InspectEvent extends DebugEvent {
+  /// The argument passed to dart:developer.inspect.
+  InstanceRef get inspectee;
+}
+
+abstract class NoneEvent extends DebugEvent {}
+
+abstract class GCEvent extends Event {
+  /// The isolate with which this event is associated.
+  IsolateRef get isolate;
+}
+
+abstract class ExtensionEvent extends Event {
+  /// The isolate with which this event is associated.
+  IsolateRef get isolate;
+  /// The extension event kind.
+  String get extensionKind;
+  /// The extension event data.
+  ExtensionData get extensionData;
+}
+
+abstract class TimelineEventsEvent extends Event {
+  /// The isolate with which this event is associated.
+  IsolateRef get isolate;
+  /// An array of TimelineEvents
+  Iterable<TimelineEvent> get timelineEvents;
+}
+
+abstract class ConnectionClosedEvent extends Event {
+  /// The reason of the closed connection
+  String get reason;
+}
diff --git a/runtime/observatory/lib/src/models/objects/extension_data.dart b/runtime/observatory/lib/src/models/objects/extension_data.dart
new file mode 100644
index 0000000..80a0012
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/extension_data.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class ExtensionData implements Map<String, dynamic> {}
diff --git a/runtime/observatory/lib/src/models/objects/field.dart b/runtime/observatory/lib/src/models/objects/field.dart
new file mode 100644
index 0000000..152c920
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/field.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class FieldRef extends ObjectRef {
+  /// The name of this field.
+  String get name;
+
+  /// The owner of this field, which can be either a Library or a
+  /// Class.
+  ObjectRef get dartOwner;
+
+  /// The declared type of this field.
+  ///
+  /// The value will always be of one of the kinds:
+  /// Type, TypeRef, TypeParameter, BoundedType.
+  InstanceRef get declaredType;
+
+  /// Is this field const?
+  bool get isConst;
+
+  /// Is this field final?
+  bool get isFinal;
+
+  /// Is this field static?
+  bool get isStatic;
+}
diff --git a/runtime/observatory/lib/src/models/objects/flag.dart b/runtime/observatory/lib/src/models/objects/flag.dart
new file mode 100644
index 0000000..3813f88
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/flag.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class Flag {
+  /// The name of the flag.
+  String get name;
+
+  /// A description of the flag.
+  String get comment;
+
+  /// Has this flag been modified from its default setting?
+  bool get modified;
+
+  /// The value of this flag as a string. [optional]
+  ///
+  /// If this property is absent, then the value of the flag was NULL.
+  String get valueAsString;
+}
diff --git a/runtime/observatory/lib/src/models/objects/frame.dart b/runtime/observatory/lib/src/models/objects/frame.dart
new file mode 100644
index 0000000..c0e40c3
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/frame.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class Frame {}
diff --git a/runtime/observatory/lib/src/models/objects/function.dart b/runtime/observatory/lib/src/models/objects/function.dart
new file mode 100644
index 0000000..e52c564
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/function.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 models;
+
+enum FunctionKind {
+  regular,
+  closure,
+  getter,
+  setter,
+  constructor,
+  implicitGetter,
+  implicitSetter,
+  implicitStaticFinalGetter,
+  irregexpFunction,
+  staticInitializer,
+  methodExtractor,
+  noSuchMethodDispatcher,
+  invokeFieldDispatcher,
+  collected,
+  native,
+  stub,
+  tag,
+  signatureFunction
+}
+
+bool isSyntheticFunction(FunctionKind kind) {
+  switch (kind) {
+    case FunctionKind.collected:
+    case FunctionKind.native:
+    case FunctionKind.stub:
+    case FunctionKind.tag:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool isDartFunction(FunctionKind kind) => !isSyntheticFunction(kind);
+bool isStubFunction(FunctionKind kind) => kind == FunctionKind.stub;
+bool hasDartCode(FunctionKind kind) =>
+    isDartFunction(kind) || isStubFunction(kind);
+
+abstract class FunctionRef extends ObjectRef {
+  /// The name of this class.
+  String get name;
+
+  /// The owner of this function, which can be a LibraryRef, ClassRef,
+  /// or a FunctionRef.
+  ObjectRef get dartOwner; // owner
+
+  /// Is this function static?
+  bool get isStatic;
+
+  /// Is this function const?
+  bool get isConst;
+
+  /// The kind of the function.
+  FunctionKind get kind;
+}
+
+abstract class Function extends Object implements FunctionRef {
+  /// The location of this function in the source code. [optional]
+  SourceLocation get location;
+
+  /// The compiled code associated with this function. [optional]
+  CodeRef get code;
+}
diff --git a/runtime/observatory/lib/src/models/objects/guarded.dart b/runtime/observatory/lib/src/models/objects/guarded.dart
new file mode 100644
index 0000000..82bf1ee
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/guarded.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class Guarded<T> {
+  bool get isValue;
+  bool get isSentinel;
+  Sentinel get asSentinel;
+  T get asValue;
+}
diff --git a/runtime/observatory/lib/src/models/objects/heap_space.dart b/runtime/observatory/lib/src/models/objects/heap_space.dart
new file mode 100644
index 0000000..cf62fbf
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/heap_space.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 models;
+
+abstract class HeapSpace {
+  int get used;
+  int get capacity;
+  int get collections;
+  int get external;
+  Duration get avgCollectionTime;
+  Duration get totalCollectionTime;
+  Duration get avgCollectionPeriod;
+}
diff --git a/runtime/observatory/lib/src/models/objects/icdata.dart b/runtime/observatory/lib/src/models/objects/icdata.dart
new file mode 100644
index 0000000..0dcb9e9
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/icdata.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class ICDataRef extends ObjectRef {
+  String get selector;
+}
diff --git a/runtime/observatory/lib/src/models/objects/instance.dart b/runtime/observatory/lib/src/models/objects/instance.dart
new file mode 100644
index 0000000..ba3d93b
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/instance.dart
@@ -0,0 +1,312 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 models;
+
+enum InstanceKind {
+  /// A general instance of the Dart class Object.
+  plainInstance,
+  /// null instance.
+  vNull,
+  /// true or false.
+  bool,
+  /// An instance of the Dart class double.
+  double,
+  /// An instance of the Dart class int.
+  int,
+  /// An instance of the Dart class String.
+  string,
+  /// An instance of the built-in VM List implementation. User-defined
+  /// Lists will be PlainInstance.
+  list,
+  /// An instance of the built-in VM Map implementation. User-defined
+  /// Maps will be PlainInstance.
+  map,
+  /// Vector instance kinds.
+  float32x4,
+  /// Vector instance kinds.
+  float64x2,
+  /// Vector instance kinds.
+  int32x4,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  uint8ClampedList,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  uint8List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  uint16List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  uint32List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  uint64List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  int8List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  int16List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  int32List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  int64List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  float32List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  float64List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  int32x4List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  float32x4List,
+  /// An instance of the built-in VM TypedData implementations. User-defined
+  /// TypedDatas will be PlainInstance.
+  float64x2List,
+  /// An instance of the Dart class StackTrace.
+  stackTrace,
+  /// An instance of the built-in VM Closure implementation. User-defined
+  /// Closures will be PlainInstance.
+  closure,
+  /// An instance of the Dart class MirrorReference.
+  mirrorReference,
+  /// An instance of the Dart class RegExp.
+  regExp,
+  /// An instance of the Dart class WeakProperty.
+  weakProperty,
+  /// An instance of the Dart class Type.
+  type,
+  /// An instance of the Dart class TypeParameter.
+  typeParameter,
+  /// An instance of the Dart class TypeRef.
+  typeRef,
+  /// An instance of the Dart class BoundedType.
+  boundedType,
+}
+
+bool isTypedData(InstanceKind kind) {
+  switch (kind) {
+    case InstanceKind.uint8ClampedList:
+    case InstanceKind.uint8List:
+    case InstanceKind.uint16List:
+    case InstanceKind.uint32List:
+    case InstanceKind.uint64List:
+    case InstanceKind.int8List:
+    case InstanceKind.int16List:
+    case InstanceKind.int32List:
+    case InstanceKind.int64List:
+    case InstanceKind.float32List:
+    case InstanceKind.float64List:
+    case InstanceKind.int32x4List:
+    case InstanceKind.float32x4List:
+    case InstanceKind.float64x2List:
+      return true;
+    default:
+    return false;
+  }
+}
+
+bool isSimdValue(InstanceKind kind) {
+  switch (kind) {
+    case InstanceKind.float32x4:
+    case InstanceKind.float64x2:
+    case InstanceKind.int32x4:
+      return true;
+    default:
+    return false;
+  }
+}
+
+abstract class InstanceRef extends ObjectRef {
+  /// What kind of instance is this?
+  InstanceKind get kind;
+
+  /// Instance references always include their class.
+  ClassRef get clazz;
+
+  /// [optional] The value of this instance as a string.
+  ///
+  /// Provided for the instance kinds:
+  ///   Null (null)
+  ///   Bool (true or false)
+  ///   Double (suitable for passing to Double.parse())
+  ///   Int (suitable for passing to int.parse())
+  ///   String (value may be truncated)
+  ///   Float32x4
+  ///   Float64x2
+  ///   Int32x4
+  ///   StackTrace
+  String get valueAsString;
+
+  /// [optional] The valueAsString for String references may be truncated. If so,
+  /// this property is added with the value 'true'.
+  ///
+  /// New code should use 'length' and 'count' instead.
+  bool get valueAsStringIsTruncated;
+
+  /// [optional] The length of a List or the number of associations in a Map or
+  /// the number of codeunits in a String.
+  ///
+  /// Provided for instance kinds:
+  ///   String
+  ///   List
+  ///   Map
+  ///   Uint8ClampedList
+  ///   Uint8List
+  ///   Uint16List
+  ///   Uint32List
+  ///   Uint64List
+  ///   Int8List
+  ///   Int16List
+  ///   Int32List
+  ///   Int64List
+  ///   Float32List
+  ///   Float64List
+  ///   Int32x4List
+  ///   Float32x4List
+  ///   Float64x2List
+  int get length;
+
+  /// [optional] The name of a Type instance.
+  ///
+  /// Provided for instance kinds:
+  ///   Type
+  String get name;
+
+  /// [optional] The corresponding Class if this Type is canonical.
+  ///
+  /// Provided for instance kinds:
+  ///   Type
+  ClassRef get typeClass;
+
+  /// [optional] The parameterized class of a type parameter:
+  ///
+  /// Provided for instance kinds:
+  ///   TypeParameter
+  ClassRef get parameterizedClass;
+
+  /// [optional] The pattern of a RegExp instance.
+  ///
+  /// The pattern is always an instance of kind String.
+  ///
+  /// Provided for instance kinds:
+  ///   RegExp
+  InstanceRef get pattern;
+
+  /// [optional] The function associated with a Closure instance.
+  ///
+  /// Provided for instance kinds:
+  ///   Closure
+  FunctionRef get closureFunction;
+}
+
+abstract class Instance extends Object implements InstanceRef {
+  /// [optional] The index of the first element or association or codeunit
+  /// returned. This is only provided when it is non-zero.
+  ///
+  /// Provided for instance kinds:
+  ///   String
+  ///   List
+  ///   Map
+  ///   Uint8ClampedList
+  ///   Uint8List
+  ///   Uint16List
+  ///   Uint32List
+  ///   Uint64List
+  ///   Int8List
+  ///   Int16List
+  ///   Int32List
+  ///   Int64List
+  ///   Float32List
+  ///   Float64List
+  ///   Int32x4List
+  ///   Float32x4List
+  ///   Float64x2List
+  int get offset;
+
+  /// [optional] The number of elements or associations or codeunits returned.
+  /// This is only provided when it is less than length.
+  ///
+  /// Provided for instance kinds:
+  ///   String
+  ///   List
+  ///   Map
+  ///   Uint8ClampedList
+  ///   Uint8List
+  ///   Uint16List
+  ///   Uint32List
+  ///   Uint64List
+  ///   Int8List
+  ///   Int16List
+  ///   Int32List
+  ///   Int64List
+  ///   Float32List
+  ///   Float64List
+  ///   Int32x4List
+  ///   Float32x4List
+  ///   Float64x2List
+  int get count;
+
+  /// [optional] The elements of a TypedData instance.
+  ///
+  /// Provided for instance kinds:
+  ///   Uint8ClampedList
+  ///   Uint8List
+  ///   Uint16List
+  ///   Uint32List
+  ///   Uint64List
+  ///   Int8List
+  ///   Int16List
+  ///   Int32List
+  ///   Int64List
+  ///   Float32List
+  ///   Float64List
+  ///   Int32x4List
+  ///   Float32x4List
+  ///   Float64x2List
+  Iterable<dynamic> get typedElements;
+
+  /// [optional]The fields of this Instance.
+  Iterable<BoundField> get fields;
+
+  /// [optional] The elements of a List instance.
+  ///
+  /// Provided for instance kinds:
+  ///   List
+  Iterable<Guarded<ObjectRef>> get elements;
+  // It should be:
+  // Iterable<Guarded<InstanceRef>> get elements;
+  // In some situations we obtain lists of non Instances
+
+  /// [optional] The elements of a Map instance.
+  ///
+  /// Provided for instance kinds:
+  ///   Map
+  Iterable<MapAssociation> get associations;
+
+  /// [optional] The key for a WeakProperty instance.
+  ///
+  /// Provided for instance kinds:
+  ///   WeakProperty
+  InstanceRef get key;
+
+  /// [optional] The key for a WeakProperty instance.
+  ///
+  /// Provided for instance kinds:
+  ///   WeakProperty
+  InstanceRef get value;
+
+  /// [optional] The referent of a MirrorReference instance.
+  ///
+  /// Provided for instance kinds:
+  ///   MirrorReference
+  ObjectRef get referent;
+}
diff --git a/runtime/observatory/lib/src/models/objects/isolate.dart b/runtime/observatory/lib/src/models/objects/isolate.dart
new file mode 100644
index 0000000..45f5524
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/isolate.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.
+
+part of models;
+
+abstract class IsolateRef {
+  /// The id which is passed to the getIsolate RPC to reload this
+  /// isolate.
+  String get id;
+
+  /// A numeric id for this isolate, represented as a string. Unique.
+  int get number;
+
+  /// A name identifying this isolate. Not guaranteed to be unique.
+  String get name;
+}
+
+abstract class Isolate extends IsolateRef {
+  /// The time that the VM started in milliseconds since the epoch.
+  DateTime get startTime;
+
+  /// Is the isolate in a runnable state?
+  bool get runnable;
+
+  /// The number of live ports for this isolate.
+  //int get livePorts;
+
+  /// Will this isolate pause when exiting?
+  //bool get pauseOnExit;
+
+  /// The last pause event delivered to the isolate. If the isolate is
+  /// running, this will be a resume event.
+  //Event get pauseEvent;
+
+  /// [optional] The root library for this isolate.
+  ///
+  /// Guaranteed to be initialized when the IsolateRunnable event fires.
+  //LibraryRef get rootLib;
+
+  /// A list of all libraries for this isolate.
+  ///
+  /// Guaranteed to be initialized when the IsolateRunnable event fires.
+  Iterable<LibraryRef> get libraries;
+
+  /// A list of all breakpoints for this isolate.
+  //Iterable<Breakpoint> get breakpoints;
+
+  /// [optional] The error that is causing this isolate to exit, if applicable.
+  Error get error;
+
+  /// The current pause on exception mode for this isolate.
+  //ExceptionPauseMode get exceptionPauseMode;
+
+  /// [optional]The list of service extension RPCs that are registered for this
+  /// isolate, if any.
+  Iterable<String> get extensionRPCs;
+
+  Map get counters;
+  HeapSpace get newSpace;
+  HeapSpace get oldSpace;
+}
diff --git a/runtime/observatory/lib/src/models/objects/library.dart b/runtime/observatory/lib/src/models/objects/library.dart
new file mode 100644
index 0000000..281242a
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/library.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.
+
+part of models;
+
+abstract class LibraryRef extends ObjectRef {
+  /// The name of this library.
+  String get name;
+
+  /// The uri of this library.
+  String get uri;
+}
+
+abstract class Library extends Object implements LibraryRef {
+  /// Is this library debuggable? Default true.
+  bool get debuggable;
+
+  /// A list of the imports for this library.
+  //LibraryDependency[] dependencies;
+
+  // A list of the scripts which constitute this library.
+  Iterable<ScriptRef> get scripts;
+
+  // A list of the top-level variables in this library.
+  //List<FieldRef> get variables;
+
+  // A list of the top-level functions in this library.
+  //List<FunctionRef> get functions;
+
+  // A list of all classes in this library.
+  Iterable<ClassRef> get classes;
+}
diff --git a/runtime/observatory/lib/src/models/objects/local_var_descriptors.dart b/runtime/observatory/lib/src/models/objects/local_var_descriptors.dart
new file mode 100644
index 0000000..5643b80
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/local_var_descriptors.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class LocalVarDescriptorsRef extends ObjectRef {
+  /// [optional]
+  String get name;
+}
diff --git a/runtime/observatory/lib/src/models/objects/map_association.dart b/runtime/observatory/lib/src/models/objects/map_association.dart
new file mode 100644
index 0000000..9f786f9
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/map_association.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class MapAssociation {
+  Guarded<InstanceRef> get key;
+  Guarded<InstanceRef> get value;
+}
diff --git a/runtime/observatory/lib/src/models/objects/megamorphiccache.dart b/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
new file mode 100644
index 0000000..a87fb48
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class MegamorphicCacheRef extends ObjectRef {
+  String get selector;
+}
diff --git a/runtime/observatory/lib/src/models/objects/notification.dart b/runtime/observatory/lib/src/models/objects/notification.dart
new file mode 100644
index 0000000..3a2ae9a
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/notification.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class Notification {}
+
+abstract class ExceptionNotification implements Notification{
+  Exception get exception;
+  /// [optional]
+  StackTrace get stacktrace;
+}
+
+abstract class EventNotification implements Notification{
+  Event get event;
+}
diff --git a/runtime/observatory/lib/src/models/objects/object.dart b/runtime/observatory/lib/src/models/objects/object.dart
new file mode 100644
index 0000000..7679c5d
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/object.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class ObjectRef {
+  /// A unique identifier for an Object.
+  String get id;
+}
+
+abstract class Object implements ObjectRef {
+  /// [optional] If an object is allocated in the Dart heap, it will have
+  /// a corresponding class object.
+  ///
+  /// The class of a non-instance is not a Dart class, but is instead
+  /// an internal vm object.
+  ///
+  /// Moving an Object into or out of the heap is considered a
+  /// backwards compatible change for types other than Instance.
+  ClassRef get clazz;
+
+  /// [optional] The size of this object in the heap.
+  ///
+  /// If an object is not heap-allocated, then this field is omitted.
+  ///
+  /// Note that the size can be zero for some objects. In the current
+  /// VM implementation, this occurs for small integers, which are
+  /// stored entirely within their object pointers.
+  int get size;
+}
diff --git a/runtime/observatory/lib/src/models/objects/objectpool.dart b/runtime/observatory/lib/src/models/objects/objectpool.dart
new file mode 100644
index 0000000..c9be553
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/objectpool.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class ObjectPoolRef extends ObjectRef {
+  int get length;
+}
diff --git a/runtime/observatory/lib/src/models/objects/pc_descriptors.dart b/runtime/observatory/lib/src/models/objects/pc_descriptors.dart
new file mode 100644
index 0000000..fea4ce6
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/pc_descriptors.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class PcDescriptorsRef extends ObjectRef {
+  /// [optional]
+  String get name;
+}
diff --git a/runtime/observatory/lib/src/models/objects/sample_profile.dart b/runtime/observatory/lib/src/models/objects/sample_profile.dart
new file mode 100644
index 0000000..5c5a983
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/sample_profile.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+enum ProfileTreeDirection {
+  inclusive,
+  exclusive
+}
+
+abstract class SampleProfile {
+  int get sampleCount;
+  int get stackDepth;
+  double get sampleRate;
+  double get timeSpan;
+
+  FunctionCallTree loadFunctionTree(ProfileTreeDirection direction);
+  CodeCallTree loadCodeTree(ProfileTreeDirection direction);
+}
+
+abstract class Profile {
+  double get normalizedExclusiveTicks;
+  double get normalizedInclusiveTicks;
+}
+
+abstract class ProfileCode extends Profile {
+  CodeRef get code;
+}
+
+abstract class ProfileFunction extends Profile {
+  FunctionRef get function;
+}
+
+typedef bool CallTreeNodeFilter(CallTreeNode);
+
+abstract class CallTree {
+  CallTree filtered(CallTreeNodeFilter filter);
+}
+
+abstract class CodeCallTree extends CallTree {
+  CodeCallTreeNode get root;
+  CodeCallTree filtered(CallTreeNodeFilter filter);
+}
+
+abstract class FunctionCallTree extends CallTree {
+  FunctionCallTreeNode get root;
+  FunctionCallTree filtered(CallTreeNodeFilter filter);
+}
+
+abstract class CallTreeNode {
+  double get percentage;
+  Iterable<CallTreeNode> get children;
+}
+
+abstract class CodeCallTreeNode extends CallTreeNode {
+  ProfileCode get profileCode;
+  Iterable<CodeCallTreeNode> get children;
+}
+
+abstract class FunctionCallTreeNode extends CallTreeNode {
+  ProfileFunction get profileFunction;
+  Iterable<FunctionCallTreeNode> get children;
+}
diff --git a/runtime/observatory/lib/src/models/objects/script.dart b/runtime/observatory/lib/src/models/objects/script.dart
new file mode 100644
index 0000000..3736651
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/script.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.
+
+part of models;
+
+abstract class ScriptRef extends ObjectRef {
+  /// The uri from which this script was loaded.
+  String get uri;
+}
+
+abstract class Script extends Object implements ScriptRef {
+  /// The library which owns this script.
+  // LibraryRef get library;
+
+  /// The source code for this script. For certain built-in scripts,
+  /// this may be reconstructed without source comments.
+  String get source;
+
+  int tokenToLine(int token);
+  int tokenToCol(int token);
+}
diff --git a/runtime/observatory/lib/src/models/objects/sentinel.dart b/runtime/observatory/lib/src/models/objects/sentinel.dart
new file mode 100644
index 0000000..f45e431
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/sentinel.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 models;
+
+enum SentinelKind {
+  /// Indicates that the object referred to has been collected by the GC.
+  collected,
+  /// Indicates that an object id has expired.
+  expired,
+  /// Indicates that a variable or field has not been initialized.
+  notInitialized,
+  /// Indicates that a variable or field is in the process of being initialized.
+  initializing,
+  /// Indicates that a variable has been eliminated by the optimizing compiler.
+  optimizedOut,
+  /// Reserved for future use.
+  free,
+}
+
+abstract class Sentinel {
+  /// What kind of sentinel is this?
+  SentinelKind get kind;
+
+  /// A reasonable string representation of this sentinel.
+  String get valueAsString;
+}
diff --git a/runtime/observatory/lib/src/models/objects/source_location.dart b/runtime/observatory/lib/src/models/objects/source_location.dart
new file mode 100644
index 0000000..dd9f663
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/source_location.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class SourceLocation {
+  /// The script containing the source location.
+  ScriptRef get script;
+  /// The first token of the location.
+  int get tokenPos;
+  /// The last token of the location if this is a range. [optional]
+  int get endTokenPos;
+}
diff --git a/runtime/observatory/lib/src/models/objects/target.dart b/runtime/observatory/lib/src/models/objects/target.dart
new file mode 100644
index 0000000..a58673f
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/target.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class Target {
+  String get name;
+}
diff --git a/runtime/observatory/lib/src/models/objects/timeline_event.dart b/runtime/observatory/lib/src/models/objects/timeline_event.dart
new file mode 100644
index 0000000..61bf444
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/timeline_event.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class TimelineEvent implements Map<String, dynamic> {}
diff --git a/runtime/observatory/lib/src/models/objects/token_stream.dart b/runtime/observatory/lib/src/models/objects/token_stream.dart
new file mode 100644
index 0000000..5dc5d69
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/token_stream.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class TokenStreamRef extends ObjectRef {
+  /// [optional]
+  String get name;
+}
diff --git a/runtime/observatory/lib/src/models/objects/unknown.dart b/runtime/observatory/lib/src/models/objects/unknown.dart
new file mode 100644
index 0000000..3faeed0
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/unknown.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class UnknownObjectRef extends ObjectRef {
+  String get vmType;
+}
diff --git a/runtime/observatory/lib/src/models/objects/vm.dart b/runtime/observatory/lib/src/models/objects/vm.dart
new file mode 100644
index 0000000..11e3af5
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/vm.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class VMRef {
+  /// A name identifying this vm. Not guaranteed to be unique.
+  String get name;
+
+  /// [Not actually from the apis]
+  /// A name used to identify the VM in the UI.
+  String get displayName;
+}
+
+abstract class VM implements VMRef {
+  /// Word length on target architecture (e.g. 32, 64).
+  int get architectureBits;
+
+  /// The CPU we are generating code for.
+  String get targetCPU;
+
+  /// The CPU we are actually running on.
+  String get hostCPU;
+
+  /// The Dart VM version string.
+  String get version;
+
+  /// The process id for the VM.
+  int get pid;
+
+  /// The time that the VM started in milliseconds since the epoch.
+  ///
+  /// Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
+  DateTime get startTime;
+
+  // A list of isolates running in the VM.
+  Iterable<IsolateRef> get isolates;
+}
diff --git a/runtime/observatory/lib/src/models/repositories/allocation_profile.dart b/runtime/observatory/lib/src/models/repositories/allocation_profile.dart
new file mode 100644
index 0000000..5b917ef
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/allocation_profile.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class AllocationProfileRepository {
+  Future<AllocationProfile> get(IsolateRef isolate, {bool gc: false,
+                                                     bool reset: false});
+}
diff --git a/runtime/observatory/lib/src/models/repositories/class.dart b/runtime/observatory/lib/src/models/repositories/class.dart
new file mode 100644
index 0000000..388256e
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/class.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class ClassRepository{
+  Future<Class> getObject();
+  Future<Class> get(String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/event.dart b/runtime/observatory/lib/src/models/repositories/event.dart
new file mode 100644
index 0000000..3e00359
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/event.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.
+
+part of models;
+
+abstract class EventRepository {
+  Stream<Event> get onEvent;
+  Stream<VMEvent> get onVMEvent;
+  Stream<VMUpdateEvent> get onVMUpdate;
+  Stream<IsolateEvent> get onIsolateEvent;
+  Stream<IsolateStartEvent> get onIsolateStart;
+  Stream<IsolateRunnableEvent> get onIsolateRunnable;
+  Stream<IsolateExitEvent> get onIsolateExit;
+  Stream<IsolateUpdateEvent> get onIsolateUpdate;
+  Stream<IsolateReloadEvent> get onIsolateReload;
+  Stream<ServiceExtensionAddedEvent> get onServiceExtensionAdded;
+  Stream<DebugEvent> get onDebugEvent;
+  Stream<PauseStartEvent> get onPauseStart;
+  Stream<PauseExitEvent> get onPauseExit;
+  Stream<PauseBreakpointEvent> get onPauseBreakpoint;
+  Stream<PauseInterruptedEvent> get onPauseInterrupted;
+  Stream<PauseExceptionEvent> get onPauseException;
+  Stream<ResumeEvent> get onResume;
+  Stream<BreakpointAddedEvent> get onBreakpointAdded;
+  Stream<BreakpointResolvedEvent> get onBreakpointResolved;
+  Stream<BreakpointRemovedEvent> get onBreakpointRemoved;
+  Stream<InspectEvent> get onInspect;
+  Stream<GCEvent> get onGCEvent;
+  Stream<ExtensionEvent> get onExtensionEvent;
+  Stream<TimelineEventsEvent> get onTimelineEvents;
+  Stream<ConnectionClosedEvent> get onConnectionClosed;
+}
diff --git a/runtime/observatory/lib/src/models/repositories/flag.dart b/runtime/observatory/lib/src/models/repositories/flag.dart
new file mode 100644
index 0000000..358b933
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/flag.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class FlagsRepository {
+  Future<Iterable<Flag>> list();
+}
diff --git a/runtime/observatory/lib/src/models/repositories/instance.dart b/runtime/observatory/lib/src/models/repositories/instance.dart
new file mode 100644
index 0000000..673d6b6
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/instance.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class InstanceRepository{
+  Future<Instance> get(String id, {int count});
+}
diff --git a/runtime/observatory/lib/src/models/repositories/notification.dart b/runtime/observatory/lib/src/models/repositories/notification.dart
new file mode 100644
index 0000000..816bf04
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/notification.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class NotificationChangeEvent {
+  NotificationRepository get repository;
+}
+
+abstract class NotificationRepository {
+  Stream<NotificationChangeEvent> get onChange;
+  Iterable<Notification> list();
+  void delete(Notification);
+  void deleteAll();
+}
diff --git a/runtime/observatory/lib/src/models/repositories/sample_profile.dart b/runtime/observatory/lib/src/models/repositories/sample_profile.dart
new file mode 100644
index 0000000..3ec7cfd
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/sample_profile.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 models;
+
+enum SampleProfileTag {
+  userVM,
+  userOnly,
+  vmUser,
+  vmOnly,
+  none
+}
+
+enum SampleProfileLoadingStatus {
+  disabled,
+  fetching,
+  loading,
+  loaded
+}
+
+bool isSampleProcessRunning(SampleProfileLoadingStatus status) {
+  switch (status) {
+    case SampleProfileLoadingStatus.fetching:
+    case SampleProfileLoadingStatus.loading:
+      return true;
+    default:
+      return false;
+  }
+}
+
+abstract class SampleProfileLoadingProgressEvent {
+  SampleProfileLoadingProgress get progress;
+}
+
+abstract class SampleProfileLoadingProgress {
+  SampleProfileLoadingStatus get status;
+  double get progress;
+  Duration get fetchingTime;
+  Duration get loadingTime;
+  SampleProfile get profile;
+}
+
+abstract class ClassSampleProfileRepository {
+  Stream<SampleProfileLoadingProgressEvent> get(ClassRef cls,
+      SampleProfileTag tag, {bool clear: false});
+}
+
+abstract class IsolateSampleProfileRepository {
+  Stream<SampleProfileLoadingProgressEvent> get(IsolateRef cls,
+      SampleProfileTag tag, {bool clear: false, bool forceFetch: false});
+}
diff --git a/runtime/observatory/lib/src/models/repositories/script.dart b/runtime/observatory/lib/src/models/repositories/script.dart
new file mode 100644
index 0000000..3073c2e
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/script.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class ScriptRepository {
+  Future<Script> get(String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/target.dart b/runtime/observatory/lib/src/models/repositories/target.dart
new file mode 100644
index 0000000..4d276f6
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/target.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.
+
+part of models;
+
+abstract class TargetChangeEvent {
+  TargetRepository get repository;
+}
+
+abstract class TargetRepository {
+  Stream<TargetChangeEvent> get onChange;
+
+  Target get current;
+  Iterable<Target> list();
+  void add(String);
+  void setCurrent(Target);
+  void delete(Target);
+}
diff --git a/runtime/observatory/lib/src/repositories/allocation_profile.dart b/runtime/observatory/lib/src/repositories/allocation_profile.dart
new file mode 100644
index 0000000..4b1a73d
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/allocation_profile.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class AllocationProfileRepository implements M.AllocationProfileRepository {
+  static const _api = '_getAllocationProfile';
+
+  Future<M.AllocationProfile> get(M.IsolateRef i, {bool gc: false,
+                                                   bool reset: false}) async {
+    assert(gc != null);
+    assert(reset != null);
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    var params = {};
+    if (gc == true) {
+      params['gc'] = 'full';
+    }
+    if (reset == true) {
+      params['reset'] = true;
+    }
+    final response = await isolate.invokeRpc(_api, params);
+    isolate.updateHeapsFromMap(response['heaps']);
+    for (S.ServiceMap clsAllocations in response['members']) {
+      S.Class cls = clsAllocations['class'];
+      if (cls == null) {
+        continue;
+      }
+      cls.newSpace.update(clsAllocations['new']);
+      cls.oldSpace.update(clsAllocations['old']);
+    }
+    return new AllocationProfile(response);
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/class.dart b/runtime/observatory/lib/src/repositories/class.dart
new file mode 100644
index 0000000..911c363
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/class.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
+
+part of repositories;
+
+class ClassRepository extends M.ClassRepository {
+  final S.Isolate isolate;
+
+  ClassRepository(this.isolate);
+
+  Future<M.Class> getObject() {
+    return isolate.getClassHierarchy();
+  }
+  Future<M.Class> get(String id) async {
+    return (await isolate.getObject(id)) as S.Class;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/event.dart b/runtime/observatory/lib/src/repositories/event.dart
new file mode 100644
index 0000000..d6300e9
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/event.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 repositories;
+
+class EventRepository implements M.EventRepository {
+  final StreamController<M.Event> _onEvent;
+  Stream<M.Event> get onEvent => _onEvent.stream;
+
+  final Stream<M.VMEvent> onVMEvent;
+  final Stream<M.VMUpdateEvent> onVMUpdate;
+  final Stream<M.IsolateEvent> onIsolateEvent;
+  final Stream<M.IsolateStartEvent> onIsolateStart;
+  final Stream<M.IsolateRunnableEvent> onIsolateRunnable;
+  final Stream<M.IsolateExitEvent> onIsolateExit;
+  final Stream<M.IsolateUpdateEvent> onIsolateUpdate;
+  final Stream<M.IsolateReloadEvent> onIsolateReload;
+  final Stream<M.ServiceExtensionAddedEvent> onServiceExtensionAdded;
+  final Stream<M.DebugEvent> onDebugEvent;
+  final Stream<M.PauseStartEvent> onPauseStart;
+  final Stream<M.PauseExitEvent> onPauseExit;
+  final Stream<M.PauseBreakpointEvent> onPauseBreakpoint;
+  final Stream<M.PauseInterruptedEvent> onPauseInterrupted;
+  final Stream<M.PauseExceptionEvent> onPauseException;
+  final Stream<M.ResumeEvent> onResume;
+  final Stream<M.BreakpointAddedEvent> onBreakpointAdded;
+  final Stream<M.BreakpointResolvedEvent> onBreakpointResolved;
+  final Stream<M.BreakpointRemovedEvent> onBreakpointRemoved;
+  final Stream<M.InspectEvent> onInspect;
+  final Stream<M.GCEvent> onGCEvent;
+  final Stream<M.ExtensionEvent> onExtensionEvent;
+  final Stream<M.TimelineEventsEvent> onTimelineEvents;
+  final Stream<M.ConnectionClosedEvent> onConnectionClosed;
+
+  EventRepository() : this._(new StreamController.broadcast());
+
+  EventRepository._(StreamController controller) : this.__(controller,
+      controller.stream.where((e) => e is M.VMEvent),
+      controller.stream.where((e) => e is M.IsolateEvent),
+      controller.stream.where((e) => e is M.DebugEvent),
+      controller.stream.where((e) => e is M.GCEvent),
+      controller.stream.where((e) => e is M.ExtensionEvent),
+      controller.stream.where((e) => e is M.TimelineEventsEvent),
+      controller.stream.where((e) => e is M.ConnectionClosedEvent));
+
+  EventRepository.__(StreamController controller,
+    Stream<M.VMEvent> onVMEvent, Stream<M.IsolateEvent> onIsolateEvent,
+    Stream<M.DebugEvent> onDebugEvent, Stream<M.GCEvent> onGCEvent,
+    Stream<M.ExtensionEvent> onExtensionEvent,
+    Stream<M.TimelineEventsEvent> onTimelineEvents,
+    Stream<M.ConnectionClosedEvent> onConnectionClosed)
+    : _onEvent = controller,
+      onVMEvent = onVMEvent,
+      onVMUpdate = onVMEvent.where((e) => e is M.VMUpdateEvent),
+      onIsolateEvent = onIsolateEvent,
+      onIsolateStart = onIsolateEvent.where((e) => e is M.IsolateStartEvent),
+      onIsolateRunnable =
+          onIsolateEvent.where((e) => e is M.IsolateRunnableEvent),
+      onIsolateExit = onIsolateEvent.where((e) => e is M.IsolateExitEvent),
+      onIsolateUpdate = onIsolateEvent.where((e) => e is M.IsolateUpdateEvent),
+      onIsolateReload = onIsolateEvent.where((e) => e is M.IsolateReloadEvent),
+      onServiceExtensionAdded =
+          onIsolateEvent.where((e) => e is M.IsolateReloadEvent),
+      onDebugEvent = onDebugEvent,
+      onPauseStart = onDebugEvent.where((e) => e is M.PauseStartEvent),
+      onPauseExit = onDebugEvent.where((e) => e is M.PauseExitEvent),
+      onPauseBreakpoint =
+          onDebugEvent.where((e) => e is M.PauseBreakpointEvent),
+      onPauseInterrupted =
+          onDebugEvent.where((e) => e is M.PauseInterruptedEvent),
+      onPauseException = onDebugEvent.where((e) => e is M.PauseExceptionEvent),
+      onResume = onDebugEvent.where((e) => e is M.ResumeEvent),
+      onBreakpointAdded =
+          onDebugEvent.where((e) => e is M.BreakpointAddedEvent),
+      onBreakpointResolved =
+          onDebugEvent.where((e) => e is M.BreakpointResolvedEvent),
+      onBreakpointRemoved =
+          onDebugEvent.where((e) => e is M.BreakpointRemovedEvent),
+      onInspect = onDebugEvent.where((e) => e is M.InspectEvent),
+      onGCEvent = onGCEvent,
+      onExtensionEvent = onExtensionEvent,
+      onTimelineEvents = onTimelineEvents,
+      onConnectionClosed = onConnectionClosed;
+
+  void add(M.Event e) {
+    _onEvent.add(e);
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/flag.dart b/runtime/observatory/lib/src/repositories/flag.dart
new file mode 100644
index 0000000..0072c0e
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/flag.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class Flag implements M.Flag {
+  final String name;
+  final String comment;
+  final bool modified;
+  final String valueAsString;
+  Flag(this.name, this.comment, this.modified, this.valueAsString) {
+    assert(name != null);
+    assert(comment != null);
+    assert(modified != null);
+  }
+}
+
+class FlagsRepository implements M.FlagsRepository {
+  final S.VM vm;
+
+  FlagsRepository(this.vm);
+
+  Future<Iterable<Flag>> list() async{
+    List<Map> flags = ((await vm.getFlagList()) as S.ServiceMap)['flags'];
+    return flags.map(_toFlag);
+  }
+
+  static _toFlag(Map map){
+    return new Flag(map['name'],
+                    map['comment'],
+                    map['modified'],
+                    map['valueAsString']);
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/instance.dart b/runtime/observatory/lib/src/repositories/instance.dart
new file mode 100644
index 0000000..4f416bd
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/instance.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class InstanceRepository extends M.InstanceRepository {
+  final S.Isolate isolate;
+
+  InstanceRepository(this.isolate);
+
+  Future<M.Instance> get(String id, {int count: S.kDefaultFieldLimit}) async{
+    assert(count != null);
+    return (await isolate.getObject(id, count: count)) as S.Instance;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/notification.dart b/runtime/observatory/lib/src/repositories/notification.dart
new file mode 100644
index 0000000..80c25f2
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/notification.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 repositories;
+
+class NotificationChangeEvent implements M.NotificationChangeEvent {
+  final NotificationRepository repository;
+  NotificationChangeEvent(this.repository);
+}
+
+class NotificationRepository implements M.NotificationRepository {
+  final List<M.Notification> _list = new List<M.Notification>();
+
+  final StreamController<M.NotificationChangeEvent> _onChange =
+      new StreamController<M.NotificationChangeEvent>.broadcast();
+  Stream<M.NotificationChangeEvent> get onChange => _onChange.stream;
+
+  void add(M.Notification notification) {
+    assert(notification != null);
+    _list.add(notification);
+    _notify();
+  }
+
+  Iterable<M.Notification> list() => _list;
+
+  void delete(M.Notification notification) {
+    if (_list.remove(notification))
+    _notify();
+  }
+
+  void deleteAll() {
+    if (_list.isNotEmpty) {
+      _list.clear();
+      _notify();
+    }
+  }
+
+  NotificationRepository();
+
+  void _notify() {
+    _onChange.add(new NotificationChangeEvent(this));
+  }
+
+  void deleteWhere(bool test(M.Notification element)) {
+    int length = _list.length;
+    _list.removeWhere(test);
+    if (_list.length != length) _notify();
+  }
+
+  void deletePauseEvents({M.Isolate isolate}) {
+    if (isolate == null) {
+      deleteWhere((notification) {
+        return notification is M.EventNotification &&
+               M.Event.isPauseEvent(notification.event);
+      });
+    } else {
+      deleteWhere((notification) {
+        return notification is M.EventNotification &&
+               M.Event.isPauseEvent(notification.event) &&
+               notification.event.isolate == isolate;
+      });
+    }
+  }
+
+  void deleteDisconnectEvents() {
+    deleteWhere((notification) {
+      return notification is M.EventNotification &&
+             notification.event is M.ConnectionClosedEvent;
+    });
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/sample_profile.dart b/runtime/observatory/lib/src/repositories/sample_profile.dart
new file mode 100644
index 0000000..5752139
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/sample_profile.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 repositories;
+
+String _tagToString(M.SampleProfileTag tag) {
+  switch (tag) {
+    case M.SampleProfileTag.userVM: return 'UserVM';
+    case M.SampleProfileTag.userOnly: return 'UserOnly';
+    case M.SampleProfileTag.vmUser: return 'VMUser';
+    case M.SampleProfileTag.vmOnly: return 'VMOnly';
+    case M.SampleProfileTag.none: return 'None';
+  }
+  throw new Exception('Unknown SampleProfileTag: $tag');
+}
+
+class SampleProfileLoadingProgressEvent
+  implements M.SampleProfileLoadingProgressEvent {
+  final SampleProfileLoadingProgress progress;
+  SampleProfileLoadingProgressEvent(this.progress);
+}
+
+class SampleProfileLoadingProgress extends M.SampleProfileLoadingProgress {
+  StreamController<SampleProfileLoadingProgressEvent> _onProgress =
+      new StreamController<SampleProfileLoadingProgressEvent>.broadcast();
+  Stream<SampleProfileLoadingProgressEvent> get onProgress =>
+      _onProgress.stream;
+
+  final S.Isolate isolate;
+  final S.Class cls;
+  final M.SampleProfileTag tag;
+  final bool clear;
+
+  M.SampleProfileLoadingStatus _status = M.SampleProfileLoadingStatus.fetching;
+  double _progress = 0.0;
+  final Stopwatch _fetchingTime = new Stopwatch();
+  final Stopwatch  _loadingTime = new Stopwatch();
+  CpuProfile _profile;
+
+  M.SampleProfileLoadingStatus get status => _status;
+  double get progress => _progress;
+  Duration get fetchingTime => _fetchingTime.elapsed;
+  Duration get loadingTime => _loadingTime.elapsed;
+  CpuProfile get profile => _profile;
+
+  SampleProfileLoadingProgress(this.isolate, this.tag,
+      this.clear, {this.cls}) {
+      _run();
+  }
+
+  Future _run() async {
+    _fetchingTime.start();
+    try {
+      if (clear) {
+        await isolate.invokeRpc('_clearCpuProfile', { });
+      }
+
+      final response = cls != null
+        ? await cls.getAllocationSamples(_tagToString(tag))
+        : await isolate.invokeRpc('_getCpuProfile',
+            { 'tags': _tagToString(tag) });
+
+      _fetchingTime.stop();
+      _loadingTime.start();
+      _status = M.SampleProfileLoadingStatus.loading;
+      _triggerOnProgress();
+
+      CpuProfile profile = new CpuProfile();
+
+      Stream<double> progress = profile.loadProgress(isolate, response);
+      progress.listen((value) { _progress = value; _triggerOnProgress(); });
+
+      await progress.drain();
+
+      profile.buildFunctionCallerAndCallees();
+      _profile = profile;
+
+      _loadingTime.stop();
+      _status = M.SampleProfileLoadingStatus.loaded;
+      _triggerOnProgress();
+    } catch (e) {
+      if (e is S.ServerRpcException) {
+        if (e.code == S.ServerRpcException.kFeatureDisabled) {
+          _status = M.SampleProfileLoadingStatus.disabled;
+          _triggerOnProgress();
+        }
+      }
+      rethrow;
+    } finally {
+      _onProgress.close();
+    }
+  }
+
+  void _triggerOnProgress() {
+    _onProgress.add(new SampleProfileLoadingProgressEvent(this));
+  }
+
+  void reuse() {
+    _onProgress =
+      new StreamController<SampleProfileLoadingProgressEvent>.broadcast();
+    (() async {
+      _triggerOnProgress();
+      _onProgress.close();
+    }());
+  }
+}
+
+class IsolateSampleProfileRepository
+    implements M.IsolateSampleProfileRepository {
+  SampleProfileLoadingProgress _last;
+
+  Stream<SampleProfileLoadingProgressEvent> get(M.IsolateRef i,
+      M.SampleProfileTag t, {bool clear: false, bool forceFetch: false}) {
+    assert(clear != null);
+    assert(forceFetch != null);
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    if (_last != null && !clear && !forceFetch && _last.isolate == isolate) {
+      _last.reuse();
+    } else {
+      _last = new SampleProfileLoadingProgress(isolate, t, clear);
+    }
+    return _last.onProgress;
+  }
+}
+
+class ClassSampleProfileRepository
+    implements M.ClassSampleProfileRepository {
+  Stream<SampleProfileLoadingProgressEvent> get(M.ClassRef c,
+      M.SampleProfileTag t, {bool clear: false}) {
+    S.Class cls = c as S.Class;
+    assert(cls != null);
+    return new SampleProfileLoadingProgress(cls.isolate, t,
+        clear, cls: cls).onProgress;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/script.dart b/runtime/observatory/lib/src/repositories/script.dart
new file mode 100644
index 0000000..918de35
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/script.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 repositories;
+
+class ScriptRepository implements M.ScriptRepository {
+  final S.Isolate isolate;
+
+  ScriptRepository(this.isolate);
+
+  Future<M.Script> get(String id) async {
+    return (await isolate.getObject(id)) as M.Script;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/settings.dart b/runtime/observatory/lib/src/repositories/settings.dart
new file mode 100644
index 0000000..4121d93
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/settings.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 repositories;
+
+/// Static settings database.
+class _Settings {
+  static Storage _storage = window.localStorage;
+
+  /// Associated [value] with [key]. [value] must be JSON encodable.
+  static void set(String key, dynamic value) {
+    _storage[key] = JSON.encode(value);
+  }
+
+  /// Get value associated with [key]. Return value will be a JSON encodable
+  /// object.
+  static dynamic get(String key) {
+    var value = _storage[key];
+    if (value == null) {
+      return null;
+    }
+    return JSON.decode(value);
+  }
+}
+
+/// A group of settings each prefixed with group name and a dot.
+class SettingsRepository {
+  /// Group name
+  final String group;
+
+  SettingsRepository(this.group);
+
+  String _fullKey(String key) => '$group.$key';
+
+  void set(String key, dynamic value) {
+    var fullKey = _fullKey(key);
+    _Settings.set(fullKey, value);
+  }
+
+  dynamic get(String key) {
+    var fullKey = _fullKey(key);
+    return _Settings.get(fullKey);
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/target.dart b/runtime/observatory/lib/src/repositories/target.dart
new file mode 100644
index 0000000..ec52128
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/target.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 repositories;
+
+class TargetChangeEvent implements M.TargetChangeEvent {
+  final TargetRepository repository;
+  TargetChangeEvent(this.repository);
+}
+
+class TargetRepository implements M.TargetRepository {
+
+  static const _historyKey = 'history';
+
+  final StreamController<TargetChangeEvent> _onChange;
+  final Stream<TargetChangeEvent> onChange;
+  final SettingsRepository _settings = new SettingsRepository('targetManager');
+
+  final List<SC.WebSocketVMTarget> _list = <SC.WebSocketVMTarget>[];
+  SC.WebSocketVMTarget current;
+
+  factory TargetRepository() {
+    var controller = new StreamController<TargetChangeEvent>();
+    var stream = controller.stream.asBroadcastStream();
+    return new TargetRepository._(controller, stream);
+  }
+
+  TargetRepository._(this._onChange, this.onChange) {
+    _restore();
+    if (_list.isEmpty) {
+      _list.add(new SC.WebSocketVMTarget(_networkAddressOfDefaultTarget()));
+    }
+    current = _list.first;
+  }
+
+  void add(String address) {
+    if (_find(address) != null) return;
+    _list.insert(0, new SC.WebSocketVMTarget(address));
+    _onChange.add(new TargetChangeEvent(this));
+    _store();
+  }
+
+  Iterable<SC.WebSocketVMTarget> list() => _list;
+
+  void setCurrent(M.Target t) {
+    SC.WebSocketVMTarget target = t as SC.WebSocketVMTarget;
+    if (!_list.contains(target)) return;
+    current = target;
+    current.lastConnectionTime = new DateTime.now().millisecondsSinceEpoch;
+    _onChange.add(new TargetChangeEvent(this));
+    _store();
+  }
+
+  void delete(o) {
+    if (_list.remove(o)) {
+      if (o == current) {
+        current = null;
+      }
+      _onChange.add(new TargetChangeEvent(this));
+      _store();
+    }
+  }
+
+  /// Read settings from data store.
+  void _restore() {
+    _list.clear();
+    var loaded = _settings.get(_historyKey);
+    if (loaded == null) {
+      return;
+    }
+    _list.addAll(loaded.map((i) => new SC.WebSocketVMTarget.fromMap(i)));
+    _list.sort((SC.WebSocketVMTarget a, SC.WebSocketVMTarget b) {
+       return b.lastConnectionTime.compareTo(a.lastConnectionTime);
+    });
+  }
+
+  /// After making a change, update settings.
+  void _store() {
+    _settings.set(_historyKey,  _list);
+  }
+
+  /// Find by networkAddress.
+  SC.WebSocketVMTarget _find(String networkAddress) {
+    for (SC.WebSocketVMTarget item in _list) {
+      if (item.networkAddress == networkAddress) {
+        return item;
+      }
+    }
+    return null;
+  }
+
+  static String _networkAddressOfDefaultTarget() {
+    if (Utils.runningInJavaScript()) {
+      // We are running as JavaScript, use the same host that Observatory has
+      // been loaded from.
+      return 'ws://${window.location.host}/ws';
+    } else {
+      // Otherwise, assume we are running from Dart Editor and want to connect
+      // to the default host.
+      return 'ws://localhost:8181/ws';
+    }
+  }
+}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 18d29bf..2d563dd 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -22,14 +22,14 @@
 
 /// An RpcException represents an exceptional event that happened
 /// while invoking an rpc.
-abstract class RpcException implements Exception {
+abstract class RpcException implements Exception, M.BasicException {
   RpcException(this.message);
 
   String message;
 }
 
 /// A ServerRpcException represents an error returned by the VM.
-class ServerRpcException extends RpcException {
+class ServerRpcException extends RpcException implements M.RequestException {
   /// A list of well-known server error codes.
   static const kParseError     = -32700;
   static const kInvalidRequest = -32600;
@@ -70,7 +70,8 @@
 
 /// A NetworkRpcException is used to indicate that an rpc has
 /// been canceled due to network error.
-class NetworkRpcException extends RpcException {
+class NetworkRpcException extends RpcException
+                          implements M.ConnectionException {
   NetworkRpcException(String message) : super(message);
 
   String toString() => 'NetworkRpcException(${message})';
@@ -92,7 +93,7 @@
 }
 
 /// A [ServiceObject] represents a persistent object within the vm.
-abstract class ServiceObject extends Observable {
+abstract class ServiceObject extends Observable implements M.ObjectRef {
   static int LexicalSortName(ServiceObject o1, ServiceObject o2) {
     return o1.name.compareTo(o2.name);
   }
@@ -237,9 +238,6 @@
           case 'ICData':
             obj = new ICData._empty(owner);
             break;
-          case 'Instructions':
-            obj = new Instructions._empty(owner);
-            break;
           case 'LocalVarDescriptors':
             obj = new LocalVarDescriptors._empty(owner);
             break;
@@ -266,8 +264,10 @@
       case 'Socket':
         obj = new Socket._empty(owner);
         break;
+      case 'Sentinel':
+        obj = new Sentinel._empty(owner);
+        break;
       case 'Instance':
-      case 'Sentinel':  // TODO(rmacnak): Separate this out.
         obj = new Instance._empty(owner);
         break;
       default:
@@ -424,7 +424,8 @@
 }
 
 /// A [SourceLocation] represents a location or range in the source code.
-class SourceLocation extends ServiceObject implements Location {
+class SourceLocation extends ServiceObject implements Location,
+                                                      M.SourceLocation {
   Script script;
   int tokenPos;
   int endTokenPos;
@@ -603,7 +604,7 @@
 }
 
 /// State for a VM being inspected.
-abstract class VM extends ServiceObjectOwner {
+abstract class VM extends ServiceObjectOwner implements M.VM {
   @reflectable VM get vm => this;
   @reflectable Isolate get isolate => null;
 
@@ -622,11 +623,13 @@
   final ObservableList<Isolate> isolates = new ObservableList<Isolate>();
 
   @observable String version = 'unknown';
+  @observable String hostCPU;
   @observable String targetCPU;
   @observable int architectureBits;
   @observable bool assertsEnabled = false;
   @observable bool typeChecksEnabled = false;
   @observable int pid = 0;
+  @observable int maxRSS = 0;
   @observable bool profileVM = false;
   @observable DateTime startTime;
   @observable DateTime refreshTime;
@@ -896,6 +899,7 @@
 
     _loaded = true;
     version = map['version'];
+    hostCPU = map['hostCPU'];
     targetCPU = map['targetCPU'];
     architectureBits = map['architectureBits'];
     int startTimeMillis = map['startTime'];
@@ -903,6 +907,7 @@
     refreshTime = new DateTime.now();
     notifyPropertyChange(#upTime, 0, 1);
     pid = map['pid'];
+    maxRSS = map['_maxRSS'];
     profileVM = map['_profilerMode'] == 'VM';
     assertsEnabled = map['_assertsEnabled'];
     typeChecksEnabled = map['_typeChecksEnabled'];
@@ -923,6 +928,8 @@
 }
 
 class FakeVM extends VM {
+  String get displayName => name;
+
   final Map _responses = {};
   FakeVM(Map responses) {
     if (responses == null) {
@@ -1071,7 +1078,7 @@
   }
 }
 
-class HeapSpace extends Observable {
+class HeapSpace extends Observable implements M.HeapSpace {
   @observable int used = 0;
   @observable int capacity = 0;
   @observable int external = 0;
@@ -1079,6 +1086,23 @@
   @observable double totalCollectionTimeInSeconds = 0.0;
   @observable double averageCollectionPeriodInMillis = 0.0;
 
+  Duration get avgCollectionTime {
+    final mcs = totalCollectionTimeInSeconds * Duration.MICROSECONDS_PER_SECOND
+                / math.max(collections, 1);
+    return new Duration(microseconds: mcs.ceil());
+  }
+
+  Duration get totalCollectionTime {
+    final mcs = totalCollectionTimeInSeconds * Duration.MICROSECONDS_PER_SECOND;
+    return new Duration(microseconds: mcs.ceil());
+  }
+
+  Duration get avgCollectionPeriod {
+    final mcs = averageCollectionPeriodInMillis
+                * Duration.MICROSECONDS_PER_MILLISECOND;
+    return new Duration(microseconds: mcs.ceil());
+  }
+
   void update(Map heapMap) {
     used = heapMap['used'];
     capacity = heapMap['capacity'];
@@ -1117,7 +1141,7 @@
 }
 
 /// State for a running isolate.
-class Isolate extends ServiceObjectOwner {
+class Isolate extends ServiceObjectOwner implements M.Isolate {
   static const kLoggingStream = '_Logging';
   static const kExtensionStream = 'Extension';
 
@@ -1133,7 +1157,7 @@
     return (new DateTime.now().difference(startTime));
   }
 
-  @observable ObservableMap counters = new ObservableMap();
+  @observable Map counters = {};
 
   void _updateRunState() {
     topFrame = (pauseEvent != null ? pauseEvent.topFrame : null);
@@ -1435,23 +1459,27 @@
       for (var i = 0; i < counts.length; i++) {
         sum += counts[i];
       }
-      // TODO: Why does this not work without this?
-      counters = toObservable({});
+      var _counters = {};
       if (sum == 0) {
         for (var i = 0; i < names.length; i++) {
-          counters[names[i]] = '0.0%';
+          _counters[names[i]] = '0.0%';
         }
       } else {
         for (var i = 0; i < names.length; i++) {
-          counters[names[i]] =
+          _counters[names[i]] =
               (counts[i] / sum * 100.0).toStringAsFixed(2) + '%';
         }
       }
+      counters = _counters;
     }
 
     updateHeapsFromMap(map['_heaps']);
     _updateBreakpoints(map['breakpoints']);
-    exceptionsPauseInfo = map['_debuggerSettings']['_exceptions'];
+    if (map['_debuggerSettings'] != null) {
+      exceptionsPauseInfo = map['_debuggerSettings']['_exceptions'];
+    } else {
+      exceptionsPauseInfo = "none";
+    }
 
     var newPauseEvent = map['pauseEvent'];
     assert((pauseEvent == null) ||
@@ -1787,16 +1815,11 @@
 
 
 /// A [ServiceObject] which implements [ObservableMap].
-class ServiceMap extends ServiceObject implements ObservableMap {
+class ServiceMap extends ServiceObject implements ObservableMap,
+                                                  M.UnknownObjectRef  {
   final ObservableMap _map = new ObservableMap();
   static String objectIdRingPrefix = 'objects/';
 
-  bool get canCache {
-    return (_type == 'Class' ||
-            _type == 'Function' ||
-            _type == 'Field') &&
-           !_id.startsWith(objectIdRingPrefix);
-  }
   bool get immutable => false;
 
   ServiceMap._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -1849,16 +1872,31 @@
   String toString() => "ServiceMap($_map)";
 }
 
+M.ErrorKind stringToErrorKind(String value) {
+  switch(value) {
+    case 'UnhandledException': return M.ErrorKind.unhandledException;
+    case 'LanguageError': return M.ErrorKind.unhandledException;
+    case 'InternalError': return M.ErrorKind.internalError;
+    case 'TerminationError': return M.ErrorKind.terminationError;
+  }
+  Logger.root.severe('Unrecognized error kind: $value');
+  throw new FallThroughError();
+}
+
 /// A [DartError] is peered to a Dart Error object.
-class DartError extends ServiceObject {
+class DartError extends ServiceObject implements M.Error {
   DartError._empty(ServiceObject owner) : super._empty(owner);
 
+  M.ErrorKind kind;
+  final M.ClassRef clazz = null;
+  final int size = null;
   @observable String message;
   @observable Instance exception;
   @observable Instance stacktrace;
 
   void _update(ObservableMap map, bool mapIsRef) {
     message = map['message'];
+    kind = stringToErrorKind(map['kind']);
     exception = new ServiceObject._fromMap(owner, map['exception']);
     stacktrace = new ServiceObject._fromMap(owner, map['stacktrace']);
     name = 'DartError($message)';
@@ -1886,6 +1924,7 @@
   static const kIsolateExit            = 'IsolateExit';
   static const kIsolateUpdate          = 'IsolateUpdate';
   static const kIsolateReload          = 'IsolateReload';
+  static const kIsolateSpawn           = 'IsolateSpawn';
   static const kServiceExtensionAdded  = 'ServiceExtensionAdded';
   static const kPauseStart             = 'PauseStart';
   static const kPauseExit              = 'PauseExit';
@@ -1913,13 +1952,15 @@
 
   @observable String kind;
   @observable DateTime timestamp;
+  List<M.Breakpoint> pauseBreakpoints;
   @observable Breakpoint breakpoint;
   @observable Frame topFrame;
+  @observable DartError error;
   @observable String extensionRPC;
   @observable Instance exception;
   @observable Instance reloadError;
   @observable bool atAsyncSuspension;
-  @observable ServiceObject inspectee;
+  @observable Instance inspectee;
   @observable ByteData data;
   @observable int count;
   @observable String reason;
@@ -1929,6 +1970,8 @@
   @observable String extensionKind;
   @observable Map extensionData;
   @observable List timelineEvents;
+  @observable String spawnToken;
+  @observable String spawnError;
 
   int chunkIndex, chunkCount, nodeCount;
 
@@ -1955,13 +1998,16 @@
     if (map['breakpoint'] != null) {
       breakpoint = map['breakpoint'];
     }
-    // TODO(turnidge): Expose the full list of breakpoints.  For now
-    // we just pretend like there is only one active breakpoint.
     if (map['pauseBreakpoints'] != null) {
-      var pauseBpts = map['pauseBreakpoints'];
-      if (pauseBpts.length > 0) {
-        breakpoint = pauseBpts[0];
+      pauseBreakpoints = map['pauseBreakpoints'];
+      if (pauseBreakpoints.length > 0) {
+        breakpoint = pauseBreakpoints[0];
       }
+    } else {
+      pauseBreakpoints = const [];
+    }
+    if (map['error'] != null) {
+      error = map['error'];
     }
     if (map['extensionRPC'] != null) {
       extensionRPC = map['extensionRPC'];
@@ -2011,6 +2057,12 @@
     if (map['timelineEvents'] != null) {
       timelineEvents = map['timelineEvents'];
     }
+    if (map['spawnToken'] != null) {
+      spawnToken = map['spawnToken'];
+    }
+    if (map['spawnError'] != null) {
+      spawnError = map['spawnError'];
+    }
   }
 
   String toString() {
@@ -2025,12 +2077,14 @@
   }
 }
 
-class Breakpoint extends ServiceObject {
+class Breakpoint extends ServiceObject implements M.Breakpoint {
   Breakpoint._empty(ServiceObjectOwner owner) : super._empty(owner);
 
+  final M.ClassRef clazz = null;
+  final int size = null;
+
   // TODO(turnidge): Add state to track if a breakpoint has been
   // removed from the program.  Remove from the cache when deleted.
-  bool get canCache => true;
   bool get immutable => false;
 
   // A unique integer identifier for this breakpoint.
@@ -2121,7 +2175,7 @@
 }
 
 
-class Library extends HeapObject {
+class Library extends HeapObject implements M.LibraryRef {
   @observable String uri;
   @reflectable final dependencies = new ObservableList<LibraryDependency>();
   @reflectable final scripts = new ObservableList<Script>();
@@ -2129,7 +2183,6 @@
   @reflectable final variables = new ObservableList<Field>();
   @reflectable final functions = new ObservableList<ServiceFunction>();
 
-  bool get canCache => true;
   bool get immutable => false;
 
   bool isDart(String libraryName) {
@@ -2187,7 +2240,7 @@
   String toString() => "Library($uri)";
 }
 
-class AllocationCount extends Observable {
+class AllocationCount extends Observable implements M.AllocationCount {
   @observable int instances = 0;
   @observable int bytes = 0;
 
@@ -2199,7 +2252,7 @@
   bool get empty => (instances == 0) && (bytes == 0);
 }
 
-class Allocations {
+class Allocations implements M.Allocations{
   // Indexes into VM provided array. (see vm/class_table.h).
   static const ALLOCATED_BEFORE_GC = 0;
   static const ALLOCATED_BEFORE_GC_SIZE = 1;
@@ -2223,7 +2276,7 @@
   bool get empty => accumulated.empty && current.empty;
 }
 
-class Class extends HeapObject {
+class Class extends HeapObject implements M.Class {
   @observable Library library;
 
   @observable bool isAbstract;
@@ -2234,7 +2287,7 @@
 
   @observable SourceLocation location;
 
-  @observable ServiceMap error;
+  @observable DartError error;
   @observable int vmCid;
 
   final Allocations newSpace = new Allocations();
@@ -2253,7 +2306,6 @@
   @observable Instance superType;
   @observable Instance mixin;
 
-  bool get canCache => true;
   bool get immutable => false;
 
   Class._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -2362,13 +2414,126 @@
   String toString() => 'Class($vmName)';
 }
 
-class Instance extends HeapObject {
-  @observable String kind;
+M.InstanceKind stringToInstanceKind(String s) {
+  switch (s) {
+    case 'PlainInstance':
+      return M.InstanceKind.plainInstance;
+    case 'Null':
+      return M.InstanceKind.vNull;
+    case 'Bool':
+      return M.InstanceKind.bool;
+    case 'Double':
+      return M.InstanceKind.double;
+    case 'Int':
+      return M.InstanceKind.int;
+    case 'String':
+      return M.InstanceKind.string;
+    case 'List':
+      return M.InstanceKind.list;
+    case 'Map':
+      return M.InstanceKind.map;
+    case 'Float32x4':
+      return M.InstanceKind.float32x4;
+    case 'Float64x2':
+      return M.InstanceKind.float64x2;
+    case 'Int32x4':
+      return M.InstanceKind.int32x4;
+    case 'Uint8ClampedList':
+      return M.InstanceKind.uint8ClampedList;
+    case 'Uint8List':
+      return M.InstanceKind.uint8List;
+    case 'Uint16List':
+      return M.InstanceKind.uint16List;
+    case 'Uint32List':
+      return M.InstanceKind.uint32List;
+    case 'Uint64List':
+      return M.InstanceKind.uint64List;
+    case 'Int8List':
+      return M.InstanceKind.int8List;
+    case 'Int16List':
+      return M.InstanceKind.int16List;
+    case 'Int32List':
+      return M.InstanceKind.int32List;
+    case 'Int64List':
+      return M.InstanceKind.int64List;
+    case 'Float32List':
+      return M.InstanceKind.float32List;
+    case 'Float64List':
+      return M.InstanceKind.float64List;
+    case 'Int32x4List':
+      return M.InstanceKind.int32x4List;
+    case 'Float32x4List':
+      return M.InstanceKind.float32x4List;
+    case 'Float64x2List':
+      return M.InstanceKind.float64x2List;
+    case 'StackTrace':
+      return M.InstanceKind.stackTrace;
+    case 'Closure':
+      return M.InstanceKind.closure;
+    case 'MirrorReference':
+      return M.InstanceKind.mirrorReference;
+    case 'RegExp':
+      return M.InstanceKind.regExp;
+    case 'WeakProperty':
+      return M.InstanceKind.weakProperty;
+    case 'Type':
+      return M.InstanceKind.type;
+    case 'TypeParameter':
+      return M.InstanceKind.typeParameter;
+    case 'TypeRef':
+      return M.InstanceKind.typeRef;
+    case 'BoundedType':
+      return M.InstanceKind.boundedType;
+  }
+  Logger.root.severe("Unrecognized InstanceKind: '$s'");
+  throw new FallThroughError();
+}
+
+class Guarded<T> implements M.Guarded<T> {
+  bool get isValue => asValue != null;
+  bool get isSentinel => asSentinel != null;
+  final Sentinel asSentinel;
+  final T asValue;
+
+  factory Guarded(ServiceObject obj) {
+    if (obj is Sentinel) {
+      return new Guarded.fromSentinel(obj);
+    } else if (obj is T) {
+      return new Guarded.fromValue(obj);
+    }
+    throw new Exception('${obj.type} is neither Sentinel or $T');
+  }
+
+  Guarded.fromSentinel(this.asSentinel)
+    : asValue = null;
+  Guarded.fromValue(this.asValue)
+    : asSentinel = null;
+}
+
+class BoundField implements M.BoundField {
+  final Field decl;
+  final Guarded<Instance> value;
+  BoundField(this.decl, value)
+    : value = new Guarded(value);
+}
+
+class MapAssociation implements M.MapAssociation {
+  final Guarded<Instance> key;
+  final Guarded<Instance> value;
+  MapAssociation(key, value)
+    : key = new Guarded(key),
+      value = new Guarded(value);
+}
+
+class Instance extends HeapObject implements M.Instance {
+  @observable M.InstanceKind kind;
   @observable String valueAsString;  // If primitive.
   @observable bool valueAsStringIsTruncated;
-  @observable ServiceFunction function;  // If a closure.
+  @observable ServiceFunction closureFunction;  // If a closure.
   @observable Context context;  // If a closure.
   @observable int length; // If a List, Map or TypedData.
+  int count;
+  int offset;
   @observable Instance pattern;  // If a RegExp.
 
   @observable String name;
@@ -2379,61 +2544,48 @@
   @observable Instance targetType;
   @observable Instance bound;
 
-  @observable var fields;
+  @observable Iterable<BoundField> fields;
   @observable var nativeFields;
-  @observable var elements;  // If a List.
-  @observable var associations;  // If a Map.
-  @observable var typedElements;  // If a TypedData.
-  @observable var referent;  // If a MirrorReference.
+  @observable Iterable<Guarded<ServiceObject>> elements;  // If a List.
+  @observable Iterable<MapAssociation> associations;  // If a Map.
+  @observable Iterable<dynamic> typedElements;  // If a TypedData.
+  @observable ServiceObject referent;  // If a MirrorReference.
   @observable Instance key;  // If a WeakProperty.
   @observable Instance value;  // If a WeakProperty.
   @observable Breakpoint activationBreakpoint;  // If a Closure.
-  @observable Function oneByteFunction;  // If a RegExp.
-  @observable Function twoByteFunction;  // If a RegExp.
-  @observable Function externalOneByteFunction;  // If a RegExp.
-  @observable Function externalTwoByteFunction;  // If a RegExp.
+  @observable ServiceFunction oneByteFunction;  // If a RegExp.
+  @observable ServiceFunction twoByteFunction;  // If a RegExp.
+  @observable ServiceFunction externalOneByteFunction;  // If a RegExp.
+  @observable ServiceFunction externalTwoByteFunction;  // If a RegExp.
   @observable Instance oneByteBytecode;  // If a RegExp.
   @observable Instance twoByteBytecode;  // If a RegExp.
   @observable bool isCaseSensitive;  // If a RegExp.
   @observable bool isMultiLine;  // If a RegExp.
 
   bool get isAbstractType {
-    return (kind == 'Type' || kind == 'TypeRef' ||
-            kind == 'TypeParameter' || kind == 'BoundedType');
+    return (kind == M.InstanceKind.type ||
+            kind == M.InstanceKind.typeRef ||
+            kind == M.InstanceKind.typeParameter ||
+            kind == M.InstanceKind.boundedType);
   }
-  bool get isNull => kind == 'Null';
-  bool get isBool => kind == 'Bool';
-  bool get isDouble => kind == 'Double';
-  bool get isString => kind == 'String';
-  bool get isInt => kind == 'Int';
-  bool get isList => kind == 'List';
-  bool get isMap => kind == 'Map';
+  bool get isNull => kind == M.InstanceKind.vNull;
+  bool get isBool => kind == M.InstanceKind.bool;
+  bool get isDouble => kind == M.InstanceKind.double;
+  bool get isString => kind == M.InstanceKind.string;
+  bool get isInt => kind == M.InstanceKind.int;
+  bool get isList => kind == M.InstanceKind.list;
+  bool get isMap => kind == M.InstanceKind.map;
   bool get isTypedData {
-    return kind == 'Uint8ClampedList'
-        || kind == 'Uint8List'
-        || kind == 'Uint16List'
-        || kind == 'Uint32List'
-        || kind == 'Uint64List'
-        || kind == 'Int8List'
-        || kind == 'Int16List'
-        || kind == 'Int32List'
-        || kind == 'Int64List'
-        || kind == 'Float32List'
-        || kind == 'Float64List'
-        || kind == 'Int32x4List'
-        || kind == 'Float32x4List'
-        || kind == 'Float64x2List';
+    return M.isTypedData(kind);
   }
   bool get isSimdValue {
-    return kind == 'Float32x4'
-        || kind == 'Float64x2'
-        || kind == 'Int32x4';
+    return M.isSimdValue(kind);
   }
-  bool get isRegExp => kind == 'RegExp';
-  bool get isMirrorReference => kind == 'MirrorReference';
-  bool get isWeakProperty => kind == 'WeakProperty';
-  bool get isClosure => kind == 'Closure';
-  bool get isStackTrace => kind == 'StackTrace';
+  bool get isRegExp => kind == M.InstanceKind.regExp;
+  bool get isMirrorReference => kind == M.InstanceKind.mirrorReference;
+  bool get isWeakProperty => kind == M.InstanceKind.weakProperty;
+  bool get isClosure => kind == M.InstanceKind.closure;
+  bool get isStackTrace => kind == M.InstanceKind.stackTrace;
   bool get isStackOverflowError {
     if (clazz == null) {
       return false;
@@ -2461,37 +2613,53 @@
   Instance._empty(ServiceObjectOwner owner) : super._empty(owner);
 
   void _update(ObservableMap map, bool mapIsRef) {
-    // Extract full properties.
+    // Extract full properties.1
     _upgradeCollection(map, isolate);
     super._update(map, mapIsRef);
 
-    kind = map['kind'];
+    kind = stringToInstanceKind(map['kind']);
     valueAsString = map['valueAsString'];
     // Coerce absence to false.
     valueAsStringIsTruncated = map['valueAsStringIsTruncated'] == true;
-    function = map['closureFunction'];
+    closureFunction = map['closureFunction'];
     context = map['closureContext'];
     name = map['name'];
     length = map['length'];
     pattern = map['pattern'];
+    typeClass = map['typeClass'];
 
     if (mapIsRef) {
       return;
     }
 
+    count = map['count'];
+    offset = map['offset'];
     isCaseSensitive = map['isCaseSensitive'];
     isMultiLine = map['isMultiLine'];
-    oneByteFunction = map['_oneByteFunction'];
-    twoByteFunction = map['_twoByteFunction'];
-    externalOneByteFunction = map['_externalOneByteFunction'];
-    externalTwoByteFunction = map['_externalTwoByteFunction'];
+    bool isCompiled = map['_oneByteFunction'] is ServiceFunction;
+    oneByteFunction = isCompiled ? map['_oneByteFunction'] : null;
+    twoByteFunction = isCompiled ? map['_twoByteFunction'] : null;
+    externalOneByteFunction = isCompiled ? map['_externalOneByteFunction'] : null;
+    externalTwoByteFunction = isCompiled ? map['_externalTwoByteFunction'] : null;
     oneByteBytecode = map['_oneByteBytecode'];
     twoByteBytecode = map['_twoByteBytecode'];
 
     nativeFields = map['_nativeFields'];
-    fields = map['fields'];
-    elements = map['elements'];
-    associations = map['associations'];
+    if (map['fields'] != null) {
+      fields = map['fields']
+        .map((f) => new BoundField(f['decl'], f['value'])).toList();
+    }
+    if (map['elements'] != null) {
+    // Should be:
+    // elements = map['elements'].map((e) => new Guarded<Instance>(e)).toList();
+    // some times we obtain object that are not InstanceRef
+      elements = map['elements'].map((e) => new Guarded<ServiceObject>(e))
+        .toList();
+    }
+    if (map['associations'] != null) {
+      associations = map['associations'].map((a) =>
+          new MapAssociation(a['key'], a['value'])).toList();
+    };
     if (map['bytes'] != null) {
       Uint8List bytes = BASE64.decode(map['bytes']);
       switch (map['kind']) {
@@ -2525,7 +2693,6 @@
           typedElements = bytes.buffer.asFloat64x2List(); break;
       }
     }
-    typeClass = map['typeClass'];
     parameterizedClass = map['parameterizedClass'];
     typeArguments = map['typeArguments'];
     parameterIndex = map['parameterIndex'];
@@ -2543,7 +2710,7 @@
 
   String get shortName {
     if (isClosure) {
-      return function.qualifiedName;
+      return closureFunction.qualifiedName;
     }
     if (valueAsString != null) {
       return valueAsString;
@@ -2559,8 +2726,8 @@
 }
 
 
-class Context extends HeapObject {
-  @observable var parentContext;
+class Context extends HeapObject implements M.Context {
+  @observable Context parentContext;
   @observable int length;
   @observable var variables;
 
@@ -2587,65 +2754,35 @@
   String toString() => 'Context($length)';
 }
 
-
-// TODO(koda): Sync this with VM.
-class FunctionKind {
-  final String _strValue;
-  FunctionKind._internal(this._strValue);
-  toString() => _strValue;
-  bool isSynthetic() => [kCollected, kNative, kStub, kTag].contains(this);
-  bool isDart() => !isSynthetic();
-  bool isStub() => (this == kStub);
-  bool hasDartCode() => isDart() || isStub();
-  static FunctionKind fromJSON(String value) {
-    switch(value) {
-      case 'RegularFunction': return kRegularFunction;
-      case 'ClosureFunction': return kClosureFunction;
-      case 'GetterFunction': return kGetterFunction;
-      case 'SetterFunction': return kSetterFunction;
-      case 'Constructor': return kConstructor;
-      case 'ImplicitGetter': return kImplicitGetterFunction;
-      case 'ImplicitSetter': return kImplicitSetterFunction;
-      case 'ImplicitStaticFinalGetter': return kImplicitStaticFinalGetter;
-      case 'IrregexpFunction': return kIrregexpFunction;
-      case 'StaticInitializer': return kStaticInitializer;
-      case 'MethodExtractor': return kMethodExtractor;
-      case 'NoSuchMethodDispatcher': return kNoSuchMethodDispatcher;
-      case 'InvokeFieldDispatcher': return kInvokeFieldDispatcher;
-      case 'Collected': return kCollected;
-      case 'Native': return kNative;
-      case 'Stub': return kStub;
-      case 'Tag': return kTag;
-      case 'SignatureFunction': return kSignatureFunction;
-    }
-    Logger.root.severe('Unrecognized function kind: $value');
-    throw new FallThroughError();
+M.FunctionKind stringToFunctionKind(String value) {
+  switch(value) {
+    case 'RegularFunction': return M.FunctionKind.regular;
+    case 'ClosureFunction': return M.FunctionKind.closure;
+    case 'GetterFunction': return M.FunctionKind.getter;
+    case 'SetterFunction': return M.FunctionKind.setter;
+    case 'Constructor': return M.FunctionKind.constructor;
+    case 'ImplicitGetter': return M.FunctionKind.implicitGetter;
+    case 'ImplicitSetter': return M.FunctionKind.implicitSetter;
+    case 'ImplicitStaticFinalGetter':
+      return M.FunctionKind.implicitStaticFinalGetter;
+    case 'IrregexpFunction': return M.FunctionKind.irregexpFunction;
+    case 'StaticInitializer': return M.FunctionKind.staticInitializer;
+    case 'MethodExtractor': return M.FunctionKind.methodExtractor;
+    case 'NoSuchMethodDispatcher': return M.FunctionKind.noSuchMethodDispatcher;
+    case 'InvokeFieldDispatcher': return M.FunctionKind.invokeFieldDispatcher;
+    case 'Collected': return M.FunctionKind.collected;
+    case 'Native': return M.FunctionKind.native;
+    case 'Stub': return M.FunctionKind.stub;
+    case 'Tag': return M.FunctionKind.tag;
+    case 'SignatureFunction': return M.FunctionKind.signatureFunction;
   }
-
-  static FunctionKind kRegularFunction = new FunctionKind._internal('function');
-  static FunctionKind kClosureFunction = new FunctionKind._internal('closure function');
-  static FunctionKind kGetterFunction = new FunctionKind._internal('getter function');
-  static FunctionKind kSetterFunction = new FunctionKind._internal('setter function');
-  static FunctionKind kConstructor = new FunctionKind._internal('constructor');
-  static FunctionKind kImplicitGetterFunction = new FunctionKind._internal('implicit getter function');
-  static FunctionKind kImplicitSetterFunction = new FunctionKind._internal('implicit setter function');
-  static FunctionKind kImplicitStaticFinalGetter = new FunctionKind._internal('implicit static final getter');
-  static FunctionKind kIrregexpFunction = new FunctionKind._internal('ir regexp function');
-  static FunctionKind kStaticInitializer = new FunctionKind._internal('static initializer');
-  static FunctionKind kMethodExtractor = new FunctionKind._internal('method extractor');
-  static FunctionKind kNoSuchMethodDispatcher = new FunctionKind._internal('noSuchMethod dispatcher');
-  static FunctionKind kInvokeFieldDispatcher = new FunctionKind._internal('invoke field dispatcher');
-  static FunctionKind kCollected = new FunctionKind._internal('Collected');
-  static FunctionKind kNative = new FunctionKind._internal('Native');
-  static FunctionKind kTag = new FunctionKind._internal('Tag');
-  static FunctionKind kStub = new FunctionKind._internal('Stub');
-  static FunctionKind kSignatureFunction = new FunctionKind._internal('SignatureFunction');
-  static FunctionKind kUNKNOWN = new FunctionKind._internal('UNKNOWN');
+  Logger.root.severe('Unrecognized function kind: $value');
+  throw new FallThroughError();
 }
 
-class ServiceFunction extends HeapObject {
+class ServiceFunction extends HeapObject implements M.Function {
   // owner is a Library, Class, or ServiceFunction.
-  @observable ServiceObject dartOwner;
+  @observable M.ObjectRef dartOwner;
   @observable Library library;
   @observable bool isStatic;
   @observable bool isConst;
@@ -2657,7 +2794,7 @@
   @observable bool hasIntrinsic;
   @observable bool isRecognized;
   @observable bool isNative;
-  @observable FunctionKind kind;
+  @observable M.FunctionKind kind;
   @observable int deoptimizations;
   @observable String qualifiedName;
   @observable int usageCounter;
@@ -2666,7 +2803,6 @@
   @observable Instance icDataArray;
   @observable Field field;
 
-  bool get canCache => true;
   bool get immutable => false;
 
   ServiceFunction._empty(ServiceObject owner) : super._empty(owner);
@@ -2679,8 +2815,8 @@
     vmName = (map.containsKey('_vmName') ? map['_vmName'] : name);
 
     dartOwner = map['owner'];
-    kind = FunctionKind.fromJSON(map['_kind']);
-    isDart = kind.isDart();
+    kind = stringToFunctionKind(map['_kind']);
+    isDart = M.isDartFunction(kind);
 
     if (dartOwner is ServiceFunction) {
       ServiceFunction ownerFunction = dartOwner;
@@ -2728,8 +2864,45 @@
   }
 }
 
+M.SentinelKind stringToSentinelKind(String s) {
+  switch (s) {
+    case 'Collected':
+      return M.SentinelKind.collected;
+    case 'Expired':
+      return M.SentinelKind.expired;
+    case 'NotInitialized':
+      return M.SentinelKind.notInitialized;
+    case 'BeingInitialized':
+      return M.SentinelKind.initializing;
+    case 'OptimizedOut':
+      return M.SentinelKind.optimizedOut;
+    case 'Free':
+      return M.SentinelKind.free;
+  }
+  Logger.root.severe("Unrecognized SentinelKind: '$s'");
+  throw new FallThroughError();
+}
 
-class Field extends HeapObject {
+class Sentinel extends ServiceObject implements M.Sentinel {
+
+  M.SentinelKind kind;
+  String valueAsString;
+
+  Sentinel._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+  void _update(ObservableMap map, bool mapIsRef) {
+    // Extract full properties.
+    _upgradeCollection(map, isolate);
+
+    kind = stringToSentinelKind(map['kind']);
+    valueAsString = map['valueAsString'];
+    _loaded = true;
+  }
+
+  String toString() => 'Sentinel($kind)';
+}
+
+class Field extends HeapObject implements M.FieldRef {
   // Library or Class.
   @observable ServiceObject dartOwner;
   @observable Library library;
@@ -2918,7 +3091,7 @@
   LocalVarLocation(this.line, this.column, this.endColumn);
 }
 
-class Script extends HeapObject {
+class Script extends HeapObject implements M.Script {
   final lines = new ObservableList<ScriptLine>();
   @observable String uri;
   @observable String kind;
@@ -2929,6 +3102,8 @@
   @observable int columnOffset;
   @observable Library library;
 
+  String source;
+
   bool get immutable => true;
 
   String _shortUri;
@@ -3030,6 +3205,7 @@
     lineOffset = map['lineOffset'];
     columnOffset = map['columnOffset'];
     _parseTokenPosTable(map['tokenPosTable']);
+    source = map['source'];
     _processSource(map['source']);
     library = map['library'];
   }
@@ -3281,10 +3457,9 @@
   }
 }
 
-class PcDescriptors extends ServiceObject {
+class PcDescriptors extends ServiceObject implements M.PcDescriptorsRef {
   @observable Class clazz;
   @observable int size;
-  bool get canCache => false;
   bool get immutable => true;
   @reflectable final List<PcDescriptor> descriptors =
       new ObservableList<PcDescriptor>();
@@ -3312,7 +3487,9 @@
   }
 }
 
-class LocalVarDescriptor extends Observable {
+class LocalVarDescriptor extends Observable
+                         implements M.LocalVarDescriptorsRef {
+  @reflectable final String id;
   @reflectable final String name;
   @reflectable final int index;
   @reflectable final int beginPos;
@@ -3320,14 +3497,13 @@
   @reflectable final int scopeId;
   @reflectable final String kind;
 
-  LocalVarDescriptor(this.name, this.index, this.beginPos, this.endPos,
+  LocalVarDescriptor(this.id, this.name, this.index, this.beginPos, this.endPos,
                      this.scopeId, this.kind);
 }
 
 class LocalVarDescriptors extends ServiceObject {
   @observable Class clazz;
   @observable int size;
-  bool get canCache => false;
   bool get immutable => true;
   @reflectable final List<LocalVarDescriptor> descriptors =
         new ObservableList<LocalVarDescriptor>();
@@ -3342,6 +3518,7 @@
     size = m['size'];
     descriptors.clear();
     for (var descriptor in m['members']) {
+      var id = descriptor['name'];
       var name = descriptor['name'];
       var index = descriptor['index'];
       var beginPos = descriptor['beginPos'];
@@ -3349,13 +3526,13 @@
       var scopeId = descriptor['scopeId'];
       var kind = descriptor['kind'].trim();
       descriptors.add(
-          new LocalVarDescriptor(name, index, beginPos, endPos, scopeId, kind));
+          new LocalVarDescriptor(id, name, index, beginPos, endPos, scopeId,
+                                 kind));
     }
   }
 }
 
-class ObjectPool extends HeapObject {
-  bool get canCache => false;
+class ObjectPool extends HeapObject implements M.ObjectPoolRef {
   bool get immutable => false;
 
   @observable int length;
@@ -3375,13 +3552,12 @@
   }
 }
 
-class ICData extends HeapObject {
+class ICData extends HeapObject implements M.ICDataRef {
   @observable ServiceObject dartOwner;
   @observable String selector;
   @observable Instance argumentsDescriptor;
   @observable Instance entries;
 
-  bool get canCache => false;
   bool get immutable => false;
 
   ICData._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -3400,13 +3576,12 @@
   }
 }
 
-class MegamorphicCache extends HeapObject {
+class MegamorphicCache extends HeapObject implements M.MegamorphicCacheRef {
   @observable int mask;
   @observable Instance buckets;
   @observable String selector;
   @observable Instance argumentsDescriptor;
 
-  bool get canCache => false;
   bool get immutable => false;
 
   MegamorphicCache._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -3426,29 +3601,7 @@
   }
 }
 
-class Instructions extends HeapObject {
-  bool get canCache => false;
-  bool get immutable => true;
-
-  @observable Code code;
-  @observable ObjectPool objectPool;
-
-  Instructions._empty(ServiceObjectOwner owner) : super._empty(owner);
-
-  void _update(ObservableMap map, bool mapIsRef) {
-    _upgradeCollection(map, isolate);
-    super._update(map, mapIsRef);
-
-    code = map['_code'];
-    if (mapIsRef) {
-      return;
-    }
-    objectPool = map['_objectPool'];
-  }
-}
-
-class TokenStream extends HeapObject {
-  bool get canCache => false;
+class TokenStream extends HeapObject implements M.TokenStreamRef {
   bool get immutable => true;
 
   @observable String privateKey;
@@ -3530,32 +3683,20 @@
   }
 }
 
-class CodeKind {
-  final _value;
-  const CodeKind._internal(this._value);
-  String toString() => '$_value';
-  bool isSynthetic() => [Collected, Native, Tag].contains(this);
-  bool isDart() => !isSynthetic();
-  static CodeKind fromString(String s) {
-    if (s == 'Native') {
-      return Native;
-    } else if (s == 'Dart') {
-      return Dart;
-    } else if (s == 'Collected') {
-      return Collected;
-    } else if (s == 'Tag') {
-      return Tag;
-    } else if (s == 'Stub') {
-      return Stub;
-    }
-    Logger.root.severe("Unrecognized code kind: '$s'");
-    throw new FallThroughError();
+M.CodeKind stringToCodeKind(String s) {
+  if (s == 'Native') {
+    return M.CodeKind.native;
+  } else if (s == 'Dart') {
+    return M.CodeKind.dart;
+  } else if (s == 'Collected') {
+    return M.CodeKind.collected;
+  } else if (s == 'Tag') {
+    return M.CodeKind.tag;
+  } else if (s == 'Stub') {
+    return M.CodeKind.stub;
   }
-  static const Collected = const CodeKind._internal('Collected');
-  static const Dart = const CodeKind._internal('Dart');
-  static const Native = const CodeKind._internal('Native');
-  static const Stub = const CodeKind._internal('Stub');
-  static const Tag = const CodeKind._internal('Tag');
+  Logger.root.severe("Unrecognized code kind: '$s'");
+  throw new FallThroughError();
 }
 
 class CodeInlineInterval {
@@ -3566,8 +3707,8 @@
   CodeInlineInterval(this.start, this.end);
 }
 
-class Code extends HeapObject {
-  @observable CodeKind kind;
+class Code extends HeapObject implements M.Code {
+  @observable M.CodeKind kind;
   @observable ServiceObject objectPool;
   @observable ServiceFunction function;
   @observable Script script;
@@ -3604,7 +3745,7 @@
       // Already done.
       return;
     }
-    if (kind != CodeKind.Dart){
+    if (kind != M.CodeKind.dart){
       return;
     }
     if (function == null) {
@@ -3643,7 +3784,7 @@
     name = m['name'];
     vmName = (m.containsKey('_vmName') ? m['_vmName'] : name);
     isOptimized = m['_optimized'];
-    kind = CodeKind.fromString(m['kind']);
+    kind = stringToCodeKind(m['kind']);
     hasIntrinsic = m['_intrinsic'];
     isNative = m['_native'];
     if (mapIsRef) {
@@ -3663,7 +3804,7 @@
       descriptors = descriptors['members'];
       _processDescriptors(descriptors);
     }
-    hasDisassembly = (instructions.length != 0) && (kind == CodeKind.Dart);
+    hasDisassembly = (instructions.length != 0) && (kind == M.CodeKind.dart);
     inlinedFunctions.clear();
     var inlinedFunctionsTable = m['_inlinedFunctions'];
     var inlinedIntervals = m['_inlinedIntervals'];
@@ -3781,8 +3922,8 @@
     return (address >= startAddress) && (address < endAddress);
   }
 
-  @reflectable bool get isDartCode => (kind == CodeKind.Dart) ||
-                                      (kind == CodeKind.Stub);
+  @reflectable bool get isDartCode => (kind == M.CodeKind.dart) ||
+                                      (kind == M.CodeKind.stub);
 
   String toString() => 'Code($kind, $name)';
 }
@@ -3831,8 +3972,6 @@
 class Socket extends ServiceObject {
   Socket._empty(ServiceObjectOwner owner) : super._empty(owner);
 
-  bool get canCache => true;
-
   ServiceObject socketOwner;
 
   @reflectable bool get isPipe => (kind == SocketKind.Pipe);
@@ -3900,7 +4039,6 @@
   ServiceMetric._empty(ServiceObjectOwner owner) : super._empty(owner) {
   }
 
-  bool get canCache => true;
   bool get immutable => false;
 
   @observable bool recording = false;
@@ -3987,7 +4125,7 @@
   }
 }
 
-class Frame extends ServiceObject {
+class Frame extends ServiceObject implements M.Frame {
   @observable int index;
   @observable ServiceFunction function;
   @observable SourceLocation location;
diff --git a/runtime/observatory/lib/utils.dart b/runtime/observatory/lib/utils.dart
index cfc447c..b8b5bb3 100644
--- a/runtime/observatory/lib/utils.dart
+++ b/runtime/observatory/lib/utils.dart
@@ -146,6 +146,16 @@
     return x.toStringAsFixed(2);
   }
 
+  static String formatMillis(double x) {
+    return x.toStringAsFixed(2);
+  }
+
+  static String formatDurationInSeconds(Duration x) =>
+    formatSeconds(x.inMicroseconds / Duration.MICROSECONDS_PER_SECOND);
+
+  static String formatDurationInMilliseconds(Duration x) =>
+    formatMillis(x.inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND);
+
   static bool runningInJavaScript() => identical(1.0, 1);
 }
 
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index c2084e1..19ba5cb 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -5,23 +5,28 @@
 # This file contains all dart, css, and html sources for Observatory.
 {
   'sources': [
+    'lib/allocation_profile.dart',
     'lib/app.dart',
     'lib/cli.dart',
     'lib/cpu_profile.dart',
     'lib/debugger.dart',
     'lib/elements.dart',
     'lib/elements.html',
+    'lib/models.dart',
     'lib/object_graph.dart',
+    'lib/repositories.dart',
     'lib/service.dart',
     'lib/service_common.dart',
     'lib/service_html.dart',
     'lib/service_io.dart',
+    'lib/src/allocation_profile/allocation_profile.dart',
     'lib/src/app/analytics.dart',
     'lib/src/app/application.dart',
+    'lib/src/app/event.dart',
     'lib/src/app/location_manager.dart',
+    'lib/src/app/notification.dart',
     'lib/src/app/page.dart',
     'lib/src/app/settings.dart',
-    'lib/src/app/target_manager.dart',
     'lib/src/app/view_model.dart',
     'lib/src/cli/command.dart',
     'lib/src/cpu_profile/cpu_profile.dart',
@@ -29,29 +34,35 @@
     'lib/src/debugger/debugger_location.dart',
     'lib/src/elements/action_link.dart',
     'lib/src/elements/action_link.html',
+    'lib/src/elements/allocation_profile.dart',
     'lib/src/elements/class_ref.dart',
-    'lib/src/elements/class_ref.html',
+    'lib/src/elements/class_ref_wrapper.dart',
+    'lib/src/elements/class_ref_as_value.dart',
+    'lib/src/elements/class_ref_as_value.html',
     'lib/src/elements/class_tree.dart',
-    'lib/src/elements/class_tree.html',
     'lib/src/elements/class_view.dart',
     'lib/src/elements/class_view.html',
     'lib/src/elements/code_ref.dart',
-    'lib/src/elements/code_ref.html',
+    'lib/src/elements/code_ref_wrapper.dart',
     'lib/src/elements/code_view.dart',
     'lib/src/elements/code_view.html',
     'lib/src/elements/context_ref.dart',
-    'lib/src/elements/context_ref.html',
+    'lib/src/elements/context_ref_wrapper.dart',
     'lib/src/elements/context_view.dart',
     'lib/src/elements/context_view.html',
+    'lib/src/elements/containers/virtual_collection.dart',
+    'lib/src/elements/containers/virtual_tree.dart',
+    'lib/src/elements/cpu_profile_table.dart',
+    'lib/src/elements/cpu_profile_table.html',
     'lib/src/elements/cpu_profile.dart',
-    'lib/src/elements/cpu_profile.html',
+    'lib/src/elements/cpu_profile/virtual_tree.dart',
     'lib/src/elements/css/shared.css',
     'lib/src/elements/curly_block.dart',
-    'lib/src/elements/curly_block.html',
+    'lib/src/elements/curly_block_wrapper.dart',
     'lib/src/elements/debugger.dart',
     'lib/src/elements/debugger.html',
     'lib/src/elements/error_ref.dart',
-    'lib/src/elements/error_ref.html',
+    'lib/src/elements/error_ref_wrapper.dart',
     'lib/src/elements/error_view.dart',
     'lib/src/elements/error_view.html',
     'lib/src/elements/eval_box.dart',
@@ -59,23 +70,25 @@
     'lib/src/elements/eval_link.dart',
     'lib/src/elements/eval_link.html',
     'lib/src/elements/field_ref.dart',
-    'lib/src/elements/field_ref.html',
+    'lib/src/elements/field_ref_wrapper.dart',
     'lib/src/elements/field_view.dart',
     'lib/src/elements/field_view.html',
     'lib/src/elements/flag_list.dart',
-    'lib/src/elements/flag_list.html',
     'lib/src/elements/function_ref.dart',
-    'lib/src/elements/function_ref.html',
+    'lib/src/elements/function_ref_wrapper.dart',
     'lib/src/elements/function_view.dart',
     'lib/src/elements/function_view.html',
     'lib/src/elements/general_error.dart',
-    'lib/src/elements/general_error.html',
     'lib/src/elements/heap_map.dart',
     'lib/src/elements/heap_map.html',
-    'lib/src/elements/heap_profile.dart',
-    'lib/src/elements/heap_profile.html',
     'lib/src/elements/heap_snapshot.dart',
     'lib/src/elements/heap_snapshot.html',
+    'lib/src/elements/helpers/any_ref.dart',
+    'lib/src/elements/helpers/rendering_queue.dart',
+    'lib/src/elements/helpers/rendering_scheduler.dart',
+    'lib/src/elements/helpers/tag.dart',
+    'lib/src/elements/helpers/uris.dart',
+    'lib/src/elements/icdata_ref.dart',
     'lib/src/elements/icdata_view.dart',
     'lib/src/elements/icdata_view.html',
     'lib/src/elements/img/chromium_icon.png',
@@ -84,17 +97,15 @@
     'lib/src/elements/inbound_reference.dart',
     'lib/src/elements/inbound_reference.html',
     'lib/src/elements/instance_ref.dart',
-    'lib/src/elements/instance_ref.html',
+    'lib/src/elements/instance_ref_wrapper.dart',
     'lib/src/elements/instance_view.dart',
     'lib/src/elements/instance_view.html',
-    'lib/src/elements/instructions_view.dart',
-    'lib/src/elements/instructions_view.html',
-    'lib/src/elements/io_view.dart',
-    'lib/src/elements/io_view.html',
     'lib/src/elements/isolate_reconnect.dart',
-    'lib/src/elements/isolate_reconnect.html',
     'lib/src/elements/isolate_ref.dart',
-    'lib/src/elements/isolate_ref.html',
+    'lib/src/elements/isolate_ref_wrapper.dart',
+    'lib/src/elements/isolate/counter_chart.dart',
+    'lib/src/elements/isolate/shared_summary_wrapper.dart',
+    'lib/src/elements/isolate/shared_summary.dart',
     'lib/src/elements/isolate_summary.dart',
     'lib/src/elements/isolate_summary.html',
     'lib/src/elements/isolate_view.dart',
@@ -102,55 +113,133 @@
     'lib/src/elements/json_view.dart',
     'lib/src/elements/json_view.html',
     'lib/src/elements/library_ref.dart',
-    'lib/src/elements/library_ref.html',
+    'lib/src/elements/library_ref_wrapper.dart',
+    'lib/src/elements/library_ref_as_value.dart',
+    'lib/src/elements/library_ref_as_value.html',
     'lib/src/elements/library_view.dart',
     'lib/src/elements/library_view.html',
-    'lib/src/elements/objectstore_view.dart',
-    'lib/src/elements/objectstore_view.html',
+    'lib/src/elements/local_var_descriptors_ref.dart',
     'lib/src/elements/logging.dart',
     'lib/src/elements/logging.html',
+    'lib/src/elements/megamorphiccache_ref.dart',
     'lib/src/elements/megamorphiccache_view.dart',
     'lib/src/elements/megamorphiccache_view.html',
     'lib/src/elements/metrics.dart',
     'lib/src/elements/metrics.html',
-    'lib/src/elements/nav_bar.dart',
-    'lib/src/elements/nav_bar.html',
+    'lib/src/elements/nav/bar.dart',
+    'lib/src/elements/nav/class_menu.dart',
+    'lib/src/elements/nav/class_menu_wrapper.dart',
+    'lib/src/elements/nav/isolate_menu.dart',
+    'lib/src/elements/nav/isolate_menu_wrapper.dart',
+    'lib/src/elements/nav/library_menu.dart',
+    'lib/src/elements/nav/library_menu_wrapper.dart',
+    'lib/src/elements/nav/menu_item.dart',
+    'lib/src/elements/nav/menu_item_wrapper.dart',
+    'lib/src/elements/nav/menu.dart',
+    'lib/src/elements/nav/menu_wrapper.dart',
+    'lib/src/elements/nav/notify_event.dart',
+    'lib/src/elements/nav/notify_exception.dart',
+    'lib/src/elements/nav/notify.dart',
+    'lib/src/elements/nav/notify_wrapper.dart',
+    'lib/src/elements/nav/refresh.dart',
+    'lib/src/elements/nav/refresh_wrapper.dart',
+    'lib/src/elements/nav/top_menu.dart',
+    'lib/src/elements/nav/top_menu_wrapper.dart',
+    'lib/src/elements/nav/vm_menu.dart',
+    'lib/src/elements/nav/vm_menu_wrapper.dart',
     'lib/src/elements/object_common.dart',
     'lib/src/elements/object_common.html',
     'lib/src/elements/object_view.dart',
     'lib/src/elements/object_view.html',
+    'lib/src/elements/objectpool_ref.dart',
     'lib/src/elements/objectpool_view.dart',
     'lib/src/elements/objectpool_view.html',
+    'lib/src/elements/objectstore_view.dart',
+    'lib/src/elements/objectstore_view.html',
     'lib/src/elements/observatory_application.dart',
-    'lib/src/elements/observatory_application.html',
     'lib/src/elements/observatory_element.dart',
-    'lib/src/elements/observatory_element.html',
+    'lib/src/elements/pc_descriptors_ref.dart',
     'lib/src/elements/persistent_handles.dart',
     'lib/src/elements/persistent_handles.html',
     'lib/src/elements/ports.dart',
     'lib/src/elements/ports.html',
+    'lib/src/elements/sample_buffer_control.dart',
     'lib/src/elements/script_inset.dart',
     'lib/src/elements/script_inset.html',
+    'lib/src/elements/script_ref_wrapper.dart',
     'lib/src/elements/script_ref.dart',
-    'lib/src/elements/script_ref.html',
     'lib/src/elements/script_view.dart',
     'lib/src/elements/script_view.html',
     'lib/src/elements/service_ref.dart',
     'lib/src/elements/service_ref.html',
     'lib/src/elements/service_view.dart',
     'lib/src/elements/service_view.html',
-    'lib/src/elements/sliding_checkbox.dart',
-    'lib/src/elements/sliding_checkbox.html',
+    'lib/src/elements/source_link_wrapper.dart',
+    'lib/src/elements/source_link.dart',
+    'lib/src/elements/shims/binding.dart',
+    'lib/src/elements/stack_trace_tree_config.dart',
     'lib/src/elements/timeline_page.dart',
     'lib/src/elements/timeline_page.html',
+    'lib/src/elements/token_stream_ref.dart',
+    'lib/src/elements/unknown_ref.dart',
     'lib/src/elements/view_footer.dart',
-    'lib/src/elements/view_footer.html',
+    'lib/src/elements/vm_connect_target.dart',
     'lib/src/elements/vm_connect.dart',
-    'lib/src/elements/vm_connect.html',
-    'lib/src/elements/vm_ref.dart',
-    'lib/src/elements/vm_ref.html',
     'lib/src/elements/vm_view.dart',
     'lib/src/elements/vm_view.html',
+    'lib/src/models/exceptions.dart',
+    'lib/src/models/objects/allocation_profile.dart',
+    'lib/src/models/objects/bound_field.dart',
+    'lib/src/models/objects/breakpoint.dart',
+    'lib/src/models/objects/class.dart',
+    'lib/src/models/objects/code.dart',
+    'lib/src/models/objects/context.dart',
+    'lib/src/models/objects/error.dart',
+    'lib/src/models/objects/event.dart',
+    'lib/src/models/objects/extension_data.dart',
+    'lib/src/models/objects/field.dart',
+    'lib/src/models/objects/flag.dart',
+    'lib/src/models/objects/frame.dart',
+    'lib/src/models/objects/function.dart',
+    'lib/src/models/objects/heap_space.dart',
+    'lib/src/models/objects/icdata.dart',
+    'lib/src/models/objects/instance.dart',
+    'lib/src/models/objects/isolate.dart',
+    'lib/src/models/objects/library.dart',
+    'lib/src/models/objects/local_var_descriptors.dart',
+    'lib/src/models/objects/map_association.dart',
+    'lib/src/models/objects/megamorphiccache.dart',
+    'lib/src/models/objects/notification.dart',
+    'lib/src/models/objects/object.dart',
+    'lib/src/models/objects/objectpool.dart',
+    'lib/src/models/objects/pc_descriptors.dart',
+    'lib/src/models/objects/sample_profile.dart',
+    'lib/src/models/objects/script.dart',
+    'lib/src/models/objects/sentinel.dart',
+    'lib/src/models/objects/source_location.dart',
+    'lib/src/models/objects/unknown.dart',
+    'lib/src/models/objects/target.dart',
+    'lib/src/models/objects/timeline_event.dart',
+    'lib/src/models/objects/token_stream.dart',
+    'lib/src/models/objects/vm.dart',
+    'lib/src/models/repositories/allocation_profile.dart',
+    'lib/src/models/repositories/class.dart',
+    'lib/src/models/repositories/event.dart',
+    'lib/src/models/repositories/flag.dart',
+    'lib/src/models/repositories/instance.dart',
+    'lib/src/models/repositories/notification.dart',
+    'lib/src/models/repositories/sample_profile.dart',
+    'lib/src/models/repositories/script.dart',
+    'lib/src/models/repositories/target.dart',
+    'lib/src/repositories/class.dart',
+    'lib/src/repositories/event.dart',
+    'lib/src/repositories/flag.dart',
+    'lib/src/repositories/instance.dart',
+    'lib/src/repositories/notification.dart',
+    'lib/src/repositories/sample_profile.dart',
+    'lib/src/repositories/script.dart',
+    'lib/src/repositories/settings.dart',
+    'lib/src/repositories/target.dart',
     'lib/src/service/object.dart',
     'lib/tracer.dart',
     'lib/utils.dart',
diff --git a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart
new file mode 100644
index 0000000..b7d8e2f
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/allocation_profile.dart';
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/containers/virtual_collection.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import '../mocks.dart';
+
+main() {
+  AllocationProfileElement.tag.ensureRegistration();
+
+  final cTag = ClassRefElement.tag.name;
+  final rTag = NavRefreshElement.tag.name;
+  final vTag = VirtualCollectionElement.tag.name;
+
+  const vm = const VMMock();
+  const isolate = const IsolateRefMock();
+  final events = new EventRepositoryMock();
+  final notif = new NotificationRepositoryMock();
+  test('instantiation', () {
+    final repo = new AllocationProfileRepositoryMock();
+    final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
+    expect(e, isNotNull, reason: 'element correctly created');
+  });
+  test('elements created', () async {
+    final completer = new Completer<AllocationProfileMock>();
+    final repo = new AllocationProfileRepositoryMock(
+      getter: expectAsync((M.IsolateRef i, bool gc, bool reset) {
+        expect(i, equals(isolate));
+        expect(gc, isFalse);
+        expect(reset, isFalse);
+        return completer.future;
+      }, count: 1));
+    final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.querySelectorAll(vTag).length, isZero);
+    completer.complete(const AllocationProfileMock());
+    await e.onRendered.first;
+    expect(e.querySelectorAll(vTag).length, equals(1));
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+  group('reacts', () {
+    test('to refresh', () async {
+      final completer = new Completer<AllocationProfileMock>();
+      int step = 0;
+      final repo = new AllocationProfileRepositoryMock(
+        getter: expectAsync((M.IsolateRef i, bool gc, bool reset) {
+          expect(i, equals(isolate));
+          switch (step) {
+              case 0:
+                expect(gc, isFalse);
+                expect(reset, isFalse);
+                break;
+              case 1:
+                expect(gc, isFalse);
+                expect(reset, isTrue);
+                break;
+              case 2:
+                expect(gc, isTrue);
+                expect(reset, isFalse);
+                break;
+              case 3:
+                expect(gc, isFalse);
+                expect(reset, isFalse);
+                break;
+          }
+          step++;
+          return completer.future;
+        }, count: 4));
+      final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
+      document.body.append(e);
+      await e.onRendered.first;
+      completer.complete(const AllocationProfileMock());
+      await e.onRendered.first;
+      e.querySelectorAll(rTag).sublist(1, 4)
+          .forEach((NavRefreshElement e) => e.refresh());
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('to gc', () async {
+      final events = new EventRepositoryMock();
+      final completer = new Completer<AllocationProfileMock>();
+      int count = 0;
+      final repo = new AllocationProfileRepositoryMock(
+        getter: expectAsync((M.IsolateRef i, bool gc, bool reset) {
+          expect(i, equals(isolate));
+          expect(gc, isFalse);
+          expect(reset, isFalse);
+          count++;
+          return completer.future;
+        }, count: 2));
+      final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
+      document.body.append(e);
+      await e.onRendered.first;
+      completer.complete(const AllocationProfileMock());
+      await e.onRendered.first;
+      e.querySelector('input[type=\'checkbox\']').click();
+      expect(events.onGCEventHasListener, isTrue);
+      events.add(new GCEventMock(isolate: isolate));
+      await e.onRendered.first;
+      expect(count, equals(2));
+      // shouldn't trigger
+      events.add(new GCEventMock(isolate: new IsolateRefMock(id: 'another')));
+      await (() async {} ());
+      e.querySelector('input[type=\'checkbox\']').click();
+      // shouldn't trigger
+      events.add(new GCEventMock(isolate: isolate));
+      await (() async {} ());
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('to sort change', () async {
+      const clazz1 = const ClassRefMock(name: 'class1');
+      const clazz2 = const ClassRefMock(name: 'class2');
+      const clazz3 = const ClassRefMock(name: 'class3');
+      const profile = const AllocationProfileMock(members: const [
+        const ClassHeapStatsMock(clazz: clazz2, newSpace: const AllocationsMock(
+          accumulated: const AllocationCountMock(bytes: 10)
+        )),
+        const ClassHeapStatsMock(clazz: clazz3),
+        const ClassHeapStatsMock(clazz: clazz1, newSpace: const AllocationsMock(
+          accumulated: const AllocationCountMock(bytes: 5)
+        ))
+      ]);
+      final completer = new Completer<AllocationProfileMock>();
+      final repo = new AllocationProfileRepositoryMock(
+        getter: expectAsync((M.IsolateRef i, bool gc, bool reset) {
+          expect(i, equals(isolate));
+          expect(gc, isFalse);
+          expect(reset, isFalse);
+          return completer.future;
+        }, count: 1));
+      final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
+      document.body.append(e);
+      await e.onRendered.first;
+      completer.complete(profile);
+      await e.onRendered.first;
+      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz1));
+      e.querySelector('button.bytes').click();
+      await e.onRendered.first;
+      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz2));
+      e.querySelector('button.bytes').click();
+      await e.onRendered.first;
+      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz3));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.html b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/class_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/class_ref/element_test.dart
new file mode 100644
index 0000000..41aeb10
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/class_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/class_ref.dart';
+import '../mocks.dart';
+
+main() {
+  ClassRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const cls = const ClassRefMock();
+  test('instantiation', () {
+    final e = new ClassRefElement(isolate, cls);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.cls, equals(cls));
+  });
+  test('elements created after attachment', () async {
+    final e = new ClassRefElement(isolate, cls);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/class_ref/element_test.html b/runtime/observatory/tests/observatory_ui/class_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/class_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart b/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
new file mode 100644
index 0000000..5d20331
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/class_tree/element_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.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/class_tree.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import '../mocks.dart';
+
+main() {
+  ClassTreeElement.tag.ensureRegistration();
+
+  final nTag = NavNotifyElement.tag.name;
+  const vm = const VMMock();
+  const isolate = const IsolateRefMock();
+  final events = new EventRepositoryMock();
+  final notifications = new NotificationRepositoryMock();
+
+  group('instantiation', () {
+    test('default', () {
+      final e = new ClassTreeElement(vm, isolate, events, notifications,
+          new ClassRepositoryMock());
+      expect(e, isNotNull, reason: 'element correctly created');
+    });
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      const child2_id = 'c2-id';
+      const child1_1_id = 'c1_1-id';
+      const child1_id = 'c1-id';
+      const child2 = const ClassMock(id: child2_id);
+      const child1_1 = const ClassMock(id: child1_1_id);
+      const child1 = const ClassMock(id: child1_id,
+                                     subclasses: const [child1_1]);
+      const object = const ClassMock(id: 'o-id',
+                                     subclasses: const [child1, child2]);
+      const ids = const [child1_id, child1_1_id, child2_id];
+      bool rendered = false;
+      final e = new ClassTreeElement(vm, isolate, events, notifications,
+          new ClassRepositoryMock(
+              object: expectAsync(() async {
+                expect(rendered, isFalse);
+                return object;
+              }, count: 1),
+              getter: expectAsync((id) async {
+                expect(ids.contains(id), isTrue);
+                switch (id) {
+                  case child1_id: return child1;
+                  case child1_1_id: return child1_1;
+                  case child2_id: return child2;
+                  default: return null;
+                }
+              }, count: 3)));
+      document.body.append(e);
+      await e.onRendered.first;
+      rendered = true;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(nTag).length, equals(1));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/class_tree/element_test.html b/runtime/observatory/tests/observatory_ui/class_tree/element_test.html
new file mode 100644
index 0000000..00d59bc
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/class_tree/element_test.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+     class-tree virtual-tree .class-tree-item {
+       line-height: 25px;
+       height: 25px;
+       padding-left: 10%;
+       padding-right: 10%;
+     }
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/code_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/code_ref/element_test.dart
new file mode 100644
index 0000000..7a65c84
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/code_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/code_ref.dart';
+import '../mocks.dart';
+
+main() {
+  CodeRefElement.tag.ensureRegistration();
+
+  final isolate = new IsolateRefMock(id: 'i-id', name: 'i-name');
+  final code = new CodeRefMock(id: 'c-id', name: 'c-name');
+  test('instantiation', () {
+    final e = new CodeRefElement(isolate, code);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.code, equals(code));
+  });
+  test('elements created after attachment', () async {
+    final e = new CodeRefElement(isolate, code);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/code_ref/element_test.html b/runtime/observatory/tests/observatory_ui/code_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/code_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/context_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/context_ref/element_test.dart
new file mode 100644
index 0000000..3ab0a66
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/context_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/context_ref.dart';
+import '../mocks.dart';
+
+main() {
+  ContextRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const context = const ContextRefMock();
+  test('instantiation', () {
+    final e = new ContextRefElement(isolate, context);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.context, equals(context));
+  });
+  test('elements created after attachment', () async {
+    final e = new ContextRefElement(isolate, context);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/context_ref/element_test.html b/runtime/observatory/tests/observatory_ui/context_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/context_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.dart b/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.dart
new file mode 100644
index 0000000..249d465
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/cpu_profile.dart';
+import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
+import 'package:observatory/src/elements/stack_trace_tree_config.dart';
+import 'package:observatory/src/elements/sample_buffer_control.dart';
+import '../mocks.dart';
+
+main() {
+  CpuProfileElement.tag.ensureRegistration();
+
+  final sTag = SampleBufferControlElement.tag.name;
+  final cTag = StackTraceTreeConfigElement.tag.name;
+  final tTag = CpuProfileVirtualTreeElement.tag.name;
+
+  const vm = const VMMock();
+  const isolate = const IsolateRefMock();
+  final events = new EventRepositoryMock();
+  final notifs = new NotificationRepositoryMock();
+  test('instantiation', () {
+    final profiles = new IsolateSampleProfileRepositoryMock();
+    final e = new CpuProfileElement(vm, isolate, events, notifs, profiles);
+    expect(e, isNotNull, reason: 'element correctly created');
+  });
+  test('elements created', () async {
+    final controller
+        = new StreamController<M.SampleProfileLoadingProgressEvent>.broadcast();
+    final profiles = new IsolateSampleProfileRepositoryMock(
+      getter: (M.IsolateRef i, M.SampleProfileTag t, bool clear,
+          bool forceFetch) {
+        expect(i, equals(isolate));
+        expect(t, isNotNull);
+        expect(clear, isFalse);
+        expect(forceFetch, isFalse);
+        return controller.stream;
+      }
+    );
+    final e = new CpuProfileElement(vm, isolate, events, notifs, profiles);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.querySelectorAll(sTag).length, isZero);
+    expect(e.querySelectorAll(cTag).length, isZero);
+    expect(e.querySelectorAll(tTag).length, isZero);
+    controller.add(new SampleProfileLoadingProgressEventMock(
+      progress: new SampleProfileLoadingProgressMock(
+        status: M.SampleProfileLoadingStatus.fetching
+      )
+    ));
+    await e.onRendered.first;
+    expect(e.querySelectorAll(sTag).length, equals(1));
+    expect(e.querySelectorAll(cTag).length, isZero);
+    expect(e.querySelectorAll(tTag).length, isZero);
+    controller.add(new SampleProfileLoadingProgressEventMock(
+      progress: new SampleProfileLoadingProgressMock(
+        status: M.SampleProfileLoadingStatus.loading
+      )
+    ));
+    controller.add(new SampleProfileLoadingProgressEventMock(
+      progress: new SampleProfileLoadingProgressMock(
+        status: M.SampleProfileLoadingStatus.loaded,
+        profile: new SampleProfileMock()
+      )
+    ));
+    controller.close();
+    await e.onRendered.first;
+    expect(e.querySelectorAll(sTag).length, equals(1));
+    expect(e.querySelectorAll(cTag).length, equals(1));
+    expect(e.querySelectorAll(tTag).length, equals(1));
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.html b/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.dart b/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.dart
new file mode 100644
index 0000000..cb93e56
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
+import '../../mocks.dart';
+
+main() {
+  CpuProfileVirtualTreeElement.tag.ensureRegistration();
+  const isolate = const IsolateRefMock();
+  group('instantiation', () {
+    final profile = new SampleProfileMock();
+    test('default', () {
+      final e = new CpuProfileVirtualTreeElement(isolate, profile);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(isolate));
+      expect(e.profile, equals(profile));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('mode', () {
+      final e = new CpuProfileVirtualTreeElement(isolate, profile,
+          mode: ProfileTreeMode.code);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(isolate));
+      expect(e.profile, equals(profile));
+      expect(e.mode, equals(ProfileTreeMode.code));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('direction', () {
+      final e = new CpuProfileVirtualTreeElement(isolate, profile,
+          direction: M.ProfileTreeDirection.inclusive);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(isolate));
+      expect(e.profile, equals(profile));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
+    });
+  });
+  test('elements created after attachment', () async {
+    final profile = new SampleProfileMock();
+    final e = new CpuProfileVirtualTreeElement(isolate, profile);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.html b/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/curly_block/element_test.dart b/runtime/observatory/tests/observatory_ui/curly_block/element_test.dart
new file mode 100644
index 0000000..139e235
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/curly_block/element_test.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+
+main() {
+  CurlyBlockElement.tag.ensureRegistration();
+
+  group('instantiation', () {
+    test('default', () {
+      final e = new CurlyBlockElement();
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isFalse);
+      expect(e.disabled, isFalse);
+    });
+    test('not expanded', () {
+      final e = new CurlyBlockElement(expanded: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isFalse);
+      expect(e.disabled, isFalse);
+    });
+    test('not expanded / not disabled', () {
+      final e = new CurlyBlockElement(expanded: false,
+                                                        disabled: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isFalse);
+      expect(e.disabled, isFalse);
+    });
+    test('not expanded / disabled', () {
+      final e = new CurlyBlockElement(expanded: false,
+                                                        disabled: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isFalse);
+      expect(e.disabled, isTrue);
+    });
+    test('expanded', () {
+      final e = new CurlyBlockElement(expanded: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isTrue);
+      expect(e.disabled, isFalse);
+    });
+    test('expanded / not disabled', () {
+      final e = new CurlyBlockElement(expanded: true, disabled: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isTrue);
+      expect(e.disabled, isFalse);
+    });
+    test('expanded / disabled', () {
+      final e = new CurlyBlockElement(expanded: true, disabled: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isTrue);
+      expect(e.disabled, isTrue);
+    });
+    test('not disabled', () {
+      final e = new CurlyBlockElement(disabled: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isFalse);
+      expect(e.disabled, isFalse);
+    });
+    test('disabled', () {
+      final e = new CurlyBlockElement(disabled: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.expanded, isFalse);
+      expect(e.disabled, isTrue);
+    });
+  });
+  test('elements created', () async {
+    final e = new CurlyBlockElement();
+    expect(e.shadowRoot, isNotNull, reason: 'shadowRoot is created');
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isNonZero,
+      reason: 'shadowRoot has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isZero, reason: 'shadowRoot is empty');
+  });
+  group('content', () {
+    CurlyBlockElement e;
+    setUp(() async {
+      e = new CurlyBlockElement();
+      document.body.append(e);
+      await e.onRendered.first;
+    });
+    tearDown(() {
+      e.remove();
+    });
+    test('toggles visibility', () async {
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.toggle();
+      await e.onRendered.first;
+      expect(e.shadowRoot.querySelector('content'), isNotNull);
+      e.toggle();
+      await e.onRendered.first;
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.remove();
+    });
+    test('toggles visibility (manually)', () async {
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.expanded = true;
+      await e.onRendered.first;
+      expect(e.shadowRoot.querySelector('content'), isNotNull);
+      e.expanded = false;
+      await e.onRendered.first;
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.remove();
+    });
+    test('does not toggle if disabled', () async {
+      e.disabled = true;
+      await e.onRendered.first;
+      expect(e.expanded, isFalse);
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.toggle();
+      await e.onRendered.first;
+      expect(e.expanded, isFalse);
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.disabled = false;
+      e.toggle();
+      await e.onRendered.first;
+      expect(e.expanded, isTrue);
+      expect(e.shadowRoot.querySelector('content'), isNotNull);
+      e.disabled = true;
+      e.toggle();
+      await e.onRendered.first;
+      expect(e.expanded, isTrue);
+      expect(e.shadowRoot.querySelector('content'), isNotNull);
+      e.remove();
+    });
+    test('toggles visibility (manually) if disabled', () async {
+      e.disabled = true;
+      await e.onRendered.first;
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.expanded = true;
+      await e.onRendered.first;
+      expect(e.shadowRoot.querySelector('content'), isNotNull);
+      e.expanded = false;
+      await e.onRendered.first;
+      expect(e.shadowRoot.querySelector('content'), isNull);
+      e.remove();
+    });
+  });
+  group('event', () {
+    CurlyBlockElement e;
+    setUp(() async {
+      e = new CurlyBlockElement();
+      document.body.append(e);
+      await e.onRendered.first;
+    });
+    tearDown(() async {
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('fires on toggle', () async {
+      e.onToggle.listen(expectAsync((CurlyBlockToggleEvent event){
+        expect(event, isNotNull);
+        expect(event.control, equals(e));
+      }, count: 1));
+      e.toggle();
+      await e.onRendered.first;
+    });
+    test('fires on manual toggle', () async {
+      e.onToggle.listen(expectAsync((CurlyBlockToggleEvent event){
+        expect(event, isNotNull);
+        expect(event.control, equals(e));
+      }, count: 1));
+      e.expanded = !e.expanded;
+      await e.onRendered.first;
+    });
+    test('does not fire if setting same expanded value', () async {
+      e.onToggle.listen(expectAsync((_){}, count: 0));
+      e.expanded = e.expanded;
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/curly_block/element_test.html b/runtime/observatory/tests/observatory_ui/curly_block/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/curly_block/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/error_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/error_ref/element_test.dart
new file mode 100644
index 0000000..878f90a
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/error_ref/element_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/error_ref.dart';
+import '../mocks.dart';
+
+main() {
+  ErrorRefElement.tag.ensureRegistration();
+
+  final ref = new ErrorRefMock(id: 'id', message: 'fixed-error-m');
+  test('instantiation', () {
+    final ErrorRefElement e = new ErrorRefElement(ref);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.error, equals(ref));
+  });
+  test('elements created after attachment', () async {
+    final ErrorRefElement e = new ErrorRefElement(ref);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.innerHtml.contains(ref.message), isTrue,
+      reason: 'no message in the component');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero,
+      reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/error_ref/element_test.html b/runtime/observatory/tests/observatory_ui/error_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/error_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/field_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/field_ref/element_test.dart
new file mode 100644
index 0000000..f576f54
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/field_ref/element_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/field_ref.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import '../mocks.dart';
+
+main() {
+  FieldRefElement.tag.ensureRegistration();
+
+  final iTag = InstanceRefElement.tag.name;
+
+  const isolate = const IsolateRefMock();
+  const field = const FieldRefMock();
+  const declaredType = const InstanceMock(kind: M.InstanceKind.type,
+                                          name: 'CustomObject');
+  const field_non_dynamic = const FieldRefMock(declaredType: declaredType);
+  final repository = new InstanceRepositoryMock();
+  test('instantiation', () {
+    final e = new FieldRefElement(isolate, field, repository);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.field, equals(field));
+  });
+  group('elements', () {
+    test('created after attachment (dynamic)', () async {
+      final e = new FieldRefElement(isolate, field, repository);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(iTag).length, isZero);
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('created after attachment (non dynamic)', () async {
+      final e = new FieldRefElement(isolate, field_non_dynamic, repository);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(iTag).length, equals(1));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/field_ref/element_test.html b/runtime/observatory/tests/observatory_ui/field_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/field_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart b/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart
new file mode 100644
index 0000000..327daa1
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/flag_list.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import '../mocks.dart';
+
+main() {
+  FlagListElement.tag.ensureRegistration();
+
+  final nTag = NavNotifyElement.tag.name;
+  const vm = const VMMock();
+  final events = new EventRepositoryMock();
+  final notifications = new NotificationRepositoryMock();
+
+  group('instantiation', () {
+    test('default', () {
+      final e = new FlagListElement(vm, events,
+                                    new FlagsRepositoryMock(),
+                                    notifications);
+      expect(e, isNotNull, reason: 'element correctly created');
+    });
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      const modified = const [
+        const FlagMock(name: 'f1', comment: 'c1', modified: true),
+      ];
+      const unmodifed = const [
+        const FlagMock(name: 'f2', comment: 'c2', modified: false),
+        const FlagMock(name: 'f3', comment: 'c3', modified: false),
+      ];
+      final flags = []..addAll(modified)..addAll(unmodifed);
+      final repository = new FlagsRepositoryMock(list: flags);
+      final e = new FlagListElement(vm, events, repository, notifications);
+      document.body.append(e);
+      expect(repository.isListInvoked, isFalse);
+      await e.onRendered.first;
+      expect(repository.isListInvoked, isTrue);
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(nTag).length, equals(1));
+      expect(e.querySelectorAll('.flag').length, equals(flags.length));
+      expect(e.querySelectorAll('.flag.modified').length,
+          equals(modified.length));
+      expect(e.querySelectorAll('.flag.unmodified').length,
+          equals(unmodifed.length));
+      expect(e.querySelectorAll('.flag').length, equals(flags.length));
+      expect(e.querySelectorAll('.comment').length, equals(flags.length));
+      expect(e.querySelectorAll('.name').length, equals(flags.length));
+      expect(e.querySelectorAll('.value').length, equals(flags.length));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/flag_list/element_test.html b/runtime/observatory/tests/observatory_ui/flag_list/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/flag_list/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/function_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/function_ref/element_test.dart
new file mode 100644
index 0000000..4068493
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/function_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/function_ref.dart';
+import '../mocks.dart';
+
+main() {
+  FunctionRefElement.tag.ensureRegistration();
+
+  final isolate = new IsolateRefMock(id: 'i-id', name: 'i-name');
+  final function = new FunctionRefMock(id: 'f-id', name: 'f-name');
+  test('instantiation', () {
+    final e = new FunctionRefElement(isolate, function);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.function, equals(function));
+  });
+  test('elements created after attachment', () async {
+    final e = new FunctionRefElement(isolate, function);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/function_ref/element_test.html b/runtime/observatory/tests/observatory_ui/function_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/function_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/general_error/element_test.dart b/runtime/observatory/tests/observatory_ui/general_error/element_test.dart
new file mode 100644
index 0000000..71ba186
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/general_error/element_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.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/general_error.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import '../mocks.dart';
+
+main() {
+  GeneralErrorElement.tag.ensureRegistration();
+
+  final nTag = NavNotifyElement.tag.name;
+  final notifications = new NotificationRepositoryMock();
+  final String message = 'content-of-the-message';
+
+  group('instantiation', () {
+    test('default', () {
+      final GeneralErrorElement e = new GeneralErrorElement(notifications);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.message, isNotNull, reason: 'message should not be null');
+      expect(e.message, equals(''), reason: 'message should be empty');
+    });
+    test('message', () {
+      final GeneralErrorElement e = new GeneralErrorElement(notifications,
+          message: message);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.message, isNotNull, reason: 'message should not be null');
+      expect(e.message, equals(message), reason: 'message should be the same');
+    });
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      final GeneralErrorElement e = new GeneralErrorElement(notifications);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(nTag).length, equals(1));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to message change', () async {
+      final GeneralErrorElement e = new GeneralErrorElement(notifications);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(message), isFalse,
+          reason: 'should not contain');
+      e.message = message;
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(message), isTrue,
+          reason: 'should contain');
+      e.message = '';
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(message), isFalse,
+          reason: 'should not contain');
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/general_error/element_test.html b/runtime/observatory/tests/observatory_ui/general_error/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/general_error/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.dart
new file mode 100644
index 0000000..3895635
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import '../mocks.dart';
+
+main() {
+  InstanceRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const instance = const InstanceRefMock();
+  final repository = new InstanceRepositoryMock();
+  test('instantiation', () {
+    final e = new InstanceRefElement(isolate, instance, repository);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.instance, equals(instance));
+  });
+  test('elements created after attachment', () async {
+    final e = new InstanceRefElement(isolate, instance, repository);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.html b/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/instance_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/instance_ref/element_test.dart
new file mode 100644
index 0000000..e156fa7
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/instance_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/icdata_ref.dart';
+import '../mocks.dart';
+
+main() {
+  ICDataRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const icdata = const ICDataRefMock();
+  test('instantiation', () {
+    final e = new ICDataRefElement(isolate, icdata);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.icdata, equals(icdata));
+  });
+  test('elements created after attachment', () async {
+    final e = new ICDataRefElement(isolate, icdata);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/instance_ref/element_test.html b/runtime/observatory/tests/observatory_ui/instance_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/instance_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.dart
new file mode 100644
index 0000000..8aef7df
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/isolate/counter_chart.dart';
+
+main() {
+  IsolateCounterChartElement.tag.ensureRegistration();
+
+  test('instantiation', () {
+    final e = new IsolateCounterChartElement({});
+    expect(e, isNotNull, reason: 'element correctly created');
+  });
+  test('elements created', () async {
+    final e = new IsolateCounterChartElement({});
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.html b/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.dart
new file mode 100644
index 0000000..14aeeed
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/isolate/counter_chart.dart';
+import 'package:observatory/src/elements/isolate/shared_summary.dart';
+import '../../mocks.dart';
+
+main() {
+  IsolateSharedSummaryElement.tag.ensureRegistration();
+
+  final cTag = IsolateCounterChartElement.tag.name;
+
+  const isolate = const IsolateMock();
+  test('instantiation', () {
+    final e = new IsolateSharedSummaryElement(isolate);
+    expect(e, isNotNull, reason: 'element correctly created');
+  });
+  test('elements created', () async {
+    final e = new IsolateSharedSummaryElement(isolate);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.querySelectorAll(cTag).length, equals(1));
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.html b/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.dart
new file mode 100644
index 0000000..9b2a782
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/isolate_reconnect.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import '../mocks.dart';
+
+main() {
+  IsolateReconnectElement.tag.ensureRegistration();
+
+  final nTag = NavNotifyElement.tag.name;
+
+  EventRepositoryMock events;
+  NotificationRepositoryMock notifications;
+  Uri uri;
+  const vm = const VMMock(isolates: const [
+    const IsolateMock(id: 'i-1-id'), const IsolateMock(id: 'i-2-id')
+  ]);
+  const missing = 'missing-id';
+  setUp(() {
+    events = new EventRepositoryMock();
+    notifications = new NotificationRepositoryMock();
+    uri = new  Uri(path: 'path');
+  });
+  test('instantiation', () {
+    final e = new IsolateReconnectElement(vm, events, notifications, missing,
+                                          uri);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.vm, equals(vm));
+    expect(e.missing, equals(missing));
+    expect(e.uri, equals(uri));
+  });
+  test('elements created after attachment', () async {
+    final e = new IsolateReconnectElement(vm, events, notifications, missing,
+                                          uri);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.querySelector(nTag), isNotNull, reason: 'has notifications');
+    expect(e.querySelectorAll('.isolate-link').length,
+        equals(vm.isolates.length), reason: 'has links');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+  group('updates', () {
+    test('are correctly listen', () async {
+      final e = new IsolateReconnectElement(vm, events, notifications, missing,
+                                            uri);
+      expect(events.onVMUpdateHasListener, isFalse);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(events.onVMUpdateHasListener, isTrue);
+      e.remove();
+      await e.onRendered.first;
+      expect(events.onVMUpdateHasListener, isFalse);
+    });
+    test('have effects', () async {
+      final e = new IsolateReconnectElement(vm, events, notifications, missing,
+                                            uri);
+      const vm2 = const VMMock(isolates: const [
+          const IsolateMock(id: 'i-1-id'), const IsolateMock(id: 'i-2-id'),
+          const IsolateMock(id: 'i-3-id')
+      ]);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.querySelectorAll('.isolate-link').length,
+          equals(vm.isolates.length));
+      events.add(new VMUpdateEventMock(vm: vm2));
+      await e.onRendered.first;
+      expect(e.querySelectorAll('.isolate-link').length,
+          equals(vm2.isolates.length));
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.html b/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.dart
new file mode 100644
index 0000000..6d4e25b
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate_ref/element_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:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/isolate_ref.dart';
+import '../mocks.dart';
+
+main() {
+  IsolateRefElement.tag.ensureRegistration();
+
+  final ref = new IsolateRefMock(id: 'id', name: 'old-name');
+  final events = new EventRepositoryMock();
+  final obj = new IsolateMock(id: 'id', name: 'new-name');
+  group('instantiation', () {
+    test('IsolateRef', () {
+      final e = new IsolateRefElement(ref, events);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(ref));
+    });
+    test('Isolate', () {
+      final e = new IsolateRefElement(obj, events);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(obj));
+    });
+  });
+  test('elements created after attachment', () async {
+    final e = new IsolateRefElement(ref, events);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+  group('updates', () {
+    test('are correctly listen', () async {
+      final e = new IsolateRefElement(ref, events);
+      expect(events.onIsolateUpdateHasListener, isFalse);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(events.onIsolateUpdateHasListener, isTrue);
+      e.remove();
+      await e.onRendered.first;
+      expect(events.onIsolateUpdateHasListener, isFalse);
+    });
+    test('have effects', () async {
+      final e = new IsolateRefElement(ref, events);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(ref.id), isTrue);
+      events.add(new IsolateUpdateEventMock(isolate: obj));
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(ref.name), isFalse);
+      expect(e.innerHtml.contains(obj.name), isTrue);
+      e.remove();
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.html b/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/library_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/library_ref/element_test.dart
new file mode 100644
index 0000000..f1e2dda
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/library_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/library_ref.dart';
+import '../mocks.dart';
+
+main() {
+  LibraryRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock(id: 'i-id', name: 'i-name');
+  const library = const LibraryRefMock(id: 'c-id', name: 'c-name');
+  test('instantiation', () {
+    final e = new LibraryRefElement(isolate, library);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.library, equals(library));
+  });
+  test('elements created after attachment', () async {
+    final e = new LibraryRefElement(isolate, library);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/library_ref/element_test.html b/runtime/observatory/tests/observatory_ui/library_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/library_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.dart
new file mode 100644
index 0000000..c3071a8
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/local_var_descriptors_ref.dart';
+import '../mocks.dart';
+
+main() {
+  LocalVarDescriptorsRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const localVar = const LocalVarDescriptorsRefMock();
+  test('instantiation', () {
+    final e = new LocalVarDescriptorsRefElement(isolate, localVar);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.localVar, equals(localVar));
+  });
+  test('elements created after attachment', () async {
+    final e = new LocalVarDescriptorsRefElement(isolate, localVar);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.html b/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.dart
new file mode 100644
index 0000000..41e879d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/megamorphiccache_ref.dart';
+import '../mocks.dart';
+
+main() {
+  MegamorphicCacheRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const cache = const MegamorphicCacheRefMock();
+  test('instantiation', () {
+    final e = new MegamorphicCacheRefElement(isolate, cache);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.cache, equals(cache));
+  });
+  test('elements created after attachment', () async {
+    final e = new MegamorphicCacheRefElement(isolate, cache);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.html b/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/mocks.dart b/runtime/observatory/tests/observatory_ui/mocks.dart
new file mode 100644
index 0000000..c2e1427
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mocks;
+
+import 'dart:async';
+
+import 'package:observatory/models.dart' as M;
+
+part 'mocks/exceptions/connection_exception.dart';
+
+part 'mocks/objects/allocation_profile.dart';
+part 'mocks/objects/error.dart';
+part 'mocks/objects/code.dart';
+part 'mocks/objects/context.dart';
+part 'mocks/objects/event.dart';
+part 'mocks/objects/class.dart';
+part 'mocks/objects/field.dart';
+part 'mocks/objects/flag.dart';
+part 'mocks/objects/function.dart';
+part 'mocks/objects/heap_space.dart';
+part 'mocks/objects/icdata.dart';
+part 'mocks/objects/instance.dart';
+part 'mocks/objects/isolate.dart';
+part 'mocks/objects/library.dart';
+part 'mocks/objects/local_var_descriptors.dart';
+part 'mocks/objects/megamorphiccache.dart';
+part 'mocks/objects/notification.dart';
+part 'mocks/objects/objectpool.dart';
+part 'mocks/objects/pc_descriptors.dart';
+part 'mocks/objects/sample_profile.dart';
+part 'mocks/objects/script.dart';
+part 'mocks/objects/sentinel.dart';
+part 'mocks/objects/source_location.dart';
+part 'mocks/objects/target.dart';
+part 'mocks/objects/token_stream.dart';
+part 'mocks/objects/unknown.dart';
+part 'mocks/objects/vm.dart';
+
+part 'mocks/repositories/allocation_profile.dart';
+part 'mocks/repositories/class.dart';
+part 'mocks/repositories/event.dart';
+part 'mocks/repositories/flag.dart';
+part 'mocks/repositories/instance.dart';
+part 'mocks/repositories/notification.dart';
+part 'mocks/repositories/sample_profile.dart';
+part 'mocks/repositories/script.dart';
+part 'mocks/repositories/target.dart';
diff --git a/runtime/observatory/tests/observatory_ui/mocks/exceptions/connection_exception.dart b/runtime/observatory/tests/observatory_ui/mocks/exceptions/connection_exception.dart
new file mode 100644
index 0000000..d036951
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/exceptions/connection_exception.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ConnectionExceptionMock implements M.ConnectionException {
+  final String message;
+  const ConnectionExceptionMock({this.message});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/allocation_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/allocation_profile.dart
new file mode 100644
index 0000000..7b13ef0
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/allocation_profile.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of mocks;
+
+class AllocationProfileMock implements M.AllocationProfile {
+  final DateTime lastServiceGC;
+  final DateTime lastAccumulatorReset;
+  final M.HeapSpace newSpace;
+  final M.HeapSpace oldSpace;
+  final Iterable<M.ClassHeapStats> members;
+
+  const AllocationProfileMock({this.lastServiceGC, this.lastAccumulatorReset,
+                               this.newSpace: const HeapSpaceMock(),
+                               this.oldSpace: const HeapSpaceMock(),
+                               this.members: const []});
+}
+
+
+class ClassHeapStatsMock implements M.ClassHeapStats {
+  final M.ClassRef clazz;
+  final M.Allocations newSpace;
+  final M.Allocations oldSpace;
+  final int promotedInstances;
+  final int promotedBytes;
+
+  const ClassHeapStatsMock({this.clazz: const ClassRefMock(),
+                            this.newSpace: const AllocationsMock(),
+                            this.oldSpace: const AllocationsMock(),
+                            this.promotedInstances: 0, this.promotedBytes: 0});
+}
+
+class AllocationsMock implements M.Allocations {
+  final M.AllocationCount accumulated;
+  final M.AllocationCount current;
+
+  const AllocationsMock({this.accumulated: const AllocationCountMock(),
+                         this.current: const AllocationCountMock()});
+}
+
+class AllocationCountMock implements M.AllocationCount {
+  final int instances;
+  final int bytes;
+
+  const AllocationCountMock({this.instances: 0, this.bytes: 0});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/class.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/class.dart
new file mode 100644
index 0000000..42209d6
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/class.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ClassRefMock implements M.ClassRef {
+  final String id;
+  final String name;
+  const ClassRefMock({this.id, this.name});
+}
+
+class ClassMock implements M.Class {
+  final String id;
+  final String name;
+  final M.ClassRef clazz;
+  final int size;
+  final M.ErrorRef error;
+  final bool isAbstract;
+  final bool isConst;
+  final bool isPatch;
+  final M.LibraryRef library;
+  final M.SourceLocation location;
+  final M.ClassRef superclass;
+  final M.InstanceRef superType;
+  final Iterable<M.InstanceRef> interfaces;
+  final M.InstanceRef mixin;
+  final Iterable<M.ClassRef> subclasses;
+  const ClassMock({this.id: 'c-id', this.name: 'c-name', this.clazz, this.size,
+      this.error, this.isAbstract: false, this.isConst: false,
+      this.isPatch: false, this.library, this.location, this.superclass,
+      this.superType, this.interfaces: const [], this.mixin,
+      this.subclasses: const []});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/code.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/code.dart
new file mode 100644
index 0000000..528d70a
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/code.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class CodeRefMock implements M.CodeRef {
+  final String id;
+  final String name;
+  final M.CodeKind kind;
+  final bool isOptimized;
+
+  const CodeRefMock({this.id, this.name, this.kind, this.isOptimized: false });
+}
+
+class CodeMock implements M.Code {
+  final String id;
+  final String name;
+  final M.ClassRef clazz;
+  final int size;
+  final M.CodeKind kind;
+  final bool isOptimized;
+
+  const CodeMock({this.id, this.name, this.clazz, this.size, this.kind,
+                  this.isOptimized: false });
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/context.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/context.dart
new file mode 100644
index 0000000..2ac5e5e
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/context.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ContextRefMock implements M.ContextRef {
+  final String id;
+  final int length;
+
+  const ContextRefMock({this.id, this.length: 0});
+}
+
+class ContextMock implements M.Context {
+  final String id;
+  final M.ClassRef clazz;
+  final int size;
+  final int length;
+  final M.Context parentContext;
+
+  const ContextMock({this.id, this.clazz, this.size, this.length: 0,
+                     this.parentContext});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
new file mode 100644
index 0000000..1a87016
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ErrorRefMock implements M.ErrorRef {
+  final String id;
+  final M.ErrorKind kind;
+  final String message;
+  const ErrorRefMock({this.id, this.kind, this.message});
+}
+
+class ErrorMock implements M.Error {
+  final String id;
+  final M.ClassRef clazz;
+  final int size;
+  final M.ErrorKind kind;
+  final String message;
+  const ErrorMock({this.id, this.clazz, this.size, this.kind, this.message});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/event.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/event.dart
new file mode 100644
index 0000000..7e4aa17
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/event.dart
@@ -0,0 +1,148 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class VMUpdateEventMock implements M.VMUpdateEvent {
+  final M.VMRef vm;
+  final DateTime timestamp;
+  const VMUpdateEventMock({this.timestamp, this.vm});
+}
+class IsolateStartEventMock implements M.IsolateStartEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const IsolateStartEventMock({this.timestamp, this.isolate});
+}
+class IsolateRunnableEventMock implements M.IsolateRunnableEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const IsolateRunnableEventMock({this.timestamp, this.isolate});
+}
+class IsolateExitEventMock implements M.IsolateExitEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const IsolateExitEventMock({this.timestamp, this.isolate});
+}
+class IsolateUpdateEventMock implements M.IsolateUpdateEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const IsolateUpdateEventMock({this.timestamp, this.isolate});
+}
+class IsolateRealodEventMock implements M.IsolateReloadEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Error error;
+  const IsolateRealodEventMock({this.timestamp, this.isolate, this.error});
+}
+class ServiceExtensionAddedEventMock implements M.ServiceExtensionAddedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final String extensionRPC;
+  const ServiceExtensionAddedEventMock({this.extensionRPC, this.isolate,
+      this.timestamp});
+}
+class DebuggerSettingsUpdateEventMock implements M.PauseStartEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const DebuggerSettingsUpdateEventMock({this.isolate, this.timestamp});
+}
+class PauseStartEventMock implements M.PauseStartEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const PauseStartEventMock({this.isolate, this.timestamp});
+}
+class PauseExitEventMock implements M.PauseExitEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const PauseExitEventMock({this.isolate, this.timestamp});
+}
+class PauseBreakpointEventMock implements M.PauseBreakpointEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Breakpoint breakpoint;
+  final List<M.Breakpoint> pauseBreakpoints;
+  final M.Frame topFrame;
+  final bool atAsyncSuspension;
+  const PauseBreakpointEventMock({this.timestamp, this.isolate, this.breakpoint,
+      this.pauseBreakpoints, this.topFrame, this.atAsyncSuspension});
+}
+class PauseInterruptedEventMock implements M.PauseInterruptedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Frame topFrame;
+  final bool atAsyncSuspension;
+  const PauseInterruptedEventMock({this.timestamp, this.isolate, this.topFrame,
+      this.atAsyncSuspension});
+}
+class PauseExceptionEventMock implements M.PauseExceptionEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Frame topFrame;
+  final M.InstanceRef exception;
+  const PauseExceptionEventMock({this.timestamp, this.isolate, this.topFrame,
+      this.exception});
+}
+class ResumeEventMock implements M.ResumeEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Frame topFrame;
+  const ResumeEventMock({this.timestamp, this.isolate, this.topFrame});
+}
+class BreakpointAddedEventMock implements M.BreakpointAddedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Breakpoint breakpoint;
+  const BreakpointAddedEventMock({this.timestamp, this.isolate,
+      this.breakpoint});
+}
+class BreakpointResolvedEventMock implements M.BreakpointResolvedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Breakpoint breakpoint;
+  const BreakpointResolvedEventMock({this.timestamp, this.isolate,
+      this.breakpoint});
+}
+class BreakpointRemovedEventMock implements M.BreakpointRemovedEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.Breakpoint breakpoint;
+  const BreakpointRemovedEventMock({this.timestamp, this.isolate,
+      this.breakpoint});
+}
+class InspectEventMock implements M.InspectEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final M.InstanceRef inspectee;
+  const InspectEventMock({this.timestamp, this.isolate, this.inspectee});
+}
+class NoneEventMock implements M.NoneEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const NoneEventMock({this.timestamp, this.isolate});
+}
+class GCEventMock implements M.GCEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  const GCEventMock({this.timestamp, this.isolate});
+}
+class ExtensionEventMock implements M.ExtensionEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final String extensionKind;
+  final M.ExtensionData extensionData;
+  const ExtensionEventMock({this.timestamp, this.isolate, this.extensionKind,
+      this.extensionData});
+}
+class TimelineEventsEventMock implements M.TimelineEventsEvent {
+  final DateTime timestamp;
+  final M.IsolateRef isolate;
+  final List<M.TimelineEvent> timelineEvents;
+  const TimelineEventsEventMock({this.timestamp, this.isolate,
+      this.timelineEvents});
+}
+class ConnectionClockedEventMock implements M.ConnectionClosedEvent {
+  final DateTime timestamp;
+  final String reason;
+  const ConnectionClockedEventMock({this.timestamp, this.reason});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/field.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/field.dart
new file mode 100644
index 0000000..99f0ed3
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/field.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of mocks;
+
+class FieldRefMock implements M.FieldRef {
+  final String id;
+  final String name;
+  final M.ObjectRef dartOwner;
+  final M.InstanceRef declaredType;
+  final bool isConst;
+  final bool isFinal;
+  final bool isStatic;
+
+  const FieldRefMock({this.id: 'field-id', this.name: 'field-name',
+                      this.dartOwner,
+                      this.declaredType: const InstanceRefMock(name: 'dynamic'),
+                      this.isConst: false,
+                      this.isFinal: false, this.isStatic: false});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/flag.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/flag.dart
new file mode 100644
index 0000000..1b250ff
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/flag.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of mocks;
+
+class FlagMock implements M.Flag {
+  final String name;
+  final String comment;
+  final bool modified;
+  final String valueAsString;
+
+  const FlagMock({this.name, this.comment, this.modified, this.valueAsString});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
new file mode 100644
index 0000000..85eae71
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/function.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.
+
+part of mocks;
+
+class FunctionRefMock implements M.FunctionRef {
+  final String id;
+  final String name;
+  final M.ObjectRef dartOwner;
+  final bool isStatic;
+  final bool isConst;
+  final M.FunctionKind kind;
+
+  const FunctionRefMock({this.id, this.name, this.dartOwner,
+      this.isStatic : false, this.isConst : false, this.kind});
+}
+
+class FunctionMock implements M.Function {
+  final String id;
+  final String name;
+  final M.ClassRef clazz;
+  final int size;
+  final M.ObjectRef dartOwner;
+  final bool isStatic;
+  final bool isConst;
+  final M.FunctionKind kind;
+  final M.SourceLocation location;
+  final M.CodeRef code;
+  const FunctionMock({this.id, this.name, this.clazz, this.size, this.dartOwner,
+      this.isStatic : false, this.isConst : false, this.kind, this.location,
+      this.code});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/heap_space.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/heap_space.dart
new file mode 100644
index 0000000..1f96ad8d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/heap_space.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class HeapSpaceMock implements M.HeapSpace {
+  final int used;
+  final int capacity;
+  final int collections;
+  final int external;
+  final Duration avgCollectionTime;
+  final Duration totalCollectionTime;
+  final Duration avgCollectionPeriod;
+  const HeapSpaceMock({this.used: 0, this.capacity: 1, this.collections: 0,
+                       this.external: 1,
+                       this.avgCollectionTime: const Duration(),
+                       this.totalCollectionTime: const Duration(),
+                       this.avgCollectionPeriod: const Duration()});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/icdata.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/icdata.dart
new file mode 100644
index 0000000..b7a3510
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/icdata.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ICDataRefMock implements M.ICDataRef {
+  final String id;
+  final String selector;
+
+  const ICDataRefMock({this.id: 'icdata-id', this.selector});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart
new file mode 100644
index 0000000..d40059a
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class InstanceRefMock implements M.InstanceRef {
+  final String id;
+  final String name;
+  final M.InstanceKind kind;
+  final M.ClassRef clazz;
+  final String valueAsString;
+  final bool valueAsStringIsTruncated;
+  final int length;
+  final M.ClassRef typeClass;
+  final M.ClassRef parameterizedClass;
+  final M.InstanceRef pattern;
+  final M.FunctionRef closureFunction;
+
+  const InstanceRefMock({this.id: 'instance-id', this.name: 'instance-name',
+                         this.kind: M.InstanceKind.vNull, this.clazz,
+                         this.valueAsString: 'null',
+                         this.valueAsStringIsTruncated, this.length,
+                         this.typeClass, this.parameterizedClass, this.pattern,
+                        this.closureFunction});
+}
+
+class InstanceMock implements M.Instance {
+  final String id;
+  final String name;
+  final M.InstanceKind kind;
+  final M.ClassRef clazz;
+  final int size;
+  final String valueAsString;
+  final bool valueAsStringIsTruncated;
+  final int length;
+  final M.ClassRef typeClass;
+  final M.ClassRef parameterizedClass;
+  final M.InstanceRef pattern;
+  final M.FunctionRef closureFunction;
+  final int offset;
+  final int count;
+  final Iterable<dynamic> typedElements;
+  final Iterable<M.BoundField> fields;
+  final Iterable<M.Guarded<M.ObjectRef>> elements;
+  final Iterable<M.MapAssociation> associations;
+  final M.InstanceRef key;
+  final M.InstanceRef value;
+  final M.InstanceRef referent;
+
+  const InstanceMock({this.id: 'instance-id', this.name: 'instance-name',
+                      this.kind: M.InstanceKind.vNull, this.clazz, this.size,
+                      this.valueAsString: 'null', this.valueAsStringIsTruncated,
+                      this.length, this.typeClass, this.parameterizedClass,
+                      this.pattern, this.closureFunction, this.offset,
+                      this.count, this.typedElements, this.fields,
+                      this.elements, this.associations, this.key, this.value,
+                      this.referent});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/isolate.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/isolate.dart
new file mode 100644
index 0000000..055b84e
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/isolate.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class IsolateRefMock implements M.IsolateRef {
+  final String id;
+  final int number;
+  final String name;
+
+  const IsolateRefMock({this.id: 'i-id', this.number, this.name: 'i-name'});
+}
+
+class IsolateMock implements M.Isolate {
+  final String id;
+  final int number;
+  final String name;
+  final DateTime startTime;
+  final bool runnable;
+  final Iterable<M.LibraryRef> libraries;
+  final M.Error error;
+  final Iterable<String> extensionRPCs;
+  final Map counters;
+  final M.HeapSpace newSpace;
+  final M.HeapSpace oldSpace;
+
+  const IsolateMock({this.id: 'i-id', this.number, this.name: 'i-name',
+                     this.startTime, this.runnable: true,
+                     this.libraries: const [], this.error,
+                     this.extensionRPCs: const [], this.counters: const {},
+                     this.newSpace: const HeapSpaceMock(),
+                     this.oldSpace: const HeapSpaceMock()});
+  // TODO(cbernaschina) add other properties.
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/library.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/library.dart
new file mode 100644
index 0000000..43e65b1
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/library.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class LibraryRefMock implements M.LibraryRef {
+  final String id;
+  final String name;
+  final String uri;
+  const LibraryRefMock({this.id, this.name, this.uri});
+}
+
+class LibraryMock implements M.Library {
+  final String id;
+  final String name;
+  final M.ClassRef clazz;
+  final int size;
+  final String uri;
+  final bool debuggable;
+  final Iterable<M.ScriptRef> scripts;
+  final Iterable<M.ClassRef> classes;
+  const LibraryMock({this.id, this.name, this.clazz, this.size, this.uri,
+                     this.debuggable, this.scripts: const [],
+                     this.classes: const []});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/local_var_descriptors.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/local_var_descriptors.dart
new file mode 100644
index 0000000..f500660
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/local_var_descriptors.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class LocalVarDescriptorsRefMock implements M.LocalVarDescriptorsRef {
+  final String id;
+  final String name;
+  const LocalVarDescriptorsRefMock({this.id: 'local-var-id',
+                              this.name: 'local_var_name'});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
new file mode 100644
index 0000000..6e58941
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class MegamorphicCacheRefMock implements M.MegamorphicCacheRef {
+  final String id;
+  final String selector;
+
+  const MegamorphicCacheRefMock({this.id : 'megamorphiccache-id',
+                                 this.selector});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/notification.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/notification.dart
new file mode 100644
index 0000000..d452cee
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/notification.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ExceptionNotificationMock implements M.ExceptionNotification {
+  final Exception exception;
+  final StackTrace stacktrace;
+  const ExceptionNotificationMock({this.exception, this.stacktrace});
+}
+
+class EventNotificationMock implements M.EventNotification {
+  final M.Event event;
+  const EventNotificationMock({this.event});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
new file mode 100644
index 0000000..59932ee
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ObjectPoolRefMock implements M.ObjectPoolRef {
+  final String id;
+  final int length;
+
+  const ObjectPoolRefMock({this.id: 'objectpool-id', this.length: 0});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/pc_descriptors.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/pc_descriptors.dart
new file mode 100644
index 0000000..fc2f6bd
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/pc_descriptors.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class PcDescriptorsRefMock implements M.PcDescriptorsRef {
+  final String id;
+  final String name;
+
+  const PcDescriptorsRefMock({this.id: 'pcdescriptors-id',
+                              this.name: 'pcdescriptors-name'});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/sample_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/sample_profile.dart
new file mode 100644
index 0000000..4e8441c
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/sample_profile.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
+
+part of mocks;
+
+typedef M.FunctionCallTree SampleProfileMockLoadFunctionTreeCallback(
+    M.ProfileTreeDirection direction);
+typedef M.CodeCallTree SampleProfileMockLoadCodeTreeCallback(
+    M.ProfileTreeDirection direction);
+
+class SampleProfileMock implements M.SampleProfile {
+  final SampleProfileMockLoadFunctionTreeCallback _loadFunctionTree;
+  final SampleProfileMockLoadCodeTreeCallback _loadCodeTree;
+
+
+  final int sampleCount;
+  final int stackDepth;
+  final double sampleRate;
+  final double timeSpan;
+
+  M.FunctionCallTree loadFunctionTree(M.ProfileTreeDirection direction) {
+    if (_loadFunctionTree != null) {
+      return _loadFunctionTree(direction);
+    }
+    return null;
+  }
+  M.CodeCallTree loadCodeTree(M.ProfileTreeDirection direction) {
+    if (_loadCodeTree != null) {
+      return _loadCodeTree(direction);
+    }
+    return null;
+  }
+
+  SampleProfileMock({this.sampleCount: 0, this.stackDepth: 0,
+      this.sampleRate: 1.0, this.timeSpan: 1.0,
+      SampleProfileMockLoadFunctionTreeCallback loadFunctionTree,
+      SampleProfileMockLoadCodeTreeCallback loadCodeTree})
+    : _loadFunctionTree = loadFunctionTree,
+      _loadCodeTree = loadCodeTree;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
new file mode 100644
index 0000000..c5139bc
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/script.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.
+
+part of mocks;
+
+class ScriptRefMock implements M.ScriptRef {
+  final String id;
+  final String uri;
+
+  const ScriptRefMock({this.id, this.uri});
+}
+
+typedef int TokenToInt(int token);
+
+class ScriptMock implements M.Script {
+  final String id;
+  final M.ClassRef clazz;
+  final int size;
+  final String uri;
+  final String source;
+
+  final TokenToInt _tokenToLine;
+  final TokenToInt _tokenToCol;
+
+  int tokenToLine(int token) => _tokenToLine(token);
+  int tokenToCol(int token) => _tokenToCol(token);
+
+  const ScriptMock({this.id, this.clazz, this.size, this.uri, this.source,
+      TokenToInt tokenToLine, TokenToInt tokenToCol})
+    : _tokenToLine = tokenToLine,
+      _tokenToCol = tokenToCol;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/sentinel.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/sentinel.dart
new file mode 100644
index 0000000..1d77a35
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/sentinel.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class Sentinel implements M.Sentinel {
+  final M.SentinelKind kind;
+  final String valueAsString;
+
+  const Sentinel({this.kind: M.SentinelKind.collected,
+                  this.valueAsString: 'sentinel-value'});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/source_location.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/source_location.dart
new file mode 100644
index 0000000..a795589
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/source_location.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class SourceLocationMock implements M.SourceLocation {
+  final M.ScriptRef script;
+  final int tokenPos;
+  final int endTokenPos;
+
+  const SourceLocationMock({this.script, this.tokenPos, this.endTokenPos});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/target.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/target.dart
new file mode 100644
index 0000000..0d15e5c
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/target.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class TargetMock implements M.Target {
+  final String name;
+  const TargetMock({this.name});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/token_stream.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/token_stream.dart
new file mode 100644
index 0000000..efb6c98
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/token_stream.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class TokenStreamRefMock implements M.TokenStreamRef {
+  final String id;
+  final String name;
+  const TokenStreamRefMock({this.id: 'tokenstream-id', this.name});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/unknown.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/unknown.dart
new file mode 100644
index 0000000..71ce7f5
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/unknown.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class UnknownObjectRefMock implements M.UnknownObjectRef {
+  final String id;
+  final String vmType;
+  const UnknownObjectRefMock({this.id: 'literal-token-id',
+                              this.vmType: 'vmType'});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/vm.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/vm.dart
new file mode 100644
index 0000000..2740b83
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/vm.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class VMRefMock implements M.VMRef {
+  final String name;
+  final String displayName;
+  const VMRefMock({this.name: 'vm-name', this.displayName: 'vm-display-name'});
+}
+
+class VMMock implements M.VM {
+  final String name;
+  final String displayName;
+  final int architectureBits;
+  final String targetCPU;
+  final String hostCPU;
+  final String version;
+  final int pid;
+  final DateTime startTime;
+  final Iterable<M.IsolateRef> isolates;
+
+  const VMMock({this.name: 'vm-name', this.displayName: 'vm-display-name',
+      this.architectureBits, this.targetCPU, this.hostCPU, this.version,
+      this.pid, this.startTime, this.isolates : const []});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/allocation_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/allocation_profile.dart
new file mode 100644
index 0000000..a83f35d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/allocation_profile.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+typedef Future<M.AllocationProfile>
+        AllocationProfileRepositoryMockGetterCallback(M.Isolate id,
+                                                      bool gc,
+                                                      bool force);
+
+class AllocationProfileRepositoryMock implements M.AllocationProfileRepository {
+  final AllocationProfileRepositoryMockGetterCallback _get;
+
+  AllocationProfileRepositoryMock(
+      {AllocationProfileRepositoryMockGetterCallback getter})
+    : _get = getter;
+
+  Future<M.AllocationProfile> get(M.IsolateRef id, {bool gc: false,
+                                                    bool reset: false}){
+    if (_get != null) {
+      return _get(id, gc, reset);
+    }
+    return new Future.value(null);
+  }
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
new file mode 100644
index 0000000..3c5fe7b
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+typedef Future<M.Class> ClassRepositoryMockObjectCallback();
+typedef Future<M.Class> ClassRepositoryMockGetterCallback(String id);
+
+class ClassRepositoryMock implements M.ClassRepository {
+  final ClassRepositoryMockObjectCallback _object;
+  final ClassRepositoryMockGetterCallback _get;
+
+  ClassRepositoryMock({ClassRepositoryMockObjectCallback object,
+                       ClassRepositoryMockGetterCallback getter})
+    : _object = object,
+      _get = getter;
+
+  Future<M.Class> getObject(){
+    if (_object != null) {
+      return _object();
+    }
+    return new Future.value(null);
+  }
+
+  Future<M.Class> get(String id){
+    if (_get != null) {
+      return _get(id);
+    }
+    return new Future.value(null);
+  }
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/event.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/event.dart
new file mode 100644
index 0000000..7748786
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/event.dart
@@ -0,0 +1,171 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class EventRepositoryMock implements M.EventRepository {
+  final _onEvent = new StreamController<M.Event>.broadcast();
+  get onEvent => _onEvent.stream;
+  get onEventHasListener => _onEvent.hasListener;
+
+  final _onVMEvent = new StreamController<M.VMEvent>.broadcast();
+  get onVMEvent => _onVMEvent.stream;
+  get onVMEventHasListener => _onVMEvent.hasListener;
+
+  final _onVMUpdate = new StreamController<M.Event>.broadcast();
+  get onVMUpdate => _onVMUpdate.stream;
+  get onVMUpdateHasListener => _onVMUpdate.hasListener;
+
+  final _onIsolateEvent = new StreamController<M.IsolateEvent>.broadcast();
+  get onIsolateEvent => _onIsolateEvent.stream;
+  get onIsolateEventHasListener => _onIsolateEvent.hasListener;
+
+  final _onIsolateStart = new StreamController<M.IsolateStartEvent>.broadcast();
+  get onIsolateStart => _onIsolateStart.stream;
+  get onIsolateStartHasListener => _onIsolateStart.hasListener;
+
+  final _onIsolateRunnable =
+      new StreamController<M.IsolateRunnableEvent>.broadcast();
+  get onIsolateRunnable => _onIsolateRunnable.stream;
+  get onIsolateRunnableHasListener => _onIsolateRunnable.hasListener;
+
+  final _onIsolateExit = new StreamController<M.IsolateExitEvent>.broadcast();
+  get onIsolateExit => _onIsolateExit.stream;
+  get onIsolateExitHasListener => _onIsolateExit.hasListener;
+
+  final _onIsolateUpdate =
+      new StreamController<M.IsolateUpdateEvent>.broadcast();
+  get onIsolateUpdate => _onIsolateUpdate.stream;
+  get onIsolateUpdateHasListener => _onIsolateUpdate.hasListener;
+
+  final _onIsolateReload = new StreamController<M.IsolateReloadEvent>.broadcast();
+  get onIsolateReload => _onIsolateReload.stream;
+  get onIsolateReloadHasListener => _onIsolateReload.hasListener;
+
+  final _onServiceExtensionAdded =
+      new StreamController<M.ServiceExtensionAddedEvent>.broadcast();
+  get onServiceExtensionAdded => _onServiceExtensionAdded.stream;
+  get onServiceExtensionAddedHasListener =>
+      _onServiceExtensionAdded.hasListener;
+
+  final _onDebugEvent = new StreamController<M.DebugEvent>.broadcast();
+  get onDebugEvent => _onDebugEvent.stream;
+  get onDebugEventHasListener => _onDebugEvent.hasListener;
+
+  final _onPauseStart = new StreamController<M.PauseStartEvent>.broadcast();
+  get onPauseStart => _onPauseStart.stream;
+  get onPauseStartHasListener => _onPauseStart.hasListener;
+
+  final _onPauseExit = new StreamController<M.PauseExitEvent>.broadcast();
+  get onPauseExit => _onPauseExit.stream;
+  get onPauseExitHasListener => _onPauseExit.hasListener;
+
+  final _onPauseBreakpoint =
+      new StreamController<M.PauseBreakpointEvent>.broadcast();
+  get onPauseBreakpoint => _onPauseBreakpoint.stream;
+  get onPauseBreakpointHasListener => _onPauseBreakpoint.hasListener;
+
+  final _onPauseInterrupted =
+      new StreamController<M.PauseInterruptedEvent>.broadcast();
+  get onPauseInterrupted => _onPauseInterrupted.stream;
+  get onPauseInterruptedHasListener => _onPauseInterrupted.hasListener;
+
+  final _onPauseException =
+      new StreamController<M.PauseExceptionEvent>.broadcast();
+  get onPauseException => _onPauseException.stream;
+  get onPauseExceptionHasListener => _onPauseException.hasListener;
+
+  final _onResume = new StreamController<M.ResumeEvent>.broadcast();
+  get onResume => _onResume.stream;
+  get onResumeHasListener => _onResume.hasListener;
+
+  final _onBreakpointAdded =
+      new StreamController<M.BreakpointAddedEvent>.broadcast();
+  get onBreakpointAdded => _onBreakpointAdded.stream;
+  get onBreakpointAddedHasListener => _onBreakpointAdded.hasListener;
+
+  final _onBreakpointResolved =
+    new StreamController<M.BreakpointResolvedEvent>.broadcast();
+  get onBreakpointResolved => _onBreakpointResolved.stream;
+  get onBreakpointResolvedHasListener => _onBreakpointResolved.hasListener;
+
+  final _onBreakpointRemoved =
+      new StreamController<M.BreakpointRemovedEvent>.broadcast();
+  get onBreakpointRemoved => _onBreakpointRemoved.stream;
+  get onBreakpointRemovedHasListener => _onBreakpointRemoved.hasListener;
+
+  final _onInspect = new StreamController<M.InspectEvent>.broadcast();
+  get onInspect => _onInspect.stream;
+  get onInspectHasListener => _onInspect.hasListener;
+
+  final _onGCEvent = new StreamController<M.GCEvent>.broadcast();
+  get onGCEvent => _onGCEvent.stream;
+  get onGCEventHasListener => _onGCEvent.hasListener;
+
+  final _onExtensionEvent = new StreamController<M.ExtensionEvent>.broadcast();
+  get onExtensionEvent => _onExtensionEvent.stream;
+  get onExtensionEventHasListener => _onExtensionEvent.hasListener;
+
+  final _onTimelineEvents =
+      new StreamController<M.TimelineEventsEvent>.broadcast();
+  get onTimelineEvents => _onTimelineEvents.stream;
+  get onTimelineEventsEventHasListener => _onTimelineEvents.hasListener;
+
+  final _onConnectionClosed =
+      new StreamController<M.ConnectionClosedEvent>.broadcast();
+  get onConnectionClosed => _onConnectionClosed.stream;
+  get onConnectionClosedHasListener => _onConnectionClosed.hasListener;
+
+  void add(M.Event event) {
+    _onEvent.add(event);
+    if (event is M.VMEvent) {
+      _onVMEvent.add(event);
+      if (event is M.VMUpdateEvent) {
+        _onVMUpdate.add(event);
+      }
+    } else if (event is M.IsolateEvent) {
+      _onIsolateEvent.add(event);
+      if (event is M.IsolateStartEvent) {
+        _onIsolateStart.add(event);
+      } else if (event is M.IsolateRunnableEvent) {
+        _onIsolateRunnable.add(event);
+      } else if (event is M.IsolateExitEvent) {
+        _onIsolateExit.add(event);
+      } else if (event is M.IsolateUpdateEvent) {
+        _onIsolateUpdate.add(event);
+      } else if (event is M.ServiceExtensionAddedEvent) {
+        _onServiceExtensionAdded.add(event);
+      }
+    } else if (event is M.DebugEvent) {
+      _onDebugEvent.add(event);
+      if (event is M.PauseStartEvent) {
+        _onPauseStart.add(event);
+      } else if (event is M.PauseExitEvent) {
+        _onPauseExit.add(event);
+      } else if (event is M.PauseBreakpointEvent) {
+        _onPauseBreakpoint.add(event);
+      } else if (event is M.PauseInterruptedEvent) {
+        _onPauseInterrupted.add(event);
+      } else if (event is M.PauseExceptionEvent) {
+        _onPauseException.add(event);
+      } else if (event is M.ResumeEvent) {
+        _onResume.add(event);
+      } else if (event is M.BreakpointAddedEvent) {
+        _onBreakpointAdded.add(event);
+      } else if (event is M.BreakpointResolvedEvent) {
+        _onBreakpointResolved.add(event);
+      } else if (event is M.BreakpointRemovedEvent) {
+        _onBreakpointRemoved.add(event);
+      } else if (event is M.InspectEvent) {
+        _onInspect.add(event);
+      }
+    } else if (event is M.GCEvent) {
+      _onGCEvent.add(event);
+    } else if (event is M.ExtensionEvent) {
+      _onExtensionEvent.add(event);
+    } else if (event is M.TimelineEventsEvent) {
+      _onTimelineEvents.add(event);
+    }
+  }
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/flag.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/flag.dart
new file mode 100644
index 0000000..e782b30
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/flag.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
+
+part of mocks;
+
+class FlagsRepositoryMock implements M.FlagsRepository {
+  final Iterable<M.Flag> _list;
+  bool isListInvoked = false;
+
+  Future<Iterable<M.Flag>> list() async {
+    isListInvoked = true;
+    return _list;
+  }
+
+  FlagsRepositoryMock({Iterable<M.Flag> list: const []})
+    : _list = new List.unmodifiable(list);
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/instance.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/instance.dart
new file mode 100644
index 0000000..21ecf16
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/instance.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+typedef Future<M.Instance> InstanceRepositoryMockCallback(String id);
+
+class InstanceRepositoryMock implements M.InstanceRepository {
+  final InstanceRepositoryMockCallback _get;
+
+  InstanceRepositoryMock({InstanceRepositoryMockCallback getter})
+    : _get = getter;
+
+  Future<M.Instance> get(String id, {int count}){
+    if (_get != null) {
+      return _get(id);
+    }
+    return new Future.value(null);
+  }
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/notification.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/notification.dart
new file mode 100644
index 0000000..f03cd27
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/notification.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class NotificationChangeEventMock implements M.NotificationChangeEvent {
+  final NotificationRepositoryMock repository;
+  const NotificationChangeEventMock({this.repository});
+}
+
+typedef void NotificationRepositoryMockCallback(M.Notification notification);
+
+class NotificationRepositoryMock implements M.NotificationRepository {
+  final StreamController<M.NotificationChangeEvent> _onChange =
+      new StreamController<M.NotificationChangeEvent>.broadcast();
+  Stream<M.NotificationChangeEvent> get onChange => _onChange.stream;
+
+  bool get hasListeners => _onChange.hasListener;
+
+  final Iterable<M.Notification> _list;
+  final NotificationRepositoryMockCallback _add;
+  final NotificationRepositoryMockCallback _delete;
+
+  bool addInvoked = false;
+  bool listInvoked = false;
+  bool deleteInvoked = false;
+  bool deleteAllInvoked = false;
+
+
+  void add(M.Notification notification) {
+    addInvoked = true;
+    if (_add != null) _add(notification);
+  }
+
+  Iterable<M.Notification> list() {
+    listInvoked = true;
+    return _list;
+  }
+
+  void delete(M.Notification notification) {
+    deleteInvoked = true;
+    if (_add != null) _delete(notification);
+  }
+
+  void deleteAll() { deleteAllInvoked = true; }
+
+  void triggerChangeEvent() {
+    _onChange.add(new NotificationChangeEventMock(repository: this));
+  }
+
+  NotificationRepositoryMock({Iterable<M.Notification> list : const [],
+      NotificationRepositoryMockCallback add,
+      NotificationRepositoryMockCallback delete})
+    : _list = list,
+      _add = add,
+      _delete = delete;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart
new file mode 100644
index 0000000..ffbf3bf
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class SampleProfileLoadingProgressEventMock
+    implements M.SampleProfileLoadingProgressEvent {
+  final M.SampleProfileLoadingProgress progress;
+  SampleProfileLoadingProgressEventMock({this.progress});
+}
+
+class SampleProfileLoadingProgressMock
+    implements M.SampleProfileLoadingProgress {
+  final M.SampleProfileLoadingStatus status;
+  final double progress;
+  final Duration fetchingTime;
+  final Duration loadingTime;
+  final M.SampleProfile profile;
+
+  const SampleProfileLoadingProgressMock({
+      this.status: M.SampleProfileLoadingStatus.disabled,
+      this.progress: 0.0,
+      this.fetchingTime: const Duration(),
+      this.loadingTime: const Duration(),
+      this.profile
+    });
+}
+
+typedef Stream<M.SampleProfileLoadingProgressEvent>
+    ClassSampleProfileRepositoryMockCallback(M.ClassRef cls,
+        M.SampleProfileTag tag, bool clear);
+
+class ClassSampleProfileRepositoryMock
+    implements M.ClassSampleProfileRepository {
+  final ClassSampleProfileRepositoryMockCallback _get;
+
+  Stream<M.SampleProfileLoadingProgressEvent> get(M.ClassRef cls,
+      M.SampleProfileTag tag, {bool clear: false}) {
+    if (_get != null) {
+      return _get(cls, tag, clear);
+    }
+    return null;
+  }
+
+  ClassSampleProfileRepositoryMock(
+      {ClassSampleProfileRepositoryMockCallback getter})
+    : _get = getter;
+}
+
+typedef Stream<M.SampleProfileLoadingProgressEvent>
+    IsolateampleProfileRepositoryMockCallback(M.IsolateRef cls,
+        M.SampleProfileTag tag, bool clear, bool forceFetch);
+
+class IsolateSampleProfileRepositoryMock
+    implements M.IsolateSampleProfileRepository {
+  final IsolateampleProfileRepositoryMockCallback _get;
+
+  Stream<M.SampleProfileLoadingProgressEvent> get(M.IsolateRef isolate,
+      M.SampleProfileTag tag, {bool clear: false, bool forceFetch: false}) {
+    if (_get != null) {
+      return _get(isolate, tag, clear, forceFetch);
+    }
+    return null;
+  }
+
+  IsolateSampleProfileRepositoryMock(
+      {IsolateampleProfileRepositoryMockCallback getter})
+    : _get = getter;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
new file mode 100644
index 0000000..78b9610
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+typedef Future<M.Script> ScriptRepositoryMockCallback(String id);
+
+class ScriptRepositoryMock implements M.ScriptRepository {
+  final ScriptRepositoryMockCallback _get;
+
+  ScriptRepositoryMock({ScriptRepositoryMockCallback getter})
+    : _get = getter;
+
+  Future<M.Script> get(String id){
+    if (_get != null) {
+      return _get(id);
+    }
+    return new Future.value(null);
+  }
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/target.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/target.dart
new file mode 100644
index 0000000..1c7f3ed
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/target.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 mocks;
+
+class TargetChangeEventMock implements M.TargetChangeEvent {
+  final TargetRepositoryMock repository;
+  const TargetChangeEventMock({this.repository});
+}
+
+typedef void TargetRepositoryMockStringCallback(String notification);
+typedef void TargetRepositoryMockTargetCallback(M.Target notification);
+
+class TargetRepositoryMock implements M.TargetRepository {
+  final StreamController<M.TargetChangeEvent> _onChange =
+      new StreamController<M.TargetChangeEvent>.broadcast();
+  Stream<M.TargetChangeEvent> get onChange => _onChange.stream;
+
+  bool get hasListeners => _onChange.hasListener;
+
+  final M.Target _current;
+  final Iterable<M.Target> _list;
+  final TargetRepositoryMockStringCallback _add;
+  final TargetRepositoryMockTargetCallback _setCurrent;
+  final TargetRepositoryMockTargetCallback _delete;
+
+  bool currentInvoked = false;
+  bool addInvoked = false;
+  bool listInvoked = false;
+  bool setCurrentInvoked = false;
+  bool deleteInvoked = false;
+
+  M.Target get current {
+    currentInvoked = true;
+    return _current;
+  }
+
+  void add(String val) {
+    addInvoked = true;
+    if (_add != null) _add(val);
+  }
+
+  Iterable<M.Target> list() {
+    listInvoked = true;
+    return _list;
+  }
+
+  void setCurrent(M.Target target) {
+    setCurrentInvoked = true;
+    if (_setCurrent != null) _setCurrent(target);
+  }
+
+  void delete(M.Target target) {
+    deleteInvoked = true;
+    if (_delete != null) _delete(target);
+  }
+
+  void triggerChangeEvent() {
+    _onChange.add(new TargetChangeEventMock(repository: this));
+  }
+
+  TargetRepositoryMock({M.Target current, Iterable<M.Target> list : const [],
+      TargetRepositoryMockStringCallback add,
+      TargetRepositoryMockTargetCallback setCurrent,
+      TargetRepositoryMockTargetCallback delete})
+    : _current = current,
+      _list = list,
+      _add = add,
+      _setCurrent = setCurrent,
+      _delete = delete;
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/bar/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/bar/element_test.dart
new file mode 100644
index 0000000..e450d3e
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/bar/element_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+
+main() {
+  NavBarElement.tag.ensureRegistration();
+
+  test('instantiation', () {
+    final e = new NavBarElement();
+    expect(e, isNotNull, reason: 'element correctly created');
+  });
+  test('elements created', () async {
+    final e = new NavBarElement();
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+    expect(e.shadowRoot.querySelector('content'), isNotNull,
+                                               reason: 'has content elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/bar/element_test.html b/runtime/observatory/tests/observatory_ui/nav/bar/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/bar/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.dart
new file mode 100644
index 0000000..32fb9f0
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/class_menu.dart';
+import '../../mocks.dart';
+
+main() {
+  NavClassMenuElement.tag.ensureRegistration();
+
+  final i_ref = const IsolateRefMock(id: 'i-id', name: 'i-name');
+  final c_ref = const ClassRefMock(id: 'c-id', name: 'c-name');
+  test('instantiation', () {
+    final e = new NavClassMenuElement(i_ref, c_ref);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(i_ref));
+    expect(e.cls, equals(c_ref));
+  });
+  test('elements created after attachment', () async {
+    final e = new NavClassMenuElement(i_ref, c_ref);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.dart
new file mode 100644
index 0000000..3241c45
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import '../../mocks.dart';
+
+main() {
+  NavIsolateMenuElement.tag.ensureRegistration();
+
+  final tag = NavMenuElement.tag.name;
+
+  EventRepositoryMock events;
+  final ref = const IsolateRefMock(id: 'i-id', name: 'old-name');
+  final obj = const IsolateMock(id: 'i-id', name: 'new-name');
+  setUp(() {
+    events = new EventRepositoryMock();
+  });
+  group('instantiation', () {
+    test('IsolateRef', () {
+      final e = new NavIsolateMenuElement(ref, events);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(ref));
+    });
+    test('Isolate', () {
+      final e = new NavIsolateMenuElement(obj, events);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(obj));
+    });
+  });
+  test('elements created after attachment', () async {
+    final e = new NavIsolateMenuElement(ref, events);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+  });
+  group('updates', () {
+    test('are correctly listen', () async {
+      final e = new NavIsolateMenuElement(ref, events);
+      expect(events.onIsolateUpdateHasListener, isFalse);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(events.onIsolateUpdateHasListener, isTrue);
+      e.remove();
+      await e.onRendered.first;
+      expect(events.onIsolateUpdateHasListener, isFalse);
+    });
+    test('have effects', () async {
+      final e = new NavIsolateMenuElement(ref, events);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect((e.shadowRoot.querySelector(tag) as NavMenuElement)
+             .label.contains(ref.name), isTrue);
+      events.add(new IsolateUpdateEventMock(isolate: obj));
+      await e.onRendered.first;
+      expect((e.shadowRoot.querySelector(tag) as NavMenuElement)
+             .label.contains(ref.name), isFalse);
+      expect((e.shadowRoot.querySelector(tag) as NavMenuElement)
+            .label.contains(obj.name), isTrue);
+      e.remove();
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.dart
new file mode 100644
index 0000000..86fecea
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import '../../mocks.dart';
+
+main() {
+  NavLibraryMenuElement.tag.ensureRegistration();
+
+  final i_ref = const IsolateRefMock(id: 'i-id', name: 'i-name');
+  final l_ref = const LibraryRefMock(id: 'l-id', name: 'l-name');
+  test('instantiation', () {
+    final e = new NavLibraryMenuElement(i_ref, l_ref);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(i_ref));
+    expect(e.library, equals(l_ref));
+  });
+  test('elements created after attachment', () async {
+    final e = new NavLibraryMenuElement(i_ref, l_ref);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.dart
new file mode 100644
index 0000000..5ab71f1
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/menu_item.dart';
+
+main() {
+  NavMenuItemElement.tag.ensureRegistration();
+
+  group('instantiation', () {
+    final label = 'custom-label';
+    final link = 'link-to-target';
+    test('label', () {
+      final e = new NavMenuItemElement(label);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.label, equals(label), reason: 'element correctly created');
+    });
+    test('label', () {
+      final e = new NavMenuItemElement(label, link: link);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.link, equals(link), reason: 'element correctly created');
+    });
+  });
+  group('elements', () {
+    test('created', () async {
+      final label = 'custom-label';
+      final e = new NavMenuItemElement(label);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+      expect(e.shadowRoot.querySelector('content'), isNotNull,
+                                                 reason: 'has content elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+    });
+    test('react to label change', () async {
+      final label1 = 'custom-label-1';
+      final label2 = 'custom-label-2';
+      final e = new NavMenuItemElement(label1);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains(label1), isTrue);
+      expect(e.shadowRoot.innerHtml.contains(label2), isFalse);
+      e.label = label2;
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains(label1), isFalse);
+      expect(e.shadowRoot.innerHtml.contains(label2), isTrue);
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('react to link change', () async {
+      final label = 'custom-label';
+      final link1 = 'custom-label-1';
+      final link2 = 'custom-label-2';
+      final e = new NavMenuItemElement(label, link: link1);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains(link1), isTrue);
+      expect(e.shadowRoot.innerHtml.contains(link2), isFalse);
+      e.link = link2;
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains(link1), isFalse);
+      expect(e.shadowRoot.innerHtml.contains(link2), isTrue);
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.html b/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/menu/element_test.dart
new file mode 100644
index 0000000..5b35836
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/menu/element_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+
+main() {
+  NavMenuElement.tag.ensureRegistration();
+
+  group('instantiation', () {
+    final label = 'custom-label';
+    test('label', () {
+      final e = new NavMenuElement(label);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.label, equals(label), reason: 'element correctly created');
+    });
+    test('not last', () {
+      final e = new NavMenuElement(label, last: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.last, isFalse, reason: 'element correctly created');
+    });
+    test('last', () {
+      final e = new NavMenuElement(label, last: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.last, isTrue, reason: 'element correctly created');
+    });
+  });
+  group('elements', () {
+    test('created', () async {
+      final label = 'custom-label';
+      final e = new NavMenuElement(label);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+      expect(e.shadowRoot.querySelector('content'), isNotNull,
+                                                 reason: 'has content elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+    });
+    test('react to label change', () async {
+      final label1 = 'custom-label-1';
+      final label2 = 'custom-label-2';
+      final e = new NavMenuElement(label1);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains(label1), isTrue);
+      expect(e.shadowRoot.innerHtml.contains(label2), isFalse);
+      e.label = label2;
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains(label1), isFalse);
+      expect(e.shadowRoot.innerHtml.contains(label2), isTrue);
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('react to last change', () async {
+      final label = 'custom-label';
+      final e = new NavMenuElement(label, last: false);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains('&gt;'), isTrue);
+      e.last = true;
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains('&gt;'), isFalse);
+      e.last = false;
+      await e.onRendered.first;
+      expect(e.shadowRoot.innerHtml.contains('&gt;'), isTrue);
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/menu/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/menu/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify/element_test.dart
new file mode 100644
index 0000000..cbdebba
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify/element_test.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html' hide Notification, NotificationEvent;
+import 'package:unittest/unittest.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/notify_event.dart';
+import 'package:observatory/src/elements/nav/notify_exception.dart';
+import '../../mocks.dart';
+
+main() {
+  NavNotifyElement.tag.ensureRegistration();
+
+  final evTag = NavNotifyEventElement.tag.name;
+  final exTag = NavNotifyExceptionElement.tag.name;
+
+  const vm = const VMRefMock();
+  const isolate = const IsolateRefMock(id: 'i-id', name: 'i-name');
+
+  group('instantiation', () {
+    NotificationRepositoryMock repository;
+    setUp(() {
+      repository = new NotificationRepositoryMock();
+    });
+    test('default', () {
+      final e = new NavNotifyElement(repository);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.notifyOnPause, isTrue, reason: 'notifyOnPause is default');
+    });
+    test('notify on pause', () {
+      final e = new NavNotifyElement(repository, notifyOnPause: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.notifyOnPause, isTrue, reason: 'notifyOnPause is the same');
+    });
+    test('do not notify on pause', () {
+      final e = new NavNotifyElement(repository, notifyOnPause: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.notifyOnPause, isFalse, reason: 'notifyOnPause is the same');
+    });
+  });
+  test('is correctly listening', () async {
+    final repository = new NotificationRepositoryMock();
+    final e = new NavNotifyElement(repository);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(repository.hasListeners, isTrue, reason: 'is listening');
+    e.remove();
+    await e.onRendered.first;
+    expect(repository.hasListeners, isFalse, reason: 'is no more listening');
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      final repository =
+          new NotificationRepositoryMock(list: [
+            new ExceptionNotificationMock(exception: new Exception("ex")),
+            const EventNotificationMock(event: const VMUpdateEventMock(vm: vm)),
+            const EventNotificationMock(event: const VMUpdateEventMock(vm: vm))
+          ]);
+      final e = new NavNotifyElement(repository);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(repository.listInvoked, isTrue, reason: 'should invoke list()');
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(evTag).length, equals(2));
+      expect(e.querySelectorAll(exTag).length, equals(1));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to notifyOnPause change', () async {
+      final NotificationRepositoryMock repository =
+          new NotificationRepositoryMock(list: [
+            new ExceptionNotificationMock(exception: new Exception("ex")),
+            const EventNotificationMock(event: const VMUpdateEventMock()),
+            const EventNotificationMock(
+                event: const PauseStartEventMock(isolate: isolate))
+          ]);
+      final e = new NavNotifyElement(repository, notifyOnPause: true);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.querySelectorAll(evTag).length, equals(2));
+      expect(e.querySelectorAll(exTag).length, equals(1));
+      e.notifyOnPause = false;
+      await e.onRendered.first;
+      expect(e.querySelectorAll(evTag).length, equals(1));
+      expect(e.querySelectorAll(exTag).length, equals(1));
+      e.notifyOnPause = true;
+      await e.onRendered.first;
+      expect(e.querySelectorAll(evTag).length, equals(2));
+      expect(e.querySelectorAll(exTag).length, equals(1));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to update event', () async {
+      final List<M.Notification> list = [
+        new ExceptionNotificationMock(exception: new Exception("ex")),
+        const EventNotificationMock(event: const VMUpdateEventMock()),
+      ];
+      final repository = new NotificationRepositoryMock(list: list);
+      final e = new NavNotifyElement(repository, notifyOnPause: true);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.querySelectorAll(evTag).length, equals(1));
+      expect(e.querySelectorAll(exTag).length, equals(1));
+      list.add(const EventNotificationMock(
+          event: const PauseStartEventMock(isolate: isolate)));
+      repository.triggerChangeEvent();
+      await e.onRendered.first;
+      expect(e.querySelectorAll(evTag).length, equals(2));
+      expect(e.querySelectorAll(exTag).length, equals(1));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify/element_test.html b/runtime/observatory/tests/observatory_ui/nav/notify/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.dart
new file mode 100644
index 0000000..7c621bb
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/notify_event.dart';
+import '../../mocks.dart';
+
+main() {
+  NavNotifyEventElement.tag.ensureRegistration();
+
+  final event = new PauseStartEventMock(
+              isolate: new IsolateMock(id: 'isolate-id', name: 'isolate-name'));
+  group('instantiation', () {
+    final e = new NavNotifyEventElement(event);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.event, equals(event));
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      final e = new NavNotifyEventElement(event);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+  group('events are fired', () {
+    NavNotifyEventElement e;
+    StreamSubscription sub;
+    setUp(() async {
+      e = new NavNotifyEventElement(event);
+      document.body.append(e);
+      await e.onRendered.first;
+    });
+    tearDown(() {
+      sub.cancel();
+      e.remove();
+    });
+    test('navigation after connect', () async {
+      sub = window.onPopState.listen(expectAsync((_) {}, count: 1,
+        reason: 'event is fired'));
+      e.querySelector('a').click();
+    });
+    test('onDelete events (DOM)', () async {
+      sub = e.onDelete.listen(expectAsync((EventDeleteEvent ev) {
+        expect(ev, isNotNull, reason: 'event is passed');
+        expect(ev.event, equals(event),
+                                            reason: 'exception is the same');
+      }, count: 1, reason: 'event is fired'));
+      e.querySelector('button').click();
+    });
+    test('onDelete events (code)', () async {
+      sub = e.onDelete.listen(expectAsync((EventDeleteEvent ev) {
+        expect(ev, isNotNull, reason: 'event is passed');
+        expect(ev.event, equals(event),
+                                            reason: 'exception is the same');
+      }, count: 1, reason: 'event is fired'));
+      e.delete();
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.html b/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.dart
new file mode 100644
index 0000000..426828d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/notify_exception.dart';
+import '../../mocks.dart';
+
+main() {
+  NavNotifyExceptionElement.tag.ensureRegistration();
+
+  final exception = new ConnectionExceptionMock(message: 'message');
+  test('instantiation', () {
+    final e = new NavNotifyExceptionElement(exception);
+    expect(e, isNotNull, reason: 'element correctly created');
+  });
+  test('elements created after attachment', () async {
+    final e = new NavNotifyExceptionElement(exception);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+  group('events are fired', () {
+    NavNotifyExceptionElement e;
+    StreamSubscription sub;
+    setUp(() async {
+      e = new NavNotifyExceptionElement(exception);
+      document.body.append(e);
+      await e.onRendered.first;
+    });
+    tearDown(() {
+      sub.cancel();
+      e.remove();
+    });
+    test('navigation after connect', () async {
+      sub = window.onPopState.listen(expectAsync((_) {}, count: 1,
+        reason: 'event is fired'));
+      e.querySelector('a').click();
+    });
+    test('onDelete events (DOM)', () async {
+      sub = e.onDelete.listen(expectAsync((ExceptionDeleteEvent event) {
+        expect(event, isNotNull, reason: 'event is passed');
+        expect(event.exception, equals(exception),
+                                              reason: 'exception is the same');
+        expect(event.stacktrace, isNull);
+      }, count: 1, reason: 'event is fired'));
+      e.querySelector('button').click();
+    });
+    test('onDelete events (code)', () async {
+      sub = e.onDelete.listen(expectAsync((ExceptionDeleteEvent event) {
+        expect(event, isNotNull, reason: 'event is passed');
+        expect(event.exception, equals(exception),
+                                              reason: 'exception is the same');
+        expect(event.stacktrace, isNull);
+      }, count: 1, reason: 'event is fired'));
+      e.delete();
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.html b/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.dart
new file mode 100644
index 0000000..e809b82
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/notify_exception.dart';
+
+main() {
+  NavNotifyExceptionElement.tag.ensureRegistration();
+
+  final st = new StackTrace.fromString('stacktrace string');
+  group('normal exception', () {
+    final ex = new Exception('exception message');
+    group('instantiation', () {
+      test('no stacktrace', () {
+        final e = new NavNotifyExceptionElement(ex);
+        expect(e, isNotNull, reason: 'element correctly created');
+        expect(e.exception, equals(ex));
+        expect(e.stacktrace, isNull);
+      });
+      test('with stacktrace', () {
+        final e = new NavNotifyExceptionElement(ex, stacktrace: st);
+        expect(e, isNotNull, reason: 'element correctly created');
+        expect(e.exception, equals(ex));
+        expect(e.stacktrace, equals(st));
+      });
+    });
+    group('elements', () {
+      test('created after attachment (no stacktrace)', () async {
+        final e = new NavNotifyExceptionElement(ex);
+        document.body.append(e);
+        await e.onRendered.first;
+        expect(e.children.length, isNonZero, reason: 'has elements');
+        expect(e.innerHtml.contains(ex.toString()), isTrue);
+        expect(e.innerHtml.contains(st.toString()), isFalse);
+        e.remove();
+        await e.onRendered.first;
+        expect(e.children.length, isZero, reason: 'is empty');
+      });
+      test('created after attachment (with stacktrace)', () async {
+        final e = new NavNotifyExceptionElement(ex, stacktrace: st);
+        document.body.append(e);
+        await e.onRendered.first;
+        expect(e.children.length, isNonZero, reason: 'has elements');
+        expect(e.innerHtml.contains(ex.toString()), isTrue);
+        expect(e.innerHtml.contains(st.toString()), isTrue);
+        e.remove();
+        await e.onRendered.first;
+        expect(e.children.length, isZero, reason: 'is empty');
+      });
+    });
+    group('events are fired', () {
+      NavNotifyExceptionElement e;
+      StreamSubscription sub;
+      setUp(() async {
+        e = new NavNotifyExceptionElement(ex, stacktrace: st);
+        document.body.append(e);
+        await e.onRendered.first;
+      });
+      tearDown(() {
+        sub.cancel();
+        e.remove();
+      });
+      test('navigation after connect', () async {
+        sub = window.onPopState.listen(expectAsync((_) {}, count: 1,
+          reason: 'event is fired'));
+        e.querySelector('a').click();
+      });
+      test('onDelete events (DOM)', () async {
+        sub = e.onDelete.listen(expectAsync((ExceptionDeleteEvent event) {
+          expect(event, isNotNull, reason: 'event is passed');
+          expect(event.exception, equals(ex), reason: 'exception is the same');
+          expect(event.stacktrace, equals(st),
+                                            reason: 'stacktrace is the same');
+        }, count: 1, reason: 'event is fired'));
+        e.querySelector('button').click();
+      });
+      test('onDelete events (code)', () async {
+        sub = e.onDelete.listen(expectAsync((ExceptionDeleteEvent event) {
+          expect(event, isNotNull, reason: 'event is passed');
+          expect(event.exception, equals(ex), reason: 'exception is the same');
+          expect(event.stacktrace, equals(st),
+                                            reason: 'stacktrace is the same');
+        }, count: 1, reason: 'event is fired'));
+        e.delete();
+      });
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.html b/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.dart
new file mode 100644
index 0000000..6752929
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+
+main() {
+  NavRefreshElement.tag.ensureRegistration();
+
+  group('instantiation', () {
+    test('no parameters', () {
+      final e = new NavRefreshElement();
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.label, isNotNull, reason: 'label is set to default');
+      expect(e.disabled, isFalse, reason: 'element correctly created');
+    });
+    test('label', () {
+      final label = 'custom-label';
+      final e = new NavRefreshElement(label: label);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.label, isNotNull, reason: 'label is set');
+      expect(e.label, equals(label), reason: 'label is set to value');
+    });
+    test('not disabled', () {
+      final e = new NavRefreshElement(disabled: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.disabled, isFalse, reason: 'element correctly created');
+    });
+    test('disabled', () {
+      final e = new NavRefreshElement(disabled: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.disabled, isTrue, reason: 'element correctly created');
+    });
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      final e = new NavRefreshElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('contain custom label', () async {
+      final label = 'custom-label';
+      final e = new NavRefreshElement(label: label);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(label), isTrue);
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('react to label change', () async {
+      final label1 = 'custom-label-1';
+      final label2 = 'custom-label-2';
+      final e = new NavRefreshElement(label: label1);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(label1), isTrue);
+      expect(e.innerHtml.contains(label2), isFalse);
+      e.label = label2;
+      await e.onRendered.first;
+      expect(e.innerHtml.contains(label2), isTrue);
+      expect(e.innerHtml.contains(label1), isFalse);
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('react to disabled change', () async {
+      final e = new NavRefreshElement(disabled: false);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.disabled, isFalse);
+      e.disabled = true;
+      await e.onRendered.first;
+      expect(e.disabled, isTrue);
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+  group('event', () {
+    NavRefreshElement e;
+    StreamSubscription sub;
+    setUp(() async {
+      e = new NavRefreshElement();
+      document.body.append(e);
+      await e.onRendered.first;
+    });
+    tearDown(() async {
+      sub.cancel();
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('fires', () async {
+      sub = e.onRefresh.listen(expectAsync((event) {
+        expect(event, isNotNull, reason: 'event passed');
+        expect(event is RefreshEvent, isTrue, reason: 'is the right event');
+        expect(event.element, equals(e), reason: 'is related to the element');
+      }, count: 1));
+      e.refresh();
+    });
+    test('fires on click', () async {
+      sub = e.onRefresh.listen(expectAsync((event) {
+        expect(event, isNotNull, reason: 'event passed');
+        expect(event is RefreshEvent, isTrue, reason: 'is the right event');
+        expect(event.element, equals(e), reason: 'is related to the element');
+      }, count: 1));
+      e.querySelector('button').click();
+    });
+    test('does not fire if disabled', () async {
+      e.disabled = true;
+      sub = e.onRefresh.listen(expectAsync((_) {}, count: 0));
+      e.refresh();
+    });
+    test('does not fires on click if disabled', () async {
+      e.disabled = true;
+      sub = e.onRefresh.listen(expectAsync((_) {}, count: 0));
+      e.querySelector('button').click();
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.html b/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/top-menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/top-menu/element_test.dart
new file mode 100644
index 0000000..8a161b6
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/top-menu/element_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+
+main() {
+  NavTopMenuElement.tag.ensureRegistration();
+
+  final tag = NavMenuElement.tag.name;
+
+  group('instantiation', () {
+    test('default', () {
+      final e = new NavTopMenuElement();
+      expect(e, isNotNull, reason: 'element correctly created');
+    });
+    test('not last', () {
+      final e = new NavTopMenuElement(last: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.last, isFalse, reason: 'element correctly created');
+    });
+    test('last', () {
+      final e = new NavTopMenuElement(last: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.last, isTrue, reason: 'element correctly created');
+    });
+  });
+  group('elements', () {
+    test('created', () async {
+      final e = new NavTopMenuElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+      expect(e.shadowRoot.querySelector('content'), isNotNull,
+                                                 reason: 'has content elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+    });
+    test('react to last change', () async {
+      final e = new NavTopMenuElement(last: false);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect((e.shadowRoot.querySelector(tag) as NavMenuElement).last, isFalse);
+      e.last = true;
+      await e.onRendered.first;
+      expect((e.shadowRoot.querySelector(tag) as NavMenuElement).last, isTrue);
+      e.last = false;
+      await e.onRendered.first;
+      expect((e.shadowRoot.querySelector(tag) as NavMenuElement).last, isFalse);
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/top-menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/top-menu/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/top-menu/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.dart
new file mode 100644
index 0000000..a5596a7
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/menu_item.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import '../../mocks.dart';
+
+main(){
+  NavVMMenuElement.tag.ensureRegistration();
+
+  final mTag = NavMenuElement.tag.name;
+  final miTag = NavMenuItemElement.tag.name;
+
+  EventRepositoryMock events;
+  final vm1 = const VMMock(name: 'vm-name-1', displayName: 'display-name-1',
+      isolates: const [const IsolateRefMock(id: 'i-id-1', name: 'i-name-1')]);
+  final vm2 = const VMMock(name: 'vm-name-2', displayName: 'display-name-2',
+      isolates: const [const IsolateRefMock(id: 'i-id-1', name: 'i-name-1'),
+                       const IsolateRefMock(id: 'i-id-2', name: 'i-name-2')]);
+  setUp(() {
+    events = new EventRepositoryMock();
+  });
+  test('instantiation', () {
+    final e = new NavVMMenuElement(vm1, events);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.vm, equals(vm1));
+  });
+  test('elements created after attachment', () async {
+    final e = new NavVMMenuElement(vm1, events);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.shadowRoot.children.length, isZero, reason: 'is empty');
+  });
+  group('updates', () {
+    test('are correctly listen', () async {
+      final e = new NavVMMenuElement(vm1, events);
+      expect(events.onVMUpdateHasListener, isFalse);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(events.onVMUpdateHasListener, isTrue);
+      e.remove();
+      await e.onRendered.first;
+      expect(events.onVMUpdateHasListener, isFalse);
+    });
+    test('have effects', () async {
+      final e = new NavVMMenuElement(vm1, events);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect((e.shadowRoot.querySelector(mTag) as NavMenuElement).label,
+          equals(vm1.displayName));
+      expect(e.shadowRoot.querySelectorAll(miTag).length,
+          equals(vm1.isolates.length));
+      events.add(new VMUpdateEventMock(vm: vm2));
+      await e.onRendered.first;
+      expect((e.shadowRoot.querySelector(mTag) as NavMenuElement).label,
+          equals(vm2.displayName));
+      expect(e.shadowRoot.querySelectorAll(miTag).length,
+          equals(vm2.isolates.length));
+      e.remove();
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.dart
new file mode 100644
index 0000000..f38ab9f
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/objectpool_ref.dart';
+import '../mocks.dart';
+
+main() {
+  ObjectPoolRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const pool = const ObjectPoolRefMock();
+  test('instantiation', () {
+    final e = new ObjectPoolRefElement(isolate, pool);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.pool, equals(pool));
+  });
+  test('elements created after attachment', () async {
+    final e = new ObjectPoolRefElement(isolate, pool);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.html b/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/observatory_ui.status b/runtime/observatory/tests/observatory_ui/observatory_ui.status
index 4d08c8a..f1cbd44 100644
--- a/runtime/observatory/tests/observatory_ui/observatory_ui.status
+++ b/runtime/observatory/tests/observatory_ui/observatory_ui.status
@@ -2,5 +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.
 
-[ $browser == false ]
+[ $browser == false || $runtime == drt ]
 *: SkipByDesign
+
+[ $runtime == dartium ]
+isolate/*: Skip
+allocation_profile: Skip
diff --git a/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.dart
new file mode 100644
index 0000000..ec10960
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/sentinel_value.dart';
+import '../mocks.dart';
+
+main() {
+  SentinelValueElement.tag.ensureRegistration();
+
+  const sentinel = const Sentinel();
+  test('instantiation', () {
+    final e = new SentinelValueElement(sentinel);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.sentinel, equals(sentinel));
+  });
+  test('elements created after attachment', () async {
+    final e = new SentinelValueElement(sentinel);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.text, isNotEmpty, reason: 'has text');
+    expect(e.title, isNotEmpty, reason: 'has title');
+    e.remove();
+    await e.onRendered.first;
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.html b/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.dart b/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.dart
new file mode 100644
index 0000000..aa82df1
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/sample_buffer_control.dart';
+import '../mocks.dart';
+
+main() {
+  SampleBufferControlElement.tag.ensureRegistration();
+
+  group('instantiation', () {
+    SampleProfileLoadingProgressMock progress;
+    StreamController<SampleProfileLoadingProgressEventMock> events;
+    setUp(() {
+      progress = new SampleProfileLoadingProgressMock();
+      events = new StreamController<SampleProfileLoadingProgressEventMock>();
+    });
+    test('no additional parameters', () {
+      final e = new SampleBufferControlElement(progress, events.stream);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.progress, equals(progress));
+      expect(e.selectedTag, equals(M.SampleProfileTag.none));
+      expect(e.showTag, isTrue);
+    });
+    test('selected tag', () {
+      const tag = M.SampleProfileTag.userOnly;
+      final e = new SampleBufferControlElement(progress, events.stream,
+          selectedTag: tag);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.progress, equals(progress));
+      expect(e.selectedTag, equals(tag));
+      expect(e.showTag, isTrue);
+    });
+    test('show tag (true)', () {
+      final e = new SampleBufferControlElement(progress, events.stream,
+          showTag: true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.progress, equals(progress));
+      expect(e.selectedTag, equals(M.SampleProfileTag.none));
+      expect(e.showTag, isTrue);
+    });
+    test('show tag (false)', () {
+      final e = new SampleBufferControlElement(progress, events.stream,
+          showTag: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.progress, equals(progress));
+      expect(e.selectedTag, equals(M.SampleProfileTag.none));
+      expect(e.showTag, isFalse);
+    });
+  });
+  group('elements', () {
+    SampleProfileLoadingProgressMock progress;
+    StreamController<SampleProfileLoadingProgressEventMock> events;
+    setUp(() {
+      progress = new SampleProfileLoadingProgressMock();
+      events = new StreamController<SampleProfileLoadingProgressEventMock>();
+    });
+    test('created after attachment', () async {
+      final e = new SampleBufferControlElement(progress, events.stream);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero,
+        reason: 'is empty');
+    });
+    test('listen for status changes', () async {
+      final e = new SampleBufferControlElement(progress, events.stream);
+      expect(events.hasListener, isFalse);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(events.hasListener, isTrue);
+      events.add(new SampleProfileLoadingProgressEventMock(progress: progress));
+      events.close();
+      await e.onRendered.first;
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('follow updates changes', () async {
+      final e = new SampleBufferControlElement(progress, events.stream);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNull);
+      events.add(new SampleProfileLoadingProgressEventMock(
+        progress: new SampleProfileLoadingProgressMock(
+          status: M.SampleProfileLoadingStatus.fetching
+      )));
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNull);
+      events.add(new SampleProfileLoadingProgressEventMock(
+        progress: new SampleProfileLoadingProgressMock(
+          status: M.SampleProfileLoadingStatus.loading
+      )));
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNull);
+      events.add(new SampleProfileLoadingProgressEventMock(
+        progress: new SampleProfileLoadingProgressMock(
+          status: M.SampleProfileLoadingStatus.loaded,
+          profile: new SampleProfileMock()
+      )));
+      events.close();
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNotNull);
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('follow updates changes (no tag)', () async {
+      final e = new SampleBufferControlElement(progress, events.stream,
+        showTag: false);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNull);
+      events.add(new SampleProfileLoadingProgressEventMock(
+        progress: new SampleProfileLoadingProgressMock(
+          status: M.SampleProfileLoadingStatus.fetching
+      )));
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNull);
+      events.add(new SampleProfileLoadingProgressEventMock(
+        progress: new SampleProfileLoadingProgressMock(
+          status: M.SampleProfileLoadingStatus.loading
+      )));
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNull);
+      events.add(new SampleProfileLoadingProgressEventMock(
+        progress: new SampleProfileLoadingProgressMock(
+          status: M.SampleProfileLoadingStatus.loaded,
+          profile: new SampleProfileMock()
+      )));
+      await e.onRendered.first;
+      expect(e.querySelector('select'), isNull);
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+  group('events', () {
+    SampleProfileLoadingProgressMock progress;
+    StreamController<SampleProfileLoadingProgressEventMock> events;
+    setUp(() {
+      progress = new SampleProfileLoadingProgressMock();
+      events = new StreamController<SampleProfileLoadingProgressEventMock>();
+    });
+    test('onModeChange', () async {
+      final e = new SampleBufferControlElement(progress, events.stream);
+      document.body.append(e);
+      await e.onRendered.first;
+      events.add(new SampleProfileLoadingProgressEventMock(
+        progress: new SampleProfileLoadingProgressMock(
+          status: M.SampleProfileLoadingStatus.loaded,
+          profile: new SampleProfileMock()
+      )));
+      await e.onRendered.first;
+      expect(e.selectedTag, equals(M.SampleProfileTag.none));
+      e.onTagChange.listen(expectAsync((_) {
+        expect(e.selectedTag, equals(M.SampleProfileTag.userOnly));
+      }, count: 1));
+      final select = (e.querySelector('.tag-select') as SelectElement);
+      select.selectedIndex = select.options.indexOf(
+          (select.options.toSet()
+            ..removeAll(select.selectedOptions)).toList().first
+        );
+      select.dispatchEvent(new Event("change"));
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.html b/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/script_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/script_ref/element_test.dart
new file mode 100644
index 0000000..b6c6e93
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/script_ref/element_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/script_ref.dart';
+import '../mocks.dart';
+
+main() {
+  ScriptRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock(id: 'isolate-id');
+  const file = 'filename.dart';
+  const ref = const ScriptRefMock(id: 'script-id', uri: 'package/$file');
+  group('instantiation', () {
+    test('no position', () {
+      final e = new ScriptRefElement(isolate, ref);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.isolate, equals(isolate));
+      expect(e.script, equals(ref));
+    });
+  });
+  test('elements created after attachment', () async {
+    final e = new ScriptRefElement(isolate, ref);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.innerHtml.contains(isolate.id), isTrue,
+      reason: 'no message in the component');
+    expect(e.innerHtml.contains(file), isTrue,
+      reason: 'no message in the component');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero,
+      reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/script_ref/element_test.html b/runtime/observatory/tests/observatory_ui/script_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/script_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.dart b/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.dart
new file mode 100644
index 0000000..304adbc
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/pc_descriptors_ref.dart';
+import '../mocks.dart';
+
+main() {
+  PcDescriptorsRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const descriptors = const PcDescriptorsRefMock();
+  test('instantiation', () {
+    final e = new PcDescriptorsRefElement(isolate, descriptors);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.descriptors, equals(descriptors));
+  });
+  test('elements created after attachment', () async {
+    final e = new PcDescriptorsRefElement(isolate, descriptors);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.html b/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/source_link/element_test.dart b/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
new file mode 100644
index 0000000..bd096b8
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/source_link.dart';
+import '../mocks.dart';
+
+main() {
+  SourceLinkElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock(id: 'isolate-id');
+  const script_id = 'script-id';
+  const file = 'filename.dart';
+  final script = new ScriptMock(id: script_id, uri: 'package/$file',
+      tokenToLine: (int token) => 1, tokenToCol: (int token) => 2);
+  final location = new SourceLocationMock(script: script, tokenPos: 0,
+      endTokenPos: 1);
+  test('instantiation', () {
+    final e = new SourceLinkElement(isolate, location,
+        new ScriptRepositoryMock());
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.location, equals(location));
+  });
+  test('elements created after attachment', () async {
+    bool rendered = false;
+    final e = new SourceLinkElement(isolate, location,
+        new ScriptRepositoryMock(getter: expectAsync((String id) async {
+          expect(rendered, isFalse);
+          expect(id, equals(script_id));
+          return script;
+        }, count: 1)));
+    document.body.append(e);
+    await e.onRendered.first;
+    rendered = true;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.innerHtml.contains(isolate.id), isTrue,
+      reason: 'no message in the component');
+    expect(e.innerHtml.contains(file), isTrue,
+      reason: 'no message in the component');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero,
+      reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/source_link/element_test.html b/runtime/observatory/tests/observatory_ui/source_link/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/source_link/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.dart b/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.dart
new file mode 100644
index 0000000..f8c0f00
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/stack_trace_tree_config.dart';
+
+main() {
+  StackTraceTreeConfigElement.tag.ensureRegistration();
+
+  group('instantiation', () {
+    test('default', () {
+      final e = new StackTraceTreeConfigElement();
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.showMode, isTrue);
+      expect(e.showDirection, isTrue);
+      expect(e.showFilter, isTrue);
+      expect(e.filter, equals(''));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('showMode', () {
+      final e = new StackTraceTreeConfigElement(showMode: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.showMode, isFalse);
+      expect(e.showDirection, isTrue);
+      expect(e.showFilter, isTrue);
+      expect(e.filter, equals(''));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('showDirection', () {
+      final e = new StackTraceTreeConfigElement(showDirection: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.showMode, isTrue);
+      expect(e.showDirection, isFalse);
+      expect(e.showFilter, isTrue);
+      expect(e.filter, equals(''));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('showFilter', () {
+      final e = new StackTraceTreeConfigElement(showFilter: false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.showMode, isTrue);
+      expect(e.showDirection, isTrue);
+      expect(e.showFilter, isFalse);
+      expect(e.filter, equals(''));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('filter', () {
+      final filter = 'filter-string';
+      final e = new StackTraceTreeConfigElement(filter: filter);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.showMode, isTrue);
+      expect(e.showDirection, isTrue);
+      expect(e.showFilter, isTrue);
+      expect(e.filter, equals(filter));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('mode', () {
+      final e = new StackTraceTreeConfigElement(mode: ProfileTreeMode.code);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.showMode, isTrue);
+      expect(e.showDirection, isTrue);
+      expect(e.showFilter, isTrue);
+      expect(e.filter, equals(''));
+      expect(e.mode, equals(ProfileTreeMode.code));
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+    });
+    test('default', () {
+      final e = new StackTraceTreeConfigElement(
+          direction: M.ProfileTreeDirection.inclusive);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.showMode, isTrue);
+      expect(e.showDirection, isTrue);
+      expect(e.showFilter, isTrue);
+      expect(e.filter, equals(''));
+      expect(e.mode, equals(ProfileTreeMode.function));
+      expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
+    });
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      final e = new StackTraceTreeConfigElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to mode change', () async {
+      final e = new StackTraceTreeConfigElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.mode, equals(ProfileTreeMode.function));
+      e.mode = ProfileTreeMode.code;
+      await e.onRendered.first;
+      expect(e.mode, equals(ProfileTreeMode.code));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to direction change', () async {
+      final e = new StackTraceTreeConfigElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+      e.direction = M.ProfileTreeDirection.inclusive;
+      await e.onRendered.first;
+      expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to filter change', () async {
+      final filter = 'filter-string';
+      final e = new StackTraceTreeConfigElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.filter, equals(''));
+      e.filter = filter;
+      await e.onRendered.first;
+      expect(e.filter, equals(filter));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+  group('events', () {
+    test('onModeChange', () async {
+      final e = new StackTraceTreeConfigElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.mode, equals(ProfileTreeMode.function));
+      e.onModeChange.listen(expectAsync((_) {
+        expect(e.mode, equals(ProfileTreeMode.code));
+      }, count: 1));
+      final select = (e.querySelector('.mode-select') as SelectElement);
+      select.selectedIndex = select.options.indexOf(
+          (select.options.toSet()
+            ..removeAll(select.selectedOptions)).toList().first
+        );
+      select.dispatchEvent(new Event("change"));
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('onDirectionChange', () async {
+      final e = new StackTraceTreeConfigElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+      e.onDirectionChange.listen(expectAsync((_) {
+        expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
+      }, count: 1));
+      final select = (e.querySelector('.direction-select') as SelectElement);
+      select.selectedIndex = select.options.indexOf(
+          (select.options.toSet()
+            ..removeAll(select.selectedOptions)).toList().first
+        );
+      select.dispatchEvent(new Event("change"));
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('onFilterChange', () async {
+      final e = new StackTraceTreeConfigElement();
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
+      e.onFilterChange.listen(expectAsync((_) {
+        expect(e.filter, equals('value'));
+      }, count: 1));
+      var input = (e.querySelector('input') as TextInputElement);
+      input.value = 'value';
+      input.dispatchEvent(new Event("change"));
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.html b/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/token_stream_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/token_stream_ref/element_test.dart
new file mode 100644
index 0000000..16c22fd
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/token_stream_ref/element_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/token_stream_ref.dart';
+import '../mocks.dart';
+
+main() {
+  TokenStreamRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const token = const TokenStreamRefMock();
+  const token_named = const TokenStreamRefMock(name: 'name');
+  test('instantiation', () {
+    final e = new TokenStreamRefElement(isolate, token);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.token, equals(token));
+  });
+  group('elements', () {
+    test('created after attachment (no name)', () async {
+      final e = new TokenStreamRefElement(isolate, token);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('created after attachment (name)', () async {
+      final e = new TokenStreamRefElement(isolate, token_named);
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.innerHtml.contains(token_named.name), isTrue);
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/token_stream_ref/element_test.html b/runtime/observatory/tests/observatory_ui/token_stream_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/token_stream_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.dart
new file mode 100644
index 0000000..f966374
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/unknown_ref.dart';
+import '../mocks.dart';
+
+main() {
+  UnknownObjectRefElement.tag.ensureRegistration();
+
+  const isolate = const IsolateRefMock();
+  const obj = const UnknownObjectRefMock();
+  test('instantiation', () {
+    final e = new UnknownObjectRefElement(isolate, obj);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.obj, equals(obj));
+  });
+  test('elements created after attachment', () async {
+    final e = new UnknownObjectRefElement(isolate, obj);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.html b/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/view_footer/element_test.dart b/runtime/observatory/tests/observatory_ui/view_footer/element_test.dart
new file mode 100644
index 0000000..77cb4cc
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/view_footer/element_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/view_footer.dart';
+
+main() {
+  ViewFooterElement.tag.ensureRegistration();
+
+  test('instantiation', () {
+    final e = new ViewFooterElement();
+    expect(e, isNotNull, reason: 'element correctly created');
+  });
+  test('elements created', () async {
+    final e = new ViewFooterElement();
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/view_footer/element_test.html b/runtime/observatory/tests/observatory_ui/view_footer/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/view_footer/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
new file mode 100644
index 0000000..84026e5
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/vm_connect_target.dart';
+import 'package:observatory/src/elements/vm_connect.dart';
+import '../mocks.dart';
+
+void load(_) {}
+
+main() {
+  VMConnectElement.tag.ensureRegistration();
+
+  final nTag = NavNotifyElement.tag.name;
+  final tTag = VMConnectTargetElement.tag.name;
+
+  group('instantiation', () {
+    test('default', () {
+      final e = new VMConnectElement(new TargetRepositoryMock(),
+          load, new NotificationRepositoryMock());
+      expect(e, isNotNull, reason: 'element correctly created');
+    });
+  });
+  test('is correctly listening', () async {
+    final targets = new TargetRepositoryMock();
+    final e = new VMConnectElement(targets, load,
+        new NotificationRepositoryMock());
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(targets.hasListeners, isTrue, reason: 'is listening');
+    e.remove();
+    await e.onRendered.first;
+    expect(targets.hasListeners, isFalse, reason: 'is no more listening');
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      final targets = new TargetRepositoryMock(list: const [
+          const TargetMock(name: 't-1'), const TargetMock(name: 't-2'),
+          ]);
+      final e = new VMConnectElement(targets, load,
+          new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(targets.listInvoked, isTrue, reason: 'should invoke list()');
+      expect(targets.currentInvoked, isTrue, reason: 'should invoke current');
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(nTag).length, equals(1));
+      expect(e.querySelectorAll(tTag).length, equals(2));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to update event', () async {
+      final list = <TargetMock>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list);
+      final e = new VMConnectElement(targets, load,
+          new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.querySelectorAll(tTag).length, equals(1));
+      list.add(const TargetMock(name: 't-2'));
+      targets.triggerChangeEvent();
+      await e.onRendered.first;
+      expect(e.querySelectorAll(tTag).length, equals(2));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+  group('invokes', () {
+    test('add on click', () async {
+      final address = 'ws://host:1234';
+      final list = <TargetMock>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list,
+          add: expectAsync((String val) {
+            expect(val, equals(address));
+          }, count: 1, reason: 'should be invoked'));
+      final e = new VMConnectElement(targets, load,
+          new NotificationRepositoryMock(), address: address);
+      document.body.append(e);
+      await e.onRendered.first;
+      (e.querySelector('button.vm_connect') as ButtonElement).click();
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('connect', () async {
+      final list = <TargetMock>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list,
+          setCurrent: expectAsync((TargetMock t) {
+            expect(t, equals(list[0]));
+          }, count: 1, reason: 'should be invoked'));
+      final e = new VMConnectElement(targets, load,
+          new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      (e.querySelector(tTag) as VMConnectTargetElement).connect();
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('delete', () async {
+      final list = <TargetMock>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list,
+          delete: expectAsync((TargetMock t) {
+            expect(t, equals(list[0]));
+          }, count: 1, reason: 'should be invoked'));
+      final e = new VMConnectElement(targets, load,
+          new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      (e.querySelector(tTag) as VMConnectTargetElement).delete();
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.dart b/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.dart
new file mode 100644
index 0000000..b4011f9
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/vm_connect_target.dart';
+import '../mocks.dart';
+
+main() {
+  VMConnectTargetElement.tag.ensureRegistration();
+
+  TargetMock t;
+  setUp(() {
+    t = new TargetMock(name: "a network address");
+  });
+  group('instantiation', () {
+    test('no other parameters', () {
+      final e = new VMConnectTargetElement(t);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.target, t, reason: 'target not setted');
+      expect(e.current, isFalse, reason: 'default to not current');
+    });
+    test('isCurrent: false', () {
+      final e = new VMConnectTargetElement(t, current:false);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.target, t, reason: 'target not setted');
+      expect(e.current, isFalse, reason: 'default to not current');
+    });
+    test('isCurrent: true', () {
+      final e = new VMConnectTargetElement(t, current:true);
+      expect(e, isNotNull, reason: 'element correctly created');
+      expect(e.target, t, reason: 'target not setted');
+      expect(e.current, isTrue, reason: 'default to not current');
+    });
+  });
+  test('elements created after attachment', () async {
+    final e = new VMConnectTargetElement(t);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+  group('events are fired', () {
+    VMConnectTargetElement e;
+    setUp(() async {
+      e = new VMConnectTargetElement(t);
+      document.body.append(e);
+      await e.onRendered.first;
+    });
+    tearDown(() async {
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('onConnect events (DOM)', () async {
+      e.onConnect.listen(expectAsync((TargetEvent event) {
+        expect(event, isNotNull, reason: 'event is passed');
+        expect(event.target, t, reason: 'target is the same');
+      }, count: 1, reason: 'event is fired'));
+      e.querySelector('a').click();
+    });
+    test('onConnect events (code)', () async {
+      e.onConnect.listen(expectAsync((TargetEvent event) {
+        expect(event, isNotNull, reason: 'event is passed');
+        expect(event.target, t, reason: 'target is the same');
+      }, count: 1, reason: 'event is fired'));
+      e.connect();
+    });
+    test('onRemove events (DOM)', () async {
+      e.onDelete.listen(expectAsync((TargetEvent event) {
+        expect(event, isNotNull, reason: 'event is passed');
+        expect(event.target, t, reason: 'target is the same');
+      }, count: 1, reason: 'event is fired'));
+      e.querySelector('button').click();
+    });
+    test('onRemove events (code)', () async {
+      e.onDelete.listen(expectAsync((TargetEvent event) {
+        expect(event, isNotNull, reason: 'event is passed');
+        expect(event.target, t, reason: 'target is the same');
+      }, count: 1, reason: 'event is fired'));
+      e.delete();
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.html b/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/service/breakpoint_two_args_checked_test.dart b/runtime/observatory/tests/service/breakpoint_two_args_checked_test.dart
new file mode 100644
index 0000000..610af92
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_two_args_checked_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override  --verbose_debug
+
+// This test is mostly interesting for DBC, which needs to patch two bytecodes
+// to create a breakpoint for fast Smi ops.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+import 'dart:developer';
+
+const int LINE_A = 26;
+const int LINE_B = 27;
+const int LINE_C = 28;
+
+class NotGeneric { }
+
+testeeMain() {
+  var x = new List(1);
+  var y = 7;
+  debugger();
+  print("Statement");
+  x[0] = 3;         // Line A.
+  x is NotGeneric;  // Line B.
+  y & 4;            // Line C.
+}
+
+var tests = [
+
+hasStoppedAtBreakpoint,
+
+// Add breakpoints.
+(Isolate isolate) async {
+  var rootLib = await isolate.rootLibrary.load();
+  var script = rootLib.scripts[0];
+
+  var bpt1 = await isolate.addBreakpoint(script, LINE_A);
+  print(bpt1);
+  expect(bpt1.resolved, isTrue);
+  expect(await bpt1.location.getLine(), equals(LINE_A));
+
+  var bpt2 = await isolate.addBreakpoint(script, LINE_B);
+  print(bpt2);
+  expect(bpt2.resolved, isTrue);
+  expect(await bpt2.location.getLine(), equals(LINE_B));
+
+  var bpt3 = await isolate.addBreakpoint(script, LINE_C);
+  print(bpt3);
+  expect(bpt3.resolved, isTrue);
+  expect(await bpt3.location.getLine(), equals(LINE_C));
+},
+
+resumeIsolate,
+
+hasStoppedAtBreakpoint,
+stoppedAtLine(LINE_A),
+resumeIsolate,
+
+hasStoppedAtBreakpoint,
+stoppedAtLine(LINE_B),
+resumeIsolate,
+
+hasStoppedAtBreakpoint,
+stoppedAtLine(LINE_C),
+resumeIsolate,
+
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testeeMain);
diff --git a/runtime/observatory/tests/service/capture_stdio_test.dart b/runtime/observatory/tests/service/capture_stdio_test.dart
index 279d055..294de12 100644
--- a/runtime/observatory/tests/service/capture_stdio_test.dart
+++ b/runtime/observatory/tests/service/capture_stdio_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=--compile-all --error_on_bad_type --error_on_bad_override
+// VMOptions=--compile_all --error_on_bad_type --error_on_bad_override
 
 import 'dart:async';
 import 'dart:developer';
diff --git a/runtime/observatory/tests/service/debugger_inspect_test.dart b/runtime/observatory/tests/service/debugger_inspect_test.dart
index 1f7fe31..269a123 100644
--- a/runtime/observatory/tests/service/debugger_inspect_test.dart
+++ b/runtime/observatory/tests/service/debugger_inspect_test.dart
@@ -26,7 +26,7 @@
   var subscription;
   subscription = stream.listen((ServiceEvent event) {
     if (event.kind == ServiceEvent.kInspect) {
-      expect((event.inspectee as Instance).clazz.name, equals('Point'));
+      expect(event.inspectee.clazz.name, equals('Point'));
       subscription.cancel();
       completer.complete();
     }
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
new file mode 100644
index 0000000..c5639a8
--- /dev/null
+++ b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+Future<String> readResponse(HttpClientResponse response) {
+  var completer = new Completer();
+  var contents = new StringBuffer();
+  response.transform(UTF8.decoder).listen((String data) {
+    contents.write(data);
+  }, onDone: () => completer.complete(contents.toString()));
+  return completer.future;
+}
+
+
+var tests = [
+  // Write a file with the ? character in the filename.
+  (VM vm) async {
+    var fsId = 'test';
+    var filePath = '/foo/bar.dat';
+    var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
+    var fileContentsBase64 = BASE64.encode(fileContents);
+
+    var result;
+    // Create DevFS.
+    result = await vm.invokeRpcNoUpgrade('_createDevFS', { 'fsName': fsId });
+    expect(result['type'], equals('FileSystem'));
+    expect(result['name'], equals(fsId));
+    expect(result['uri'], new isInstanceOf<String>());
+
+    // Write the file by issuing an HTTP PUT.
+    HttpClient client = new HttpClient();
+    HttpClientRequest request =
+        await client.putUrl(Uri.parse(serviceHttpAddress));
+    request.headers.add('dev_fs_name', fsId);
+    request.headers.add('dev_fs_path', filePath);
+    request.add(GZIP.encode([9]));
+    HttpClientResponse response = await request.close();
+    String responseBody = await readResponse(response);
+    result = JSON.decode(responseBody);
+    expect(result['result']['type'], equals('Success'));
+
+    // Trigger an error by issuing an HTTP PUT.
+    request = await client.putUrl(Uri.parse(serviceHttpAddress));
+    request.headers.add('dev_fs_name', fsId);
+    // omit the 'dev_fs_path' parameter.
+    request.write(GZIP.encode(fileContents));
+    response = await request.close();
+    responseBody = await readResponse(response);
+    result = JSON.decode(responseBody);
+    Map error = result['error']['data'];
+    expect(error, isNotNull);
+    expect(error['details'].contains("expects the 'path' parameter"), isTrue);
+
+    // Write the file again but this time with the true file contents.
+    client = new HttpClient();
+    request =
+        await client.putUrl(Uri.parse(serviceHttpAddress));
+    request.headers.add('dev_fs_name', fsId);
+    request.headers.add('dev_fs_path', filePath);
+    request.add(GZIP.encode(fileContents));
+    response = await request.close();
+    responseBody = await readResponse(response);
+    result = JSON.decode(responseBody);
+    expect(result['result']['type'], equals('Success'));
+
+    // Close the HTTP client.
+    client.close();
+
+    // Read the file back.
+    result = await vm.invokeRpcNoUpgrade('_readDevFSFile', {
+        'fsName': fsId,
+        'path': filePath,
+    });
+    expect(result['type'], equals('FSFile'));
+    expect(result['fileContents'], equals(fileContentsBase64));
+
+    // List all the files in the file system.
+    result = await vm.invokeRpcNoUpgrade('_listDevFSFiles', {
+        'fsName': fsId,
+    });
+    expect(result['type'], equals('FSFileList'));
+    expect(result['files'].length, equals(1));
+    expect(result['files'][0]['name'], equals(filePath));
+
+    // Delete DevFS.
+    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
+        'fsName': fsId,
+    });
+    expect(result['type'], equals('Success'));
+  },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/dev_fs_spawn_test.dart b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
new file mode 100644
index 0000000..ae8f482
--- /dev/null
+++ b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
@@ -0,0 +1,220 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 'dart:async';
+import 'dart:convert';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+var tests = [
+  (VM vm) async {
+    // Create a new fs.
+    var fsName = 'scratch';
+    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
+        'fsName': fsName,
+      });
+    expect(result['type'], equals('FileSystem'));
+    expect(result['name'], equals('scratch'));
+    expect(result['uri'], new isInstanceOf<String>());
+    var fsUri = result['uri'];
+
+    // Spawn a script with a bad uri and make sure that the error is
+    // delivered asynchronously.
+    Completer completer = new Completer();
+    var sub;
+    sub = await vm.listenEventStream(
+      VM.kIsolateStream,
+      (ServiceEvent event) {
+        if (event.kind == ServiceEvent.kIsolateSpawn) {
+          expect(event.spawnToken, equals('someSpawnToken'));
+          expect(event.spawnError, startsWith(
+              'IsolateSpawnException: Unable to spawn isolate: '));
+          expect(event.isolate, isNull);
+          completer.complete();
+          sub.cancel();
+        }
+      });
+
+    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
+        'token': 'someSpawnToken',
+        'uri': '${fsUri}doesnotexist.dart',
+    });
+    expect(result['type'], equals('Success'));
+    await completer.future;
+
+    // Delete the fs.
+    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
+        'fsName': fsName,
+    });
+    expect(result['type'], equals('Success'));
+  },
+
+  (VM vm) async {
+    // Create a new fs.
+    var fsName = 'scratch';
+    var result = await vm.invokeRpcNoUpgrade('_createDevFS', {
+        'fsName': fsName,
+      });
+    expect(result['type'], equals('FileSystem'));
+    expect(result['name'], equals('scratch'));
+    expect(result['uri'], new isInstanceOf<String>());
+    var fsUri = result['uri'];
+
+    var filePaths = [
+        'devfs_file0.dart',
+        'devfs_file1.dart',
+        'devfs_file2.dart'
+    ];
+    var scripts = [
+'''
+import 'dart:developer';
+proofOfLife() => 'I live!';
+main() {
+  print('HELLO WORLD 1');
+  debugger();
+}
+''',
+'''
+import 'dart:developer';
+var globalArgs;
+proofOfLife() => 'I live, \${globalArgs}!';
+main(args) {
+  globalArgs = args;
+  print('HELLO WORLD 2');
+  debugger();
+}
+''',
+'''
+import 'dart:developer';
+var globalArgs;
+var globalMsg;
+proofOfLife() => 'I live, \${globalArgs}, \${globalMsg}!';
+main(args, msg) {
+  globalArgs = args;
+  globalMsg = msg;
+  print('HELLO WORLD 3');
+  debugger();
+}
+''',
+    ];
+
+    // Write three scripts to the fs.
+    for (int i = 0; i < 3; i++) {
+      var fileContents = BASE64.encode(UTF8.encode(scripts[i]));
+      result = await vm.invokeRpcNoUpgrade('_writeDevFSFile', {
+        'fsName': fsName,
+        'path': filePaths[i],
+        'fileContents': fileContents
+      });
+      expect(result['type'], equals('Success'));
+    }
+
+    // Spawn the script with no arguments or message and make sure
+    // that we are notified.
+    Completer completer = new Completer();
+    var sub;
+    sub = await vm.listenEventStream(
+      VM.kIsolateStream,
+      (ServiceEvent event) {
+        if (event.kind == ServiceEvent.kIsolateSpawn) {
+          expect(event.spawnToken, equals('mySpawnToken0'));
+          expect(event.isolate, isNotNull);
+          expect(event.isolate.name, equals('devfs_file0.dart\$main'));
+          completer.complete(event.isolate);
+          sub.cancel();
+        }
+      });
+    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
+        'token': 'mySpawnToken0',
+        'uri': '${fsUri}${filePaths[0]}',
+    });
+    expect(result['type'], equals('Success'));
+    var spawnedIsolate = await completer.future;
+
+    // Wait for the spawned isolate to hit a breakpoint.
+    await spawnedIsolate.load();
+    await hasStoppedAtBreakpoint(spawnedIsolate);
+
+    // Make sure that we are running code from the spawned isolate.
+    result = await spawnedIsolate.rootLibrary.evaluate('proofOfLife()');
+    expect(result.type, equals('Instance'));
+    expect(result.kind, equals(M.InstanceKind.string));
+    expect(result.valueAsString, equals('I live!'));
+
+    // Spawn the script with arguments.
+    completer = new Completer();
+    sub = await vm.listenEventStream(
+      VM.kIsolateStream,
+      (ServiceEvent event) {
+        if (event.kind == ServiceEvent.kIsolateSpawn) {
+          expect(event.spawnToken, equals('mySpawnToken1'));
+          expect(event.isolate, isNotNull);
+          expect(event.isolate.name, equals('devfs_file1.dart\$main'));
+          completer.complete(event.isolate);
+          sub.cancel();
+        }
+      });
+    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
+        'token': 'mySpawnToken1',
+        'uri': '${fsUri}${filePaths[1]}',
+        'args': ['one', 'two', 'three']
+    });
+    expect(result['type'], equals('Success'));
+    spawnedIsolate = await completer.future;
+
+    // Wait for the spawned isolate to hit a breakpoint.
+    await spawnedIsolate.load();
+    await hasStoppedAtBreakpoint(spawnedIsolate);
+
+    // Make sure that we are running code from the spawned isolate.
+    result = await spawnedIsolate.rootLibrary.evaluate('proofOfLife()');
+    expect(result.type, equals('Instance'));
+    expect(result.kind, equals(M.InstanceKind.string));
+    expect(result.valueAsString, equals('I live, [one, two, three]!'));
+
+    // Spawn the script with arguments and message
+    completer = new Completer();
+    sub = await vm.listenEventStream(
+      VM.kIsolateStream,
+      (ServiceEvent event) {
+        if (event.kind == ServiceEvent.kIsolateSpawn) {
+          expect(event.spawnToken, equals('mySpawnToken2'));
+          expect(event.isolate, isNotNull);
+          expect(event.isolate.name, equals('devfs_file2.dart\$main'));
+          completer.complete(event.isolate);
+          sub.cancel();
+        }
+      });
+    result = await vm.invokeRpcNoUpgrade('_spawnUri', {
+        'token': 'mySpawnToken2',
+        'uri': '${fsUri}${filePaths[2]}',
+        'args': ['A', 'B', 'C'],
+        'message': 'test'
+    });
+    expect(result['type'], equals('Success'));
+    spawnedIsolate = await completer.future;
+
+    // Wait for the spawned isolate to hit a breakpoint.
+    await spawnedIsolate.load();
+    await hasStoppedAtBreakpoint(spawnedIsolate);
+
+    // Make sure that we are running code from the spawned isolate.
+    result = await spawnedIsolate.rootLibrary.evaluate('proofOfLife()');
+    expect(result.type, equals('Instance'));
+    expect(result.kind, equals(M.InstanceKind.string));
+    expect(result.valueAsString, equals('I live, [A, B, C], test!'));
+
+    // Delete the fs.
+    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
+        'fsName': fsName,
+    });
+    expect(result['type'], equals('Success'));
+  },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/dev_fs_test.dart b/runtime/observatory/tests/service/dev_fs_test.dart
index 08e5a5e..5b2930d 100644
--- a/runtime/observatory/tests/service/dev_fs_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_test.dart
@@ -58,7 +58,7 @@
 
   (VM vm) async {
     var fsId = 'banana';
-    var filePath = '/foobar.dat';
+    var filePath = '/foo/bar.dat';
     var fileContents = BASE64.encode(UTF8.encode('fileContents'));
 
     var result;
diff --git a/runtime/observatory/tests/service/dev_fs_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
new file mode 100644
index 0000000..9ee2412
--- /dev/null
+++ b/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 'dart:convert';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+var tests = [
+  // Write a file with the ? character in the filename.
+  (VM vm) async {
+    var fsId = 'test';
+    var filePath = '/foo/bar?dat';
+    var fileContents = BASE64.encode(UTF8.encode('fileContents'));
+
+    var result;
+    // Create DevFS.
+    result = await vm.invokeRpcNoUpgrade('_createDevFS', { 'fsName': fsId });
+    expect(result['type'], equals('FileSystem'));
+    expect(result['name'], equals(fsId));
+    expect(result['uri'], new isInstanceOf<String>());
+
+    // Write the file.
+    result = await vm.invokeRpcNoUpgrade('_writeDevFSFile', {
+        'fsName': fsId,
+        'path': filePath,
+        'fileContents': fileContents
+    });
+    expect(result['type'], equals('Success'));
+
+    // Read the file back.
+    result = await vm.invokeRpcNoUpgrade('_readDevFSFile', {
+        'fsName': fsId,
+        'path': filePath,
+    });
+    expect(result['type'], equals('FSFile'));
+    expect(result['fileContents'], equals(fileContents));
+
+    // List all the files in the file system.
+    result = await vm.invokeRpcNoUpgrade('_listDevFSFiles', {
+        'fsName': fsId,
+    });
+    expect(result['type'], equals('FSFileList'));
+    expect(result['files'].length, equals(1));
+    expect(result['files'][0]['name'], equals('/foo/bar?dat'));
+
+    // Delete DevFS.
+    result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
+        'fsName': fsId,
+    });
+    expect(result['type'], equals('Success'));
+  },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/eval_internal_class_test.dart b/runtime/observatory/tests/service/eval_internal_class_test.dart
new file mode 100644
index 0000000..1b08482
--- /dev/null
+++ b/runtime/observatory/tests/service/eval_internal_class_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 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+var tests = [
+
+(Isolate isolate) async {
+  Library root = await isolate.rootLibrary.load();
+
+  Class classLibrary = await root.clazz.load();
+  print(classLibrary);
+  var result = await classLibrary.evaluate('3 + 4');
+  print(result);
+  expect(result is DartError, isTrue);
+  expect(result.message, contains('Cannot evaluate'));
+
+  Class classClass = await classLibrary.clazz.load();
+  print(classClass);
+  result = await classClass.evaluate('3 + 4');
+  print(result);
+  expect(result is DartError, isTrue);
+  expect(result.message, contains('Cannot evaluate'));
+
+  var someArray = await root.evaluate("new List(2)");
+  print(someArray);
+  expect(someArray is Instance, isTrue);
+  Class classArray = await someArray.clazz.load();
+  print(classArray);
+  result = await classArray.evaluate('3 + 4');
+  print(result);
+  expect(result is Instance, isTrue);
+  expect(result.valueAsString, equals('7'));
+},
+
+];
+
+main(args) => runIsolateTests(args, tests);
diff --git a/runtime/observatory/tests/service/get_allocation_profile_rpc_test.dart b/runtime/observatory/tests/service/get_allocation_profile_rpc_test.dart
index 7db64c9..2af7ffe 100644
--- a/runtime/observatory/tests/service/get_allocation_profile_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_allocation_profile_rpc_test.dart
@@ -3,11 +3,19 @@
 // BSD-style license that can be found in the LICENSE file.
 // VMOptions=--error_on_bad_type --error_on_bad_override
 
+import 'dart:async';
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 
 import 'test_helper.dart';
 
+Future sleep(int milliseconds) {
+  Completer completer = new Completer();
+  Duration duration = new Duration(milliseconds: milliseconds);
+  new Timer(duration, () => completer.complete() );
+  return completer.future;
+}
+
 var tests = [
   (Isolate isolate) async {
     var params = {
@@ -15,10 +23,8 @@
     var result = await isolate.invokeRpcNoUpgrade(
         '_getAllocationProfile', params);
     expect(result['type'], equals('AllocationProfile'));
-    var lastReset = result['dateLastAccumulatorReset'];
-    expect(lastReset, new isInstanceOf<String>());
-    var lastGC = result['dateLastServiceGC'];
-    expect(lastGC, new isInstanceOf<String>());
+    expect(result.containsKey('dateLastAccumulatorReset'), isFalse);
+    expect(result.containsKey('dateLastServiceGC'), isFalse);
     expect(result['heaps'].length, isPositive);
     expect(result['heaps']['new']['type'], equals('HeapSpace'));
     expect(result['heaps']['old']['type'], equals('HeapSpace'));
@@ -31,29 +37,41 @@
     };
     result = await isolate.invokeRpcNoUpgrade('_getAllocationProfile', params);
     expect(result['type'], equals('AllocationProfile'));
-    var newReset = result['dateLastAccumulatorReset'];
-    expect(newReset, isNot(equals(lastReset)));
-    expect(result['dateLastServiceGC'], equals(lastGC));
+    var firstReset = result['dateLastAccumulatorReset'];
+    expect(firstReset, new isInstanceOf<String>());
+    expect(result.containsKey('dateLastServiceGC'), isFalse);
     expect(result['heaps'].length, isPositive);
     expect(result['heaps']['new']['type'], equals('HeapSpace'));
     expect(result['heaps']['old']['type'], equals('HeapSpace'));
     expect(result['members'].length, isPositive);
     expect(result['members'][0]['type'], equals('ClassHeapStats'));
 
+    await sleep(10);
+
+    result = await isolate.invokeRpcNoUpgrade('_getAllocationProfile', params);
+    var secondReset = result['dateLastAccumulatorReset'];
+    expect(secondReset, isNot(equals(firstReset)));
+
     // gc.
     params = {
       'gc' : 'full',
     };
     result = await isolate.invokeRpcNoUpgrade('_getAllocationProfile', params);
     expect(result['type'], equals('AllocationProfile'));
-    expect(result['dateLastAccumulatorReset'], equals(newReset));
-    var newGC = result['dateLastServiceGCt'];
-    expect(newGC, isNot(equals(lastGC)));
+    expect(result['dateLastAccumulatorReset'], equals(secondReset));
+    var firstGC = result['dateLastServiceGC'];
+    expect(firstGC, new isInstanceOf<String>());
     expect(result['heaps'].length, isPositive);
     expect(result['heaps']['new']['type'], equals('HeapSpace'));
     expect(result['heaps']['old']['type'], equals('HeapSpace'));
     expect(result['members'].length, isPositive);
     expect(result['members'][0]['type'], equals('ClassHeapStats'));
+
+    await sleep(10);
+
+    result = await isolate.invokeRpcNoUpgrade('_getAllocationProfile', params);
+    var secondGC = result['dateLastAccumulatorReset'];
+    expect(secondGC, isNot(equals(firstGC)));
   },
 
   (Isolate isolate) async {
diff --git a/runtime/observatory/tests/service/get_allocation_samples_test.dart b/runtime/observatory/tests/service/get_allocation_samples_test.dart
index 85626ee..d26c75f 100644
--- a/runtime/observatory/tests/service/get_allocation_samples_test.dart
+++ b/runtime/observatory/tests/service/get_allocation_samples_test.dart
@@ -4,6 +4,7 @@
 // VMOptions=--error_on_bad_type --error_on_bad_override
 
 import 'dart:developer';
+import 'package:observatory/models.dart' as M;
 import 'package:observatory/service_io.dart';
 import 'package:observatory/cpu_profile.dart';
 import 'package:unittest/unittest.dart';
@@ -61,10 +62,10 @@
     await fooClass.reload();
     expect(fooClass.traceAllocations, isFalse);
     CpuProfile cpuProfile = new CpuProfile();
-    cpuProfile.load(isolate, profileResponse);
+    await cpuProfile.load(isolate, profileResponse);
     cpuProfile.buildCodeCallerAndCallees();
     cpuProfile.buildFunctionCallerAndCallees();
-    var tree = cpuProfile.loadCodeTree('exclusive');
+    var tree = cpuProfile.loadCodeTree(M.ProfileTreeDirection.exclusive);
     var node = tree.root;
     var expected =
         ['Root', 'DRT_AllocateObject', 'test', 'test', '_Closure.call'];
diff --git a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
index 74e98c9..c2b7fc1 100644
--- a/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_retaining_path_rpc_test.dart
@@ -9,25 +9,27 @@
 import 'test_helper.dart';
 
 class _TestClass {
-  _TestClass(this.x, this.y);
+  _TestClass();
   var x;
   var y;
 }
 
-var target1;
-var target2;
-var target3;
-var globalObject;
-var globalList;
+var target1 = new _TestClass();
+var target2 = new _TestClass();
+var target3 = new _TestClass();
+var target4 = new _TestClass();
+var target5 = new _TestClass();
+var globalObject = new _TestClass();
+var globalList = new List(100);
+var globalMap1 = new Map();
+var globalMap2 = new Map();
 
 void warmup() {
-  target1 = new _TestClass(null, null);
-  target2 = new _TestClass(null, null);
-  globalObject = new _TestClass(target1, target2);
-
-  target3 = new _TestClass(null, null);
-  globalList = new List(100);
+  globalObject.x = target1;
+  globalObject.y = target2;
   globalList[12] = target3;
+  globalMap1['key'] = target4;
+  globalMap2[target5] = 'value';
 }
 
 eval(Isolate isolate, String expression) async {
@@ -44,9 +46,10 @@
     var obj = await eval(isolate, 'globalObject');
     var params = {
       'targetId': obj['id'],
-      'limit': 4,
+      'limit': 100,
     };
     var result = await isolate.invokeRpcNoUpgrade('_getRetainingPath', params);
+    expect(result['elements'].length, equals(2));
     expect(result['elements'][1]['value']['name'], equals('globalObject'));
   },
 
@@ -74,10 +77,11 @@
         isolate, '() { var tmp = target1; target1 = null; return tmp;} ()');
     var params = {
       'targetId': target1['id'],
-      'limit': 4,
+      'limit': 100,
     };
     var result = await isolate.invokeRpcNoUpgrade('_getRetainingPath', params);
     expect(result['type'], equals('RetainingPath'));
+    expect(result['elements'].length, equals(3));
     expect(result['elements'][1]['parentField']['name'], equals('x'));
     expect(result['elements'][2]['value']['name'], equals('globalObject'));
   },
@@ -87,10 +91,11 @@
         isolate, '() { var tmp = target2; target2 = null; return tmp;} ()');
     var params = {
       'targetId': target2['id'],
-      'limit': 4,
+      'limit': 100,
     };
     var result = await isolate.invokeRpcNoUpgrade('_getRetainingPath', params);
     expect(result['type'], equals('RetainingPath'));
+    expect(result['elements'].length, equals(3));
     expect(result['elements'][1]['parentField']['name'], equals('y'));
     expect(result['elements'][2]['value']['name'], equals('globalObject'));
   },
@@ -100,13 +105,44 @@
         isolate, '() { var tmp = target3; target3 = null; return tmp;} ()');
     var params = {
       'targetId': target3['id'],
-      'limit': 4,
+      'limit': 100,
     };
     var result = await isolate.invokeRpcNoUpgrade('_getRetainingPath', params);
     expect(result['type'], equals('RetainingPath'));
+    expect(result['elements'].length, equals(3));
     expect(result['elements'][1]['parentListIndex'], equals(12));
     expect(result['elements'][2]['value']['name'], equals('globalList'));
   },
+
+  (Isolate isolate) async {
+    var target4 = await eval(
+        isolate, '() { var tmp = target4; target4 = null; return tmp;} ()');
+    var params = {
+      'targetId': target4['id'],
+      'limit': 100,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('_getRetainingPath', params);
+    expect(result['type'], equals('RetainingPath'));
+    expect(result['elements'].length, equals(3));
+    expect(result['elements'][1]['parentMapKey']['valueAsString'],
+        equals('key'));
+    expect(result['elements'][2]['value']['name'], equals('globalMap1'));
+  },
+
+  (Isolate isolate) async {
+    var target5 = await eval(
+        isolate, '() { var tmp = target5; target5 = null; return tmp;} ()');
+    var params = {
+      'targetId': target5['id'],
+      'limit': 100,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('_getRetainingPath', params);
+    expect(result['type'], equals('RetainingPath'));
+    expect(result['elements'].length, equals(3));
+    expect(result['elements'][1]['parentMapKey']['class']['name'],
+      equals('_TestClass'));
+    expect(result['elements'][2]['value']['name'], equals('globalMap2'));
+  }
 ];
 
 main(args) async => runIsolateTests(args, tests, testeeBefore:warmup);
diff --git a/runtime/observatory/tests/service/regexp_function_test.dart b/runtime/observatory/tests/service/regexp_function_test.dart
new file mode 100644
index 0000000..4736266
--- /dev/null
+++ b/runtime/observatory/tests/service/regexp_function_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.
+// VMOptions=
+// VMOptions=--interpret_irregexp
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+var regex0;
+var regex;
+
+void script() {
+  // Check the internal NUL doesn't trip up the name scrubbing in the vm.
+  regex0 = new RegExp("with internal \u{0} NUL");
+  regex = new RegExp(r"(\w+)");
+  String str = "Parse my string";
+  Iterable<Match> matches = regex.allMatches(str);  // Run to generate bytecode.
+  expect(matches.length, equals(3));
+}
+
+var tests = [
+
+(Isolate isolate) async {
+  Library lib = isolate.rootLibrary;
+  await lib.load();
+
+  Field field0 = lib.variables.singleWhere((v) => v.name == 'regex0');
+  await field0.load();  // No crash due to embedded NUL.
+
+  Field field = lib.variables.singleWhere((v) => v.name == 'regex');
+  await field.load();
+  Instance regex = field.staticValue;
+  expect(regex.isInstance, isTrue);
+  expect(regex.isRegExp, isTrue);
+  await regex.load();
+
+  if (regex.oneByteFunction == null) {
+    // Running with interpreted regexp.
+    var b1 = await regex.oneByteBytecode.load();
+    expect(b1.isTypedData, isTrue);
+    var b2 = await regex.twoByteBytecode.load();
+    expect(b2.isTypedData, isFalse);  // No two-byte string subject was used.
+  } else {
+    // Running with compiled regexp.
+    var f1 = await regex.oneByteFunction.load();
+    expect(f1 is ServiceFunction, isTrue);
+    var f2 = await regex.twoByteFunction.load();
+    expect(f2 is ServiceFunction, isTrue);
+    var f3 = await regex.externalOneByteFunction.load();
+    expect(f3 is ServiceFunction, isTrue);
+    var f4 = await regex.externalTwoByteFunction.load();
+    expect(f4 is ServiceFunction, isTrue);
+  }
+}
+
+];
+
+main(args) => runIsolateTests(args, tests, testeeBefore: script);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index b18b6ce..8e9cc6c 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -14,7 +14,7 @@
 isolate_lifecycle_test: Pass, RuntimeError # Issue 24174
 
 # Disable on simulators.
-[ $arch == simarm || $arch == simmips || $arch == simarm64]
+[ $arch == simarm || $arch == simmips || $arch == simarm64 ]
 *: SkipSlow
 
 # All tests use dart:io
@@ -51,22 +51,13 @@
 evaluate_activation_in_method_class_test: CompileTimeError # Issue 24478
 
 [ $arch == simdbc || $arch == simdbc64 ]
-# TODO(vegorov) re-enable when debugger, coverage and profiling is completely
-# fixed for SIMDBC.
-*: Skip
+get_allocation_samples_test: RuntimeError # Profiling unimplemented.
+get_cpu_profile_timeline_rpc_test: RuntimeError # Profiling unimplemented.
+implicit_getter_setter_test: RuntimeError # Field guards unimplemented.
 
-[ $hot_reload ]
-add_breakpoint_rpc_test: Pass, Timeout, Fail, Crash
-code_test: Fail, Crash
-debugger_location_test: Timeout, Fail, Crash
-debugging_inlined_finally_test: Pass, Timeout, Fail, Crash
-dominator_tree_test: Timeout, Crash
-eval_test: Timeout, Fail, Crash
-evaluate_in_frame_rpc_test: Timeout, Fail, Crash
-get_cpu_profile_timeline_rpc_test: Pass, Timeout, Crash
-get_heap_map_rpc_test: Pass, Timeout, Fail, Crash
-get_vm_timeline_rpc_test: Timeout, Fail, Crash
-graph_test: Pass, Timeout, Fail, Crash
-smart_next_test: Pass, Timeout, Fail, Crash
-step_over_await_test: Pass, Timeout, Fail, Crash
-vm_timeline_events_test: Timeout, Fail, Crash
+[ $hot_reload || $hot_reload_rollback ]
+# Skip all service tests because random reloads interfere.
+*: SkipByDesign # The service tests should run without being reloaded.
+
+[ $system == windows ]
+dev_fs_weird_char_test: Skip # Windows disallows question mark in paths
\ No newline at end of file
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 0e8b6e9..4828557 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -102,10 +102,6 @@
     assert(trace_service != null);
     assert(trace_compiler != null);
 
-    // TODO(turnidge): I have temporarily turned on service tracing for
-    // all tests to help diagnose flaky tests.
-    trace_service = true;
-
     if (_shouldLaunchSkyShell()) {
       return _spawnSkyProcess(pause_on_start,
                               pause_on_exit,
@@ -195,8 +191,11 @@
   }
 
   Future<Process> _spawnCommon(String executable, List<String> arguments) {
-    print('** Launching $executable ${arguments.join(' ')}');
-    return Process.start(executable, arguments, environment: _TESTEE_SPAWN_ENV);
+    var environment = _TESTEE_SPAWN_ENV;
+    var bashEnvironment = new StringBuffer();
+    environment.forEach((k, v) => bashEnvironment.write("$k=$v "));
+    print('** Launching $bashEnvironment$executable ${arguments.join(' ')}');
+    return Process.start(executable, arguments, environment: environment);
   }
 
   Future<int> launch(bool pause_on_start,
@@ -255,6 +254,67 @@
   }
 }
 
+// A tester runner that doesn't spawn a process but instead connects to
+// an already running flutter application running on a device. Assumes
+// port 8100. This is only useful for debugging.
+class _FlutterDeviceServiceTesterRunner {
+  void run({List<String> mainArgs,
+            List<VMTest> vmTests,
+            List<IsolateTest> isolateTests,
+            bool pause_on_start: false,
+            bool pause_on_exit: false,
+            bool trace_service: false,
+            bool trace_compiler: false,
+            bool verbose_vm: false,
+            bool pause_on_unhandled_exceptions: false}) {
+    var port = 8100;
+    serviceWebsocketAddress = 'ws://localhost:$port/ws';
+    serviceHttpAddress = 'http://localhost:$port';
+    var name = Platform.script.pathSegments.last;
+    runZoned(() async {
+      var vm =
+          new WebSocketVM(new WebSocketVMTarget(serviceWebsocketAddress));
+      print('Loading VM...');
+      await vm.load();
+      print('Done loading VM');
+
+      // Run vm tests.
+      if (vmTests != null) {
+        var testIndex = 1;
+        var totalTests = vmTests.length;
+        for (var test in vmTests) {
+          vm.verbose = verbose_vm;
+          print('Running $name [$testIndex/$totalTests]');
+          testIndex++;
+          await test(vm);
+        }
+      }
+
+      // Run isolate tests.
+      if (isolateTests != null) {
+        var isolate = await vm.isolates.first.load();
+        var testIndex = 1;
+        var totalTests = isolateTests.length;
+        for (var test in isolateTests) {
+          vm.verbose = verbose_vm;
+          print('Running $name [$testIndex/$totalTests]');
+          testIndex++;
+          await test(isolate);
+        }
+      }
+    }, onError: (e, st) {
+        if (!_isWebSocketDisconnect(e)) {
+          print('Unexpected exception in service tests: $e $st');
+          throw e;
+        }
+    });
+  }
+}
+
+void suppressWarning() {
+  new _FlutterDeviceServiceTesterRunner();
+}
+
 class _ServiceTesterRunner {
   void run({List<String> mainArgs,
             List<VMTest> vmTests,
@@ -270,7 +330,10 @@
                    pause_on_unhandled_exceptions,
                    trace_service, trace_compiler).then((port) async {
       if (mainArgs.contains("--gdb")) {
-        port = 8181;
+        var pid = process.process.pid;
+        var wait = new Duration(seconds: 10);
+        print("Testee has pid $pid, waiting $wait before continuing");
+        sleep(wait);
       }
       serviceWebsocketAddress = 'ws://localhost:$port/ws';
       serviceHttpAddress = 'http://localhost:$port';
diff --git a/runtime/observatory/tests/service/vm_restart_test.dart b/runtime/observatory/tests/service/vm_restart_test.dart
index 605e7bf..6168313 100644
--- a/runtime/observatory/tests/service/vm_restart_test.dart
+++ b/runtime/observatory/tests/service/vm_restart_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=--compile-all --error_on_bad_type --error_on_bad_override
+// VMOptions=--compile_all --error_on_bad_type --error_on_bad_override
 
 import 'dart:async';
 import 'dart:developer';
diff --git a/runtime/observatory/web/index.html b/runtime/observatory/web/index.html
index d318cf7..ccd9bfc 100644
--- a/runtime/observatory/web/index.html
+++ b/runtime/observatory/web/index.html
@@ -4,12 +4,13 @@
   <meta charset="utf-8">
   <title>Dart VM Observatory</title>
   <link rel="import" href="packages/polymer/polymer.html">
+  <link rel="stylesheet" href="packages/charted/charts/themes/quantum_theme.css">
   <link rel="stylesheet" href="packages/observatory/src/elements/css/shared.css">
   <link rel="import" href="packages/observatory/elements.html">
+  <script src="packages/js_util/dist/js_util.js"></script>
   <script type="application/dart" src="main.dart"></script>
   <script src="packages/browser/dart.js"></script>
 </head>
 <body style="height: 100%">
-  <observatory-application></observatory-application>
 </body>
 </html>
diff --git a/runtime/observatory/web/main.dart b/runtime/observatory/web/main.dart
index 238bf97..36c03ab 100644
--- a/runtime/observatory/web/main.dart
+++ b/runtime/observatory/web/main.dart
@@ -2,10 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:html';
 import 'package:logging/logging.dart';
 import 'package:polymer/polymer.dart';
+import 'package:observatory/elements.dart';
 
-main() {
+main() async {
   Logger.root.level = Level.INFO;
   Logger.root.onRecord.listen((LogRecord rec) {
       if (rec.level == Level.WARNING &&
@@ -17,13 +19,12 @@
       }
       print('${rec.level.name}: ${rec.time}: ${rec.message}');
   });
+  await initElements();
   Logger.root.info('Starting Observatory');
-  initPolymer().then((zone) {
-    Logger.root.info('Polymer initialized');
-    // Code here is in the polymer Zone, which ensures that
-    // @observable properties work correctly.
-    Polymer.onReady.then((_) {
-      Logger.root.info('Polymer elements have been upgraded');
-    });
-  });
+  await initPolymer();
+  Logger.root.info('Polymer initialized');
+  await Polymer.onReady;
+  Logger.root.info('Polymer elements have been upgraded');
+  document.body.children
+      .insert(0, document.createElement('observatory-application'));
 }
diff --git a/runtime/platform/assert.cc b/runtime/platform/assert.cc
index c5b91e7..921a564 100644
--- a/runtime/platform/assert.cc
+++ b/runtime/platform/assert.cc
@@ -6,6 +6,7 @@
 
 #include "platform/globals.h"
 #include "vm/os.h"
+#include "vm/profiler.h"
 
 namespace dart {
 
@@ -34,16 +35,14 @@
             arguments);
   va_end(arguments);
 
-  // Print the buffer on stderr.
-  fprintf(stderr, "%s\n", buffer);
-  fflush(stderr);
+  // Print the buffer on stderr and/or syslog.
+  OS::PrintErr("%s\n", buffer);
 
   // In case of failed assertions, abort right away. Otherwise, wait
   // until the program is exiting before producing a non-zero exit
   // code through abort.
-  // TODO(5411324): replace std::abort with OS::Abort so that we can handle
-  // restoring of signal handlers before aborting.
   if (kind_ == ASSERT) {
+    NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /* native_stack_trace */));
     OS::Abort();
   }
   static bool failed = false;
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 5e3b011..3a3ed26 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -113,6 +113,9 @@
 // Windows, both 32- and 64-bit, regardless of the check for _WIN32.
 #define TARGET_OS_WINDOWS 1
 
+#elif defined(__Fuchsia__)
+#define TARGET_OS_FUCHSIA
+
 #elif !defined(TARGET_OS_FUCHSIA)
 #error Automatic target os detection failed.
 #endif
diff --git a/runtime/platform/hashmap.cc b/runtime/platform/hashmap.cc
index 693367f..34f7ea1 100644
--- a/runtime/platform/hashmap.cc
+++ b/runtime/platform/hashmap.cc
@@ -15,7 +15,7 @@
 
 
 HashMap::~HashMap() {
-  free(map_);
+  delete[] map_;
 }
 
 
@@ -106,14 +106,19 @@
 
   // Clear the candidate which will not break searching the hash table.
   candidate->key = NULL;
+  candidate->value = NULL;
   occupancy_--;
 }
 
 
-void HashMap::Clear() {
+void HashMap::Clear(ClearFun clear) {
   // Mark all entries as empty.
   const Entry* end = map_end();
   for (Entry* p = map_; p < end; p++) {
+    if ((clear != NULL) && (p->key != NULL)) {
+      clear(p->value);
+    }
+    p->value = NULL;
     p->key = NULL;
   }
   occupancy_ = 0;
@@ -159,14 +164,14 @@
 
 void HashMap::Initialize(uint32_t capacity) {
   ASSERT(dart::Utils::IsPowerOfTwo(capacity));
-  map_ = reinterpret_cast<Entry*>(malloc(capacity * sizeof(Entry)));
+  map_ = new Entry[capacity];
   if (map_ == NULL) {
     // TODO(sgjesse): Handle out of memory.
     FATAL("Cannot allocate memory for hashmap");
     return;
   }
   capacity_ = capacity;
-  Clear();
+  occupancy_ = 0;
 }
 
 
@@ -186,7 +191,7 @@
   }
 
   // Delete old map.
-  free(map);
+  delete[] map;
 }
 
 }  // namespace dart
diff --git a/runtime/platform/hashmap.h b/runtime/platform/hashmap.h
index d5a0293..185c75f 100644
--- a/runtime/platform/hashmap.h
+++ b/runtime/platform/hashmap.h
@@ -13,6 +13,14 @@
  public:
   typedef bool (*MatchFun) (void* key1, void* key2);
 
+  typedef void (*ClearFun) (void* value);
+
+  // initial_capacity is the size of the initial hash map;
+  // it must be a power of 2 (and thus must not be 0).
+  HashMap(MatchFun match, uint32_t initial_capacity);
+
+  ~HashMap();
+
   static bool SamePointerValue(void* key1, void* key2) {
     return key1 == key2;
   }
@@ -37,17 +45,11 @@
                   reinterpret_cast<char*>(key2)) == 0;
   }
 
-
-  // initial_capacity is the size of the initial hash map;
-  // it must be a power of 2 (and thus must not be 0).
-  HashMap(MatchFun match, uint32_t initial_capacity);
-
-  ~HashMap();
-
   // HashMap entries are (key, value, hash) triplets.
   // Some clients may not need to use the value slot
   // (e.g. implementers of sets, where the key is the value).
   struct Entry {
+    Entry() : key(NULL), value(NULL), hash(0) {}
     void* key;
     void* value;
     uint32_t hash;  // The full hash value for key.
@@ -63,8 +65,12 @@
   // Removes the entry with matching key.
   void Remove(void* key, uint32_t hash);
 
-  // Empties the hash map (occupancy() == 0).
-  void Clear();
+  // Empties the hash map (occupancy() == 0), and calls the function 'clear' on
+  // each of the values if given.
+  void Clear(ClearFun clear = NULL);
+
+  // The number of entries stored in the table.
+  intptr_t size() const { return occupancy_; }
 
   // The capacity of the table. The implementation
   // makes sure that occupancy is at most 80% of
@@ -94,6 +100,7 @@
   void Resize();
 
   friend class IntSet;  // From hashmap_test.cc
+  DISALLOW_COPY_AND_ASSIGN(HashMap);
 };
 
 }  // namespace dart
diff --git a/runtime/platform/text_buffer.cc b/runtime/platform/text_buffer.cc
index 9cbb577..5b4cc05 100644
--- a/runtime/platform/text_buffer.cc
+++ b/runtime/platform/text_buffer.cc
@@ -57,6 +57,7 @@
   buf_[msg_len_] = '\0';
 }
 
+
 intptr_t TextBuffer::Printf(const char* format, ...) {
   va_list args;
   va_start(args, format);
@@ -79,6 +80,7 @@
   return len;
 }
 
+
 // Write a UTF-32 code unit so it can be read by a JSON parser in a string
 // literal. Use official encoding from JSON specification. http://json.org/
 void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
@@ -119,6 +121,7 @@
   }
 }
 
+
 // Write an incomplete UTF-16 code unit so it can be read by a JSON parser in a
 // string literal.
 void TextBuffer::EscapeAndAddUTF16CodeUnit(uint16_t codeunit) {
diff --git a/runtime/platform/utils_fuchsia.h b/runtime/platform/utils_fuchsia.h
index 7054225..4e8c4e9 100644
--- a/runtime/platform/utils_fuchsia.h
+++ b/runtime/platform/utils_fuchsia.h
@@ -5,61 +5,65 @@
 #ifndef PLATFORM_UTILS_FUCHSIA_H_
 #define PLATFORM_UTILS_FUCHSIA_H_
 
-#include "platform/assert.h"
+#include <endian.h>
 
 namespace dart {
 
 inline int Utils::CountLeadingZeros(uword x) {
-  UNIMPLEMENTED();
-  return 0;
+#if defined(ARCH_IS_32_BIT)
+  return __builtin_clzl(x);
+#elif defined(ARCH_IS_64_BIT)
+  return __builtin_clzll(x);
+#else
+#error Architecture is not 32-bit or 64-bit.
+#endif
 }
 
 
 inline int Utils::CountTrailingZeros(uword x) {
-  UNIMPLEMENTED();
-  return 0;
+#if defined(ARCH_IS_32_BIT)
+  return __builtin_ctzl(x);
+#elif defined(ARCH_IS_64_BIT)
+  return __builtin_ctzll(x);
+#else
+#error Architecture is not 32-bit or 64-bit.
+#endif
 }
 
 
 inline uint16_t Utils::HostToBigEndian16(uint16_t value) {
-  UNIMPLEMENTED();
-  return 0;
+  return htobe16(value);
 }
 
 
 inline uint32_t Utils::HostToBigEndian32(uint32_t value) {
-  UNIMPLEMENTED();
-  return 0;
+  return htobe32(value);
 }
 
 
 inline uint64_t Utils::HostToBigEndian64(uint64_t value) {
-  UNIMPLEMENTED();
-  return 0;
+  return htobe64(value);
 }
 
 
 inline uint16_t Utils::HostToLittleEndian16(uint16_t value) {
-  UNIMPLEMENTED();
-  return 0;
+  return htole16(value);
 }
 
 
 inline uint32_t Utils::HostToLittleEndian32(uint32_t value) {
-  UNIMPLEMENTED();
-  return 0;
+  return htole32(value);
 }
 
 
 inline uint64_t Utils::HostToLittleEndian64(uint64_t value) {
-  UNIMPLEMENTED();
-  return 0;
+  return htole64(value);
 }
 
 
 inline char* Utils::StrError(int err, char* buffer, size_t bufsize) {
-  UNIMPLEMENTED();
-  return NULL;
+  snprintf(buffer, bufsize, "errno = %d", err);
+  return buffer;
 }
 
 }  // namespace dart
diff --git a/runtime/tests/vm/dart/double_materialize_test.dart b/runtime/tests/vm/dart/double_materialize_test.dart
new file mode 100644
index 0000000..2cab01c
--- /dev/null
+++ b/runtime/tests/vm/dart/double_materialize_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization_counter_threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+double f(double x, double five, dynamic y) {
+  double z = x + five;
+  var a = y + 5;
+  return z + a.toDouble();
+}
+
+void main() {
+  double x = 1.0;
+  for (int i = 0; i < 1000; i++) {
+    x = f(x, 5.0, i);
+  }
+  x = f(x, 5.0, 1.0);
+  Expect.equals(509512.0, x);
+}
+
diff --git a/runtime/tests/vm/dart/double_to_smi_test.dart b/runtime/tests/vm/dart/double_to_smi_test.dart
new file mode 100644
index 0000000..06d6139
--- /dev/null
+++ b/runtime/tests/vm/dart/double_to_smi_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization_counter_threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+int convert(dynamic d) {
+  return d.toInt();
+}
+
+main() {
+  double x = -100.0;
+  int count = 0;
+  while (x < 100.0) {
+    count = count + convert(x);
+    x = x + 0.5;
+  }
+  Expect.equals(-100, count);
+  count = convert(42);
+  Expect.equals(42, count);
+}
diff --git a/runtime/tests/vm/dart/hello_fuchsia_test.dart b/runtime/tests/vm/dart/hello_fuchsia_test.dart
new file mode 100644
index 0000000..501ffe7
--- /dev/null
+++ b/runtime/tests/vm/dart/hello_fuchsia_test.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  print("Hello, Fuchsia!");
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 1faa41c..ebb0df9 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -139,22 +139,6 @@
 cc/Profiler_TypedArrayAllocation: Skip
 cc/Profiler_GetSourceReport: Skip
 
-# TODO(vegorov) These tests are crashing because ICData objects can't be found
-cc/SourceReport_CallSites_PolymorphicCall: Skip
-cc/SourceReport_CallSites_SimpleCall: Skip
-cc/SourceReport_Coverage_AllFunctions: Skip
-cc/SourceReport_Coverage_ForceCompile: Skip
-cc/SourceReport_Coverage_AllFunctions_ForceCompile: Skip
-cc/SourceReport_Coverage_NestedFunctions: Skip
-cc/SourceReport_Coverage_SimpleCall: Skip
-cc/SourceReport_Coverage_UnusedClass_NoForceCompile: Skip
-cc/SourceReport_Coverage_UnusedClass_ForceCompile: Skip
-cc/SourceReport_Coverage_UnusedClass_ForceCompileError: Skip
-cc/SourceReport_MultipleReports: Skip
-cc/Coverage_Empty: Skip
-cc/Coverage_FilterFunction: Skip
-cc/Coverage_MainWithClass: Skip
-
 # TODO(vegorov) These tests don't seem to work if FLAG_interpret_irregexp
 # is switched on by default because they attempt to call regexp functions
 # directly instead of going through JSSyntaxRegExp_ExecuteMatch.
@@ -163,9 +147,6 @@
 cc/RegExp_OneByteString: Skip
 cc/RegExp_TwoByteString: Skip
 
-# TODO(vegorov) Optimizing compiler is disabled for the SIMDBC
-cc/CompileFunctionOnHelperThread: Skip
-
 # TODO(vegorov) Field guards are disabled for SIMDBC
 cc/GuardFieldConstructor2Test: Skip
 cc/GuardFieldConstructorTest: Skip
@@ -173,46 +154,9 @@
 cc/GuardFieldFinalVariableLengthListTest: Skip
 cc/GuardFieldSimpleTest: Skip
 
-# TODO(vegorov) Not all bytecodes have appropriate debug breaks.
-cc/Debug_BreakpointStubPatching: Skip
-cc/Debug_ExprClosureBreakpoint: Skip
-cc/Debug_StackTraceDump1: Skip
-cc/Debug_StepInto: Skip
-
-# TODO(vegorov) These parser tests rely on debugger.
-cc/Parser_AllocateVariables_CapturedVar: Skip
-cc/Parser_AllocateVariables_MiddleChain: Skip
-
 # This test is meaningless for DBC as allocation stubs are not used.
 cc/RegenerateAllocStubs: Skip
 
-# TODO(vegorov) Enable when DBC supports optimizing compiler.
-cc/Debug_InspectStack_Optimized: Skip
-cc/Debug_InspectStackWithClosure_Optimized: Skip
-
-# Isolate reload code assumes that all static calls have ICData attached to
-# them. However this is not the case on DBC.
-cc/IsolateReload_LiveStack: Skip
-cc/IsolateReload_StaticValuePreserved: Skip
-cc/IsolateReload_TopLevelFieldAdded: Skip
-cc/IsolateReload_ConstructorChanged: Skip
-cc/IsolateReload_ImplicitConstructorChanged: Skip
-cc/IsolateReload_MixinChanged: Skip
-cc/IsolateReload_SuperClassChanged: Skip
-cc/IsolateReload_ComplexInheritanceChange: Skip
-cc/IsolateReload_LibraryImportAdded: Skip
-cc/IsolateReload_LibraryHide: Skip
-cc/IsolateReload_LibraryLookup: Skip
-cc/IsolateReload_LibraryShow: Skip
-cc/IsolateReload_LiveStack: Skip
-cc/IsolateReload_StaticValuePreserved: Skip
-cc/IsolateReload_TopLevelFieldAdded: Skip
-cc/IsolateReload_ConstructorChanged: Skip
-cc/IsolateReload_ImplicitConstructorChanged: Skip
-cc/IsolateReload_MixinChanged: Skip
-cc/IsolateReload_SuperClassChanged: Skip
-cc/IsolateReload_ComplexInheritanceChange: Skip
-cc/IsolateReload_LibraryImportAdded: Skip
-cc/IsolateReload_LibraryHide: Skip
-cc/IsolateReload_LibraryLookup: Skip
-cc/IsolateReload_LibraryShow: Skip
+[ $hot_reload || $hot_reload_rollback ]
+dart/spawn_shutdown_test: Skip # We can shutdown an isolate before it reloads.
+dart/spawn_infinite_loop_test: Skip # We can shutdown an isolate before it reloads.
diff --git a/runtime/tools/create_resources.py b/runtime/tools/create_resources.py
old mode 100644
new mode 100755
index 27c9d78..1e97496
--- a/runtime/tools/create_resources.py
+++ b/runtime/tools/create_resources.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # 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/runtime/tools/create_string_literal.py b/runtime/tools/create_string_literal.py
old mode 100644
new mode 100755
index 7b4b2ec..52a9b10
--- a/runtime/tools/create_string_literal.py
+++ b/runtime/tools/create_string_literal.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env 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.
diff --git a/runtime/tools/gen_library_src_paths.py b/runtime/tools/gen_library_src_paths.py
old mode 100644
new mode 100755
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index f1c2da4..cf35eca 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -3,16 +3,20 @@
 # BSD-style license that can be found in the LICENSE file.
 
 config("libdart_vm_config") {
-  libs = [
-    "dl",
-  ]
+  # TODO(zra, jamesr): This check can go away after some problems with the
+  # fuchsia toolchain definition are fixed.
+  if (!defined(is_fuchsia) || !is_fuchsia) {
+    libs = [ "dl" ]
 
-  if (!is_android) {
-    libs += [ "pthread" ]
+    if (!is_android) {
+      libs += [ "pthread" ]
 
-    if (is_linux) {
-      libs += [ "rt" ]
+      if (is_linux) {
+        libs += [ "rt" ]
+      }
     }
+  } else {
+    libs = [ "runtime" ]
   }
 }
 
@@ -43,17 +47,18 @@
   ]
 }
 
+
+vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
+                              [rebase_path("vm_sources.gypi")],
+                              "scope",
+                              ["vm_sources.gypi"])
+
+
 static_library("libdart_vm") {
   configs += ["..:dart_config",
               "..:dart_product_config",
               "..:dart_precompiled_runtime_config"]
   public_configs = [":libdart_vm_config"]
-
-  vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
-                                [rebase_path("vm_sources.gypi")],
-                                "scope",
-                                ["vm_sources.gypi"])
-
   set_sources_assignment_filter(["*_test.cc", "*_test.h"])
   sources = vm_sources_list.sources
   include_dirs = [
@@ -68,11 +73,6 @@
               "..:dart_precompiled_runtime_config"]
   public_configs = [":libdart_vm_config"]
   defines = [ "DART_NO_SNAPSHOT" ]
-  vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
-                                [rebase_path("vm_sources.gypi")],
-                                "scope",
-                                ["vm_sources.gypi"])
-
   set_sources_assignment_filter(["*_test.cc", "*_test.h"])
   sources = vm_sources_list.sources
   include_dirs = [
@@ -87,11 +87,6 @@
               "..:dart_precompiler_config"]
   public_configs = [":libdart_vm_config"]
   defines = [ "DART_NO_SNAPSHOT" ]
-  vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
-                                [rebase_path("vm_sources.gypi")],
-                                "scope",
-                                ["vm_sources.gypi"])
-
   set_sources_assignment_filter(["*_test.cc", "*_test.h"])
   sources = vm_sources_list.sources
   include_dirs = [
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index cdc4753..3d4b07f 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -1674,8 +1674,8 @@
 bool AotOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
   ASSERT(call->HasICData());
   const ICData& ic_data = *call->ic_data();
-  if ((ic_data.NumberOfUsedChecks() == 0) || !ic_data.HasOneTarget()) {
-    // No type feedback collected or multiple targets found.
+  if (ic_data.NumberOfUsedChecks() != 1) {
+    // No type feedback collected or multiple receivers/targets found.
     return false;
   }
 
@@ -1690,14 +1690,13 @@
       (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
       (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) ||
       (recognized_kind == MethodRecognizer::kGrowableArraySetData) ||
-      (recognized_kind == MethodRecognizer::kGrowableArraySetLength)) {
-      ASSERT(ic_data.NumberOfChecks() == 1);
+      (recognized_kind == MethodRecognizer::kGrowableArraySetLength) ||
+      (recognized_kind == MethodRecognizer::kSmi_bitAndFromSmi)) {
     return FlowGraphInliner::TryReplaceInstanceCallWithInline(
         flow_graph_, current_iterator(), call);
   }
 
-  if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
-      (ic_data.NumberOfChecks() == 1)) {
+  if (recognized_kind == MethodRecognizer::kStringBaseCharAt) {
       ASSERT((class_ids[0] == kOneByteStringCid) ||
              (class_ids[0] == kTwoByteStringCid) ||
              (class_ids[0] == kExternalOneByteStringCid) ||
@@ -1706,7 +1705,7 @@
         flow_graph_, current_iterator(), call);
   }
 
-  if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kOneByteStringCid) {
     if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
       // This is an internal method, no need to check argument types nor
       // range.
@@ -1729,8 +1728,7 @@
   }
 
   if (CanUnboxDouble() &&
-      (recognized_kind == MethodRecognizer::kIntegerToDouble) &&
-      (ic_data.NumberOfChecks() == 1)) {
+      (recognized_kind == MethodRecognizer::kIntegerToDouble)) {
     if (class_ids[0] == kSmiCid) {
       AddReceiverCheck(call);
       ReplaceCall(call,
@@ -1799,21 +1797,20 @@
     }
   }
 
-  if (IsSupportedByteArrayViewCid(class_ids[0]) &&
-      (ic_data.NumberOfChecks() == 1)) {
+  if (IsSupportedByteArrayViewCid(class_ids[0])) {
     return FlowGraphInliner::TryReplaceInstanceCallWithInline(
         flow_graph_, current_iterator(), call);
   }
 
-  if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kFloat32x4Cid) {
     return TryInlineFloat32x4Method(call, recognized_kind);
   }
 
-  if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kInt32x4Cid) {
     return TryInlineInt32x4Method(call, recognized_kind);
   }
 
-  if ((class_ids[0] == kFloat64x2Cid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kFloat64x2Cid) {
     return TryInlineFloat64x2Method(call, recognized_kind);
   }
 
@@ -2050,6 +2047,10 @@
   return true;  // May deoptimize since we have not identified all 'true' tests.
 }
 
+// Tells whether the function of the call matches the core private name.
+static bool matches_core(InstanceCallInstr* call, const String& name) {
+  return call->function_name().raw() == Library::PrivateCoreLibName(name).raw();
+}
 
 // TODO(srdjan): Use ICData to check if always true or false.
 void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
@@ -2060,26 +2061,27 @@
   bool negate = false;
   if (call->ArgumentCount() == 2) {
     type_args = flow_graph()->constant_null();
-    if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfNum()).raw()) {
-      type = Type::Number();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfInt()).raw()) {
-      type = Type::IntType();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfSmi()).raw()) {
-      type = Type::SmiType();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfDouble()).raw()) {
-      type = Type::Double();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfString()).raw()) {
-      type = Type::StringType();
+    if (matches_core(call, Symbols::_simpleInstanceOf())) {
+      type =
+          AbstractType::Cast(call->ArgumentAt(1)->AsConstant()->value()).raw();
+      negate = false;  // Just to be sure.
     } else {
-      UNIMPLEMENTED();
+      if (matches_core(call, Symbols::_instanceOfNum())) {
+        type = Type::Number();
+      } else if (matches_core(call, Symbols::_instanceOfInt())) {
+        type = Type::IntType();
+      } else if (matches_core(call, Symbols::_instanceOfSmi())) {
+        type = Type::SmiType();
+      } else if (matches_core(call, Symbols::_instanceOfDouble())) {
+        type = Type::Double();
+      } else if (matches_core(call, Symbols::_instanceOfString())) {
+        type = Type::StringType();
+      } else {
+        UNIMPLEMENTED();
+      }
+      negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition()
+                          ->AsConstant()->value()).value();
     }
-    negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition()
-        ->AsConstant()->value()).value();
   } else {
     type_args = call->ArgumentAt(1);
     type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw();
@@ -2746,4 +2748,26 @@
 }
 
 
+void AotOptimizer::ReplaceArrayBoundChecks() {
+  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    ForwardInstructionIterator it(block_it.Current());
+    current_iterator_ = &it;
+    for (; !it.Done(); it.Advance()) {
+      CheckArrayBoundInstr* check = it.Current()->AsCheckArrayBound();
+      if (check != NULL) {
+        GenericCheckBoundInstr* new_check = new(Z) GenericCheckBoundInstr(
+            new(Z) Value(check->length()->definition()),
+            new(Z) Value(check->index()->definition()),
+            check->deopt_id());
+        flow_graph_->InsertBefore(check, new_check,
+                                  check->env(), FlowGraph::kEffect);
+        current_iterator()->RemoveCurrentFromGraph();
+      }
+    }
+  }
+}
+
+
 }  // namespace dart
diff --git a/runtime/vm/aot_optimizer.h b/runtime/vm/aot_optimizer.h
index 1afdadd..6c4586e 100644
--- a/runtime/vm/aot_optimizer.h
+++ b/runtime/vm/aot_optimizer.h
@@ -46,6 +46,8 @@
   // Merge instructions (only per basic-block).
   void TryOptimizePatterns();
 
+  void ReplaceArrayBoundChecks();
+
   virtual void VisitStaticCall(StaticCallInstr* instr);
   virtual void VisitInstanceCall(InstanceCallInstr* instr);
   virtual void VisitLoadCodeUnits(LoadCodeUnitsInstr* instr);
diff --git a/runtime/vm/assembler.h b/runtime/vm/assembler.h
index ceaadaa..36279fb 100644
--- a/runtime/vm/assembler.h
+++ b/runtime/vm/assembler.h
@@ -175,6 +175,8 @@
   // Returns the position in the instruction stream.
   intptr_t GetPosition() const { return cursor_ - contents_; }
 
+  void Reset() { cursor_ = contents_; }
+
  private:
   // The limit is set to kMinimumGap bytes before the end of the data area.
   // This leaves enough space for the longest possible instruction and allows
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 2e39e22..e768806 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -1921,47 +1921,6 @@
 }
 
 
-void Assembler::ComputeRange(Register result,
-                             Register value,
-                             Register scratch,
-                             Label* not_mint) {
-  const Register hi = TMP;
-  const Register lo = scratch;
-
-  Label done;
-  mov(result, Operand(value, LSR, kBitsPerWord - 1));
-  tst(value, Operand(kSmiTagMask));
-  b(&done, EQ);
-  CompareClassId(value, kMintCid, result);
-  b(not_mint, NE);
-  ldr(hi, FieldAddress(value, Mint::value_offset() + kWordSize));
-  ldr(lo, FieldAddress(value, Mint::value_offset()));
-  rsb(result, hi, Operand(ICData::kInt32RangeBit));
-  cmp(hi, Operand(lo, ASR, kBitsPerWord - 1));
-  b(&done, EQ);
-  LoadImmediate(result, ICData::kUint32RangeBit);  // Uint32
-  tst(hi, Operand(hi));
-  LoadImmediate(result, ICData::kInt64RangeBit, NE);  // Int64
-  Bind(&done);
-}
-
-
-void Assembler::UpdateRangeFeedback(Register value,
-                                    intptr_t index,
-                                    Register ic_data,
-                                    Register scratch1,
-                                    Register scratch2,
-                                    Label* miss) {
-  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
-  ComputeRange(scratch1, value, scratch2, miss);
-  ldr(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()));
-  orr(scratch2,
-      scratch2,
-      Operand(scratch1, LSL, ICData::RangeFeedbackShift(index)));
-  str(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()));
-}
-
-
 static bool CanEncodeBranchOffset(int32_t offset) {
   ASSERT(Utils::IsAligned(offset, 4));
   return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset);
@@ -3263,7 +3222,9 @@
     ldr(PP, Address(FP, kSavedCallerPpSlotFromFp * kWordSize));
     set_constant_pool_allowed(false);
   }
-  Drop(2);  // Drop saved PP, PC marker.
+
+  // This will implicitly drop saved PP, PC marker due to restoring SP from FP
+  // first.
   LeaveFrame((1 << FP) | (1 << LR));
 }
 
@@ -3278,6 +3239,56 @@
 }
 
 
+void Assembler::NoMonomorphicCheckedEntry() {
+  buffer_.Reset();
+  bkpt(0);
+  bkpt(0);
+  bkpt(0);
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+}
+
+
+// R0 receiver, R9 guarded cid as Smi
+void Assembler::MonomorphicCheckedEntry() {
+#if defined(TESTING) || defined(DEBUG)
+  bool saved_use_far_branches = use_far_branches();
+  set_use_far_branches(false);
+#endif
+
+  Label miss;
+  Bind(&miss);
+  ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
+  ldr(IP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  bx(IP);
+
+  Comment("MonomorphicCheckedEntry");
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+  LoadClassIdMayBeSmi(R4, R0);
+  SmiUntag(R9);
+  cmp(R4, Operand(R9));
+  b(&miss, NE);
+
+  // Fall through to unchecked entry.
+  ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset);
+
+#if defined(TESTING) || defined(DEBUG)
+  set_use_far_branches(saved_use_far_branches);
+#endif
+}
+
+
+#ifndef PRODUCT
+void Assembler::MaybeTraceAllocation(intptr_t cid,
+                                     Register temp_reg,
+                                     Label* trace) {
+  LoadAllocationStatsAddress(temp_reg, cid);
+  const uword state_offset = ClassHeapStats::state_offset();
+  ldr(temp_reg, Address(temp_reg, state_offset));
+  tst(temp_reg, Operand(ClassHeapStats::TraceAllocationMask()));
+  b(trace, NE);
+}
+
+
 void Assembler::LoadAllocationStatsAddress(Register dest,
                                            intptr_t cid) {
   ASSERT(dest != kNoRegister);
@@ -3292,17 +3303,6 @@
 }
 
 
-void Assembler::MaybeTraceAllocation(intptr_t cid,
-                                     Register temp_reg,
-                                     Label* trace) {
-  LoadAllocationStatsAddress(temp_reg, cid);
-  const uword state_offset = ClassHeapStats::state_offset();
-  ldr(temp_reg, Address(temp_reg, state_offset));
-  tst(temp_reg, Operand(ClassHeapStats::TraceAllocationMask()));
-  b(trace, NE);
-}
-
-
 void Assembler::IncrementAllocationStats(Register stats_addr_reg,
                                          intptr_t cid,
                                          Heap::Space space) {
@@ -3339,6 +3339,7 @@
   add(TMP, TMP, Operand(size_reg));
   str(TMP, size_address);
 }
+#endif  // !PRODUCT
 
 
 void Assembler::TryAllocate(const Class& cls,
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index cac760b..3afce46 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -368,7 +368,9 @@
         prologue_offset_(-1),
         use_far_branches_(use_far_branches),
         comments_(),
-        constant_pool_allowed_(false) { }
+        constant_pool_allowed_(false) {
+    MonomorphicCheckedEntry();
+  }
 
   ~Assembler() { }
 
@@ -794,18 +796,6 @@
   void LoadClassIdMayBeSmi(Register result, Register object);
   void LoadTaggedClassIdMayBeSmi(Register result, Register object);
 
-  void ComputeRange(Register result,
-                    Register value,
-                    Register scratch,
-                    Label* miss);
-
-  void UpdateRangeFeedback(Register value,
-                           intptr_t idx,
-                           Register ic_data,
-                           Register scratch1,
-                           Register scratch2,
-                           Label* miss);
-
   intptr_t FindImmediate(int32_t imm);
   bool CanLoadFromObjectPool(const Object& object) const;
   void LoadFromOffset(OperandSize type,
@@ -919,6 +909,11 @@
     b(is_smi, CC);
   }
 
+  void BranchIfNotSmi(Register reg, Label* label) {
+    tst(reg, Operand(kSmiTagMask));
+    b(label, NE);
+  }
+
   void CheckCodePointer();
 
   // Function frame setup and tear down.
@@ -951,6 +946,9 @@
   void EnterStubFrame();
   void LeaveStubFrame();
 
+  void NoMonomorphicCheckedEntry();
+  void MonomorphicCheckedEntry();
+
   // The register into which the allocation stats table is loaded with
   // LoadAllocationStatsAddress should be passed to
   // IncrementAllocationStats(WithSize) as stats_addr_reg to update the
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 26c0b4a..72278e9 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -13,12 +13,6 @@
 #include "vm/stack_frame.h"
 #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) && \
-    !TARGET_OS_IOS
-#error ARM64 cross-compile only supported on Linux
-#endif
-
 namespace dart {
 
 DECLARE_FLAG(bool, check_code_pointer);
@@ -33,6 +27,7 @@
       use_far_branches_(use_far_branches),
       comments_(),
       constant_pool_allowed_(false) {
+  MonomorphicCheckedEntry();
 }
 
 
@@ -1036,51 +1031,6 @@
 }
 
 
-void Assembler::ComputeRange(Register result,
-                             Register value,
-                             Register scratch,
-                             Label* not_mint) {
-  Label done, not_smi;
-  tsti(value, Immediate(kSmiTagMask));
-  b(&not_smi, NE);
-
-  AsrImmediate(scratch, value, 32);
-  LoadImmediate(result, ICData::kUint32RangeBit);
-  cmp(scratch, Operand(1));
-  b(&done, EQ);
-
-  neg(scratch, scratch);
-  add(result, scratch, Operand(ICData::kInt32RangeBit));
-  cmp(scratch, Operand(1));
-  LoadImmediate(TMP, ICData::kSignedRangeBit);
-  csel(result, result, TMP, LS);
-  b(&done);
-
-  Bind(&not_smi);
-  CompareClassId(value, kMintCid);
-  b(not_mint, NE);
-
-  LoadImmediate(result, ICData::kInt64RangeBit);
-  Bind(&done);
-}
-
-
-void Assembler::UpdateRangeFeedback(Register value,
-                                    intptr_t index,
-                                    Register ic_data,
-                                    Register scratch1,
-                                    Register scratch2,
-                                    Label* miss) {
-  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
-  ComputeRange(scratch1, value, scratch2, miss);
-  ldr(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()), kWord);
-  orrw(scratch2,
-       scratch2,
-       Operand(scratch1, LSL, ICData::RangeFeedbackShift(index)));
-  str(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()), kWord);
-}
-
-
 // Frame entry and exit.
 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
   // Reserve space for arguments and align frame before entering
@@ -1288,6 +1238,70 @@
 }
 
 
+void Assembler::NoMonomorphicCheckedEntry() {
+  buffer_.Reset();
+  brk(0);
+  brk(0);
+  brk(0);
+  brk(0);
+  brk(0);
+  brk(0);
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+}
+
+
+// R0 receiver, R5 guarded cid as Smi
+void Assembler::MonomorphicCheckedEntry() {
+  bool saved_use_far_branches = use_far_branches();
+  set_use_far_branches(false);
+
+  Label immediate, have_cid, miss;
+  Bind(&miss);
+  ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
+  ldr(IP0, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  br(IP0);
+  brk(0);
+
+  Bind(&immediate);
+  movz(R4, Immediate(kSmiCid), 0);
+  b(&have_cid);
+
+  Comment("MonomorphicCheckedEntry");
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+  tsti(R0, Immediate(kSmiTagMask));
+  SmiUntag(R5);
+  b(&immediate, EQ);
+
+  LoadClassId(R4, R0);
+
+  Bind(&have_cid);
+  cmp(R4, Operand(R5));
+  b(&miss, NE);
+
+  // Fall through to unchecked entry.
+  ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset);
+
+  set_use_far_branches(saved_use_far_branches);
+}
+
+
+#ifndef PRODUCT
+void Assembler::MaybeTraceAllocation(intptr_t cid,
+                                     Register temp_reg,
+                                     Label* trace) {
+  ASSERT(cid > 0);
+  intptr_t state_offset = ClassTable::StateOffsetFor(cid);
+  LoadIsolate(temp_reg);
+  intptr_t table_offset =
+      Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
+  ldr(temp_reg, Address(temp_reg, table_offset));
+  AddImmediate(temp_reg, temp_reg, state_offset);
+  ldr(temp_reg, Address(temp_reg, 0));
+  tsti(temp_reg, Immediate(ClassHeapStats::TraceAllocationMask()));
+  b(trace, NE);
+}
+
+
 void Assembler::UpdateAllocationStats(intptr_t cid,
                                       Heap::Space space) {
   ASSERT(cid > 0);
@@ -1327,22 +1341,7 @@
   add(TMP, TMP, Operand(size_reg));
   str(TMP, Address(TMP2, size_field_offset));
 }
-
-
-void Assembler::MaybeTraceAllocation(intptr_t cid,
-                                     Register temp_reg,
-                                     Label* trace) {
-  ASSERT(cid > 0);
-  intptr_t state_offset = ClassTable::StateOffsetFor(cid);
-  LoadIsolate(temp_reg);
-  intptr_t table_offset =
-      Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
-  ldr(temp_reg, Address(temp_reg, table_offset));
-  AddImmediate(temp_reg, temp_reg, state_offset);
-  ldr(temp_reg, Address(temp_reg, 0));
-  tsti(temp_reg, Immediate(ClassHeapStats::TraceAllocationMask()));
-  b(trace, NE);
-}
+#endif  // !PRODUCT
 
 
 void Assembler::TryAllocate(const Class& cls,
diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h
index 8080ab8..1f8edfa 100644
--- a/runtime/vm/assembler_arm64.h
+++ b/runtime/vm/assembler_arm64.h
@@ -488,7 +488,6 @@
   }
 
   void set_use_far_branches(bool b) {
-    ASSERT(buffer_.Size() == 0);
     use_far_branches_ = b;
   }
 
@@ -1219,6 +1218,11 @@
     LslImmediate(dst, src, kSmiTagSize);
   }
 
+  void BranchIfNotSmi(Register reg, Label* label) {
+    tsti(reg, Immediate(kSmiTagMask));
+    b(label, NE);
+  }
+
   void Branch(const StubEntry& stub_entry,
               Register pp,
               Patchability patchable = kNotPatchable);
@@ -1337,18 +1341,6 @@
   void LoadClassIdMayBeSmi(Register result, Register object);
   void LoadTaggedClassIdMayBeSmi(Register result, Register object);
 
-  void ComputeRange(Register result,
-                    Register value,
-                    Register scratch,
-                    Label* miss);
-
-  void UpdateRangeFeedback(Register value,
-                           intptr_t idx,
-                           Register ic_data,
-                           Register scratch1,
-                           Register scratch2,
-                           Label* miss);
-
   void SetupDartSP();
   void RestoreCSP();
 
@@ -1371,6 +1363,9 @@
   void EnterStubFrame();
   void LeaveStubFrame();
 
+  void NoMonomorphicCheckedEntry();
+  void MonomorphicCheckedEntry();
+
   void UpdateAllocationStats(intptr_t cid,
                              Heap::Space space);
 
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index 7c7a620..3d95b7c 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -13,8 +13,6 @@
 
 namespace dart {
 
-static const intptr_t kTestStackSpace = 512 * kWordSize;
-
 #define __ assembler->
 
 ASSEMBLER_TEST_GENERATE(Simple, assembler) {
@@ -3634,68 +3632,6 @@
   __ ret();
 }
 
-
-ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
-  __ SetupDartSP();
-  EnterTestFrame(assembler);
-  Label miss, done;
-  __ ComputeRange(R0, R2, R3, &miss);
-  __ b(&done);
-
-  __ Bind(&miss);
-  __ LoadImmediate(R0, -1);
-
-  __ Bind(&done);
-  LeaveTestFrame(assembler);
-  __ RestoreCSP();
-  __ ret();
-}
-
-
-ASSEMBLER_TEST_RUN(ComputeRange, test) {
-#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)));
-  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(RawSmi*, Smi::New(kMaxInt32)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            RANGE_OF(RawSmi*, Smi::New(-1)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            RANGE_OF(RawSmi*, Smi::New(kMinInt32)));
-
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            RANGE_OF(RawSmi*, Smi::New(static_cast<int64_t>(kMaxInt32) + 1)));
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            RANGE_OF(RawSmi*, Smi::New(kMaxUint32)));
-
-  // On 64-bit platforms we don't track the sign of the smis outside of
-  // int32 range because it is not needed to distinguish kInt32Range from
-  // kUint32Range.
-  EXPECT_EQ(ICData::kSignedRangeBit,
-            RANGE_OF(RawSmi*, Smi::New(static_cast<int64_t>(kMinInt32) - 1)));
-  EXPECT_EQ(ICData::kSignedRangeBit,
-            RANGE_OF(RawSmi*, Smi::New(static_cast<int64_t>(kMaxUint32) + 1)));
-  EXPECT_EQ(ICData::kSignedRangeBit,
-            RANGE_OF(RawSmi*, Smi::New(Smi::kMaxValue)));
-  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(RawSmi*,
-            Smi::New(Smi::kMinValue)));
-
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(RawInteger*, Integer::New(Smi::kMaxValue + 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(RawInteger*, Integer::New(Smi::kMinValue - 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(RawInteger*, Integer::New(kMaxInt64)));
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(RawInteger*, Integer::New(kMinInt64)));
-
-  EXPECT_EQ(-1, RANGE_OF(RawBool*, Bool::True().raw()));
-
-#undef RANGE_OF
-}
-
-
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index 1e6e6ef..7eca350 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -3961,58 +3961,6 @@
   __ Ret();
 }
 
-
-ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
-  Label miss, done;
-  __ mov(R1, Operand(R0));
-  __ ComputeRange(R0, R1, R2, &miss);
-  __ b(&done);
-
-  __ Bind(&miss);
-  __ LoadImmediate(R0, -1);
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-
-ASSEMBLER_TEST_RUN(ComputeRange, test) {
-  typedef intptr_t (*ComputeRange)(intptr_t value) DART_UNUSED;
-
-#define RANGE_OF(v)                                              \
-  (EXECUTE_TEST_CODE_INTPTR_INTPTR(                              \
-    ComputeRange, test->entry(), reinterpret_cast<intptr_t>(v)))
-
-  EXPECT_EQ(0, RANGE_OF(Smi::New(0)));
-  EXPECT_EQ(0, RANGE_OF(Smi::New(1)));
-  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(-1)));
-  EXPECT_EQ(0, RANGE_OF(Smi::New(Smi::kMaxValue)));
-  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(Smi::kMinValue)));
-
-  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(Smi::kMaxValue + 1)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            RANGE_OF(Integer::New(Smi::kMinValue - 1)));
-  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(kMaxInt32)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            RANGE_OF(Integer::New(kMinInt32)));
-
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxInt32) + 1)));
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            RANGE_OF(Integer::New(kMaxUint32)));
-
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxUint32) + 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(Integer::New(static_cast<int64_t>(kMinInt32) - 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMaxInt64)));
-  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMinInt64)));
-
-  EXPECT_EQ(-1, RANGE_OF(Bool::True().raw()));
-
-#undef RANGE_OF
-}
-
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/assembler_dbc.h b/runtime/vm/assembler_dbc.h
index 590dd5c..7e23863 100644
--- a/runtime/vm/assembler_dbc.h
+++ b/runtime/vm/assembler_dbc.h
@@ -166,6 +166,8 @@
 
   intptr_t AddConstant(const Object& obj);
 
+  void Nop(intptr_t d) { Nop(0, d); }
+
  private:
   AssemblerBuffer buffer_;  // Contains position independent code.
   ObjectPoolWrapper object_pool_wrapper_;
diff --git a/runtime/vm/assembler_dbc_test.cc b/runtime/vm/assembler_dbc_test.cc
index 180437e..254f638 100644
--- a/runtime/vm/assembler_dbc_test.cc
+++ b/runtime/vm/assembler_dbc_test.cc
@@ -28,6 +28,8 @@
     (Bool::RawCast(ExecuteTest(code)) == Bool::True().raw())
 #define EXECUTE_TEST_CODE_OBJECT(code)                                         \
     Object::Handle(ExecuteTest(code))
+#define EXECUTE_TEST_CODE_DOUBLE(code)                                         \
+    bit_cast<double, RawObject*>(ExecuteTest(code))
 
 #define __ assembler->
 
@@ -1650,6 +1652,91 @@
 }
 
 
+//  - TestCids rA, D
+//
+//    The next D instructions must be Nops whose D field encodes a class id. If
+//    the class id of FP[rA] matches, jump to PC + N + 1 if the matching Nop's
+//    A != 0 or PC + N + 2 if the matching Nop's A = 0. If no match is found,
+//    jump to PC + N.
+ASSEMBLER_TEST_GENERATE(TestCidsTrue, assembler) {
+  Label true_branch, no_match_branch;
+  __ Frame(2);
+  __ LoadConstant(0, Object::Handle(String::New("Hi", Heap::kOld)));
+  const intptr_t num_cases = 2;
+  __ TestCids(0, num_cases);
+  __ Nop(0, static_cast<uint16_t>(kSmiCid));            // Smi    => false
+  __ Nop(1, static_cast<uint16_t>(kOneByteStringCid));  // String => true
+  __ Jump(&no_match_branch);
+  __ Jump(&true_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(0)));  // false branch
+  __ Return(1);
+  __ Bind(&true_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(1)));
+  __ Return(1);
+  __ Bind(&no_match_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(2)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(TestCidsTrue, test) {
+  EXPECT_EQ(1, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(TestCidsFalse, assembler) {
+  Label true_branch, no_match_branch;
+  __ Frame(2);
+  __ LoadConstant(0, Object::Handle(Smi::New(42)));
+  const intptr_t num_cases = 2;
+  __ TestCids(0, num_cases);
+  __ Nop(0, static_cast<uint16_t>(kSmiCid));            // Smi    => false
+  __ Nop(1, static_cast<uint16_t>(kOneByteStringCid));  // String => true
+  __ Jump(&no_match_branch);
+  __ Jump(&true_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(0)));  // false branch
+  __ Return(1);
+  __ Bind(&true_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(1)));
+  __ Return(1);
+  __ Bind(&no_match_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(2)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(TestCidsFalse, test) {
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(TestCidsNoMatch, assembler) {
+  Label true_branch, no_match_branch;
+  __ Frame(2);
+  __ LoadConstant(0, Object::Handle(Array::New(1, Heap::kOld)));
+  const intptr_t num_cases = 2;
+  __ TestCids(0, num_cases);
+  __ Nop(0, static_cast<uint16_t>(kSmiCid));            // Smi    => false
+  __ Nop(1, static_cast<uint16_t>(kOneByteStringCid));  // String => true
+  __ Jump(&no_match_branch);
+  __ Jump(&true_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(0)));  // false branch
+  __ Return(1);
+  __ Bind(&true_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(1)));
+  __ Return(1);
+  __ Bind(&no_match_branch);
+  __ LoadConstant(1, Smi::Handle(Smi::New(2)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(TestCidsNoMatch, test) {
+  EXPECT_EQ(2, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+
 //  - CheckSmi rA
 //
 //    If FP[rA] is a Smi, then skip the next instruction.
@@ -1688,9 +1775,10 @@
 //    If the object at FP[rA]'s class id matches hthe class id in PP[D], then
 //    skip the following instruction.
 ASSEMBLER_TEST_GENERATE(CheckClassIdSmiPass, assembler) {
-  __ Frame(1);
+  __ Frame(2);
   __ LoadConstant(0, Smi::Handle(Smi::New(42)));
-  __ CheckClassId(0, kSmiCid);
+  __ LoadClassId(1, 0);
+  __ CheckClassId(1, kSmiCid);
   __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
   __ Return(0);
 }
@@ -1702,9 +1790,10 @@
 
 
 ASSEMBLER_TEST_GENERATE(CheckClassIdNonSmiPass, assembler) {
-  __ Frame(1);
+  __ Frame(2);
   __ LoadConstant(0, Bool::True());
-  __ CheckClassId(0, kBoolCid);
+  __ LoadClassId(1, 0);
+  __ CheckClassId(1, kBoolCid);
   __ LoadConstant(0, Bool::False());
   __ Return(0);
 }
@@ -1716,9 +1805,10 @@
 
 
 ASSEMBLER_TEST_GENERATE(CheckClassIdFail, assembler) {
-  __ Frame(1);
+  __ Frame(2);
   __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
-  __ CheckClassId(0, kBoolCid);
+  __ LoadClassId(1, 0);
+  __ CheckClassId(1, kBoolCid);
   __ LoadConstant(0, Smi::Handle(Smi::New(42)));
   __ Return(0);
 }
@@ -1792,6 +1882,948 @@
   EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
 }
 
+//  - If<Cond> rA, rD
+//
+//    Cond is Le, Lt, Ge, Gt, unsigned variants ULe, ULt, UGe, UGt, and
+//    unboxed double variants DEq, DNe, DLe, DLt, DGe, DGt.
+//    Skips the next instruction unless FP[rA] <Cond> FP[rD]. Assumes that
+//    FP[rA] and FP[rD] are Smis or unboxed doubles as inidcated by <Cond>.
+ASSEMBLER_TEST_GENERATE(IfLeTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(-5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfLe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfLeTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfLeFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(-5)));
+  __ IfLe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfLeFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfLtTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(-5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfLt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfLtTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfLtFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(-5)));
+  __ IfLt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfLtFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfGeTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(-5)));
+  __ IfGe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfGeTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfGeFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(-5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfGe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfGeFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfGtTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(-5)));
+  __ IfGt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfGtTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfGtFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(-5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfGt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfGtFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+#if defined(ARCH_IS_64_BIT)
+ASSEMBLER_TEST_GENERATE(IfDNeTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDNe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDNeTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDNeFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDNe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDNeFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDNeNan, assembler) {
+  const double not_a_number = bit_cast<double, intptr_t>(0x7FF8000000000000LL);
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDNe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDNeNan, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDEqTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDEq(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDEqTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDEqFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDEq(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDEqFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDEqNan, assembler) {
+  const double not_a_number = bit_cast<double, intptr_t>(0x7FF8000000000000LL);
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDEq(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDEqNan, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDLeTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDLe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDLeTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDLeFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDLe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDLeFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDLeNan, assembler) {
+  const double not_a_number = bit_cast<double, intptr_t>(0x7FF8000000000000LL);
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDLe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDLeNan, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDLtTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDLt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDLtTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDLtFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDLt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDLtFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDLtNan, assembler) {
+  const double not_a_number = bit_cast<double, intptr_t>(0x7FF8000000000000LL);
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDLt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDLtNan, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDGeTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDGe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDGeTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDGeFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDGe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDGeFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDGeNan, assembler) {
+  const double not_a_number = bit_cast<double, intptr_t>(0x7FF8000000000000LL);
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDGe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDGeNan, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDGtTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDGt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDGtTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDGtFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(-5.0, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDGt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDGtFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfDGtNan, assembler) {
+  const double not_a_number = bit_cast<double, intptr_t>(0x7FF8000000000000LL);
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Double::Handle(Double::New(not_a_number, Heap::kOld)));
+  __ LoadConstant(2, Double::Handle(Double::New(100.0, Heap::kOld)));
+  __ UnboxDouble(1, 1);
+  __ UnboxDouble(2, 2);
+  __ IfDGt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfDGtNan, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+#endif  // defined(ARCH_IS_64_BIT)
+
+
+ASSEMBLER_TEST_GENERATE(IfULeTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfULe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfULeTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfULeFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(5)));
+  __ IfULe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfULeFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfULeNegTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(-5)));
+  __ IfULe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfULeNegTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfULtTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfULt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfULtTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfULtFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(5)));
+  __ IfULt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfULtFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfUGeTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(5)));
+  __ IfUGe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfUGeTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfUGeFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfUGe(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfUGeFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfUGtTrue, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(100)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(5)));
+  __ IfUGt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfUGtTrue, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfUGtFalse, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(5)));
+  __ LoadConstant(2, Smi::Handle(Smi::New(100)));
+  __ IfUGt(1, 2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(-1)));
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(IfUGtFalse, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - Min, Max rA, rB, rC
+//
+//    FP[rA] <- {min, max}(FP[rB], FP[rC]). Assumes that FP[rB], and FP[rC] are
+//    Smis.
+ASSEMBLER_TEST_GENERATE(Min, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(500)));
+  __ Min(2, 0, 1);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(Min, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Max, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(5)));
+  __ Max(2, 0, 1);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(Max, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+#if defined(ARCH_IS_64_BIT)
+//  - UnboxDouble rA, rD
+//
+//    Unbox the double in FP[rD] into FP[rA]. Assumes FP[rD] is a double.
+//
+//  - CheckedUnboxDouble rA, rD
+//
+//    Unboxes FP[rD] into FP[rA] and skips the following instruction unless
+//    FP[rD] is not a double or a Smi. When FP[rD] is a Smi, converts it to a
+//    double.
+ASSEMBLER_TEST_GENERATE(Unbox, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(42.0, Heap::kOld)));
+  __ UnboxDouble(1, 0);
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(Unbox, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(CheckedUnboxDouble, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(42.0, Heap::kOld)));
+  __ CheckedUnboxDouble(1, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(0)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(CheckedUnboxDouble, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(CheckedUnboxSmi, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ CheckedUnboxDouble(1, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(0)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(CheckedUnboxSmi, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(CheckedUnboxFail, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Bool::True());
+  __ LoadConstant(1, Smi::Handle(Smi::New(-1)));
+  __ CheckedUnboxDouble(1, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(42)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(CheckedUnboxFail, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - DAdd, DSub, DMul, DDiv rA, rB, rC
+//
+//    Arithmetic operaions on unboxed doubles. FP[rA] <- FP[rB] op FP[rC].
+ASSEMBLER_TEST_GENERATE(DAdd, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Double::Handle(Double::New(41.0, Heap::kOld)));
+  __ LoadConstant(1, Double::Handle(Double::New(1.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ UnboxDouble(1, 1);
+  __ DAdd(2, 1, 0);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(DAdd, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DSub, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Double::Handle(Double::New(1.0, Heap::kOld)));
+  __ LoadConstant(1, Double::Handle(Double::New(43.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ UnboxDouble(1, 1);
+  __ DSub(2, 1, 0);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(DSub, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DMul, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Double::Handle(Double::New(6.0, Heap::kOld)));
+  __ LoadConstant(1, Double::Handle(Double::New(7.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ UnboxDouble(1, 1);
+  __ DMul(2, 1, 0);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(DMul, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DDiv, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Double::Handle(Double::New(2.0, Heap::kOld)));
+  __ LoadConstant(1, Double::Handle(Double::New(84.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ UnboxDouble(1, 1);
+  __ DDiv(2, 1, 0);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(DDiv, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DNeg, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(-42.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ DNeg(1, 0);
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(DNeg, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DSqrt, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(36.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ DSqrt(1, 0);
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(DSqrt, test) {
+  EXPECT_EQ(6.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+//  - SmiToDouble rA, rD
+//
+//    Convert the Smi in FP[rD] to an unboxed double in FP[rA].
+//
+//  - DoubleToSmi rA, rD
+//
+//    If the unboxed double in FP[rD] can be converted to a Smi in FP[rA], then
+//    this instruction does so, and skips the following instruction. Otherwise,
+//    the following instruction is not skipped.
+ASSEMBLER_TEST_GENERATE(SmiToDouble, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ SmiToDouble(1, 0);
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(SmiToDouble, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DoubleToSmi, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(42.0, Heap::kOld)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(-1)));
+  __ UnboxDouble(0, 0);
+  __ DoubleToSmi(1, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(-1)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(DoubleToSmi, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DoubleToSmiNearMax, assembler) {
+  const double m = static_cast<double>(Smi::kMaxValue - 1000);
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(m, Heap::kOld)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(42)));
+  __ UnboxDouble(0, 0);
+  __ DoubleToSmi(0, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(-1)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(DoubleToSmiNearMax, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DoubleToSmiNearMin, assembler) {
+  const double m = static_cast<double>(Smi::kMinValue);
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(m, Heap::kOld)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(42)));
+  __ UnboxDouble(0, 0);
+  __ DoubleToSmi(0, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(-1)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(DoubleToSmiNearMin, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DoubleToSmiFailPos, assembler) {
+  const double pos_overflow = static_cast<double>(Smi::kMaxValue + 1);
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(pos_overflow, Heap::kOld)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(-1)));
+  __ UnboxDouble(0, 0);
+  __ DoubleToSmi(1, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(42)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(DoubleToSmiFailPos, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DoubleToSmiFailNeg, assembler) {
+  const double neg_overflow = static_cast<double>(Smi::kMinValue - 1000);
+  __ Frame(2);
+  __ LoadConstant(0, Double::Handle(Double::New(neg_overflow, Heap::kOld)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(-1)));
+  __ UnboxDouble(0, 0);
+  __ DoubleToSmi(1, 0);
+  __ LoadConstant(1, Smi::Handle(Smi::New(42)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(DoubleToSmiFailNeg, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DMin, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Double::Handle(Double::New(42.0, Heap::kOld)));
+  __ LoadConstant(1, Double::Handle(Double::New(500.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ UnboxDouble(1, 1);
+  __ DMin(2, 0, 1);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(DMin, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DMax, assembler) {
+  __ Frame(3);
+  __ LoadConstant(0, Double::Handle(Double::New(42.0, Heap::kOld)));
+  __ LoadConstant(1, Double::Handle(Double::New(5.0, Heap::kOld)));
+  __ UnboxDouble(0, 0);
+  __ UnboxDouble(1, 1);
+  __ DMax(2, 0, 1);
+  __ Return(2);
+}
+
+
+ASSEMBLER_TEST_RUN(DMax, test) {
+  EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(test->code()));
+}
+
+#endif  // defined(ARCH_IS_64_BIT)
+
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_DBC)
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 1bc37d8..bb57905 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -2569,6 +2569,7 @@
 }
 
 
+#ifndef PRODUCT
 void Assembler::MaybeTraceAllocation(intptr_t cid,
                                      Register temp_reg,
                                      Label* trace,
@@ -2626,6 +2627,7 @@
   intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
   addl(Address(temp_reg, size_offset), Immediate(size_in_bytes));
 }
+#endif  // !PRODUCT
 
 
 void Assembler::TryAllocate(const Class& cls,
@@ -2939,47 +2941,6 @@
 }
 
 
-void Assembler::ComputeRange(Register result,
-                             Register value,
-                             Register lo_temp,
-                             Register hi_temp,
-                             Label* not_mint) {
-  Label done;
-  movl(result, value);
-  shrl(result, Immediate(kBitsPerWord - 1));  // Sign bit.
-  testl(value, Immediate(kSmiTagMask));
-  j(ZERO, &done, Assembler::kNearJump);
-  CompareClassId(value, kMintCid, result);
-  j(NOT_EQUAL, not_mint);
-  movl(lo_temp, FieldAddress(value, Mint::value_offset()));
-  movl(hi_temp, FieldAddress(value, Mint::value_offset() + kWordSize));
-  movl(result, Immediate(ICData::kInt32RangeBit));
-  subl(result, hi_temp);  // 10 (positive int32), 11 (negative int32)
-  sarl(lo_temp, Immediate(kBitsPerWord - 1));
-  cmpl(lo_temp, hi_temp);
-  j(EQUAL, &done, Assembler::kNearJump);
-  movl(result, Immediate(ICData::kUint32RangeBit));  // Uint32
-  cmpl(hi_temp, Immediate(0));
-  j(EQUAL, &done, Assembler::kNearJump);
-  movl(result, Immediate(ICData::kInt64RangeBit));  // Int64
-  Bind(&done);
-}
-
-
-void Assembler::UpdateRangeFeedback(Register value,
-                                    intptr_t index,
-                                    Register ic_data,
-                                    Register scratch1,
-                                    Register scratch2,
-                                    Register scratch3,
-                                    Label* miss) {
-  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
-  ComputeRange(scratch1, value, scratch2, scratch3, miss);
-  shll(scratch1, Immediate(ICData::RangeFeedbackShift(index)));
-  orl(FieldAddress(ic_data, ICData::state_bits_offset()), scratch1);
-}
-
-
 Address Assembler::ElementAddressForIntIndex(bool is_external,
                                              intptr_t cid,
                                              intptr_t index_scale,
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index 77f77a6..df3d6ff 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -740,20 +740,6 @@
                             Register scratch,
                             Label* is_smi);
 
-  void ComputeRange(Register result,
-                    Register value,
-                    Register lo_temp,
-                    Register hi_temp,
-                    Label* miss);
-
-  void UpdateRangeFeedback(Register value,
-                           intptr_t index,
-                           Register ic_data,
-                           Register scratch1,
-                           Register scratch2,
-                           Register scratch3,
-                           Label* miss);
-
   static Address ElementAddressForIntIndex(bool is_external,
                                            intptr_t cid,
                                            intptr_t index_scale,
@@ -781,7 +767,11 @@
     sarl(reg, Immediate(kSmiTagSize));
   }
 
-  intptr_t PreferredLoopAlignment() { return 16; }
+  void BranchIfNotSmi(Register reg, Label* label) {
+    testl(reg, Immediate(kSmiTagMask));
+    j(NOT_ZERO, label);
+  }
+
   void Align(intptr_t alignment, intptr_t offset);
   void Bind(Label* label);
   void Jump(Label* label) { jmp(label); }
diff --git a/runtime/vm/assembler_ia32_test.cc b/runtime/vm/assembler_ia32_test.cc
index 2ce9da2..116cc9e 100644
--- a/runtime/vm/assembler_ia32_test.cc
+++ b/runtime/vm/assembler_ia32_test.cc
@@ -3425,58 +3425,6 @@
   EXPECT_EQ(1, reinterpret_cast<BitTest>(test->entry())());
 }
 
-
-ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
-  Label miss, done;
-  __ movl(ECX, Address(ESP, 1 * kWordSize));
-
-  __ pushl(ESI);
-  __ pushl(EDI);
-  __ ComputeRange(EAX, ECX, ESI, EDI, &miss);
-  __ jmp(&done);
-
-  __ Bind(&miss);
-  __ movl(EAX, Immediate(-1));
-
-  __ Bind(&done);
-  __ popl(EDI);
-  __ popl(ESI);
-  __ ret();
-}
-
-
-ASSEMBLER_TEST_RUN(ComputeRange, test) {
-  typedef intptr_t (*ComputeRange)(RawObject* value);
-  ComputeRange range_of = reinterpret_cast<ComputeRange>(test->entry());
-
-  EXPECT_EQ(0, range_of(Smi::New(0)));
-  EXPECT_EQ(0, range_of(Smi::New(1)));
-  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(-1)));
-  EXPECT_EQ(0, range_of(Smi::New(Smi::kMaxValue)));
-  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(Smi::kMinValue)));
-
-  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Integer::New(Smi::kMaxValue + 1)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            range_of(Integer::New(Smi::kMinValue - 1)));
-  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Integer::New(kMaxInt32)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            range_of(Integer::New(kMinInt32)));
-
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            range_of(Integer::New(static_cast<int64_t>(kMaxInt32) + 1)));
-  EXPECT_EQ(ICData::kUint32RangeBit, range_of(Integer::New(kMaxUint32)));
-
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            range_of(Integer::New(static_cast<int64_t>(kMaxUint32) + 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            range_of(Integer::New(static_cast<int64_t>(kMinInt32) - 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMaxInt64)));
-  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMinInt64)));
-
-  EXPECT_EQ(-1, range_of(Bool::True().raw()));
-}
-
-
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index ffd927d..a85aa08 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -826,49 +826,6 @@
 }
 
 
-void Assembler::ComputeRange(Register result,
-                             Register value,
-                             Label* miss) {
-  const Register hi = TMP;
-  const Register lo = CMPRES2;
-
-  Label done;
-  srl(result, value, kBitsPerWord - 1);
-  andi(CMPRES1, value, Immediate(kSmiTagMask));
-  beq(CMPRES1, ZR, &done);
-
-  LoadClassId(CMPRES1, value);
-  BranchNotEqual(CMPRES1, Immediate(kMintCid), miss);
-  LoadFieldFromOffset(hi, value, Mint::value_offset() + kWordSize);
-  LoadFieldFromOffset(lo, value, Mint::value_offset());
-  sra(lo, lo, kBitsPerWord - 1);
-
-  LoadImmediate(result, ICData::kInt32RangeBit);
-
-  beq(hi, lo, &done);
-  delay_slot()->subu(result, result, hi);
-
-  beq(hi, ZR, &done);
-  delay_slot()->addiu(result, ZR, Immediate(ICData::kUint32RangeBit));
-  LoadImmediate(result, ICData::kInt64RangeBit);
-  Bind(&done);
-}
-
-
-void Assembler::UpdateRangeFeedback(Register value,
-                                    intptr_t index,
-                                    Register ic_data,
-                                    Register scratch,
-                                    Label* miss) {
-  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
-  ComputeRange(scratch, value, miss);
-  LoadFieldFromOffset(TMP, ic_data, ICData::state_bits_offset());
-  sll(scratch, scratch, ICData::RangeFeedbackShift(index));
-  or_(TMP, TMP, scratch);
-  StoreFieldToOffset(TMP, ic_data, ICData::state_bits_offset());
-}
-
-
 void Assembler::EnterFrame() {
   ASSERT(!in_delay_slot_);
   addiu(SP, SP, Immediate(-2 * kWordSize));
@@ -903,6 +860,60 @@
 }
 
 
+void Assembler::NoMonomorphicCheckedEntry() {
+  buffer_.Reset();
+  break_(0);
+  break_(0);
+  break_(0);
+  break_(0);
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+}
+
+
+// T0 receiver, S5 guarded cid as Smi
+void Assembler::MonomorphicCheckedEntry() {
+  bool saved_use_far_branches = use_far_branches();
+  set_use_far_branches(false);
+
+  Label have_cid, miss;
+  Bind(&miss);
+  lw(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
+  lw(T9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  jr(T9);
+
+  Comment("MonomorphicCheckedEntry");
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+  SmiUntag(S5);
+  LoadClassIdMayBeSmi(S4, T0);
+  bne(S4, S5, &miss);
+
+  // Fall through to unchecked entry.
+  ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset);
+
+  set_use_far_branches(saved_use_far_branches);
+}
+
+
+#ifndef PRODUCT
+void Assembler::MaybeTraceAllocation(intptr_t cid,
+                                     Register temp_reg,
+                                     Label* trace) {
+  ASSERT(cid > 0);
+  ASSERT(!in_delay_slot_);
+  ASSERT(temp_reg != kNoRegister);
+  ASSERT(temp_reg != TMP);
+  intptr_t state_offset = ClassTable::StateOffsetFor(cid);
+  LoadIsolate(temp_reg);
+  intptr_t table_offset =
+    Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
+  lw(temp_reg, Address(temp_reg, table_offset));
+  AddImmediate(temp_reg, state_offset);
+  lw(temp_reg, Address(temp_reg, 0));
+  andi(CMPRES1, temp_reg, Immediate(ClassHeapStats::TraceAllocationMask()));
+  bne(CMPRES1, ZR, trace);
+}
+
+
 void Assembler::UpdateAllocationStats(intptr_t cid,
                                       Register temp_reg,
                                       Heap::Space space) {
@@ -950,25 +961,7 @@
   addu(TMP, TMP, size_reg);
   sw(TMP, Address(temp_reg, size_field_offset));
 }
-
-
-void Assembler::MaybeTraceAllocation(intptr_t cid,
-                                     Register temp_reg,
-                                     Label* trace) {
-  ASSERT(cid > 0);
-  ASSERT(!in_delay_slot_);
-  ASSERT(temp_reg != kNoRegister);
-  ASSERT(temp_reg != TMP);
-  intptr_t state_offset = ClassTable::StateOffsetFor(cid);
-  LoadIsolate(temp_reg);
-  intptr_t table_offset =
-    Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
-  lw(temp_reg, Address(temp_reg, table_offset));
-  AddImmediate(temp_reg, state_offset);
-  lw(temp_reg, Address(temp_reg, 0));
-  andi(CMPRES1, temp_reg, Immediate(ClassHeapStats::TraceAllocationMask()));
-  bne(CMPRES1, ZR, trace);
-}
+#endif  // !PRODUCT
 
 
 void Assembler::TryAllocate(const Class& cls,
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 39b06a4..095fa74 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -243,7 +243,9 @@
         delay_slot_available_(false),
         in_delay_slot_(false),
         comments_(),
-        constant_pool_allowed_(true) { }
+        constant_pool_allowed_(true) {
+    MonomorphicCheckedEntry();
+  }
   ~Assembler() { }
 
   void PopRegister(Register r) { Pop(r); }
@@ -280,7 +282,6 @@
   }
 
   void set_use_far_branches(bool b) {
-    ASSERT(buffer_.Size() == 0);
     use_far_branches_ = b;
   }
 
@@ -295,6 +296,9 @@
   // the branch delay slot.
   void LeaveStubFrameAndReturn(Register ra = RA);
 
+  void NoMonomorphicCheckedEntry();
+  void MonomorphicCheckedEntry();
+
   void UpdateAllocationStats(intptr_t cid,
                              Register temp_reg,
                              Heap::Space space);
@@ -1472,6 +1476,11 @@
     sra(dst, src, kSmiTagSize);
   }
 
+  void BranchIfNotSmi(Register reg, Label* label) {
+    andi(CMPRES1, reg, Immediate(kSmiTagMask));
+    bne(CMPRES1, ZR, label);
+  }
+
   void LoadFromOffset(Register reg, Register base, int32_t offset) {
     ASSERT(!in_delay_slot_);
     if (Utils::IsInt(kImmBits, offset)) {
@@ -1549,16 +1558,6 @@
   void LoadClassIdMayBeSmi(Register result, Register object);
   void LoadTaggedClassIdMayBeSmi(Register result, Register object);
 
-  void ComputeRange(Register result,
-                    Register value,
-                    Label* miss);
-
-  void UpdateRangeFeedback(Register value,
-                           intptr_t index,
-                           Register ic_data,
-                           Register scratch,
-                           Label* miss);
-
   void StoreIntoObject(Register object,  // Object we are storing into.
                        const Address& dest,  // Where we are storing into.
                        Register value,  // Value we are storing.
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 2072751..2a77101 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -2141,57 +2141,6 @@
 }
 
 
-ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
-  Label miss, done;
-  __ ComputeRange(V0, A0, &miss);
-  __ b(&done);
-
-  __ Bind(&miss);
-  __ LoadImmediate(V0, -1);
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-
-ASSEMBLER_TEST_RUN(ComputeRange, test) {
-  typedef intptr_t (*ComputeRange)(intptr_t value) DART_UNUSED;
-
-#define RANGE_OF(v)                                              \
-  (EXECUTE_TEST_CODE_INTPTR_INTPTR(                              \
-    ComputeRange, test->entry(), reinterpret_cast<intptr_t>(v)))
-
-  EXPECT_EQ(0, RANGE_OF(Smi::New(0)));
-  EXPECT_EQ(0, RANGE_OF(Smi::New(1)));
-  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(-1)));
-  EXPECT_EQ(0, RANGE_OF(Smi::New(Smi::kMaxValue)));
-  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(Smi::kMinValue)));
-
-  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(Smi::kMaxValue + 1)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            RANGE_OF(Integer::New(Smi::kMinValue - 1)));
-  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(kMaxInt32)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            RANGE_OF(Integer::New(kMinInt32)));
-
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxInt32) + 1)));
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            RANGE_OF(Integer::New(kMaxUint32)));
-
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxUint32) + 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit,
-            RANGE_OF(Integer::New(static_cast<int64_t>(kMinInt32) - 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMaxInt64)));
-  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMinInt64)));
-
-  EXPECT_EQ(-1, RANGE_OF(Bool::True().raw()));
-
-#undef RANGE_OF
-}
-
-
 ASSEMBLER_TEST_GENERATE(Semaphore, assembler) {
   __ EnterFrame();
   __ LoadImmediate(T0, 40);
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index c266bf6..74f0ece 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -28,6 +28,7 @@
       constant_pool_allowed_(false) {
   // Far branching mode is only needed and implemented for MIPS and ARM.
   ASSERT(!use_far_branches);
+  MonomorphicCheckedEntry();
 }
 
 
@@ -3321,6 +3322,46 @@
 }
 
 
+void Assembler::NoMonomorphicCheckedEntry() {
+  buffer_.Reset();
+  for (intptr_t i = 0; i < Instructions::kCheckedEntryOffset; i++) {
+    int3();
+  }
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+}
+
+
+// RDI receiver, RBX guarded cid as Smi
+void Assembler::MonomorphicCheckedEntry() {
+  Label immediate, have_cid, miss;
+  Bind(&miss);
+  movq(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
+  movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  jmp(RCX);
+
+  Bind(&immediate);
+  movq(R10, Immediate(kSmiCid));
+  jmp(&have_cid, kNearJump);
+
+  Comment("MonomorphicCheckedEntry");
+  ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
+  SmiUntag(RBX);
+  testq(RDI, Immediate(kSmiTagMask));
+  j(ZERO, &immediate, kNearJump);
+
+  LoadClassId(R10, RDI);
+
+  Bind(&have_cid);
+  cmpq(R10, RBX);
+  j(NOT_EQUAL, &miss, Assembler::kNearJump);
+
+  // Fall through to unchecked entry.
+  ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset);
+  ASSERT((CodeSize() & kSmiTagMask) == kSmiTag);
+}
+
+
+#ifndef PRODUCT
 void Assembler::MaybeTraceAllocation(intptr_t cid,
                                      Label* trace,
                                      bool near_jump) {
@@ -3375,6 +3416,7 @@
   intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
   addq(Address(temp_reg, size_offset), Immediate(size_in_bytes));
 }
+#endif  // !PRODUCT
 
 
 void Assembler::TryAllocate(const Class& cls,
@@ -3673,48 +3715,6 @@
 }
 
 
-void Assembler::ComputeRange(Register result, Register value, Label* not_mint) {
-  Label done, not_smi;
-  testl(value, Immediate(kSmiTagMask));
-  j(NOT_ZERO, &not_smi, Assembler::kNearJump);
-
-  sarq(value, Immediate(32));  // Take the tag into account.
-  movq(result, Immediate(ICData::kUint32RangeBit));  // Uint32
-  cmpq(value, Immediate(1));
-  j(EQUAL, &done, Assembler::kNearJump);
-
-  movq(result, Immediate(ICData::kInt32RangeBit));
-  subq(result, value);  // 10 (positive int32), 11 (negative int32)
-  negq(value);
-  cmpq(value, Immediate(1));
-  j(BELOW_EQUAL, &done);
-
-  // On 64-bit we don't need to track sign of smis outside of the Int32 range.
-  // Just pretend they are all signed.
-  movq(result, Immediate(ICData::kSignedRangeBit));
-  jmp(&done);
-
-  Bind(&not_smi);
-  CompareClassId(value, kMintCid);
-  j(NOT_EQUAL, not_mint);
-  movq(result, Immediate(ICData::kInt64RangeBit));
-
-  Bind(&done);
-}
-
-
-void Assembler::UpdateRangeFeedback(Register value,
-                                    intptr_t index,
-                                    Register ic_data,
-                                    Register scratch,
-                                    Label* miss) {
-  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
-  ComputeRange(scratch, value, miss);
-  shll(scratch, Immediate(ICData::RangeFeedbackShift(index)));
-  orl(FieldAddress(ic_data, ICData::state_bits_offset()), scratch);
-}
-
-
 Address Assembler::ElementAddressForIntIndex(bool is_external,
                                              intptr_t cid,
                                              intptr_t index_scale,
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index f31d37b..651fcd5 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -861,14 +861,11 @@
     sarq(reg, Immediate(kSmiTagSize));
   }
 
-  void ComputeRange(Register result, Register value, Label* miss);
-  void UpdateRangeFeedback(Register value,
-                           intptr_t index,
-                           Register ic_data,
-                           Register scratch,
-                           Label* miss);
+  void BranchIfNotSmi(Register reg, Label* label) {
+    testq(reg, Immediate(kSmiTagMask));
+    j(NOT_ZERO, label);
+  }
 
-  int PreferredLoopAlignment() { return 16; }
   void Align(int alignment, intptr_t offset);
   void Bind(Label* label);
   void Jump(Label* label) { jmp(label); }
@@ -952,6 +949,10 @@
   void EnterStubFrame();
   void LeaveStubFrame();
 
+  void RawEntry() { buffer_.Reset(); }
+  void NoMonomorphicCheckedEntry();
+  void MonomorphicCheckedEntry();
+
   void UpdateAllocationStats(intptr_t cid,
                              Heap::Space space);
 
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index eb8219d..8a3c373 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -3113,6 +3113,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(TestNop, assembler) {
+  __ RawEntry();
+
   __ nop(1);
   __ nop(2);
   __ nop(3);
@@ -3128,12 +3130,14 @@
 
 ASSEMBLER_TEST_RUN(TestNop, test) {
   typedef int (*TestNop)();
-  int res = reinterpret_cast<TestNop>(test->entry())();
+  int res = reinterpret_cast<TestNop>(test->payload_start())();
   EXPECT_EQ(36, res);  // 36 nop bytes emitted.
 }
 
 
 ASSEMBLER_TEST_GENERATE(TestAlign0, assembler) {
+  __ RawEntry();
+
   __ Align(4, 0);
   __ movq(RAX, Immediate(assembler->CodeSize()));  // Return code size.
   __ ret();
@@ -3142,12 +3146,14 @@
 
 ASSEMBLER_TEST_RUN(TestAlign0, test) {
   typedef int (*TestAlign0)();
-  int res = reinterpret_cast<TestAlign0>(test->entry())();
+  int res = reinterpret_cast<TestAlign0>(test->payload_start())();
   EXPECT_EQ(0, res);  // 0 bytes emitted.
 }
 
 
 ASSEMBLER_TEST_GENERATE(TestAlign1, assembler) {
+  __ RawEntry();
+
   __ nop(1);
   __ Align(4, 0);
   __ movq(RAX, Immediate(assembler->CodeSize()));  // Return code size.
@@ -3157,12 +3163,14 @@
 
 ASSEMBLER_TEST_RUN(TestAlign1, test) {
   typedef int (*TestAlign1)();
-  int res = reinterpret_cast<TestAlign1>(test->entry())();
+  int res = reinterpret_cast<TestAlign1>(test->payload_start())();
   EXPECT_EQ(4, res);  // 4 bytes emitted.
 }
 
 
 ASSEMBLER_TEST_GENERATE(TestAlign1Offset1, assembler) {
+  __ RawEntry();
+
   __ nop(1);
   __ Align(4, 1);
   __ movq(RAX, Immediate(assembler->CodeSize()));  // Return code size.
@@ -3172,12 +3180,14 @@
 
 ASSEMBLER_TEST_RUN(TestAlign1Offset1, test) {
   typedef int (*TestAlign1Offset1)();
-  int res = reinterpret_cast<TestAlign1Offset1>(test->entry())();
+  int res = reinterpret_cast<TestAlign1Offset1>(test->payload_start())();
   EXPECT_EQ(3, res);  // 3 bytes emitted.
 }
 
 
 ASSEMBLER_TEST_GENERATE(TestAlignLarge, assembler) {
+  __ RawEntry();
+
   __ nop(1);
   __ Align(16, 0);
   __ movq(RAX, Immediate(assembler->CodeSize()));  // Return code size.
@@ -3187,7 +3197,7 @@
 
 ASSEMBLER_TEST_RUN(TestAlignLarge, test) {
   typedef int (*TestAlignLarge)();
-  int res = reinterpret_cast<TestAlignLarge>(test->entry())();
+  int res = reinterpret_cast<TestAlignLarge>(test->payload_start())();
   EXPECT_EQ(16, res);  // 16 bytes emitted.
 }
 
@@ -3589,55 +3599,6 @@
   EXPECT_EQ(0, res);
 }
 
-
-ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
-  Label miss;
-  __ movq(RDX, CallingConventions::kArg1Reg);
-  __ ComputeRange(RAX, RDX, &miss);
-  __ ret();
-
-  __ Bind(&miss);
-  __ movq(RAX, Immediate(0));
-  __ ret();
-}
-
-
-ASSEMBLER_TEST_RUN(ComputeRange, test) {
-  typedef intptr_t (*ComputeRange)(RawObject*);
-  ComputeRange range_of = reinterpret_cast<ComputeRange>(test->entry());
-
-  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Smi::New(0)));
-  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Smi::New(1)));
-  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Smi::New(kMaxInt32)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            range_of(Smi::New(-1)));
-  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
-            range_of(Smi::New(kMinInt32)));
-
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            range_of(Smi::New(static_cast<int64_t>(kMaxInt32) + 1)));
-  EXPECT_EQ(ICData::kUint32RangeBit,
-            range_of(Smi::New(kMaxUint32)));
-
-  // On 64-bit platforms we don't track the sign of the smis outside of
-  // int32 range because it is not needed to distinguish kInt32Range from
-  // kUint32Range.
-  EXPECT_EQ(ICData::kSignedRangeBit,
-            range_of(Smi::New(static_cast<int64_t>(kMinInt32) - 1)));
-  EXPECT_EQ(ICData::kSignedRangeBit,
-            range_of(Smi::New(static_cast<int64_t>(kMaxUint32) + 1)));
-  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(Smi::kMaxValue)));
-  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(Smi::kMinValue)));
-
-  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(Smi::kMaxValue + 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(Smi::kMinValue - 1)));
-  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMaxInt64)));
-  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMinInt64)));
-
-  EXPECT_EQ(0, range_of(Bool::True().raw()));
-}
-
-
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/atomic.h b/runtime/vm/atomic.h
index b6e5f28..d6a833b 100644
--- a/runtime/vm/atomic.h
+++ b/runtime/vm/atomic.h
@@ -51,14 +51,9 @@
 
   // Performs a load of a word from 'ptr', but without any guarantees about
   // memory order (i.e., no load barriers/fences).
-  static uword LoadRelaxed(uword* ptr) {
-    return *static_cast<volatile uword*>(ptr);
-  }
-
-  // Performs a load of a word from 'ptr', but without any guarantees about
-  // memory order (i.e., no load barriers/fences).
-  static intptr_t LoadRelaxedIntPtr(intptr_t* ptr) {
-    return *static_cast<volatile intptr_t*>(ptr);
+  template <typename T>
+  static T LoadRelaxed(T* ptr) {
+    return *static_cast<volatile T*>(ptr);
   }
 };
 
diff --git a/runtime/vm/atomic_fuchsia.h b/runtime/vm/atomic_fuchsia.h
index d6c0f57..67dd329 100644
--- a/runtime/vm/atomic_fuchsia.h
+++ b/runtime/vm/atomic_fuchsia.h
@@ -13,34 +13,30 @@
 #error This file should only be included on Fuchsia builds.
 #endif
 
-#include "platform/assert.h"
-
 namespace dart {
 
 inline uintptr_t AtomicOperations::FetchAndIncrement(uintptr_t* p) {
-  UNIMPLEMENTED();
-  return 0;
+  return __sync_fetch_and_add(p, 1);
 }
 
 
 inline void AtomicOperations::IncrementBy(intptr_t* p, intptr_t value) {
-  UNIMPLEMENTED();
+  __sync_fetch_and_add(p, value);
 }
 
 
 inline void AtomicOperations::IncrementInt64By(int64_t* p, int64_t value) {
-  UNIMPLEMENTED();
+  __sync_fetch_and_add(p, value);
 }
 
 
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
-  UNIMPLEMENTED();
-  return 0;
+  return __sync_fetch_and_sub(p, 1);
 }
 
 
 inline void AtomicOperations::DecrementBy(intptr_t* p, intptr_t value) {
-  UNIMPLEMENTED();
+  __sync_fetch_and_sub(p, value);
 }
 
 
@@ -48,16 +44,14 @@
 inline uword AtomicOperations::CompareAndSwapWord(uword* ptr,
                                                   uword old_value,
                                                   uword new_value) {
-  UNIMPLEMENTED();
-  return 0;
+  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) {
-  UNIMPLEMENTED();
-  return 0;
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
 }
 #endif  // !defined(USING_SIMULATOR_ATOMICS)
 
diff --git a/runtime/vm/become.cc b/runtime/vm/become.cc
index 13b7439..0850584 100644
--- a/runtime/vm/become.cc
+++ b/runtime/vm/become.cc
@@ -148,6 +148,79 @@
 };
 
 
+// On IA32, object pointers are embedded directly in the instruction stream,
+// which is normally write-protected, so we need to make it temporarily writable
+// to forward the pointers. On all other architectures, object pointers are
+// accessed through ObjectPools.
+#if defined(TARGET_ARCH_IA32)
+class WritableCodeLiteralsScope : public ValueObject {
+ public:
+  explicit WritableCodeLiteralsScope(Heap* heap) : heap_(heap) {
+    if (FLAG_write_protect_code) {
+      heap_->WriteProtectCode(false);
+    }
+  }
+
+  ~WritableCodeLiteralsScope() {
+    if (FLAG_write_protect_code) {
+      heap_->WriteProtectCode(true);
+    }
+  }
+
+ private:
+  Heap* heap_;
+};
+#else
+class WritableCodeLiteralsScope : public ValueObject {
+ public:
+  explicit WritableCodeLiteralsScope(Heap* heap) { }
+  ~WritableCodeLiteralsScope() { }
+};
+#endif
+
+
+void Become::MakeDummyObject(const Instance& instance) {
+  // Make the forward pointer point to itself.
+  // This is needed to distinguish it from a real forward object.
+  ForwardObjectTo(instance.raw(), instance.raw());
+}
+
+
+static bool IsDummyObject(RawObject* object) {
+  if (!object->IsForwardingCorpse()) return false;
+  return GetForwardedObject(object) == object;
+}
+
+
+void Become::CrashDump(RawObject* before_obj, RawObject* after_obj) {
+  OS::PrintErr("DETECTED FATAL ISSUE IN BECOME MAPPINGS\n");
+
+  OS::PrintErr("BEFORE ADDRESS: %p\n", before_obj);
+  OS::PrintErr("BEFORE IS HEAP OBJECT: %s",
+               before_obj->IsHeapObject() ? "YES" : "NO");
+  OS::PrintErr("BEFORE IS VM HEAP OBJECT: %s",
+               before_obj->IsVMHeapObject() ? "YES" : "NO");
+
+  OS::PrintErr("AFTER ADDRESS: %p\n", after_obj);
+  OS::PrintErr("AFTER IS HEAP OBJECT: %s",
+               after_obj->IsHeapObject() ? "YES" : "NO");
+  OS::PrintErr("AFTER IS VM HEAP OBJECT: %s",
+               after_obj->IsVMHeapObject() ? "YES" : "NO");
+
+  if (before_obj->IsHeapObject()) {
+    OS::PrintErr("BEFORE OBJECT CLASS ID=%" Pd "\n", before_obj->GetClassId());
+    const Object& obj = Object::Handle(before_obj);
+    OS::PrintErr("BEFORE OBJECT AS STRING=%s\n", obj.ToCString());
+  }
+
+  if (after_obj->IsHeapObject()) {
+    OS::PrintErr("AFTER OBJECT CLASS ID=%" Pd "\n", after_obj->GetClassId());
+    const Object& obj = Object::Handle(after_obj);
+    OS::PrintErr("AFTER OBJECT AS STRING=%s\n", obj.ToCString());
+  }
+}
+
+
 void Become::ElementsForwardIdentity(const Array& before, const Array& after) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
@@ -166,15 +239,18 @@
       FATAL("become: Cannot self-forward");
     }
     if (!before_obj->IsHeapObject()) {
+      CrashDump(before_obj, after_obj);
       FATAL("become: Cannot forward immediates");
     }
     if (!after_obj->IsHeapObject()) {
-      FATAL("become: Cannot become an immediates");
+      CrashDump(before_obj, after_obj);
+      FATAL("become: Cannot become immediates");
     }
     if (before_obj->IsVMHeapObject()) {
+      CrashDump(before_obj, after_obj);
       FATAL("become: Cannot forward VM heap objects");
     }
-    if (before_obj->IsForwardingCorpse()) {
+    if (before_obj->IsForwardingCorpse() && !IsDummyObject(before_obj)) {
       FATAL("become: Cannot forward to multiple targets");
     }
     if (after_obj->IsForwardingCorpse()) {
@@ -199,9 +275,12 @@
     isolate->VisitWeakPersistentHandles(&handle_visitor);
 
     //   Heap pointers (may require updating the remembered set)
-    ForwardHeapPointersVisitor object_visitor(&pointer_visitor);
-    heap->VisitObjects(&object_visitor);
-    pointer_visitor.VisitingObject(NULL);
+    {
+      WritableCodeLiteralsScope writable_code(heap);
+      ForwardHeapPointersVisitor object_visitor(&pointer_visitor);
+      heap->VisitObjects(&object_visitor);
+      pointer_visitor.VisitingObject(NULL);
+    }
 
 #if !defined(PRODUCT)
     tds.SetNumArguments(2);
diff --git a/runtime/vm/become.h b/runtime/vm/become.h
index b78524d..12ab764 100644
--- a/runtime/vm/become.h
+++ b/runtime/vm/become.h
@@ -80,6 +80,14 @@
   // in 'after'. Every element in 'before' is guaranteed to be not reachable.
   // Useful for atomically applying behavior and schema changes.
   static void ElementsForwardIdentity(const Array& before, const Array& after);
+
+  // Convert and instance object into a dummy object,
+  // making the instance independent of its class.
+  // (used for morphic instances during reload).
+  static void MakeDummyObject(const Instance& instance);
+
+ private:
+  static void CrashDump(RawObject* before_obj, RawObject* after_obj);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/bit_vector.cc b/runtime/vm/bit_vector.cc
index bf18147..cc38df3 100644
--- a/runtime/vm/bit_vector.cc
+++ b/runtime/vm/bit_vector.cc
@@ -100,6 +100,16 @@
 }
 
 
+bool BitVector::IsEmpty() const {
+  for (intptr_t i = 0; i < data_length_; i++) {
+    if (data_[i] != 0) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
 void BitVector::Print() const {
   OS::Print("[");
   for (intptr_t i = 0; i < length_; i++) {
diff --git a/runtime/vm/bit_vector.h b/runtime/vm/bit_vector.h
index af5122d..9afa05f 100644
--- a/runtime/vm/bit_vector.h
+++ b/runtime/vm/bit_vector.h
@@ -84,6 +84,8 @@
 
   void Intersect(const BitVector* other);
 
+  bool IsEmpty() const;
+
   bool Contains(intptr_t i) const {
     ASSERT(i >= 0 && i < length());
     uword block = data_[i / kBitsPerWord];
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 4bb5e93..161d0b2 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -21,6 +21,7 @@
   V(Object_noSuchMethod, 6)                                                    \
   V(Object_runtimeType, 1)                                                     \
   V(Object_instanceOf, 4)                                                      \
+  V(Object_simpleInstanceOf, 2)                                                \
   V(Object_instanceOfNum, 2)                                                   \
   V(Object_instanceOfInt, 2)                                                   \
   V(Object_instanceOfSmi, 2)                                                   \
@@ -365,6 +366,7 @@
   V(VMService_CancelStream, 1)                                                 \
   V(VMService_RequestAssets, 0)                                                \
   V(VMService_DecodeAssets, 1)                                                 \
+  V(VMService_spawnUriNotify, 2)                                               \
 
 // List of bootstrap native entry points used in the dart:mirror library.
 #define MIRRORS_BOOTSTRAP_NATIVE_LIST(V)                                       \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 6554d23..1191301 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2521,12 +2521,15 @@
 // getter function object for each enumeration value and for the
 // values field. We also don't have to generate the code for these getters
 // from thin air (no source code is available).
-void ClassFinalizer::AllocateEnumValues(const Class &enum_cls) {
+void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const Field& index_field =
       Field::Handle(zone, enum_cls.LookupInstanceField(Symbols::Index()));
   ASSERT(!index_field.IsNull());
+  const Field& name_field = Field::Handle(zone,
+        enum_cls.LookupInstanceFieldAllowPrivate(Symbols::_name()));
+  ASSERT(!name_field.IsNull());
   const Field& values_field =
       Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values()));
   ASSERT(!values_field.IsNull());
@@ -2539,6 +2542,11 @@
   Instance& ordinal_value = Instance::Handle(zone);
   Instance& enum_value = Instance::Handle(zone);
 
+  const String& enum_name = String::Handle(enum_cls.ScrubbedName());
+  const String& name_prefix =
+      String::Handle(String::Concat(enum_name, Symbols::Dot()));
+
+  String& enum_ident = String::Handle();
   for (intptr_t i = 0; i < fields.Length(); i++) {
     field = Field::RawCast(fields.At(i));
     if (!field.is_static()) continue;
@@ -2547,8 +2555,18 @@
     // contain the smi value of the ordinal number, which was stored in
     // the field by the parser. Other fields contain non-smi values.
     if (!ordinal_value.IsSmi()) continue;
+    enum_ident = field.name();
+    // Construct the string returned by toString.
+    ASSERT(!enum_ident.IsNull());
+    // For the user-visible name of the enumeration value, we need to
+    // unmangle private names.
+    if (enum_ident.CharAt(0) == '_') {
+      enum_ident = String::ScrubName(enum_ident);
+    }
+    enum_ident = Symbols::FromConcat(thread, name_prefix, enum_ident);
     enum_value = Instance::New(enum_cls, Heap::kOld);
     enum_value.SetField(index_field, ordinal_value);
+    enum_value.SetField(name_field, enum_ident);
     const char* error_msg = "";
     enum_value = enum_value.CheckAndCanonicalize(thread, &error_msg);
     ASSERT(!enum_value.IsNull());
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 4549fb8..e8d8ae8 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -19,9 +19,9 @@
 
 ClassTable::ClassTable()
     : top_(kNumPredefinedCids), capacity_(0), table_(NULL),
-      old_tables_(new MallocGrowableArray<RawClass**>()),
-      class_heap_stats_table_(NULL),
-      predefined_class_heap_stats_table_(NULL) {
+      old_tables_(new MallocGrowableArray<RawClass**>()) {
+  NOT_IN_PRODUCT(class_heap_stats_table_ = NULL);
+  NOT_IN_PRODUCT(predefined_class_heap_stats_table_ = NULL);
   if (Dart::vm_isolate() == NULL) {
     capacity_ = initial_capacity_;
     table_ = reinterpret_cast<RawClass**>(
@@ -39,17 +39,22 @@
     table_[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse);
     table_[kDynamicCid] = vm_class_table->At(kDynamicCid);
     table_[kVoidCid] = vm_class_table->At(kVoidCid);
+
+#ifndef PRODUCT
     class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>(
         calloc(capacity_, sizeof(ClassHeapStats)));  // NOLINT
     for (intptr_t i = 0; i < capacity_; i++) {
       class_heap_stats_table_[i].Initialize();
     }
+#endif  // !PRODUCT
   }
+#ifndef PRODUCT
   predefined_class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>(
         calloc(kNumPredefinedCids, sizeof(ClassHeapStats)));  // NOLINT
   for (intptr_t i = 0; i < kNumPredefinedCids; i++) {
     predefined_class_heap_stats_table_[i].Initialize();
   }
+#endif  // !PRODUCT
 }
 
 
@@ -57,9 +62,9 @@
     : top_(original->top_),
       capacity_(original->top_),
       table_(original->table_),
-      old_tables_(NULL),
-      class_heap_stats_table_(NULL),
-      predefined_class_heap_stats_table_(NULL) {
+      old_tables_(NULL) {
+  NOT_IN_PRODUCT(class_heap_stats_table_ = NULL);
+  NOT_IN_PRODUCT(predefined_class_heap_stats_table_ = NULL);
 }
 
 
@@ -68,16 +73,22 @@
     FreeOldTables();
     delete old_tables_;
     free(table_);
-    free(predefined_class_heap_stats_table_);
-    free(class_heap_stats_table_);
+    NOT_IN_PRODUCT(free(predefined_class_heap_stats_table_));
+    NOT_IN_PRODUCT(free(class_heap_stats_table_));
   } else {
     // This instance was a shallow copy. It doesn't own any memory.
-    ASSERT(predefined_class_heap_stats_table_ == NULL);
-    ASSERT(class_heap_stats_table_ == NULL);
+    NOT_IN_PRODUCT(ASSERT(predefined_class_heap_stats_table_ == NULL));
+    NOT_IN_PRODUCT(ASSERT(class_heap_stats_table_ == NULL));
   }
 }
 
 
+void ClassTable::AddOldTable(RawClass** old_table) {
+  ASSERT(Thread::Current()->IsMutatorThread());
+  old_tables_->Add(old_table);
+}
+
+
 void ClassTable::FreeOldTables() {
   while (old_tables_->length() > 0) {
     free(old_tables_->RemoveLast());
@@ -85,6 +96,7 @@
 }
 
 
+#ifndef PRODUCT
 void ClassTable::SetTraceAllocationFor(intptr_t cid, bool trace) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   stats->set_trace_allocation(trace);
@@ -95,6 +107,7 @@
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   return stats->trace_allocation();
 }
+#endif  // !PRODUCT
 
 
 void ClassTable::Register(const Class& cls) {
@@ -120,17 +133,19 @@
       RawClass** new_table = reinterpret_cast<RawClass**>(
           malloc(new_capacity * sizeof(RawClass*)));  // NOLINT
       memmove(new_table, table_, capacity_ * sizeof(RawClass*));
+#ifndef PRODUCT
       ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
           realloc(class_heap_stats_table_,
                   new_capacity * sizeof(ClassHeapStats)));  // NOLINT
+#endif
       for (intptr_t i = capacity_; i < new_capacity; i++) {
         new_table[i] = NULL;
-        new_stats_table[i].Initialize();
+        NOT_IN_PRODUCT(new_stats_table[i].Initialize());
       }
       capacity_ = new_capacity;
       old_tables_->Add(table_);
       table_ = new_table;  // TODO(koda): This should use atomics.
-      class_heap_stats_table_ = new_stats_table;
+      NOT_IN_PRODUCT(class_heap_stats_table_ = new_stats_table);
     }
     ASSERT(top_ < capacity_);
     if (!Class::is_valid_id(top_)) {
@@ -156,17 +171,19 @@
     RawClass** new_table = reinterpret_cast<RawClass**>(
         malloc(new_capacity * sizeof(RawClass*)));  // NOLINT
     memmove(new_table, table_, capacity_ * sizeof(RawClass*));
+#ifndef PRODUCT
     ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
         realloc(class_heap_stats_table_,
                 new_capacity * sizeof(ClassHeapStats)));  // NOLINT
+#endif
     for (intptr_t i = capacity_; i < new_capacity; i++) {
       new_table[i] = NULL;
-      new_stats_table[i].Initialize();
+      NOT_IN_PRODUCT(new_stats_table[i].Initialize());
     }
     capacity_ = new_capacity;
     old_tables_->Add(table_);
     table_ = new_table;  // TODO(koda): This should use atomics.
-    class_heap_stats_table_ = new_stats_table;
+    NOT_IN_PRODUCT(class_heap_stats_table_ = new_stats_table);
     ASSERT(capacity_increment_ >= 1);
   }
 
@@ -252,7 +269,6 @@
     }
   }
 }
-#endif  // PRODUCT
 
 
 void ClassHeapStats::Initialize() {
@@ -264,6 +280,7 @@
   promoted_count = 0;
   promoted_size = 0;
   state_ = 0;
+  USE(align_);
 }
 
 
@@ -332,7 +349,6 @@
 }
 
 
-#ifndef PRODUCT
 void ClassHeapStats::PrintToJSONObject(const Class& cls,
                                        JSONObject* obj) const {
   if (!FLAG_support_service) {
@@ -369,7 +385,6 @@
   obj->AddProperty("promotedInstances", promoted_count);
   obj->AddProperty("promotedBytes", promoted_size);
 }
-#endif
 
 
 void ClassTable::UpdateAllocatedNew(intptr_t cid, intptr_t size) {
@@ -496,7 +511,6 @@
 }
 
 
-#ifndef PRODUCT
 void ClassTable::AllocationProfilePrintJSON(JSONStream* stream) {
   if (!FLAG_support_service) {
     return;
@@ -507,14 +521,18 @@
   ASSERT(heap != NULL);
   JSONObject obj(stream);
   obj.AddProperty("type", "AllocationProfile");
-  obj.AddPropertyF(
-      "dateLastAccumulatorReset",
-      "%" Pd64 "",
-      isolate->last_allocationprofile_accumulator_reset_timestamp());
-  obj.AddPropertyF(
-      "dateLastServiceGC",
-      "%" Pd64 "",
-      isolate->last_allocationprofile_gc_timestamp());
+  if (isolate->last_allocationprofile_accumulator_reset_timestamp() != 0) {
+    obj.AddPropertyF(
+        "dateLastAccumulatorReset",
+        "%" Pd64 "",
+        isolate->last_allocationprofile_accumulator_reset_timestamp());
+  }
+  if (isolate->last_allocationprofile_gc_timestamp() != 0) {
+    obj.AddPropertyF(
+        "dateLastServiceGC",
+        "%" Pd64 "",
+        isolate->last_allocationprofile_gc_timestamp());
+  }
 
   {
     JSONObject heaps(&obj, "heaps");
@@ -538,7 +556,6 @@
     }
   }
 }
-#endif
 
 
 void ClassTable::ResetAllocationAccumulators() {
@@ -566,6 +583,7 @@
   ASSERT(size >= 0);
   stats->post_gc.AddNew(size);
 }
+#endif  // !PRODUCT
 
 
 }  // namespace dart
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 9a12fc3e..1722dec 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -20,6 +20,7 @@
 class ObjectPointerVisitor;
 class RawClass;
 
+#ifndef PRODUCT
 template<typename T>
 class AllocStats {
  public:
@@ -141,8 +142,9 @@
   intptr_t old_pre_new_gc_count_;
   intptr_t old_pre_new_gc_size_;
   intptr_t state_;
+  intptr_t align_;  // Make SIMARM and ARM agree on the size of ClassHeapStats.
 };
-
+#endif  // !PRODUCT
 
 class ClassTable {
  public:
@@ -194,15 +196,16 @@
   void Validate();
 
   void Print();
-#ifndef PRODUCT
-  void PrintToJSONObject(JSONObject* object);
-#endif
 
   // Used by the generated code.
   static intptr_t table_offset() {
     return OFFSET_OF(ClassTable, table_);
   }
 
+  // Used by the generated code.
+  static intptr_t ClassOffsetFor(intptr_t cid);
+
+#ifndef PRODUCT
   // Called whenever a class is allocated in the runtime.
   void UpdateAllocatedNew(intptr_t cid, intptr_t size);
   void UpdateAllocatedOld(intptr_t cid, intptr_t size);
@@ -215,9 +218,6 @@
   void UpdatePromoted();
 
   // Used by the generated code.
-  static intptr_t ClassOffsetFor(intptr_t cid);
-
-  // Used by the generated code.
   ClassHeapStats** TableAddressFor(intptr_t cid);
   static intptr_t TableOffsetFor(intptr_t cid);
 
@@ -235,6 +235,10 @@
   void AllocationProfilePrintJSON(JSONStream* stream);
   void ResetAllocationAccumulators();
 
+  void PrintToJSONObject(JSONObject* object);
+#endif  // !PRODUCT
+
+  void AddOldTable(RawClass** old_table);
   // Deallocates table copies. Do not call during concurrent access to table.
   void FreeOldTables();
 
@@ -257,14 +261,15 @@
   RawClass** table_;
   MallocGrowableArray<RawClass**>* old_tables_;
 
+#ifndef PRODUCT
   ClassHeapStats* class_heap_stats_table_;
-
   ClassHeapStats* predefined_class_heap_stats_table_;
 
   // May not have updated size for variable size classes.
   ClassHeapStats* PreliminaryStatsAt(intptr_t cid);
   void UpdateLiveOld(intptr_t cid, intptr_t size, intptr_t count = 1);
   void UpdateLiveNew(intptr_t cid, intptr_t size);
+#endif  // !PRODUCT
 
   DISALLOW_COPY_AND_ASSIGN(ClassTable);
 };
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index e938fef..fe51886 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -78,15 +78,15 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kClassCid);
     intptr_t count = predefined_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClass* cls = predefined_[i];
       intptr_t class_id = cls->ptr()->id_;
-      s->Write<intptr_t>(class_id);
+      s->WriteCid(class_id);
       s->AssignRef(cls);
     }
     count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClass* cls = objects_[i];
       s->AssignRef(cls);
@@ -137,10 +137,10 @@
   void ReadAlloc(Deserializer* d) {
     predefined_start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     ClassTable* table = d->isolate()->class_table();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t class_id = d->Read<intptr_t>();
+      intptr_t class_id = d->ReadCid();
       ASSERT(table->HasValidClassAt(class_id));
       RawClass* cls = table->At(class_id);
       ASSERT(cls != NULL);
@@ -149,7 +149,7 @@
     predefined_stop_index_ = d->next_index();
 
     start_index_ = d->next_index();
-    count = d->Read<intptr_t>();
+    count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          Class::InstanceSize()));
@@ -174,8 +174,13 @@
 
       intptr_t class_id = d->ReadCid();
       cls->ptr()->id_ = class_id;
-      cls->ptr()->instance_size_in_words_ = d->Read<int32_t>();
-      cls->ptr()->next_field_offset_in_words_ = d->Read<int32_t>();
+      if (!RawObject::IsInternalVMdefinedClassId(class_id)) {
+        cls->ptr()->instance_size_in_words_ = d->Read<int32_t>();
+        cls->ptr()->next_field_offset_in_words_ = d->Read<int32_t>();
+      } else {
+        d->Read<int32_t>();  // Skip.
+        d->Read<int32_t>();  // Skip.
+      }
       cls->ptr()->type_arguments_field_offset_in_words_ = d->Read<int32_t>();
       cls->ptr()->num_type_arguments_ = d->Read<uint16_t>();
       cls->ptr()->num_own_type_arguments_ = d->Read<uint16_t>();
@@ -261,7 +266,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kUnresolvedClassCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawUnresolvedClass* cls = objects_[i];
       s->AssignRef(cls);
@@ -270,7 +275,7 @@
 
   void WriteFill(Serializer* s) {
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawUnresolvedClass* cls = objects_[i];
       RawObject** from = cls->from();
@@ -295,7 +300,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          UnresolvedClass::InstanceSize()));
@@ -342,11 +347,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeArgumentsCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypeArguments* type_args = objects_[i];
       intptr_t length = Smi::Value(type_args->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(type_args);
     }
   }
@@ -356,7 +361,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawTypeArguments* type_args = objects_[i];
       intptr_t length = Smi::Value(type_args->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->Write<bool>(type_args->IsCanonical());
       intptr_t hash = Smi::Value(type_args->ptr()->hash_);
       s->Write<int32_t>(hash);
@@ -380,9 +385,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
                                          TypeArguments::InstanceSize(length)));
     }
@@ -395,7 +400,7 @@
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTypeArguments* type_args =
           reinterpret_cast<RawTypeArguments*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
                                      TypeArguments::InstanceSize(length),
@@ -432,7 +437,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kPatchClassCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawPatchClass* cls = objects_[i];
       s->AssignRef(cls);
@@ -464,7 +469,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          PatchClass::InstanceSize()));
@@ -514,7 +519,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kFunctionCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawFunction* func = objects_[i];
       s->AssignRef(func);
@@ -572,7 +577,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          Function::InstanceSize()));
@@ -684,7 +689,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kClosureDataCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClosureData* data = objects_[i];
       s->AssignRef(data);
@@ -716,7 +721,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          ClosureData::InstanceSize()));
@@ -760,7 +765,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kRedirectionDataCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawRedirectionData* data = objects_[i];
       s->AssignRef(data);
@@ -792,7 +797,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          RedirectionData::InstanceSize()));
@@ -864,7 +869,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kFieldCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawField* field = objects_[i];
       s->AssignRef(field);
@@ -929,7 +934,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Field::InstanceSize()));
     }
@@ -1006,7 +1011,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLiteralTokenCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLiteralToken* token = objects_[i];
       s->AssignRef(token);
@@ -1039,7 +1044,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          LiteralToken::InstanceSize()));
@@ -1085,7 +1090,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTokenStreamCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTokenStream* stream = objects_[i];
       s->AssignRef(stream);
@@ -1117,7 +1122,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          TokenStream::InstanceSize()));
@@ -1161,7 +1166,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kScriptCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawScript* script = objects_[i];
       s->AssignRef(script);
@@ -1198,7 +1203,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Script::InstanceSize()));
     }
@@ -1251,7 +1256,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLibraryCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLibrary* lib = objects_[i];
       s->AssignRef(lib);
@@ -1289,7 +1294,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Library::InstanceSize()));
     }
@@ -1361,7 +1366,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kNamespaceCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawNamespace* ns = objects_[i];
       s->AssignRef(ns);
@@ -1393,7 +1398,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Namespace::InstanceSize()));
     }
@@ -1436,7 +1441,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kCodeCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawCode* code = objects_[i];
       s->AssignRef(code);
@@ -1496,7 +1501,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Code::InstanceSize(0)));
     }
@@ -1514,9 +1519,10 @@
       int32_t text_offset = d->Read<int32_t>();
       RawInstructions* instr = reinterpret_cast<RawInstructions*>(
           d->GetInstructionsAt(text_offset) + kHeapObjectTag);
-      uword entry_point = Instructions::EntryPoint(instr);
 
-      code->ptr()->entry_point_ = entry_point;
+      code->ptr()->entry_point_ = Instructions::UncheckedEntryPoint(instr);
+      code->ptr()->checked_entry_point_ =
+          Instructions::CheckedEntryPoint(instr);
       code->ptr()->active_instructions_ = instr;
       code->ptr()->instructions_ = instr;
       code->ptr()->object_pool_ =
@@ -1571,11 +1577,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kObjectPoolCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawObjectPool* pool = objects_[i];
       intptr_t length = pool->ptr()->length_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(pool);
     }
   }
@@ -1586,7 +1592,7 @@
       RawObjectPool* pool = objects_[i];
       RawTypedData* info_array = pool->ptr()->info_array_;
       intptr_t length = pool->ptr()->length_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       for (intptr_t j = 0; j < length; j++) {
         ObjectPool::EntryType entry_type =
             static_cast<ObjectPool::EntryType>(info_array->ptr()->data()[j]);
@@ -1638,9 +1644,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
                                          ObjectPool::InstanceSize(length)));
     }
@@ -1651,7 +1657,7 @@
     bool is_vm_object = d->isolate() == Dart::vm_isolate();
     PageSpace* old_space = d->heap()->old_space();
     for (intptr_t id = start_index_; id < stop_index_; id += 1) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       RawTypedData* info_array = reinterpret_cast<RawTypedData*>(
           AllocateUninitialized(old_space, TypedData::InstanceSize(length)));
       Deserializer::InitializeHeader(info_array, kTypedDataUint8ArrayCid,
@@ -1728,7 +1734,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawObject* object = objects_[i];
       int32_t rodata_offset = s->GetRODataOffset(object);
@@ -1753,7 +1759,7 @@
   virtual ~RODataDeserializationCluster() { }
 
   void ReadAlloc(Deserializer* d) {
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       int32_t rodata_offset = d->Read<int32_t>();
       d->AssignRef(d->GetObjectAt(rodata_offset));
@@ -1795,11 +1801,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kExceptionHandlersCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawExceptionHandlers* handlers = objects_[i];
       intptr_t length = handlers->ptr()->num_entries_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(handlers);
     }
   }
@@ -1809,7 +1815,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawExceptionHandlers* handlers = objects_[i];
       intptr_t length = handlers->ptr()->num_entries_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->WriteRef(handlers->ptr()->handled_types_data_);
 
       uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
@@ -1832,9 +1838,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
           ExceptionHandlers::InstanceSize(length)));
     }
@@ -1847,7 +1853,7 @@
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawExceptionHandlers* handlers =
           reinterpret_cast<RawExceptionHandlers*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
                                      ExceptionHandlers::InstanceSize(length),
                                      is_vm_object);
@@ -1882,11 +1888,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kContextCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawContext* context = objects_[i];
       intptr_t length = context->ptr()->num_variables_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(context);
     }
   }
@@ -1896,7 +1902,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawContext* context = objects_[i];
       intptr_t length = context->ptr()->num_variables_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->WriteRef(context->ptr()->parent_);
       for (intptr_t j = 0; j < length; j++) {
         s->WriteRef(context->ptr()->data()[j]);
@@ -1917,9 +1923,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
                                          Context::InstanceSize(length)));
     }
@@ -1931,7 +1937,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawContext* context = reinterpret_cast<RawContext*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       Deserializer::InitializeHeader(context, kContextCid,
                                      Context::InstanceSize(length),
                                      is_vm_object);
@@ -1965,11 +1971,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kContextScopeCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawContextScope* scope = objects_[i];
       intptr_t length = scope->ptr()->num_variables_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(scope);
     }
   }
@@ -1979,7 +1985,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawContextScope* scope = objects_[i];
       intptr_t length = scope->ptr()->num_variables_;
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->Write<bool>(scope->ptr()->is_implicit_);
       RawObject** from = scope->from();
       RawObject** to = scope->to(length);
@@ -2002,9 +2008,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
                                          ContextScope::InstanceSize(length)));
     }
@@ -2016,7 +2022,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawContextScope* scope = reinterpret_cast<RawContextScope*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       Deserializer::InitializeHeader(scope, kContextScopeCid,
                                      ContextScope::InstanceSize(length),
                                      is_vm_object);
@@ -2051,7 +2057,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kICDataCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawICData* ic = objects_[i];
       s->AssignRef(ic);
@@ -2071,7 +2077,7 @@
       s->Write<int32_t>(ic->ptr()->deopt_id_);
       s->Write<uint32_t>(ic->ptr()->state_bits_);
 #if defined(TAG_IC_DATA)
-      s->Write<intptr_t>(ic->ptr()->tag_);
+      s->Write<int32_t>(ic->ptr()->tag_);
 #endif
     }
   }
@@ -2089,7 +2095,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, ICData::InstanceSize()));
     }
@@ -2116,33 +2122,10 @@
       ic->ptr()->deopt_id_ = d->Read<int32_t>();
       ic->ptr()->state_bits_ = d->Read<int32_t>();
 #if defined(TAG_IC_DATA)
-      ic->ptr()->tag_ = d->Read<intptr_t>();
+      ic->ptr()->tag_ = d->Read<int32_t>();
 #endif
     }
   }
-
-  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(),
-        Timeline::GetIsolateStream(), "PostLoadICData"));
-
-    if (kind == Snapshot::kAppNoJIT) {
-      ICData& ic = ICData::Handle(zone);
-      Object& funcOrCode = Object::Handle(zone);
-      Code& code = Code::Handle(zone);
-      Smi& entry_point = Smi::Handle(zone);
-      for (intptr_t i = start_index_; i < stop_index_; i++) {
-        ic ^= refs.At(i);
-        for (intptr_t j = 0; j < ic.NumberOfChecks(); j++) {
-          funcOrCode = ic.GetTargetOrCodeAt(j);
-          if (funcOrCode.IsCode()) {
-            code ^= funcOrCode.raw();
-            entry_point = Smi::FromAlignedAddress(code.EntryPoint());
-            ic.SetEntryPointAt(j, entry_point);
-          }
-        }
-      }
-    }
-  }
 };
 
 
@@ -2165,7 +2148,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kMegamorphicCacheCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawMegamorphicCache* cache = objects_[i];
       s->AssignRef(cache);
@@ -2198,7 +2181,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          MegamorphicCache::InstanceSize()));
@@ -2240,7 +2223,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kSubtypeTestCacheCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawSubtypeTestCache* cache = objects_[i];
       s->AssignRef(cache);
@@ -2268,7 +2251,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          SubtypeTestCache::InstanceSize()));
@@ -2310,7 +2293,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLanguageErrorCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLanguageError* error = objects_[i];
       s->AssignRef(error);
@@ -2345,7 +2328,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          LanguageError::InstanceSize()));
@@ -2393,7 +2376,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kUnhandledExceptionCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawUnhandledException* exception = objects_[i];
       s->AssignRef(exception);
@@ -2425,7 +2408,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          UnhandledException::InstanceSize()));
@@ -2456,10 +2439,9 @@
  public:
   explicit InstanceSerializationCluster(intptr_t cid) : cid_(cid) {
     RawClass* cls = Isolate::Current()->class_table()->At(cid);
-    next_field_offset_ =
-        cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2;
+    next_field_offset_in_words_ = cls->ptr()->next_field_offset_in_words_;
     instance_size_in_words_ = cls->ptr()->instance_size_in_words_;
-    ASSERT(next_field_offset_ > 0);
+    ASSERT(next_field_offset_in_words_ > 0);
     ASSERT(instance_size_in_words_ > 0);
   }
   virtual ~InstanceSerializationCluster() { }
@@ -2468,8 +2450,9 @@
     RawInstance* instance = Instance::RawCast(object);
     objects_.Add(instance);
 
+    intptr_t next_field_offset = next_field_offset_in_words_ << kWordSizeLog2;
     intptr_t offset = Instance::NextFieldOffset();
-    while (offset < next_field_offset_) {
+    while (offset < next_field_offset) {
       RawObject* raw_obj = *reinterpret_cast<RawObject**>(
           reinterpret_cast<uword>(instance->ptr()) + offset);
       s->Push(raw_obj);
@@ -2478,12 +2461,12 @@
   }
 
   void WriteAlloc(Serializer* s) {
-    s->Write<intptr_t>(cid_);
+    s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
 
-    s->Write<intptr_t>(next_field_offset_);
-    s->Write<intptr_t>(instance_size_in_words_);
+    s->Write<int32_t>(next_field_offset_in_words_);
+    s->Write<int32_t>(instance_size_in_words_);
 
     for (intptr_t i = 0; i < count; i++) {
       RawInstance* instance = objects_[i];
@@ -2492,12 +2475,13 @@
   }
 
   void WriteFill(Serializer* s) {
+    intptr_t next_field_offset = next_field_offset_in_words_ << kWordSizeLog2;
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawInstance* instance = objects_[i];
       s->Write<bool>(instance->IsCanonical());
       intptr_t offset = Instance::NextFieldOffset();
-      while (offset < next_field_offset_) {
+      while (offset < next_field_offset) {
         RawObject* raw_obj = *reinterpret_cast<RawObject**>(
             reinterpret_cast<uword>(instance->ptr()) + offset);
         s->WriteRef(raw_obj);
@@ -2508,7 +2492,7 @@
 
  private:
   const intptr_t cid_;
-  intptr_t next_field_offset_;
+  intptr_t next_field_offset_in_words_;
   intptr_t instance_size_in_words_;
   GrowableArray<RawInstance*> objects_;
 };
@@ -2522,9 +2506,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
-    next_field_offset_  = d->Read<intptr_t>();
-    instance_size_in_words_  = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
+    next_field_offset_in_words_ = d->Read<int32_t>();
+    instance_size_in_words_ = d->Read<int32_t>();
     intptr_t instance_size =
         Object::RoundedAllocationSize(instance_size_in_words_ * kWordSize);
     for (intptr_t i = 0; i < count; i++) {
@@ -2534,6 +2518,7 @@
   }
 
   void ReadFill(Deserializer* d) {
+    intptr_t next_field_offset = next_field_offset_in_words_ << kWordSizeLog2;
     intptr_t instance_size =
         Object::RoundedAllocationSize(instance_size_in_words_ * kWordSize);
     bool is_vm_object = d->isolate() == Dart::vm_isolate();
@@ -2545,7 +2530,7 @@
                                      instance_size,
                                      is_vm_object, is_canonical);
       intptr_t offset = Instance::NextFieldOffset();
-      while (offset < next_field_offset_) {
+      while (offset < next_field_offset) {
         RawObject** p = reinterpret_cast<RawObject**>(
             reinterpret_cast<uword>(instance->ptr()) + offset);
         *p = d->ReadRef();
@@ -2563,7 +2548,7 @@
 
  private:
   const intptr_t cid_;
-  intptr_t next_field_offset_;
+  intptr_t next_field_offset_in_words_;
   intptr_t instance_size_in_words_;
 };
 
@@ -2587,7 +2572,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLibraryPrefixCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLibraryPrefix* prefix = objects_[i];
       s->AssignRef(prefix);
@@ -2622,7 +2607,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          LibraryPrefix::InstanceSize()));
@@ -2680,13 +2665,13 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeCid);
     intptr_t count = canonical_objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawType* type = canonical_objects_[i];
       s->AssignRef(type);
     }
     count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawType* type = objects_[i];
       s->AssignRef(type);
@@ -2732,14 +2717,14 @@
   void ReadAlloc(Deserializer* d) {
     canonical_start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
     }
     canonical_stop_index_ = d->next_index();
 
     start_index_ = d->next_index();
-    count = d->Read<intptr_t>();
+    count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
     }
@@ -2803,7 +2788,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeRefCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypeRef* type = objects_[i];
       s->AssignRef(type);
@@ -2835,7 +2820,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, TypeRef::InstanceSize()));
     }
@@ -2879,7 +2864,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeParameterCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypeParameter* type = objects_[i];
       s->AssignRef(type);
@@ -2895,7 +2880,7 @@
       for (RawObject** p = from; p <= to; p++) {
         s->WriteRef(*p);
       }
-      s->Write<intptr_t>(type->ptr()->parameterized_class_id_);
+      s->Write<int32_t>(type->ptr()->parameterized_class_id_);
       s->WriteTokenPosition(type->ptr()->token_pos_);
       s->Write<int16_t>(type->ptr()->index_);
       s->Write<int8_t>(type->ptr()->type_state_);
@@ -2915,7 +2900,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          TypeParameter::InstanceSize()));
@@ -2936,7 +2921,7 @@
       for (RawObject** p = from; p <= to; p++) {
         *p = d->ReadRef();
       }
-      type->ptr()->parameterized_class_id_ = d->Read<intptr_t>();
+      type->ptr()->parameterized_class_id_ = d->Read<int32_t>();
       type->ptr()->token_pos_ = d->ReadTokenPosition();
       type->ptr()->index_ = d->Read<int16_t>();
       type->ptr()->type_state_ = d->Read<int8_t>();
@@ -2964,7 +2949,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kBoundedTypeCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawBoundedType* type = objects_[i];
       s->AssignRef(type);
@@ -2996,7 +2981,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          BoundedType::InstanceSize()));
@@ -3040,7 +3025,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kClosureCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawClosure* closure = objects_[i];
       s->AssignRef(closure);
@@ -3073,7 +3058,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Closure::InstanceSize()));
     }
@@ -3105,31 +3090,38 @@
   virtual ~MintSerializationCluster() { }
 
   void Trace(Serializer* s, RawObject* object) {
-    RawMint* mint = Mint::RawCast(object);
-    objects_.Add(mint);
+    if (!object->IsHeapObject()) {
+      RawSmi* smi = Smi::RawCast(object);
+      smis_.Add(smi);
+    } else {
+      RawMint* mint = Mint::RawCast(object);
+      mints_.Add(mint);
+    }
   }
 
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kMintCid);
-    intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
-    for (intptr_t i = 0; i < count; i++) {
-      RawMint* mint = objects_[i];
+
+    s->Write<int32_t>(smis_.length() + mints_.length());
+    for (intptr_t i = 0; i < smis_.length(); i++) {
+      RawSmi* smi = smis_[i];
+      s->Write<bool>(true);
+      s->Write<int64_t>(Smi::Value(smi));
+      s->AssignRef(smi);
+    }
+    for (intptr_t i = 0; i < mints_.length(); i++) {
+      RawMint* mint = mints_[i];
+      s->Write<bool>(mint->IsCanonical());
+      s->Write<int64_t>(mint->ptr()->value_);
       s->AssignRef(mint);
     }
   }
 
-  void WriteFill(Serializer* s) {
-    intptr_t count = objects_.length();
-    for (intptr_t i = 0; i < count; i++) {
-      RawMint* mint = objects_[i];
-      s->Write<bool>(mint->IsCanonical());
-      s->Write<int64_t>(mint->ptr()->value_);
-    }
-  }
+  void WriteFill(Serializer* s) { }
 
  private:
-  GrowableArray<RawMint*> objects_;
+  GrowableArray<RawSmi*> smis_;
+  GrowableArray<RawMint*> mints_;
 };
 
 
@@ -3139,26 +3131,49 @@
   virtual ~MintDeserializationCluster() { }
 
   void ReadAlloc(Deserializer* d) {
-    start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    bool is_vm_object = d->isolate() == Dart::vm_isolate();
+
+    start_index_ = d->next_index();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      d->AssignRef(AllocateUninitialized(old_space, Mint::InstanceSize()));
+      bool is_canonical = d->Read<bool>();
+      int64_t value = d->Read<int64_t>();
+      if (Smi::IsValid(value)) {
+        d->AssignRef(Smi::New(value));
+      } else {
+        RawMint* mint = static_cast<RawMint*>(
+            AllocateUninitialized(old_space, Mint::InstanceSize()));
+        Deserializer::InitializeHeader(mint, kMintCid,
+                                       Mint::InstanceSize(),
+                                       is_vm_object, is_canonical);
+        mint->ptr()->value_ = value;
+        d->AssignRef(mint);
+      }
     }
     stop_index_ = d->next_index();
   }
 
-  void ReadFill(Deserializer* d) {
-    bool is_vm_object = d->isolate() == Dart::vm_isolate();
+  void ReadFill(Deserializer* d) { }
 
-    for (intptr_t id = start_index_; id < stop_index_; id++) {
-      RawMint* mint = reinterpret_cast<RawMint*>(d->Ref(id));
-      bool is_canonical = d->Read<bool>();
-      Deserializer::InitializeHeader(mint, kMintCid,
-                                     Mint::InstanceSize(),
-                                     is_vm_object, is_canonical);
-      mint->ptr()->value_ = d->Read<int64_t>();
+  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+    NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(),
+        Timeline::GetIsolateStream(), "PostLoadMint"));
+
+    const GrowableObjectArray& new_constants =
+        GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+    Object& number = Object::Handle(zone);
+    for (intptr_t i = start_index_; i < stop_index_; i++) {
+      number = refs.At(i);
+      if (number.IsMint() && number.IsCanonical()) {
+        new_constants.Add(number);
+      }
     }
+    const Array& constants_array =
+        Array::Handle(zone, Array::MakeArray(new_constants));
+    const Class& mint_cls = Class::Handle(zone,
+        Isolate::Current()->object_store()->mint_class());
+    mint_cls.set_constants(constants_array);
   }
 };
 
@@ -3182,7 +3197,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kBigintCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawBigint* bigint = objects_[i];
       s->AssignRef(bigint);
@@ -3215,7 +3230,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Bigint::InstanceSize()));
     }
@@ -3254,7 +3269,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kDoubleCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawDouble* dbl = objects_[i];
       s->AssignRef(dbl);
@@ -3283,7 +3298,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space, Double::InstanceSize()));
     }
@@ -3324,7 +3339,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kGrowableObjectArrayCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawGrowableObjectArray* array = objects_[i];
       s->AssignRef(array);
@@ -3358,7 +3373,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          GrowableObjectArray::InstanceSize()));
@@ -3397,13 +3412,13 @@
   }
 
   void WriteAlloc(Serializer* s) {
-    s->Write<intptr_t>(cid_);
+    s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTypedData* data = objects_[i];
       intptr_t length = Smi::Value(data->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(data);
     }
   }
@@ -3414,7 +3429,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawTypedData* data = objects_[i];
       intptr_t length = Smi::Value(data->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->Write<bool>(data->IsCanonical());
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
       s->WriteBytes(cdata, length * element_size);
@@ -3435,10 +3450,10 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
           TypedData::InstanceSize(length * element_size)));
     }
@@ -3451,7 +3466,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTypedData* data = reinterpret_cast<RawTypedData*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       bool is_canonical = d->Read<bool>();
       intptr_t length_in_bytes = length * element_size;
       Deserializer::InitializeHeader(data, cid_,
@@ -3480,9 +3495,9 @@
   }
 
   void WriteAlloc(Serializer* s) {
-    s->Write<intptr_t>(cid_);
+    s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawExternalTypedData* data = objects_[i];
       s->AssignRef(data);
@@ -3495,7 +3510,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawExternalTypedData* data = objects_[i];
       intptr_t length = Smi::Value(data->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data_);
       s->WriteBytes(cdata, length * element_size);
     }
@@ -3515,7 +3530,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          ExternalTypedData::InstanceSize()));
@@ -3530,7 +3545,7 @@
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawExternalTypedData* data =
           reinterpret_cast<RawExternalTypedData*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       Deserializer::InitializeHeader(data, cid_,
                                      ExternalTypedData::InstanceSize(),
                                      is_vm_object);
@@ -3564,7 +3579,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kStacktraceCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawStacktrace* trace = objects_[i];
       s->AssignRef(trace);
@@ -3596,7 +3611,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          Stacktrace::InstanceSize()));
@@ -3640,7 +3655,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kRegExpCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawRegExp* regexp = objects_[i];
       s->AssignRef(regexp);
@@ -3657,7 +3672,7 @@
         s->WriteRef(*p);
       }
 
-      s->Write<intptr_t>(regexp->ptr()->num_registers_);
+      s->Write<int32_t>(regexp->ptr()->num_registers_);
       s->Write<int8_t>(regexp->ptr()->type_flags_);
     }
   }
@@ -3675,7 +3690,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          RegExp::InstanceSize()));
@@ -3696,7 +3711,7 @@
         *p = d->ReadRef();
       }
 
-      regexp->ptr()->num_registers_ = d->Read<intptr_t>();
+      regexp->ptr()->num_registers_ = d->Read<int32_t>();
       regexp->ptr()->type_flags_ = d->Read<int8_t>();
     }
   }
@@ -3730,7 +3745,7 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kLinkedHashMapCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawLinkedHashMap* map = objects_[i];
       s->AssignRef(map);
@@ -3750,7 +3765,7 @@
       const intptr_t deleted_keys = Smi::Value(map->ptr()->deleted_keys_);
 
       // Write out the number of (not deleted) key/value pairs that will follow.
-      s->Write<intptr_t>((used_data >> 1) - deleted_keys);
+      s->Write<int32_t>((used_data >> 1) - deleted_keys);
 
       RawArray* data_array = map->ptr()->data_;
       RawObject** data_elements = data_array->ptr()->data();
@@ -3778,7 +3793,7 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(AllocateUninitialized(old_space,
                                          LinkedHashMap::InstanceSize()));
@@ -3801,7 +3816,7 @@
           reinterpret_cast<RawTypeArguments*>(d->ReadRef());
 
       // TODO(rmacnak): Reserve ref ids and co-allocate in ReadAlloc.
-      intptr_t pairs = d->Read<intptr_t>();
+      intptr_t pairs = d->Read<int32_t>();
       intptr_t used_data = pairs << 1;
       intptr_t data_size = Utils::Maximum(
           Utils::RoundUpToPowerOfTwo(used_data),
@@ -3848,11 +3863,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(cid_);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawArray* array = objects_[i];
       intptr_t length = Smi::Value(array->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(array);
     }
   }
@@ -3862,7 +3877,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawArray* array = objects_[i];
       intptr_t length = Smi::Value(array->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->Write<bool>(array->IsCanonical());
       s->WriteRef(array->ptr()->type_arguments_);
       for (intptr_t j = 0; j < length; j++) {
@@ -3885,9 +3900,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
                                          Array::InstanceSize(length)));
     }
@@ -3899,7 +3914,7 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawArray* array = reinterpret_cast<RawArray*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(array, cid_,
                                      Array::InstanceSize(length),
@@ -3931,11 +3946,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kOneByteStringCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawOneByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(str);
     }
   }
@@ -3945,7 +3960,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawOneByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->Write<bool>(str->IsCanonical());
       intptr_t hash = Smi::Value(str->ptr()->hash_);
       s->Write<int32_t>(hash);
@@ -3966,9 +3981,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
                                          OneByteString::InstanceSize(length)));
     }
@@ -3980,13 +3995,13 @@
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(str, kOneByteStringCid,
                                      OneByteString::InstanceSize(length),
                                      is_vm_object, is_canonical);
       str->ptr()->length_ = Smi::New(length);
-      str->ptr()->hash_ = Smi::New(d->Read<intptr_t>());
+      str->ptr()->hash_ = Smi::New(d->Read<int32_t>());
       for (intptr_t j = 0; j < length; j++) {
         str->ptr()->data()[j] = d->Read<uint8_t>();
       }
@@ -4008,11 +4023,11 @@
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTwoByteStringCid);
     intptr_t count = objects_.length();
-    s->Write<intptr_t>(count);
+    s->Write<int32_t>(count);
     for (intptr_t i = 0; i < count; i++) {
       RawTwoByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->AssignRef(str);
     }
   }
@@ -4022,7 +4037,7 @@
     for (intptr_t i = 0; i < count; i++) {
       RawTwoByteString* str = objects_[i];
       intptr_t length = Smi::Value(str->ptr()->length_);
-      s->Write<intptr_t>(length);
+      s->Write<int32_t>(length);
       s->Write<bool>(str->IsCanonical());
       intptr_t hash = Smi::Value(str->ptr()->hash_);
       s->Write<int32_t>(hash);
@@ -4043,9 +4058,9 @@
   void ReadAlloc(Deserializer* d) {
     start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    intptr_t count = d->Read<intptr_t>();
+    intptr_t count = d->Read<int32_t>();
     for (intptr_t i = 0; i < count; i++) {
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       d->AssignRef(AllocateUninitialized(old_space,
                                          TwoByteString::InstanceSize(length)));
     }
@@ -4058,7 +4073,7 @@
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTwoByteString* str =
           reinterpret_cast<RawTwoByteString*>(d->Ref(id));
-      intptr_t length = d->Read<intptr_t>();
+      intptr_t length = d->Read<int32_t>();
       bool is_canonical = d->Read<bool>();
       Deserializer::InitializeHeader(str, kTwoByteStringCid,
                                      TwoByteString::InstanceSize(length),
@@ -4196,7 +4211,9 @@
 void Serializer::Trace(RawObject* object) {
   intptr_t cid;
   if (!object->IsHeapObject()) {
-    cid = kSmiCid;
+    // Smis are merged into the Mint cluster because Smis for the writer might
+    // become Mints for the reader and vice versa.
+    cid = kMintCid;
   } else {
     cid = object->GetClassId();
   }
@@ -4227,7 +4244,7 @@
 
 
 #if defined(DEBUG)
-static const intptr_t kSectionMarker = 0xABAB;
+static const int32_t kSectionMarker = 0xABAB;
 #endif
 
 void Serializer::Serialize() {
@@ -4244,6 +4261,11 @@
   }
 
   intptr_t num_objects = num_base_objects_ + num_written_objects_;
+#if defined(ARCH_IS_64_BIT)
+  if (!Utils::IsInt(32, num_objects)) {
+    FATAL("Ref overflow");
+  }
+#endif
 
   Write<int32_t>(num_objects);
   Write<int32_t>(num_clusters);
@@ -4253,7 +4275,7 @@
     if (cluster != NULL) {
       cluster->WriteAlloc(this);
 #if defined(DEBUG)
-      Write<intptr_t>(next_ref_index_);
+      Write<int32_t>(next_ref_index_);
 #endif
     }
   }
@@ -4266,7 +4288,7 @@
     if (cluster != NULL) {
       cluster->WriteFill(this);
 #if defined(DEBUG)
-      Write<intptr_t>(kSectionMarker);
+      Write<int32_t>(kSectionMarker);
 #endif
     }
   }
@@ -4336,7 +4358,7 @@
   }
 
 #if defined(DEBUG)
-  Write<intptr_t>(kSectionMarker);
+  Write<int32_t>(kSectionMarker);
 #endif
 
   // Note we are not clearing the object id table. The full ref table
@@ -4379,7 +4401,7 @@
   }
 
 #if defined(DEBUG)
-  Write<intptr_t>(kSectionMarker);
+  Write<int32_t>(kSectionMarker);
 #endif
 
   heap_->ResetObjectIdTable();
@@ -4599,7 +4621,7 @@
       clusters_[i] = ReadCluster();
       clusters_[i]->ReadAlloc(this);
 #if defined(DEBUG)
-      intptr_t serializers_next_ref_index_ = Read<intptr_t>();
+      intptr_t serializers_next_ref_index_ = Read<int32_t>();
       ASSERT(serializers_next_ref_index_ == next_ref_index_);
 #endif
     }
@@ -4614,7 +4636,7 @@
     for (intptr_t i = 0; i < num_clusters_; i++) {
       clusters_[i]->ReadFill(this);
 #if defined(DEBUG)
-      intptr_t section_marker = Read<intptr_t>();
+      int32_t section_marker = Read<int32_t>();
       ASSERT(section_marker == kSectionMarker);
 #endif
     }
@@ -4698,7 +4720,7 @@
     }
 
 #if defined(DEBUG)
-    intptr_t section_marker = Read<intptr_t>();
+    int32_t section_marker = Read<int32_t>();
     ASSERT(section_marker == kSectionMarker);
 #endif
 
@@ -4739,7 +4761,7 @@
     }
 
 #if defined(DEBUG)
-    intptr_t section_marker = Read<intptr_t>();
+    int32_t section_marker = Read<int32_t>();
     ASSERT(section_marker == kSectionMarker);
 #endif
 
@@ -4766,27 +4788,27 @@
 }
 
 
-// An object visitor which will iterate over all the script objects in the heap
-// and either count them or collect them into an array. This is used during
-// full snapshot generation of the VM isolate to write out all script
-// objects and their accompanying token streams.
-class ScriptVisitor : public ObjectVisitor {
+// An object visitor which will iterate over all the token stream objects in the
+// heap and either count them or collect them into an array. This is used during
+// full snapshot generation of the VM isolate to write out all token streams so
+// they will be shared across all isolates.
+class SnapshotTokenStreamVisitor : public ObjectVisitor {
  public:
-  explicit ScriptVisitor(Thread* thread) :
+  explicit SnapshotTokenStreamVisitor(Thread* thread) :
       objHandle_(Object::Handle(thread->zone())),
       count_(0),
-      scripts_(NULL) {}
+      token_streams_(NULL) {}
 
-  ScriptVisitor(Thread* thread, const Array* scripts) :
+  SnapshotTokenStreamVisitor(Thread* thread, const Array* token_streams) :
       objHandle_(Object::Handle(thread->zone())),
       count_(0),
-      scripts_(scripts) {}
+      token_streams_(token_streams) {}
 
   void VisitObject(RawObject* obj) {
-    if (obj->IsScript()) {
-      if (scripts_ != NULL) {
+    if (obj->IsTokenStream()) {
+      if (token_streams_ != NULL) {
         objHandle_ = obj;
-        scripts_->SetAt(count_, objHandle_);
+        token_streams_->SetAt(count_, objHandle_);
       }
       count_ += 1;
     }
@@ -4797,7 +4819,7 @@
  private:
   Object& objHandle_;
   intptr_t count_;
-  const Array* scripts_;
+  const Array* token_streams_;
 };
 
 
@@ -4814,7 +4836,7 @@
       vm_isolate_snapshot_size_(0),
       isolate_snapshot_size_(0),
       instructions_writer_(instructions_writer),
-      scripts_(Array::Handle(zone())),
+      token_streams_(Array::Handle(zone())),
       saved_symbol_table_(Array::Handle(zone())),
       new_vm_symbol_table_(Array::Handle(zone())) {
   ASSERT(isolate_snapshot_buffer_ != NULL);
@@ -4837,16 +4859,16 @@
     NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
         Timeline::GetIsolateStream(), "PrepareNewVMIsolate"));
 
-    // Collect all the script objects and their accompanying token stream
-    // objects into an array so that we can write it out as part of the VM
-    // isolate snapshot. We first count the number of script objects, allocate
-    // an array and then fill it up with the script objects.
-    ScriptVisitor scripts_counter(thread());
-    heap()->IterateOldObjects(&scripts_counter);
-    Dart::vm_isolate()->heap()->IterateOldObjects(&scripts_counter);
-    intptr_t count = scripts_counter.count();
-    scripts_ = Array::New(count, Heap::kOld);
-    ScriptVisitor script_visitor(thread(), &scripts_);
+    // Collect all the token stream objects into an array so that we can write
+    // it out as part of the VM isolate snapshot. We first count the number of
+    // token streams, allocate an array and then fill it up with the token
+    // streams.
+    SnapshotTokenStreamVisitor token_streams_counter(thread());
+    heap()->IterateOldObjects(&token_streams_counter);
+    Dart::vm_isolate()->heap()->IterateOldObjects(&token_streams_counter);
+    intptr_t count = token_streams_counter.count();
+    token_streams_ = Array::New(count, Heap::kOld);
+    SnapshotTokenStreamVisitor script_visitor(thread(), &token_streams_);
     heap()->IterateOldObjects(&script_visitor);
     Dart::vm_isolate()->heap()->IterateOldObjects(&script_visitor);
     ASSERT(script_visitor.count() == count);
@@ -4873,7 +4895,7 @@
     saved_symbol_table_ = Array::null();
   }
   new_vm_symbol_table_ = Array::null();
-  scripts_ = Array::null();
+  token_streams_ = Array::null();
 }
 
 
@@ -4894,11 +4916,11 @@
   /*
    * Now Write out the following
    * - the symbol table
-   * - all the scripts and token streams for these scripts
+   * - all the token streams
    * - the stub code (precompiled snapshots only)
    **/
   intptr_t num_objects = serializer.WriteVMSnapshot(new_vm_symbol_table_,
-                                                    scripts_);
+                                                    token_streams_);
   serializer.FillHeader(serializer.kind());
 
   vm_isolate_snapshot_size_ = serializer.bytes_written();
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index b2bdd0c..aae4e82 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -12,6 +12,7 @@
 #include "vm/exceptions.h"
 #include "vm/globals.h"
 #include "vm/growable_array.h"
+#include "vm/hash_map.h"
 #include "vm/heap.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
@@ -83,15 +84,34 @@
 };
 
 
-enum {
-  kRefTagSize = 1,
-  kRefTagShift = 1,
-  kRefTagMask = 1,
-  kSmiRefTag = 0x0,
-  kHeapRefTag = 0x1,
+class SmiObjectIdPair {
+ public:
+  SmiObjectIdPair() : smi_(NULL), id_(0) { }
+  RawSmi* smi_;
+  intptr_t id_;
+
+  bool operator==(const SmiObjectIdPair& other) const {
+    return (smi_ == other.smi_) && (id_ == other.id_);
+  }
 };
 
 
+class SmiObjectIdPairTrait {
+ public:
+  typedef RawSmi* Key;
+  typedef intptr_t Value;
+  typedef SmiObjectIdPair Pair;
+
+  static Key KeyOf(Pair kv) { return kv.smi_; }
+  static Value ValueOf(Pair kv) { return kv.id_; }
+  static inline intptr_t Hashcode(Key key) { return Smi::Value(key); }
+  static inline bool IsKeyEqual(Pair kv, Key key) { return kv.smi_ == key; }
+};
+
+
+typedef DirectChainedHashMap<SmiObjectIdPairTrait> SmiObjectIdMap;
+
+
 class Serializer : public StackResource {
  public:
   Serializer(Thread* thread,
@@ -114,13 +134,36 @@
 
   void AssignRef(RawObject* object) {
     ASSERT(next_ref_index_ != 0);
-    heap_->SetObjectId(object, next_ref_index_);
-    ASSERT(heap_->GetObjectId(object) == next_ref_index_);
+    if (object->IsHeapObject()) {
+      heap_->SetObjectId(object, next_ref_index_);
+      ASSERT(heap_->GetObjectId(object) == next_ref_index_);
+    } else {
+      RawSmi* smi = Smi::RawCast(object);
+      SmiObjectIdPair* existing_pair = smi_ids_.Lookup(smi);
+      if (existing_pair != NULL) {
+        ASSERT(existing_pair->id_ == 1);
+        existing_pair->id_ = next_ref_index_;
+      } else {
+        SmiObjectIdPair new_pair;
+        new_pair.smi_ = smi;
+        new_pair.id_ = next_ref_index_;
+        smi_ids_.Insert(new_pair);
+      }
+    }
     next_ref_index_++;
   }
 
   void Push(RawObject* object) {
     if (!object->IsHeapObject()) {
+      RawSmi* smi = Smi::RawCast(object);
+      if (smi_ids_.Lookup(smi) == NULL) {
+        SmiObjectIdPair pair;
+        pair.smi_ = smi;
+        pair.id_ = 1;
+        smi_ids_.Insert(pair);
+        stack_.Add(object);
+        num_written_objects_++;
+      }
       return;
     }
 
@@ -180,9 +223,12 @@
 
   void WriteRef(RawObject* object) {
     if (!object->IsHeapObject()) {
-      ASSERT(static_cast<intptr_t>(kSmiRefTag) ==
-             static_cast<intptr_t>(kSmiTag));
-      Write<intptr_t>(reinterpret_cast<intptr_t>(object));
+      RawSmi* smi = Smi::RawCast(object);
+      intptr_t id = smi_ids_.Lookup(smi)->id_;
+      if (id == 0) {
+        FATAL("Missing ref");
+      }
+      Write<int32_t>(id);
       return;
     }
 
@@ -200,7 +246,7 @@
       }
       FATAL("Missing ref");
     }
-    Write<intptr_t>((id << kRefTagShift) | kHeapRefTag);
+    Write<int32_t>(id);
   }
 
   void WriteTokenPosition(TokenPosition pos) {
@@ -234,6 +280,7 @@
   intptr_t num_base_objects_;
   intptr_t num_written_objects_;
   intptr_t next_ref_index_;
+  SmiObjectIdMap smi_ids_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(Serializer);
 };
@@ -300,13 +347,8 @@
   }
 
   RawObject* ReadRef() {
-    intptr_t index = Read<intptr_t>();
-    if ((index & kRefTagMask) == kSmiRefTag) {
-      ASSERT(static_cast<intptr_t>(kSmiRefTag) ==
-             static_cast<intptr_t>(kSmiTag));
-      return reinterpret_cast<RawSmi*>(index);
-    }
-    return Ref(index >> kRefTagShift);
+    int32_t index = Read<int32_t>();
+    return Ref(index);
   }
 
   TokenPosition ReadTokenPosition() {
@@ -400,7 +442,7 @@
   intptr_t isolate_snapshot_size_;
   ForwardList* forward_list_;
   InstructionsWriter* instructions_writer_;
-  Array& scripts_;
+  Array& token_streams_;
   Array& saved_symbol_table_;
   Array& new_vm_symbol_table_;
 
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 4b572a7..ca1ba0b 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -91,6 +91,35 @@
 }
 
 
+DEFINE_RUNTIME_ENTRY(RangeError, 2) {
+  const Instance& length = Instance::CheckedHandle(arguments.ArgAt(0));
+  const Instance& index = Instance::CheckedHandle(arguments.ArgAt(1));
+  if (!length.IsInteger()) {
+    // Throw: new ArgumentError.value(length, "length", "is not an integer");
+    const Array& args = Array::Handle(Array::New(3));
+    args.SetAt(0, length);
+    args.SetAt(1, Symbols::Length());
+    args.SetAt(2, String::Handle(String::New("is not an integer")));
+    Exceptions::ThrowByType(Exceptions::kArgumentValue, args);
+  }
+  if (!index.IsInteger()) {
+    // Throw: new ArgumentError.value(index, "index", "is not an integer");
+    const Array& args = Array::Handle(Array::New(3));
+    args.SetAt(0, index);
+    args.SetAt(1, Symbols::Index());
+    args.SetAt(2, String::Handle(String::New("is not an integer")));
+    Exceptions::ThrowByType(Exceptions::kArgumentValue, args);
+  }
+  // Throw: new RangeError.range(index, 0, length, "length");
+  const Array& args = Array::Handle(Array::New(4));
+  args.SetAt(0, index);
+  args.SetAt(1, Integer::Handle(Integer::New(0)));
+  args.SetAt(2, length);
+  args.SetAt(3, Symbols::Length());
+  Exceptions::ThrowByType(Exceptions::kRange, args);
+}
+
+
 // Allocation of a fixed length array of given element type.
 // This runtime entry is never called for allocating a List of a generic type,
 // because a prior run time call instantiates the element type if necessary.
@@ -642,7 +671,7 @@
         " to '%s' new entry point %#" Px " (%s)\n",
         caller_frame->pc(),
         target_function.ToFullyQualifiedCString(),
-        target_code.EntryPoint(),
+        target_code.UncheckedEntryPoint(),
         target_code.is_optimized() ? "optimized" : "unoptimized");
   }
   arguments.SetReturn(target_code);
@@ -782,6 +811,25 @@
   return result.raw();
 }
 
+
+// Perform the subtype and return constant function based on the result.
+static RawFunction* ComputeTypeCheckTarget(const Instance& receiver,
+                                           const AbstractType& type,
+                                           const ArgumentsDescriptor& desc) {
+  const TypeArguments& checked_type_arguments = TypeArguments::Handle();
+  Error& error = Error::Handle();
+  bool result = receiver.IsInstanceOf(type, checked_type_arguments, &error);
+  ASSERT(error.IsNull());
+  ObjectStore* store = Isolate::Current()->object_store();
+  const Function& target
+      = Function::Handle(result
+                         ? store->simple_instance_of_true_function()
+                         : store->simple_instance_of_false_function());
+  ASSERT(!target.IsNull());
+  return target.raw();;
+}
+
+
 static RawFunction* InlineCacheMissHandler(
     const GrowableArray<const Instance*>& args,
     const ICData& ic_data) {
@@ -790,8 +838,17 @@
       arguments_descriptor(Array::Handle(ic_data.arguments_descriptor()));
   String& function_name = String::Handle(ic_data.target_name());
   ASSERT(function_name.IsSymbol());
+
   Function& target_function = Function::Handle(
       Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor));
+
+  ObjectStore* store = Isolate::Current()->object_store();
+  if (target_function.raw() == store->simple_instance_of_function()) {
+    // Replace the target function with constant function.
+    const AbstractType& type = AbstractType::Cast(*args[1]);
+    target_function
+        = ComputeTypeCheckTarget(receiver, type, arguments_descriptor);
+  }
   if (target_function.IsNull()) {
     if (FLAG_trace_ic) {
       OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n",
@@ -971,12 +1028,88 @@
 
 // Handle a miss of a megamorphic cache.
 //   Arg0: Receiver.
+//   Returns: the ICData used to continue with a polymorphic call.
+DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) {
+#if defined(TARGET_ARCH_DBC)
+  // DBC does not use switchable calls.
+  UNREACHABLE();
+#else
+  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+
+  DartFrameIterator iterator;
+  StackFrame* caller_frame = iterator.NextFrame();
+  ASSERT(caller_frame->IsDartFrame());
+  const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
+  const Function& caller_function =
+      Function::Handle(zone, caller_frame->LookupDartFunction());
+
+  Smi& old_expected_cid = Smi::Handle(zone);
+  old_expected_cid ^= CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(),
+                                                          caller_code);
+  const Code& old_target_code =
+      Code::Handle(CodePatcher::GetSwitchableCallTargetAt(caller_frame->pc(),
+                                                          caller_code));
+  Function& old_target = Function::Handle(zone);
+  old_target ^= old_target_code.owner();
+
+  // We lost the original ICData when we patched to the monomorphic case.
+  const String& name = String::Handle(zone, old_target.name());
+  ASSERT(!old_target.HasOptionalParameters());
+  const Array& descriptor = Array::Handle(zone,
+      ArgumentsDescriptor::New(old_target.num_fixed_parameters()));
+  const ICData& ic_data =
+      ICData::Handle(zone, ICData::New(caller_function,
+                                       name,
+                                       descriptor,
+                                       Thread::kNoDeoptId,
+                                       1, /* args_tested */
+                                       false /* static_call */));
+
+  // Add the first target.
+  ic_data.AddReceiverCheck(old_expected_cid.Value(), old_target);
+
+  // Maybe add the new target.
+  Class& cls = Class::Handle(zone, receiver.clazz());
+  ArgumentsDescriptor args_desc(descriptor);
+  Function& target_function = Function::Handle(zone,
+      Resolver::ResolveDynamicForReceiverClass(cls,
+                                               name,
+                                               args_desc));
+  if (target_function.IsNull()) {
+    target_function = InlineCacheMissHelper(receiver, descriptor, name);
+  }
+  if (target_function.IsNull()) {
+    ASSERT(!FLAG_lazy_dispatchers);
+  } else {
+    ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+  }
+
+  // Patch to call through stub.
+  const Code& stub =
+      Code::Handle(zone, StubCode::ICLookupThroughCode_entry()->code());
+  ASSERT(!Isolate::Current()->compilation_allowed());
+  CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
+                                     caller_code,
+                                     ic_data,
+                                     stub);
+
+  // Return the ICData. The miss stub will jump to continue in the IC lookup
+  // stub.
+  arguments.SetReturn(ic_data);
+#endif  // !defined(TARGET_ARCH_DBC)
+}
+
+
+// Handle a miss of a megamorphic cache.
+//   Arg0: Receiver.
 //   Arg1: ICData or MegamorphicCache.
 //   Arg2: Arguments descriptor array.
 //   Returns: target function to call.
 DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
-// DBC does not use megamorphic calls right now.
-#if !defined(TARGET_ARCH_DBC)
+#if defined(TARGET_ARCH_DBC)
+  // DBC does not use megamorphic calls right now.
+  UNREACHABLE();
+#else
   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));
@@ -1010,21 +1143,58 @@
 
   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));
+
+    if ((ic_data.NumberOfChecks() == 0) &&
+        !target_function.HasOptionalParameters() &&
+        !Isolate::Current()->compilation_allowed()) {
+      // This call site is unlinked: transition to a monomorphic direct call.
+      // Note we cannot do this if the target has optional parameters because
+      // the monomorphic direct call does not load the arguments descriptor.
+      // We cannot do this if we are still in the middle of precompiling because
+      // the monomorphic case hides an live instance selector from the
+      // treeshaker.
+
+      if (!target_function.HasCode()) {
+        const Error& error =
+          Error::Handle(Compiler::CompileFunction(thread, target_function));
+        if (!error.IsNull()) {
+          Exceptions::PropagateError(error);
+        }
+      }
+
       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);
+      const Code& caller_code =
+          Code::Handle(zone, caller_frame->LookupDartCode());
+      const Code& target_code =
+          Code::Handle(zone, target_function.CurrentCode());
+      const Smi& expected_cid =
+          Smi::Handle(zone, Smi::New(receiver.GetClassId()));
+
+      CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code,
+                                         expected_cid, target_code);
+    } else {
+      ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+      if (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& caller_code =
+            Code::Handle(zone, caller_frame->LookupDartCode());
+        const Code& stub =
+            Code::Handle(zone, StubCode::MegamorphicLookup_entry()->code());
+
+        CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code,
+                                           cache, stub);
+      }
     }
   } else {
     const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache);
@@ -1034,8 +1204,6 @@
     cache.Insert(class_id, target_function);
   }
   arguments.SetReturn(target_function);
-#else
-  UNREACHABLE();
 #endif  // !defined(TARGET_ARCH_DBC)
 }
 
@@ -1242,9 +1410,11 @@
   bool do_deopt = false;
   bool do_stacktrace = false;
   bool do_reload = false;
+  const intptr_t isolate_reload_every =
+      isolate->reload_every_n_stack_overflow_checks();
   if ((FLAG_deoptimize_every > 0) ||
       (FLAG_stacktrace_every > 0) ||
-      (FLAG_reload_every > 0)) {
+      (isolate_reload_every > 0)) {
     // TODO(turnidge): To make --deoptimize_every and
     // --stacktrace-every faster we could move this increment/test to
     // the generated code.
@@ -1257,14 +1427,14 @@
         (count % FLAG_stacktrace_every) == 0) {
       do_stacktrace = true;
     }
-    if ((FLAG_reload_every > 0) &&
-        (count % FLAG_reload_every) == 0) {
+    if ((isolate_reload_every > 0) &&
+        (count % isolate_reload_every) == 0) {
       do_reload = isolate->CanReload();
     }
   }
   if ((FLAG_deoptimize_filter != NULL) ||
       (FLAG_stacktrace_filter != NULL) ||
-      FLAG_reload_every_optimized) {
+       FLAG_reload_every_optimized) {
     DartFrameIterator iterator;
     StackFrame* frame = iterator.NextFrame();
     ASSERT(frame != NULL);
@@ -1297,10 +1467,16 @@
     DeoptimizeFunctionsOnStack();
   }
   if (do_reload) {
-    if (FLAG_reload_every_back_off) {
-      FLAG_reload_every *= 2;
+#ifndef PRODUCT
+    JSONStream js;
+    // Maybe adjust the rate of future reloads.
+    isolate->MaybeIncreaseReloadEveryNStackOverflowChecks();
+    // Issue a reload.
+    bool success = isolate->ReloadSources(&js, true /* force_reload */);
+    if (!success) {
+      FATAL1("*** Isolate reload failed:\n%s\n", js.ToCString());
     }
-    NOT_IN_PRODUCT(isolate->ReloadSources();)
+#endif
   }
   if (FLAG_support_debugger && do_stacktrace) {
     String& var_name = String::Handle();
@@ -1317,6 +1493,10 @@
     intptr_t num_frames = stack->Length();
     for (intptr_t i = 0; i < num_frames; i++) {
       ActivationFrame* frame = stack->FrameAt(i);
+#ifndef DART_PRECOMPILED_RUNTIME
+      // Ensure that we have unoptimized code.
+      frame->function().EnsureHasCompiledUnoptimizedCode();
+#endif
       // Variable locations and number are unknown when precompiling.
       const int num_vars =
          FLAG_precompiled_runtime ? 0 : frame->NumLocalVariables();
@@ -1341,8 +1521,16 @@
     ASSERT(frame != NULL);
     const Code& code = Code::ZoneHandle(frame->LookupDartCode());
     ASSERT(!code.IsNull());
+    ASSERT(!code.is_optimized());
     const Function& function = Function::Handle(code.function());
     ASSERT(!function.IsNull());
+
+    // If the code of the frame does not match the function's unoptimized code,
+    // we bail out since the code was reset by an isolate reload.
+    if (code.raw() != function.unoptimized_code()) {
+      return;
+    }
+
     // Since the code is referenced from the frame and the ZoneHandle,
     // it cannot have been removed from the function.
     ASSERT(function.HasCode());
@@ -1384,7 +1572,7 @@
       // unoptimized code.  Patch the stack frame to return into the OSR
       // code.
       uword optimized_entry =
-          Instructions::Handle(optimized_code.instructions()).EntryPoint();
+          Instructions::UncheckedEntryPoint(optimized_code.instructions());
       function.AttachCode(original_code);
       frame->set_pc(optimized_entry);
       frame->set_pc_marker(optimized_code.raw());
@@ -1519,7 +1707,7 @@
                  "target '%s' -> %#" Px "\n",
                  frame->pc(),
                  target_function.ToFullyQualifiedCString(),
-                 current_target_code.EntryPoint());
+                 current_target_code.UncheckedEntryPoint());
   }
   arguments.SetReturn(current_target_code);
 }
@@ -1561,7 +1749,7 @@
         " -> %#" Px "\n",
         frame->pc(),
         alloc_class.ToCString(),
-        alloc_stub.EntryPoint());
+        alloc_stub.UncheckedEntryPoint());
   }
   arguments.SetReturn(alloc_stub);
 #else
@@ -1613,7 +1801,7 @@
   const Instructions& instrs =
       Instructions::Handle(zone, optimized_code.instructions());
   {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
+    WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
     CodePatcher::InsertDeoptimizationCallAt(pc, lazy_deopt_jump);
   }
   if (FLAG_trace_patching) {
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index ebcdeaa..bde916f 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -75,10 +75,13 @@
                                      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);
+                                    const Code& caller_code,
+                                    const Object& data,
+                                    const Code& target);
+  static RawObject* GetSwitchableCallDataAt(uword return_address,
+                                            const Code& caller_code);
+  static RawCode* GetSwitchableCallTargetAt(uword return_address,
+                                            const Code& caller_code);
 
   static RawCode* GetNativeCallAt(uword return_address,
                                   const Code& code,
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 7e0e8ea..62775bf 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -70,15 +70,29 @@
 
 
 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);
+                                        const Code& caller_code,
+                                        const Object& data,
+                                        const Code& target) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  call.SetData(data);
+  call.SetTarget(target);
+}
+
+
+RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.target();
+}
+
+
+RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.data();
 }
 
 
diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc
index 53f26ed..76b959b 100644
--- a/runtime/vm/code_patcher_arm64.cc
+++ b/runtime/vm/code_patcher_arm64.cc
@@ -110,15 +110,29 @@
 
 
 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);
+                                        const Code& caller_code,
+                                        const Object& data,
+                                        const Code& target) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  call.SetData(data);
+  call.SetTarget(target);
+}
+
+
+RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.target();
+}
+
+
+RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.data();
 }
 
 
diff --git a/runtime/vm/code_patcher_arm64_test.cc b/runtime/vm/code_patcher_arm64_test.cc
index b1cdfdd..af3417f 100644
--- a/runtime/vm/code_patcher_arm64_test.cc
+++ b/runtime/vm/code_patcher_arm64_test.cc
@@ -53,8 +53,8 @@
 
 
 ASSEMBLER_TEST_RUN(IcDataAccess, test) {
-  uword return_address =
-      test->entry() + test->code().Size() - Instr::kInstrSize;
+  uword end = test->payload_start() + test->code().Size();
+  uword return_address = end - Instr::kInstrSize;
   ICData& ic_data = ICData::Handle();
   CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
   EXPECT_STREQ("targetFunction",
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index 3671eb8..f63c546 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -53,8 +53,8 @@
 
 
 ASSEMBLER_TEST_RUN(IcDataAccess, test) {
-  uword return_address =
-      test->entry() + test->code().Size() - Instr::kInstrSize;
+  uword end = test->payload_start() + test->code().Size();
+  uword return_address = end - Instr::kInstrSize;
   ICData& ic_data = ICData::Handle();
   CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
   EXPECT_STREQ("targetFunction",
diff --git a/runtime/vm/code_patcher_dbc.cc b/runtime/vm/code_patcher_dbc.cc
index 6a273ac..327b27f 100644
--- a/runtime/vm/code_patcher_dbc.cc
+++ b/runtime/vm/code_patcher_dbc.cc
@@ -68,15 +68,29 @@
 
 
 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);
+                                        const Code& caller_code,
+                                        const Object& data,
+                                        const Code& target) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  call.SetData(data);
+  call.SetTarget(target);
+}
+
+
+RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.target();
+}
+
+
+RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.data();
 }
 
 
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 90f1876..db04cdf 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -170,7 +170,7 @@
                                     const Code& code,
                                     const Code& new_target) {
   const Instructions& instrs = Instructions::Handle(code.instructions());
-  WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
+  WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
   ASSERT(code.ContainsInstructionAt(return_address));
   StaticCall call(return_address);
   call.set_target(new_target);
@@ -212,15 +212,30 @@
 
 
 void CodePatcher::PatchSwitchableCallAt(uword return_address,
-                                        const Code& code,
-                                        const ICData& ic_data,
-                                        const MegamorphicCache& cache,
-                                        const Code& lookup_stub) {
+                                        const Code& caller_code,
+                                        const Object& data,
+                                        const Code& target) {
   // Switchable instance calls only generated for precompilation.
   UNREACHABLE();
 }
 
 
+RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                                const Code& caller_code) {
+  // Switchable instance calls only generated for precompilation.
+  UNREACHABLE();
+  return Code::null();
+}
+
+
+RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                                const Code& caller_code) {
+  // Switchable instance calls only generated for precompilation.
+  UNREACHABLE();
+  return Object::null();
+}
+
+
 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 4c8ab99..a4d0433 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -69,15 +69,29 @@
 
 
 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);
+                                        const Code& caller_code,
+                                        const Object& data,
+                                        const Code& target) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  call.SetData(data);
+  call.SetTarget(target);
+}
+
+
+RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.target();
+}
+
+
+RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCallPattern call(return_address, caller_code);
+  return call.data();
 }
 
 
diff --git a/runtime/vm/code_patcher_mips_test.cc b/runtime/vm/code_patcher_mips_test.cc
index b6d4109..8e07b77 100644
--- a/runtime/vm/code_patcher_mips_test.cc
+++ b/runtime/vm/code_patcher_mips_test.cc
@@ -50,8 +50,8 @@
 
 
 ASSEMBLER_TEST_RUN(IcDataAccess, test) {
-  uword return_address =
-      test->entry() + test->code().Size() - 2 * Instr::kInstrSize;
+  uword end = test->payload_start() + test->code().Size();
+  uword return_address = end - 2 * Instr::kInstrSize;
   ICData& ic_data = ICData::Handle();
   CodePatcher::GetInstanceCallAt(return_address, test->code(), &ic_data);
   EXPECT_STREQ("targetFunction",
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index b8863dc..0e18f6f 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -190,10 +190,11 @@
 };
 
 
-// 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
+// Instance call that can switch between a direct monomorphic call, an IC call,
+// and a megamorphic call.
+//   load guarded cid            load ICData             load MegamorphicCache
+//   load monomorphic target <-> load ICLookup stub  ->  load MMLookup stub
+//   call target.entry           call stub.entry         call stub.entry
 class SwitchableCall : public ValueObject {
  public:
   SwitchableCall(uword return_address, const Code& code)
@@ -202,39 +203,42 @@
     ASSERT(IsValid());
   }
 
-  static const int kCallPatternSize = 24;
+  static const int kCallPatternSize = 21;
 
   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
+      0x49, 0x8b, 0x4c, 0x24, 0x0f,      // movq rcx, [r12 + entrypoint_off]
       0xff, 0xd1,                        // call rcx
     };
+    ASSERT(ARRAY_SIZE(pattern) == kCallPatternSize);
     return MatchesPattern(start_, pattern, kCallPatternSize);
   }
 
-  intptr_t cache_index() const {
+  intptr_t data_index() const {
     return IndexFromPPLoad(start_ + 3);
   }
-  intptr_t lookup_stub_index() const {
+  intptr_t target_index() const {
     return IndexFromPPLoad(start_ + 10);
   }
 
-  RawObject* cache() const {
-    return object_pool_.ObjectAt(cache_index());
+  RawObject* data() const {
+    return object_pool_.ObjectAt(data_index());
+  }
+  RawCode* target() const {
+    return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_index()));
   }
 
-  void SetCache(const MegamorphicCache& cache) const {
-    ASSERT(Object::Handle(object_pool_.ObjectAt(cache_index())).IsICData());
-    object_pool_.SetObjectAt(cache_index(), cache);
+  void SetData(const Object& data) const {
+    ASSERT(!Object::Handle(object_pool_.ObjectAt(data_index())).IsCode());
+    object_pool_.SetObjectAt(data_index(), data);
     // 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);
+  void SetTarget(const Code& target) const {
+    ASSERT(Object::Handle(object_pool_.ObjectAt(target_index())).IsCode());
+    object_pool_.SetObjectAt(target_index(), target);
     // No need to flush the instruction cache, since the code is not modified.
   }
 
@@ -313,15 +317,29 @@
 
 
 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);
+                                        const Code& caller_code,
+                                        const Object& data,
+                                        const Code& target) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCall call(return_address, caller_code);
+  call.SetData(data);
+  call.SetTarget(target);
+}
+
+
+RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCall call(return_address, caller_code);
+  return call.target();
+}
+
+
+RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
+                                                const Code& caller_code) {
+  ASSERT(caller_code.ContainsInstructionAt(return_address));
+  SwitchableCall call(return_address, caller_code);
+  return call.data();
 }
 
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index cc3b691..ace33b0 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1167,8 +1167,10 @@
         done = true;
       }
 
-      // Clear the error if it was not a real error, but just a bailout.
-      if (error.IsLanguageError() &&
+      // If is is not a background compilation, clear the error if it was not a
+      // real error, but just a bailout. If we're it a background compilation
+      // this will be dealt with in the caller.
+      if (!Compiler::IsBackgroundCompilation() && error.IsLanguageError() &&
           (LanguageError::Cast(error).kind() == Report::kBailout)) {
         thread()->clear_sticky_error();
       }
@@ -1277,6 +1279,21 @@
             THR_Print("Aborted background compilation: %s\n",
                 function.ToFullyQualifiedCString());
           }
+          {
+            // If it was a bailout, then disable optimization.
+            Error& error = Error::Handle();
+            // We got an error during compilation.
+            error = thread->sticky_error();
+            thread->clear_sticky_error();
+            if (error.IsLanguageError() &&
+                LanguageError::Cast(error).kind() == Report::kBailout) {
+              if (FLAG_trace_compiler) {
+                THR_Print("--> disabling optimizations for '%s'\n",
+                          function.ToFullyQualifiedCString());
+              }
+              function.SetIsOptimizable(false);
+            }
+          }
           return Error::null();
         }
         // Optimizer bailed out. Disable optimizations and never try again.
@@ -1295,6 +1312,7 @@
         // We got an error during compilation.
         error = thread->sticky_error();
         thread->clear_sticky_error();
+        // The non-optimizing compiler should not bail out.
         ASSERT(error.IsLanguageError() &&
                LanguageError::Cast(error).kind() != Report::kBailout);
         return error.raw();
@@ -1306,7 +1324,7 @@
     if (trace_compiler && success) {
       THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
                 function.ToFullyQualifiedCString(),
-                Code::Handle(function.CurrentCode()).EntryPoint(),
+                Code::Handle(function.CurrentCode()).PayloadStart(),
                 Code::Handle(function.CurrentCode()).Size(),
                 per_compile_timer.TotalElapsedTime());
     }
@@ -1856,10 +1874,7 @@
         ASSERT(error.IsNull());
 #ifndef PRODUCT
         Isolate* isolate = thread->isolate();
-        // We cannot aggregate stats if isolate is shutting down.
-        if (isolate->HasMutatorThread()) {
-          isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats());
-        }
+        isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats());
         thread->compiler_stats()->Clear();
 #endif  // PRODUCT
 
@@ -1870,8 +1885,9 @@
             function = Function::null();
           } else {
             qelem = function_queue()->Remove();
-            if (FLAG_stress_test_background_compilation) {
-              const Function& old = Function::Handle(qelem->Function());
+            const Function& old = Function::Handle(qelem->Function());
+            if ((!old.HasOptimizedCode() && old.IsOptimizable()) ||
+                 FLAG_stress_test_background_compilation) {
               if (Compiler::CanOptimizeFunction(thread, old)) {
                 QueueElement* repeat_qelem = new QueueElement(old);
                 function_queue()->Add(repeat_qelem);
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index 6b97f7d..1f5290d 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -253,6 +253,10 @@
 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { }
 
 
+void ConstantPropagator::VisitGenericCheckBound(GenericCheckBoundInstr* instr) {
+}
+
+
 void ConstantPropagator::VisitCheckEitherNonSmi(
     CheckEitherNonSmiInstr* instr) { }
 
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index 5d901b8..3f950df 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -148,6 +148,11 @@
 //    Invoke function in SP[0] with arguments SP[-(1+ArgC)], ..., SP[-1] and
 //    argument descriptor PP[D].
 //
+//  - IndirectStaticCall ArgC, D
+//
+//    Invoke the function given by the ICData in SP[0] with arguments
+//    SP[-(1+ArgC)], ..., SP[-1] and argument descriptor PP[D].
+//
 //  - InstanceCall<N> ArgC, D; InstanceCall<N>Opt ArgC, D
 //
 //    Lookup and invoke method with N checked arguments using ICData in PP[D]
@@ -157,6 +162,15 @@
 //
 //    Invoke native function SP[-1] with argc_tag SP[0].
 //
+//  - PushPolymorphicInstanceCall ArgC, D
+//
+//    Skips 2*D + 1 instructions and pushes a function object onto the stack
+//    if one can be found as follows. Otherwise skips only 2*D instructions.
+//    The function is looked up in the IC data encoded in the following 2*D
+//    Nop instructions. The Nop instructions should be arranged in pairs with
+//    the first being the cid, and the second being the function to push if
+//    the cid is the cid of the receiver found at SP[-(1 + ArgC)].
+//
 //  - OneByteStringFromCharCode rA, rX
 //
 //    Load the one-character symbol with the char code given by the Smi
@@ -183,11 +197,29 @@
 //    the immediately following instruction is skipped. These instructions
 //    expect their operands to be Smis, but don't check that they are.
 //
+//  - ShrImm rA, rB, rC
+//
+//    FP[rA] <- FP[rB] >> rC. Shifts the Smi in FP[rB] right by rC. rC is
+//    assumed to be a legal positive number by which righ-shifting is possible.
+//
+//  - Min, Max rA, rB, rC
+//
+//    FP[rA] <- {min, max}(FP[rB], FP[rC]). Assumes that FP[rB], and FP[rC] are
+//    Smis.
+//
 //  - Neg rA , rD
 //
 //    FP[rA] <- -FP[rD]. Assumes FP[rD] is a Smi. If there is no overflow the
 //    immediately following instruction is skipped.
 //
+//  - DMin, DMax, DAdd, DSub, DMul, DDiv, DPow, DMod rA, rB, rC
+//
+//    Arithmetic operaions on unboxed doubles. FP[rA] <- FP[rB] op FP[rC].
+//
+//  - DNeg, DCos, DSin, DSqrt rA, rD
+//
+//    FP[rA] <- op(FP[rD]). Assumes FP[rD] is an unboxed double.
+//
 //  - BitOr, BitAnd, BitXor rA, rB, rC
 //
 //    FP[rA] <- FP[rB] op FP[rC]. These instructions expect their operands to be
@@ -197,6 +229,30 @@
 //
 //    FP[rA] <- ~FP[rD]. As above, assumes FP[rD] is a Smi.
 //
+//  - WriteIntoDouble rA, rD
+//
+//    Box the double in FP[rD] with the result in FP[rA].
+//
+//  - UnboxDouble rA, rD
+//
+//    Unbox the double in FP[rD] into FP[rA]. Assumes FP[rD] is a double.
+//
+//  - CheckedUnboxDouble rA, rD
+//
+//    Unboxes FP[rD] into FP[rA] and skips the following instruction unless
+//    FP[rD] is not a double or a Smi. When FP[rD] is a Smi, converts it to a
+//    double.
+//
+//  - SmiToDouble rA, rD
+//
+//    Convert the Smi in FP[rD] to an unboxed double in FP[rA].
+//
+//  - DoubleToSmi rA, rD
+//
+//    If the unboxed double in FP[rD] can be converted to a Smi in FP[rA], then
+//    this instruction does so, and skips the following instruction. Otherwise,
+//    the following instruction is not skipped.
+//
 //  - StoreStaticT`OS D
 //
 //    Stores TOS into the static field PP[D].
@@ -228,6 +284,13 @@
 //    Cond is Eq or Ne. Skips the next instruction unless the given condition
 //    holds.
 //
+//  - If<Cond> rA, rD
+//
+//    Cond is Le, Lt, Ge, Gt, unsigned variants ULe, ULt, UGe, UGt, and
+//    unboxed double variants DEq, DNe, DLe, DLt, DGe, DGt.
+//    Skips the next instruction unless FP[rA] <Cond> FP[rD]. Assumes that
+//    FP[rA] and FP[rD] are Smis or unboxed doubles as inidcated by <Cond>.
+//
 //  - CreateArrayTOS
 //
 //    Allocate array of length SP[0] with type arguments SP[-1].
@@ -247,8 +310,23 @@
 //
 //  - StoreIndexed rA, rB, rC
 //
-//    Store rC into array rA at index rB. No typechecking is done.
-//    rA is assumed to be a RawArray, rB to be a smi.
+//    Store FP[rC] into array FP[rA] at index FP[rB]. No typechecking is done.
+//    FP[rA] is assumed to be a RawArray, FP[rB] to be a smi.
+//
+//  - StoreFloat64Indexed rA, rB, rC
+//
+//    Store the unboxed double in FP[rC] into the typed data array at FP[rA]
+//    at index FP[rB].
+//
+//  - LoadIndexed rA, rB, rC
+//
+//    Loads from array FP[rB] at index FP[rC] into FP[rA]. No typechecking is
+//    done. FP[rB] is assumed to be a RawArray, and to contain a Smi at FP[rC].
+//
+//  - Load{Float64, OneByteString, TwoByteString}Indexed rA, rB, rC
+//
+//    Loads from typed data array FP[rB] at index FP[rC] into an unboxed double,
+//    or tagged Smi in FP[rA] as indicated by the type in the name.
 //
 //  - StoreField rA, B, rC
 //
@@ -376,13 +454,24 @@
 //    If FP[rA] & FP[rD] != 0, then skip the next instruction. FP[rA] and FP[rD]
 //    must be Smis.
 //
+//  - TestCids rA, D
+//
+//    The next D instructions must be Nops whose D field encodes a class id. If
+//    the class id of FP[rA] matches, jump to PC + N + 1 if the matching Nop's
+//    A != 0 or PC + N + 2 if the matching Nop's A = 0. If no match is found,
+//    jump to PC + N.
+//
 //  - CheckSmi rA
 //
 //    If FP[rA] is a Smi, then skip the next instruction.
 //
+//  - CheckEitherNonSmi rA, rD
+//
+//    If either FP[rA] or FP[rD] is not a Smi, then skip the next instruction.
+//
 //  - CheckClassId rA, D
 //
-//    If the object at FP[rA]'s class id matches the class id D, then skip the
+//    If the class id in FP[rA] matches the class id D, then skip the
 //    following instruction.
 //
 //  - CheckDenseSwitch rA, D
@@ -455,12 +544,12 @@
 //     tgt jump target relative to the PC of the current instruction
 //
 // TODO(vegorov) jump targets should be encoded relative to PC of the next
-//               instruction because PC is incremeted immediately after fetch
+//               instruction because PC is incremented immediately after fetch
 //               and before decoding.
 //
 #define BYTECODES_LIST(V)                              \
   V(Trap,                            0, ___, ___, ___) \
-  V(Nop,                             D, lit, ___, ___) \
+  V(Nop,                           A_D, num, lit, ___) \
   V(Compile,                         0, ___, ___, ___) \
   V(HotCheck,                      A_D, num, num, ___) \
   V(Intrinsic,                       A, num, ___, ___) \
@@ -479,11 +568,13 @@
   V(PushConstant,                    D, lit, ___, ___) \
   V(StoreLocal,                      X, xeg, ___, ___) \
   V(PopLocal,                        X, xeg, ___, ___) \
+  V(IndirectStaticCall,            A_D, num, num, ___) \
   V(StaticCall,                    A_D, num, num, ___) \
   V(InstanceCall1,                 A_D, num, num, ___) \
   V(InstanceCall2,                 A_D, num, num, ___) \
   V(InstanceCall1Opt,              A_D, num, num, ___) \
   V(InstanceCall2Opt,              A_D, num, num, ___) \
+  V(PushPolymorphicInstanceCall,   A_D, num, num, ___) \
   V(NativeCall,                      0, ___, ___, ___) \
   V(NativeBootstrapCall,             0, ___, ___, ___) \
   V(OneByteStringFromCharCode,     A_X, reg, xeg, ___) \
@@ -503,11 +594,31 @@
   V(Mod,                         A_B_C, reg, reg, reg) \
   V(Shl,                         A_B_C, reg, reg, reg) \
   V(Shr,                         A_B_C, reg, reg, reg) \
+  V(ShrImm,                      A_B_C, reg, reg, num) \
   V(Neg,                           A_D, reg, reg, ___) \
   V(BitOr,                       A_B_C, reg, reg, reg) \
   V(BitAnd,                      A_B_C, reg, reg, reg) \
   V(BitXor,                      A_B_C, reg, reg, reg) \
   V(BitNot,                        A_D, reg, reg, ___) \
+  V(Min,                         A_B_C, reg, reg, reg) \
+  V(Max,                         A_B_C, reg, reg, reg) \
+  V(WriteIntoDouble,               A_D, reg, reg, ___) \
+  V(UnboxDouble,                   A_D, reg, reg, ___) \
+  V(CheckedUnboxDouble,            A_D, reg, reg, ___) \
+  V(SmiToDouble,                   A_D, reg, reg, ___) \
+  V(DoubleToSmi,                   A_D, reg, reg, ___) \
+  V(DAdd,                        A_B_C, reg, reg, reg) \
+  V(DSub,                        A_B_C, reg, reg, reg) \
+  V(DMul,                        A_B_C, reg, reg, reg) \
+  V(DDiv,                        A_B_C, reg, reg, reg) \
+  V(DNeg,                          A_D, reg, reg, ___) \
+  V(DSqrt,                         A_D, reg, reg, ___) \
+  V(DMin,                        A_B_C, reg, reg, reg) \
+  V(DMax,                        A_B_C, reg, reg, reg) \
+  V(DCos,                          A_D, reg, reg, ___) \
+  V(DSin,                          A_D, reg, reg, ___) \
+  V(DPow,                        A_B_C, reg, reg, reg) \
+  V(DMod,                        A_B_C, reg, reg, reg) \
   V(StoreStaticTOS,                  D, lit, ___, ___) \
   V(PushStatic,                      D, lit, ___, ___) \
   V(InitStaticTOS,                   0, ___, ___, ___) \
@@ -517,6 +628,20 @@
   V(IfEqStrictNumTOS,                0, ___, ___, ___) \
   V(IfNeStrict,                    A_D, reg, reg, ___) \
   V(IfEqStrict,                    A_D, reg, reg, ___) \
+  V(IfLe,                          A_D, reg, reg, ___) \
+  V(IfLt,                          A_D, reg, reg, ___) \
+  V(IfGe,                          A_D, reg, reg, ___) \
+  V(IfGt,                          A_D, reg, reg, ___) \
+  V(IfULe,                         A_D, reg, reg, ___) \
+  V(IfULt,                         A_D, reg, reg, ___) \
+  V(IfUGe,                         A_D, reg, reg, ___) \
+  V(IfUGt,                         A_D, reg, reg, ___) \
+  V(IfDNe,                         A_D, reg, reg, ___) \
+  V(IfDEq,                         A_D, reg, reg, ___) \
+  V(IfDLe,                         A_D, reg, reg, ___) \
+  V(IfDLt,                         A_D, reg, reg, ___) \
+  V(IfDGe,                         A_D, reg, reg, ___) \
+  V(IfDGt,                         A_D, reg, reg, ___) \
   V(IfNeStrictNum,                 A_D, reg, reg, ___) \
   V(IfEqStrictNum,                 A_D, reg, reg, ___) \
   V(IfEqNull,                        A, reg, ___, ___) \
@@ -526,6 +651,11 @@
   V(AllocateT,                       0, ___, ___, ___) \
   V(StoreIndexedTOS,                 0, ___, ___, ___) \
   V(StoreIndexed,                A_B_C, reg, reg, reg) \
+  V(StoreFloat64Indexed,         A_B_C, reg, reg, reg) \
+  V(LoadIndexed,                 A_B_C, reg, reg, reg) \
+  V(LoadFloat64Indexed,          A_B_C, reg, reg, reg) \
+  V(LoadOneByteStringIndexed,    A_B_C, reg, reg, reg) \
+  V(LoadTwoByteStringIndexed,    A_B_C, reg, reg, reg) \
   V(StoreField,                  A_B_C, reg, num, reg) \
   V(StoreFieldTOS,                   D, num, ___, ___) \
   V(LoadField,                   A_B_C, reg, reg, num) \
@@ -547,7 +677,9 @@
   V(AssertAssignable,                D, num, lit, ___) \
   V(AssertBoolean,                   A, num, ___, ___) \
   V(TestSmi,                       A_D, reg, reg, ___) \
+  V(TestCids,                      A_D, reg, num, ___) \
   V(CheckSmi,                        A, reg, ___, ___) \
+  V(CheckEitherNonSmi,             A_D, reg, reg, ___) \
   V(CheckClassId,                  A_D, reg, num, ___) \
   V(CheckDenseSwitch,              A_D, reg, num, ___) \
   V(CheckCids,                   A_B_C, reg, num, ___) \
@@ -619,6 +751,7 @@
   DART_FORCE_INLINE static bool IsCallOpcode(Instr instr) {
     switch (DecodeOpcode(instr)) {
       case Bytecode::kStaticCall:
+      case Bytecode::kIndirectStaticCall:
       case Bytecode::kInstanceCall1:
       case Bytecode::kInstanceCall2:
       case Bytecode::kInstanceCall1Opt:
@@ -631,6 +764,23 @@
     }
   }
 
+  DART_FORCE_INLINE static bool IsFastSmiOpcode(Instr instr) {
+    switch (DecodeOpcode(instr)) {
+      case Bytecode::kAddTOS:
+      case Bytecode::kSubTOS:
+      case Bytecode::kMulTOS:
+      case Bytecode::kBitOrTOS:
+      case Bytecode::kBitAndTOS:
+      case Bytecode::kEqualTOS:
+      case Bytecode::kLessThanTOS:
+      case Bytecode::kGreaterThanTOS:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
   DART_FORCE_INLINE static uint8_t DecodeArgc(Instr call) {
     ASSERT(IsCallOpcode(call));
     return (call >> 8) & 0xFF;
@@ -650,7 +800,11 @@
 
 const int16_t FPREG = 0;
 const int16_t SPREG = 1;
-const intptr_t kNumberOfCpuRegisters = 20;
+#if defined(ARCH_IS_64_BIT)
+const intptr_t kNumberOfCpuRegisters = 64;
+#else
+const intptr_t kNumberOfCpuRegisters = 32;
+#endif
 const intptr_t kDartAvailableCpuRegs = -1;
 const intptr_t kNoRegister = -1;
 const intptr_t kReservedCpuRegisters = 0;
diff --git a/runtime/vm/cpu_arm64.cc b/runtime/vm/cpu_arm64.cc
index 881aebc..e612cce 100644
--- a/runtime/vm/cpu_arm64.cc
+++ b/runtime/vm/cpu_arm64.cc
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
-
 #if defined(TARGET_ARCH_ARM64)
 
 #include "vm/cpu.h"
+#include "vm/cpu_arm64.h"
+
 #include "vm/cpuinfo.h"
 #include "vm/simulator.h"
 
@@ -31,13 +32,15 @@
 
   // ARM recommends using the gcc intrinsic __clear_cache on Linux and Android.
   // blogs.arm.com/software-enablement/141-caches-and-self-modifying-code/
-  #if defined(__linux__) || defined(ANDROID)
+  #if defined(TARGET_OS_ANDROID) || \
+      defined(TARGET_OS_FUCHSIA) || \
+      defined(TARGET_OS_LINUX)
     extern void __clear_cache(char*, char*);
     char* beg = reinterpret_cast<char*>(start);
     char* end = reinterpret_cast<char*>(start + size);
     ::__clear_cache(beg, end);
   #else
-    #error FlushICache only tested/supported on Linux and Android
+    #error FlushICache only tested/supported on Android, Fuchsia, and Linux
   #endif
 
 #endif
diff --git a/runtime/vm/cpuinfo_fuchsia.cc b/runtime/vm/cpuinfo_fuchsia.cc
index 04fe196..ad9e990 100644
--- a/runtime/vm/cpuinfo_fuchsia.cc
+++ b/runtime/vm/cpuinfo_fuchsia.cc
@@ -8,8 +8,7 @@
 #include "vm/cpuinfo.h"
 
 #include "platform/assert.h"
-
-// TODO(zra): Use "vm/cpuid.h"
+#include "vm/cpuid.h"
 
 namespace dart {
 
@@ -17,30 +16,55 @@
 const char* CpuInfo::fields_[kCpuInfoMax] = {0};
 
 void CpuInfo::InitOnce() {
-  UNIMPLEMENTED();
+  // TODO(zra): Add support for HOST_ARCH_ARM64
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
+  method_ = kCpuInfoCpuId;
+
+  // Initialize the CpuId information.
+  CpuId::InitOnce();
+
+  fields_[kCpuInfoProcessor] = "Processor";
+  fields_[kCpuInfoModel] = "Hardware";
+  fields_[kCpuInfoHardware] = "Hardware";
+  fields_[kCpuInfoFeatures] = "Features";
+#endif
 }
 
 
 void CpuInfo::Cleanup() {
-  UNIMPLEMENTED();
+  if (method_ == kCpuInfoCpuId) {
+    CpuId::Cleanup();
+  }
 }
 
 
 bool CpuInfo::FieldContains(CpuInfoIndices idx, const char* search_string) {
-  UNIMPLEMENTED();
-  return false;
+  if (method_ == kCpuInfoCpuId) {
+    return strstr(CpuId::field(idx), search_string);
+  } else {
+    return false;
+  }
 }
 
 
 const char* CpuInfo::ExtractField(CpuInfoIndices idx) {
-  UNIMPLEMENTED();
-  return "<undefined>";
+  if (method_ == kCpuInfoCpuId) {
+    return CpuId::field(idx);
+  } else {
+    return strdup("");
+  }
 }
 
 
 bool CpuInfo::HasField(const char* field) {
-  UNIMPLEMENTED();
-  return false;
+  if (method_ == kCpuInfoCpuId) {
+    return (strcmp(field, fields_[kCpuInfoProcessor]) == 0) ||
+           (strcmp(field, fields_[kCpuInfoModel]) == 0) ||
+           (strcmp(field, fields_[kCpuInfoHardware]) == 0) ||
+           (strcmp(field, fields_[kCpuInfoFeatures]) == 0);
+  } else {
+    return false;
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 62c7226..0bd8730 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -41,7 +41,6 @@
 DECLARE_FLAG(bool, trace_time_all);
 DEFINE_FLAG(bool, keep_code, false,
             "Keep deoptimized code for profiling.");
-DEFINE_FLAG(bool, shutdown, true, "Do a clean shutdown of the VM");
 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr");
 
 Isolate* Dart::vm_isolate_ = NULL;
@@ -96,6 +95,7 @@
   CHECK_OFFSET(Isolate::heap_offset(), 8);
   CHECK_OFFSET(Thread::stack_limit_offset(), 4);
   CHECK_OFFSET(Thread::object_null_offset(), 36);
+  NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 120));
 #endif
 #if defined(TARGET_ARCH_MIPS)
   // These offsets are embedded in precompiled instructions. We need simmips
@@ -104,6 +104,7 @@
   CHECK_OFFSET(Isolate::heap_offset(), 8);
   CHECK_OFFSET(Thread::stack_limit_offset(), 4);
   CHECK_OFFSET(Thread::object_null_offset(), 36);
+  NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 120));
 #endif
 #if defined(TARGET_ARCH_ARM64)
   // These offsets are embedded in precompiled instructions. We need simarm64
@@ -112,6 +113,7 @@
   CHECK_OFFSET(Isolate::heap_offset(), 16);
   CHECK_OFFSET(Thread::stack_limit_offset(), 8);
   CHECK_OFFSET(Thread::object_null_offset(), 72);
+  NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 208));
 #endif
 #undef CHECK_OFFSET
 }
@@ -375,105 +377,89 @@
     Thread::ExitIsolate();
   }
 
-  if (FLAG_shutdown) {
-    // Disable the creation of new isolates.
+  // Disable the creation of new isolates.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling isolate creation\n",
+                 timestamp());
+  }
+  Isolate::DisableIsolateCreation();
+
+  // Send the OOB Kill message to all remaining application isolates.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Killing all app isolates\n",
+                 timestamp());
+  }
+  Isolate::KillAllIsolates(Isolate::kInternalKillMsg);
+
+  // Wait for all isolates, but the service and the vm isolate to shut down.
+  // Only do that if there is a service isolate running.
+  if (ServiceIsolate::IsRunning()) {
     if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling isolate creation\n",
+      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down app isolates\n",
                    timestamp());
     }
-    Isolate::DisableIsolateCreation();
+    WaitForApplicationIsolateShutdown();
+  }
 
-    // Send the OOB Kill message to all remaining application isolates.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Killing all app isolates\n",
-                   timestamp());
-    }
-    Isolate::KillAllIsolates(Isolate::kInternalKillMsg);
+  // Shutdown the service isolate.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n",
+                 timestamp());
+  }
+  ServiceIsolate::Shutdown();
 
-    // Wait for all isolates, but the service and the vm isolate to shut down.
-    // Only do that if there is a service isolate running.
-    if (ServiceIsolate::IsRunning()) {
-      if (FLAG_trace_shutdown) {
-        OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down app isolates\n",
-                     timestamp());
-      }
-      WaitForApplicationIsolateShutdown();
-    }
+  // Wait for the remaining isolate (service isolate) to shutdown
+  // before shutting down the thread pool.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Waiting for isolate shutdown\n",
+                 timestamp());
+  }
+  WaitForIsolateShutdown();
 
-    // Shutdown the service isolate.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n",
-                   timestamp());
-    }
-    ServiceIsolate::Shutdown();
+  // Shutdown the thread pool. On return, all thread pool threads have exited.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n",
+                 timestamp());
+  }
+  delete thread_pool_;
+  thread_pool_ = NULL;
 
-    // Wait for the remaining isolate (service isolate) to shutdown
-    // before shutting down the thread pool.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Waiting for isolate shutdown\n",
-                   timestamp());
-    }
-    WaitForIsolateShutdown();
+  // 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.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n",
+                 timestamp());
+  }
+  OSThread::DisableOSThreadCreation();
 
-    // Shutdown the thread pool. On return, all thread pool threads have exited.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n",
-                   timestamp());
-    }
-    delete thread_pool_;
-    thread_pool_ = NULL;
+  // Set the VM isolate as current isolate.
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
+                 timestamp());
+  }
+  bool result = Thread::EnterIsolate(vm_isolate_);
+  ASSERT(result);
 
-    // Disable creation of any new OSThread structures which means no more new
-    // threads can do an EnterIsolate. This must come after isolate shutdown
-    // because new threads may need to be spawned to shutdown the isolates.
-    // 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.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n",
-                   timestamp());
-    }
-    OSThread::DisableOSThreadCreation();
+  ShutdownIsolate();
+  vm_isolate_ = NULL;
+  ASSERT(Isolate::IsolateListLength() == 0);
 
-    // Set the VM isolate as current isolate.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Cleaning up vm isolate\n",
-                   timestamp());
-    }
-    bool result = Thread::EnterIsolate(vm_isolate_);
-    ASSERT(result);
+  TargetCPUFeatures::Cleanup();
+  StoreBuffer::ShutDown();
 
-    ShutdownIsolate();
-    vm_isolate_ = NULL;
-    ASSERT(Isolate::IsolateListLength() == 0);
-
-    TargetCPUFeatures::Cleanup();
-    StoreBuffer::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;
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n",
-                   timestamp());
-    }
-  } else {
-    // Shutdown the service isolate.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down service isolate\n",
-                   timestamp());
-    }
-    ServiceIsolate::Shutdown();
-
-    // Disable thread creation.
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Disabling OS Thread creation\n",
-                   timestamp());
-    }
-    OSThread::DisableOSThreadCreation();
+  // 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;
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleted os_thread\n",
+                 timestamp());
   }
 
   if (FLAG_trace_shutdown) {
@@ -674,12 +660,6 @@
 #elif defined(TARGET_ARCH_DBC64)
     buffer.AddString(" dbc64");
 #endif
-  } else if (Snapshot::IsFull(kind)) {
-#if defined(ARCH_IS_32BIT)
-  buffer.AddString(" 32");
-#else
-  buffer.AddString(" 64");
-#endif
   }
 
   return buffer.Steal();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index c9942da..61bd28f 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -21,6 +21,7 @@
 #include "vm/flags.h"
 #include "vm/growable_array.h"
 #include "vm/lockers.h"
+#include "vm/isolate_reload.h"
 #include "vm/message.h"
 #include "vm/message_handler.h"
 #include "vm/native_entry.h"
@@ -1141,37 +1142,29 @@
   return Version::String();
 }
 
-DART_EXPORT char* Dart_Initialize(
-    const uint8_t* vm_isolate_snapshot,
-    const uint8_t* instructions_snapshot,
-    const uint8_t* data_snapshot,
-    Dart_IsolateCreateCallback create,
-    Dart_IsolateInterruptCallback interrupt,
-    Dart_IsolateUnhandledExceptionCallback unhandled,
-    Dart_IsolateShutdownCallback shutdown,
-    Dart_ThreadExitCallback thread_exit,
-    Dart_FileOpenCallback file_open,
-    Dart_FileReadCallback file_read,
-    Dart_FileWriteCallback file_write,
-    Dart_FileCloseCallback file_close,
-    Dart_EntropySource entropy_source,
-    Dart_GetVMServiceAssetsArchive get_service_assets) {
-  if (interrupt != NULL) {
+DART_EXPORT char* Dart_Initialize(Dart_InitializeParams* params) {
+  if (params == NULL) {
     return strdup("Dart_Initialize: "
-                  "Setting of interrupt callback is not supported.");
+                  "Dart_InitializeParams is null.");
   }
-  if (unhandled != NULL) {
+
+  if (params->version != DART_INITIALIZE_PARAMS_CURRENT_VERSION) {
     return strdup("Dart_Initialize: "
-                  "Setting of unhandled exception callback is not supported.");
+                  "Invalid Dart_InitializeParams version.");
   }
-  return Dart::InitOnce(vm_isolate_snapshot,
-                        instructions_snapshot,
-                        data_snapshot,
-                        create, shutdown,
-                        thread_exit,
-                        file_open, file_read, file_write, file_close,
-                        entropy_source,
-                        get_service_assets);
+
+  return Dart::InitOnce(params->vm_isolate_snapshot,
+                        params->instructions_snapshot,
+                        params->data_snapshot,
+                        params->create,
+                        params->shutdown,
+                        params->thread_exit,
+                        params->file_open,
+                        params->file_read,
+                        params->file_write,
+                        params->file_close,
+                        params->entropy_source,
+                        params->get_service_assets);
 }
 
 
@@ -1325,10 +1318,9 @@
 
 DART_EXPORT void* Dart_IsolateData(Dart_Isolate isolate) {
   if (isolate == NULL) {
-    FATAL1("%s expects argument 'isolate' to be non-null.",  CURRENT_FUNC);
+    FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
   }
   // TODO(16615): Validate isolate parameter.
-  NoSafepointScope no_safepoint_scope;
   Isolate* iso = reinterpret_cast<Isolate*>(isolate);
   return iso->init_callback_data();
 }
@@ -1345,11 +1337,10 @@
   CHECK_NO_ISOLATE(Isolate::Current());
   // TODO(16615): Validate isolate parameter.
   Isolate* iso = reinterpret_cast<Isolate*>(isolate);
-  if (iso->HasMutatorThread()) {
-    FATAL("Multiple mutators within one isolate is not supported.");
-  }
   if (!Thread::EnterIsolate(iso)) {
-    FATAL("Unable to Enter Isolate as Dart VM is shutting down");
+    FATAL("Unable to Enter Isolate : "
+          "Multiple mutators entering an isolate / "
+          "Dart VM is shutting down");
   }
   // A Thread structure has been associated to the thread, we do the
   // safepoint transition explicity here instead of using the
@@ -1451,6 +1442,32 @@
 }
 
 
+DART_EXPORT void Dart_SetStickyError(Dart_Handle error) {
+  Thread* thread = Thread::Current();
+  DARTSCOPE(thread);
+  Isolate* isolate = thread->isolate();
+  CHECK_ISOLATE(isolate);
+  NoSafepointScope no_safepoint_scope;
+  if (isolate->sticky_error() != Error::null()) {
+    FATAL1("%s expects there to be no sticky error.", CURRENT_FUNC);
+  }
+  if (!::Dart_IsUnhandledExceptionError(error)) {
+    FATAL1("%s expects the error to be an unhandled exception error.",
+            CURRENT_FUNC);
+  }
+  isolate->SetStickyError(
+      Api::UnwrapErrorHandle(Z, error).raw());
+}
+
+
+DART_EXPORT bool Dart_HasStickyError() {
+  Isolate* isolate = Isolate::Current();
+  CHECK_ISOLATE(isolate);
+  NoSafepointScope no_safepoint_scope;
+  return isolate->sticky_error() != Error::null();
+}
+
+
 DART_EXPORT void Dart_ExitIsolate() {
   Thread* T = Thread::Current();
   CHECK_ISOLATE(T->isolate());
@@ -5222,6 +5239,7 @@
 
 
 DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
+                                        Dart_Handle resolved_url,
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset) {
@@ -5232,6 +5250,13 @@
   if (url_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, url, String);
   }
+  if (::Dart_IsNull(resolved_url)) {
+    resolved_url = url;
+  }
+  const String& resolved_url_str = Api::UnwrapStringHandle(Z, resolved_url);
+  if (resolved_url_str.IsNull()) {
+    RETURN_TYPE_ERROR(Z, resolved_url, String);
+  }
   const String& source_str = Api::UnwrapStringHandle(Z, source);
   if (source_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, source, String);
@@ -5260,8 +5285,9 @@
   library.Register(T);
   I->object_store()->set_root_library(library);
 
-  const Script& script = Script::Handle(Z,
-      Script::New(url_str, source_str, RawScript::kScriptTag));
+  const Script& script =
+      Script::Handle(Z, Script::New(url_str, resolved_url_str, source_str,
+                                    RawScript::kScriptTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
   CompileSource(T, library, script, &result);
@@ -5499,6 +5525,7 @@
 
 
 DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle url,
+                                         Dart_Handle resolved_url,
                                          Dart_Handle source,
                                          intptr_t line_offset,
                                          intptr_t column_offset) {
@@ -5509,6 +5536,13 @@
   if (url_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, url, String);
   }
+  if (::Dart_IsNull(resolved_url)) {
+    resolved_url = url;
+  }
+  const String& resolved_url_str = Api::UnwrapStringHandle(Z, resolved_url);
+  if (resolved_url_str.IsNull()) {
+    RETURN_TYPE_ERROR(Z, resolved_url, String);
+  }
   const String& source_str = Api::UnwrapStringHandle(Z, source);
   if (source_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, source, String);
@@ -5538,8 +5572,9 @@
     return Api::NewError("%s: library '%s' has already been loaded.",
                          CURRENT_FUNC, url_str.ToCString());
   }
-  const Script& script = Script::Handle(Z,
-      Script::New(url_str, source_str, RawScript::kLibraryTag));
+  const Script& script =
+      Script::Handle(Z, Script::New(url_str, resolved_url_str, source_str,
+                                    RawScript::kLibraryTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
   CompileSource(T, library, script, &result);
@@ -5605,6 +5640,7 @@
 
 DART_EXPORT Dart_Handle Dart_LoadSource(Dart_Handle library,
                                         Dart_Handle url,
+                                        Dart_Handle resolved_url,
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset) {
@@ -5619,6 +5655,13 @@
   if (url_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, url, String);
   }
+  if (::Dart_IsNull(resolved_url)) {
+    resolved_url = url;
+  }
+  const String& resolved_url_str = Api::UnwrapStringHandle(Z, resolved_url);
+  if (resolved_url_str.IsNull()) {
+    RETURN_TYPE_ERROR(Z, resolved_url, String);
+  }
   const String& source_str = Api::UnwrapStringHandle(Z, source);
   if (source_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, source, String);
@@ -5636,8 +5679,9 @@
 
   NoHeapGrowthControlScope no_growth_control;
 
-  const Script& script = Script::Handle(Z,
-      Script::New(url_str, source_str, RawScript::kSourceTag));
+  const Script& script =
+      Script::Handle(Z, Script::New(url_str, resolved_url_str, source_str,
+                                    RawScript::kSourceTag));
   script.SetLocationOffset(line_offset, column_offset);
   Dart_Handle result;
   CompileSource(T, lib, script, &result);
@@ -5668,8 +5712,9 @@
 
   NoHeapGrowthControlScope no_growth_control;
 
-  const Script& script = Script::Handle(Z,
-      Script::New(url_str, source_str, RawScript::kPatchTag));
+  const Script& script =
+      Script::Handle(Z, Script::New(url_str, url_str, source_str,
+                                    RawScript::kPatchTag));
   Dart_Handle result;
   CompileSource(T, lib, script, &result);
   return result;
@@ -5808,6 +5853,77 @@
 }
 
 
+DART_EXPORT int64_t Dart_TimelineGetMicros() {
+  return OS::GetCurrentMonotonicMicros();
+}
+
+
+#if defined(PRODUCT)
+DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data) {
+  return;
+}
+
+
+DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
+    const char* name,
+    Dart_ServiceRequestCallback callback,
+    void* user_data) {
+  return;
+}
+
+
+DART_EXPORT Dart_Handle Dart_SetServiceStreamCallbacks(
+    Dart_ServiceStreamListenCallback listen_callback,
+    Dart_ServiceStreamCancelCallback cancel_callback) {
+  return Api::Success();
+}
+
+
+DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
+                                                  const char* event_kind,
+                                                  const uint8_t* bytes,
+                                                  intptr_t bytes_length) {
+  return Api::Success();
+}
+
+
+DART_EXPORT Dart_Handle Dart_SetFileModifiedCallback(
+    Dart_FileModifiedCallback file_mod_callback) {
+  return Api::Success();
+}
+
+
+DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) {
+  return;
+}
+
+
+DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
+    Dart_EmbedderTimelineStartRecording start_recording,
+    Dart_EmbedderTimelineStopRecording stop_recording) {
+  return;
+}
+
+
+DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
+                                             void* user_data) {
+  return false;
+}
+
+
+DART_EXPORT void Dart_TimelineEvent(const char* label,
+                                    int64_t timestamp0,
+                                    int64_t timestamp1_or_async_id,
+                                    Dart_Timeline_Event_Type type,
+                                    intptr_t argument_count,
+                                    const char** argument_names,
+                                    const char** argument_values) {
+  return;
+}
+#else  // defined(PRODUCT)
 DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
     const char* name,
     Dart_ServiceRequestCallback callback,
@@ -5871,9 +5987,6 @@
                                                   const char* event_kind,
                                                   const uint8_t* bytes,
                                                   intptr_t bytes_length) {
-#if defined(PRODUCT)
-  return Api::Success();
-#else  // defined(PRODUCT)
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   if (stream_id == NULL) {
@@ -5892,12 +6005,30 @@
   Service::SendEmbedderEvent(I, stream_id, event_kind,
                              bytes, bytes_length);
   return Api::Success();
-#endif  // defined(PRODUCT)
 }
 
 
-DART_EXPORT int64_t Dart_TimelineGetMicros() {
-  return OS::GetCurrentMonotonicMicros();
+DART_EXPORT Dart_Handle Dart_SetFileModifiedCallback(
+    Dart_FileModifiedCallback file_modified_callback) {
+  if (!FLAG_support_service) {
+    return Api::Success();
+  }
+  if (file_modified_callback != NULL) {
+    if (IsolateReloadContext::file_modified_callback() != NULL) {
+      return Api::NewError(
+          "%s permits only one callback to be registered, please "
+          "remove the existing callback and then add this callback",
+          CURRENT_FUNC);
+    }
+  } else {
+    if (IsolateReloadContext::file_modified_callback() == NULL) {
+      return Api::NewError(
+          "%s expects 'file_modified_callback' to be set before it is cleared.",
+          CURRENT_FUNC);
+    }
+  }
+  IsolateReloadContext::SetFileModifiedCallback(file_modified_callback);
+  return Api::Success();
 }
 
 
@@ -6125,6 +6256,7 @@
   }
   event->Complete();
 }
+#endif  // defined(PRODUCT)
 
 
 DART_EXPORT void Dart_SetThreadName(const char* name) {
@@ -6181,6 +6313,8 @@
     bool reset_fields) {
 #if defined(TARGET_ARCH_IA32)
   return Api::NewError("Precompilation is not supported on IA32.");
+#elif defined(TARGET_ARCH_DBC)
+  return Api::NewError("Precompilation is not supported on DBC.");
 #else
   API_TIMELINE_BEGIN_END;
   DARTSCOPE(Thread::Current());
@@ -6210,7 +6344,9 @@
     uint8_t** assembly_buffer,
     intptr_t* assembly_size) {
 #if defined(TARGET_ARCH_IA32)
-  return Api::NewError("Snapshots with code are not supported on IA32.");
+  return Api::NewError("Precompilation is not supported on IA32.");
+#elif defined(TARGET_ARCH_DBC)
+  return Api::NewError("Precompilation is not supported on DBC.");
 #else
   API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
@@ -6270,7 +6406,9 @@
     uint8_t** rodata_blob_buffer,
     intptr_t* rodata_blob_size) {
 #if defined(TARGET_ARCH_IA32)
-  return Api::NewError("Snapshots with code are not supported on IA32.");
+  return Api::NewError("Precompilation is not supported on IA32.");
+#elif defined(TARGET_ARCH_DBC)
+  return Api::NewError("Precompilation is not supported on DBC.");
 #else
   API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
@@ -6372,6 +6510,8 @@
     intptr_t* rodata_blob_size) {
 #if defined(TARGET_ARCH_IA32)
   return Api::NewError("Snapshots with code are not supported on IA32.");
+#elif defined(TARGET_ARCH_DBC)
+  return Api::NewError("Snapshots with code are not supported on DBC.");
 #else
   API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 53d7755..8d913dc 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3578,7 +3578,7 @@
     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);
+    Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
     EXPECT_VALID(lib);
     result = Dart_FinalizeLoading(false);
     EXPECT_VALID(result);
@@ -3618,6 +3618,19 @@
 }
 
 
+TEST_CASE(SetStickyError) {
+    const char* kScriptChars =
+      "main() => throw 'HI';";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_Handle retobj = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT(Dart_IsError(retobj));
+  EXPECT(Dart_IsUnhandledExceptionError(retobj));
+  EXPECT(!Dart_HasStickyError());
+  Dart_SetStickyError(retobj);
+  EXPECT(Dart_HasStickyError());
+}
+
+
 TEST_CASE(TypeGetNonParamtericTypes) {
   const char* kScriptChars =
       "class MyClass0 {\n"
@@ -3961,7 +3974,7 @@
   // Load imported lib.
   Dart_Handle url = NewString("library_url");
   Dart_Handle source = NewString(kImportedScriptChars);
-  Dart_Handle imported_lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle imported_lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   Dart_Handle prefix = Dart_EmptyString();
   EXPECT_VALID(imported_lib);
   Dart_Handle result = Dart_LibraryImportLibrary(lib, imported_lib, prefix);
@@ -5356,13 +5369,13 @@
   // Load lib1
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib1 = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib1 = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib1);
 
   // Load lib2
   url = NewString("library2_url");
   source = NewString(kLibrary2Chars);
-  Dart_Handle lib2 = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib2 = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib2);
 
   // Import lib2 from lib1
@@ -5883,37 +5896,47 @@
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
 
-  result = Dart_LoadScript(Dart_Null(), source, 0, 0);
+  result = Dart_LoadScript(Dart_Null(), Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadScript expects argument 'url' to be non-null.",
                Dart_GetError(result));
 
-  result = Dart_LoadScript(Dart_True(), source, 0, 0);
+  result = Dart_LoadScript(Dart_True(), Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadScript expects argument 'url' to be of type String.",
                Dart_GetError(result));
 
-  result = Dart_LoadScript(error, source, 0, 0);
+  result = Dart_LoadScript(error, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("incoming error", Dart_GetError(result));
 
-  result = Dart_LoadScript(url, Dart_Null(), 0, 0);
+  result = Dart_LoadScript(url, Dart_True(), source, 0, 0);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ(
+      "Dart_LoadScript expects argument 'resolved_url' to be of type String.",
+      Dart_GetError(result));
+
+  result = Dart_LoadScript(url, error, source, 0, 0);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ("incoming error", Dart_GetError(result));
+
+  result = Dart_LoadScript(url, Dart_Null(), Dart_Null(), 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadScript expects argument 'source' to be non-null.",
                Dart_GetError(result));
 
-  result = Dart_LoadScript(url, Dart_True(), 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), Dart_True(), 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ(
       "Dart_LoadScript expects argument 'source' to be of type String.",
       Dart_GetError(result));
 
-  result = Dart_LoadScript(url, error, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), error, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("incoming error", Dart_GetError(result));
 
   // Load a script successfully.
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
   Dart_FinalizeLoading(false);
 
@@ -5925,7 +5948,7 @@
   EXPECT_EQ(12345, value);
 
   // Further calls to LoadScript are errors.
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadScript: "
                "A script has already been loaded from 'test-lib'.",
@@ -5947,7 +5970,7 @@
   // Load a script.
   Dart_Handle url = NewString(TestCase::url());
   Dart_Handle source = NewString(kScriptChars);
-  EXPECT_VALID(Dart_LoadScript(url, source, 0, 0));
+  EXPECT_VALID(Dart_LoadScript(url, Dart_Null(), source, 0, 0));
 
   root_lib = Dart_RootLibrary();
   Dart_Handle lib_name = Dart_LibraryName(root_lib);
@@ -6035,7 +6058,7 @@
   Dart_Handle source = NewString(kScriptChars);
   Dart_Handle result = Dart_SetLibraryTagHandler(import_library_handler);
   EXPECT_VALID(result);
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT(strstr(Dart_GetError(result), "unexpected token ')'"));
 }
@@ -6054,12 +6077,12 @@
   Dart_Handle source = NewString(kScriptChars);
   Dart_Handle result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
 
   url = NewString("library1_dart");
   source = NewString(kLibrary1Chars);
-  result = Dart_LoadLibrary(url, source, 0, 0);
+  result = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
 
   result = Dart_LookupLibrary(url);
@@ -6093,7 +6116,7 @@
       "library library1_name;";
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   Dart_Handle error = Dart_NewApiError("incoming error");
   EXPECT_VALID(lib);
 
@@ -6129,7 +6152,7 @@
       "library library1_name;";
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   Dart_Handle error = Dart_NewApiError("incoming error");
   EXPECT_VALID(lib);
   intptr_t libraryId = -1;
@@ -6169,7 +6192,7 @@
       "library library1_name;";
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   Dart_Handle error = Dart_NewApiError("incoming error");
   EXPECT_VALID(lib);
 
@@ -6213,7 +6236,7 @@
 
   Dart_Handle url = NewString("library_url");
   Dart_Handle source = NewString(kLibraryChars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   Dart_Handle result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
@@ -6266,7 +6289,7 @@
   // Get the functions from a library.
   Dart_Handle url = NewString("library_url");
   Dart_Handle source = NewString(kLibraryChars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   Dart_Handle result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
@@ -6318,12 +6341,12 @@
 
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib1 = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib1 = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib1);
 
   url = NewString("library2_url");
   source = NewString(kLibrary2Chars);
-  Dart_Handle lib2 = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib2 = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib2);
 
   result = Dart_LibraryImportLibrary(Dart_Null(), lib2, Dart_Null());
@@ -6369,7 +6392,7 @@
       "int bar() => 42;";
   Dart_Handle url1 = NewString("library1_url");
   Dart_Handle source1 = NewString(kLibrary1Chars);
-  Dart_Handle lib1 = Dart_LoadLibrary(url1, source1, 0, 0);
+  Dart_Handle lib1 = Dart_LoadLibrary(url1, Dart_Null(), source1, 0, 0);
   EXPECT_VALID(lib1);
   EXPECT(Dart_IsLibrary(lib1));
 
@@ -6378,7 +6401,7 @@
       "int foobar() => foo.bar();";
   Dart_Handle url2 = NewString("library2_url");
   Dart_Handle source2 = NewString(kLibrary2Chars);
-  Dart_Handle lib2 = Dart_LoadLibrary(url2, source2, 0, 0);
+  Dart_Handle lib2 = Dart_LoadLibrary(url2, Dart_Null(), source2, 0, 0);
   EXPECT_VALID(lib2);
   EXPECT(Dart_IsLibrary(lib2));
 
@@ -6415,42 +6438,52 @@
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
 
-  result = Dart_LoadLibrary(Dart_Null(), source, 0, 0);
+  result = Dart_LoadLibrary(Dart_Null(), Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadLibrary expects argument 'url' to be non-null.",
                Dart_GetError(result));
 
-  result = Dart_LoadLibrary(Dart_True(), source, 0, 0);
+  result = Dart_LoadLibrary(Dart_True(), Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadLibrary expects argument 'url' to be of type String.",
                Dart_GetError(result));
 
-  result = Dart_LoadLibrary(error, source, 0, 0);
+  result = Dart_LoadLibrary(error, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("incoming error", Dart_GetError(result));
 
-  result = Dart_LoadLibrary(url, Dart_Null(), 0, 0);
+  result = Dart_LoadLibrary(url, Dart_True(), source, 0, 0);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ(
+      "Dart_LoadLibrary expects argument 'resolved_url' to be of type String.",
+      Dart_GetError(result));
+
+  result = Dart_LoadLibrary(url, error, source, 0, 0);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ("incoming error", Dart_GetError(result));
+
+  result = Dart_LoadLibrary(url, Dart_Null(), Dart_Null(), 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadLibrary expects argument 'source' to be non-null.",
                Dart_GetError(result));
 
-  result = Dart_LoadLibrary(url, Dart_True(), 0, 0);
+  result = Dart_LoadLibrary(url, Dart_Null(), Dart_True(), 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ(
       "Dart_LoadLibrary expects argument 'source' to be of type String.",
       Dart_GetError(result));
 
-  result = Dart_LoadLibrary(url, error, 0, 0);
+  result = Dart_LoadLibrary(url, Dart_Null(), error, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("incoming error", Dart_GetError(result));
 
   // Success.
-  result = Dart_LoadLibrary(url, source, 0, 0);
+  result = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
   EXPECT(Dart_IsLibrary(result));
 
   // Duplicate library load fails.
-  result = Dart_LoadLibrary(url, source, 0, 0);
+  result = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ(
       "Dart_LoadLibrary: library 'library1_url' has already been loaded.",
@@ -6464,7 +6497,7 @@
       ")";
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle result = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle result = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT(strstr(Dart_GetError(result), "unexpected token ')'"));
 }
@@ -6483,72 +6516,82 @@
   // Load up a library.
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   EXPECT(Dart_IsLibrary(lib));
 
   url = NewString("source_url");
   source = NewString(kSourceChars);
 
-  result = Dart_LoadSource(Dart_Null(), url, source, 0, 0);
+  result = Dart_LoadSource(Dart_Null(), url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadSource expects argument 'library' to be non-null.",
                Dart_GetError(result));
 
-  result = Dart_LoadSource(Dart_True(), url, source, 0, 0);
+  result = Dart_LoadSource(Dart_True(), url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ(
       "Dart_LoadSource expects argument 'library' to be of type Library.",
       Dart_GetError(result));
 
-  result = Dart_LoadSource(error, url, source, 0, 0);
+  result = Dart_LoadSource(error, url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("incoming error", Dart_GetError(result));
 
-  result = Dart_LoadSource(lib, Dart_Null(), source, 0, 0);
+  result = Dart_LoadSource(lib, Dart_Null(), Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadSource expects argument 'url' to be non-null.",
                Dart_GetError(result));
 
-  result = Dart_LoadSource(lib, Dart_True(), source, 0, 0);
+  result = Dart_LoadSource(lib, Dart_True(), Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadSource expects argument 'url' to be of type String.",
                Dart_GetError(result));
 
-  result = Dart_LoadSource(lib, error, source, 0, 0);
+  result = Dart_LoadSource(lib, error, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("incoming error", Dart_GetError(result));
 
-  result = Dart_LoadSource(lib, url, Dart_Null(), 0, 0);
+  result = Dart_LoadSource(lib, url, Dart_True(), source, 0, 0);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ(
+      "Dart_LoadSource expects argument 'resolved_url' to be of type String.",
+      Dart_GetError(result));
+
+  result = Dart_LoadSource(lib, url, error, source, 0, 0);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ("incoming error", Dart_GetError(result));
+
+  result = Dart_LoadSource(lib, url, Dart_Null(), Dart_Null(), 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("Dart_LoadSource expects argument 'source' to be non-null.",
                Dart_GetError(result));
 
-  result = Dart_LoadSource(lib, url, Dart_True(), 0, 0);
+  result = Dart_LoadSource(lib, url, Dart_Null(), Dart_True(), 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ(
       "Dart_LoadSource expects argument 'source' to be of type String.",
       Dart_GetError(result));
 
-  result = Dart_LoadSource(lib, error, source, 0, 0);
+  result = Dart_LoadSource(lib, error, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
   EXPECT_STREQ("incoming error", Dart_GetError(result));
 
   // Success.
-  result = Dart_LoadSource(lib, url, source, 0, 0);
+  result = Dart_LoadSource(lib, url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
   EXPECT(Dart_IsLibrary(result));
   EXPECT(Dart_IdentityEquals(lib, result));
 
   // Duplicate calls are okay.
-  result = Dart_LoadSource(lib, url, source, 0, 0);
+  result = Dart_LoadSource(lib, url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
   EXPECT(Dart_IsLibrary(result));
   EXPECT(Dart_IdentityEquals(lib, result));
 
   // Language errors are detected.
   source = NewString(kBadSourceChars);
-  result = Dart_LoadSource(lib, url, source, 0, 0);
+  result = Dart_LoadSource(lib, url, Dart_Null(), source, 0, 0);
   EXPECT(Dart_IsError(result));
 }
 
@@ -6566,7 +6609,7 @@
       "}\n";
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   EXPECT(Dart_IsLibrary(lib));
   Dart_Handle result = Dart_FinalizeLoading(false);
@@ -6586,7 +6629,7 @@
   // Load a source file late.
   url = NewString("source_url");
   source = NewString(kSourceChars);
-  EXPECT_VALID(Dart_LoadSource(lib, url, source, 0, 0));
+  EXPECT_VALID(Dart_LoadSource(lib, url, Dart_Null(), source, 0, 0));
   result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
 
@@ -6610,19 +6653,19 @@
       "part of library1_name;\n"
       "external int foo();";
   const char* kPatchChars =
-      "patch int foo() => 42;";
+      "@patch int foo() => 42;";
 
   // Load up a library.
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   EXPECT(Dart_IsLibrary(lib));
 
   url = NewString("source_url");
   source = NewString(kSourceChars);
 
-  Dart_Handle result = Dart_LoadSource(lib, url, source, 0, 0);
+  Dart_Handle result = Dart_LoadSource(lib, url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
 
   url = NewString("patch_url");
@@ -6655,8 +6698,8 @@
       "}";
   const char* kPatchChars =
       "const _UNDEFINED = const Object();\n"
-      "patch foo([x=_UNDEFINED]) => identical(x, _UNDEFINED) ? 42 : x;\n"
-      "patch class Foo {\n"
+      "@patch foo([x=_UNDEFINED]) => identical(x, _UNDEFINED) ? 42 : x;\n"
+      "@patch class Foo {\n"
       "  static addDefault10([x=_UNDEFINED, y=_UNDEFINED]) {\n"
       "    if (identical(x, _UNDEFINED)) x = 10;\n"
       "    if (identical(y, _UNDEFINED)) y = 10;\n"
@@ -6670,14 +6713,14 @@
   // Load up a library.
   Dart_Handle url = NewString("library1_url");
   Dart_Handle source = NewString(kLibrary1Chars);
-  Dart_Handle lib = Dart_LoadLibrary(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   EXPECT(Dart_IsLibrary(lib));
 
   url = NewString("source_url");
   source = NewString(kSourceChars);
 
-  Dart_Handle result = Dart_LoadSource(lib, url, source, 0, 0);
+  Dart_Handle result = Dart_LoadSource(lib, url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
 
   url = NewString("patch_url");
@@ -6799,39 +6842,39 @@
   "external void set topLevelSetter(int value);\n";
 
   const char* kPatchChars =
-  "patch class A {\n"
+  "@patch class A {\n"
   "  var _g;\n"
   "  A() : fvalue = 13;\n"
   "  get _field => _g;\n"
-  "  /*patch*/ void method(var value) {\n"
+  "  @patch void method(var value) {\n"
   "    int closeYourEyes(var eggs) { return eggs * -1; }\n"
   "    value = callFunc(closeYourEyes, value);\n"
   "    _g = value * 5;\n"
   "  }\n"
   "}\n"
-  "patch class B {\n"
+  "@patch class B {\n"
   "  B._internal(x) : val = x;\n"
-  "  /*patch*/ factory B.named(x) { return new B._internal(x); }\n"
-  "  /*patch*/ factory B(v) native \"const_B_factory\";\n"
+  "  @patch factory B.named(x) { return new B._internal(x); }\n"
+  "  @patch factory B(v) native \"const_B_factory\";\n"
   "}\n"
   "var _topLevelValue = -1;\n"
-  "patch int topLevel(var value) => value * value;\n"
-  "patch int set topLevelSetter(value) { _topLevelValue = value; }\n"
-  "patch int get topLevelGetter => 2 * _topLevelValue;\n"
+  "@patch int topLevel(var value) => value * value;\n"
+  "@patch int set topLevelSetter(value) { _topLevelValue = value; }\n"
+  "@patch int get topLevelGetter => 2 * _topLevelValue;\n"
   // Allow top level methods named patch.
   "patch(x) => x*3;\n"
   ;  // NOLINT
 
   const char* kPatchClassOnlyChars =
-  "patch class C {\n"
-  "  /*patch*/ int method() {\n"
+  "@patch class C {\n"
+  "  @patch int method() {\n"
   "    return 42;\n"
   "  }\n"
   "}\n"
   ;  // NOLINT
 
   const char* kPatchNoClassChars =
-  "patch topLevel2(x) => x * 2;\n";
+  "@patch topLevel2(x) => x * 2;\n";
 
   const char* kScriptChars =
   "import 'theLibrary';\n"
@@ -6862,7 +6905,7 @@
 
   Dart_Handle url = NewString("theLibrary");
   Dart_Handle source = NewString(kLibraryChars);
-  result = Dart_LoadLibrary(url, source, 0, 0);
+  result = Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
 
   const char* patchNames[] = { "main library patch",
@@ -6892,7 +6935,8 @@
 
   Dart_Handle script_url = NewString("theScript");
   source = NewString(kScriptChars);
-  Dart_Handle test_script = Dart_LoadScript(script_url, source, 0, 0);
+  Dart_Handle test_script =
+      Dart_LoadScript(script_url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(test_script);
   result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
@@ -6996,7 +7040,7 @@
   Dart_Handle source = NewString(kScriptChars);
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  Dart_Handle lib = Dart_LoadScript(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
@@ -7082,15 +7126,15 @@
   Dart_Handle source = NewString(kScriptChars);
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
 
   url = NewString("library1_dart");
   source = NewString(kLibrary1Chars);
-  Dart_LoadLibrary(url, source, 0, 0);
+  Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
 
   url = NewString("library2_dart");
   source = NewString(kLibrary2Chars);
-  Dart_LoadLibrary(url, source, 0, 0);
+  Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
 
   Dart_FinalizeLoading(false);
 
@@ -7120,16 +7164,16 @@
   Dart_Handle source = NewString(kScriptChars);
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
 
   url = NewString("library2_dart");
   source = NewString(kLibrary2Chars);
-  Dart_LoadLibrary(url, source, 0, 0);
+  Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
 
   url = NewString("library1_dart");
   source = NewString(kLibrary1Chars);
-  Dart_LoadLibrary(url, source, 0, 0);
+  Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
 
@@ -7159,16 +7203,16 @@
   Dart_Handle source = NewString(kScriptChars);
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(result);
 
   url = NewString("library2_dart");
   source = NewString(kLibrary2Chars);
-  Dart_LoadLibrary(url, source, 0, 0);
+  Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
 
   url = NewString("library1_dart");
   source = NewString(kLibrary1Chars);
-  Dart_LoadLibrary(url, source, 0, 0);
+  Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   Dart_FinalizeLoading(false);
 
   result = Dart_Invoke(result, NewString("main"), 0, NULL);
@@ -7195,11 +7239,11 @@
   Dart_Handle source = NewString(kScriptChars);
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  result = Dart_LoadScript(url, source, 0, 0);
+  result = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
 
   url = NewString("lib.dart");
   source = NewString(kLibraryChars);
-  Dart_LoadLibrary(url, source, 0, 0);
+  Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   Dart_FinalizeLoading(false);
 
   result = Dart_Invoke(result, NewString("main"), 0, NULL);
@@ -7538,7 +7582,7 @@
   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);
+  Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
@@ -7645,7 +7689,7 @@
     Dart_Handle source = NewString(kScriptChars);
     Dart_Handle result = Dart_SetLibraryTagHandler(TestCase::library_handler);
     EXPECT_VALID(result);
-    lib = Dart_LoadScript(url, source, 0, 0);
+    lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
     EXPECT_VALID(lib);
     result = Dart_FinalizeLoading(false);
     EXPECT_VALID(result);
@@ -7758,7 +7802,7 @@
     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);
+    Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
     EXPECT_VALID(lib);
     result = Dart_FinalizeLoading(false);
     EXPECT_VALID(result);
@@ -7937,7 +7981,7 @@
   Dart_Handle source = NewString(kScriptChars);
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  Dart_Handle lib = Dart_LoadScript(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   EXPECT(Dart_IsLibrary(lib));
   result = Dart_SetNativeResolver(lib, &MyNativeClosureResolver, NULL);
@@ -8086,7 +8130,7 @@
   Dart_Handle source = NewString(kScriptChars);
   result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
-  Dart_Handle lib = Dart_LoadScript(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   EXPECT_VALID(lib);
   EXPECT(Dart_IsLibrary(lib));
   result = Dart_SetNativeResolver(lib, &MyStaticNativeClosureResolver, NULL);
@@ -8855,7 +8899,7 @@
 
   Dart_Handle source = NewString(kLoadSecond);
   Dart_Handle url = NewString(TestCase::url());
-  Dart_LoadSource(TestCase::lib(), url, source, 0, 0);
+  Dart_LoadSource(TestCase::lib(), url, Dart_Null(), source, 0, 0);
   result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
 
@@ -10015,9 +10059,9 @@
       "foomoo() { A.moo(); }\n";
 
   const char* kScriptChars2 =
-      "patch class A {\n"
-      "  /* patch */ int zoo() { return 1; }\n"
-      "  /* patch */ static int moo() { return 1; }\n"
+      "@patch class A {\n"
+      "  @patch int zoo() { return 1; }\n"
+      "  @patch static int moo() { return 1; }\n"
       "}\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
@@ -10055,9 +10099,9 @@
       "foozoo() { new A().zoo(); }\n";
 
   const char* kScriptChars2 =
-      "patch class A {\n"
-      "  /* patch */ int zoo() { return 1; }\n"
-      "  /* patch */ int fld1;\n"
+      "@patch class A {\n"
+      "  @patch int zoo() { return 1; }\n"
+      "  @patch int fld1;\n"
       "}\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
@@ -10092,8 +10136,8 @@
       "foozoo() { new A().zoo(); }\n";
 
   const char* kScriptChars2 =
-      "patch class A {\n"
-      "  /* patch */ int zoo() { return 1; }\n"
+      "@patch class A {\n"
+      "  @patch int zoo() { return 1; }\n"
       "}\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
@@ -10129,8 +10173,8 @@
       "foozoo() { new A().zoo(); }\n";
 
   const char* kScriptChars2 =
-      "patch class A {\n"
-      "  /* patch */ int zoo() { return 1; }\n"
+      "@patch class A {\n"
+      "  @patch int zoo() { return 1; }\n"
       "}\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars1, NULL);
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 2d4e759..ed04af0 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -642,8 +642,6 @@
     }
     case kOneByteStringCid: {
       intptr_t len = ReadSmiValue();
-      intptr_t hash = ReadSmiValue();
-      USE(hash);
       uint8_t *latin1 =
           reinterpret_cast<uint8_t*>(allocator(len * sizeof(uint8_t)));
       intptr_t utf8_len = 0;
@@ -663,8 +661,6 @@
     }
     case kTwoByteStringCid: {
       intptr_t len = ReadSmiValue();
-      intptr_t hash = ReadSmiValue();
-      USE(hash);
       uint16_t *utf16 = reinterpret_cast<uint16_t*>(
           allocator(len * sizeof(uint16_t)));
       intptr_t utf8_len = 0;
@@ -1203,9 +1199,8 @@
       WriteIndexedObject(type == Utf8::kLatin1 ? kOneByteStringCid
                                                : kTwoByteStringCid);
       WriteTags(0);
-      // Write string length, hash and content
+      // Write string length and content.
       WriteSmi(len);
-      WriteSmi(0);  // TODO(sgjesse): Hash - not written.
       if (type == Utf8::kLatin1) {
         uint8_t* latin1_str =
             reinterpret_cast<uint8_t*>(::malloc(len * sizeof(uint8_t)));
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 64476a9..155512a 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -519,7 +519,7 @@
     token_pos_ = TokenPosition::kNoSource;
     GetPcDescriptors();
     PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
-    uword pc_offset = pc_ - code().EntryPoint();
+    uword pc_offset = pc_ - code().PayloadStart();
     while (iter.MoveNext()) {
       if (iter.PcOffset() == pc_offset) {
         try_index_ = iter.TryIndex();
@@ -827,7 +827,7 @@
   if (deopt_frame_.IsNull()) {
     return GetVariableValue(LocalVarAddress(fp(), slot_index));
   } else {
-    return deopt_frame_.At(deopt_frame_offset_ + slot_index);
+    return deopt_frame_.At(LocalVarIndex(deopt_frame_offset_, slot_index));
   }
 }
 
@@ -1108,7 +1108,8 @@
 #if !defined(TARGET_ARCH_DBC)
       saved_value_(Code::null())
 #else
-      saved_value_(Bytecode::kTrap)
+      saved_value_(Bytecode::kTrap),
+      saved_value_fastsmi_(Bytecode::kTrap)
 #endif
     {
   ASSERT(!code.IsNull());
@@ -1527,7 +1528,7 @@
     if (!function.IsNull() && function.is_visible()) {
       code = ex_trace.CodeAtFrame(i);
       ASSERT(function.raw() == code.function());
-      uword pc = code.EntryPoint() + Smi::Value(ex_trace.PcOffsetAtFrame(i));
+      uword pc = code.PayloadStart() + Smi::Value(ex_trace.PcOffsetAtFrame(i));
       if (code.is_optimized() && ex_trace.expand_inlined()) {
         // Traverse inlined frames.
         for (InlinedFunctionsIterator it(code, pc); !it.Done(); it.Advance()) {
@@ -1536,8 +1537,8 @@
           ASSERT(function.raw() == code.function());
           uword pc = it.pc();
           ASSERT(pc != 0);
-          ASSERT(code.EntryPoint() <= pc);
-          ASSERT(pc < (code.EntryPoint() + code.Size()));
+          ASSERT(code.PayloadStart() <= pc);
+          ASSERT(pc < (code.PayloadStart() + code.Size()));
 
           ActivationFrame* activation = new ActivationFrame(
             pc, fp, sp, code, deopt_frame, deopt_frame_offset);
@@ -1827,7 +1828,7 @@
   if (lowest_pc_offset == kUwordMax) {
     return;
   }
-  uword lowest_pc = code.EntryPoint() + lowest_pc_offset;
+  uword lowest_pc = code.PayloadStart() + lowest_pc_offset;
   CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc);
   if (code_bpt == NULL) {
     // No code breakpoint for this code exists; create one.
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 1d7e1ce..e78e839 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -235,6 +235,7 @@
   // DebugBreak. This is an instruction that was replaced. DebugBreak
   // will execute it after the breakpoint.
   Instr saved_value_;
+  Instr saved_value_fastsmi_;
 #endif
 
   friend class Debugger;
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 957bd6f..18fb194 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -54,12 +54,17 @@
                          CURRENT_FUNC, #param);                                \
   }
 
+#define CHECK_DEBUGGER(isolate)                                                \
+  if (isolate->debugger() == NULL) {                                           \
+    return Api::NewError("%s requires debugger support.", CURRENT_FUNC);       \
+  }
+
 
 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()) {
+  if (obj.IsApiError() || (I->debugger() == NULL)) {
     return -1;
   }
   return I->debugger()->CacheObject(obj);
@@ -69,6 +74,7 @@
 DART_EXPORT Dart_Handle Dart_GetCachedObject(intptr_t obj_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   if (!I->debugger()->IsValidObjectId(obj_id)) {
     return Api::NewError("%s: object id %" Pd " is invalid",
                          CURRENT_FUNC, obj_id);
@@ -208,6 +214,7 @@
                             Dart_ExceptionPauseInfo pause_info) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetExceptionPauseInfo(pause_info);
   return Api::Success();
 }
@@ -216,6 +223,9 @@
 DART_EXPORT Dart_ExceptionPauseInfo Dart_GetExceptionPauseInfo() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  if (I->debugger() == NULL) {
+    return kNoPauseOnExceptions;
+  }
   return I->debugger()->GetExceptionPauseInfo();
 }
 
@@ -223,6 +233,7 @@
 DART_EXPORT Dart_Handle Dart_GetStackTrace(Dart_StackTrace* trace) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   CHECK_NOT_NULL(trace);
   *trace = reinterpret_cast<Dart_StackTrace>(
       I->debugger()->CurrentStackTrace());
@@ -233,6 +244,7 @@
 DART_EXPORT Dart_Handle Dart_GetStackTraceFromError(Dart_Handle handle,
                                                     Dart_StackTrace* trace) {
   DARTSCOPE(Thread::Current());
+  CHECK_DEBUGGER(T->isolate());
   CHECK_NOT_NULL(trace);
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
   if (obj.IsUnhandledException()) {
@@ -341,6 +353,7 @@
                             intptr_t line_number) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
 
   Debugger* debugger = I->debugger();
@@ -357,6 +370,7 @@
 DART_EXPORT Dart_Handle Dart_GetBreakpointURL(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   Debugger* debugger = I->debugger();
 
   Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
@@ -371,6 +385,7 @@
 DART_EXPORT Dart_Handle Dart_GetBreakpointLine(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   Debugger* debugger = I->debugger();
 
   Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
@@ -392,6 +407,7 @@
                             Dart_Handle function_name_in) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   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);
@@ -432,6 +448,7 @@
                             Dart_Handle function_name_in) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   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);
@@ -468,6 +485,7 @@
 DART_EXPORT Dart_Handle Dart_RemoveBreakpoint(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->RemoveBreakpoint(bp_id);
   return Api::Success();
 }
@@ -476,6 +494,7 @@
 DART_EXPORT Dart_Handle Dart_SetStepOver() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetStepOver();
   return Api::Success();
 }
@@ -484,6 +503,7 @@
 DART_EXPORT Dart_Handle Dart_SetStepInto() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetSingleStep();
   return Api::Success();
 }
@@ -492,6 +512,7 @@
 DART_EXPORT Dart_Handle Dart_SetStepOut() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetStepOut();
   return Api::Success();
 }
@@ -500,6 +521,7 @@
 DART_EXPORT Dart_Handle Dart_GetInstanceFields(Dart_Handle object_in) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
   return Api::NewHandle(T, I->debugger()->GetInstanceFields(obj));
 }
@@ -508,6 +530,7 @@
 DART_EXPORT Dart_Handle Dart_GetStaticFields(Dart_Handle target) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   const Type& type_obj = Api::UnwrapTypeHandle(Z, target);
   if (type_obj.IsNull()) {
     return Api::NewError("%s expects argument 'target' to be a type",
@@ -521,6 +544,7 @@
 DART_EXPORT Dart_Handle Dart_GetLibraryFields(intptr_t library_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   const Library& lib =
       Library::Handle(Z, Library::GetLibrary(library_id));
   if (lib.IsNull()) {
@@ -534,6 +558,7 @@
 DART_EXPORT Dart_Handle Dart_GetGlobalVariables(intptr_t library_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
 
   const Library& lib = Library::Handle(Z, Library::GetLibrary(library_id));
   if (lib.IsNull()) {
@@ -548,6 +573,7 @@
                             Dart_ActivationFrame activation_frame,
                             Dart_Handle expr_in) {
   DARTSCOPE(Thread::Current());
+  CHECK_DEBUGGER(T->isolate());
   CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
   UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
   return Api::NewHandle(T, frame->Evaluate(expr));
@@ -557,6 +583,7 @@
 DART_EXPORT Dart_Handle Dart_EvaluateExpr(Dart_Handle target_in,
                                           Dart_Handle expr_in) {
   DARTSCOPE(Thread::Current());
+  CHECK_DEBUGGER(T->isolate());
 
   const Object& target = Object::Handle(Z, Api::UnwrapHandle(target_in));
   if (target.IsError()) return target_in;
@@ -718,6 +745,7 @@
                             Dart_Handle* static_fields) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   if (!I->class_table()->IsValidIndex(cls_id)) {
     return Api::NewError("%s: %" Pd " is not a valid class id",
                          CURRENT_FUNC, cls_id);
@@ -967,6 +995,9 @@
 
 DART_EXPORT Dart_IsolateId Dart_GetIsolateId(Dart_Isolate dart_isolate) {
   Isolate* isolate = reinterpret_cast<Isolate*>(dart_isolate);
+  if (isolate->debugger() == NULL) {
+    return ILLEGAL_ISOLATE_ID;
+  }
   return isolate->debugger()->GetIsolateId();
 }
 
diff --git a/runtime/vm/debugger_dbc.cc b/runtime/vm/debugger_dbc.cc
index 5f82cd5..ac21678 100644
--- a/runtime/vm/debugger_dbc.cc
+++ b/runtime/vm/debugger_dbc.cc
@@ -25,12 +25,17 @@
 }
 
 
+static Instr* FastSmiInstructionFromReturnAddress(uword pc) {
+  return reinterpret_cast<Instr*>(pc) - 2;
+}
+
+
 void CodeBreakpoint::PatchCode() {
   ASSERT(!is_enabled_);
   const Code& code = Code::Handle(code_);
   const Instructions& instrs = Instructions::Handle(code.instructions());
   {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
+    WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
     saved_value_ = *CallInstructionFromReturnAddress(pc_);
     switch (breakpoint_kind_) {
       case RawPcDescriptors::kIcCall:
@@ -54,6 +59,17 @@
       default:
         UNREACHABLE();
     }
+
+    // If this call is the fall-through for a fast Smi op, also disable the fast
+    // Smi op.
+    if ((Bytecode::DecodeOpcode(saved_value_) == Bytecode::kInstanceCall2) &&
+        Bytecode::IsFastSmiOpcode(*FastSmiInstructionFromReturnAddress(pc_))) {
+      saved_value_fastsmi_ = *FastSmiInstructionFromReturnAddress(pc_);
+      *FastSmiInstructionFromReturnAddress(pc_) =
+          Bytecode::Encode(Bytecode::kNop, 0, 0, 0);
+    } else {
+      saved_value_fastsmi_ = Bytecode::kTrap;
+    }
   }
   is_enabled_ = true;
 }
@@ -64,7 +80,7 @@
   const Code& code = Code::Handle(code_);
   const Instructions& instrs = Instructions::Handle(code.instructions());
   {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
+    WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
     switch (breakpoint_kind_) {
       case RawPcDescriptors::kIcCall:
       case RawPcDescriptors::kUnoptStaticCall:
@@ -75,6 +91,12 @@
       default:
         UNREACHABLE();
     }
+
+    if (saved_value_fastsmi_ != Bytecode::kTrap) {
+      Instr current_instr = *FastSmiInstructionFromReturnAddress(pc_);
+      ASSERT(Bytecode::DecodeOpcode(current_instr) == Bytecode::kNop);
+      *FastSmiInstructionFromReturnAddress(pc_) = saved_value_fastsmi_;
+    }
   }
   is_enabled_ = false;
 }
diff --git a/runtime/vm/debugger_ia32.cc b/runtime/vm/debugger_ia32.cc
index 9c4473b..c900f75 100644
--- a/runtime/vm/debugger_ia32.cc
+++ b/runtime/vm/debugger_ia32.cc
@@ -30,7 +30,7 @@
   const Instructions& instrs = Instructions::Handle(code.instructions());
   Code& stub_target = Code::Handle();
   {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
+    WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
     switch (breakpoint_kind_) {
       case RawPcDescriptors::kIcCall:
       case RawPcDescriptors::kUnoptStaticCall: {
@@ -57,7 +57,7 @@
   const Code& code = Code::Handle(code_);
   const Instructions& instrs = Instructions::Handle(code.instructions());
   {
-    WritableInstructionsScope writable(instrs.EntryPoint(), instrs.size());
+    WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
     switch (breakpoint_kind_) {
       case RawPcDescriptors::kIcCall:
       case RawPcDescriptors::kUnoptStaticCall:
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index f31a897..e658740 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -7,6 +7,7 @@
 #include "vm/assembler.h"
 #include "vm/code_patcher.h"
 #include "vm/compiler.h"
+#include "vm/disassembler.h"
 #include "vm/intermediate_language.h"
 #include "vm/locations.h"
 #include "vm/parser.h"
@@ -52,6 +53,13 @@
       deoptimizing_code_(deoptimizing_code) {
   const TypedData& deopt_info = TypedData::Handle(
       code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_));
+#if defined(DEBUG)
+  if (deopt_info.IsNull()) {
+    OS::PrintErr("Missing deopt info for pc %" Px "\n", frame->pc());
+    DisassembleToStdout formatter;
+    code.Disassemble(&formatter);
+  }
+#endif
   ASSERT(!deopt_info.IsNull());
   deopt_info_ = deopt_info.raw();
 
@@ -147,6 +155,7 @@
   delete[] deferred_objects_;
   deferred_objects_ = NULL;
   deferred_objects_count_ = 0;
+#ifndef PRODUCT
   if (FLAG_support_timeline && (deopt_start_micros_ != 0)) {
     TimelineStream* compiler_stream = Timeline::GetCompilerStream();
     ASSERT(compiler_stream != NULL);
@@ -172,6 +181,7 @@
       }
     }
   }
+#endif  // !PRODUCT
 }
 
 
@@ -1045,6 +1055,10 @@
   Location::Kind stack_slot_kind) {
   if (loc.IsFpuRegister()) {
     return FpuRegisterSource(FpuRegisterSource::kRegister, loc.fpu_reg());
+#if defined(TARGET_ARCH_DBC)
+  } else if (loc.IsRegister()) {
+    return FpuRegisterSource(FpuRegisterSource::kRegister, loc.reg());
+#endif
   } else {
     ASSERT((stack_slot_kind == Location::kQuadStackSlot) ||
            (stack_slot_kind == Location::kDoubleStackSlot));
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 79a2c50..09e01b4 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -86,8 +86,14 @@
     ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles());
     ASSERT(fpu_registers_ != NULL);
     ASSERT(reg >= 0);
+#if !defined(TARGET_ARCH_DBC)
     ASSERT(reg < kNumberOfFpuRegisters);
     return *reinterpret_cast<double*>(&fpu_registers_[reg]);
+#else
+    // On DBC registers and stack slots are the same.
+    const intptr_t stack_index = num_args_ + kDartFrameFixedSize + reg;
+    return *reinterpret_cast<double*>(GetSourceFrameAddressAt(stack_index));
+#endif
   }
 
   simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const {
diff --git a/runtime/vm/disassembler.cc b/runtime/vm/disassembler.cc
index eef90c3..abf9c84 100644
--- a/runtime/vm/disassembler.cc
+++ b/runtime/vm/disassembler.cc
@@ -26,6 +26,7 @@
                                              intptr_t hex_size,
                                              char* human_buffer,
                                              intptr_t human_size,
+                                             Object* object,
                                              uword pc) {
   static const int kHexColumnWidth = 23;
   uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc);
@@ -37,6 +38,9 @@
     }
   }
   THR_Print("%s", human_buffer);
+  if (object != NULL) {
+    THR_Print("   %s", object->ToCString());
+  }
   THR_Print("\n");
 }
 
@@ -54,6 +58,7 @@
                                                  intptr_t hex_size,
                                                  char* human_buffer,
                                                  intptr_t human_size,
+                                                 Object* object,
                                                  uword pc) {
   // 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,
@@ -63,9 +68,8 @@
   jsarr_.AddValue(hex_buffer);
   jsarr_.AddValue(human_buffer);
 
-  Object& object = Object::Handle();
-  if (DecodeLoadObjectFromPoolOrThread(pc, code, &object)) {
-    jsarr_.AddValue(object);
+  if (object != NULL) {
+    jsarr_.AddValue(*object);
   } else {
     jsarr_.AddValueNull();  // Not a reference to null.
   }
@@ -97,33 +101,6 @@
 }
 
 
-class FindAddrVisitor : public FindObjectVisitor {
- public:
-  explicit FindAddrVisitor(uword addr) : addr_(addr) { }
-  virtual ~FindAddrVisitor() { }
-
-  virtual uword filter_addr() const { return addr_; }
-
-  // Check if object matches find condition.
-  virtual bool FindObject(RawObject* obj) const {
-    return obj == reinterpret_cast<RawObject*>(addr_);
-  }
-
- private:
-  const uword addr_;
-
-  DISALLOW_COPY_AND_ASSIGN(FindAddrVisitor);
-};
-
-
-bool Disassembler::CanFindOldObject(uword addr) {
-  FindAddrVisitor visitor(addr);
-  NoSafepointScope no_safepoint;
-  return Dart::vm_isolate()->heap()->FindOldObject(&visitor) != Object::null()
-      || Isolate::Current()->heap()->FindOldObject(&visitor) != Object::null();
-}
-
-
 void Disassembler::Disassemble(uword start,
                                uword end,
                                DisassemblyFormatter* formatter,
@@ -168,16 +145,18 @@
       }
     }
     int instruction_length;
+    Object* object;
     DecodeInstruction(hex_buffer,
                       sizeof(hex_buffer),
                       human_buffer,
                       sizeof(human_buffer),
-                      &instruction_length, pc);
+                      &instruction_length, code, &object, pc);
     formatter->ConsumeInstruction(code,
                                   hex_buffer,
                                   sizeof(hex_buffer),
                                   human_buffer,
                                   sizeof(human_buffer),
+                                  object,
                                   pc);
     pc += instruction_length;
   }
@@ -197,7 +176,7 @@
   // Pointer offsets are stored in descending order.
   Object& obj = Object::Handle();
   for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) {
-    const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
+    const uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
     obj = *reinterpret_cast<RawObject**>(addr);
     THR_Print(" %d : %#" Px " '%s'\n",
               code.GetPointerOffsetAt(i), addr, obj.ToCString());
@@ -216,7 +195,7 @@
       PcDescriptors::Handle(code.pc_descriptors());
   THR_Print("%s}\n", descriptors.ToCString());
 
-  uword start = Instructions::Handle(code.instructions()).EntryPoint();
+  uword start = Instructions::Handle(code.instructions()).PayloadStart();
   const Array& deopt_table = Array::Handle(code.deopt_info_array());
   intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table);
   if (deopt_table_length > 0) {
@@ -250,37 +229,39 @@
   }
   THR_Print("}\n");
 
-  THR_Print("Variable Descriptors for function '%s' {\n",
-            function_fullname);
-  const LocalVarDescriptors& var_descriptors =
-      LocalVarDescriptors::Handle(code.GetLocalVarDescriptors());
-  intptr_t var_desc_length =
-      var_descriptors.IsNull() ? 0 : var_descriptors.Length();
-  String& var_name = String::Handle();
-  for (intptr_t i = 0; i < var_desc_length; i++) {
-    var_name = var_descriptors.GetName(i);
-    RawLocalVarDescriptors::VarInfo var_info;
-    var_descriptors.GetInfo(i, &var_info);
-    const int8_t kind = var_info.kind();
-    if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
-      THR_Print("  saved current CTX reg offset %d\n", var_info.index());
-    } else {
-      if (kind == RawLocalVarDescriptors::kContextLevel) {
-        THR_Print("  context level %d scope %d", var_info.index(),
-            var_info.scope_id);
-      } else if (kind == RawLocalVarDescriptors::kStackVar) {
-        THR_Print("  stack var '%s' offset %d",
-          var_name.ToCString(), var_info.index());
+  if (FLAG_print_variable_descriptors) {
+    THR_Print("Variable Descriptors for function '%s' {\n",
+              function_fullname);
+    const LocalVarDescriptors& var_descriptors =
+        LocalVarDescriptors::Handle(code.GetLocalVarDescriptors());
+    intptr_t var_desc_length =
+        var_descriptors.IsNull() ? 0 : var_descriptors.Length();
+    String& var_name = String::Handle();
+    for (intptr_t i = 0; i < var_desc_length; i++) {
+      var_name = var_descriptors.GetName(i);
+      RawLocalVarDescriptors::VarInfo var_info;
+      var_descriptors.GetInfo(i, &var_info);
+      const int8_t kind = var_info.kind();
+      if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
+        THR_Print("  saved current CTX reg offset %d\n", var_info.index());
       } else {
-        ASSERT(kind == RawLocalVarDescriptors::kContextVar);
-        THR_Print("  context var '%s' level %d offset %d",
-            var_name.ToCString(), var_info.scope_id, var_info.index());
+        if (kind == RawLocalVarDescriptors::kContextLevel) {
+          THR_Print("  context level %d scope %d", var_info.index(),
+              var_info.scope_id);
+        } else if (kind == RawLocalVarDescriptors::kStackVar) {
+          THR_Print("  stack var '%s' offset %d",
+            var_name.ToCString(), var_info.index());
+        } else {
+          ASSERT(kind == RawLocalVarDescriptors::kContextVar);
+          THR_Print("  context var '%s' level %d offset %d",
+              var_name.ToCString(), var_info.scope_id, var_info.index());
+        }
+        THR_Print(" (valid %s-%s)\n", var_info.begin_pos.ToCString(),
+                                      var_info.end_pos.ToCString());
       }
-      THR_Print(" (valid %s-%s)\n", var_info.begin_pos.ToCString(),
-                                    var_info.end_pos.ToCString());
     }
+    THR_Print("}\n");
   }
-  THR_Print("}\n");
 
   THR_Print("Exception Handlers for function '%s' {\n", function_fullname);
   const ExceptionHandlers& handlers =
diff --git a/runtime/vm/disassembler.h b/runtime/vm/disassembler.h
index fc3649a..7adb12a 100644
--- a/runtime/vm/disassembler.h
+++ b/runtime/vm/disassembler.h
@@ -29,6 +29,7 @@
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
+                                  Object* object,
                                   uword pc) = 0;
 
   // Print a formatted message.
@@ -48,6 +49,7 @@
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
+                                  Object* object,
                                   uword pc);
 
   virtual void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
@@ -70,6 +72,7 @@
                                   intptr_t hex_size,
                                   char* human_buffer,
                                   intptr_t human_size,
+                                  Object* object,
                                   uword pc);
 
   virtual void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
@@ -112,29 +115,14 @@
     Disassemble(start, end, &stdout_formatter);
   }
 
-  // Disassemble instructions in a memory region.
-  static void DisassembleMemoryRegion(const MemoryRegion& instructions,
-                                      DisassemblyFormatter* formatter) {
-    uword start = instructions.start();
-    uword end = instructions.end();
-    Disassemble(start, end, formatter);
-  }
-
-  static void DisassembleMemoryRegion(const MemoryRegion& instructions) {
-    uword start = instructions.start();
-    uword end = instructions.end();
-    Disassemble(start, end);
-  }
-
   // Decodes one instruction.
   // Writes a hexadecimal representation into the hex_buffer and a
   // human-readable representation into the human_buffer.
   // Writes the length of the decoded instruction in bytes in out_instr_len.
   static void DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                 char* human_buffer, intptr_t human_size,
-                                int* out_instr_len, uword pc);
-
-  static bool CanFindOldObject(uword addr);
+                                int* out_instr_len, const Code& code,
+                                Object** object, uword pc);
 
   static void DisassembleCode(const Function& function, bool optimized);
   static void DisassembleCodeUnoptimized(
diff --git a/runtime/vm/disassembler_arm.cc b/runtime/vm/disassembler_arm.cc
index 2b0c103..67c0afb 100644
--- a/runtime/vm/disassembler_arm.cc
+++ b/runtime/vm/disassembler_arm.cc
@@ -6,9 +6,9 @@
 
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM.
 #if defined(TARGET_ARCH_ARM)
-
 #include "platform/assert.h"
 #include "vm/cpu.h"
+#include "vm/instructions.h"
 
 namespace dart {
 
@@ -1534,7 +1534,8 @@
 
 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                      char* human_buffer, intptr_t human_size,
-                                     int* out_instr_size, uword pc) {
+                                     int* out_instr_size, const Code& code,
+                                     Object** object, uword pc) {
   ARMDecoder decoder(human_buffer, human_size);
   decoder.InstructionDecode(pc);
   int32_t instruction_bits = Instr::At(pc)->InstructionBits();
@@ -1542,6 +1543,14 @@
   if (out_instr_size) {
     *out_instr_size = Instr::kInstrSize;
   }
+
+  *object = NULL;
+  if (!code.IsNull()) {
+    *object = &Object::Handle();
+    if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
+      *object = NULL;
+    }
+  }
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/disassembler_arm64.cc b/runtime/vm/disassembler_arm64.cc
index a238641..dd7d00c 100644
--- a/runtime/vm/disassembler_arm64.cc
+++ b/runtime/vm/disassembler_arm64.cc
@@ -7,6 +7,7 @@
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM64.
 #if defined(TARGET_ARCH_ARM64)
 #include "platform/assert.h"
+#include "vm/instructions.h"
 
 namespace dart {
 
@@ -1488,7 +1489,8 @@
 
 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                      char* human_buffer, intptr_t human_size,
-                                     int* out_instr_size, uword pc) {
+                                     int* out_instr_size, const Code& code,
+                                     Object** object, uword pc) {
   ARM64Decoder decoder(human_buffer, human_size);
   decoder.InstructionDecode(pc);
   int32_t instruction_bits = Instr::At(pc)->InstructionBits();
@@ -1496,6 +1498,14 @@
   if (out_instr_size) {
     *out_instr_size = Instr::kInstrSize;
   }
+
+  *object = NULL;
+  if (!code.IsNull()) {
+    *object = &Object::Handle();
+    if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
+      *object = NULL;
+    }
+  }
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/disassembler_dbc.cc b/runtime/vm/disassembler_dbc.cc
index 5c8b3a0..a2095a0 100644
--- a/runtime/vm/disassembler_dbc.cc
+++ b/runtime/vm/disassembler_dbc.cc
@@ -10,6 +10,7 @@
 #include "platform/assert.h"
 #include "vm/constants_dbc.h"
 #include "vm/cpu.h"
+#include "vm/instructions.h"
 
 namespace dart {
 
@@ -214,6 +215,8 @@
                                      char* human_buffer,
                                      intptr_t human_size,
                                      int* out_instr_size,
+                                     const Code& code,
+                                     Object** object,
                                      uword pc) {
   const uint32_t instr = *reinterpret_cast<uint32_t*>(pc);
   const uint8_t opcode = instr & 0xFF;
@@ -229,6 +232,14 @@
   if (out_instr_size) {
     *out_instr_size = sizeof(uint32_t);
   }
+
+  *object = NULL;
+  if (!code.IsNull()) {
+    *object = &Object::Handle();
+    if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
+      *object = NULL;
+    }
+  }
 }
 
 
diff --git a/runtime/vm/disassembler_ia32.cc b/runtime/vm/disassembler_ia32.cc
index 31e4fdba..d0252d3 100644
--- a/runtime/vm/disassembler_ia32.cc
+++ b/runtime/vm/disassembler_ia32.cc
@@ -465,69 +465,17 @@
 }
 
 
-static const char* ObjectToCStringNoGC(const Object& obj) {
-  if (obj.IsSmi() ||
-      obj.IsMint() ||
-      obj.IsDouble() ||
-      obj.IsString() ||
-      obj.IsNull() ||
-      obj.IsBool() ||
-      obj.IsClass() ||
-      obj.IsFunction() ||
-      obj.IsICData() ||
-      obj.IsField() ||
-      obj.IsCode()) {
-    return obj.ToCString();
-  }
-
-  const Class& clazz = Class::Handle(obj.clazz());
-  const char* full_class_name = clazz.ToCString();
-  return OS::SCreate(Thread::Current()->zone(),
-      "instance of %s", full_class_name);
-}
-
-
 void X86Decoder::PrintAddress(uword addr) {
   char addr_buffer[32];
   OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr);
   Print(addr_buffer);
-  // Try to print as heap object or stub name
-  if (((addr & kSmiTagMask) == kHeapObjectTag) &&
-      reinterpret_cast<RawObject*>(addr)->IsWellFormed() &&
-      reinterpret_cast<RawObject*>(addr)->IsOldObject() &&
-      !Isolate::Current()->heap()->CodeContains(addr) &&
-      !Dart::vm_isolate()->heap()->CodeContains(addr) &&
-      Disassembler::CanFindOldObject(addr)) {
-    NoSafepointScope no_safepoint;
-    const Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr));
-    if (obj.IsArray()) {
-      const Array& arr = Array::Cast(obj);
-      intptr_t len = arr.Length();
-      if (len > 5) len = 5;  // Print a max of 5 elements.
-      Print("  Array[");
-      int i = 0;
-      Object& element = Object::Handle();
-      while (i < len) {
-        element = arr.At(i);
-        if (i > 0) Print(", ");
-        Print(ObjectToCStringNoGC(element));
-        i++;
-      }
-      if (i < arr.Length()) Print(", ...");
-      Print("]");
-      return;
-    }
-    Print("  '");
-    Print(ObjectToCStringNoGC(obj));
-    Print("'");
-  } else {
-    // 'addr' is not an object, but probably a code address.
-    const char* name_of_stub = StubCode::NameOfStub(addr);
-    if (name_of_stub != NULL) {
-      Print("  [stub: ");
-      Print(name_of_stub);
-      Print("]");
-    }
+
+  // Try to print as  stub name.
+  const char* name_of_stub = StubCode::NameOfStub(addr);
+  if (name_of_stub != NULL) {
+    Print("  [stub: ");
+    Print(name_of_stub);
+    Print("]");
   }
 }
 
@@ -1845,7 +1793,8 @@
 
 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                      char* human_buffer, intptr_t human_size,
-                                     int* out_instr_len, uword pc) {
+                                     int* out_instr_len, const Code& code,
+                                     Object** object, uword pc) {
   ASSERT(hex_size > 0);
   ASSERT(human_size > 0);
   X86Decoder decoder(human_buffer, human_size);
@@ -1862,6 +1811,18 @@
   if (out_instr_len) {
     *out_instr_len = instruction_length;
   }
+
+  *object = NULL;
+  if (!code.IsNull() && code.is_alive()) {
+    intptr_t offsets_length = code.pointer_offsets_length();
+    for (intptr_t i = 0; i < offsets_length; i++) {
+      uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
+      if ((pc <= addr) && (addr < (pc + instruction_length))) {
+        *object = &Object::Handle(*reinterpret_cast<RawObject**>(addr));
+        break;
+      }
+    }
+  }
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index 22fe462..78831a7 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -7,6 +7,7 @@
 #include "vm/globals.h"  // Needed here to get TARGET_ARCH_MIPS.
 #if defined(TARGET_ARCH_MIPS)
 #include "platform/assert.h"
+#include "vm/instructions.h"
 
 namespace dart {
 
@@ -778,7 +779,8 @@
 
 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                      char* human_buffer, intptr_t human_size,
-                                     int* out_instr_len, uword pc) {
+                                     int* out_instr_len, const Code& code,
+                                     Object** object, uword pc) {
   MIPSDecoder decoder(human_buffer, human_size);
   Instr* instr = Instr::At(pc);
   decoder.InstructionDecode(instr);
@@ -786,6 +788,14 @@
   if (out_instr_len) {
     *out_instr_len = Instr::kInstrSize;
   }
+
+  *object = NULL;
+  if (!code.IsNull()) {
+    *object = &Object::Handle();
+    if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
+      *object = NULL;
+    }
+  }
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc
index 60118f1..f389415 100644
--- a/runtime/vm/disassembler_x64.cc
+++ b/runtime/vm/disassembler_x64.cc
@@ -9,6 +9,7 @@
 #include "platform/utils.h"
 #include "vm/allocation.h"
 #include "vm/heap.h"
+#include "vm/instructions.h"
 #include "vm/os.h"
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
@@ -785,65 +786,9 @@
 }
 
 
-static const char* ObjectToCStringNoGC(const Object& obj) {
-  if (obj.IsSmi() ||
-      obj.IsMint() ||
-      obj.IsDouble() ||
-      obj.IsString() ||
-      obj.IsNull() ||
-      obj.IsBool() ||
-      obj.IsClass() ||
-      obj.IsFunction() ||
-      obj.IsICData() ||
-      obj.IsField() ||
-      obj.IsCode()) {
-    return obj.ToCString();
-  }
-
-  const Class& clazz = Class::Handle(obj.clazz());
-  const char* full_class_name = clazz.ToCString();
-  return OS::SCreate(Thread::Current()->zone(),
-      "instance of %s", full_class_name);
-}
-
-
 void DisassemblerX64::PrintAddress(uint8_t* addr_byte_ptr) {
   uword addr = reinterpret_cast<uword>(addr_byte_ptr);
   Print("%#" Px "", addr);
-  // Try to print as heap object or stub name
-  if (((addr & kSmiTagMask) == kHeapObjectTag) &&
-      reinterpret_cast<RawObject*>(addr)->IsWellFormed() &&
-      reinterpret_cast<RawObject*>(addr)->IsOldObject() &&
-      !Dart::vm_isolate()->heap()->CodeContains(addr) &&
-      !Isolate::Current()->heap()->CodeContains(addr) &&
-      Disassembler::CanFindOldObject(addr)) {
-    NoSafepointScope no_safepoint;
-    const Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr));
-    if (obj.IsArray()) {
-      const Array& arr = Array::Cast(obj);
-      intptr_t len = arr.Length();
-      if (len > 5) len = 5;  // Print a max of 5 elements.
-      Print("  Array[");
-      int i = 0;
-      Object& element = Object::Handle();
-      while (i < len) {
-        element = arr.At(i);
-        if (i > 0) Print(", ");
-        Print("%s", ObjectToCStringNoGC(element));
-        i++;
-      }
-      if (i < arr.Length()) Print(", ...");
-      Print("]");
-      return;
-    }
-    Print("  '%s'", ObjectToCStringNoGC(obj));
-  } else {
-    // 'addr' is not an object, but probably a code address.
-    const char* name_of_stub = StubCode::NameOfStub(addr);
-    if (name_of_stub != NULL) {
-      Print("  [stub: %s]", name_of_stub);
-    }
-  }
 }
 
 
@@ -1935,7 +1880,8 @@
 
 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size,
                                      char* human_buffer, intptr_t human_size,
-                                     int* out_instr_len, uword pc) {
+                                     int* out_instr_len, const Code& code,
+                                     Object** object, uword pc) {
   ASSERT(hex_size > 0);
   ASSERT(human_size > 0);
   DisassemblerX64 decoder(human_buffer, human_size);
@@ -1952,6 +1898,14 @@
   if (out_instr_len) {
     *out_instr_len = instruction_length;
   }
+
+  *object = NULL;
+  if (!code.IsNull()) {
+    *object = &Object::Handle();
+    if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
+      *object = NULL;
+    }
+  }
 }
 
 #endif  // !PRODUCT
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 2cb67e1..37a99f2 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -127,7 +127,7 @@
   while (frame != NULL) {
     if (frame->IsDartFrame()) {
       code = frame->LookupDartCode();
-      offset = Smi::New(frame->pc() - code.EntryPoint());
+      offset = Smi::New(frame->pc() - code.PayloadStart());
       builder->AddFrame(code, offset);
     }
     frame = frames.NextFrame();
diff --git a/runtime/vm/find_code_object_test.cc b/runtime/vm/find_code_object_test.cc
index b7e437b..75ffa2b 100644
--- a/runtime/vm/find_code_object_test.cc
+++ b/runtime/vm/find_code_object_test.cc
@@ -13,19 +13,20 @@
 
 namespace dart {
 
-VM_TEST_CASE(FindCodeObject) {
 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
-  const int kLoopCount = 50000;
-  const int kScriptSize = 512 * KB;
+static const int kScriptSize = 512 * KB;
+static const int kLoopCount = 50000;
 #elif defined(TARGET_ARCH_DBC)
-  const int kLoopCount = 60000;
-  const int kScriptSize = 1 * MB;
+static const int kScriptSize = 1 * MB;
+static const int kLoopCount = 60000;
 #else
-  const int kLoopCount = 25000;
-  const int kScriptSize = 512 * KB;
+static const int kScriptSize = 512 * KB;
+static const int kLoopCount = 25000;
 #endif
+static char scriptChars[kScriptSize];
+
+VM_TEST_CASE(FindCodeObject) {
   const int kNumFunctions = 1024;
-  char scriptChars[kScriptSize];
 
   // Get access to the code index table.
   Isolate* isolate = Isolate::Current();
@@ -132,7 +133,7 @@
   EXPECT(!function.IsNull());
   code = function.CurrentCode();
   EXPECT(code.Size() > 16);
-  pc = code.EntryPoint() + 16;
+  pc = code.PayloadStart() + 16;
   EXPECT(Code::LookupCode(pc) == code.raw());
 
   OS::SNPrint(buffer, 256, "moo%d", 54);
@@ -141,7 +142,7 @@
   EXPECT(!function.IsNull());
   code = function.CurrentCode();
   EXPECT(code.Size() > 16);
-  pc = code.EntryPoint() + 16;
+  pc = code.PayloadStart() + 16;
   EXPECT(Code::LookupCode(pc) == code.raw());
 
   // Lookup the large function
@@ -151,11 +152,11 @@
   EXPECT(!function.IsNull());
   code = function.CurrentCode();
   EXPECT(code.Size() > 16);
-  pc = code.EntryPoint() + 16;
+  pc = code.PayloadStart() + 16;
   EXPECT(code.Size() > (PageSpace::kPageSizeInWords << kWordSizeLog2));
   EXPECT(Code::LookupCode(pc) == code.raw());
   EXPECT(code.Size() > (1 * MB));
-  pc = code.EntryPoint() + (1 * MB);
+  pc = code.PayloadStart() + (1 * MB);
   EXPECT(Code::LookupCode(pc) == code.raw());
 }
 
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index c22e43c..7daddd9 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -12,6 +12,12 @@
 #define USING_DBC false
 #endif
 
+#if defined(TARGET_OS_FUCHSIA)
+#define USING_FUCHSIA true
+#else
+#define USING_FUCHSIA false
+#endif
+
 // Don't use USING_MULTICORE outside of this file.
 #if defined(ARCH_IS_MULTI_CORE)
 #define USING_MULTICORE true
@@ -35,8 +41,6 @@
 //   D(name, type, default_value, comment)
 //   C(name, precompiled_value, product_value, type, default_value, comment)
 #define FLAG_LIST(P, R, D, C)                                                  \
-P(always_megamorphic_calls, bool, false,                                       \
-  "Instance call always as megamorphic.")                                      \
 P(background_compilation, bool, USING_MULTICORE,                               \
   "Run optimizing compilation in background")                                  \
 R(background_compilation_stop_alot, false, bool, false,                        \
@@ -90,8 +94,6 @@
   "Ratio of getter/setter usage used for double field unboxing heuristics")    \
 P(guess_icdata_cid, bool, true,                                                \
   "Artificially create type feedback for arithmetic etc. operations")          \
-P(ic_range_profiling, bool, !USING_DBC,                                        \
-  "Generate special IC stubs collecting range information ")                   \
 P(interpret_irregexp, bool, USING_DBC,                                         \
   "Use irregexp bytecode interpreter")                                         \
 P(lazy_dispatchers, bool, true,                                                \
@@ -108,7 +110,7 @@
 P(max_polymorphic_checks, int, 4,                                              \
   "Maximum number of polymorphic check, otherwise it is megamorphic.")         \
 P(max_equality_polymorphic_checks, int, 32,                                    \
-    "Maximum number of polymorphic checks in equality operator,")              \
+  "Maximum number of polymorphic checks in equality operator,")                \
 P(merge_sin_cos, bool, false,                                                  \
   "Merge sin/cos into sincos")                                                 \
 P(new_gen_ext_limit, int, 64,                                                  \
@@ -138,7 +140,9 @@
   "Print live ranges after allocation.")                                       \
 C(print_stop_message, false, false, bool, false,                               \
   "Print stop message.")                                                       \
-R(profiler, false, bool, !USING_DBC,                                           \
+D(print_variable_descriptors, bool, false,                                     \
+  "Print variable descriptors in disassembly.")                                \
+R(profiler, false, bool, !USING_DBC && !USING_FUCHSIA,                         \
   "Enable the profiler.")                                                      \
 P(reorder_basic_blocks, bool, true,                                            \
   "Reorder basic blocks")                                                      \
@@ -146,13 +150,13 @@
   "Support the AST printer.")                                                  \
 R(support_compiler_stats, false, bool, true,                                   \
   "Support compiler stats.")                                                   \
-R(support_debugger, false, bool, true,                                         \
+C(support_debugger, false, false, bool, true,                                  \
   "Support the debugger.")                                                     \
 R(support_disassembler, false, bool, true,                                     \
   "Support the disassembler.")                                                 \
 R(support_il_printer, false, bool, true,                                       \
   "Support the IL printer.")                                                   \
-R(support_reload, false, bool, true,                                           \
+C(support_reload, false, false, bool, true,                                    \
   "Support isolate reload.")                                                   \
 R(support_service, false, bool, true,                                          \
   "Support the service protocol.")                                             \
@@ -184,8 +188,6 @@
   "Use field guards and track field types")                                    \
 C(use_osr, false, true, bool, true,                                            \
   "Use OSR")                                                                   \
-R(verbose_dev, false, bool, false,                                             \
-  "Enables verbose messages during development.")                              \
 P(verbose_gc, bool, false,                                                     \
   "Enables verbose GC.")                                                       \
 P(verbose_gc_hdr, int, 40,                                                     \
diff --git a/runtime/vm/flags.cc b/runtime/vm/flags.cc
index cb76c91..8c5a9d8 100644
--- a/runtime/vm/flags.cc
+++ b/runtime/vm/flags.cc
@@ -487,6 +487,7 @@
 }
 
 
+#ifndef PRODUCT
 void Flags::PrintFlagToJSONArray(JSONArray* jsarr, const Flag* flag) {
   if (!FLAG_support_service) {
     return;
@@ -542,5 +543,6 @@
     PrintFlagToJSONArray(&jsarr, flags_[i]);
   }
 }
+#endif  // !PRODUCT
 
 }  // namespace dart
diff --git a/runtime/vm/flags.h b/runtime/vm/flags.h
index 81f594e..b30299c 100644
--- a/runtime/vm/flags.h
+++ b/runtime/vm/flags.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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.
 
@@ -67,7 +67,9 @@
 
   static bool Initialized() { return initialized_; }
 
+#ifndef PRODUCT
   static void PrintJSON(JSONStream* js);
+#endif  // !PRODUCT
 
   static bool SetFlag(const char* name,
                       const char* value,
@@ -90,7 +92,9 @@
 
   static void PrintFlags();
 
+#ifndef PRODUCT
   static void PrintFlagToJSONArray(JSONArray* jsarr, const Flag* flag);
+#endif  // !PRODUCT
 
   // Testing needs direct access to private methods.
   friend void Dart_TestParseFlags();
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 009e500..558e6f7 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -749,15 +749,22 @@
 
 
 static Location::Kind RegisterKindForResult(Instruction* instr) {
-  if ((instr->representation() == kUnboxedDouble) ||
-      (instr->representation() == kUnboxedFloat32x4) ||
-      (instr->representation() == kUnboxedInt32x4) ||
-      (instr->representation() == kUnboxedFloat64x2) ||
-      (instr->representation() == kPairOfUnboxedDouble)) {
+  const Representation rep = instr->representation();
+#if !defined(TARGET_ARCH_DBC)
+  if ((rep == kUnboxedDouble) || (rep == kUnboxedFloat32x4) ||
+      (rep == kUnboxedInt32x4) || (rep == kUnboxedFloat64x2) ||
+      (rep == kPairOfUnboxedDouble)) {
     return Location::kFpuRegister;
   } else {
     return Location::kRegister;
   }
+#else
+  // DBC supports only unboxed doubles and does not have distinguished FPU
+  // registers.
+  ASSERT((rep != kUnboxedFloat32x4) && (rep != kUnboxedInt32x4) &&
+         (rep != kUnboxedFloat64x2) && (rep != kPairOfUnboxedDouble));
+  return Location::kRegister;
+#endif
 }
 
 
@@ -3055,6 +3062,11 @@
                        unallocated_xmm_,
                        fpu_regs_,
                        blocked_fpu_registers_);
+#if defined(TARGET_ARCH_DBC)
+  // For DBC all registers should have been allocated in the first pass.
+  ASSERT(unallocated_.is_empty());
+#endif
+
   AllocateUnallocatedRanges();
 #if defined(TARGET_ARCH_DBC)
   const intptr_t last_used_fpu_register = last_used_register_;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index aeea819..0bcf854 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -899,10 +899,13 @@
           context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
           token_pos));
     }
-    return new(Z) LoadFieldInstr(context,
-                                 Context::variable_offset(local.index()),
-                                 local.type(),
-                                 token_pos);
+    LoadFieldInstr* load = new(Z) LoadFieldInstr(
+        context,
+        Context::variable_offset(local.index()),
+        local.type(),
+        token_pos);
+    load->set_is_immutable(local.is_final());
+    return load;
   } else {
     return new(Z) LoadLocalInstr(local, token_pos);
   }
@@ -1543,6 +1546,22 @@
   return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name));
 }
 
+static bool simpleInstanceOfType(const AbstractType& type) {
+  // Bail if the type is still uninstantiated at compile time.
+  if (!type.IsInstantiated()) return false;
+
+  // Bail if the type is a function or a Dart Function type.
+  if (type.IsFunctionType() || type.IsDartFunctionType()) return false;
+
+  ASSERT(type.HasResolvedTypeClass());
+  const Class& type_class = Class::Handle(type.type_class());
+  // Bail if the type has any type parameters.
+  if (type_class.IsGeneric()) return false;
+
+  // Finally a simple class for instance of checking.
+  return true;
+}
+
 
 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
   ASSERT(Token::IsTypeTestOperator(node->kind()));
@@ -1599,7 +1618,32 @@
     return;
   }
 
+  // We now know type is a real class (!num, !int, !smi, !string)
+  // and the type check could NOT be removed at compile time.
   PushArgumentInstr* push_left = PushArgument(for_left_value.value());
+  if (simpleInstanceOfType(type)) {
+    ASSERT(!node->right()->AsTypeNode()->type().IsNull());
+    ZoneGrowableArray<PushArgumentInstr*>* arguments =
+        new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
+    arguments->Add(push_left);
+    Value* type_const = Bind(new(Z) ConstantInstr(type));
+    arguments->Add(PushArgument(type_const));
+    const intptr_t kNumArgsChecked = 2;
+    Definition* result = new(Z) InstanceCallInstr(
+        node->token_pos(),
+        Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()),
+        node->kind(),
+        arguments,
+        Object::null_array(),  // No argument names.
+        kNumArgsChecked,
+        owner()->ic_data_array());
+    if (negate_result) {
+      result = new(Z) BooleanNegateInstr(Bind(result));
+    }
+    ReturnDefinition(result);
+    return;
+  }
+
   PushArgumentInstr* push_type_args = NULL;
   if (type.IsInstantiated()) {
     push_type_args = PushArgument(BuildNullValue(node->token_pos()));
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 13159ba..8367316 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -43,7 +43,6 @@
 DEFINE_FLAG(bool, source_lines, false, "Emit source line as assembly comment.");
 DEFINE_FLAG(bool, trace_inlining_intervals, false,
     "Inlining interval diagnostics");
-DEFINE_FLAG(bool, use_megamorphic_stub, true, "Out of line megamorphic lookup");
 
 DECLARE_FLAG(bool, code_comments);
 DECLARE_FLAG(charp, deoptimize_filter);
@@ -85,9 +84,7 @@
     FLAG_inlining_constant_arguments_min_size_threshold = 30;
 
     FLAG_background_compilation = false;
-    FLAG_always_megamorphic_calls = true;
     FLAG_fields_may_be_reset = true;
-    FLAG_ic_range_profiling = false;
     FLAG_interpret_irregexp = true;
     FLAG_lazy_dispatchers = false;
     FLAG_link_natives_lazily = true;
@@ -356,7 +353,7 @@
 bool FlowGraphCompiler::ForceSlowPathForStackOverflow() const {
   if ((FLAG_stacktrace_every > 0) ||
       (FLAG_deoptimize_every > 0) ||
-      (FLAG_reload_every > 0)) {
+      (isolate()->reload_every_n_stack_overflow_checks() > 0)) {
     return true;
   }
   if (FLAG_stacktrace_filter != NULL &&
@@ -993,12 +990,15 @@
                                   uint32_t flags) {
   ASSERT(is_optimizing());
   ASSERT(!intrinsic_mode());
+  // The pending deoptimization environment may be changed after this deopt is
+  // emitted, so we need to make a copy.
+  Environment* env_copy =
+      pending_deoptimization_env_->DeepCopy(zone());
   CompilerDeoptInfo* info =
       new(zone()) CompilerDeoptInfo(deopt_id,
                                     reason,
                                     flags,
-                                    pending_deoptimization_env_);
-
+                                    env_copy);
   deopt_infos_.Add(info);
   assembler()->Deopt(0, /*is_eager =*/ 1);
   info->set_pc_offset(assembler()->CodeSize());
@@ -1009,7 +1009,7 @@
 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
   ASSERT(exception_handlers_list_ != NULL);
   const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
-      exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
+      exception_handlers_list_->FinalizeExceptionHandlers(code.PayloadStart()));
   code.set_exception_handlers(handlers);
   if (FLAG_compiler_stats) {
     Thread* thread = Thread::Current();
@@ -1023,7 +1023,7 @@
 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
   ASSERT(pc_descriptors_list_ != NULL);
   const PcDescriptors& descriptors = PcDescriptors::Handle(
-      pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint()));
+      pc_descriptors_list_->FinalizePcDescriptors(code.PayloadStart()));
   if (!is_optimizing_) descriptors.Verify(parsed_function_.function());
   code.set_pc_descriptors(descriptors);
   code.set_lazy_deopt_pc_offset(lazy_deopt_pc_offset_);
@@ -1198,12 +1198,6 @@
                                deopt_id, token_pos, locs);
     return;
   }
-  if (FLAG_always_megamorphic_calls) {
-    EmitMegamorphicInstanceCall(ic_data_in, argument_count,
-                                deopt_id, token_pos, locs,
-                                CatchClauseNode::kInvalidTryIndex);
-    return;
-  }
   ASSERT(!ic_data.IsNull());
   if (is_optimizing() && (ic_data_in.NumberOfUsedChecks() == 0)) {
     // Emit IC call that will count and thus may need reoptimization at
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 0a30dc9..7541f1b 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -199,7 +199,6 @@
   Label* exit_label() { return &exit_label_; }
 
   void GenerateCode(FlowGraphCompiler* compiler) {
-    ASSERT(exit_label_.IsBound());
     EmitNativeCode(compiler);
     ASSERT(entry_label_.IsBound());
   }
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 4162943..09be30f 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -27,7 +27,6 @@
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
-DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -1056,13 +1055,8 @@
   // No such checking code is generated if only fixed parameters are declared,
   // unless we are in debug mode or unless we are compiling a closure.
   if (num_copied_params == 0) {
-#ifdef DEBUG
-    ASSERT(!parsed_function().function().HasOptionalParameters());
-    const bool check_arguments = !flow_graph().IsCompiledForOsr();
-#else
     const bool check_arguments =
         function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
-#endif
     if (check_arguments) {
       __ Comment("Check argument count");
       // Check that exactly num_fixed arguments are passed in.
@@ -1075,14 +1069,10 @@
       __ cmp(R0, Operand(R1));
       __ b(&correct_num_arguments, EQ);
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
-        ASSERT(assembler()->constant_pool_allowed());
-        __ LeaveDartFrame(kKeepCalleePP);  // Arguments are still on the stack.
-        __ Branch(*StubCode::CallClosureNoSuchMethod_entry());
-        // The noSuchMethod call may return to the caller, but not here.
-      } else {
-        __ Stop("Wrong number of arguments");
-      }
+      ASSERT(assembler()->constant_pool_allowed());
+      __ LeaveDartFrame(kKeepCalleePP);  // Arguments are still on the stack.
+      __ Branch(*StubCode::CallClosureNoSuchMethod_entry());
+      // The noSuchMethod call may return to the caller, but not here.
       __ Bind(&correct_num_arguments);
     }
   } else if (!flow_graph().IsCompiledForOsr()) {
@@ -1342,12 +1332,8 @@
     __ Comment("Slow case: megamorphic call");
   }
   __ LoadObject(R9, cache);
-  if (FLAG_use_megamorphic_stub) {
-    __ BranchLink(*StubCode::MegamorphicLookup_entry());
-  } else {
-    StubCode::EmitMegamorphicLookup(assembler());
-  }
-  __ blx(R1);
+  __ ldr(LR, Address(THR, Thread::megamorphic_lookup_checked_entry_offset()));
+  __ blx(LR);
 
   __ Bind(&done);
   RecordSafepoint(locs, slow_path_argument_count);
@@ -1385,12 +1371,17 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
-  __ Comment("SwitchableCall");
-  __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
   ASSERT(ic_data.NumArgsTested() == 1);
+  const Code& initial_stub = Code::ZoneHandle(
+      StubCode::ICLookupThroughFunction_entry()->code());
+
+  __ Comment("SwitchableCall");
+
+  __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
   __ LoadUniqueObject(R9, ic_data);
-  __ BranchLinkPatchable(*StubCode::ICLookupThroughFunction_entry());
-  __ blx(R1);
+  __ LoadUniqueObject(CODE_REG, initial_stub);
+  __ ldr(LR, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+  __ blx(LR);
 
   AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
@@ -1432,7 +1423,12 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
-  __ LoadObject(R4, arguments_descriptor);
+  ASSERT(!function.IsClosureFunction());
+  if (function.HasOptionalParameters()) {
+    __ LoadObject(R4, arguments_descriptor);
+  } else {
+    __ LoadImmediate(R4, 0);  // GC safe smi zero because of stub.
+  }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateStaticDartCall(deopt_id,
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index d0c066e..5dd2308 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -25,7 +25,6 @@
 
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(bool, enable_simd_inline);
-DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -1051,13 +1050,8 @@
   // No such checking code is generated if only fixed parameters are declared,
   // unless we are in debug mode or unless we are compiling a closure.
   if (num_copied_params == 0) {
-#ifdef DEBUG
-    ASSERT(!parsed_function().function().HasOptionalParameters());
-    const bool check_arguments = !flow_graph().IsCompiledForOsr();
-#else
     const bool check_arguments =
         function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
-#endif
     if (check_arguments) {
       __ Comment("Check argument count");
       // Check that exactly num_fixed arguments are passed in.
@@ -1070,13 +1064,9 @@
       __ CompareRegisters(R0, R1);
       __ b(&correct_num_arguments, EQ);
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
-        __ LeaveDartFrame(kKeepCalleePP);  // Arguments are still on the stack.
-        __ BranchPatchable(*StubCode::CallClosureNoSuchMethod_entry());
-        // The noSuchMethod call may return to the caller, but not here.
-      } else {
-        __ Stop("Wrong number of arguments");
-      }
+      __ LeaveDartFrame(kKeepCalleePP);  // Arguments are still on the stack.
+      __ BranchPatchable(*StubCode::CallClosureNoSuchMethod_entry());
+      // The noSuchMethod call may return to the caller, but not here.
       __ Bind(&correct_num_arguments);
     }
   } else if (!flow_graph().IsCompiledForOsr()) {
@@ -1324,12 +1314,8 @@
   }
 
   __ LoadObject(R5, cache);
-  if (FLAG_use_megamorphic_stub) {
-    __ BranchLink(*StubCode::MegamorphicLookup_entry());
-  } else  {
-    StubCode::EmitMegamorphicLookup(assembler());
-  }
-  __ blr(R1);
+  __ ldr(LR, Address(THR, Thread::megamorphic_lookup_checked_entry_offset()));
+  __ blr(LR);
 
   __ Bind(&done);
   RecordSafepoint(locs, slow_path_argument_count);
@@ -1366,12 +1352,16 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
-  __ Comment("SwitchableCall");
-  __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
   ASSERT(ic_data.NumArgsTested() == 1);
+  const Code& initial_stub = Code::ZoneHandle(
+      StubCode::ICLookupThroughFunction_entry()->code());
+  __ Comment("SwitchableCall");
+
+  __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
   __ LoadUniqueObject(R5, ic_data);
-  __ BranchLinkPatchable(*StubCode::ICLookupThroughFunction_entry());
-  __ blr(R1);
+  __ LoadUniqueObject(CODE_REG, initial_stub);
+  __ ldr(TMP, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+  __ blr(TMP);
 
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
@@ -1413,7 +1403,12 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
-  __ LoadObject(R4, arguments_descriptor);
+  ASSERT(!function.IsClosureFunction());
+  if (function.HasOptionalParameters()) {
+    __ LoadObject(R4, arguments_descriptor);
+  } else {
+    __ LoadImmediate(R4, 0);  // GC safe smi zero because of stub.
+  }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateStaticDartCall(deopt_id,
diff --git a/runtime/vm/flow_graph_compiler_dbc.cc b/runtime/vm/flow_graph_compiler_dbc.cc
index 8fb0b4c..fc1534d 100644
--- a/runtime/vm/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/flow_graph_compiler_dbc.cc
@@ -27,7 +27,6 @@
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
-DECLARE_FLAG(bool, use_megamorphic_stub);
 DECLARE_FLAG(charp, optimization_filter);
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -45,7 +44,12 @@
 
 
 bool FlowGraphCompiler::SupportsUnboxedDoubles() {
+#if defined(ARCH_IS_64_BIT)
+  return true;
+#else
+  // We use 64-bit wide stack slots to unbox doubles.
   return false;
+#endif
 }
 
 
@@ -423,7 +427,18 @@
   } else if (source.IsRegister() && destination.IsRegister()) {
     __ Move(destination.reg(), source.reg());
   } else if (source.IsConstant() && destination.IsRegister()) {
-    __ LoadConstant(destination.reg(), source.constant());
+    if (source.constant_instruction()->representation() == kUnboxedDouble) {
+      const Register result = destination.reg();
+      const Object& constant = source.constant();
+      if (Utils::DoublesBitEqual(Double::Cast(constant).value(), 0.0)) {
+        __ BitXor(result, result, result);
+      } else {
+        __ LoadConstant(result, constant);
+        __ UnboxDouble(result, result);
+      }
+    } else {
+      __ LoadConstant(destination.reg(), source.constant());
+    }
   } else {
     compiler_->Bailout("Unsupported move");
     UNREACHABLE();
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 4a036e2..fbfe34c 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -29,7 +29,6 @@
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 
 DECLARE_FLAG(bool, enable_simd_inline);
-DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -1055,13 +1054,8 @@
   // No such checking code is generated if only fixed parameters are declared,
   // unless we are in debug mode or unless we are compiling a closure.
   if (num_copied_params == 0) {
-#ifdef DEBUG
-    ASSERT(!parsed_function().function().HasOptionalParameters());
-    const bool check_arguments = !flow_graph().IsCompiledForOsr();
-#else
     const bool check_arguments =
         function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
-#endif
     if (check_arguments) {
       __ Comment("Check argument count");
       // Check that exactly num_fixed arguments are passed in.
@@ -1075,13 +1069,9 @@
       __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
 
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
-        __ LeaveFrame();  // The arguments are still on the stack.
-        __ Jmp(*StubCode::CallClosureNoSuchMethod_entry());
-        // The noSuchMethod call may return to the caller, but not here.
-      } else {
-        __ Stop("Wrong number of arguments");
-      }
+      __ LeaveFrame();  // The arguments are still on the stack.
+      __ Jmp(*StubCode::CallClosureNoSuchMethod_entry());
+      // The noSuchMethod call may return to the caller, but not here.
       __ Bind(&correct_num_arguments);
     }
   } else if (!flow_graph().IsCompiledForOsr()) {
@@ -1319,11 +1309,7 @@
     __ Comment("Slow case: megamorphic call");
   }
   __ LoadObject(ECX, cache);
-  if (FLAG_use_megamorphic_stub) {
-    __ Call(*StubCode::MegamorphicLookup_entry());
-  } else  {
-    StubCode::EmitMegamorphicLookup(assembler());
-  }
+  __ call(Address(THR, Thread::megamorphic_lookup_checked_entry_offset()));
   __ call(EBX);
 
   __ Bind(&done);
@@ -1362,7 +1348,11 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
-  __ LoadObject(EDX, arguments_descriptor);
+  if (function.HasOptionalParameters()) {
+    __ LoadObject(EDX, arguments_descriptor);
+  } else {
+    __ xorl(EDX, EDX);  // GC safe smi zero because of stub.
+  }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateDartCall(deopt_id,
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 2376554..8e568c9 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -23,7 +23,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -1073,13 +1072,8 @@
   // No such checking code is generated if only fixed parameters are declared,
   // unless we are in debug mode or unless we are compiling a closure.
   if (num_copied_params == 0) {
-#ifdef DEBUG
-    ASSERT(!parsed_function().function().HasOptionalParameters());
-    const bool check_arguments = !flow_graph().IsCompiledForOsr();
-#else
     const bool check_arguments =
         function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
-#endif
     if (check_arguments) {
       __ Comment("Check argument count");
       // Check that exactly num_fixed arguments are passed in.
@@ -1092,13 +1086,9 @@
                              ArgumentsDescriptor::positional_count_offset()));
       __ beq(T0, T1, &correct_num_arguments);
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
-        __ LeaveDartFrame(kKeepCalleePP);  // Arguments are still on the stack.
-        __ Branch(*StubCode::CallClosureNoSuchMethod_entry());
-        // The noSuchMethod call may return to the caller, but not here.
-      } else {
-        __ Stop("Wrong number of arguments");
-      }
+      __ LeaveDartFrame(kKeepCalleePP);  // Arguments are still on the stack.
+      __ Branch(*StubCode::CallClosureNoSuchMethod_entry());
+      // The noSuchMethod call may return to the caller, but not here.
       __ Bind(&correct_num_arguments);
     }
   } else if (!flow_graph().IsCompiledForOsr()) {
@@ -1349,12 +1339,8 @@
     __ Comment("Slow case: megamorphic call");
   }
   __ LoadObject(S5, cache);
-  if (FLAG_use_megamorphic_stub) {
-    __ BranchLink(*StubCode::MegamorphicLookup_entry());
-  } else  {
-    StubCode::EmitMegamorphicLookup(assembler());
-  }
-  __ jalr(T1);
+  __ lw(T9, Address(THR, Thread::megamorphic_lookup_checked_entry_offset()));
+  __ jalr(T9);
 
   __ Bind(&done);
   RecordSafepoint(locs, slow_path_argument_count);
@@ -1391,12 +1377,16 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
+  ASSERT(ic_data.NumArgsTested() == 1);
+  const Code& initial_stub = Code::ZoneHandle(
+      StubCode::ICLookupThroughFunction_entry()->code());
+
   __ Comment("SwitchableCall");
   __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
-  ASSERT(ic_data.NumArgsTested() == 1);
   __ LoadUniqueObject(S5, ic_data);
-  __ BranchLinkPatchable(*StubCode::ICLookupThroughFunction_entry());
-  __ jalr(T1);
+  __ LoadUniqueObject(CODE_REG, initial_stub);
+  __ lw(T9, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+  __ jalr(T9);
 
   AddCurrentDescriptor(RawPcDescriptors::kOther,
       Thread::kNoDeoptId, token_pos);
@@ -1439,7 +1429,12 @@
     TokenPosition token_pos,
     LocationSummary* locs) {
   __ Comment("StaticCall");
-  __ LoadObject(S4, arguments_descriptor);
+  ASSERT(!function.IsClosureFunction());
+  if (function.HasOptionalParameters()) {
+    __ LoadObject(S4, arguments_descriptor);
+  } else {
+    __ LoadImmediate(S4, 0);  // GC safe smi zero because of stub.
+  }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateStaticDartCall(deopt_id,
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 5cc5c93..9118bb12 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -25,7 +25,7 @@
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
-DECLARE_FLAG(bool, use_megamorphic_stub);
+
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
   Assembler* assembler = compiler->assembler();
@@ -1057,13 +1057,8 @@
   // No such checking code is generated if only fixed parameters are declared,
   // unless we are in debug mode or unless we are compiling a closure.
   if (num_copied_params == 0) {
-#ifdef DEBUG
-    ASSERT(!parsed_function().function().HasOptionalParameters());
-    const bool check_arguments = !flow_graph().IsCompiledForOsr();
-#else
     const bool check_arguments =
         function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
-#endif
     if (check_arguments) {
       __ Comment("Check argument count");
       // Check that exactly num_fixed arguments are passed in.
@@ -1077,13 +1072,9 @@
       __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
 
       __ Bind(&wrong_num_arguments);
-      if (function.IsClosureFunction()) {
-        __ LeaveDartFrame(kKeepCalleePP);  // Leave arguments on the stack.
-        __ Jmp(*StubCode::CallClosureNoSuchMethod_entry());
-        // The noSuchMethod call may return to the caller, but not here.
-      } else {
-        __ Stop("Wrong number of arguments");
-      }
+      __ LeaveDartFrame(kKeepCalleePP);  // Leave arguments on the stack.
+      __ Jmp(*StubCode::CallClosureNoSuchMethod_entry());
+      // The noSuchMethod call may return to the caller, but not here.
       __ Bind(&correct_num_arguments);
     }
   } else if (!flow_graph().IsCompiledForOsr()) {
@@ -1348,12 +1339,7 @@
     __ Comment("Slow case: megamorphic call");
   }
   __ LoadObject(RBX, cache);
-  if (FLAG_use_megamorphic_stub) {
-    __ Call(*StubCode::MegamorphicLookup_entry());
-  } else  {
-    StubCode::EmitMegamorphicLookup(assembler());
-  }
-  __ call(RCX);
+  __ call(Address(THR, Thread::megamorphic_lookup_checked_entry_offset()));
 
   __ Bind(&done);
   RecordSafepoint(locs, slow_path_argument_count);
@@ -1390,11 +1376,15 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
+  ASSERT(ic_data.NumArgsTested() == 1);
+  const Code& initial_stub = Code::ZoneHandle(
+      StubCode::ICLookupThroughFunction_entry()->code());
+
   __ Comment("SwitchableCall");
   __ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
-  ASSERT(ic_data.NumArgsTested() == 1);
   __ LoadUniqueObject(RBX, ic_data);
-  __ CallPatchable(*StubCode::ICLookupThroughFunction_entry());
+  __ LoadUniqueObject(CODE_REG, initial_stub);
+  __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
   __ call(RCX);
 
   AddCurrentDescriptor(RawPcDescriptors::kOther,
@@ -1419,7 +1409,12 @@
     intptr_t deopt_id,
     TokenPosition token_pos,
     LocationSummary* locs) {
-  __ LoadObject(R10, arguments_descriptor);
+  ASSERT(!function.IsClosureFunction());
+  if (function.HasOptionalParameters()) {
+    __ LoadObject(R10, arguments_descriptor);
+  } else {
+    __ xorq(R10, R10);  // GC safe smi zero because of stub.
+  }
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
   GenerateStaticDartCall(deopt_id,
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index f93b1d1..8ee6739 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -634,7 +634,9 @@
 
     // Don't inline any intrinsified functions in precompiled mode
     // to reduce code size and make sure we use the intrinsic code.
-    if (FLAG_precompiled_mode && function.is_intrinsic()) {
+    if (FLAG_precompiled_mode &&
+        function.is_intrinsic() &&
+        !inliner_->AlwaysInline(function)) {
       TRACE_INLINING(THR_Print("     Bailout: intrinisic\n"));
       PRINT_INLINING_TREE("intrinsic",
           &call_data->caller, &function, call_data->call);
@@ -2045,15 +2047,6 @@
                                        Definition** array,
                                        Definition* index,
                                        Instruction** cursor) {
-  // Insert index smi check.
-  *cursor = flow_graph->AppendTo(
-      *cursor,
-      new(Z) CheckSmiInstr(new(Z) Value(index),
-                           call->deopt_id(),
-                           call->token_pos()),
-      call->env(),
-      FlowGraph::kEffect);
-
   // Insert array length load and bounds check.
   LoadFieldInstr* length =
       new(Z) LoadFieldInstr(
@@ -2109,86 +2102,6 @@
 }
 
 
-static intptr_t MethodKindToCid(MethodRecognizer::Kind kind) {
-  switch (kind) {
-    case MethodRecognizer::kImmutableArrayGetIndexed:
-      return kImmutableArrayCid;
-
-    case MethodRecognizer::kObjectArrayGetIndexed:
-    case MethodRecognizer::kObjectArraySetIndexed:
-      return kArrayCid;
-
-    case MethodRecognizer::kGrowableArrayGetIndexed:
-    case MethodRecognizer::kGrowableArraySetIndexed:
-      return kGrowableObjectArrayCid;
-
-    case MethodRecognizer::kFloat32ArrayGetIndexed:
-    case MethodRecognizer::kFloat32ArraySetIndexed:
-      return kTypedDataFloat32ArrayCid;
-
-    case MethodRecognizer::kFloat64ArrayGetIndexed:
-    case MethodRecognizer::kFloat64ArraySetIndexed:
-      return kTypedDataFloat64ArrayCid;
-
-    case MethodRecognizer::kInt8ArrayGetIndexed:
-    case MethodRecognizer::kInt8ArraySetIndexed:
-      return kTypedDataInt8ArrayCid;
-
-    case MethodRecognizer::kUint8ArrayGetIndexed:
-    case MethodRecognizer::kUint8ArraySetIndexed:
-      return kTypedDataUint8ArrayCid;
-
-    case MethodRecognizer::kUint8ClampedArrayGetIndexed:
-    case MethodRecognizer::kUint8ClampedArraySetIndexed:
-      return kTypedDataUint8ClampedArrayCid;
-
-    case MethodRecognizer::kExternalUint8ArrayGetIndexed:
-    case MethodRecognizer::kExternalUint8ArraySetIndexed:
-      return kExternalTypedDataUint8ArrayCid;
-
-    case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
-    case MethodRecognizer::kExternalUint8ClampedArraySetIndexed:
-      return kExternalTypedDataUint8ClampedArrayCid;
-
-    case MethodRecognizer::kInt16ArrayGetIndexed:
-    case MethodRecognizer::kInt16ArraySetIndexed:
-      return kTypedDataInt16ArrayCid;
-
-    case MethodRecognizer::kUint16ArrayGetIndexed:
-    case MethodRecognizer::kUint16ArraySetIndexed:
-      return kTypedDataUint16ArrayCid;
-
-    case MethodRecognizer::kInt32ArrayGetIndexed:
-    case MethodRecognizer::kInt32ArraySetIndexed:
-      return kTypedDataInt32ArrayCid;
-
-    case MethodRecognizer::kUint32ArrayGetIndexed:
-    case MethodRecognizer::kUint32ArraySetIndexed:
-      return kTypedDataUint32ArrayCid;
-
-    case MethodRecognizer::kInt64ArrayGetIndexed:
-    case MethodRecognizer::kInt64ArraySetIndexed:
-      return kTypedDataInt64ArrayCid;
-
-    case MethodRecognizer::kFloat32x4ArrayGetIndexed:
-    case MethodRecognizer::kFloat32x4ArraySetIndexed:
-      return kTypedDataFloat32x4ArrayCid;
-
-    case MethodRecognizer::kInt32x4ArrayGetIndexed:
-    case MethodRecognizer::kInt32x4ArraySetIndexed:
-      return kTypedDataInt32x4ArrayCid;
-
-    case MethodRecognizer::kFloat64x2ArrayGetIndexed:
-    case MethodRecognizer::kFloat64x2ArraySetIndexed:
-      return kTypedDataFloat64x2ArrayCid;
-
-    default:
-      break;
-  }
-  return kIllegalCid;
-}
-
-
 static Instruction* GetCheckClass(FlowGraph* flow_graph,
                                   Definition* to_check,
                                   const ICData& unary_checks,
@@ -2211,8 +2124,7 @@
                              Definition* receiver,
                              TargetEntryInstr** entry,
                              Definition** last) {
-  intptr_t array_cid = MethodKindToCid(kind);
-  ASSERT(array_cid != kIllegalCid);
+  intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind);
 
   Definition* array = receiver;
   Definition* index = call->ArgumentAt(1);
@@ -2269,8 +2181,7 @@
                              const ICData& value_check,
                              TargetEntryInstr** entry,
                              Definition** last) {
-  intptr_t array_cid = MethodKindToCid(kind);
-  ASSERT(array_cid != kIllegalCid);
+  intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind);
 
   Definition* array = receiver;
   Definition* index = call->ArgumentAt(1);
@@ -2460,6 +2371,29 @@
 }
 
 
+static bool InlineSmiBitAndFromSmi(FlowGraph* flow_graph,
+                                   Instruction* call,
+                                   TargetEntryInstr** entry,
+                                   Definition** last) {
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+
+  *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(),
+                                   call->GetBlock()->try_index());
+  (*entry)->InheritDeoptTarget(Z, call);
+  // Right arguments is known to be smi: other._bitAndFromSmi(this);
+  BinarySmiOpInstr* smi_op =
+      new(Z) BinarySmiOpInstr(Token::kBIT_AND,
+                              new(Z) Value(left),
+                              new(Z) Value(right),
+                              call->deopt_id());
+  flow_graph->AppendTo(*entry, smi_op, call->env(), FlowGraph::kValue);
+  *last = smi_op;
+
+  return true;
+}
+
+
 static bool InlineGrowableArraySetter(FlowGraph* flow_graph,
                                       intptr_t offset,
                                       StoreBarrierType store_barrier_type,
@@ -2495,15 +2429,6 @@
     Definition** array,
     Definition* byte_index,
     Instruction** cursor) {
-  // Insert byte_index smi check.
-  *cursor = flow_graph->AppendTo(*cursor,
-                                 new(Z) CheckSmiInstr(
-                                     new(Z) Value(byte_index),
-                                     call->deopt_id(),
-                                     call->token_pos()),
-                                 call->env(),
-                                 FlowGraph::kEffect);
-
   LoadFieldInstr* length =
       new(Z) LoadFieldInstr(
           new(Z) Value(*array),
@@ -2804,15 +2729,6 @@
     Definition* str,
     Definition* index,
     Instruction* cursor) {
-
-  cursor = flow_graph->AppendTo(cursor,
-                                new(Z) CheckSmiInstr(
-                                    new(Z) Value(index),
-                                    call->deopt_id(),
-                                    call->token_pos()),
-                                call->env(),
-                                FlowGraph::kEffect);
-
   // Load the length of the string.
   // Treat length loads as mutable (i.e. affected by side effects) to avoid
   // hoisting them since we can't hoist the preceding class-check. This
@@ -3227,6 +3143,8 @@
       return InlineGrowableArraySetter(
           flow_graph, GrowableObjectArray::length_offset(), kNoStoreBarrier,
           call, entry, last);
+    case MethodRecognizer::kSmi_bitAndFromSmi:
+      return InlineSmiBitAndFromSmi(flow_graph, call, entry, last);
     default:
       return false;
   }
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 70a9dc5..1e7afbd 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -693,6 +693,7 @@
     }
 
     if (!range.Equals(defn->range())) {
+#ifndef PRODUCT
       if (FLAG_support_il_printer && FLAG_trace_range_analysis) {
         THR_Print("%c [%" Pd "] %s:  %s => %s\n",
                   OpPrefix(op),
@@ -701,6 +702,7 @@
                   Range::ToCString(defn->range()),
                   Range::ToCString(&range));
       }
+#endif  // !PRODUCT
       defn->set_range(range);
       return true;
     }
@@ -1022,12 +1024,14 @@
     // range give up on generalization for simplicity.
     GrowableArray<Definition*> non_positive_symbols;
     if (!FindNonPositiveSymbols(&non_positive_symbols, upper_bound)) {
+#ifndef PRODUCT
       if (FLAG_support_il_printer && FLAG_trace_range_analysis) {
         THR_Print("Failed to generalize %s index to %s"
                   " (can't ensure positivity)\n",
                   check->ToCString(),
                   IndexBoundToCString(upper_bound));
       }
+#endif  // !PRODUCT
       return;
     }
 
@@ -1056,21 +1060,25 @@
     if (!RangeUtils::IsPositive(lower_bound->range())) {
       // Can't prove that lower bound is positive even with additional checks
       // against potentially non-positive symbols. Give up.
+#ifndef PRODUCT
       if (FLAG_support_il_printer && FLAG_trace_range_analysis) {
         THR_Print("Failed to generalize %s index to %s"
                   " (lower bound is not positive)\n",
                   check->ToCString(),
                   IndexBoundToCString(upper_bound));
       }
+#endif  // !PRODUCT
       return;
     }
 
+#ifndef PRODUCT
     if (FLAG_support_il_printer && FLAG_trace_range_analysis) {
       THR_Print("For %s computed index bounds [%s, %s]\n",
                 check->ToCString(),
                 IndexBoundToCString(lower_bound),
                 IndexBoundToCString(upper_bound));
     }
+#endif  // !PRODUCT
 
     // At this point we know that 0 <= index < UpperBound(index) under
     // certain preconditions. Start by emitting this preconditions.
@@ -1493,6 +1501,7 @@
     return defn;
   }
 
+#ifndef PRODUCT
   static void PrettyPrintIndexBoundRecursively(BufferFormatter* f,
                                                Definition* index_bound) {
     BinarySmiOpInstr* binary_op = index_bound->AsBinarySmiOp();
@@ -1518,6 +1527,7 @@
     PrettyPrintIndexBoundRecursively(&f, index_bound);
     return Thread::Current()->zone()->MakeCopyOfString(buffer);
   }
+#endif  // !PRODUCT
 
   RangeAnalysis* range_analysis_;
   FlowGraph* flow_graph_;
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 2ee8ed1..2162cfe 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -237,6 +237,13 @@
 }
 
 
+void FlowGraphTypePropagator::VisitCheckArrayBound(
+    CheckArrayBoundInstr* check) {
+  // Array bounds checks also test index for smi.
+  SetCid(check->index()->definition(), kSmiCid);
+}
+
+
 void FlowGraphTypePropagator::VisitCheckClass(CheckClassInstr* check) {
   if ((check->unary_checks().NumberOfChecks() != 1) ||
       !check->Dependencies().IsNone()) {
diff --git a/runtime/vm/flow_graph_type_propagator.h b/runtime/vm/flow_graph_type_propagator.h
index 3c10917..7a5e87e 100644
--- a/runtime/vm/flow_graph_type_propagator.h
+++ b/runtime/vm/flow_graph_type_propagator.h
@@ -27,6 +27,7 @@
 
   virtual void VisitJoinEntry(JoinEntryInstr* instr);
   virtual void VisitCheckSmi(CheckSmiInstr* instr);
+  virtual void VisitCheckArrayBound(CheckArrayBoundInstr* instr);
   virtual void VisitCheckClass(CheckClassInstr* instr);
   virtual void VisitCheckClassId(CheckClassIdInstr* instr);
   virtual void VisitGuardFieldClass(GuardFieldClassInstr* instr);
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index ae0e205..7ea64d6 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -534,6 +534,7 @@
 
 
 void GCMarker::ProcessObjectIdTable(Isolate* isolate) {
+#ifndef PRODUCT
   if (!FLAG_support_service) {
     return;
   }
@@ -541,6 +542,7 @@
   ObjectIdRing* ring = isolate->object_id_ring();
   ASSERT(ring != NULL);
   ring->VisitPointers(&visitor);
+#endif  // !PRODUCT
 }
 
 
@@ -608,8 +610,13 @@
         } while (true);
         // Wait for all markers to stop.
         barrier_->Sync();
+#if defined(DEBUG)
         ASSERT(AtomicOperations::LoadRelaxed(num_busy_) == 0);
-
+        // Caveat: must not allow any marker to continue past the barrier
+        // before we checked num_busy, otherwise one of them might rush
+        // ahead and increment it.
+        barrier_->Sync();
+#endif
         // Check if we have any pending properties with marked keys.
         // Those might have been marked by another marker.
         more_to_mark = visitor.ProcessPendingWeakProperties();
@@ -624,7 +631,7 @@
         // between all markers and the main thread.
         barrier_->Sync();
         if (!more_to_mark && (AtomicOperations::LoadRelaxed(num_busy_) > 0)) {
-          // All markers continue to marker as long as any single marker has
+          // All markers continue to mark as long as any single marker has
           // some work to do.
           AtomicOperations::FetchAndIncrement(num_busy_);
           more_to_mark = true;
@@ -666,6 +673,7 @@
 
 template<class MarkingVisitorType>
 void GCMarker::FinalizeResultsFrom(MarkingVisitorType* visitor) {
+#ifndef PRODUCT
   {
     MutexLocker ml(&stats_mutex_);
     marked_bytes_ += visitor->marked_bytes();
@@ -680,6 +688,7 @@
       }
     }
   }
+#endif  // !PRODUCT
   visitor->Finalize();
 }
 
@@ -743,6 +752,13 @@
       do {
         // Wait for all markers to stop.
         barrier.Sync();
+#if defined(DEBUG)
+        ASSERT(AtomicOperations::LoadRelaxed(&num_busy) == 0);
+        // Caveat: must not allow any marker to continue past the barrier
+        // before we checked num_busy, otherwise one of them might rush
+        // ahead and increment it.
+        barrier.Sync();
+#endif
 
         // Wait for all markers to go through weak properties and verify
         // that there are no more objects to mark.
diff --git a/runtime/vm/gc_sweeper.cc b/runtime/vm/gc_sweeper.cc
index 5b7949b..e37f1db 100644
--- a/runtime/vm/gc_sweeper.cc
+++ b/runtime/vm/gc_sweeper.cc
@@ -152,7 +152,7 @@
     {
       MonitorLocker ml(old_space_->tasks_lock());
       old_space_->set_tasks(old_space_->tasks() - 1);
-      ml.Notify();
+      ml.NotifyAll();
     }
   }
 
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 21a4b46..83bacb1 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -236,7 +236,7 @@
 #endif
   ASSERT(old_space_->tasks() == 1);
   old_space_->set_tasks(0);
-  ml.Notify();
+  ml.NotifyAll();
 }
 
 
@@ -350,6 +350,7 @@
 }
 
 
+#ifndef PRODUCT
 void Heap::UpdateClassHeapStatsBeforeGC(Heap::Space space) {
   ClassTable* class_table = isolate()->class_table();
   if (space == kNew) {
@@ -358,6 +359,7 @@
     class_table->ResetCountersOld();
   }
 }
+#endif
 
 
 void Heap::CollectNewSpaceGarbage(Thread* thread,
@@ -369,9 +371,9 @@
     RecordBeforeGC(kNew, reason);
     VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
     TIMELINE_FUNCTION_GC_DURATION(thread, "CollectNewGeneration");
-    UpdateClassHeapStatsBeforeGC(kNew);
+    NOT_IN_PRODUCT(UpdateClassHeapStatsBeforeGC(kNew));
     new_space_.Scavenge(invoke_api_callbacks);
-    isolate()->class_table()->UpdatePromoted();
+    NOT_IN_PRODUCT(isolate()->class_table()->UpdatePromoted());
     RecordAfterGC(kNew);
     PrintStats();
     NOT_IN_PRODUCT(PrintStatsToTimeline(&tds));
@@ -393,7 +395,7 @@
     RecordBeforeGC(kOld, reason);
     VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
     TIMELINE_FUNCTION_GC_DURATION(thread, "CollectOldGeneration");
-    UpdateClassHeapStatsBeforeGC(kOld);
+    NOT_IN_PRODUCT(UpdateClassHeapStatsBeforeGC(kOld));
     old_space_.MarkSweep(invoke_api_callbacks);
     RecordAfterGC(kOld);
     PrintStats();
@@ -729,11 +731,13 @@
   stats_.after_.old_ = old_space_.GetCurrentUsage();
   ASSERT((space == kNew && gc_new_space_in_progress_) ||
          (space == kOld && gc_old_space_in_progress_));
+#ifndef PRODUCT
   if (FLAG_support_service && Service::gc_stream.enabled()) {
     ServiceEvent event(Isolate::Current(), ServiceEvent::kGC);
     event.set_gc_stats(&stats_);
     Service::HandleEvent(&event);
   }
+#endif  // !PRODUCT
 }
 
 
diff --git a/runtime/vm/heap_test.cc b/runtime/vm/heap_test.cc
index 1d55a13..7454cf4 100644
--- a/runtime/vm/heap_test.cc
+++ b/runtime/vm/heap_test.cc
@@ -74,6 +74,7 @@
 }
 
 
+#ifndef PRODUCT
 class ClassHeapStatsTestHelper {
  public:
   static ClassHeapStats* GetHeapStatsForCid(ClassTable* class_table,
@@ -231,6 +232,7 @@
   EXPECT_GT(expected_size + kTolerance, after - before);
   Dart_ExitScope();
 }
+#endif  // !PRODUCT
 
 
 class FindOnly : public FindObjectVisitor {
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 5104545..d8d18f3 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -197,16 +197,6 @@
                               const ICData& ic_data,
                               intptr_t num_checks_to_print) {
   f->Print(" IC[");
-  if (ic_data.HasRangeFeedback()) {
-    f->Print("{%s",
-        ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(0)));
-    if (ic_data.NumArgsTested() == 2) {
-      f->Print(" x %s",
-          ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(1)));
-    }
-    f->Print("->%s} ",
-        ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(2)));
-  }
   f->Print("%" Pd ": ", ic_data.NumberOfChecks());
   Function& target = Function::Handle();
   if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 36281df..0e5cfb2 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -309,40 +309,45 @@
 
 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
     : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
-      cache_pool_index_(-1),
-      stub_pool_index_(-1) {
+      data_pool_index_(-1),
+      target_pool_index_(-1) {
   ASSERT(code.ContainsInstructionAt(pc));
-  // Last instruction: blx r1.
-  ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff31);
+  // Last instruction: blx lr.
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e);
 
   Register reg;
   uword stub_load_end =
-      InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
+      InstructionPattern::DecodeLoadWordFromPool(pc - 2 * Instr::kInstrSize,
                                                  &reg,
-                                                 &stub_pool_index_);
+                                                 &target_pool_index_);
   ASSERT(reg == CODE_REG);
   InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
                                              &reg,
-                                             &cache_pool_index_);
+                                             &data_pool_index_);
   ASSERT(reg == R9);
 }
 
 
-RawObject* SwitchableCallPattern::cache() const {
+RawObject* SwitchableCallPattern::data() const {
+  return object_pool_.ObjectAt(data_pool_index_);
+}
+
+
+RawCode* SwitchableCallPattern::target() const {
   return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(cache_pool_index_));
+      object_pool_.ObjectAt(target_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::SetData(const Object& data) const {
+  ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(data_pool_index_, data);
 }
 
 
-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);
+void SwitchableCallPattern::SetTarget(const Code& target) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(target_pool_index_, target);
 }
 
 
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 57d4824..86d81a7 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -98,22 +98,24 @@
 };
 
 
-// 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
+// Instance call that can switch between a direct monomorphic call, an IC call,
+// and a megamorphic call.
+//   load guarded cid            load ICData             load MegamorphicCache
+//   load monomorphic target <-> load ICLookup stub  ->  load MMLookup stub
+//   call target.entry           call stub.entry         call stub.entry
 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;
+  RawObject* data() const;
+  RawCode* target() const;
+  void SetData(const Object& data) const;
+  void SetTarget(const Code& target) const;
 
  private:
   const ObjectPool& object_pool_;
-  intptr_t cache_pool_index_;
-  intptr_t stub_pool_index_;
+  intptr_t data_pool_index_;
+  intptr_t target_pool_index_;
 
   DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
 };
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index 99c57ba..60ef9bf 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -359,40 +359,45 @@
 
 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
     : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
-      cache_pool_index_(-1),
-      stub_pool_index_(-1) {
+      data_pool_index_(-1),
+      target_pool_index_(-1) {
   ASSERT(code.ContainsInstructionAt(pc));
-  // Last instruction: blr r1.
-  ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0020);
+  // Last instruction: blr ip0.
+  ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200);
 
   Register reg;
   uword stub_load_end =
-      InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
+      InstructionPattern::DecodeLoadWordFromPool(pc - 2 * Instr::kInstrSize,
                                                  &reg,
-                                                 &stub_pool_index_);
+                                                 &target_pool_index_);
   ASSERT(reg == CODE_REG);
   InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
                                              &reg,
-                                             &cache_pool_index_);
+                                             &data_pool_index_);
   ASSERT(reg == R5);
 }
 
 
-RawObject* SwitchableCallPattern::cache() const {
+RawObject* SwitchableCallPattern::data() const {
+  return object_pool_.ObjectAt(data_pool_index_);
+}
+
+
+RawCode* SwitchableCallPattern::target() const {
   return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(cache_pool_index_));
+      object_pool_.ObjectAt(target_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::SetData(const Object& data) const {
+  ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(data_pool_index_, data);
 }
 
 
-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);
+void SwitchableCallPattern::SetTarget(const Code& target) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(target_pool_index_, target);
 }
 
 
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 6195d52..80de324 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -106,22 +106,24 @@
 };
 
 
-// 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
+// Instance call that can switch between a direct monomorphic call, an IC call,
+// and a megamorphic call.
+//   load guarded cid            load ICData             load MegamorphicCache
+//   load monomorphic target <-> load ICLookup stub  ->  load MMLookup stub
+//   call target.entry           call stub.entry         call stub.entry
 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;
+  RawObject* data() const;
+  RawCode* target() const;
+  void SetData(const Object& data) const;
+  void SetTarget(const Code& target) const;
 
  private:
   const ObjectPool& object_pool_;
-  intptr_t cache_pool_index_;
-  intptr_t stub_pool_index_;
+  intptr_t data_pool_index_;
+  intptr_t target_pool_index_;
 
   DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
 };
diff --git a/runtime/vm/instructions_arm64_test.cc b/runtime/vm/instructions_arm64_test.cc
index 970d271..7ad4fb9 100644
--- a/runtime/vm/instructions_arm64_test.cc
+++ b/runtime/vm/instructions_arm64_test.cc
@@ -27,7 +27,8 @@
   // The return address, which must be the address of an instruction contained
   // in the code, points to the Ret instruction above, i.e. one instruction
   // before the end of the code buffer.
-  CallPattern call(test->entry() + test->code().Size() - Instr::kInstrSize,
+  uword end = test->payload_start() + test->code().Size();
+  CallPattern call(end - Instr::kInstrSize,
                    test->code());
   EXPECT_EQ(StubCode::InvokeDartCode_entry()->code(),
             call.TargetCode());
diff --git a/runtime/vm/instructions_arm_test.cc b/runtime/vm/instructions_arm_test.cc
index de3ff6f..24effd8 100644
--- a/runtime/vm/instructions_arm_test.cc
+++ b/runtime/vm/instructions_arm_test.cc
@@ -27,8 +27,8 @@
   // The return address, which must be the address of an instruction contained
   // in the code, points to the Ret instruction above, i.e. one instruction
   // before the end of the code buffer.
-  CallPattern call(test->entry() + test->code().Size() - Instr::kInstrSize,
-                   test->code());
+  uword end = test->payload_start() + test->code().Size();
+  CallPattern call(end - Instr::kInstrSize, test->code());
   EXPECT_EQ(StubCode::InvokeDartCode_entry()->code(), call.TargetCode());
 }
 
diff --git a/runtime/vm/instructions_dbc.cc b/runtime/vm/instructions_dbc.cc
index 4dc73be..7d8dab7 100644
--- a/runtime/vm/instructions_dbc.cc
+++ b/runtime/vm/instructions_dbc.cc
@@ -20,6 +20,7 @@
     case Bytecode::kLoadConstant:
     case Bytecode::kPushConstant:
     case Bytecode::kStaticCall:
+    case Bytecode::kIndirectStaticCall:
     case Bytecode::kInstanceCall1:
     case Bytecode::kInstanceCall2:
     case Bytecode::kInstanceCall1Opt:
@@ -189,27 +190,32 @@
 
 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
     : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
-      cache_pool_index_(-1),
-      stub_pool_index_(-1) {
+      data_pool_index_(-1),
+      target_pool_index_(-1) {
   UNIMPLEMENTED();
 }
 
 
-RawObject* SwitchableCallPattern::cache() const {
+RawObject* SwitchableCallPattern::data() const {
+  return object_pool_.ObjectAt(data_pool_index_);
+}
+
+
+RawCode* SwitchableCallPattern::target() const {
   return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(cache_pool_index_));
+      object_pool_.ObjectAt(target_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::SetData(const Object& data) const {
+  ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(data_pool_index_, data);
 }
 
 
-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);
+void SwitchableCallPattern::SetTarget(const Code& target) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(target_pool_index_, target);
 }
 
 
diff --git a/runtime/vm/instructions_dbc.h b/runtime/vm/instructions_dbc.h
index 5eb0c6e..6db5205 100644
--- a/runtime/vm/instructions_dbc.h
+++ b/runtime/vm/instructions_dbc.h
@@ -98,19 +98,24 @@
 };
 
 
-// Instance call that can switch from an IC call to a megamorphic call
+// Instance call that can switch between a direct monomorphic call, an IC call,
+// and a megamorphic call.
+//   load guarded cid            load ICData             load MegamorphicCache
+//   load monomorphic target <-> load ICLookup stub  ->  load MMLookup stub
+//   call target.entry           call stub.entry         call stub.entry
 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;
+  RawObject* data() const;
+  RawCode* target() const;
+  void SetData(const Object& data) const;
+  void SetTarget(const Code& target) const;
 
  private:
   const ObjectPool& object_pool_;
-  intptr_t cache_pool_index_;
-  intptr_t stub_pool_index_;
+  intptr_t data_pool_index_;
+  intptr_t target_pool_index_;
 
   DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
 };
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index cdb2cbe..70fff9d 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -237,41 +237,46 @@
 
 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
     : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
-      cache_pool_index_(-1),
-      stub_pool_index_(-1) {
+      data_pool_index_(-1),
+      target_pool_index_(-1) {
   ASSERT(code.ContainsInstructionAt(pc));
-  // Last instruction: jalr t1.
+  // Last instruction: jalr t9.
   ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0);  // Delay slot.
-  ASSERT(*(reinterpret_cast<uword*>(pc) - 2) == 0x0120f809);
+  ASSERT(*(reinterpret_cast<uword*>(pc) - 2) == 0x0320f809);
 
   Register reg;
   uword stub_load_end =
-      InstructionPattern::DecodeLoadWordFromPool(pc - 5 * Instr::kInstrSize,
+      InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
                                                  &reg,
-                                                 &stub_pool_index_);
+                                                 &target_pool_index_);
   ASSERT(reg == CODE_REG);
   InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
                                              &reg,
-                                             &cache_pool_index_);
+                                             &data_pool_index_);
   ASSERT(reg == S5);
 }
 
 
-RawObject* SwitchableCallPattern::cache() const {
+RawObject* SwitchableCallPattern::data() const {
+  return object_pool_.ObjectAt(data_pool_index_);
+}
+
+
+RawCode* SwitchableCallPattern::target() const {
   return reinterpret_cast<RawCode*>(
-      object_pool_.ObjectAt(cache_pool_index_));
+      object_pool_.ObjectAt(target_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::SetData(const Object& data) const {
+  ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(data_pool_index_, data);
 }
 
 
-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);
+void SwitchableCallPattern::SetTarget(const Code& target) const {
+  ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
+  object_pool_.SetObjectAt(target_pool_index_, target);
 }
 
 
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index 607e835..a5a398f 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -97,22 +97,24 @@
 };
 
 
-// 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
+// Instance call that can switch between a direct monomorphic call, an IC call,
+// and a megamorphic call.
+//   load guarded cid            load ICData             load MegamorphicCache
+//   load monomorphic target <-> load ICLookup stub  ->  load MMLookup stub
+//   call target.entry           call stub.entry         call stub.entry
 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;
+  RawObject* data() const;
+  RawCode* target() const;
+  void SetData(const Object& data) const;
+  void SetTarget(const Code& target) const;
 
  private:
   const ObjectPool& object_pool_;
-  intptr_t cache_pool_index_;
-  intptr_t stub_pool_index_;
+  intptr_t data_pool_index_;
+  intptr_t target_pool_index_;
 
   DISALLOW_COPY_AND_ASSIGN(SwitchableCallPattern);
 };
diff --git a/runtime/vm/instructions_mips_test.cc b/runtime/vm/instructions_mips_test.cc
index cf2f7f2..38d5936 100644
--- a/runtime/vm/instructions_mips_test.cc
+++ b/runtime/vm/instructions_mips_test.cc
@@ -25,8 +25,8 @@
   // in the code, points to the Ret instruction above, i.e. two instructions
   // before the end of the code buffer, including the delay slot for the
   // return jump.
-  CallPattern call(test->entry() + test->code().Size() - (2*Instr::kInstrSize),
-                   test->code());
+  uword end = test->payload_start() + test->code().Size();
+  CallPattern call(end - (2 * Instr::kInstrSize), test->code());
   EXPECT_EQ(StubCode::InvokeDartCode_entry()->code(), call.TargetCode());
 }
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 689d535..d1f8f92 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -3177,18 +3177,6 @@
       ASSERT(ArgumentCount() == 2);
       compiler->EmitInstanceCall(*stub_entry, *call_ic_data, ArgumentCount(),
                                  deopt_id(), token_pos(), locs());
-    } else if (FLAG_ic_range_profiling &&
-               (Token::IsBinaryArithmeticOperator(token_kind()) ||
-                Token::IsUnaryArithmeticOperator(token_kind()))) {
-      ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) ==
-                 (ArgumentCount() == 1));
-      ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) ==
-                 (ArgumentCount() == 2));
-      const StubEntry* stub_entry = (ArgumentCount() == 1)
-          ? StubCode::UnaryRangeCollectingInlineCache_entry()
-          : StubCode::BinaryRangeCollectingInlineCache_entry();
-      compiler->EmitInstanceCall(*stub_entry, *call_ic_data, ArgumentCount(),
-                                 deopt_id(), token_pos(), locs());
     } else {
       compiler->GenerateInstanceCall(deopt_id(),
                                      token_pos(),
@@ -3198,14 +3186,17 @@
     }
   }
 #else
-  ICData* ic_data = &ICData::ZoneHandle(call_ic_data->Original());
+  ICData* original_ic_data = &ICData::ZoneHandle(call_ic_data->Original());
 
   // Emit smi fast path instruction. If fast-path succeeds it skips the next
-  // instruction otherwise it falls through.
-  TryFastPathSmiOp(compiler, ic_data, function_name());
+  // instruction otherwise it falls through. Only attempt in unoptimized code
+  // because TryFastPathSmiOp will update original_ic_data.
+  if (!compiler->is_optimizing()) {
+    TryFastPathSmiOp(compiler, original_ic_data, function_name());
+  }
 
-  const intptr_t call_ic_data_kidx = __ AddConstant(*call_ic_data);
-  switch (ic_data->NumArgsTested()) {
+  const intptr_t call_ic_data_kidx = __ AddConstant(*original_ic_data);
+  switch (original_ic_data->NumArgsTested()) {
     case 1:
       if (compiler->is_optimizing()) {
         __ InstanceCall1Opt(ArgumentCount(), call_ic_data_kidx);
@@ -3292,7 +3283,6 @@
 
 
 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-#if !defined(TARGET_ARCH_DBC)
   const ICData* call_ic_data = NULL;
   if (!FLAG_propagate_ic_data || !compiler->is_optimizing() ||
       (ic_data() == NULL)) {
@@ -3318,6 +3308,8 @@
   } else {
     call_ic_data = &ICData::ZoneHandle(ic_data()->raw());
   }
+
+#if !defined(TARGET_ARCH_DBC)
   compiler->GenerateStaticCall(deopt_id(),
                                token_pos(),
                                function(),
@@ -3333,17 +3325,20 @@
         Array::Handle(ic_data()->arguments_descriptor());
   const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
 
-  __ PushConstant(function());
-  __ StaticCall(ArgumentCount(), argdesc_kidx);
-  RawPcDescriptors::Kind kind = (compiler->is_optimizing())
-                              ? RawPcDescriptors::kOther
-                              : RawPcDescriptors::kUnoptStaticCall;
-  compiler->AddCurrentDescriptor(kind, deopt_id(), token_pos());
-
-  compiler->RecordAfterCall(this);
-
   if (compiler->is_optimizing()) {
+    __ PushConstant(function());
+    __ StaticCall(ArgumentCount(), argdesc_kidx);
+    compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
+        deopt_id(), token_pos());
+    compiler->RecordAfterCall(this);
     __ PopLocal(locs()->out(0).reg());
+  } else {
+    const intptr_t ic_data_kidx = __ AddConstant(*call_ic_data);
+    __ PushConstant(ic_data_kidx);
+    __ IndirectStaticCall(ArgumentCount(), argdesc_kidx);
+    compiler->AddCurrentDescriptor(RawPcDescriptors::kUnoptStaticCall,
+        deopt_id(), token_pos());
+    compiler->RecordAfterCall(this);
   }
 #endif  // !defined(TARGET_ARCH_DBC)
 }
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 7307344..bfcb8a7 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -512,6 +512,7 @@
   M(ShiftMintOp)                                                               \
   M(UnaryMintOp)                                                               \
   M(CheckArrayBound)                                                           \
+  M(GenericCheckBound)                                                         \
   M(Constraint)                                                                \
   M(StringToCharCode)                                                          \
   M(OneByteStringFromCharCode)                                                 \
@@ -7928,6 +7929,35 @@
 };
 
 
+class GenericCheckBoundInstr : public TemplateInstruction<2, Throws, NoCSE> {
+ public:
+  GenericCheckBoundInstr(Value* length, Value* index, intptr_t deopt_id)
+      : TemplateInstruction(deopt_id) {
+    SetInputAt(kLengthPos, length);
+    SetInputAt(kIndexPos, index);
+  }
+
+  Value* length() const { return inputs_[kLengthPos]; }
+  Value* index() const { return inputs_[kIndexPos]; }
+
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+
+  DECLARE_INSTRUCTION(GenericCheckBound)
+
+  virtual bool CanDeoptimize() const { return true; }
+
+  // Give a name to the location/input indices.
+  enum {
+    kLengthPos = 0,
+    kIndexPos = 1
+  };
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GenericCheckBoundInstr);
+};
+
+
 class UnboxedIntConverterInstr : public TemplateDefinition<1, NoThrow> {
  public:
   UnboxedIntConverterInstr(Representation from,
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 1750418..aac4891 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -6111,8 +6111,7 @@
   Label* deopt = compiler->AddDeoptStub(deopt_id(),
                                         ICData::kDeoptCheckSmi,
                                         licm_hoisted_ ? ICData::kHoisted : 0);
-  __ tst(value, Operand(kSmiTagMask));
-  __ b(deopt, NE);
+  __ BranchIfNotSmi(value, deopt);
 }
 
 
@@ -6135,6 +6134,66 @@
 }
 
 
+LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone,
+                                                             bool opt) const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new(zone) LocationSummary(
+      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
+  locs->set_in(kLengthPos, Location::RequiresRegister());
+  locs->set_in(kIndexPos, Location::RequiresRegister());
+  return locs;
+}
+
+
+class RangeErrorSlowPath : public SlowPathCode {
+ public:
+  RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index)
+      : instruction_(instruction), try_index_(try_index) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (Assembler::EmittingComments()) {
+      __ Comment("slow path check bound operation");
+    }
+    __ Bind(entry_label());
+    LocationSummary* locs = instruction_->locs();
+    __ Push(locs->in(0).reg());
+    __ Push(locs->in(1).reg());
+    __ CallRuntime(kRangeErrorRuntimeEntry, 2);
+    compiler->pc_descriptors_list()->AddDescriptor(
+        RawPcDescriptors::kOther,
+        compiler->assembler()->CodeSize(),
+        instruction_->deopt_id(),
+        instruction_->token_pos(),
+        try_index_);
+    compiler->RecordSafepoint(locs, 2);
+    __ bkpt(0);
+  }
+
+ private:
+  GenericCheckBoundInstr* instruction_;
+  intptr_t try_index_;
+};
+
+
+void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  RangeErrorSlowPath* slow_path =
+      new RangeErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  Location length_loc = locs()->in(kLengthPos);
+  Location index_loc = locs()->in(kIndexPos);
+  Register length = length_loc.reg();
+  Register index = index_loc.reg();
+  const intptr_t index_cid = this->index()->Type()->ToCid();
+  if (index_cid != kSmiCid) {
+    __ BranchIfNotSmi(index, slow_path->entry_label());
+  }
+  __ cmp(index, Operand(length));
+  __ b(slow_path->entry_label(), CS);
+}
+
+
 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
                                                            bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -6168,6 +6227,7 @@
     return;
   }
 
+  const intptr_t index_cid = index()->Type()->ToCid();
   if (index_loc.IsConstant()) {
     const Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
@@ -6176,6 +6236,9 @@
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
     const Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     if (length.Value() == Smi::kMaxValue) {
       __ tst(index, Operand(index));
       __ b(deopt, MI);
@@ -6186,6 +6249,9 @@
   } else {
     const Register length = length_loc.reg();
     const Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     __ cmp(index, Operand(length));
     __ b(deopt, CS);
   }
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 642bc9e..c4f0fdc 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -5254,8 +5254,68 @@
   Label* deopt = compiler->AddDeoptStub(deopt_id(),
                                         ICData::kDeoptCheckSmi,
                                         licm_hoisted_ ? ICData::kHoisted : 0);
-  __ tsti(value, Immediate(kSmiTagMask));
-  __ b(deopt, NE);
+  __ BranchIfNotSmi(value, deopt);
+}
+
+
+
+LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone,
+                                                             bool opt) const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new(zone) LocationSummary(
+      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
+  locs->set_in(kLengthPos, Location::RequiresRegister());
+  locs->set_in(kIndexPos, Location::RequiresRegister());
+  return locs;
+}
+
+
+class RangeErrorSlowPath : public SlowPathCode {
+ public:
+  RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index)
+      : instruction_(instruction), try_index_(try_index) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (Assembler::EmittingComments()) {
+      __ Comment("slow path check bound operation");
+    }
+    __ Bind(entry_label());
+    LocationSummary* locs = instruction_->locs();
+    __ Push(locs->in(0).reg());
+    __ Push(locs->in(1).reg());
+    __ CallRuntime(kRangeErrorRuntimeEntry, 2);
+    compiler->pc_descriptors_list()->AddDescriptor(
+        RawPcDescriptors::kOther,
+        compiler->assembler()->CodeSize(),
+        instruction_->deopt_id(),
+        instruction_->token_pos(),
+        try_index_);
+    compiler->RecordSafepoint(locs, 2);
+    __ brk(0);
+  }
+
+ private:
+  GenericCheckBoundInstr* instruction_;
+  intptr_t try_index_;
+};
+
+
+void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  RangeErrorSlowPath* slow_path =
+      new RangeErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  Location length_loc = locs()->in(kLengthPos);
+  Location index_loc = locs()->in(kIndexPos);
+  Register length = length_loc.reg();
+  Register index = index_loc.reg();
+  const intptr_t index_cid = this->index()->Type()->ToCid();
+  if (index_cid != kSmiCid) {
+    __ BranchIfNotSmi(index, slow_path->entry_label());
+  }
+  __ cmp(index, Operand(length));
+  __ b(slow_path->entry_label(), CS);
 }
 
 
@@ -5282,6 +5342,7 @@
   Location length_loc = locs()->in(kLengthPos);
   Location index_loc = locs()->in(kIndexPos);
 
+  const intptr_t index_cid = index()->Type()->ToCid();
   if (length_loc.IsConstant() && index_loc.IsConstant()) {
     // TODO(srdjan): remove this code once failures are fixed.
     if ((Smi::Cast(length_loc.constant()).Value() >
@@ -5307,6 +5368,9 @@
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
     const Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     if (length.Value() == Smi::kMaxValue) {
       __ tst(index, Operand(index));
       __ b(deopt, MI);
@@ -5317,6 +5381,9 @@
   } else {
     const Register length = length_loc.reg();
     const Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     __ CompareRegisters(index, length);
     __ b(deopt, CS);
   }
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index 8c954b6..d2fb113 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -30,36 +30,43 @@
 
 // List of instructions that are still unimplemented by DBC backend.
 #define FOR_EACH_UNIMPLEMENTED_INSTRUCTION(M)                                  \
-  M(IndirectGoto)                                                              \
   M(LoadCodeUnits)                                                             \
   M(LoadUntagged)                                                              \
   M(AllocateUninitializedContext)                                              \
   M(BinaryInt32Op)                                                             \
-  M(UnaryDoubleOp)                                                             \
-  M(SmiToDouble)                                                               \
   M(Int32ToDouble)                                                             \
-  M(MintToDouble)                                                              \
   M(DoubleToInteger)                                                           \
-  M(DoubleToSmi)                                                               \
   M(DoubleToDouble)                                                            \
   M(DoubleToFloat)                                                             \
   M(FloatToDouble)                                                             \
-  M(UnboxedConstant)                                                           \
-  M(BinaryDoubleOp)                                                            \
-  M(MathUnary)                                                                 \
-  M(MathMinMax)                                                                \
-  M(Box)                                                                       \
-  M(Unbox)                                                                     \
   M(BoxInt64)                                                                  \
-  M(CaseInsensitiveCompareUC16)                                                \
-  M(BinaryMintOp)                                                              \
-  M(ShiftMintOp)                                                               \
-  M(UnaryMintOp)                                                               \
-  M(InvokeMathCFunction)                                                       \
   M(MergedMath)                                                                \
   M(GuardFieldClass)                                                           \
   M(GuardFieldLength)                                                          \
   M(IfThenElse)                                                                \
+  M(ExtractNthOutput)                                                          \
+  M(BinaryUint32Op)                                                            \
+  M(ShiftUint32Op)                                                             \
+  M(UnaryUint32Op)                                                             \
+  M(UnboxedIntConverter)                                                       \
+  M(BoxInteger32)                                                              \
+  M(UnboxInteger32)                                                            \
+
+// List of instructions that are not used by DBC.
+// Things we aren't planning to implement for DBC:
+// - Unboxed SIMD,
+// - Unboxed Mint,
+// - Optimized RegExps,
+// - Precompilation.
+#define FOR_EACH_UNREACHABLE_INSTRUCTION(M)                                    \
+  M(CaseInsensitiveCompareUC16)                                                \
+  M(GenericCheckBound)                                                         \
+  M(GrowRegExpStack)                                                           \
+  M(IndirectGoto)                                                              \
+  M(MintToDouble)                                                              \
+  M(BinaryMintOp)                                                              \
+  M(ShiftMintOp)                                                               \
+  M(UnaryMintOp)                                                               \
   M(BinaryFloat32x4Op)                                                         \
   M(Simd32x4Shuffle)                                                           \
   M(Simd32x4ShuffleMix)                                                        \
@@ -82,7 +89,6 @@
   M(Int32x4SetFlag)                                                            \
   M(Int32x4ToFloat32x4)                                                        \
   M(BinaryInt32x4Op)                                                           \
-  M(TestCids)                                                                  \
   M(BinaryFloat64x2Op)                                                         \
   M(Float64x2Zero)                                                             \
   M(Float64x2Constructor)                                                      \
@@ -92,19 +98,7 @@
   M(Simd64x2Shuffle)                                                           \
   M(Float64x2ZeroArg)                                                          \
   M(Float64x2OneArg)                                                           \
-  M(ExtractNthOutput)                                                          \
-  M(BinaryUint32Op)                                                            \
-  M(ShiftUint32Op)                                                             \
-  M(UnaryUint32Op)                                                             \
-  M(UnboxedIntConverter)                                                       \
-  M(GrowRegExpStack)                                                           \
-  M(BoxInteger32)                                                              \
-  M(UnboxInteger32)                                                            \
   M(CheckedSmiOp)                                                              \
-  M(CheckArrayBound)                                                           \
-  M(RelationalOp)                                                              \
-  M(EqualityCompare)                                                           \
-  M(LoadIndexed)
 
 // Location summaries actually are not used by the unoptimizing DBC compiler
 // because we don't allocate any registers.
@@ -112,14 +106,17 @@
     Zone* zone,
     intptr_t num_inputs,
     Location output = Location::NoLocation(),
-    LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall) {
-  const intptr_t kNumTemps = 0;
+    LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall,
+    intptr_t num_temps = 0) {
   LocationSummary* locs = new(zone) LocationSummary(
-      zone, num_inputs, kNumTemps, contains_call);
+      zone, num_inputs, num_temps, contains_call);
   for (intptr_t i = 0; i < num_inputs; i++) {
     locs->set_in(i, (contains_call == LocationSummary::kNoCall) ?
         Location::RequiresRegister() : Location::RegisterLocation(i));
   }
+  for (intptr_t i = 0; i < num_temps; i++) {
+    locs->set_temp(i, Location::RequiresRegister());
+  }
   if (!output.IsInvalid()) {
     // For instructions that call we default to returning result in R0.
     locs->set_out(0, output);
@@ -145,11 +142,23 @@
     return NULL;                                                               \
   }                                                                            \
 
+#define DEFINE_UNREACHABLE_MAKE_LOCATION_SUMMARY(Name)                         \
+  LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt)      \
+      const {                                                                  \
+    UNREACHABLE();                                                             \
+    return NULL;                                                               \
+  }                                                                            \
+
 #define DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name)                            \
   void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) {              \
     UNIMPLEMENTED();                                                           \
   }
 
+#define DEFINE_UNREACHABLE_EMIT_NATIVE_CODE(Name)                              \
+  void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler) {              \
+    UNREACHABLE();                                                             \
+  }
+
 #define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name)                            \
   void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) {         \
     UNIMPLEMENTED();                                                           \
@@ -168,9 +177,13 @@
 
 #undef DEFINE_UNIMPLEMENTED
 
-DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestCids)
-DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(RelationalOp)
-DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare)
+#define DEFINE_UNREACHABLE(Name)                                               \
+  DEFINE_UNREACHABLE_MAKE_LOCATION_SUMMARY(Name)                               \
+  DEFINE_UNREACHABLE_EMIT_NATIVE_CODE(Name)                                    \
+
+FOR_EACH_UNREACHABLE_INSTRUCTION(DEFINE_UNREACHABLE)
+
+#undef DEFINE_UNREACHABLE
 
 
 EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(),
@@ -221,15 +234,56 @@
 }
 
 
-LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
-    Zone* zone, bool optimizing) const {
-  return MakeCallSummary(zone);
-}
+EMIT_NATIVE_CODE(PolymorphicInstanceCall,
+                 0, Location::RegisterLocation(0),
+                 LocationSummary::kCall) {
+  ASSERT(ic_data().NumArgsTested() == 1);
+  const Array& arguments_descriptor =
+      Array::Handle(ArgumentsDescriptor::New(
+          instance_call()->ArgumentCount(),
+          instance_call()->argument_names()));
+  const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
 
+  // Push the target onto the stack.
+  if (with_checks()) {
+    const intptr_t may_be_smi =
+        (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? 1 : 0;
+    GrowableArray<CidTarget> sorted_ic_data;
+    FlowGraphCompiler::SortICDataByCount(ic_data(),
+                                         &sorted_ic_data,
+                                         /* drop_smi = */ true);
+    const intptr_t sorted_length = sorted_ic_data.length();
+    if (!Utils::IsUint(8, sorted_length)) {
+      Unsupported(compiler);
+      UNREACHABLE();
+    }
+    __ PushPolymorphicInstanceCall(
+        instance_call()->ArgumentCount(), sorted_length + may_be_smi);
+    if (may_be_smi == 1) {
+      const Function& target = Function::ZoneHandle(
+          compiler->zone(), ic_data().GetTargetAt(0));
+      __ Nop(compiler->ToEmbeddableCid(kSmiCid, this));
+      __ Nop(__ AddConstant(target));
+    }
+    for (intptr_t i = 0; i < sorted_length; i++) {
+      const Function& target = *sorted_ic_data[i].target;
+      __ Nop(compiler->ToEmbeddableCid(sorted_ic_data[i].cid, this));
+      __ Nop(__ AddConstant(target));
+    }
+    compiler->EmitDeopt(
+        deopt_id(), ICData::kDeoptPolymorphicInstanceCallTestFail, 0);
+  } else {
+    ASSERT(ic_data().HasOneTarget());
+    const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
+    __ PushConstant(target);
+  }
 
-void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Unsupported(compiler);
-  UNREACHABLE();
+  // Call the function.
+  __ StaticCall(instance_call()->ArgumentCount(), argdesc_kidx);
+  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
+      deopt_id(), instance_call()->token_pos());
+  compiler->RecordAfterCall(this);
+  __ PopLocal(locs()->out(0).reg());
 }
 
 
@@ -242,10 +296,10 @@
                  0, Location::NoLocation(),
                  LocationSummary::kCall) {
   __ CheckStack();
-  compiler->RecordSafepoint(locs());
-  compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
-                                 Thread::kNoDeoptId,
+  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
+                                 deopt_id(),
                                  token_pos());
+  compiler->RecordAfterCall(this);
 }
 
 
@@ -294,6 +348,25 @@
 }
 
 
+EMIT_NATIVE_CODE(UnboxedConstant, 0, Location::RequiresRegister()) {
+  // The register allocator drops constant definitions that have no uses.
+  if (locs()->out(0).IsInvalid()) {
+    return;
+  }
+  if (representation_ != kUnboxedDouble) {
+    Unsupported(compiler);
+    UNREACHABLE();
+  }
+  const Register result = locs()->out(0).reg();
+  if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) {
+    __ BitXor(result, result, result);
+  } else {
+    __ LoadConstant(result, value());
+    __ UnboxDouble(result, result);
+  }
+}
+
+
 EMIT_NATIVE_CODE(Return, 1) {
   if (compiler->is_optimizing()) {
     __ Return(locs()->in(0).reg());
@@ -367,7 +440,6 @@
       compiler->assembler()->AddConstant(arguments_descriptor);
   __ StaticCall(argument_count, argdesc_kidx);
   compiler->RecordAfterCall(this);
-
   if (compiler->is_optimizing()) {
     __ PopLocal(locs()->out(0).reg());
   }
@@ -378,14 +450,25 @@
                                   Condition true_condition,
                                   BranchLabels labels) {
   if (true_condition == NEXT_IS_TRUE) {
+    // NEXT_IS_TRUE indicates that the preceeding test expects the true case
+    // to be in the subsequent instruction, which it skips if the test fails.
     __ Jump(labels.true_label);
     if (labels.fall_through != labels.false_label) {
+      // The preceeding Jump instruction will be skipped if the test fails.
+      // If we aren't falling through to the false case, then we have to do
+      // a Jump to it here.
       __ Jump(labels.false_label);
     }
   } else {
     ASSERT(true_condition == NEXT_IS_FALSE);
+    // NEXT_IS_FALSE indicates that the preceeing test has been flipped and
+    // expects the false case to be in the subsequent instruction, which it
+    // skips if the test succeeds.
     __ Jump(labels.false_label);
     if (labels.fall_through != labels.true_label) {
+      // The preceeding Jump instruction will be skipped if the test succeeds.
+      // If we aren't falling through to the true case, then we have to do
+      // a Jump to it here.
       __ Jump(labels.true_label);
     }
   }
@@ -544,6 +627,62 @@
 }
 
 
+Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                           BranchLabels labels) {
+  ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
+  const Register value = locs()->in(0).reg();
+  const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
+
+  const ZoneGrowableArray<intptr_t>& data = cid_results();
+  const intptr_t num_cases = data.length() / 2;
+  ASSERT(num_cases <= 255);
+  __ TestCids(value, num_cases);
+
+  bool result = false;
+  for (intptr_t i = 0; i < data.length(); i += 2) {
+    const intptr_t test_cid = data[i];
+    result = data[i + 1] == true_result;
+    __ Nop(result ? 1 : 0, compiler->ToEmbeddableCid(test_cid, this));
+  }
+
+  // No match found, deoptimize or false.
+  if (CanDeoptimize()) {
+    compiler->EmitDeopt(deopt_id(),
+                        ICData::kDeoptTestCids,
+                        licm_hoisted_ ? ICData::kHoisted : 0);
+  } else {
+    Label* target = result ? labels.false_label : labels.true_label;
+    __ Jump(target);
+  }
+
+  return NEXT_IS_TRUE;
+}
+
+
+void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+                                   BranchInstr* branch) {
+  BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
+}
+
+
+EMIT_NATIVE_CODE(TestCids, 1, Location::RequiresRegister(),
+                 LocationSummary::kNoCall) {
+  Register result_reg = locs()->out(0).reg();
+  Label is_true, is_false, done;
+  BranchLabels labels = { &is_true, &is_false, &is_false };
+  EmitComparisonCode(compiler, labels);
+  __ Jump(&is_true);
+  __ Bind(&is_false);
+  __ LoadConstant(result_reg, Bool::False());
+  __ Jump(&done);
+  __ Bind(&is_true);
+  __ LoadConstant(result_reg, Bool::True());
+  __ Bind(&done);
+}
+
+
 EMIT_NATIVE_CODE(CreateArray,
                  2, Location::RequiresRegister(),
                  LocationSummary::kCall) {
@@ -559,15 +698,38 @@
 }
 
 
-EMIT_NATIVE_CODE(StoreIndexed, 3) {
+EMIT_NATIVE_CODE(StoreIndexed, 3, Location::NoLocation(),
+                 LocationSummary::kNoCall, 1) {
   if (compiler->is_optimizing()) {
-    if (class_id() != kArrayCid) {
+    if (IsExternal()) {
       Unsupported(compiler);
       UNREACHABLE();
     }
-    __ StoreIndexed(locs()->in(kArrayPos).reg(),
-                    locs()->in(kIndexPos).reg(),
-                    locs()->in(kValuePos).reg());
+    const Register array = locs()->in(kArrayPos).reg();
+    const Register index = locs()->in(kIndexPos).reg();
+    const Register value = locs()->in(kValuePos).reg();
+    const Register temp = locs()->temp(0).reg();
+    switch (class_id()) {
+      case kArrayCid:
+        __ StoreIndexed(array, index, value);
+        break;
+      case kTypedDataFloat64ArrayCid:
+        if ((index_scale() != 8) && (index_scale() != 1)) {
+          Unsupported(compiler);
+          UNREACHABLE();
+        }
+        if (index_scale() == 1) {
+          __ ShrImm(temp, index, 3);
+        } else {
+          __ Move(temp, index);
+        }
+        __ StoreFloat64Indexed(array, temp, value);
+        break;
+      default:
+        Unsupported(compiler);
+        UNREACHABLE();
+        break;
+    }
   } else {
     ASSERT(class_id() == kArrayCid);
     __ StoreIndexedTOS();
@@ -575,6 +737,49 @@
 }
 
 
+EMIT_NATIVE_CODE(LoadIndexed, 2, Location::RequiresRegister()) {
+  ASSERT(compiler->is_optimizing());
+  if (IsExternal()) {
+    Unsupported(compiler);
+    UNREACHABLE();
+  }
+  const Register array = locs()->in(0).reg();
+  const Register index = locs()->in(1).reg();
+  const Register result = locs()->out(0).reg();
+  switch (class_id()) {
+    case kArrayCid:
+      __ LoadIndexed(result, array, index);
+      break;
+    case kTypedDataFloat64ArrayCid:
+      if ((index_scale() != 8) && (index_scale() != 1)) {
+        Unsupported(compiler);
+        UNREACHABLE();
+      }
+      if (index_scale() == 1) {
+        __ ShrImm(index, index, 3);
+      }
+      __ LoadFloat64Indexed(result, array, index);
+      break;
+    case kOneByteStringCid:
+      ASSERT(index_scale() == 1);
+      __ LoadOneByteStringIndexed(result, array, index);
+      break;
+    case kTwoByteStringCid:
+      if (index_scale() != 2) {
+        // TODO(zra): Fix-up index.
+        Unsupported(compiler);
+        UNREACHABLE();
+      }
+      __ LoadTwoByteStringIndexed(result, array, index);
+      break;
+    default:
+      Unsupported(compiler);
+      UNREACHABLE();
+      break;
+  }
+}
+
+
 EMIT_NATIVE_CODE(StringInterpolate,
                  1, Location::RegisterLocation(0),
                  LocationSummary::kCall) {
@@ -588,7 +793,6 @@
   const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
   __ StaticCall(kArgumentCount, argdesc_kidx);
   compiler->RecordAfterCall(this);
-
   if (compiler->is_optimizing()) {
     __ PopLocal(locs()->out(0).reg());
   }
@@ -605,7 +809,7 @@
   ASSERT(!link_lazily());
   const ExternalLabel label(reinterpret_cast<uword>(native_c_function()));
   const intptr_t target_kidx =
-      __ object_pool_wrapper().FindImmediate(label.address());
+      __ object_pool_wrapper().FindNativeEntry(&label, kNotPatchable);
   const intptr_t argc_tag_kidx =
       __ object_pool_wrapper().FindImmediate(static_cast<uword>(argc_tag));
   __ PushConstant(target_kidx);
@@ -642,7 +846,6 @@
 }
 
 
-
 EMIT_NATIVE_CODE(AllocateObject,
                  0, Location::RequiresRegister(),
                  LocationSummary::kCall) {
@@ -741,10 +944,10 @@
 
 EMIT_NATIVE_CODE(Throw, 0, Location::NoLocation(), LocationSummary::kCall) {
   __ Throw(0);
-  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  deopt_id(),
                                  token_pos());
+  compiler->RecordAfterCall(this);
   __ Trap();
 }
 
@@ -752,10 +955,10 @@
 EMIT_NATIVE_CODE(ReThrow, 0, Location::NoLocation(), LocationSummary::kCall) {
   compiler->SetNeedsStacktrace(catch_try_index());
   __ Throw(1);
-  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  deopt_id(),
                                  token_pos());
+  compiler->RecordAfterCall(this);
   __ Trap();
 }
 
@@ -966,12 +1169,9 @@
     // Check that we are in the backend - register allocation has been run.
     ASSERT(locations_ != NULL);
 
-    // Check that we are only dropping PushArgument instructions from the
+    // Check that we are only dropping a valid number of instructions from the
     // environment.
     ASSERT(argc <= values_.length());
-    for (intptr_t i = 0; i < argc; i++) {
-      ASSERT(values_[values_.length() - i - 1]->definition()->IsPushArgument());
-    }
 #endif
     values_.TruncateTo(values_.length() - argc);
 }
@@ -986,22 +1186,9 @@
 
 
 EMIT_NATIVE_CODE(CheckEitherNonSmi, 2) {
-  intptr_t left_cid = left()->Type()->ToCid();
-  intptr_t right_cid = right()->Type()->ToCid();
   const Register left = locs()->in(0).reg();
   const Register right = locs()->in(1).reg();
-  if (this->left()->definition() == this->right()->definition()) {
-    __ CheckSmi(left);
-  } else if (left_cid == kSmiCid) {
-    __ CheckSmi(right);
-  } else if (right_cid == kSmiCid) {
-    __ CheckSmi(left);
-  } else {
-    __ CheckSmi(left);
-    compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp,
-                        licm_hoisted_ ? ICData::kHoisted : 0);
-    __ CheckSmi(right);
-  }
+  __ CheckEitherNonSmi(left, right);
   compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinaryDoubleOp,
                       licm_hoisted_ ? ICData::kHoisted : 0);
 }
@@ -1127,9 +1314,314 @@
       break;
     default:
       UNREACHABLE();
+      break;
   }
 }
 
+
+EMIT_NATIVE_CODE(Box, 1, Location::RequiresRegister(), LocationSummary::kCall) {
+  ASSERT(from_representation() == kUnboxedDouble);
+  const Register value = locs()->in(0).reg();
+  const Register out = locs()->out(0).reg();
+  const intptr_t kidx = __ AddConstant(compiler->double_class());
+  __ Allocate(kidx);
+  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
+                                 Thread::kNoDeoptId,
+                                 token_pos());
+  compiler->RecordSafepoint(locs());
+  // __ Allocate puts the box at the top of the stack.
+  __ WriteIntoDouble(out, value);
+}
+
+
+EMIT_NATIVE_CODE(Unbox, 1, Location::RequiresRegister()) {
+  ASSERT(representation() == kUnboxedDouble);
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t box_cid = BoxCid();
+  const Register box = locs()->in(0).reg();
+  const Register result = locs()->out(0).reg();
+  if (value_cid == box_cid) {
+    __ UnboxDouble(result, box);
+  } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
+    __ SmiToDouble(result, box);
+  } else if ((value()->Type()->ToNullableCid() == box_cid) &&
+              value()->Type()->is_nullable()) {
+    __ IfEqNull(box);
+    compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
+    __ UnboxDouble(result, box);
+  } else {
+    __ CheckedUnboxDouble(result, box);
+    compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
+  }
+}
+
+
+EMIT_NATIVE_CODE(DoubleToSmi, 1, Location::RequiresRegister()) {
+  const Register value = locs()->in(0).reg();
+  const Register result = locs()->out(0).reg();
+  __ DoubleToSmi(result, value);
+  compiler->EmitDeopt(deopt_id(), ICData::kDeoptDoubleToSmi);
+}
+
+
+EMIT_NATIVE_CODE(SmiToDouble, 1, Location::RequiresRegister()) {
+  const Register value = locs()->in(0).reg();
+  const Register result = locs()->out(0).reg();
+  __ SmiToDouble(result, value);
+}
+
+
+EMIT_NATIVE_CODE(BinaryDoubleOp, 2, Location::RequiresRegister()) {
+  const Register left = locs()->in(0).reg();
+  const Register right = locs()->in(1).reg();
+  const Register result = locs()->out(0).reg();
+  switch (op_kind()) {
+    case Token::kADD: __ DAdd(result, left, right); break;
+    case Token::kSUB: __ DSub(result, left, right); break;
+    case Token::kMUL: __ DMul(result, left, right); break;
+    case Token::kDIV: __ DDiv(result, left, right); break;
+    default: UNREACHABLE();
+  }
+}
+
+
+EMIT_NATIVE_CODE(UnaryDoubleOp, 1, Location::RequiresRegister()) {
+  const Register value = locs()->in(0).reg();
+  const Register result = locs()->out(0).reg();
+  __ DNeg(result, value);
+}
+
+
+EMIT_NATIVE_CODE(MathUnary, 1, Location::RequiresRegister()) {
+  const Register value = locs()->in(0).reg();
+  const Register result = locs()->out(0).reg();
+  if (kind() == MathUnaryInstr::kSqrt) {
+    __ DSqrt(result, value);
+  } else if (kind() == MathUnaryInstr::kDoubleSquare) {
+    __ DMul(result, value, value);
+  } else if (kind() == MathUnaryInstr::kSin) {
+    __ DSin(result, value);
+  } else if (kind() == MathUnaryInstr::kCos) {
+    __ DCos(result, value);
+  } else {
+    Unsupported(compiler);
+    UNREACHABLE();
+  }
+}
+
+
+EMIT_NATIVE_CODE(InvokeMathCFunction,
+                 InputCount(), Location::RequiresRegister()) {
+  const Register left = locs()->in(0).reg();
+  const Register result = locs()->out(0).reg();
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    const Register right = locs()->in(1).reg();
+    __ DPow(result, left, right);
+  } else if (recognized_kind() == MethodRecognizer::kDoubleMod) {
+    const Register right = locs()->in(1).reg();
+    __ DMod(result, left, right);
+  } else {
+    Unsupported(compiler);
+    UNREACHABLE();
+  }
+}
+
+
+EMIT_NATIVE_CODE(MathMinMax, 2, Location::RequiresRegister()) {
+  ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
+         (op_kind() == MethodRecognizer::kMathMax));
+  const Register left = locs()->in(0).reg();
+  const Register right = locs()->in(1).reg();
+  const Register result = locs()->out(0).reg();
+  if (result_cid() == kDoubleCid) {
+    if (op_kind() == MethodRecognizer::kMathMin) {
+      __ DMin(result, left, right);
+    } else {
+      __ DMax(result, left, right);
+    }
+  } else {
+    ASSERT(result_cid() == kSmiCid);
+    if (op_kind() == MethodRecognizer::kMathMin) {
+      __ Min(result, left, right);
+    } else {
+      __ Max(result, left, right);
+    }
+  }
+}
+
+
+static Token::Kind FlipCondition(Token::Kind kind) {
+  switch (kind) {
+    case Token::kEQ: return Token::kNE;
+    case Token::kNE: return Token::kEQ;
+    case Token::kLT: return Token::kGTE;
+    case Token::kGT: return Token::kLTE;
+    case Token::kLTE: return Token::kGT;
+    case Token::kGTE: return Token::kLT;
+    default:
+      UNREACHABLE();
+      return Token::kNE;
+  }
+}
+
+
+static Bytecode::Opcode OpcodeForSmiCondition(Token::Kind kind) {
+  switch (kind) {
+    case Token::kEQ: return Bytecode::kIfEqStrict;
+    case Token::kNE: return Bytecode::kIfNeStrict;
+    case Token::kLT: return Bytecode::kIfLt;
+    case Token::kGT: return Bytecode::kIfGt;
+    case Token::kLTE: return Bytecode::kIfLe;
+    case Token::kGTE: return Bytecode::kIfGe;
+    default:
+      UNREACHABLE();
+      return Bytecode::kTrap;
+  }
+}
+
+
+static Bytecode::Opcode OpcodeForDoubleCondition(Token::Kind kind) {
+  switch (kind) {
+    case Token::kEQ: return Bytecode::kIfDEq;
+    case Token::kNE: return Bytecode::kIfDNe;
+    case Token::kLT: return Bytecode::kIfDLt;
+    case Token::kGT: return Bytecode::kIfDGt;
+    case Token::kLTE: return Bytecode::kIfDLe;
+    case Token::kGTE: return Bytecode::kIfDGe;
+    default:
+      UNREACHABLE();
+      return Bytecode::kTrap;
+  }
+}
+
+
+static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
+                                     LocationSummary* locs,
+                                     Token::Kind kind,
+                                     BranchLabels labels) {
+  const Register left = locs->in(0).reg();
+  const Register right = locs->in(1).reg();
+  Token::Kind comparison = kind;
+  Condition condition = NEXT_IS_TRUE;
+  if (labels.fall_through != labels.false_label) {
+    // If we aren't falling through to the false label, we can save a Jump
+    // instruction in the case that the true case is the fall through by
+    // flipping the sense of the test such that the instruction following the
+    // test is the Jump to the false label.
+    condition = NEXT_IS_FALSE;
+    comparison = FlipCondition(kind);
+  }
+  __ Emit(Bytecode::Encode(OpcodeForSmiCondition(comparison), left, right));
+  return condition;
+}
+
+
+static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
+                                        LocationSummary* locs,
+                                        Token::Kind kind,
+                                        BranchLabels labels) {
+  const Register left = locs->in(0).reg();
+  const Register right = locs->in(1).reg();
+  Token::Kind comparison = kind;
+  Condition condition = NEXT_IS_TRUE;
+  if (labels.fall_through != labels.false_label) {
+    // If we aren't falling through to the false label, we can save a Jump
+    // instruction in the case that the true case is the fall through by
+    // flipping the sense of the test such that the instruction following the
+    // test is the Jump to the false label.
+    condition = NEXT_IS_FALSE;
+    comparison = FlipCondition(kind);
+  }
+  __ Emit(Bytecode::Encode(OpcodeForDoubleCondition(comparison), left, right));
+  return condition;
+}
+
+
+Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                   BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, locs(), kind(), labels);
+  }
+}
+
+
+EMIT_NATIVE_CODE(EqualityCompare, 2, Location::RequiresRegister()) {
+  ASSERT(compiler->is_optimizing());
+  ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
+  Label is_true, is_false;
+  // These labels are not used. They are arranged so that EmitComparisonCode
+  // emits a test that executes the following instruction when the test
+  // succeeds.
+  BranchLabels labels = { &is_true, &is_false, &is_false };
+  const Register result = locs()->out(0).reg();
+  __ LoadConstant(result, Bool::False());
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  ASSERT(true_condition == NEXT_IS_TRUE);
+  __ LoadConstant(result, Bool::True());
+}
+
+
+void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+                                          BranchInstr* branch) {
+  ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
+  BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
+}
+
+
+Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, locs(), kind(), labels);
+  }
+}
+
+
+EMIT_NATIVE_CODE(RelationalOp, 2, Location::RequiresRegister()) {
+  ASSERT(compiler->is_optimizing());
+  Label is_true, is_false;
+  BranchLabels labels = { &is_true, &is_false, &is_false };
+  const Register result = locs()->out(0).reg();
+  __ LoadConstant(result, Bool::False());
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  ASSERT(true_condition == NEXT_IS_TRUE);
+  __ LoadConstant(result, Bool::True());
+}
+
+
+void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+                                       BranchInstr* branch) {
+  BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
+}
+
+
+EMIT_NATIVE_CODE(CheckArrayBound, 2) {
+  const Register length = locs()->in(kLengthPos).reg();
+  const Register index = locs()->in(kIndexPos).reg();
+  const intptr_t index_cid = this->index()->Type()->ToCid();
+  if (index_cid != kSmiCid) {
+    __ CheckSmi(index);
+    compiler->EmitDeopt(deopt_id(),
+                        ICData::kDeoptCheckArrayBound,
+                        (generalized_ ? ICData::kGeneralized : 0) |
+                        (licm_hoisted_ ? ICData::kHoisted : 0));
+  }
+  __ IfULe(length, index);
+  compiler->EmitDeopt(deopt_id(),
+                      ICData::kDeoptCheckArrayBound,
+                      (generalized_ ? ICData::kGeneralized : 0) |
+                      (licm_hoisted_ ? ICData::kHoisted : 0));
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 34555dc..3ccb078 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -5847,8 +5847,7 @@
   Label* deopt = compiler->AddDeoptStub(deopt_id(),
                                         ICData::kDeoptCheckSmi,
                                         licm_hoisted_ ? ICData::kHoisted : 0);
-  __ testl(value, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, deopt);
+  __ BranchIfNotSmi(value, deopt);
 }
 
 
@@ -5871,6 +5870,20 @@
 }
 
 
+LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone,
+                                                             bool opt) const {
+  // Only needed for AOT.
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // Only needed for AOT.
+  UNIMPLEMENTED();
+}
+
+
 // Length: register or constant.
 // Index: register, constant or stack slot.
 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
@@ -5910,8 +5923,12 @@
     return;
   }
 
+  const intptr_t index_cid = index()->Type()->ToCid();
   if (length_loc.IsConstant()) {
     Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     const Smi& length = Smi::Cast(length_loc.constant());
     if (length.Value() == Smi::kMaxValue) {
       __ testl(index, index);
@@ -5933,11 +5950,17 @@
   } else if (length_loc.IsStackSlot()) {
     Register index = index_loc.reg();
     const Address& length = length_loc.ToStackSlotAddress();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     __ cmpl(index, length);
     __ j(ABOVE_EQUAL, deopt);
   } else {
     Register index = index_loc.reg();
     Register length = length_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     __ cmpl(length, index);
     __ j(BELOW_EQUAL, deopt);
   }
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 342e267..645273f 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -4836,8 +4836,7 @@
   Label* deopt = compiler->AddDeoptStub(deopt_id(),
                                         ICData::kDeoptCheckSmi,
                                         licm_hoisted_ ? ICData::kHoisted : 0);
-  __ andi(CMPRES1, value, Immediate(kSmiTagMask));
-  __ bne(CMPRES1, ZR, deopt);
+  __ BranchIfNotSmi(value, deopt);
 }
 
 
@@ -4859,6 +4858,64 @@
 }
 
 
+LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone,
+                                                             bool opt) const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new(zone) LocationSummary(
+      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
+  locs->set_in(kLengthPos, Location::RequiresRegister());
+  locs->set_in(kIndexPos, Location::RequiresRegister());
+  return locs;
+}
+
+
+class RangeErrorSlowPath : public SlowPathCode {
+ public:
+  RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index)
+      : instruction_(instruction), try_index_(try_index) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (Assembler::EmittingComments()) {
+      __ Comment("slow path check bound operation");
+    }
+    __ Bind(entry_label());
+    LocationSummary* locs = instruction_->locs();
+    __ Push(locs->in(0).reg());
+    __ Push(locs->in(1).reg());
+    __ CallRuntime(kRangeErrorRuntimeEntry, 2);
+    compiler->pc_descriptors_list()->AddDescriptor(
+        RawPcDescriptors::kOther,
+        compiler->assembler()->CodeSize(),
+        instruction_->deopt_id(),
+        instruction_->token_pos(),
+        try_index_);
+    __ break_(0);
+  }
+
+ private:
+  GenericCheckBoundInstr* instruction_;
+  intptr_t try_index_;
+};
+
+
+void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  RangeErrorSlowPath* slow_path =
+      new RangeErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  Location length_loc = locs()->in(kLengthPos);
+  Location index_loc = locs()->in(kIndexPos);
+  Register length = length_loc.reg();
+  Register index = index_loc.reg();
+  const intptr_t index_cid = this->index()->Type()->ToCid();
+  if (index_cid != kSmiCid) {
+    __ BranchIfNotSmi(index, slow_path->entry_label());
+  }
+  __ BranchUnsignedGreaterEqual(index, length, slow_path->entry_label());
+}
+
+
 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
                                                            bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -4892,6 +4949,7 @@
     return;
   }
 
+  const intptr_t index_cid = index()->Type()->ToCid();
   if (index_loc.IsConstant()) {
     Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
@@ -4900,6 +4958,9 @@
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
     Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     if (length.Value() == Smi::kMaxValue) {
       __ BranchSignedLess(index, Immediate(0), deopt);
     } else {
@@ -4909,6 +4970,9 @@
   } else {
     Register length = length_loc.reg();
     Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     __ BranchUnsignedGreaterEqual(index, length, deopt);
   }
 }
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index da4b4c2..c908d1e 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -5697,8 +5697,7 @@
   Label* deopt = compiler->AddDeoptStub(deopt_id(),
                                         ICData::kDeoptCheckSmi,
                                         licm_hoisted_ ? ICData::kHoisted : 0);
-  __ testq(value, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, deopt);
+  __ BranchIfNotSmi(value, deopt);
 }
 
 
@@ -5721,6 +5720,66 @@
 }
 
 
+LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone,
+                                                             bool opt) const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new(zone) LocationSummary(
+      zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
+  locs->set_in(kLengthPos, Location::RequiresRegister());
+  locs->set_in(kIndexPos, Location::RequiresRegister());
+  return locs;
+}
+
+
+class RangeErrorSlowPath : public SlowPathCode {
+ public:
+  RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index)
+      : instruction_(instruction), try_index_(try_index) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (Assembler::EmittingComments()) {
+      __ Comment("slow path check bound operation");
+    }
+    __ Bind(entry_label());
+    LocationSummary* locs = instruction_->locs();
+    __ pushq(locs->in(0).reg());
+    __ pushq(locs->in(1).reg());
+    __ CallRuntime(kRangeErrorRuntimeEntry, 2);
+    compiler->pc_descriptors_list()->AddDescriptor(
+        RawPcDescriptors::kOther,
+        compiler->assembler()->CodeSize(),
+        instruction_->deopt_id(),
+        instruction_->token_pos(),
+        try_index_);
+    compiler->RecordSafepoint(locs, 2);
+    __ int3();
+  }
+
+ private:
+  GenericCheckBoundInstr* instruction_;
+  intptr_t try_index_;
+};
+
+
+void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  RangeErrorSlowPath* slow_path =
+      new RangeErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  Location length_loc = locs()->in(kLengthPos);
+  Location index_loc = locs()->in(kIndexPos);
+  Register length = length_loc.reg();
+  Register index = index_loc.reg();
+  const intptr_t index_cid = this->index()->Type()->ToCid();
+  if (index_cid != kSmiCid) {
+    __ BranchIfNotSmi(index, slow_path->entry_label());
+  }
+  __ cmpq(index, length);
+  __ j(ABOVE_EQUAL, slow_path->entry_label());
+}
+
+
 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
                                                            bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -5754,6 +5813,7 @@
     return;
   }
 
+  const intptr_t index_cid = index()->Type()->ToCid();
   if (index_loc.IsConstant()) {
     Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
@@ -5763,6 +5823,9 @@
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
     Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     if (length.Value() == Smi::kMaxValue) {
       __ testq(index, index);
       __ j(NEGATIVE, deopt);
@@ -5774,6 +5837,9 @@
   } else {
     Register length = length_loc.reg();
     Register index = index_loc.reg();
+    if (index_cid != kSmiCid) {
+      __ BranchIfNotSmi(index, deopt);
+    }
     __ cmpq(index, length);
     __ j(ABOVE_EQUAL, deopt);
   }
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 9e049d0..02c469d 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -265,6 +265,10 @@
       return kDoubleCid;
     case kUnboxedFloat32x4:
       return kFloat32x4Cid;
+    case kUnboxedInt32x4:
+      return kInt32x4Cid;
+    case kUnboxedFloat64x2:
+      return kFloat64x2Cid;
     case kUnboxedUint32:
       return kDynamicCid;  // smi or mint.
     default:
@@ -373,12 +377,6 @@
                              Definition* array,
                              Definition* index,
                              intptr_t length_offset) {
-  TokenPosition token_pos = builder->TokenPos();
-  builder->AddInstruction(
-      new CheckSmiInstr(new Value(index),
-                        Thread::kNoDeoptId,
-                        token_pos));
-
   Definition* length = builder->AddDefinition(
       new LoadFieldInstr(new Value(array),
                          length_offset,
@@ -390,8 +388,8 @@
                                Thread::kNoDeoptId));
 }
 
-
-bool Intrinsifier::Build_ObjectArrayGetIndexed(FlowGraph* flow_graph) {
+static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph,
+                                      intptr_t array_cid) {
   GraphEntryInstr* graph_entry = flow_graph->graph_entry();
   TargetEntryInstr* normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
@@ -399,199 +397,82 @@
   Definition* index = builder.AddParameter(1);
   Definition* array = builder.AddParameter(2);
 
-  PrepareIndexedOp(&builder, array, index, Array::length_offset());
-
-  Definition* result = builder.AddDefinition(
-      new LoadIndexedInstr(new Value(array),
-                           new Value(index),
-                           Instance::ElementSizeFor(kArrayCid),  // index scale
-                           kArrayCid,
-                           Thread::kNoDeoptId,
-                           builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-
-bool Intrinsifier::Build_ImmutableArrayGetIndexed(FlowGraph* flow_graph) {
-  return Build_ObjectArrayGetIndexed(flow_graph);
-}
-
-
-bool Intrinsifier::Build_Uint8ArrayGetIndexed(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* index = builder.AddParameter(1);
-  Definition* array = builder.AddParameter(2);
-
-  PrepareIndexedOp(&builder, array, index, TypedData::length_offset());
-
-  Definition* result = builder.AddDefinition(
-      new LoadIndexedInstr(new Value(array),
-                           new Value(index),
-                           1,  // index scale
-                           kTypedDataUint8ArrayCid,
-                           Thread::kNoDeoptId,
-                           builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-
-bool Intrinsifier::Build_ExternalUint8ArrayGetIndexed(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* index = builder.AddParameter(1);
-  Definition* array = builder.AddParameter(2);
-
-  PrepareIndexedOp(&builder, array, index, ExternalTypedData::length_offset());
-
-  Definition* elements = builder.AddDefinition(
-      new LoadUntaggedInstr(new Value(array),
-                            ExternalTypedData::data_offset()));
-  Definition* result = builder.AddDefinition(
-      new LoadIndexedInstr(new Value(elements),
-                           new Value(index),
-                           1,  // index scale
-                           kExternalTypedDataUint8ArrayCid,
-                           Thread::kNoDeoptId,
-                           builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-
-bool Intrinsifier::Build_Uint8ArraySetIndexed(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
-
-  PrepareIndexedOp(&builder, array, index, TypedData::length_offset());
-
-  builder.AddInstruction(
-      new CheckSmiInstr(new Value(value),
-                        Thread::kNoDeoptId,
-                        builder.TokenPos()));
-
-  builder.AddInstruction(
-      new StoreIndexedInstr(new Value(array),
-                            new Value(index),
-                            new Value(value),
-                            kNoStoreBarrier,
-                            1,  // index scale
-                            kTypedDataUint8ArrayCid,
-                            Thread::kNoDeoptId,
-                            builder.TokenPos()));
-  // Return null.
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-
-bool Intrinsifier::Build_ExternalUint8ArraySetIndexed(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
-
-  PrepareIndexedOp(&builder, array, index, ExternalTypedData::length_offset());
-
-  builder.AddInstruction(
-      new CheckSmiInstr(new Value(value),
-                        Thread::kNoDeoptId,
-                        builder.TokenPos()));
-  Definition* elements = builder.AddDefinition(
-      new LoadUntaggedInstr(new Value(array),
-                            ExternalTypedData::data_offset()));
-  builder.AddInstruction(
-      new StoreIndexedInstr(new Value(elements),
-                            new Value(index),
-                            new Value(value),
-                            kNoStoreBarrier,
-                            1,  // index scale
-                            kExternalTypedDataUint8ArrayCid,
-                            Thread::kNoDeoptId,
-                            builder.TokenPos()));
-  // Return null.
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-
-bool Intrinsifier::Build_Uint32ArraySetIndexed(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
-
-  PrepareIndexedOp(&builder, array, index, TypedData::length_offset());
-
-  Definition* unboxed_value =
-      builder.AddUnboxInstr(kUnboxedUint32,
-                            new Value(value),
-                            /* is_checked = */ true);
-
-  builder.AddInstruction(
-      new StoreIndexedInstr(new Value(array),
-                            new Value(index),
-                            new Value(unboxed_value),
-                            kNoStoreBarrier,
-                            4,  // index scale
-                            kTypedDataUint32ArrayCid,
-                            Thread::kNoDeoptId,
-                            builder.TokenPos()));
-  // Return null.
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-
-bool Intrinsifier::Build_Uint32ArrayGetIndexed(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* index = builder.AddParameter(1);
-  Definition* array = builder.AddParameter(2);
-
-  PrepareIndexedOp(&builder, array, index, TypedData::length_offset());
-
-  Definition* unboxed_value = builder.AddDefinition(
-      new LoadIndexedInstr(new Value(array),
-                           new Value(index),
-                           4,  // index scale
-                           kTypedDataUint32ArrayCid,
-                           Thread::kNoDeoptId,
-                           builder.TokenPos()));
-  Definition* result = builder.AddDefinition(
-      BoxInstr::Create(kUnboxedUint32, new Value(unboxed_value)));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-
-bool Intrinsifier::Build_Float64ArraySetIndexed(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
-    return false;
+  intptr_t length_offset = Array::length_offset();
+  if (RawObject::IsTypedDataClassId(array_cid)) {
+    length_offset = TypedData::length_offset();
+  } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+    length_offset = ExternalTypedData::length_offset();
   }
 
+  PrepareIndexedOp(&builder, array, index, length_offset);
+
+  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+    array = builder.AddDefinition(
+      new LoadUntaggedInstr(new Value(array),
+                            ExternalTypedData::data_offset()));
+  }
+
+  Definition* result = builder.AddDefinition(
+      new LoadIndexedInstr(new Value(array),
+                           new Value(index),
+                           Instance::ElementSizeFor(array_cid),  // index scale
+                           array_cid,
+                           Thread::kNoDeoptId,
+                           builder.TokenPos()));
+  // Box and/or convert result if necessary.
+  switch (array_cid) {
+    case kTypedDataInt32ArrayCid:
+    case kExternalTypedDataInt32ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedInt32, new Value(result)));
+      break;
+    case kTypedDataUint32ArrayCid:
+    case kExternalTypedDataUint32ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedUint32, new Value(result)));
+      break;
+    case kTypedDataFloat32ArrayCid:
+      result = builder.AddDefinition(
+          new FloatToDoubleInstr(new Value(result), Thread::kNoDeoptId));
+      // Fall through.
+    case kTypedDataFloat64ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedDouble, new Value(result)));
+      break;
+    case kTypedDataFloat32x4ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedFloat32x4, new Value(result)));
+      break;
+    case kTypedDataInt32x4ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedInt32x4, new Value(result)));
+      break;
+    case kTypedDataFloat64x2ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedFloat64x2, new Value(result)));
+      break;
+    case kArrayCid:
+    case kImmutableArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+      // Nothing to do.
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+
+static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph,
+                                      intptr_t array_cid) {
   GraphEntryInstr* graph_entry = flow_graph->graph_entry();
   TargetEntryInstr* normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
@@ -600,33 +481,104 @@
   Definition* index = builder.AddParameter(2);
   Definition* array = builder.AddParameter(3);
 
-  PrepareIndexedOp(&builder, array, index, TypedData::length_offset());
+  intptr_t length_offset = Array::length_offset();
+  if (RawObject::IsTypedDataClassId(array_cid)) {
+    length_offset = TypedData::length_offset();
+  } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+    length_offset = ExternalTypedData::length_offset();
+  }
 
-  const ICData& value_check = ICData::ZoneHandle(ICData::New(
-      flow_graph->function(),
-      String::Handle(flow_graph->function().name()),
-      Object::empty_array(),  // Dummy args. descr.
-      Thread::kNoDeoptId,
-      1,
-      false));
-  value_check.AddReceiverCheck(kDoubleCid, flow_graph->function());
-  builder.AddInstruction(
-      new CheckClassInstr(new Value(value),
-                          Thread::kNoDeoptId,
-                          value_check,
-                          builder.TokenPos()));
-  Definition* double_value =
-      builder.AddUnboxInstr(kUnboxedDouble,
-                            new Value(value),
-                            /* is_checked = */ true);
+  PrepareIndexedOp(&builder, array, index, length_offset);
 
+  // Value check/conversion.
+  switch (array_cid) {
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+      builder.AddInstruction(new CheckSmiInstr(new Value(value),
+                                               Thread::kNoDeoptId,
+                                               builder.TokenPos()));
+      break;
+    case kTypedDataInt32ArrayCid:
+    case kExternalTypedDataInt32ArrayCid:
+      // Use same truncating unbox-instruction for int32 and uint32.
+      // Fall-through.
+    case kTypedDataUint32ArrayCid:
+    case kExternalTypedDataUint32ArrayCid:
+      // Supports smi and mint, slow-case for bigints.
+      value = builder.AddUnboxInstr(kUnboxedUint32,
+                                    new Value(value),
+                                    /* is_checked = */ false);
+      break;
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+    case kTypedDataFloat32x4ArrayCid:
+    case kTypedDataInt32x4ArrayCid:
+    case kTypedDataFloat64x2ArrayCid: {
+      intptr_t value_check_cid = kDoubleCid;
+      Representation rep = kUnboxedDouble;
+      switch (array_cid) {
+        case kTypedDataFloat32x4ArrayCid:
+          value_check_cid = kFloat32x4Cid;
+          rep = kUnboxedFloat32x4;
+          break;
+        case kTypedDataInt32x4ArrayCid:
+          value_check_cid = kInt32x4Cid;
+          rep = kUnboxedInt32x4;
+          break;
+        case kTypedDataFloat64x2ArrayCid:
+          value_check_cid = kFloat64x2Cid;
+          rep = kUnboxedFloat64x2;
+          break;
+        default:
+          // Float32/Float64 case already handled.
+          break;
+      }
+      const ICData& value_check = ICData::ZoneHandle(ICData::New(
+          flow_graph->function(),
+          Symbols::Empty(),  // Dummy function name.
+          Object::empty_array(),  // Dummy args. descr.
+          Thread::kNoDeoptId,
+          1,
+          false));
+      value_check.AddReceiverCheck(value_check_cid, flow_graph->function());
+      builder.AddInstruction(
+          new CheckClassInstr(new Value(value),
+                              Thread::kNoDeoptId,
+                              value_check,
+                              builder.TokenPos()));
+      value = builder.AddUnboxInstr(rep,
+                                    new Value(value),
+                                    /* is_checked = */ true);
+      if (array_cid == kTypedDataFloat32ArrayCid) {
+        value = builder.AddDefinition(
+            new DoubleToFloatInstr(new Value(value), Thread::kNoDeoptId));
+      }
+      break;
+    }
+    default:
+      UNREACHABLE();
+  }
+
+  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+    array = builder.AddDefinition(
+      new LoadUntaggedInstr(new Value(array),
+                            ExternalTypedData::data_offset()));
+  }
+  // No store barrier.
+  ASSERT(RawObject::IsExternalTypedDataClassId(array_cid) ||
+         RawObject::IsTypedDataClassId(array_cid));
   builder.AddInstruction(
       new StoreIndexedInstr(new Value(array),
                             new Value(index),
-                            new Value(double_value),
+                            new Value(value),
                             kNoStoreBarrier,
-                            8,  // index scale
-                            kTypedDataFloat64ArrayCid,
+                            Instance::ElementSizeFor(array_cid),  // index scale
+                            array_cid,
                             Thread::kNoDeoptId,
                             builder.TokenPos()));
   // Return null.
@@ -636,34 +588,116 @@
 }
 
 
-bool Intrinsifier::Build_Float64ArrayGetIndexed(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
-    return false;
-  }
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* index = builder.AddParameter(1);
-  Definition* array = builder.AddParameter(2);
-
-  PrepareIndexedOp(&builder, array, index, TypedData::length_offset());
-
-  Definition* unboxed_value = builder.AddDefinition(
-      new LoadIndexedInstr(new Value(array),
-                           new Value(index),
-                           8,  // index scale
-                           kTypedDataFloat64ArrayCid,
-                           Thread::kNoDeoptId,
-                           builder.TokenPos()));
-  Definition* result = builder.AddDefinition(
-      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value)));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
+#define DEFINE_ARRAY_GETTER_INTRINSIC(enum_name)                               \
+bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) {      \
+  return IntrinsifyArrayGetIndexed(                                            \
+      flow_graph,                                                              \
+      MethodRecognizer::MethodKindToReceiverCid(                               \
+          MethodRecognizer::k##enum_name##GetIndexed));                        \
 }
 
 
+#define DEFINE_ARRAY_SETTER_INTRINSIC(enum_name)                               \
+bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) {      \
+  return IntrinsifyArraySetIndexed(                                            \
+      flow_graph,                                                              \
+      MethodRecognizer::MethodKindToReceiverCid(                               \
+          MethodRecognizer::k##enum_name##SetIndexed));                        \
+}
+
+DEFINE_ARRAY_GETTER_INTRINSIC(ObjectArray)  // Setter in intrinsifier_<arch>.cc.
+DEFINE_ARRAY_GETTER_INTRINSIC(ImmutableArray)
+
+#define DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                       \
+DEFINE_ARRAY_GETTER_INTRINSIC(enum_name)                                       \
+DEFINE_ARRAY_SETTER_INTRINSIC(enum_name)
+
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int8Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint8Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(ExternalUint8Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint8ClampedArray)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(ExternalUint8ClampedArray)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int16Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint16Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int32Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint32Array)
+
+#undef DEFINE_ARRAY_GETTER_SETTER_INTRINSICS
+#undef DEFINE_ARRAY_GETTER_INTRINSIC
+#undef DEFINE_ARRAY_SETTER_INTRINSIC
+
+
+#define DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC(enum_name)                         \
+bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) {      \
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {                          \
+    return false;                                                              \
+  }                                                                            \
+  return IntrinsifyArrayGetIndexed(                                            \
+      flow_graph,                                                              \
+      MethodRecognizer::MethodKindToReceiverCid(                               \
+          MethodRecognizer::k##enum_name##GetIndexed));                        \
+}
+
+
+#define DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name)                         \
+bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) {      \
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {                          \
+    return false;                                                              \
+  }                                                                            \
+  return IntrinsifyArraySetIndexed(                                            \
+      flow_graph,                                                              \
+      MethodRecognizer::MethodKindToReceiverCid(                               \
+          MethodRecognizer::k##enum_name##SetIndexed));                        \
+}
+
+#define DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                 \
+DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC(enum_name)                                 \
+DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name)
+
+DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float64Array)
+DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float32Array)
+
+#undef DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS
+#undef DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC
+#undef DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC
+
+
+#define DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name)                          \
+bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) {      \
+  if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {                          \
+    return false;                                                              \
+  }                                                                            \
+  return IntrinsifyArrayGetIndexed(                                            \
+      flow_graph,                                                              \
+      MethodRecognizer::MethodKindToReceiverCid(                               \
+          MethodRecognizer::k##enum_name##GetIndexed));                        \
+}
+
+
+#define DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name)                          \
+bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) {      \
+  if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {                          \
+    return false;                                                              \
+  }                                                                            \
+  return IntrinsifyArraySetIndexed(                                            \
+      flow_graph,                                                              \
+      MethodRecognizer::MethodKindToReceiverCid(                               \
+          MethodRecognizer::k##enum_name##SetIndexed));                        \
+}
+
+#define DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                 \
+DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name)                                 \
+DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name)
+
+DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float32x4Array)
+DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Int32x4Array)
+DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float64x2Array)
+
+#undef DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS
+#undef DEFINE_SIMD_ARRAY_GETTER_INTRINSIC
+#undef DEFINE_SIMD_ARRAY_SETTER_INTRINSIC
+
+
 static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) {
   GraphEntryInstr* graph_entry = flow_graph->graph_entry();
   TargetEntryInstr* normal_entry = graph_entry->normal_entry();
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 2daafed..7e9dc7c 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -521,7 +521,6 @@
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label fall_through;
-  __ Push(R6);
   TestBothArgumentsSmis(assembler, &fall_through);
   __ CompareImmediate(R0, Smi::RawValue(Smi::kBits));
   __ b(&fall_through, HI);
@@ -549,10 +548,10 @@
   __ 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
+  __ rsb(R3, R0, Operand(32));  // R3 <- 32 - R0
+  __ mov(NOTFP, Operand(NOTFP, LSL, R3));  // NOTFP <- NOTFP << R3
   __ and_(NOTFP, R1, Operand(NOTFP));  // NOTFP <- NOTFP & R1
-  __ mov(NOTFP, Operand(NOTFP, LSR, R6));  // NOTFP <- NOTFP >> R6
+  __ mov(NOTFP, Operand(NOTFP, LSR, R3));  // NOTFP <- NOTFP >> R3
   // Now NOTFP has the bits that fall off of R1 on a left shift.
   __ mov(R1, Operand(R1, LSL, R0));  // R1 gets the low bits.
 
@@ -563,11 +562,8 @@
 
   __ str(R1, FieldAddress(R0, Mint::value_offset()));
   __ str(NOTFP, FieldAddress(R0, Mint::value_offset() + kWordSize));
-  __ Pop(R6);
   __ Ret();
   __ Bind(&fall_through);
-  ASSERT(CODE_REG == R6);
-  __ Pop(R6);
 }
 
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index eee6d04..e6e1564 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -45,6 +45,7 @@
 #include "vm/timeline.h"
 #include "vm/timeline_analysis.h"
 #include "vm/timer.h"
+#include "vm/verifier.h"
 #include "vm/visitor.h"
 
 
@@ -53,9 +54,14 @@
 DECLARE_FLAG(bool, print_metrics);
 DECLARE_FLAG(bool, timing);
 DECLARE_FLAG(bool, trace_service);
-DECLARE_FLAG(bool, trace_reload);
 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
+
+// Reload flags.
 DECLARE_FLAG(bool, check_reloaded);
+DECLARE_FLAG(int, reload_every);
+DECLARE_FLAG(bool, reload_every_back_off);
+DECLARE_FLAG(bool, trace_reload);
+
 
 NOT_IN_PRODUCT(
 static void CheckedModeHandler(bool value) {
@@ -202,8 +208,10 @@
   const char* name() const;
   void MessageNotify(Message::Priority priority);
   MessageStatus HandleMessage(Message* message);
+#ifndef PRODUCT
   void NotifyPauseOnStart();
   void NotifyPauseOnExit();
+#endif  // !PRODUCT
 
 #if defined(DEBUG)
   // Check that it is safe to access this handler.
@@ -570,6 +578,7 @@
     }
   }
   delete message;
+#ifndef PRODUCT
   if (status == kOK) {
     const Object& result =
         Object::Handle(zone, I->InvokePendingServiceExtensionCalls());
@@ -579,10 +588,12 @@
       ASSERT(result.IsNull());
     }
   }
+#endif  // !PRODUCT
   return status;
 }
 
 
+#ifndef PRODUCT
 void IsolateMessageHandler::NotifyPauseOnStart() {
   if (!FLAG_support_service) {
     return;
@@ -615,6 +626,7 @@
               I->name());
   }
 }
+#endif  // !PRODUCT
 
 
 #if defined(DEBUG)
@@ -648,12 +660,6 @@
 
 MessageHandler::MessageStatus IsolateMessageHandler::ProcessUnhandledException(
     const Error& result) {
-  NOT_IN_PRODUCT(
-    if (I->IsReloading()) {
-      I->ReportReloadError(result);
-      return kOK;
-    }
-  )
   // Generate the error and stacktrace strings for the error message.
   String& exc_str = String::Handle(T->zone());
   String& stacktrace_str = String::Handle(T->zone());
@@ -815,7 +821,6 @@
       tag_table_(GrowableObjectArray::null()),
       deoptimized_code_array_(GrowableObjectArray::null()),
       sticky_error_(Error::null()),
-      sticky_reload_error_(Error::null()),
       background_compiler_(NULL),
       background_compiler_disabled_depth_(0),
       pending_service_extension_calls_(GrowableObjectArray::null()),
@@ -833,7 +838,9 @@
       spawn_count_(0),
       has_attempted_reload_(false),
       no_reload_scope_depth_(0),
-      reload_context_(NULL) {
+      reload_every_n_stack_overflow_checks_(FLAG_reload_every),
+      reload_context_(NULL),
+      last_reload_timestamp_(OS::GetCurrentTimeMillis()) {
   NOT_IN_PRODUCT(FlagsCopyFrom(api_flags));
   // TODO(asiva): A Thread is not available here, need to figure out
   // how the vm_tag (kEmbedderTagId) can be set, these tags need to
@@ -851,9 +858,11 @@
   delete heap_;
   delete object_store_;
   delete api_state_;
+#ifndef PRODUCT
   if (FLAG_support_debugger) {
     delete debugger_;
   }
+#endif  // !PRODUCT
 #if defined(USING_SIMULATOR)
   delete simulator_;
 #endif
@@ -871,9 +880,11 @@
   message_handler_ = NULL;  // Fail fast if we send messages to a dead isolate.
   ASSERT(deopt_context_ == NULL);  // No deopt in progress when isolate deleted.
   delete spawn_state_;
+#ifndef PRODUCT
   if (FLAG_support_service) {
     delete object_id_ring_;
   }
+#endif  // !PRODUCT
   object_id_ring_ = NULL;
   delete pause_loop_monitor_;
   pause_loop_monitor_ = NULL;
@@ -954,9 +965,11 @@
     }
   }
 
+#ifndef PRODUCT
   if (FLAG_support_service) {
     ObjectIdRing::Init(result);
   }
+#endif  // !PRODUCT
 
   // Add to isolate list. Shutdown and delete the isolate on failure.
   if (!AddIsolateToList(result)) {
@@ -970,6 +983,12 @@
 }
 
 
+Thread* Isolate::mutator_thread() const {
+  ASSERT(thread_registry() != NULL);
+  return thread_registry()->mutator_thread();
+}
+
+
 void Isolate::SetupInstructionsSnapshotPage(
     const uint8_t* instructions_snapshot_buffer) {
   InstructionsSnapshot snapshot(instructions_snapshot_buffer);
@@ -1054,8 +1073,9 @@
 
 bool Isolate::CanReload() const {
 #ifndef PRODUCT
-  return (!ServiceIsolate::IsServiceIsolateDescendant(this) &&
-          is_runnable() && !IsReloading() && no_reload_scope_depth_ == 0);
+  return !ServiceIsolate::IsServiceIsolateDescendant(this) &&
+         is_runnable() && !IsReloading() && (no_reload_scope_depth_ == 0) &&
+         IsolateCreationEnabled();
 #else
   return false;
 #endif
@@ -1063,42 +1083,46 @@
 
 
 #ifndef PRODUCT
-void Isolate::ReportReloadError(const Error& error) {
-  ASSERT(IsReloading());
-  reload_context_->AbortReload(error);
+bool Isolate::ReloadSources(JSONStream* js,
+                            bool force_reload,
+                            bool dont_delete_reload_context) {
+  ASSERT(!IsReloading());
+  has_attempted_reload_ = true;
+  reload_context_ = new IsolateReloadContext(this, js);
+  reload_context_->Reload(force_reload);
+  bool success = !reload_context_->reload_aborted();
+  if (!dont_delete_reload_context) {
+    DeleteReloadContext();
+  }
+#if defined(DEBUG)
+  if (success) {
+    return success;
+    Thread* thread = Thread::Current();
+    Isolate* isolate = thread->isolate();
+    isolate->heap()->CollectAllGarbage();
+    VerifyCanonicalVisitor check_canonical(thread);
+    isolate->heap()->IterateObjects(&check_canonical);
+  }
+#endif  // DEBUG
+  return success;
+}
+
+
+void Isolate::DeleteReloadContext() {
+  // Another thread may be in the middle of GetClassForHeapWalkAt.
+  Thread* thread = Thread::Current();
+  SafepointOperationScope safepoint_scope(thread);
+
   delete reload_context_;
   reload_context_ = NULL;
 }
-
-
-void Isolate::ReloadSources(bool test_mode) {
-  ASSERT(!IsReloading());
-  has_attempted_reload_ = true;
-  reload_context_ = new IsolateReloadContext(this, test_mode);
-  reload_context_->StartReload();
-}
-
-#endif
+#endif  // !PRODUCT
 
 
 void Isolate::DoneFinalizing() {
   NOT_IN_PRODUCT(
     if (IsReloading()) {
-      reload_context_->FinishReload();
-      if (reload_context_->has_error() && reload_context_->test_mode()) {
-        // If the reload has an error and we are in test mode keep the reload
-        // context on the isolate so that it can be used by unit tests.
-        return;
-      }
-      if (reload_context_->has_error()) {
-        // Remember the reload error.
-        sticky_reload_error_ = reload_context_->error();
-      }
-      if (!reload_context_->has_error()) {
-        reload_context_->ReportSuccess();
-      }
-      delete reload_context_;
-      reload_context_ = NULL;
+      reload_context_->FinalizeLoading();
     }
   )
 }
@@ -1117,11 +1141,13 @@
   // isolate on thread pool for execution.
   ASSERT(object_store()->root_library() != Library::null());
   set_is_runnable(true);
+#ifndef PRODUCT
   if (FLAG_support_debugger && !ServiceIsolate::IsServiceIsolate(this)) {
     if (FLAG_pause_isolates_on_unhandled_exceptions) {
       debugger()->SetExceptionPauseInfo(kPauseOnUnhandledExceptions);
     }
   }
+#endif  // !PRODUCT
   IsolateSpawnState* state = spawn_state();
   if (state != NULL) {
     ASSERT(this == state->isolate());
@@ -1137,11 +1163,11 @@
       event->Complete();
     }
   }
-#endif  // !PRODUCT
   if (FLAG_support_service && Service::isolate_stream.enabled()) {
     ServiceEvent runnableEvent(this, ServiceEvent::kIsolateRunnable);
     Service::HandleEvent(&runnableEvent);
   }
+#endif  // !PRODUCT
   return true;
 }
 
@@ -1472,6 +1498,14 @@
     ASSERT(thread->isolate() == isolate);
     StackZone zone(thread);
     HandleScope handle_scope(thread);
+    // TODO(27003): Enable for precompiled.
+#if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME)
+    if (!isolate->HasAttemptedReload()) {
+      isolate->heap()->CollectAllGarbage();
+      VerifyCanonicalVisitor check_canonical(thread);
+      isolate->heap()->IterateObjects(&check_canonical);
+    }
+#endif  // DEBUG
     const Error& error = Error::Handle(thread->sticky_error());
     if (!error.IsNull() && !error.IsUnwindError()) {
       OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
@@ -1483,6 +1517,13 @@
 }
 
 
+void Isolate::SetStickyError(RawError* sticky_error) {
+  ASSERT(sticky_error_ == Error::null());
+  sticky_error_ = sticky_error;
+  message_handler()->PausedOnExit(true);
+}
+
+
 void Isolate::Run() {
   message_handler()->Run(Dart::thread_pool(),
                          RunIsolate,
@@ -1624,13 +1665,13 @@
   }
   if (FLAG_print_metrics) {
     LogBlock lb;
-    THR_Print("Printing metrics for %s\n", name());
+    OS::PrintErr("Printing metrics for %s\n", name());
 #define ISOLATE_METRIC_PRINT(type, variable, name, unit)                       \
-  THR_Print("%s\n", metric_##variable##_.ToString());
+  OS::PrintErr("%s\n", metric_##variable##_.ToString());
 
     ISOLATE_METRIC_LIST(ISOLATE_METRIC_PRINT);
 #undef ISOLATE_METRIC_PRINT
-    THR_Print("\n");
+    OS::PrintErr("\n");
   }
 }
 
@@ -1643,6 +1684,21 @@
 }
 
 
+void Isolate::MaybeIncreaseReloadEveryNStackOverflowChecks() {
+  if (FLAG_reload_every_back_off) {
+    if (reload_every_n_stack_overflow_checks_ < 5000) {
+      reload_every_n_stack_overflow_checks_ += 99;
+    } else {
+      reload_every_n_stack_overflow_checks_ *= 2;
+    }
+    // Cap the value.
+    if (reload_every_n_stack_overflow_checks_ > 1000000) {
+      reload_every_n_stack_overflow_checks_ = 1000000;
+    }
+  }
+}
+
+
 void Isolate::Shutdown() {
   ASSERT(this == Isolate::Current());
   StopBackgroundCompiler();
@@ -1697,7 +1753,7 @@
     }
   }
 
-  if (FLAG_check_reloaded &&
+  if (FLAG_check_reloaded && is_runnable() &&
       (this != Dart::vm_isolate()) &&
       !ServiceIsolate::IsServiceIsolateDescendant(this)) {
     if (!HasAttemptedReload()) {
@@ -1776,9 +1832,6 @@
   visitor->VisitPointer(
         reinterpret_cast<RawObject**>(&sticky_error_));
 
-  visitor->VisitPointer(
-        reinterpret_cast<RawObject**>(&sticky_reload_error_));
-
   // Visit the pending service extension calls.
   visitor->VisitPointer(
       reinterpret_cast<RawObject**>(&pending_service_extension_calls_));
@@ -1893,36 +1946,35 @@
   jsobj.AddProperty("pauseOnExit", message_handler()->should_pause_on_exit());
   jsobj.AddProperty("_isReloading", IsReloading());
 
-  if (debugger() != NULL) {
-    if (!is_runnable()) {
-      // Isolate is not yet runnable.
-      ASSERT(debugger()->PauseEvent() == NULL);
-      ServiceEvent pause_event(this, ServiceEvent::kNone);
-      jsobj.AddProperty("pauseEvent", &pause_event);
-    } else if (message_handler()->is_paused_on_start() ||
-               message_handler()->should_pause_on_start()) {
-      ASSERT(debugger()->PauseEvent() == NULL);
-      ServiceEvent pause_event(this, ServiceEvent::kPauseStart);
-      jsobj.AddProperty("pauseEvent", &pause_event);
-    } else if (message_handler()->is_paused_on_exit()) {
-      ASSERT(debugger()->PauseEvent() == NULL);
-      ServiceEvent pause_event(this, ServiceEvent::kPauseExit);
-      jsobj.AddProperty("pauseEvent", &pause_event);
-    } else if (debugger()->PauseEvent() != NULL && !resume_request_) {
-      jsobj.AddProperty("pauseEvent", debugger()->PauseEvent());
-    } else {
-      ServiceEvent pause_event(this, ServiceEvent::kResume);
+  if (!is_runnable()) {
+    // Isolate is not yet runnable.
+    ASSERT((debugger() == NULL) || (debugger()->PauseEvent() == NULL));
+    ServiceEvent pause_event(this, ServiceEvent::kNone);
+    jsobj.AddProperty("pauseEvent", &pause_event);
+  } else if (message_handler()->is_paused_on_start() ||
+             message_handler()->should_pause_on_start()) {
+    ASSERT((debugger() == NULL) || (debugger()->PauseEvent() == NULL));
+    ServiceEvent pause_event(this, ServiceEvent::kPauseStart);
+    jsobj.AddProperty("pauseEvent", &pause_event);
+  } else if (message_handler()->is_paused_on_exit()) {
+    ASSERT((debugger() == NULL) || (debugger()->PauseEvent() == NULL));
+    ServiceEvent pause_event(this, ServiceEvent::kPauseExit);
+    jsobj.AddProperty("pauseEvent", &pause_event);
+  } else if ((debugger() != NULL) &&
+             (debugger()->PauseEvent() != NULL) &&
+             !resume_request_) {
+    jsobj.AddProperty("pauseEvent", debugger()->PauseEvent());
+  } else {
+    ServiceEvent pause_event(this, ServiceEvent::kResume);
 
+    if (debugger() != NULL) {
       // TODO(turnidge): Don't compute a full stack trace.
       DebuggerStackTrace* stack = debugger()->StackTrace();
       if (stack->Length() > 0) {
         pause_event.set_top_frame(stack->FrameAt(0));
       }
-      jsobj.AddProperty("pauseEvent", &pause_event);
     }
-
-    jsobj.AddProperty("exceptionPauseMode",
-        ExceptionPauseInfoToServiceEnum(debugger()->GetExceptionPauseInfo()));
+    jsobj.AddProperty("pauseEvent", &pause_event);
   }
 
   const Library& lib =
@@ -1931,7 +1983,7 @@
     jsobj.AddProperty("rootLib", lib);
   }
 
-  {
+  if (FLAG_profiler) {
     JSONObject tagCounters(&jsobj, "_tagCounters");
     vm_tag_counters()->PrintToJSONObject(&tagCounters);
   }
@@ -1959,16 +2011,22 @@
     }
   }
 
-  if (debugger() != NULL) {
-    {
-      JSONArray breakpoints(&jsobj, "breakpoints");
+  {
+    JSONArray breakpoints(&jsobj, "breakpoints");
+    if (debugger() != NULL) {
       debugger()->PrintBreakpointsToJSONArray(&breakpoints);
     }
+  }
 
-    {
-      JSONObject jssettings(&jsobj, "_debuggerSettings");
-      debugger()->PrintSettingsToJSONObject(&jssettings);
-    }
+  Dart_ExceptionPauseInfo pause_info = (debugger() != NULL)
+      ? debugger()->GetExceptionPauseInfo()
+      : kNoPauseOnExceptions;
+  jsobj.AddProperty("exceptionPauseMode",
+                    ExceptionPauseInfoToServiceEnum(pause_info));
+
+  if (debugger() != NULL) {
+    JSONObject settings(&jsobj, "_debuggerSettings");
+    debugger()->PrintSettingsToJSONObject(&settings);
   }
 
   {
@@ -2034,11 +2092,6 @@
 }
 
 
-void Isolate::clear_sticky_reload_error() {
-  sticky_reload_error_ = Error::null();
-}
-
-
 void Isolate::set_pending_service_extension_calls(
       const GrowableObjectArray& value) {
   pending_service_extension_calls_ = value.raw();
@@ -2081,6 +2134,7 @@
 }
 
 
+#ifndef PRODUCT
 RawObject* Isolate::InvokePendingServiceExtensionCalls() {
   if (!FLAG_support_service) {
     return Object::null();
@@ -2261,6 +2315,7 @@
   }
   return Instance::null();
 }
+#endif  // !PRODUCT
 
 
 void Isolate::WakePauseEventHandler(Dart_Isolate isolate) {
@@ -2403,6 +2458,12 @@
 }
 
 
+bool Isolate::IsolateCreationEnabled() {
+  MonitorLocker ml(isolates_list_monitor_);
+  return creation_enabled_;
+}
+
+
 void Isolate::KillLocked(LibMsgId msg_id) {
   Dart_CObject kill_msg;
   Dart_CObject* list_values[4];
@@ -2525,9 +2586,14 @@
     // no_safepoint_scope_depth increments/decrements.
     MonitorLocker ml(threads_lock(), false);
 
+    // Check to make sure we don't already have a mutator thread.
+    if (is_mutator && mutator_thread_ != NULL) {
+      return NULL;
+    }
+
     // If a safepoint operation is in progress wait for it
     // to finish before scheduling this thread in.
-    while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) {
+    while (!bypass_safepoint && safepoint_handler()->SafepointInProgress()) {
       ml.Wait();
     }
 
@@ -2540,7 +2606,8 @@
     ASSERT(heap() != NULL);
     thread->heap_ = heap();
     thread->set_os_thread(os_thread);
-    ASSERT(thread->execution_state() == Thread::kThreadInVM);
+    ASSERT(thread->execution_state() == Thread::kThreadInNative);
+    thread->set_execution_state(Thread::kThreadInVM);
     thread->set_safepoint_state(0);
     thread->set_vm_tag(VMTag::kVMTagId);
     ASSERT(thread->no_safepoint_scope_depth() == 0);
@@ -2591,8 +2658,8 @@
   thread->isolate_ = NULL;
   thread->heap_ = NULL;
   thread->set_os_thread(NULL);
-  thread->set_execution_state(Thread::kThreadInVM);
-  thread->set_safepoint_state(0);
+  thread->set_execution_state(Thread::kThreadInNative);
+  thread->set_safepoint_state(Thread::SetAtSafepoint(true, 0));
   thread->clear_pending_functions();
   ASSERT(thread->no_safepoint_scope_depth() == 0);
   // Return thread structure.
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 7f1df6d..12dd5fa 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -177,15 +177,7 @@
     message_notify_callback_ = value;
   }
 
-  // Limited public access to BaseIsolate::mutator_thread_ for code that
-  // must treat the mutator as the default or a special case. Prefer code
-  // that works uniformly across all threads.
-  bool HasMutatorThread() {
-    return mutator_thread_ != NULL;
-  }
-  Thread* mutator_thread() const {
-    return mutator_thread_;
-  }
+  Thread* mutator_thread() const;
 
   const char* name() const { return name_; }
   const char* debugger_name() const { return debugger_name_; }
@@ -255,7 +247,11 @@
   void DoneLoading();
   void DoneFinalizing();
 
-  void ReloadSources(bool test_mode = false);
+  // By default the reload context is deleted. This parameter allows
+  // the caller to delete is separately if it is still needed.
+  bool ReloadSources(JSONStream* js,
+                     bool force_reload,
+                     bool dont_delete_reload_context = false);
 
   bool MakeRunnable();
   void Run();
@@ -464,8 +460,7 @@
 
   // Mutator thread is used to aggregate compiler stats.
   CompilerStats* aggregate_compiler_stats() {
-    ASSERT(HasMutatorThread());
-    return mutator_thread_->compiler_stats();
+    return mutator_thread()->compiler_stats();
   }
 
   VMTagCounters* vm_tag_counters() {
@@ -480,13 +475,20 @@
     return reload_context_;
   }
 
+  void DeleteReloadContext();
+
   bool HasAttemptedReload() const {
     return has_attempted_reload_;
   }
 
   bool CanReload() const;
 
-  void ReportReloadError(const Error& error);
+  void set_last_reload_timestamp(int64_t value) {
+    last_reload_timestamp_ = value;
+  }
+  int64_t last_reload_timestamp() const {
+    return last_reload_timestamp_;
+  }
 
   uword user_tag() const {
     return user_tag_;
@@ -533,12 +535,12 @@
   void set_deoptimized_code_array(const GrowableObjectArray& value);
   void TrackDeoptimizedCode(const Code& code);
 
+  // Also sends a paused at exit event over the service protocol.
+  void SetStickyError(RawError* sticky_error);
+
   RawError* sticky_error() const { return sticky_error_; }
   void clear_sticky_error();
 
-  RawError* sticky_reload_error() const { return sticky_reload_error_; }
-  void clear_sticky_reload_error();
-
   bool compilation_allowed() const { return compilation_allowed_; }
   void set_compilation_allowed(bool allowed) {
     compilation_allowed_ = allowed;
@@ -553,7 +555,7 @@
   // True during top level parsing.
   bool IsTopLevelParsing() {
     const intptr_t value =
-        AtomicOperations::LoadRelaxedIntPtr(&top_level_parsing_count_);
+        AtomicOperations::LoadRelaxed(&top_level_parsing_count_);
     ASSERT(value >= 0);
     return value > 0;
   }
@@ -574,7 +576,7 @@
     }
   }
   intptr_t loading_invalidation_gen() {
-    return AtomicOperations::LoadRelaxedIntPtr(&loading_invalidation_gen_);
+    return AtomicOperations::LoadRelaxed(&loading_invalidation_gen_);
   }
 
   // Used by background compiler which field became boxed and must trigger
@@ -583,6 +585,7 @@
   // Returns Field::null() if none available in the list.
   RawField* GetDeoptimizingBoxedField();
 
+#ifndef PRODUCT
   RawObject* InvokePendingServiceExtensionCalls();
   void AppendServiceExtensionCall(const Instance& closure,
                            const String& method_name,
@@ -593,6 +596,7 @@
   void RegisterServiceExtensionHandler(const String& name,
                                        const Instance& closure);
   RawInstance* LookupServiceExtensionHandler(const String& name);
+#endif
 
   static void VisitIsolates(IsolateVisitor* visitor);
 
@@ -629,9 +633,16 @@
 
   static void DisableIsolateCreation();
   static void EnableIsolateCreation();
+  static bool IsolateCreationEnabled();
 
   void StopBackgroundCompiler();
 
+  intptr_t reload_every_n_stack_overflow_checks() const {
+    return reload_every_n_stack_overflow_checks_;
+  }
+
+  void MaybeIncreaseReloadEveryNStackOverflowChecks();
+
  private:
   friend class Dart;  // Init, InitOnce, Shutdown.
   friend class IsolateKillerVisitor;  // Kill().
@@ -680,8 +691,8 @@
   // 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();
+    ASSERT(Thread::Current() == mutator_thread());
+    return mutator_thread()->zone();
   }
 
   // Accessed from generated code:
@@ -759,8 +770,6 @@
 
   RawError* sticky_error_;
 
-  RawError* sticky_reload_error_;
-
   // Background compilation.
   BackgroundCompiler* background_compiler_;
   intptr_t background_compiler_disabled_depth_;
@@ -815,7 +824,10 @@
   // Has a reload ever been attempted?
   bool has_attempted_reload_;
   intptr_t no_reload_scope_depth_;  // we can only reload when this is 0.
+  // Per-isolate copy of FLAG_reload_every.
+  intptr_t reload_every_n_stack_overflow_checks_;
   IsolateReloadContext* reload_context_;
+  int64_t last_reload_timestamp_;
 
 #define ISOLATE_METRIC_VARIABLE(type, variable, name, unit)                    \
   type metric_##variable##_;
@@ -825,7 +837,6 @@
 
   static Dart_IsolateCreateCallback create_callback_;
   static Dart_IsolateShutdownCallback shutdown_callback_;
-  static Dart_IsolateInterruptCallback vmstats_callback_;
 
   static void WakePauseEventHandler(Dart_Isolate isolate);
 
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 15aaf29..2b00272 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -5,6 +5,7 @@
 #include "vm/isolate_reload.h"
 
 #include "vm/become.h"
+#include "vm/bit_vector.h"
 #include "vm/code_generator.h"
 #include "vm/compiler.h"
 #include "vm/dart_api_impl.h"
@@ -24,11 +25,15 @@
 namespace dart {
 
 DEFINE_FLAG(bool, trace_reload, false, "Trace isolate reloading");
+DEFINE_FLAG(bool, trace_reload_verbose, false,
+            "trace isolate reloading verbose");
 DEFINE_FLAG(bool, identity_reload, false, "Enable checks for identity reload.");
 DEFINE_FLAG(int, reload_every, 0, "Reload every N stack overflow checks.");
 DEFINE_FLAG(bool, reload_every_optimized, true, "Only from optimized code.");
 DEFINE_FLAG(bool, reload_every_back_off, false,
             "Double the --reload-every value after each reload.");
+DEFINE_FLAG(bool, reload_force_rollback, false,
+            "Force all reloads to fail and rollback.");
 DEFINE_FLAG(bool, check_reloaded, false,
             "Assert that an isolate has reloaded at least once.")
 #ifndef PRODUCT
@@ -42,6 +47,192 @@
                                    #name)
 
 
+InstanceMorpher::InstanceMorpher(Zone* zone, const Class& from, const Class& to)
+    : from_(Class::Handle(zone, from.raw())),
+      to_(Class::Handle(zone, to.raw())),
+      mapping_(zone, 0) {
+  ComputeMapping();
+  before_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0);
+  after_ = new(zone) ZoneGrowableArray<const Instance*>(zone, 0);
+  ASSERT(from_.id() == to_.id());
+  cid_ = from_.id();
+}
+
+
+void InstanceMorpher::AddObject(RawObject* object) const {
+  ASSERT(object->GetClassId() == cid());
+  const Instance& instance = Instance::Cast(Object::Handle(object));
+  before_->Add(&instance);
+}
+
+
+void InstanceMorpher::ComputeMapping() {
+  if (from_.NumTypeArguments()) {
+    // Add copying of the optional type argument field.
+    intptr_t from_offset = from_.type_arguments_field_offset();
+    ASSERT(from_offset != Class::kNoTypeArguments);
+    intptr_t to_offset = to_.type_arguments_field_offset();
+    ASSERT(to_offset != Class::kNoTypeArguments);
+    mapping_.Add(from_offset);
+    mapping_.Add(to_offset);
+  }
+
+  // Add copying of the instance fields if matching by name.
+  // Note: currently the type of the fields are ignored.
+  const Array& from_fields = Array::Handle(from_.OffsetToFieldMap());
+  const Array& to_fields = Array::Handle(to_.OffsetToFieldMap());
+  Field& from_field = Field::Handle();
+  Field& to_field = Field::Handle();
+  String& from_name = String::Handle();
+  String& to_name = String::Handle();
+  for (intptr_t i = 0; i < from_fields.Length(); i++) {
+    if (from_fields.At(i) == Field::null()) continue;  // Ignore non-fields.
+    from_field = Field::RawCast(from_fields.At(i));
+    ASSERT(from_field.is_instance());
+    from_name = from_field.name();
+    // We now have to find where this field is in the to class.
+    for (intptr_t j = 0; j < to_fields.Length(); j++) {
+      if (to_fields.At(j) == Field::null()) continue;  // Ignore non-fields.
+      to_field = Field::RawCast(to_fields.At(j));
+      ASSERT(to_field.is_instance());
+      to_name = to_field.name();
+      if (from_name.Equals(to_name)) {
+        // Success
+        mapping_.Add(from_field.Offset());
+        mapping_.Add(to_field.Offset());
+      }
+    }
+  }
+}
+
+
+RawInstance* InstanceMorpher::Morph(const Instance& instance) const {
+  const Instance& result = Instance::Handle(Instance::New(to_));
+  // Morph the context from instance to result using mapping_.
+  for (intptr_t i = 0; i < mapping_.length(); i +=2) {
+    intptr_t from_offset = mapping_.At(i);
+    intptr_t to_offset = mapping_.At(i+1);
+    const Object& value =
+        Object::Handle(instance.RawGetFieldAtOffset(from_offset));
+    result.RawSetFieldAtOffset(to_offset, value);
+  }
+  // Convert the instance into a filler object.
+  Become::MakeDummyObject(instance);
+  return result.raw();
+}
+
+
+void InstanceMorpher::CreateMorphedCopies() const {
+  for (intptr_t i = 0; i < before()->length(); i++) {
+    const Instance& copy = Instance::Handle(Morph(*before()->At(i)));
+    after()->Add(&copy);
+  }
+}
+
+
+void InstanceMorpher::DumpFormatFor(const Class& cls) const {
+  THR_Print("%s\n", cls.ToCString());
+  if (cls.NumTypeArguments()) {
+    intptr_t field_offset = cls.type_arguments_field_offset();
+    ASSERT(field_offset != Class::kNoTypeArguments);
+    THR_Print("  - @%" Pd " <type arguments>\n", field_offset);
+  }
+  const Array& fields = Array::Handle(cls.OffsetToFieldMap());
+  Field& field = Field::Handle();
+  String& name = String::Handle();
+  for (intptr_t i = 0; i < fields.Length(); i++) {
+    if (fields.At(i) != Field::null()) {
+      field = Field::RawCast(fields.At(i));
+      ASSERT(field.is_instance());
+      name = field.name();
+      THR_Print("  - @%" Pd " %s\n", field.Offset(), name.ToCString());
+    }
+  }
+
+  THR_Print("Mapping: ");
+  for (int i = 0; i < mapping_.length(); i +=2) {
+    THR_Print(" %" Pd "->%" Pd,  mapping_.At(i),  mapping_.At(i+1));
+  }
+  THR_Print("\n");
+}
+
+
+void InstanceMorpher::Dump() const {
+  LogBlock blocker;
+  THR_Print("Morphing from ");
+  DumpFormatFor(from_);
+  THR_Print("To ");
+  DumpFormatFor(to_);
+  THR_Print("\n");
+}
+
+
+void InstanceMorpher::AppendTo(JSONArray* array) {
+  JSONObject jsobj(array);
+  jsobj.AddProperty("type", "ShapeChangeMapping");
+  jsobj.AddProperty("class", to_);
+  jsobj.AddProperty("instanceCount", before()->length());
+  JSONArray map(&jsobj, "fieldOffsetMappings");
+  for (int i = 0; i < mapping_.length(); i += 2) {
+    JSONArray pair(&map);
+    pair.AddValue(mapping_.At(i));
+    pair.AddValue(mapping_.At(i+1));
+  }
+}
+
+
+void ReasonForCancelling::Report(IsolateReloadContext* context) {
+  const Error& error = Error::Handle(ToError());
+  context->ReportError(error);
+}
+
+
+RawError* ReasonForCancelling::ToError() {
+  // By default create the error returned from ToString.
+  const String& message = String::Handle(ToString());
+  return LanguageError::New(message);
+}
+
+
+RawString* ReasonForCancelling::ToString() {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+void ReasonForCancelling::AppendTo(JSONArray* array) {
+  JSONObject jsobj(array);
+  jsobj.AddProperty("type", "ReasonForCancelling");
+  const String& message = String::Handle(ToString());
+  jsobj.AddProperty("message", message.ToCString());
+}
+
+
+ClassReasonForCancelling::ClassReasonForCancelling(Zone* zone,
+                                                   const Class& from,
+                                                   const Class& to)
+    : ReasonForCancelling(zone),
+      from_(Class::ZoneHandle(zone, from.raw())),
+      to_(Class::ZoneHandle(zone, to.raw())) {
+}
+
+
+void ClassReasonForCancelling::AppendTo(JSONArray* array) {
+  JSONObject jsobj(array);
+  jsobj.AddProperty("type", "ReasonForCancelling");
+  jsobj.AddProperty("class", from_);
+  const String& message = String::Handle(ToString());
+  jsobj.AddProperty("message", message.ToCString());
+}
+
+
+RawError* IsolateReloadContext::error() const {
+  ASSERT(reload_aborted());
+  // Report the first error to the surroundings.
+  return reasons_to_cancel_reload_.At(0)->ToError();
+}
+
+
 class ScriptUrlSetTraits {
  public:
   static bool ReportStats() { return false; }
@@ -117,6 +308,8 @@
       return String::HashRawSymbol(Class::Cast(obj).Name());
     } else if (obj.IsField()) {
       return String::HashRawSymbol(Field::Cast(obj).name());
+    } else if (obj.IsInstance()) {
+      return Smi::Handle(Smi::RawCast(Instance::Cast(obj).HashCode())).Value();
     }
     return 0;
   }
@@ -150,15 +343,15 @@
   // TODO(turnidge): We need to look at generic type arguments for
   // synthetic mixin classes.  Their names are not necessarily unique
   // currently.
-  const String& a_name = String::Handle(Class::Cast(a).Name());
-  const String& b_name = String::Handle(Class::Cast(b).Name());
+  const String& a_name = String::Handle(a.Name());
+  const String& b_name = String::Handle(b.Name());
 
   if (!a_name.Equals(b_name)) {
     return false;
   }
 
-  const Library& a_lib = Library::Handle(Class::Cast(a).library());
-  const Library& b_lib = Library::Handle(Class::Cast(b).library());
+  const Library& a_lib = Library::Handle(a.library());
+  const Library& b_lib = Library::Handle(b.library());
   return IsSameLibrary(a_lib, b_lib);
 }
 
@@ -173,28 +366,101 @@
 }
 
 
-IsolateReloadContext::IsolateReloadContext(Isolate* isolate, bool test_mode)
-    : start_time_micros_(OS::GetCurrentMonotonicMicros()),
+IsolateReloadContext::IsolateReloadContext(Isolate* isolate,
+                                           JSONStream* js)
+    : zone_(Thread::Current()->zone()),
+      start_time_micros_(OS::GetCurrentMonotonicMicros()),
+      reload_timestamp_(OS::GetCurrentTimeMillis()),
       isolate_(isolate),
-      test_mode_(test_mode),
-      has_error_(false),
+      reload_skipped_(false),
+      reload_aborted_(false),
+      reload_finalized_(false),
+      js_(js),
       saved_num_cids_(-1),
       saved_class_table_(NULL),
       num_saved_libs_(-1),
+      instance_morphers_(zone_, 0),
+      reasons_to_cancel_reload_(zone_, 0),
+      cid_mapper_(),
+      modified_libs_(NULL),
       script_uri_(String::null()),
       error_(Error::null()),
-      clean_scripts_set_storage_(Array::null()),
-      compile_time_constants_(Array::null()),
       old_classes_set_storage_(Array::null()),
       class_map_storage_(Array::null()),
       old_libraries_set_storage_(Array::null()),
       library_map_storage_(Array::null()),
       become_map_storage_(Array::null()),
+      become_enum_mappings_(GrowableObjectArray::null()),
       saved_root_library_(Library::null()),
       saved_libraries_(GrowableObjectArray::null()) {
+  // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not
+  // associated with the isolate yet and if a GC is triggered here the raw
+  // objects will not be properly accounted for.
+  ASSERT(zone_ != NULL);
+}
+
+
+IsolateReloadContext::~IsolateReloadContext() {
+}
+
+
+void IsolateReloadContext::ReportError(const Error& error) {
+  if (FLAG_trace_reload) {
+    THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
+  }
+  ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
+  service_event.set_reload_error(&error);
+  Service::HandleEvent(&service_event);
+}
+
+
+void IsolateReloadContext::ReportSuccess() {
+  ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
+  Service::HandleEvent(&service_event);
+}
+
+
+class Aborted : public ReasonForCancelling {
+ public:
+  Aborted(Zone* zone, const Error& error)
+      : ReasonForCancelling(zone),
+        error_(Error::ZoneHandle(zone, error.raw())) {
+  }
+
+ private:
+  const Error& error_;
+
+  RawError* ToError() { return error_.raw(); }
+  RawString* ToString() {
+    return String::NewFormatted("%s", error_.ToErrorCString());
+  }
+};
+
+
+// NOTE: This function returns *after* FinalizeLoading is called.
+void IsolateReloadContext::Reload(bool force_reload) {
+  TIMELINE_SCOPE(Reload);
+  Thread* thread = Thread::Current();
+  ASSERT(isolate() == thread->isolate());
+
+  // Grab root library before calling CheckpointBeforeReload.
+  const Library& root_lib = Library::Handle(object_store()->root_library());
+  ASSERT(!root_lib.IsNull());
+  const String& root_lib_url = String::Handle(root_lib.url());
+
+  // Check to see which libraries have been modified.
+  modified_libs_ = FindModifiedLibraries(force_reload);
+  if (!modified_libs_->Contains(root_lib.index())) {
+    ASSERT(modified_libs_->IsEmpty());
+    reload_skipped_ = true;
+    ReportOnJSON(js_);
+    TIR_Print("---- SKIPPING RELOAD (No libraries were modified)\n");
+    return;
+  }
+
+  TIR_Print("---- STARTING RELOAD\n");
+
   // Preallocate storage for maps.
-  clean_scripts_set_storage_ =
-      HashTables::New<UnorderedHashSet<ScriptUrlSetTraits> >(4);
   old_classes_set_storage_ =
       HashTables::New<UnorderedHashSet<ClassMapTraits> >(4);
   class_map_storage_ =
@@ -205,53 +471,13 @@
       HashTables::New<UnorderedHashMap<LibraryMapTraits> >(4);
   become_map_storage_ =
       HashTables::New<UnorderedHashMap<BecomeMapTraits> >(4);
-}
-
-
-IsolateReloadContext::~IsolateReloadContext() {
-}
-
-
-void IsolateReloadContext::ReportError(const Error& error) {
-  has_error_ = true;
-  error_ = error.raw();
-  if (FLAG_trace_reload) {
-    THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
-  }
-  ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
-  service_event.set_reload_error(&error);
-  Service::HandleEvent(&service_event);
-}
-
-
-void IsolateReloadContext::ReportError(const String& error_msg) {
-  ReportError(LanguageError::Handle(LanguageError::New(error_msg)));
-}
-
-
-void IsolateReloadContext::ReportSuccess() {
-  ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
-  Service::HandleEvent(&service_event);
-}
-
-
-void IsolateReloadContext::StartReload() {
-  TIMELINE_SCOPE(Reload);
-  Thread* thread = Thread::Current();
-
-  // Grab root library before calling CheckpointBeforeReload.
-  const Library& root_lib = Library::Handle(object_store()->root_library());
-  ASSERT(!root_lib.IsNull());
-  const String& root_lib_url = String::Handle(root_lib.url());
+  // Keep a separate array for enum mappings to avoid having to invoke
+  // hashCode on the instances.
+  become_enum_mappings_ = GrowableObjectArray::New(Heap::kOld);
 
   // Disable the background compiler while we are performing the reload.
   BackgroundCompiler::Disable();
 
-  if (FLAG_write_protect_code) {
-    // Disable code page write protection while we are reloading.
-    I->heap()->WriteProtectCode(false);
-  }
-
   // Ensure all functions on the stack have unoptimized code.
   EnsuredUnoptimizedCodeForStack();
   // Deoptimize all code that had optimizing decisions that are dependent on
@@ -261,6 +487,25 @@
   DeoptimizeDependentCode();
   Checkpoint();
 
+  // WEIRD CONTROL FLOW BEGINS.
+  //
+  // The flow of execution until we return from the tag handler can be complex.
+  //
+  // On a successful load, the following will occur:
+  //   1) Tag Handler is invoked and the embedder is in control.
+  //   2) All sources and libraries are loaded.
+  //   3) Dart_FinalizeLoading is called by the embedder.
+  //   4) Dart_FinalizeLoading invokes IsolateReloadContext::FinalizeLoading
+  //      and we are temporarily back in control.
+  //      This is where we validate the reload and commit or reject.
+  //   5) Dart_FinalizeLoading invokes Dart code related to deferred libraries.
+  //   6) The tag handler returns and we move on.
+  //
+  // Even after a successful reload the Dart code invoked in (5) can result
+  // in an Unwind error or an UnhandledException error. This error will be
+  // returned by the tag handler. The tag handler can return other errors,
+  // for example, top level parse errors. We want to capture these errors while
+  // propagating the UnwindError or an UnhandledException error.
   Object& result = Object::Handle(thread->zone());
   {
     TransitionVMToNative transition(thread);
@@ -272,8 +517,22 @@
                                    Api::NewHandle(thread, root_lib_url.raw()));
     result = Api::UnwrapHandle(retval);
   }
+  //
+  // WEIRD CONTROL FLOW ENDS.
+
+  BackgroundCompiler::Enable();
+
+  if (result.IsUnwindError() ||
+      result.IsUnhandledException()) {
+    // If the tag handler returns with an UnwindError or an UnhandledException
+    // error, propagate it and give up.
+    Exceptions::PropagateError(Error::Cast(result));
+    UNREACHABLE();
+  }
+
+  // Other errors (e.g. a parse error) are captured by the reload system.
   if (result.IsError()) {
-    ReportError(Error::Cast(result));
+    FinalizeFailedLoad(Error::Cast(result));
   }
 }
 
@@ -304,32 +563,87 @@
 }
 
 
-void IsolateReloadContext::FinishReload() {
+// FinalizeLoading will be called *before* Reload() returns but will not be
+// called if the embedder fails to load sources.
+void IsolateReloadContext::FinalizeLoading() {
+  if (reload_skipped_) {
+    return;
+  }
+  ASSERT(!reload_finalized_);
   BuildLibraryMapping();
-  TIR_Print("---- DONE FINALIZING\n");
+  TIR_Print("---- LOAD SUCCEEDED\n");
   if (ValidateReload()) {
     Commit();
     PostCommit();
+    isolate()->set_last_reload_timestamp(reload_timestamp_);
   } else {
+    ReportReasonsForCancelling();
     Rollback();
   }
   // ValidateReload mutates the direct subclass information and does
   // not remove dead subclasses.  Rebuild the direct subclass
   // information from scratch.
   RebuildDirectSubclasses();
-
-  if (FLAG_write_protect_code) {
-    // Disable code page write protection while we are reloading.
-    I->heap()->WriteProtectCode(true);
-  }
-
-  BackgroundCompiler::Enable();
+  CommonFinalizeTail();
 }
 
 
-void IsolateReloadContext::AbortReload(const Error& error) {
-  ReportError(error);
-  Rollback();
+// FinalizeFailedLoad will be called *before* Reload() returns and will only
+// be called if the embedder fails to load sources.
+void IsolateReloadContext::FinalizeFailedLoad(const Error& error) {
+  TIR_Print("---- LOAD FAILED, ABORTING RELOAD\n");
+  AddReasonForCancelling(new Aborted(zone_, error));
+  ReportReasonsForCancelling();
+  if (!reload_finalized_) {
+    Rollback();
+  }
+  CommonFinalizeTail();
+}
+
+
+void IsolateReloadContext::CommonFinalizeTail() {
+  ReportOnJSON(js_);
+  reload_finalized_ = true;
+}
+
+
+void IsolateReloadContext::ReportOnJSON(JSONStream* stream) {
+  JSONObject jsobj(stream);
+  jsobj.AddProperty("type", "ReloadReport");
+  jsobj.AddProperty("success", reload_skipped_ || !HasReasonsForCancelling());
+  {
+    JSONObject details(&jsobj, "details");
+    if (reload_skipped_) {
+      // Reload was skipped.
+      const GrowableObjectArray& libs =
+          GrowableObjectArray::Handle(object_store()->libraries());
+      const intptr_t final_library_count = libs.Length();
+      details.AddProperty("savedLibraryCount", final_library_count);
+      details.AddProperty("loadedLibraryCount", static_cast<intptr_t>(0));
+      details.AddProperty("finalLibraryCount", final_library_count);
+    } else if (HasReasonsForCancelling()) {
+      // Reload was rejected.
+      JSONArray array(&jsobj, "notices");
+      for (intptr_t i = 0; i < reasons_to_cancel_reload_.length(); i++) {
+        ReasonForCancelling* reason = reasons_to_cancel_reload_.At(i);
+        reason->AppendTo(&array);
+      }
+    } else {
+      // Reload was successful.
+      const GrowableObjectArray& libs =
+          GrowableObjectArray::Handle(object_store()->libraries());
+      const intptr_t final_library_count = libs.Length();
+      const intptr_t loaded_library_count =
+          final_library_count - num_saved_libs_;
+      details.AddProperty("savedLibraryCount", num_saved_libs_);
+      details.AddProperty("loadedLibraryCount", loaded_library_count);
+      details.AddProperty("finalLibraryCount", final_library_count);
+      JSONArray array(&jsobj, "shapeChangeMappings");
+      for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
+        instance_morphers_.At(i)->AppendTo(&array);
+      }
+    }
+  }
 }
 
 
@@ -426,14 +740,136 @@
 }
 
 
-bool IsolateReloadContext::IsCleanLibrary(const Library& lib) {
-  return lib.is_dart_scheme();
+Dart_FileModifiedCallback IsolateReloadContext::file_modified_callback_ = NULL;
+
+
+bool IsolateReloadContext::ScriptModifiedSince(const Script& script,
+                                               int64_t since) {
+  if (file_modified_callback_ == NULL) {
+    return true;
+  }
+  // We use the resolved url to determine if the script has been modified.
+  const String& url = String::Handle(script.resolved_url());
+  const char* url_chars = url.ToCString();
+  return (*file_modified_callback_)(url_chars, since);
+}
+
+
+static void PropagateLibraryModified(
+    const ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >* imported_by,
+    intptr_t lib_index,
+    BitVector* modified_libs) {
+  ZoneGrowableArray<intptr_t>* dep_libs = (*imported_by)[lib_index];
+  for (intptr_t i = 0; i < dep_libs->length(); i++) {
+    intptr_t dep_lib_index = (*dep_libs)[i];
+    if (!modified_libs->Contains(dep_lib_index)) {
+      modified_libs->Add(dep_lib_index);
+      PropagateLibraryModified(imported_by, dep_lib_index, modified_libs);
+    }
+  }
+}
+
+
+BitVector* IsolateReloadContext::FindModifiedLibraries(bool force_reload) {
+  Thread* thread = Thread::Current();
+  int64_t last_reload = I->last_reload_timestamp();
+
+  const GrowableObjectArray& libs =
+      GrowableObjectArray::Handle(object_store()->libraries());
+  Library& lib = Library::Handle();
+  Array& scripts = Array::Handle();
+  Script& script = Script::Handle();
+  intptr_t num_libs = libs.Length();
+
+  // Construct the imported-by graph.
+  ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >* imported_by =
+      new(zone_) ZoneGrowableArray<ZoneGrowableArray<intptr_t>* >(
+          zone_, num_libs);
+  imported_by->SetLength(num_libs);
+  for (intptr_t i = 0; i < num_libs; i++) {
+    (*imported_by)[i] = new(zone_) ZoneGrowableArray<intptr_t>(zone_, 0);
+  }
+  Array& ports = Array::Handle();
+  Namespace& ns = Namespace::Handle();
+  Library& target = Library::Handle();
+
+  for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) {
+    lib ^= libs.At(lib_idx);
+    ASSERT(lib_idx == lib.index());
+    if (lib.is_dart_scheme()) {
+      // We don't care about imports among dart scheme libraries.
+      continue;
+    }
+
+    // Add imports to the import-by graph.
+    ports = lib.imports();
+    for (intptr_t import_idx = 0; import_idx < ports.Length(); import_idx++) {
+      ns ^= ports.At(import_idx);
+      if (!ns.IsNull()) {
+        target = ns.library();
+        (*imported_by)[target.index()]->Add(lib.index());
+      }
+    }
+
+    // Add exports to the import-by graph.
+    ports = lib.exports();
+    for (intptr_t export_idx = 0; export_idx < ports.Length(); export_idx++) {
+      ns ^= ports.At(export_idx);
+      if (!ns.IsNull()) {
+        target = ns.library();
+        (*imported_by)[target.index()]->Add(lib.index());
+      }
+    }
+
+    // Add prefixed imports to the import-by graph.
+    DictionaryIterator entries(lib);
+    Object& entry = Object::Handle();
+    LibraryPrefix& prefix = LibraryPrefix::Handle();
+    while (entries.HasNext()) {
+      entry = entries.GetNext();
+      if (entry.IsLibraryPrefix()) {
+        prefix ^= entry.raw();
+        ports = prefix.imports();
+        for (intptr_t import_idx = 0; import_idx < ports.Length();
+             import_idx++) {
+          ns ^= ports.At(import_idx);
+          if (!ns.IsNull()) {
+            target = ns.library();
+            (*imported_by)[target.index()]->Add(lib.index());
+          }
+        }
+      }
+    }
+  }
+
+  BitVector* modified_libs = new(Z) BitVector(Z, num_libs);
+
+  for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) {
+    lib ^= libs.At(lib_idx);
+    if (lib.is_dart_scheme() || modified_libs->Contains(lib_idx)) {
+      // We don't consider dart scheme libraries during reload.  If
+      // the modified libs set already contains this library, then we
+      // have already visited it.
+      continue;
+    }
+    scripts = lib.LoadedScripts();
+    for (intptr_t script_idx = 0; script_idx < scripts.Length(); script_idx++) {
+      script ^= scripts.At(script_idx);
+      if (force_reload || ScriptModifiedSince(script, last_reload)) {
+        modified_libs->Add(lib_idx);
+        PropagateLibraryModified(imported_by, lib_idx, modified_libs);
+        break;
+      }
+    }
+  }
+
+  return modified_libs;
 }
 
 
 void IsolateReloadContext::CheckpointLibraries() {
   TIMELINE_SCOPE(CheckpointLibraries);
-
+  TIR_Print("---- CHECKPOINTING LIBRARIES\n");
   // Save the root library in case we abort the reload.
   const Library& root_lib =
       Library::Handle(object_store()->root_library());
@@ -454,19 +890,20 @@
   num_saved_libs_ = 0;
   for (intptr_t i = 0; i < libs.Length(); i++) {
     lib ^= libs.At(i);
-    if (IsCleanLibrary(lib)) {
+    if (modified_libs_->Contains(i)) {
+      // We are going to reload this library. Clear the index.
+      lib.set_index(-1);
+    } else {
       // We are preserving this library across the reload, assign its new index
       lib.set_index(new_libs.Length());
       new_libs.Add(lib, Heap::kOld);
       num_saved_libs_++;
-    } else {
-      // We are going to reload this library. Clear the index.
-      lib.set_index(-1);
     }
     // Add old library to old libraries set.
     bool already_present = old_libraries_set.Insert(lib);
     ASSERT(!already_present);
   }
+  modified_libs_ = NULL;  // Renumbering the libraries has invalidated this.
   old_libraries_set_storage_ = old_libraries_set.Release().raw();
 
   // Reset the registered libraries to the filtered array.
@@ -476,86 +913,6 @@
 }
 
 
-void IsolateReloadContext::BuildCleanScriptSet() {
-  const GrowableObjectArray& libs =
-      GrowableObjectArray::Handle(object_store()->libraries());
-
-  UnorderedHashSet<ScriptUrlSetTraits>
-      clean_scripts_set(clean_scripts_set_storage_);
-
-  Library& lib = Library::Handle();
-  Array& scripts = Array::Handle();
-  Script& script = Script::Handle();
-  String& script_url = String::Handle();
-  for (intptr_t lib_idx = 0; lib_idx < libs.Length(); lib_idx++) {
-    lib = Library::RawCast(libs.At(lib_idx));
-    ASSERT(!lib.IsNull());
-    ASSERT(IsCleanLibrary(lib));
-    scripts = lib.LoadedScripts();
-    ASSERT(!scripts.IsNull());
-    for (intptr_t script_idx = 0; script_idx < scripts.Length(); script_idx++) {
-      script = Script::RawCast(scripts.At(script_idx));
-      ASSERT(!script.IsNull());
-      script_url = script.url();
-      ASSERT(!script_url.IsNull());
-      bool already_present = clean_scripts_set.Insert(script_url);
-      ASSERT(!already_present);
-    }
-  }
-
-  clean_scripts_set_storage_ = clean_scripts_set.Release().raw();
-}
-
-
-void IsolateReloadContext::FilterCompileTimeConstants() {
-  // Save the compile time constants array.
-  compile_time_constants_ = I->object_store()->compile_time_constants();
-  // Clear the compile time constants array. This will be repopulated
-  // in the loop below.
-  I->object_store()->set_compile_time_constants(Array::Handle());
-
-  if (compile_time_constants_ == Array::null()) {
-    // Nothing to do.
-    return;
-  }
-
-  // Iterate over the saved compile time constants map.
-  ConstantsMap old_constants(compile_time_constants_);
-  ConstantsMap::Iterator it(&old_constants);
-
-  Array& key = Array::Handle();
-  String& url = String::Handle();
-  Smi& token_pos = Smi::Handle();
-  Instance& value = Instance::Handle();
-
-  // We filter the compile time constants map so that after it only contains
-  // constants from scripts contained in this set.
-  UnorderedHashSet<ScriptUrlSetTraits>
-      clean_scripts_set(clean_scripts_set_storage_);
-
-  while (it.MoveNext()) {
-    const intptr_t entry = it.Current();
-    ASSERT(entry != -1);
-    key = Array::RawCast(old_constants.GetKey(entry));
-    ASSERT(!key.IsNull());
-    url = String::RawCast(key.At(0));
-    ASSERT(!url.IsNull());
-    if (clean_scripts_set.ContainsKey(url)) {
-      // We've found a cached constant from a clean script, add it to the
-      // compile time constants map again.
-      token_pos = Smi::RawCast(key.At(1));
-      TokenPosition tp(token_pos.Value());
-      // Use ^= because this might be null.
-      value ^= old_constants.GetPayload(entry, 0);
-      Parser::InsertCachedConstantValue(url, tp, value);
-    }
-  }
-
-  old_constants.Release();
-  clean_scripts_set.Release();
-}
-
-
 // While reloading everything we do must be reversible so that we can abort
 // safely if the reload fails. This function stashes things to the side and
 // prepares the isolate for the reload attempt.
@@ -563,8 +920,6 @@
   TIMELINE_SCOPE(Checkpoint);
   CheckpointClasses();
   CheckpointLibraries();
-  BuildCleanScriptSet();
-  FilterCompileTimeConstants();
 }
 
 
@@ -580,9 +935,13 @@
       class_table->SetAt(i, saved_class_table_[i]);
     }
   }
-  free(saved_class_table_);
+
+  RawClass** local_saved_class_table = saved_class_table_;
   saved_class_table_ = NULL;
-  saved_num_cids_ = 0;
+  // Can't free this table immediately as another thread (e.g., the sweeper) may
+  // be suspended between loading the table pointer and loading the table
+  // element. Table will be freed at the next major GC or isolate shutdown.
+  class_table->AddOldTable(local_saved_class_table);
 }
 
 
@@ -614,8 +973,7 @@
 
 
 void IsolateReloadContext::Rollback() {
-  I->object_store()->set_compile_time_constants(
-      Array::Handle(compile_time_constants_));
+  TIR_Print("---- ROLLING BACK");
   RollbackClasses();
   RollbackLibraries();
 }
@@ -659,7 +1017,16 @@
 
 void IsolateReloadContext::Commit() {
   TIMELINE_SCOPE(Commit);
-  TIR_Print("---- COMMITTING REVERSE MAP\n");
+  TIR_Print("---- COMMITTING RELOAD\n");
+
+  // Note that the object heap contains before and after instances
+  // used for morphing. It is therefore important that morphing takes
+  // place prior to any heap walking.
+  // So please keep this code at the top of Commit().
+  if (HasInstanceMorphers()) {
+    // Perform shape shifting of instances if necessary.
+    MorphInstances();
+  }
 
 #ifdef DEBUG
   VerifyMaps();
@@ -670,9 +1037,8 @@
     // Copy static field values from the old classes to the new classes.
     // Patch fields and functions in the old classes so that they retain
     // the old script.
-    Class& cls = Class::Handle();
+    Class& old_cls = Class::Handle();
     Class& new_cls = Class::Handle();
-
     UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_);
 
     {
@@ -680,14 +1046,16 @@
       while (it.MoveNext()) {
         const intptr_t entry = it.Current();
         new_cls = Class::RawCast(class_map.GetKey(entry));
-        cls = Class::RawCast(class_map.GetPayload(entry, 0));
-        if (new_cls.raw() != cls.raw()) {
-          ASSERT(new_cls.is_enum_class() == cls.is_enum_class());
+        old_cls = Class::RawCast(class_map.GetPayload(entry, 0));
+        if (new_cls.raw() != old_cls.raw()) {
+          ASSERT(new_cls.is_enum_class() == old_cls.is_enum_class());
           if (new_cls.is_enum_class() && new_cls.is_finalized()) {
-            new_cls.ReplaceEnum(cls);
+            new_cls.ReplaceEnum(old_cls);
+          } else {
+            new_cls.CopyStaticFieldValues(old_cls);
           }
-          new_cls.CopyStaticFieldValues(cls);
-          cls.PatchFieldsAndFunctions();
+          old_cls.PatchFieldsAndFunctions();
+          old_cls.MigrateImplicitStaticClosures(this, new_cls);
         }
       }
     }
@@ -729,7 +1097,7 @@
         I->object_store()->libraries());
     for (intptr_t i = 0; i < libs.Length(); i++) {
       lib = Library::RawCast(libs.At(i));
-      TIR_Print("Lib '%s' at index %" Pd "\n", lib.ToCString(), i);
+      VTIR_Print("Lib '%s' at index %" Pd "\n", lib.ToCString(), i);
       lib.set_index(i);
     }
 
@@ -743,8 +1111,11 @@
   }
 
   {
+    const GrowableObjectArray& become_enum_mappings =
+        GrowableObjectArray::Handle(become_enum_mappings_);
     UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_);
-    intptr_t replacement_count = become_map.NumOccupied();
+    intptr_t replacement_count = become_map.NumOccupied() +
+                                 become_enum_mappings.Length() / 2;
     const Array& before =
         Array::Handle(Array::New(replacement_count, Heap::kOld));
     const Array& after =
@@ -760,6 +1131,13 @@
       after.SetAt(replacement_index, obj);
       replacement_index++;
     }
+    for (intptr_t i = 0; i < become_enum_mappings.Length(); i += 2) {
+      obj = become_enum_mappings.At(i);
+      before.SetAt(replacement_index, obj);
+      obj = become_enum_mappings.At(i + 1);
+      after.SetAt(replacement_index, obj);
+      replacement_index++;
+    }
     ASSERT(replacement_index == replacement_count);
     become_map.Release();
 
@@ -801,34 +1179,153 @@
   set_saved_root_library(Library::Handle());
   set_saved_libraries(GrowableObjectArray::Handle());
   InvalidateWorld();
+  TIR_Print("---- DONE COMMIT\n");
+}
+
+
+void IsolateReloadContext::AddReasonForCancelling(ReasonForCancelling* reason) {
+  reload_aborted_ = true;
+  reasons_to_cancel_reload_.Add(reason);
+}
+
+
+void IsolateReloadContext::AddInstanceMorpher(InstanceMorpher* morpher) {
+  instance_morphers_.Add(morpher);
+  cid_mapper_.Insert(morpher);
+}
+
+
+void IsolateReloadContext::ReportReasonsForCancelling() {
+  ASSERT(FLAG_reload_force_rollback || HasReasonsForCancelling());
+  for (int i = 0; i < reasons_to_cancel_reload_.length(); i++) {
+    reasons_to_cancel_reload_.At(i)->Report(this);
+  }
+}
+
+
+// The ObjectLocator is used for collecting instances that
+// needs to be morphed.
+class ObjectLocator : public ObjectVisitor {
+ public:
+  explicit ObjectLocator(IsolateReloadContext* context)
+      : context_(context), count_(0) {
+  }
+
+  void VisitObject(RawObject* obj) {
+    InstanceMorpher* morpher =
+        context_->cid_mapper_.LookupValue(obj->GetClassId());
+    if (morpher != NULL) {
+      morpher->AddObject(obj);
+      count_++;
+    }
+  }
+
+  // Return the number of located objects for morphing.
+  intptr_t count() { return count_; }
+
+ private:
+  IsolateReloadContext* context_;
+  intptr_t count_;
+};
+
+
+void IsolateReloadContext::MorphInstances() {
+  TIMELINE_SCOPE(MorphInstances);
+  ASSERT(HasInstanceMorphers());
+  if (FLAG_trace_reload) {
+    LogBlock blocker;
+    TIR_Print("MorphInstance: \n");
+    for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
+      instance_morphers_.At(i)->Dump();
+    }
+  }
+
+  // Find all objects that need to be morphed.
+  ObjectLocator locator(this);
+  isolate()->heap()->VisitObjects(&locator);
+
+  // Return if no objects are located.
+  intptr_t count = locator.count();
+  if (count == 0) return;
+
+  TIR_Print("Found %" Pd " object%s subject to morphing.\n",
+            count, (count > 1) ? "s" : "");
+
+  Array& before = Array::Handle();
+  Array& after = Array::Handle();
+  { // Prevent GC to take place due object format confusion.
+    // Hint: More than one class share the same cid.
+    NoHeapGrowthControlScope scope;
+    for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
+      instance_morphers_.At(i)->CreateMorphedCopies();
+    }
+    // Create the inputs for Become.
+    intptr_t index = 0;
+    before = Array::New(count);
+    after = Array::New(count);
+    for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
+      InstanceMorpher* morpher = instance_morphers_.At(i);
+      for (intptr_t j = 0; j < morpher->before()->length(); j++) {
+        before.SetAt(index, *morpher->before()->At(j));
+        after.SetAt(index, *morpher->after()->At(j));
+        index++;
+      }
+    }
+    ASSERT(index == count);
+  }
+
+  // This is important: The saved class table (describing before objects)
+  // must be zapped to prevent the forwarding in GetClassForHeapWalkAt.
+  // Instance will from now be described by the isolate's class table.
+  free(saved_class_table_);
+  saved_class_table_ = NULL;
+  Become::ElementsForwardIdentity(before, after);
 }
 
 
 bool IsolateReloadContext::ValidateReload() {
   TIMELINE_SCOPE(ValidateReload);
-  if (has_error_) {
-    return false;
-  }
+  if (reload_aborted()) return false;
 
-  // Already built.
-  ASSERT(class_map_storage_ != Array::null());
-  UnorderedHashMap<ClassMapTraits> map(class_map_storage_);
-  UnorderedHashMap<ClassMapTraits>::Iterator it(&map);
-  Class& cls = Class::Handle();
-  Class& new_cls = Class::Handle();
-  while (it.MoveNext()) {
-    const intptr_t entry = it.Current();
-    new_cls = Class::RawCast(map.GetKey(entry));
-    cls = Class::RawCast(map.GetPayload(entry, 0));
-    if (new_cls.raw() != cls.raw()) {
-      if (!cls.CanReload(new_cls)) {
-        map.Release();
-        return false;
+  TIR_Print("---- VALIDATING RELOAD\n");
+
+  // Validate libraries.
+  {
+    ASSERT(library_map_storage_ != Array::null());
+    UnorderedHashMap<LibraryMapTraits> map(library_map_storage_);
+    UnorderedHashMap<LibraryMapTraits>::Iterator it(&map);
+    Library& lib = Library::Handle();
+    Library& new_lib = Library::Handle();
+    while (it.MoveNext()) {
+      const intptr_t entry = it.Current();
+      new_lib = Library::RawCast(map.GetKey(entry));
+      lib = Library::RawCast(map.GetPayload(entry, 0));
+      if (new_lib.raw() != lib.raw()) {
+        lib.CheckReload(new_lib, this);
       }
     }
+    map.Release();
   }
-  map.Release();
-  return true;
+
+  // Validate classes.
+  {
+    ASSERT(class_map_storage_ != Array::null());
+    UnorderedHashMap<ClassMapTraits> map(class_map_storage_);
+    UnorderedHashMap<ClassMapTraits>::Iterator it(&map);
+    Class& cls = Class::Handle();
+    Class& new_cls = Class::Handle();
+    while (it.MoveNext()) {
+      const intptr_t entry = it.Current();
+      new_cls = Class::RawCast(map.GetKey(entry));
+      cls = Class::RawCast(map.GetPayload(entry, 0));
+      if (new_cls.raw() != cls.raw()) {
+        cls.CheckReload(new_cls, this);
+      }
+    }
+    map.Release();
+  }
+
+  return !FLAG_reload_force_rollback && !HasReasonsForCancelling();
 }
 
 
@@ -838,10 +1335,11 @@
 
 
 RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
-  if (saved_class_table_ != NULL) {
+  RawClass** class_table = AtomicOperations::LoadRelaxed(&saved_class_table_);
+  if (class_table != NULL) {
     ASSERT(cid > 0);
     ASSERT(cid < saved_num_cids_);
-    return saved_class_table_[cid];
+    return class_table[cid];
   } else {
     return isolate_->class_table()->At(cid);
   }
@@ -884,8 +1382,12 @@
 
 
 void IsolateReloadContext::ResetUnoptimizedICsOnStack() {
-  Code& code = Code::Handle();
-  Function& function = Function::Handle();
+  Thread* thread = Thread::Current();
+  StackZone stack_zone(thread);
+  Zone* zone = stack_zone.GetZone();
+
+  Code& code = Code::Handle(zone);
+  Function& function = Function::Handle(zone);
   DartFrameIterator iterator;
   StackFrame* frame = iterator.NextFrame();
   while (frame != NULL) {
@@ -897,9 +1399,9 @@
       function = code.function();
       code = function.unoptimized_code();
       ASSERT(!code.IsNull());
-      code.ResetICDatas();
+      code.ResetICDatas(zone);
     } else {
-      code.ResetICDatas();
+      code.ResetICDatas(zone);
     }
     frame = iterator.NextFrame();
   }
@@ -918,13 +1420,15 @@
 class MarkFunctionsForRecompilation : public ObjectVisitor {
  public:
   MarkFunctionsForRecompilation(Isolate* isolate,
-                                IsolateReloadContext* reload_context)
+                                IsolateReloadContext* reload_context,
+                                Zone* zone)
     : ObjectVisitor(),
-      handle_(Object::Handle()),
-      owning_class_(Class::Handle()),
-      owning_lib_(Library::Handle()),
-      code_(Code::Handle()),
-      reload_context_(reload_context) {
+      handle_(Object::Handle(zone)),
+      owning_class_(Class::Handle(zone)),
+      owning_lib_(Library::Handle(zone)),
+      code_(Code::Handle(zone)),
+      reload_context_(reload_context),
+      zone_(zone) {
   }
 
   virtual void VisitObject(RawObject* obj) {
@@ -950,6 +1454,8 @@
 
       if (!stub_code) {
         if (clear_code) {
+          VTIR_Print("Marking %s for recompilation, clearning code\n",
+              func.ToCString());
           ClearAllCode(func);
         } else {
           PreserveUnoptimizedCode();
@@ -976,7 +1482,7 @@
     ASSERT(!code_.IsNull());
     // We are preserving the unoptimized code, fill all ICData arrays with
     // the sentinel values so that we have no stale type feedback.
-    code_.ResetICDatas();
+    code_.ResetICDatas(zone_);
   }
 
   bool IsFromDirtyLibrary(const Function& func) {
@@ -990,19 +1496,25 @@
   Library& owning_lib_;
   Code& code_;
   IsolateReloadContext* reload_context_;
+  Zone* zone_;
 };
 
 
 void IsolateReloadContext::MarkAllFunctionsForRecompilation() {
   TIMELINE_SCOPE(MarkAllFunctionsForRecompilation);
+  TIR_Print("---- MARKING ALL FUNCTIONS FOR RECOMPILATION\n");
+  Thread* thread = Thread::Current();
+  StackZone stack_zone(thread);
+  Zone* zone = stack_zone.GetZone();
   NoSafepointScope no_safepoint;
   HeapIterationScope heap_iteration_scope;
-  MarkFunctionsForRecompilation visitor(isolate_, this);
+  MarkFunctionsForRecompilation visitor(isolate_, this, zone);
   isolate_->heap()->VisitObjects(&visitor);
 }
 
 
 void IsolateReloadContext::InvalidateWorld() {
+  TIR_Print("---- INVALIDATING WORLD\n");
   ResetMegamorphicCaches();
   DeoptimizeFunctionsOnStack();
   ResetUnoptimizedICsOnStack();
@@ -1063,11 +1575,8 @@
 
   Library& replacement_or_new = Library::Handle();
   Library& old = Library::Handle();
-  for (intptr_t i = 0; i < libs.Length(); i++) {
+  for (intptr_t i = num_saved_libs_; i < libs.Length(); i++) {
     replacement_or_new = Library::RawCast(libs.At(i));
-    if (IsCleanLibrary(replacement_or_new)) {
-      continue;
-    }
     old ^= OldLibraryOrNull(replacement_or_new);
     if (old.IsNull()) {
       if (FLAG_identity_reload) {
@@ -1129,6 +1638,16 @@
 }
 
 
+void IsolateReloadContext::AddEnumBecomeMapping(const Object& old,
+                                                const Object& neu) {
+  const GrowableObjectArray& become_enum_mappings =
+      GrowableObjectArray::Handle(become_enum_mappings_);
+  become_enum_mappings.Add(old);
+  become_enum_mappings.Add(neu);
+  ASSERT((become_enum_mappings.Length() % 2) == 0);
+}
+
+
 void IsolateReloadContext::RebuildDirectSubclasses() {
   ClassTable* class_table = I->class_table();
   intptr_t num_cids = class_table->NumCids();
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index de6ff00..ce16bef 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -5,11 +5,15 @@
 #ifndef VM_ISOLATE_RELOAD_H_
 #define VM_ISOLATE_RELOAD_H_
 
+#include "include/dart_tools_api.h"
+
+#include "vm/hash_map.h"
 #include "vm/globals.h"
 #include "vm/growable_array.h"
 #include "vm/log.h"
 
 DECLARE_FLAG(bool, trace_reload);
+DECLARE_FLAG(bool, trace_reload_verbose);
 
 // 'Trace Isolate Reload' TIR_Print
 #if defined(_MSC_VER)
@@ -20,45 +24,140 @@
     if (FLAG_trace_reload) Log::Current()->Print(format, ##__VA_ARGS__)
 #endif
 
+// 'Verbose Trace Isolate Reload' VTIR_Print
+#if defined(_MSC_VER)
+#define VTIR_Print(format, ...) \
+    if (FLAG_trace_reload_verbose) Log::Current()->Print(format, __VA_ARGS__)
+#else
+#define VTIR_Print(format, ...) \
+    if (FLAG_trace_reload_verbose) Log::Current()->Print(format, ##__VA_ARGS__)
+#endif
+
 namespace dart {
 
+class BitVector;
 class GrowableObjectArray;
 class Isolate;
 class Library;
+class ObjectPointerVisitor;
+class ObjectStore;
 class RawError;
 class RawGrowableObjectArray;
 class RawLibrary;
 class RawObject;
 class RawString;
-class ObjectPointerVisitor;
-class ObjectStore;
+class Script;
 class UpdateClassesVisitor;
 
+
+class InstanceMorpher : public ZoneAllocated {
+ public:
+  InstanceMorpher(Zone* zone, const Class& from, const Class& to);
+  virtual ~InstanceMorpher() {}
+
+  // Called on each instance that needs to be morphed.
+  RawInstance* Morph(const Instance& instance) const;
+
+  // Adds an object to be morphed.
+  void AddObject(RawObject* object) const;
+
+  // Create the morphed objects based on the before() list.
+  void CreateMorphedCopies() const;
+
+  // Dump the state of the morpher.
+  void Dump() const;
+
+  // Append the morper info to JSON array.
+  void AppendTo(JSONArray* array);
+
+  // Returns the list of objects that need to be morphed.
+  ZoneGrowableArray<const Instance*>* before() const { return before_; }
+  // Returns the list of morphed objects (matches order in before()).
+  ZoneGrowableArray<const Instance*>* after() const { return after_; }
+
+  // Returns the cid associated with the from_ and to_ class.
+  intptr_t cid() const { return cid_; }
+
+ private:
+  const Class& from_;
+  const Class& to_;
+  ZoneGrowableArray<intptr_t> mapping_;
+  ZoneGrowableArray<const Instance*>* before_;
+  ZoneGrowableArray<const Instance*>* after_;
+  intptr_t cid_;
+
+  void ComputeMapping();
+  void DumpFormatFor(const Class& cls) const;
+};
+
+
+class ReasonForCancelling : public ZoneAllocated {
+ public:
+  explicit ReasonForCancelling(Zone* zone) {}
+  virtual ~ReasonForCancelling() {}
+
+  // Reports a reason for cancelling reload.
+  void Report(IsolateReloadContext* context);
+
+  // Conversion to a VM error object.
+  // Default implementation calls ToString.
+  virtual RawError* ToError();
+
+  // Conversion to a string object.
+  // Default implementation calls ToError.
+  virtual RawString* ToString();
+
+  // Append the reason to JSON array.
+  virtual void AppendTo(JSONArray* array);
+
+  // Concrete subclasses must override either ToError or ToString.
+};
+
+
+// Abstract class for also capturing the from_ and to_ class.
+class ClassReasonForCancelling : public ReasonForCancelling {
+ public:
+  ClassReasonForCancelling(Zone* zone, const Class& from, const Class& to);
+  void AppendTo(JSONArray* array);
+
+ protected:
+  const Class& from_;
+  const Class& to_;
+};
+
+
 class IsolateReloadContext {
  public:
-  explicit IsolateReloadContext(Isolate* isolate, bool test_mode = false);
+  explicit IsolateReloadContext(Isolate* isolate,
+                                JSONStream* js);
   ~IsolateReloadContext();
 
-  void StartReload();
-  void FinishReload();
-  void AbortReload(const Error& error);
+  void Reload(bool force_reload);
 
-  RawLibrary* saved_root_library() const;
+  // All zone allocated objects must be allocated from this zone.
+  Zone* zone() const { return zone_; }
 
-  RawGrowableObjectArray* saved_libraries() const;
+  bool reload_skipped() const { return reload_skipped_; }
+  bool reload_aborted() const { return reload_aborted_; }
+  RawError* error() const;
+  int64_t reload_timestamp() const { return reload_timestamp_; }
 
-  void ReportError(const Error& error);
-  void ReportError(const String& error_msg);
-  void ReportSuccess();
-
-  bool has_error() const { return has_error_; }
-  RawError* error() const { return error_; }
-  bool test_mode() const { return test_mode_; }
+  static Dart_FileModifiedCallback file_modified_callback() {
+    return file_modified_callback_;
+  }
+  static void SetFileModifiedCallback(Dart_FileModifiedCallback callback) {
+    file_modified_callback_ = callback;
+  }
 
   static bool IsSameField(const Field& a, const Field& b);
   static bool IsSameLibrary(const Library& a_lib, const Library& b_lib);
   static bool IsSameClass(const Class& a, const Class& b);
 
+ private:
+  RawLibrary* saved_root_library() const;
+
+  RawGrowableObjectArray* saved_libraries() const;
+
   RawClass* FindOriginalClass(const Class& cls);
 
   bool IsDirty(const Library& lib);
@@ -74,7 +173,44 @@
 
   int64_t start_time_micros() const { return start_time_micros_; }
 
- private:
+  // Tells whether there are reasons for cancelling the reload.
+  bool HasReasonsForCancelling() const {
+    return !reasons_to_cancel_reload_.is_empty();
+  }
+
+  // Record problem for this reload.
+  void AddReasonForCancelling(ReasonForCancelling* reason);
+
+  // Reports all reasons for cancelling reload.
+  void ReportReasonsForCancelling();
+
+  // Reports the deails of a reload operation.
+  void ReportOnJSON(JSONStream* stream);
+
+  // Store morphing operation.
+  void AddInstanceMorpher(InstanceMorpher* morpher);
+
+  // Tells whether instance in the heap must be morphed.
+  bool HasInstanceMorphers() const {
+    return !instance_morphers_.is_empty();
+  }
+
+  // NOTE: FinalizeLoading will be called *before* Reload() returns. This
+  // function will not be called if the embedder does not call
+  // Dart_FinalizeLoading.
+  void FinalizeLoading();
+
+  // NOTE: FinalizeFailedLoad will be called *before* Reload returns. This
+  // function will not be called if the embedder calls Dart_FinalizeLoading.
+  void FinalizeFailedLoad(const Error& error);
+
+  // Called by both FinalizeLoading and FinalizeFailedLoad.
+  void CommonFinalizeTail();
+
+  // Report back through the observatory channels.
+  void ReportError(const Error& error);
+  void ReportSuccess();
+
   void set_saved_root_library(const Library& value);
 
   void set_saved_libraries(const GrowableObjectArray& value);
@@ -91,10 +227,14 @@
 
   void CheckpointClasses();
 
-  // Is |lib| a library whose sources have not changed?
-  bool IsCleanLibrary(const Library& lib);
+  bool ScriptModifiedSince(const Script& script, int64_t since);
+  BitVector* FindModifiedLibraries(bool force_reload);
+
   void CheckpointLibraries();
 
+  // Transforms the heap based on instance_morphers_.
+  void MorphInstances();
+
   bool ValidateReload();
 
   void Rollback();
@@ -112,29 +252,56 @@
 
   void ClearReplacedObjectBits();
 
-  void BuildCleanScriptSet();
-  void FilterCompileTimeConstants();
-
   // atomic_install:
   void MarkAllFunctionsForRecompilation();
   void ResetUnoptimizedICsOnStack();
   void ResetMegamorphicCaches();
   void InvalidateWorld();
 
+  // The zone used for all reload related allocations.
+  Zone* zone_;
+
   int64_t start_time_micros_;
+  int64_t reload_timestamp_;
   Isolate* isolate_;
-  bool test_mode_;
-  bool has_error_;
+  bool reload_skipped_;
+  bool reload_aborted_;
+  bool reload_finalized_;
+  JSONStream* js_;
 
   intptr_t saved_num_cids_;
   RawClass** saved_class_table_;
-
   intptr_t num_saved_libs_;
+
+  // Collect the necessary instance transformation for schema changes.
+  ZoneGrowableArray<InstanceMorpher*> instance_morphers_;
+
+  // Collects the reasons for cancelling the reload.
+  ZoneGrowableArray<ReasonForCancelling*> reasons_to_cancel_reload_;
+
+  // Required trait for the cid_mapper_;
+  struct MorpherTrait {
+    typedef InstanceMorpher* Value;
+    typedef intptr_t Key;
+    typedef InstanceMorpher* Pair;
+
+    static Key KeyOf(Pair kv) { return kv->cid(); }
+    static Value ValueOf(Pair kv) { return kv; }
+    static intptr_t Hashcode(Key key) { return key; }
+    static bool IsKeyEqual(Pair kv, Key key) { return kv->cid() == key; }
+  };
+
+  // Hash map from cid to InstanceMorpher.
+  DirectChainedHashMap<MorpherTrait> cid_mapper_;
+
   struct LibraryInfo {
     bool dirty;
   };
   MallocGrowableArray<LibraryInfo> library_infos_;
 
+  // A bit vector indicating which of the original libraries were modified.
+  BitVector* modified_libs_;
+
   RawClass* OldClassOrNull(const Class& replacement_or_new);
 
   RawLibrary* OldLibraryOrNull(const Library& replacement_or_new);
@@ -148,7 +315,8 @@
 
   void AddStaticFieldMapping(const Field& old_field, const Field& new_field);
 
-  void AddBecomeMapping(const Object& old, const Object& nue);
+  void AddBecomeMapping(const Object& old, const Object& neu);
+  void AddEnumBecomeMapping(const Object& old, const Object& neu);
 
   void RebuildDirectSubclasses();
 
@@ -158,19 +326,24 @@
   RawObject** from() { return reinterpret_cast<RawObject**>(&script_uri_); }
   RawString* script_uri_;
   RawError* error_;
-  RawArray* clean_scripts_set_storage_;
-  RawArray* compile_time_constants_;
   RawArray* old_classes_set_storage_;
   RawArray* class_map_storage_;
   RawArray* old_libraries_set_storage_;
   RawArray* library_map_storage_;
   RawArray* become_map_storage_;
+  RawGrowableObjectArray* become_enum_mappings_;
   RawLibrary* saved_root_library_;
   RawGrowableObjectArray* saved_libraries_;
   RawObject** to() { return reinterpret_cast<RawObject**>(&saved_libraries_); }
 
   friend class Isolate;
-  friend class Class;  // AddStaticFieldMapping.
+  friend class Class;  // AddStaticFieldMapping, AddEnumBecomeMapping.
+  friend class Library;
+  friend class ObjectLocator;
+  friend class MarkFunctionsForRecompilation;  // IsDirty.
+  friend class ReasonForCancelling;
+
+  static Dart_FileModifiedCallback file_modified_callback_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index aa8f188..018ed1c 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -65,7 +65,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(10, SimpleInvoke(lib, "main"));
 }
 
@@ -83,7 +82,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(4, SimpleInvoke(lib, "main"));
 
   const char* kReloadScript =
@@ -99,7 +97,6 @@
 
   Dart_Handle result = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_ERROR(result, "unexpected token");
-
   EXPECT_EQ(4, SimpleInvoke(lib, "main"));
 }
 
@@ -114,7 +111,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("init()=old value,value=old value",
                SimpleInvokeStr(lib, "main"));
 
@@ -128,7 +124,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("init()=new value,value=old value",
                SimpleInvokeStr(lib, "main"));
 }
@@ -149,7 +144,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("antediluvian!", SimpleInvokeStr(lib, "main"));
 
   // Remove the original closure from the source code.  The closure is
@@ -166,7 +160,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("postapocalyptic!", SimpleInvokeStr(lib, "main"));
 }
 
@@ -180,7 +173,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("value1=10", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -192,9 +184,7 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
-  EXPECT_STREQ("value1=10,value2=20",
-               SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("value1=10,value2=20", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -210,7 +200,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(44, SimpleInvoke(lib, "main"));
 
   const char* kReloadScript =
@@ -224,7 +213,8 @@
       "}\n";
 
   lib = TestCase::ReloadTestScript(kReloadScript);
-  EXPECT_ERROR(lib, "Number of instance fields changed");
+  EXPECT_VALID(lib);
+  EXPECT_EQ(44, SimpleInvoke(lib, "main"));
 }
 
 
@@ -241,7 +231,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(44, SimpleInvoke(lib, "main"));
 
   const char* kReloadScript =
@@ -256,7 +245,8 @@
       "}\n";
 
   lib = TestCase::ReloadTestScript(kReloadScript);
-  EXPECT_ERROR(lib, "Number of instance fields changed");
+  EXPECT_VALID(lib);
+  EXPECT_EQ(44, SimpleInvoke(lib, "main"));
 }
 
 
@@ -273,7 +263,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(44, SimpleInvoke(lib, "main"));
 
   const char* kReloadScript =
@@ -286,7 +275,8 @@
       "}\n";
 
   lib = TestCase::ReloadTestScript(kReloadScript);
-  EXPECT_ERROR(lib, "Number of instance fields changed");
+  EXPECT_VALID(lib);
+  EXPECT_EQ(44, SimpleInvoke(lib, "main"));
 }
 
 
@@ -298,7 +288,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("hello", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -312,7 +301,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("hello from A", SimpleInvokeStr(lib, "main"));
 }
 
@@ -325,7 +313,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_ERROR(SimpleInvokeError(lib, "main"), "max");;
 
   const char* kReloadScript =
@@ -336,7 +323,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(4, SimpleInvoke(lib, "main"));
 }
 
@@ -350,7 +336,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(4, SimpleInvoke(lib, "main"));
 
   const char* kReloadScript =
@@ -420,7 +405,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("saved:20 new:20", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -435,7 +419,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("saved:20 new:10", SimpleInvokeStr(lib, "main"));
 }
 
@@ -454,7 +437,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("saved:20 new:20", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -471,7 +453,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("saved:20 new:10", SimpleInvokeStr(lib, "main"));
 }
 
@@ -489,7 +470,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("(true/false, true/true)", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -505,7 +485,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("(true/true, false/true)", SimpleInvokeStr(lib, "main"));
 }
 
@@ -525,7 +504,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Instance of 'B<A>'", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -539,11 +517,108 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Instance of 'B<A>'", SimpleInvokeStr(lib, "main"));
 }
 
 
+TEST_CASE(IsolateReload_TypeIdentity) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class T { }\n"
+      "getType() => T;\n"
+      "main() {\n"
+      "  var oldType = getType();\n"
+      "  reloadTest();\n"
+      "  var newType = getType();\n"
+      "  return identical(oldType, newType).toString();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class T extends Stopwatch { }\n"
+      "getType() => T;\n"
+      "main() {\n"
+      "  var oldType = getType();\n"
+      "  reloadTest();\n"
+      "  var newType = getType();\n"
+      "  return identical(oldType, newType).toString();\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("true", SimpleInvokeStr(lib, "main"));
+}
+
+
+TEST_CASE(IsolateReload_TypeIdentityGeneric) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class T<G> { }\n"
+      "getType() => new T<int>().runtimeType;\n"
+      "main() {\n"
+      "  var oldType = getType();\n"
+      "  reloadTest();\n"
+      "  var newType = getType();\n"
+      "  return identical(oldType, newType).toString();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class T<G> extends Stopwatch { }\n"
+      "getType() => new T<int>().runtimeType;\n"
+      "main() {\n"
+      "  var oldType = getType();\n"
+      "  reloadTest();\n"
+      "  var newType = getType();\n"
+      "  return identical(oldType, newType).toString();\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("true", SimpleInvokeStr(lib, "main"));
+}
+
+
+TEST_CASE(IsolateReload_TypeIdentityParameter) {
+  const char* kScript =
+      "import 'dart:mirrors';\n"
+      "import 'test:isolate_reload_helper';\n"
+      "class T<G> { }\n"
+      "getTypeVar() => reflectType(T).typeVariables[0];\n"
+      "main() {\n"
+      "  var oldType = getTypeVar();\n"
+      "  reloadTest();\n"
+      "  var newType = getTypeVar();\n"
+      "  return (oldType == newType).toString();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'dart:mirrors';\n"
+      "import 'test:isolate_reload_helper';\n"
+      "class T<G> extends Stopwatch { }\n"
+      "getTypeVar() => reflectType(T).typeVariables[0];\n"
+      "main() {\n"
+      "  var oldType = getTypeVar();\n"
+      "  reloadTest();\n"
+      "  var newType = getTypeVar();\n"
+      "  return (oldType == newType).toString();\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("true", SimpleInvokeStr(lib, "main"));
+}
+
+
 TEST_CASE(IsolateReload_MixinChanged) {
   const char* kScript =
       "class Mixin1 {\n"
@@ -559,7 +634,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("saved:field=mixin1,func=mixin1",
                SimpleInvokeStr(lib, "main"));
 
@@ -609,7 +683,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("(a is A(true)/ B(false)/ C(false),"
                " b is A(true)/ B(true)/ C(false),"
                " c is A(true)/ B(true)/ C(true))",
@@ -636,7 +709,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("(a is A(true)/ C(true)/ X(true),"
                " b is A(true)/ C(true)/ X(true),"  // still extends A...
                " c is A(false)/ C(true)/ X(false),"
@@ -669,7 +741,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript2);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("(a is A(true)/ B(false)/ C(false)/ X(true),"
                " b is A(false)/ B(true)/ C(false)/ X(true),"
                " c is A(true)/ B(false)/ C(true)/ X(true),"
@@ -708,59 +779,62 @@
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-
   EXPECT_EQ(105, SimpleInvoke(lib, "main"));
 }
 
 
 TEST_CASE(IsolateReload_LibraryLookup) {
+  const char* kImportScript =
+      "importedFunc() => 'a';\n";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
   const char* kScript =
       "main() {\n"
       "  return importedFunc();\n"
       "}\n";
-
   Dart_Handle result;
-
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_ERROR(SimpleInvokeError(lib, "main"), "importedFunc");
 
-  // Fail to find 'test:importable_lib' in the isolate.
-  result = Dart_LookupLibrary(NewString("test:importable_lib"));
+  // Fail to find 'test:lib1' in the isolate.
+  result = Dart_LookupLibrary(NewString("test:lib1"));
   EXPECT(Dart_IsError(result));
 
   const char* kReloadScript =
-      "import 'test:importable_lib';\n"
+      "import 'test:lib1';\n"
       "main() {\n"
       "  return importedFunc();\n"
       "}\n";
 
-  // Reload and add 'test:importable_lib' to isolate.
+  // Reload and add 'test:lib1' to isolate.
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("a", SimpleInvokeStr(lib, "main"));
 
-  // Find 'test:importable_lib' in the isolate.
-  result = Dart_LookupLibrary(NewString("test:importable_lib"));
+  // Find 'test:lib1' in the isolate.
+  result = Dart_LookupLibrary(NewString("test:lib1"));
   EXPECT(Dart_IsLibrary(result));
 
   // Reload and remove 'dart:math' from isolate.
   lib = TestCase::ReloadTestScript(kScript);
   EXPECT_VALID(lib);
 
-  // Fail to find 'test:importable_lib' in the isolate.
-  result = Dart_LookupLibrary(NewString("test:importable_lib"));
+  // Fail to find 'test:lib1' in the isolate.
+  result = Dart_LookupLibrary(NewString("test:lib1"));
   EXPECT(Dart_IsError(result));
 }
 
 
 TEST_CASE(IsolateReload_LibraryHide) {
-  // Import 'test:importable_lib' with importedFunc hidden. Will result in an
+  const char* kImportScript =
+      "importedFunc() => 'a';\n";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
+  // Import 'test:lib1' with importedFunc hidden. Will result in an
   // error.
   const char* kScript =
-      "import 'test:importable_lib' hide importedFunc;\n"
+      "import 'test:lib1' hide importedFunc;\n"
       "main() {\n"
       "  return importedFunc();\n"
       "}\n";
@@ -769,28 +843,31 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_ERROR(SimpleInvokeError(lib, "main"), "importedFunc");
 
-  // Import 'test:importable_lib'.
+  // Import 'test:lib1'.
   const char* kReloadScript =
-      "import 'test:importable_lib';\n"
+      "import 'test:lib1';\n"
       "main() {\n"
       "  return importedFunc();\n"
       "}\n";
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("a", SimpleInvokeStr(lib, "main"));
 }
 
 
 TEST_CASE(IsolateReload_LibraryShow) {
-  // Import 'test:importable_lib' with importedIntFunc visible. Will result in
+  const char* kImportScript =
+      "importedFunc() => 'a';\n"
+      "importedIntFunc() => 4;\n";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
+  // Import 'test:lib1' with importedIntFunc visible. Will result in
   // an error when 'main' is invoked.
   const char* kScript =
-      "import 'test:importable_lib' show importedIntFunc;\n"
+      "import 'test:lib1' show importedIntFunc;\n"
       "main() {\n"
       "  return importedFunc();\n"
       "}\n"
@@ -807,10 +884,10 @@
   // Results in an error.
   EXPECT_ERROR(SimpleInvokeError(lib, "main"), "importedFunc");
 
-  // Import 'test:importable_lib' with importedFunc visible. Will result in
+  // Import 'test:lib1' with importedFunc visible. Will result in
   // an error when 'mainInt' is invoked.
   const char* kReloadScript =
-      "import 'test:importable_lib' show importedFunc;\n"
+      "import 'test:lib1' show importedFunc;\n"
       "main() {\n"
       "  return importedFunc();\n"
       "}\n"
@@ -831,9 +908,13 @@
 // Verifies that we clear the ICs for the functions live on the stack in a way
 // that is compatible with the fast path smi stubs.
 TEST_CASE(IsolateReload_SmiFastPathStubs) {
+  const char* kImportScript =
+      "importedIntFunc() => 4;\n";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
   const char* kScript =
       "import 'test:isolate_reload_helper';\n"
-      "import 'test:importable_lib' show importedIntFunc;\n"
+      "import 'test:lib1' show importedIntFunc;\n"
       "main() {\n"
       "  var x = importedIntFunc();\n"
       "  var y = importedIntFunc();\n"
@@ -855,8 +936,14 @@
 // Verifies that we assign the correct patch classes for imported
 // mixins when we reload.
 TEST_CASE(IsolateReload_ImportedMixinFunction) {
+  const char* kImportScript =
+      "class ImportedMixin {\n"
+      "  mixinFunc() => 'mixin';\n"
+      "}\n";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
   const char* kScript =
-      "import 'test:importable_lib' show ImportedMixin;\n"
+      "import 'test:lib1' show ImportedMixin;\n"
       "class A extends Object with ImportedMixin {\n"
       "}"
       "var func = new A().mixinFunc;\n"
@@ -870,7 +957,7 @@
   EXPECT_STREQ("mixin", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
-      "import 'test:importable_lib' show ImportedMixin;\n"
+      "import 'test:lib1' show ImportedMixin;\n"
       "class A extends Object with ImportedMixin {\n"
       "}"
       "var func;\n"
@@ -880,7 +967,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("mixin", SimpleInvokeStr(lib, "main"));
 }
 
@@ -893,7 +979,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_EQ(4, SimpleInvoke(lib, "main"));
 
   const char* kReloadScript =
@@ -939,12 +1024,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("instance", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("instance", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-
-  EXPECT_EQ("instance", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("instance", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -980,12 +1064,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1031,12 +1114,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("okay", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("okay", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-
-  EXPECT_EQ("okay", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("okay", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1082,12 +1164,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1130,12 +1211,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1178,12 +1258,690 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
+}
 
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+
+TEST_CASE(IsolateReload_PendingSuperCall) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class S {\n"
+      "  foo() => 1;\n"
+      "}\n"
+      "class C extends S {\n"
+      "  foo() => 100;\n"
+      "  test() {\n"
+      "    var n = super.foo();\n"
+      "    reloadTest();\n"
+      "    return n + super.foo();\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  return new C().test();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class S {\n"
+      "  foo() => 10;\n"
+      "}\n"
+      "class C extends S {\n"
+      "  foo() => 100;\n"
+      "  test() {\n"
+      "    var n = super.foo();\n"
+      "    reloadTest();\n"
+      "    return n + super.foo();\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  return new C().test();\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_EQ(11, SimpleInvoke(lib, "main"));
+}
+
+
+TEST_CASE(IsolateReload_TearOff_Instance_Equality) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'old';\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f1 = c.foo;\n"
+      "  reloadTest();\n"
+      "  var f2 = c.foo;\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'new';\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f1 = c.foo;\n"
+      "  reloadTest();\n"
+      "  var f2 = c.foo;\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("new new true false", SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_TearOff_Class_Identity) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static foo() => 'old';\n"
+      "}\n"
+      "getFoo() => C.foo;\n"
+      "main() {\n"
+      "  var f1 = getFoo();\n"
+      "  reloadTest();\n"
+      "  var f2 = getFoo();\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static foo() => 'new';\n"
+      "}\n"
+      "getFoo() => C.foo;\n"
+      "main() {\n"
+      "  var f1 = getFoo();\n"
+      "  reloadTest();\n"
+      "  var f2 = getFoo();\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("new new true true", SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_TearOff_Library_Identity) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "foo() => 'old';\n"
+      "getFoo() => foo;\n"
+      "main() {\n"
+      "  var f1 = getFoo();\n"
+      "  reloadTest();\n"
+      "  var f2 = getFoo();\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "foo() => 'new';\n"
+      "getFoo() => foo;\n"
+      "main() {\n"
+      "  var f1 = getFoo();\n"
+      "  reloadTest();\n"
+      "  var f2 = getFoo();\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("new new true true", SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_TearOff_List_Set) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'old';\n"
+      "}\n"
+      "List list = new List(2);\n"
+      "Set set = new Set();\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  list[0] = c.foo;\n"
+      "  list[1] = c#foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countBefore = set.length;\n"
+      "  reloadTest();\n"
+      "  list[1] = c.foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countAfter = set.length;\n"
+      "  return '${list[0]()} ${list[1]()} ${list[0] == list[1]} '\n"
+      "         '${countBefore == 1} ${countAfter == 1} ${(set.first)()} '\n"
+      "         '${set.first == c.foo} ${set.first == c#foo} '\n"
+      "         '${set.remove(c#foo)}';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'new';\n"
+      "}\n"
+      "List list = new List(2);\n"
+      "Set set = new Set();\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  list[0] = c.foo;\n"
+      "  list[1] = c#foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countBefore = set.length;\n"
+      "  reloadTest();\n"
+      "  list[1] = c.foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countAfter = set.length;\n"
+      "  return '${list[0]()} ${list[1]()} ${list[0] == list[1]} '\n"
+      "         '${countBefore == 1} ${countAfter == 1} ${(set.first)()} '\n"
+      "         '${set.first == c.foo} ${set.first == c#foo} '\n"
+      "         '${set.remove(c#foo)}';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("new new true true true new true true true",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_DanglingGetter_Instance) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  var x = 3;\n"
+      "  var y = 4;\n"
+      "}\n"
+      "invoke(f) {\n"
+      "  try {\n"
+      "    return f();\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f = c#y;\n"
+      "  var r1 = invoke(f);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  var x = 3;\n"
+      "}\n"
+      "invoke(f) {\n"
+      "  try {\n"
+      "    return f();\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f = c#y;\n"
+      "  var r1 = invoke(f);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("4 Class 'C' has no instance getter 'y'.",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_DanglingGetter_Class) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static var x;\n"
+      "  static var y;\n"
+      "}\n"
+      "invoke(f) {\n"
+      "  try {\n"
+      "    return f();\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  C.x = 3;\n"
+      "  C.y = 4;\n"
+      "  var f = C#y;\n"
+      "  var r1 = invoke(f);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static var x;\n"
+      "}\n"
+      "invoke(f) {\n"
+      "  try {\n"
+      "    return f();\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  C.x = 3;\n"
+      "  C.y = 4;\n"
+      "  var f = C#y;\n"
+      "  var r1 = invoke(f);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("4 No static getter 'y' declared in class 'C'.",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+static void IsolateReload_DanlingGetter_LibraryReload(
+    Dart_NativeArguments native_args) {
+  const char* kImportScript2 =
+    "var x;\n";
+  TestCase::AddTestLib("test:other", kImportScript2);
+
+  DART_CHECK_VALID(TestCase::TriggerReload());
+}
+
+
+static Dart_NativeFunction IsolateReload_DanlingGetter_LibraryNativeResolver(
+    Dart_Handle name,
+    int num_of_arguments,
+    bool* auto_setup_scope) {
+  return IsolateReload_DanlingGetter_LibraryReload;
+}
+
+
+TEST_CASE(IsolateReload_DanglingGetter_Library) {
+  const char* kImportScript =
+      "var x;\n"
+      "var y;\n";
+  TestCase::AddTestLib("test:other", kImportScript);
+
+  const char* kScript =
+      "import 'test:other' as prefix;\n"
+      "reloadTest() native 'ReloadTest';\n"
+      "invoke(f) {\n"
+      "  try {\n"
+      "    return f();\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  prefix.x = 3;\n"
+      "  prefix.y = 4;\n"
+      "  var f = prefix#y;\n"
+      "  var r1 = invoke(f);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(
+      kScript, IsolateReload_DanlingGetter_LibraryNativeResolver);
+  EXPECT_VALID(lib);
+
+  TestCase::SetReloadTestScript(kScript);  // Root library does not change.
+
+  EXPECT_STREQ("4 No top-level getter 'y' declared.",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_DanglingSetter_Instance) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  var x = 3;\n"
+      "  var y = 4;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f = c#y=;\n"
+      "  var r1 = invoke(f, 5);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 6);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  var x = 3;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f = c#y=;\n"
+      "  var r1 = invoke(f, 5);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 6);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("null Class 'C' has no instance setter 'y='.",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_DanglingSetter_Class) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static var x;\n"
+      "  static var y;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  C.x = 3;\n"
+      "  C.y = 4;\n"
+      "  var f = C#y=;\n"
+      "  var r1 = invoke(f, 5);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 6);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static var x;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  C.x = 3;\n"
+      "  C.y = 4;\n"
+      "  var f = C#y=;\n"
+      "  var r1 = invoke(f, 5);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 6);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("5 No static setter 'y=' declared in class 'C'.",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+static void IsolateReload_DanlingSetter_LibraryReload(
+    Dart_NativeArguments native_args) {
+  const char* kImportScript2 =
+    "var x;\n";
+  TestCase::AddTestLib("test:other", kImportScript2);
+
+  DART_CHECK_VALID(TestCase::TriggerReload());
+}
+
+
+static Dart_NativeFunction IsolateReload_DanlingSetter_LibraryNativeResolver(
+    Dart_Handle name,
+    int num_of_arguments,
+    bool* auto_setup_scope) {
+  return IsolateReload_DanlingSetter_LibraryReload;
+}
+
+
+TEST_CASE(IsolateReload_DanglingSetter_Library) {
+  const char* kImportScript =
+      "var x;\n"
+      "var y;\n";
+  TestCase::AddTestLib("test:other", kImportScript);
+
+  const char* kScript =
+      "import 'test:other' as prefix;\n"
+      "reloadTest() native 'ReloadTest';\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  prefix.x = 3;\n"
+      "  prefix.y = 4;\n"
+      "  var f = prefix#y=;\n"
+      "  var r1 = invoke(f, 5);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 6);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(
+      kScript, IsolateReload_DanlingSetter_LibraryNativeResolver);
+  EXPECT_VALID(lib);
+
+  TestCase::SetReloadTestScript(kScript);  // Root library does not change.
+
+  EXPECT_STREQ("5 No top-level setter 'y=' declared.",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_TearOff_AddArguments) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo(x) => x;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f = c#foo;\n"
+      "  var r1 = invoke(f, 1);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 1);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo(x, y, z) => x + y + z;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f = c#foo;\n"
+      "  var r1 = invoke(f, 1);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 1);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("1 Class 'C' has no instance method 'foo' with matching"
+               " arguments.", SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_TearOff_AddArguments2) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static foo(x) => x;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var f = C#foo;\n"
+      "  var r1 = invoke(f, 1);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 1);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  static foo(x, y, z) => x + y + z;\n"
+      "}\n"
+      "invoke(f, a) {\n"
+      "  try {\n"
+      "    return f(a);\n"
+      "  } catch (e) {\n"
+      "    return e.toString().split('\\n').first;\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  var f = C#foo;\n"
+      "  var r1 = invoke(f, 1);\n"
+      "  reloadTest();\n"
+      "  var r2 = invoke(f, 1);\n"
+      "  return '$r1 $r2';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("1 Closure call with mismatched arguments: function 'C.foo'",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
 }
 
 
@@ -1220,7 +1978,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("yes", SimpleInvokeStr(lib, "main"));
 }
 
@@ -1239,7 +1996,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -1258,7 +2014,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("yes", SimpleInvokeStr(lib, "main"));
 }
 
@@ -1277,7 +2032,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -1296,7 +2050,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("yes", SimpleInvokeStr(lib, "main"));
 }
 
@@ -1314,7 +2067,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -1333,7 +2085,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("0/Fruit.Apple 1/Fruit.Cantalope 2/Fruit.Banana",
                SimpleInvokeStr(lib, "main"));
 }
@@ -1350,7 +2101,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -1376,7 +2126,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("yes", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -1401,129 +2150,31 @@
       "}\n"
       "var x;\n"
       "main() {\n"
-      "  return Fruit.Apple.toString();\n"
-      "}\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
-  EXPECT_VALID(lib);
-
-  EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
-
-  // Delete 'Cantalope'.
-
-  const char* kReloadScript =
-      "enum Fruit {\n"
-      "  Apple,\n"
-      "  Banana,\n"
-      "}\n"
-      "var x;\n"
-      "main() {\n"
-      "  String r = '${Fruit.Apple.index}/${Fruit.Apple} ';\n"
-      "  r += '${Fruit.Banana.index}/${Fruit.Banana} ';\n"
-      "  r += '${Fruit.Cantalope.index}/${Fruit.Cantalope}';\n"
-      "  return r;\n"
-      "}\n";
-
-  lib = TestCase::ReloadTestScript(kReloadScript);
-  EXPECT_VALID(lib);
-
-  EXPECT_STREQ("0/Fruit.Apple 1/Fruit.Banana 2/Fruit.Cantalope",
-               SimpleInvokeStr(lib, "main"));
-}
-
-
-TEST_CASE(IsolateReload_EnumComplex) {
-  const char* kScript =
-      "enum Fruit {\n"
-      "  Apple,\n"
-      "  Banana,\n"
-      "  Cantalope,\n"
-      "}\n"
-      "var x;\n"
-      "var y;\n"
-      "var z;\n"
-      "main() {\n"
-      "  x = Fruit.Apple;\n"
-      "  y = Fruit.Banana;\n"
-      "  z = Fruit.Cantalope;\n"
-      "  return Fruit.Apple.toString();\n"
-      "}\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
-  EXPECT_VALID(lib);
-
-  EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
-
-  // Delete 'Cantalope'. Add 'Dragon'. Move 'Apple' and 'Banana'.
-
-  const char* kReloadScript =
-      "enum Fruit {\n"
-      "  Dragon,\n"
-      "  Apple,\n"
-      "  Banana,\n"
-      "}\n"
-      "var x;\n"
-      "var y;\n"
-      "var z;\n"
-      "main() {\n"
-      "  String r = '';\n"
-      "  r += '${identical(x, Fruit.Apple)}';\n"
-      "  r += ' ${identical(y, Fruit.Banana)}';\n"
-      "  r += ' ${identical(z, Fruit.Cantalope)}';\n"
-      "  r += ' ${Fruit.Dragon}';\n"
-      "  return r;\n"
-      "}\n";
-
-  lib = TestCase::ReloadTestScript(kReloadScript);
-  EXPECT_VALID(lib);
-
-  EXPECT_STREQ("true true true Fruit.Dragon", SimpleInvokeStr(lib, "main"));
-}
-
-
-TEST_CASE(IsolateReload_EnumValuesArray) {
-  const char* kScript =
-      "enum Fruit {\n"
-      "  Cantalope,\n"
-      "  Apple,\n"
-      "  Banana,\n"
-      "}\n"
-      "var x;\n"
-      "main() {\n"
       "  x = Fruit.Cantalope;\n"
       "  return Fruit.Apple.toString();\n"
       "}\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
 
-  // Delete 'Cantalope'.
+  // Delete 'Cantalope' but make sure that we can still invoke toString,
+  // and access the hashCode and index properties.
 
   const char* kReloadScript =
       "enum Fruit {\n"
+      "  Apple,\n"
       "  Banana,\n"
-      "  Apple\n"
       "}\n"
       "var x;\n"
-      "bool identityCheck(Fruit f) {\n"
-      "  return identical(Fruit.values[f.index], f);\n"
-      "}\n"
       "main() {\n"
-      "  if ((x is Fruit) && identical(x, Fruit.Cantalope)) {\n"
-      "    String r = '${identityCheck(Fruit.Apple)}';\n"
-      "    r += ' ${identityCheck(Fruit.Banana)}';\n"
-      "    r += ' ${identityCheck(Fruit.Cantalope)}';\n"
-      "    r += ' ${identityCheck(x)}';\n"
-      "    return r;\n"
-      "  }\n"
+      "  String r = '$x ${x.hashCode is int} ${x.index}';\n"
+      "  return r;\n"
       "}\n";
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
-  EXPECT_STREQ("true true true true",
+  EXPECT_STREQ("Fruit.Cantalope true 2",
                SimpleInvokeStr(lib, "main"));
 }
 
@@ -1551,7 +2202,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -1583,7 +2233,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("true true true true true true true true true ",
                SimpleInvokeStr(lib, "main"));
 }
@@ -1604,7 +2253,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Pear", SimpleInvokeStr(lib, "main"));
 
   const char* kReloadScript =
@@ -1624,7 +2272,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("yes", SimpleInvokeStr(lib, "main"));
 }
 
@@ -1646,7 +2293,6 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple Fruit.Banana", SimpleInvokeStr(lib, "main"));
 
   // Insert 'Cantalope'.
@@ -1670,7 +2316,6 @@
 
   lib = TestCase::ReloadTestScript(kReloadScript);
   EXPECT_VALID(lib);
-
   EXPECT_STREQ("Fruit.Apple Fruit.Cantalope Fruit.Banana",
                SimpleInvokeStr(lib, "main"));
 }
@@ -1859,6 +2504,526 @@
   EXPECT_STREQ("AIterator", name.ToCString());
 }
 
+
+// Tests reload succeeds when instance format changes.
+// Change: Foo {a, b, c:42}  -> Foo {c:42}
+// Validate: c keeps the value in the retained Foo object.
+TEST_CASE(IsolateReload_ChangeInstanceFormat0) {
+  const char* kScript =
+      "class Foo {\n"
+      "  var a;\n"
+      "  var b;\n"
+      "  var c;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  f = new Foo();\n"
+      "  f.c = 42;\n"
+      "  return f.c;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(42, SimpleInvoke(lib, "main"));
+
+  const char* kReloadScript =
+      "class Foo {\n"
+      "  var c;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  return f.c;\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(42, SimpleInvoke(lib, "main"));
+}
+
+
+// Tests reload succeeds when instance format changes.
+// Change: Foo {}  -> Foo {c:null}
+// Validate: c is initialized to null the retained Foo object.
+TEST_CASE(IsolateReload_ChangeInstanceFormat1) {
+  const char* kScript =
+      "class Foo {\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  f = new Foo();\n"
+      "  return 42;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(42, SimpleInvoke(lib, "main"));
+
+  const char* kReloadScript =
+      "class Foo {\n"
+      "  var c;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  return (f.c == null) ? 42: 21;\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(42, SimpleInvoke(lib, "main"));
+}
+
+// Tests reload succeeds when instance format changes.
+// Change: Foo {c:42}  -> Foo {}
+// Validate: running the after script fails.
+TEST_CASE(IsolateReload_ChangeInstanceFormat2) {
+  const char* kScript =
+      "class Foo {\n"
+      "  var c;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  f = new Foo();\n"
+      "  f.c = 42;\n"
+      "  return f.c;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(42, SimpleInvoke(lib, "main"));
+
+  const char* kReloadScript =
+      "class Foo {\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  try {\n"
+      "    return f.c;\n"
+      "  } catch (e) {\n"
+      "    return 24;\n"
+      "  }\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(24, SimpleInvoke(lib, "main"));
+}
+
+
+// Tests reload succeeds when instance format changes.
+// Change: Foo {a, b, c:42, d}  -> Foo {c:42, g}
+// Validate: c keeps the value in the retained Foo object.
+TEST_CASE(IsolateReload_ChangeInstanceFormat3) {
+  const char* kScript =
+      "class Foo<A,B> {\n"
+      "  var a;\n"
+      "  var b;\n"
+      "  var c;\n"
+      "  var d;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  f = new Foo();\n"
+      "  f.a = 1;\n"
+      "  f.b = 2;\n"
+      "  f.c = 3;\n"
+      "  f.d = 4;\n"
+      "  return f.c;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(3, SimpleInvoke(lib, "main"));
+
+  const char* kReloadScript =
+      "class Foo<A,B> {\n"
+      "  var c;\n"
+      "  var g;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  return f.c;\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(3, SimpleInvoke(lib, "main"));
+}
+
+
+// Tests reload succeeds when instance format changes.
+// Change: Bar {c:42}, Foo : Bar {d, e} -> Foo {c:42}
+// Validate: c keeps the value in the retained Foo object.
+TEST_CASE(IsolateReload_ChangeInstanceFormat4) {
+  const char* kScript =
+      "class Bar{\n"
+      "  var c;\n"
+      "}\n"
+      "class Foo extends Bar{\n"
+      "  var d;\n"
+      "  var e;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  f = new Foo();\n"
+      "  f.c = 44;\n"
+      "  return f.c;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(44, SimpleInvoke(lib, "main"));
+
+  const char* kReloadScript =
+      "class Foo {\n"
+      "  var c;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  return f.c;\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(44, SimpleInvoke(lib, "main"));
+}
+
+
+// Tests reload succeeds when instance format changes.
+// Change: Bar {a, b}, Foo : Bar {c:42} -> Bar {c:42}, Foo : Bar {}
+// Validate: c keeps the value in the retained Foo object.
+TEST_CASE(IsolateReload_ChangeInstanceFormat5) {
+  const char* kScript =
+      "class Bar{\n"
+      "  var a;\n"
+      "  var b;\n"
+      "}\n"
+      "class Foo extends Bar{\n"
+      "  var c;\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  f = new Foo();\n"
+      "  f.c = 44;\n"
+      "  return f.c;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(44, SimpleInvoke(lib, "main"));
+
+  const char* kReloadScript =
+      "class Bar{\n"
+      "  var c;\n"
+      "}\n"
+      "class Foo extends Bar {\n"
+      "}\n"
+      "var f;\n"
+      "main() {\n"
+      "  return f.c;\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(44, SimpleInvoke(lib, "main"));
+}
+
+
+// Tests reload fails when type parameters change.
+// Change: Foo<A,B> {a, b}  -> Foo<A> {a}
+// Validate: the right error message is returned.
+TEST_CASE(IsolateReload_ChangeInstanceFormat6) {
+  const char* kScript =
+      "class Foo<A, B> {\n"
+      "  var a;\n"
+      "  var b;\n"
+      "}\n"
+      "main() {\n"
+      "  new Foo();\n"
+      "  return 43;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_EQ(43, SimpleInvoke(lib, "main"));
+
+  const char* kReloadScript =
+      "class Foo<A> {\n"
+      "  var a;\n"
+      "}\n";
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_ERROR(lib, "type parameters have changed");
+}
+
+// Tests reload succeeds when type parameters are changed for allocated class.
+// Change: Foo<A,B> {a, b} -> Foo<A> {a}
+// Validate: return value from main is correct.
+// Please note: This test works because no instances are created from Foo.
+TEST_CASE(IsolateReload_ChangeInstanceFormat7) {
+  const char* kScript =
+      "class Foo<A, B> {\n"
+      "  var a;\n"
+      "  var b;\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "class Foo<A> {\n"
+      "  var a;\n"
+      "}\n";
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+}
+
+
+// Regression for handle sharing bug: Change the shape of two classes and see
+// that their instances don't change class.
+TEST_CASE(IsolateReload_ChangeInstanceFormat8) {
+  const char* kScript =
+      "class A{\n"
+      "  var x;\n"
+      "}\n"
+      "class B {\n"
+      "  var x, y, z, w;\n"
+      "}\n"
+      "var a, b;\n"
+      "main() {\n"
+      "  a = new A();\n"
+      "  b = new B();\n"
+      "  return '$a $b';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("Instance of 'A' Instance of 'B'", SimpleInvokeStr(lib, "main"));
+
+  const char* kReloadScript =
+      "class A{\n"
+      "  var x, y;\n"
+      "}\n"
+      "class B {\n"
+      "  var x, y, z, w, v;\n"
+      "}\n"
+      "var a, b;\n"
+      "main() {\n"
+      "  return '$a $b';\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("Instance of 'A' Instance of 'B'", SimpleInvokeStr(lib, "main"));
+}
+
+
+static bool NothingModifiedCallback(const char* url, int64_t since) {
+  return false;
+}
+
+
+TEST_CASE(IsolateReload_NoLibsModified) {
+  const char* kImportScript =
+      "importedFunc() => 'fancy';";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
+  const char* kScript =
+      "import 'test:lib1';\n"
+      "main() {\n"
+      "  return importedFunc() + ' feast';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("fancy feast", SimpleInvokeStr(lib, "main"));
+
+  const char* kReloadImportScript =
+      "importedFunc() => 'bossy';";
+  TestCase::AddTestLib("test:lib1", kReloadImportScript);
+
+  const char* kReloadScript =
+      "import 'test:lib1';\n"
+      "main() {\n"
+      "  return importedFunc() + ' pants';\n"
+      "}\n";
+
+  Dart_SetFileModifiedCallback(&NothingModifiedCallback);
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  Dart_SetFileModifiedCallback(NULL);
+
+  // No reload occurred because no files were "modified".
+  EXPECT_STREQ("fancy feast", SimpleInvokeStr(lib, "main"));
+}
+
+
+static bool MainModifiedCallback(const char* url, int64_t since) {
+  if (strcmp(url, "test-lib") == 0) {
+    return true;
+  }
+  return false;
+}
+
+
+TEST_CASE(IsolateReload_MainLibModified) {
+  const char* kImportScript =
+      "importedFunc() => 'fancy';";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
+  const char* kScript =
+      "import 'test:lib1';\n"
+      "main() {\n"
+      "  return importedFunc() + ' feast';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("fancy feast", SimpleInvokeStr(lib, "main"));
+
+  const char* kReloadImportScript =
+      "importedFunc() => 'bossy';";
+  TestCase::AddTestLib("test:lib1", kReloadImportScript);
+
+  const char* kReloadScript =
+      "import 'test:lib1';\n"
+      "main() {\n"
+      "  return importedFunc() + ' pants';\n"
+      "}\n";
+
+  Dart_SetFileModifiedCallback(&MainModifiedCallback);
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  Dart_SetFileModifiedCallback(NULL);
+
+  // Imported library is not reloaded.
+  EXPECT_STREQ("fancy pants", SimpleInvokeStr(lib, "main"));
+}
+
+
+static bool ImportModifiedCallback(const char* url, int64_t since) {
+  if (strcmp(url, "test:lib1") == 0) {
+    return true;
+  }
+  return false;
+}
+
+
+TEST_CASE(IsolateReload_ImportedLibModified) {
+  const char* kImportScript =
+      "importedFunc() => 'fancy';";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
+  const char* kScript =
+      "import 'test:lib1';\n"
+      "main() {\n"
+      "  return importedFunc() + ' feast';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("fancy feast", SimpleInvokeStr(lib, "main"));
+
+  const char* kReloadImportScript =
+      "importedFunc() => 'bossy';";
+  TestCase::AddTestLib("test:lib1", kReloadImportScript);
+
+  const char* kReloadScript =
+      "import 'test:lib1';\n"
+      "main() {\n"
+      "  return importedFunc() + ' pants';\n"
+      "}\n";
+
+  Dart_SetFileModifiedCallback(&ImportModifiedCallback);
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  Dart_SetFileModifiedCallback(NULL);
+
+  // Modification of an imported library propagates to the importing library.
+  EXPECT_STREQ("bossy pants", SimpleInvokeStr(lib, "main"));
+}
+
+
+TEST_CASE(IsolateReload_PrefixImportedLibModified) {
+  const char* kImportScript =
+      "importedFunc() => 'fancy';";
+  TestCase::AddTestLib("test:lib1", kImportScript);
+
+  const char* kScript =
+      "import 'test:lib1' as cobra;\n"
+      "main() {\n"
+      "  return cobra.importedFunc() + ' feast';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("fancy feast", SimpleInvokeStr(lib, "main"));
+
+  const char* kReloadImportScript =
+      "importedFunc() => 'bossy';";
+  TestCase::AddTestLib("test:lib1", kReloadImportScript);
+
+  const char* kReloadScript =
+      "import 'test:lib1' as cobra;\n"
+      "main() {\n"
+      "  return cobra.importedFunc() + ' pants';\n"
+      "}\n";
+
+  Dart_SetFileModifiedCallback(&ImportModifiedCallback);
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  Dart_SetFileModifiedCallback(NULL);
+
+  // Modification of an prefix-imported library propagates to the
+  // importing library.
+  EXPECT_STREQ("bossy pants", SimpleInvokeStr(lib, "main"));
+}
+
+
+static bool ExportModifiedCallback(const char* url, int64_t since) {
+  if (strcmp(url, "test:exportlib") == 0) {
+    return true;
+  }
+  return false;
+}
+
+
+TEST_CASE(IsolateReload_ExportedLibModified) {
+  const char* kImportScript =
+      "export 'test:exportlib';";
+  TestCase::AddTestLib("test:importlib", kImportScript);
+
+  const char* kExportScript =
+      "exportedFunc() => 'fancy';";
+  TestCase::AddTestLib("test:exportlib", kExportScript);
+
+  const char* kScript =
+      "import 'test:importlib';\n"
+      "main() {\n"
+      "  return exportedFunc() + ' feast';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("fancy feast", SimpleInvokeStr(lib, "main"));
+
+  const char* kReloadExportScript =
+      "exportedFunc() => 'bossy';";
+  TestCase::AddTestLib("test:exportlib", kReloadExportScript);
+
+  const char* kReloadScript =
+      "import 'test:importlib';\n"
+      "main() {\n"
+      "  return exportedFunc() + ' pants';\n"
+      "}\n";
+
+  Dart_SetFileModifiedCallback(&ExportModifiedCallback);
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  Dart_SetFileModifiedCallback(NULL);
+
+  // Modification of an exported library propagates.
+  EXPECT_STREQ("bossy pants", SimpleInvokeStr(lib, "main"));
+}
+
 #endif  // !PRODUCT
 
 }  // namespace dart
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index e40cf12..56074a2 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -1680,7 +1680,7 @@
 bool JitOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
   ASSERT(call->HasICData());
   const ICData& ic_data = *call->ic_data();
-  if ((ic_data.NumberOfUsedChecks() == 0) || !ic_data.HasOneTarget()) {
+  if (ic_data.NumberOfUsedChecks() != 1) {
     // No type feedback collected or multiple targets found.
     return false;
   }
@@ -1696,14 +1696,13 @@
       (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
       (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) ||
       (recognized_kind == MethodRecognizer::kGrowableArraySetData) ||
-      (recognized_kind == MethodRecognizer::kGrowableArraySetLength)) {
-      ASSERT(ic_data.NumberOfChecks() == 1);
+      (recognized_kind == MethodRecognizer::kGrowableArraySetLength) ||
+      (recognized_kind == MethodRecognizer::kSmi_bitAndFromSmi)) {
     return FlowGraphInliner::TryReplaceInstanceCallWithInline(
         flow_graph_, current_iterator(), call);
   }
 
-  if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
-      (ic_data.NumberOfChecks() == 1)) {
+  if (recognized_kind == MethodRecognizer::kStringBaseCharAt) {
       ASSERT((class_ids[0] == kOneByteStringCid) ||
              (class_ids[0] == kTwoByteStringCid) ||
              (class_ids[0] == kExternalOneByteStringCid) ||
@@ -1712,7 +1711,7 @@
         flow_graph_, current_iterator(), call);
   }
 
-  if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kOneByteStringCid) {
     if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
       // This is an internal method, no need to check argument types nor
       // range.
@@ -1735,8 +1734,7 @@
   }
 
   if (CanUnboxDouble() &&
-      (recognized_kind == MethodRecognizer::kIntegerToDouble) &&
-      (ic_data.NumberOfChecks() == 1)) {
+      (recognized_kind == MethodRecognizer::kIntegerToDouble)) {
     if (class_ids[0] == kSmiCid) {
       AddReceiverCheck(call);
       ReplaceCall(call,
@@ -1805,36 +1803,23 @@
     }
   }
 
-  if (IsSupportedByteArrayViewCid(class_ids[0]) &&
-      (ic_data.NumberOfChecks() == 1)) {
+  if (IsSupportedByteArrayViewCid(class_ids[0])) {
     return FlowGraphInliner::TryReplaceInstanceCallWithInline(
         flow_graph_, current_iterator(), call);
   }
 
-  if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kFloat32x4Cid) {
     return TryInlineFloat32x4Method(call, recognized_kind);
   }
 
-  if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kInt32x4Cid) {
     return TryInlineInt32x4Method(call, recognized_kind);
   }
 
-  if ((class_ids[0] == kFloat64x2Cid) && (ic_data.NumberOfChecks() == 1)) {
+  if (class_ids[0] == kFloat64x2Cid) {
     return TryInlineFloat64x2Method(call, recognized_kind);
   }
 
-  if (recognized_kind == MethodRecognizer::kSmi_bitAndFromSmi) {
-    AddReceiverCheck(call);
-    BinarySmiOpInstr* op =
-        new(Z) BinarySmiOpInstr(
-            Token::kBIT_AND,
-            new(Z) Value(call->ArgumentAt(0)),
-            new(Z) Value(call->ArgumentAt(1)),
-            call->deopt_id());
-    ReplaceCall(call, op);
-    return true;
-  }
-
   return false;
 }
 
@@ -2347,6 +2332,12 @@
 }
 
 
+// Tells whether the function of the call matches the core private name.
+static bool matches_core(InstanceCallInstr* call, const String& name) {
+  return call->function_name().raw() == Library::PrivateCoreLibName(name).raw();
+}
+
+
 // TODO(srdjan): Use ICData to check if always true or false.
 void JitOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
   ASSERT(Token::IsTypeTestOperator(call->token_kind()));
@@ -2356,26 +2347,27 @@
   bool negate = false;
   if (call->ArgumentCount() == 2) {
     type_args = flow_graph()->constant_null();
-    if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfNum()).raw()) {
-      type = Type::Number();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfInt()).raw()) {
-      type = Type::IntType();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfSmi()).raw()) {
-      type = Type::SmiType();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfDouble()).raw()) {
-      type = Type::Double();
-    } else if (call->function_name().raw() ==
-        Library::PrivateCoreLibName(Symbols::_instanceOfString()).raw()) {
-      type = Type::StringType();
+    if (matches_core(call, Symbols::_simpleInstanceOf())) {
+      type =
+          AbstractType::Cast(call->ArgumentAt(1)->AsConstant()->value()).raw();
+      negate = false;  // Just to be sure.
     } else {
-      UNIMPLEMENTED();
+      if (matches_core(call, Symbols::_instanceOfNum())) {
+        type = Type::Number();
+      } else if (matches_core(call, Symbols::_instanceOfInt())) {
+        type = Type::IntType();
+      } else if (matches_core(call, Symbols::_instanceOfSmi())) {
+        type = Type::SmiType();
+      } else if (matches_core(call, Symbols::_instanceOfDouble())) {
+        type = Type::Double();
+      } else if (matches_core(call, Symbols::_instanceOfString())) {
+        type = Type::StringType();
+      } else {
+        UNIMPLEMENTED();
+      }
+      negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition()
+                          ->AsConstant()->value()).value();
     }
-    negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition()
-        ->AsConstant()->value()).value();
   } else {
     type_args = call->ArgumentAt(1);
     type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw();
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
index fae87a7..0692007 100644
--- a/runtime/vm/locations.h
+++ b/runtime/vm/locations.h
@@ -398,7 +398,11 @@
   typedef BitField<uword, Policy, 0, 3> PolicyField;
 
   // Layout for stack slots.
+#if defined(ARCH_IS_64_BIT)
+  static const intptr_t kBitsForBaseReg = 6;
+#else
   static const intptr_t kBitsForBaseReg = 5;
+#endif
   static const intptr_t kBitsForStackIndex = kBitsForPayload - kBitsForBaseReg;
   class StackSlotBaseField :
       public BitField<uword, Register, 0, kBitsForBaseReg> {};
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index 035428d..0cb618a 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -181,6 +181,7 @@
 
 
 void MessageQueue::PrintJSON(JSONStream* stream) {
+#ifndef PRODUCT
   if (!FLAG_support_service) {
     return;
   }
@@ -221,6 +222,7 @@
       }
     }
   }
+#endif  // !PRODUCT
 }
 
 }  // namespace dart
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 5e5f685..80cfbbf 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -64,6 +64,7 @@
       should_pause_on_exit_(false),
       is_paused_on_start_(false),
       is_paused_on_exit_(false),
+      delete_me_(false),
       paused_timestamp_(-1),
       pool_(NULL),
       task_(NULL),
@@ -78,6 +79,10 @@
 MessageHandler::~MessageHandler() {
   delete queue_;
   delete oob_queue_;
+  queue_ = NULL;
+  oob_queue_ = NULL;
+  pool_ = NULL;
+  task_ = NULL;
 }
 
 
@@ -110,6 +115,7 @@
               name());
   }
   ASSERT(pool_ == NULL);
+  ASSERT(!delete_me_);
   pool_ = pool;
   start_callback_ = start_callback;
   end_callback_ = end_callback;
@@ -148,6 +154,7 @@
     message = NULL;  // Do not access message.  May have been deleted.
 
     if ((pool_ != NULL) && (task_ == NULL)) {
+      ASSERT(!delete_me_);
       task_ = new MessageHandlerTask(this);
       task_running = pool_->Run(task_);
     }
@@ -251,6 +258,7 @@
   // assigned to a thread pool.
   MonitorLocker ml(&monitor_);
   ASSERT(pool_ == NULL);
+  ASSERT(!delete_me_);
 #if defined(DEBUG)
   CheckAccess();
 #endif
@@ -263,6 +271,7 @@
   // assigned to a thread pool.
   MonitorLocker ml(&monitor_);
   ASSERT(pool_ == NULL);
+  ASSERT(!delete_me_);
 #if defined(DEBUG)
   CheckAccess();
 #endif
@@ -275,6 +284,7 @@
     return kOK;
   }
   MonitorLocker ml(&monitor_);
+  ASSERT(!delete_me_);
 #if defined(DEBUG)
   CheckAccess();
 #endif
@@ -316,6 +326,7 @@
   ASSERT(Isolate::Current() == NULL);
   MessageStatus status = kOK;
   bool run_end_callback = false;
+  bool delete_me = false;
   {
     // We will occasionally release and reacquire this monitor in this
     // function. Whenever we reacquire the monitor we *must* process
@@ -395,6 +406,7 @@
       }
       pool_ = NULL;
       run_end_callback = true;
+      delete_me = delete_me_;
     }
 
     // Clear the task_ last.  This allows other tasks to potentially start
@@ -402,10 +414,17 @@
     ASSERT(oob_queue_->IsEmpty());
     task_ = NULL;
   }
+
+  // Message handlers either use delete_me or end_callback but not both.
+  ASSERT(!delete_me || end_callback_ == NULL);
+
   if (run_end_callback && end_callback_ != NULL) {
     end_callback_(callback_data_);
     // The handler may have been deleted after this point.
   }
+  if (delete_me) {
+    delete this;
+  }
 }
 
 
@@ -433,6 +452,22 @@
 }
 
 
+void MessageHandler::RequestDeletion() {
+  ASSERT(OwnedByPortMap());
+  {
+    MonitorLocker ml(&monitor_);
+    if (task_ != NULL) {
+      // This message handler currently has a task running on the thread pool.
+      delete_me_ = true;
+      return;
+    }
+  }
+
+  // This message handler has no current task.  Delete it.
+  delete this;
+}
+
+
 void MessageHandler::increment_live_ports() {
   MonitorLocker ml(&monitor_);
 #if defined(DEBUG)
diff --git a/runtime/vm/message_handler.h b/runtime/vm/message_handler.h
index c52431d..825e3d3 100644
--- a/runtime/vm/message_handler.h
+++ b/runtime/vm/message_handler.h
@@ -187,6 +187,10 @@
   // This is used to delete handlers when their last live port is closed.
   virtual bool OwnedByPortMap() const { return false; }
 
+  // Requests deletion of this message handler when the next task
+  // completes.
+  void RequestDeletion();
+
   void increment_live_ports();
   void decrement_live_ports();
   // ------------ END PortMap API ------------
@@ -241,6 +245,7 @@
   bool should_pause_on_exit_;
   bool is_paused_on_start_;
   bool is_paused_on_exit_;
+  bool delete_me_;
   int64_t paused_timestamp_;
   ThreadPool* pool_;
   ThreadPool::Task* task_;
diff --git a/runtime/vm/method_recognizer.cc b/runtime/vm/method_recognizer.cc
index 03014ac..649a1fe 100644
--- a/runtime/vm/method_recognizer.cc
+++ b/runtime/vm/method_recognizer.cc
@@ -37,6 +37,87 @@
 }
 
 
+intptr_t MethodRecognizer::MethodKindToReceiverCid(Kind kind) {
+  switch (kind) {
+    case kImmutableArrayGetIndexed:
+      return kImmutableArrayCid;
+
+    case kObjectArrayGetIndexed:
+    case kObjectArraySetIndexed:
+      return kArrayCid;
+
+    case kGrowableArrayGetIndexed:
+    case kGrowableArraySetIndexed:
+      return kGrowableObjectArrayCid;
+
+    case kFloat32ArrayGetIndexed:
+    case kFloat32ArraySetIndexed:
+      return kTypedDataFloat32ArrayCid;
+
+    case kFloat64ArrayGetIndexed:
+    case kFloat64ArraySetIndexed:
+      return kTypedDataFloat64ArrayCid;
+
+    case kInt8ArrayGetIndexed:
+    case kInt8ArraySetIndexed:
+      return kTypedDataInt8ArrayCid;
+
+    case kUint8ArrayGetIndexed:
+    case kUint8ArraySetIndexed:
+      return kTypedDataUint8ArrayCid;
+
+    case kUint8ClampedArrayGetIndexed:
+    case kUint8ClampedArraySetIndexed:
+      return kTypedDataUint8ClampedArrayCid;
+
+    case kExternalUint8ArrayGetIndexed:
+    case kExternalUint8ArraySetIndexed:
+      return kExternalTypedDataUint8ArrayCid;
+
+    case kExternalUint8ClampedArrayGetIndexed:
+    case kExternalUint8ClampedArraySetIndexed:
+      return kExternalTypedDataUint8ClampedArrayCid;
+
+    case kInt16ArrayGetIndexed:
+    case kInt16ArraySetIndexed:
+      return kTypedDataInt16ArrayCid;
+
+    case kUint16ArrayGetIndexed:
+    case kUint16ArraySetIndexed:
+      return kTypedDataUint16ArrayCid;
+
+    case kInt32ArrayGetIndexed:
+    case kInt32ArraySetIndexed:
+      return kTypedDataInt32ArrayCid;
+
+    case kUint32ArrayGetIndexed:
+    case kUint32ArraySetIndexed:
+      return kTypedDataUint32ArrayCid;
+
+    case kInt64ArrayGetIndexed:
+    case kInt64ArraySetIndexed:
+      return kTypedDataInt64ArrayCid;
+
+    case kFloat32x4ArrayGetIndexed:
+    case kFloat32x4ArraySetIndexed:
+      return kTypedDataFloat32x4ArrayCid;
+
+    case kInt32x4ArrayGetIndexed:
+    case kInt32x4ArraySetIndexed:
+      return kTypedDataInt32x4ArrayCid;
+
+    case kFloat64x2ArrayGetIndexed:
+    case kFloat64x2ArraySetIndexed:
+      return kTypedDataFloat64x2ArrayCid;
+
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kIllegalCid;
+}
+
+
 #define KIND_TO_STRING(class_name, function_name, enum_name, type, fp) \
   #enum_name,
 static const char* recognized_list_method_name[] = {
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index 083b477..0232d83 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -13,7 +13,7 @@
 // When adding a new function add a 0 as fingerprint, build and run to get the
 // correct fingerprint from the mismatch error.
 #define OTHER_RECOGNIZED_LIST(V)                                               \
-  V(::, identical, ObjectIdentical, Bool, 0x12e69c8c)                          \
+  V(::, identical, ObjectIdentical, Bool, 0x49c6e96a)                          \
   V(ClassID, getID, ClassIDgetID, Smi, 0x528fd455)                             \
   V(Object, Object., ObjectConstructor, Dynamic, 0x681617fe)                   \
   V(_List, ., ObjectArrayAllocate, Array, 0x63078b15)                          \
@@ -111,30 +111,8 @@
   V(Int32x4, withFlagY, Int32x4WithFlagY, Int32x4, 0x6485a9c4)                 \
   V(Int32x4, withFlagZ, Int32x4WithFlagZ, Int32x4, 0x267acdfa)                 \
   V(Int32x4, withFlagW, Int32x4WithFlagW, Int32x4, 0x345ac675)                 \
-  V(Float32List, [], Float32ArrayGetIndexed, Double, 0x5686528f)               \
-  V(Float32List, []=, Float32ArraySetIndexed, Dynamic, 0x1b0d90df)             \
-  V(Int8List, [], Int8ArrayGetIndexed, Smi, 0x069af8b3)                        \
-  V(Int8List, []=, Int8ArraySetIndexed, Dynamic, 0x33994cd7)                   \
-  V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, Smi, 0x027603ed)        \
-  V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, Dynamic, 0x28f5f058)   \
-  V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
-    Smi, 0x027603ed)                                                           \
-  V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
-    Dynamic, 0x28f5f058)                                                       \
-  V(Int16List, [], Int16ArrayGetIndexed, Smi, 0x173cd6a1)                      \
-  V(Int16List, []=, Int16ArraySetIndexed, Dynamic, 0x32f84e3c)                 \
-  V(Uint16List, [], Uint16ArrayGetIndexed, Smi, 0x3ececa2f)                    \
-  V(Uint16List, []=, Uint16ArraySetIndexed, Dynamic, 0x5c3a0bb9)               \
-  V(Int32List, [], Int32ArrayGetIndexed, Dynamic, 0x262eef09)                  \
-  V(Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x1b05b471)                 \
   V(Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x0c0c939a)                  \
   V(Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x3714d004)                 \
-  V(Float32x4List, [], Float32x4ArrayGetIndexed, Float32x4, 0x01c7017b)        \
-  V(Float32x4List, []=, Float32x4ArraySetIndexed, Dynamic, 0x56e843aa)         \
-  V(Int32x4List, [], Int32x4ArrayGetIndexed, Int32x4, 0x08353f8d)              \
-  V(Int32x4List, []=, Int32x4ArraySetIndexed, Dynamic, 0x1d9a47a5)             \
-  V(Float64x2List, [], Float64x2ArrayGetIndexed, Float64x2, 0x669b1498)        \
-  V(Float64x2List, []=, Float64x2ArraySetIndexed, Dynamic, 0x76da6ffe)         \
   V(_Bigint, get:_neg, Bigint_getNeg, Bool, 0x7bf17a57)                        \
   V(_Bigint, get:_used, Bigint_getUsed, Smi, 0x55041013)                       \
   V(_Bigint, get:_digits, Bigint_getDigits, TypedDataUint32Array, 0x46a6c1b3)  \
@@ -239,17 +217,17 @@
 
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
-  V(::, sqrt, MathSqrt, Double, 0x18e8d5f6)                                    \
+  V(::, sqrt, MathSqrt, Double, 0x1afb83d4)                                    \
   V(_Random, _nextState, Random_nextState, Dynamic, 0x1e4b0103)                \
 
 #define GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                       \
-  V(::, sin, MathSin, Double, 0x0000fe08)                                      \
-  V(::, cos, MathCos, Double, 0x7794b33e)                                      \
-  V(::, tan, MathTan, Double, 0x4c1b72fd)                                      \
-  V(::, asin, MathAsin, Double, 0x640d48ad)                                    \
-  V(::, acos, MathAcos, Double, 0x42d46f81)                                    \
-  V(::, atan, MathAtan, Double, 0x4223f879)                                    \
-  V(::, atan2, MathAtan2, Double, 0x3553fb61)                                  \
+  V(::, sin, MathSin, Double, 0x0213abe6)                                      \
+  V(::, cos, MathCos, Double, 0x79a7611c)                                      \
+  V(::, tan, MathTan, Double, 0x4e2e20db)                                      \
+  V(::, asin, MathAsin, Double, 0x661ff68b)                                    \
+  V(::, acos, MathAcos, Double, 0x44e71d5f)                                    \
+  V(::, atan, MathAtan, Double, 0x4436a657)                                    \
+  V(::, atan2, MathAtan2, Double, 0x60a40743)                                  \
 
 #define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
   V(Int8List, ., TypedData_Int8Array_factory, TypedDataInt8Array, 0x2e7749e3)  \
@@ -281,15 +259,37 @@
     TypedDataFloat64x2Array, 0x18cbf4d9)                                       \
 
 #define GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                    \
+  V(Int8List, [], Int8ArrayGetIndexed, Smi, 0x069af8b3)                        \
+  V(Int8List, []=, Int8ArraySetIndexed, Dynamic, 0x33994cd7)                   \
   V(Uint8List, [], Uint8ArrayGetIndexed, Smi, 0x027603ed)                      \
   V(Uint8List, []=, Uint8ArraySetIndexed, Dynamic, 0x060d5256)                 \
   V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, Smi, 0x027603ed)    \
   V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, Dynamic,           \
     0x060d5256)                                                                \
+  V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, Smi, 0x027603ed)        \
+  V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, Dynamic, 0x28f5f058)   \
+  V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
+    Smi, 0x027603ed)                                                           \
+  V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
+    Dynamic, 0x28f5f058)                                                       \
+  V(Int16List, [], Int16ArrayGetIndexed, Smi, 0x173cd6a1)                      \
+  V(Int16List, []=, Int16ArraySetIndexed, Dynamic, 0x32f84e3c)                 \
+  V(Uint16List, [], Uint16ArrayGetIndexed, Smi, 0x3ececa2f)                    \
+  V(Uint16List, []=, Uint16ArraySetIndexed, Dynamic, 0x5c3a0bb9)               \
+  V(Int32List, [], Int32ArrayGetIndexed, Dynamic, 0x262eef09)                  \
+  V(Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x1b05b471)                 \
   V(Uint32List, [], Uint32ArrayGetIndexed, Dynamic, 0x6040f7fb)                \
   V(Uint32List, []=, Uint32ArraySetIndexed, Dynamic, 0x3a4e1119)               \
   V(Float64List, [], Float64ArrayGetIndexed, Double, 0x7a27098d)               \
   V(Float64List, []=, Float64ArraySetIndexed, Dynamic, 0x139b2465)             \
+  V(Float32List, [], Float32ArrayGetIndexed, Double, 0x5686528f)               \
+  V(Float32List, []=, Float32ArraySetIndexed, Dynamic, 0x1b0d90df)             \
+  V(Float32x4List, [], Float32x4ArrayGetIndexed, Float32x4, 0x01c7017b)        \
+  V(Float32x4List, []=, Float32x4ArraySetIndexed, Dynamic, 0x56e843aa)         \
+  V(Int32x4List, [], Int32x4ArrayGetIndexed, Int32x4, 0x08353f8d)              \
+  V(Int32x4List, []=, Int32x4ArraySetIndexed, Dynamic, 0x1d9a47a5)             \
+  V(Float64x2List, [], Float64x2ArrayGetIndexed, Float64x2, 0x669b1498)        \
+  V(Float64x2List, []=, Float64x2ArraySetIndexed, Dynamic, 0x76da6ffe)         \
   V(_TypedList, get:length, TypedDataLength, Smi, 0x2090dc1a)                  \
   V(Float32x4, get:x, Float32x4ShuffleX, Double, 0x63d0c13f)                   \
   V(Float32x4, get:y, Float32x4ShuffleY, Double, 0x20343b1b)                   \
@@ -335,7 +335,7 @@
   V(::, _getDefaultTag, UserTag_defaultTag, Dynamic, 0x14ddc3b7)               \
   V(::, _getCurrentTag, Profiler_getCurrentTag, Dynamic, 0x486ee02d)           \
   V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, Dynamic,           \
-    0x3fe92e14)                                                                \
+    0x1667ce76)                                                                \
 
 #define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                  \
   CORE_LIB_INTRINSIC_LIST(V)                                                   \
@@ -359,8 +359,9 @@
   V(_ImmutableList, get:length, ImmutableArrayLength, 0x25943ad2)              \
   V(_TypedList, get:length, TypedDataLength, 0x2090dc1a)                       \
   V(_GrowableList, get:length, GrowableArrayLength, 0x18dc9df6)                \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x02734d82)           \
   V(_GrowableList, add, GrowableListAdd, 0x0d1358ed)                           \
-  V(_GrowableList, removeLast, GrowableListRemoveLast, 0x135d7384)             \
+  V(_GrowableList, removeLast, GrowableListRemoveLast, 0x7add0363)             \
   V(_StringBase, get:length, StringBaseLength, 0x2a2c1b13)                     \
   V(ListIterator, moveNext, ListIteratorMoveNext, 0x3f892e71)                  \
   V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 0x5681c902)  \
@@ -420,19 +421,11 @@
   V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x2fab992e)               \
   V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x387e9fc6)             \
   V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x5396432d)             \
-  V(::, asin, MathAsin, 0x640d48ad)                                            \
-  V(::, acos, MathAcos, 0x42d46f81)                                            \
-  V(::, atan, MathAtan, 0x4223f879)                                            \
-  V(::, atan2, MathAtan2, 0x3553fb61)                                          \
-  V(::, cos, MathCos, 0x7794b33e)                                              \
-  V(::, exp, MathExp, 0x59769f9d)                                              \
-  V(::, log, MathLog, 0x2c12654e)                                              \
+  V(::, exp, MathExp, 0x5b894d7b)                                              \
+  V(::, log, MathLog, 0x2e25132c)                                              \
   V(::, max, MathMax, 0x54121d6a)                                              \
   V(::, min, MathMin, 0x4276561c)                                              \
-  V(::, pow, MathPow, 0x7ab62ca7)                                              \
-  V(::, sin, MathSin, 0x0000fe08)                                              \
-  V(::, sqrt, MathSqrt, 0x18e8d5f6)                                            \
-  V(::, tan, MathTan, 0x4c1b72fd)                                              \
+  V(::, pow, MathPow, 0x438e3089)                                              \
   V(Lists, copy, ListsCopy, 0x21a194fa)                                        \
   V(_Bigint, get:_neg, Bigint_getNeg, 0x7bf17a57)                              \
   V(_Bigint, get:_used, Bigint_getUsed, 0x55041013)                            \
@@ -450,6 +443,14 @@
 
 // A list of core function that should never be inlined.
 #define INLINE_BLACK_LIST(V)                                                   \
+  V(::, asin, MathAsin, 0x661ff68b)                                            \
+  V(::, acos, MathAcos, 0x44e71d5f)                                            \
+  V(::, atan, MathAtan, 0x4436a657)                                            \
+  V(::, atan2, MathAtan2, 0x60a40743)                                          \
+  V(::, cos, MathCos, 0x79a7611c)                                              \
+  V(::, sin, MathSin, 0x0213abe6)                                              \
+  V(::, sqrt, MathSqrt, 0x1afb83d4)                                            \
+  V(::, tan, MathTan, 0x4e2e20db)                                              \
   V(_Bigint, _lsh, Bigint_lsh, 0x5cd95513)                                     \
   V(_Bigint, _rsh, Bigint_rsh, 0x2d68d0e1)                                     \
   V(_Bigint, _absAdd, Bigint_absAdd, 0x492f4865)                               \
@@ -528,6 +529,7 @@
   static bool AlwaysInline(const Function& function);
   static bool PolymorphicTarget(const Function& function);
   static intptr_t ResultCid(const Function& function);
+  static intptr_t MethodKindToReceiverCid(Kind kind);
   static const char* KindToCString(Kind kind);
 #if defined(DART_NO_SNAPSHOT)
   static void InitializeState();
diff --git a/runtime/vm/metrics.cc b/runtime/vm/metrics.cc
index cb6c205..137042e 100644
--- a/runtime/vm/metrics.cc
+++ b/runtime/vm/metrics.cc
@@ -67,6 +67,7 @@
 }
 
 
+#ifndef PRODUCT
 static const char* UnitString(intptr_t unit) {
   switch (unit) {
     case Metric::kCounter: return "counter";
@@ -97,6 +98,7 @@
   double value_as_double = static_cast<double>(Value());
   obj.AddProperty("value", value_as_double);
 }
+#endif  // !PRODUCT
 
 
 char* Metric::ValueToString(int64_t value, Unit unit) {
@@ -306,13 +308,13 @@
   if (FLAG_print_metrics) {
     // Create a zone to allocate temporary strings in.
     StackZone sz(Thread::Current());
-    OS::Print("Printing metrics for VM\n");
+    OS::PrintErr("Printing metrics for VM\n");
     Metric* current = Metric::vm_head();
     while (current != NULL) {
-      OS::Print("%s\n", current->ToString());
+      OS::PrintErr("%s\n", current->ToString());
       current = current->next();
     }
-    OS::Print("\n");
+    OS::PrintErr("\n");
   }
 }
 
diff --git a/runtime/vm/metrics.h b/runtime/vm/metrics.h
index 9fde2d8..c34f02d 100644
--- a/runtime/vm/metrics.h
+++ b/runtime/vm/metrics.h
@@ -56,7 +56,9 @@
 
   virtual ~Metric();
 
+#ifndef PRODUCT
   void PrintJSON(JSONStream* stream);
+#endif  // !PRODUCT
 
   // Returns a zone allocated string.
   static char* ValueToString(int64_t value, Unit unit);
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index 1bc5d4c..7abd52e 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -90,6 +90,7 @@
 
   NativeMessageHandler* nmh = new NativeMessageHandler(name, handler);
   Dart_Port port_id = PortMap::CreatePort(nmh);
+  PortMap::SetPortState(port_id, PortMap::kLivePort);
   nmh->Run(Dart::thread_pool(), NULL, NULL, 0);
   return port_id;
 }
diff --git a/runtime/vm/native_message_handler.cc b/runtime/vm/native_message_handler.cc
index 7779e95..1763341 100644
--- a/runtime/vm/native_message_handler.cc
+++ b/runtime/vm/native_message_handler.cc
@@ -15,8 +15,6 @@
                                            Dart_NativeMessageHandler func)
     : name_(strdup(name)),
       func_(func) {
-  // A NativeMessageHandler always has one live port.
-  increment_live_ports();
 }
 
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 9b2e319..f72b629 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1845,6 +1845,7 @@
     Exceptions::Throw(thread, exception);
     UNREACHABLE();
   }
+#ifndef PRODUCT
   ClassTable* class_table = isolate->class_table();
   if (space == Heap::kNew) {
     class_table->UpdateAllocatedNew(cls_id, size);
@@ -1855,6 +1856,7 @@
   if (FLAG_profiler && cls.TraceAllocation(isolate)) {
     Profiler::SampleAllocation(thread, cls_id);
   }
+#endif  // !PRODUCT
   NoSafepointScope no_safepoint;
   InitializeObject(address, cls_id, size, (isolate == Dart::vm_isolate()));
   RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
@@ -2074,7 +2076,7 @@
       fields = cls.fields();
       for (intptr_t i = 0; i < fields.Length(); ++i) {
         f ^= fields.At(i);
-        if (!f.is_static()) {
+        if (f.is_instance()) {
           array.SetAt(f.Offset() >> kWordSizeLog2, f);
         }
       }
@@ -2808,12 +2810,17 @@
 
 
 bool Class::TraceAllocation(Isolate* isolate) const {
+#ifndef PRODUCT
   ClassTable* class_table = isolate->class_table();
   return class_table->TraceAllocationFor(id());
+#else
+  return false;
+#endif
 }
 
 
 void Class::SetTraceAllocation(bool trace_allocation) const {
+#ifndef PRODUCT
   Isolate* isolate = Isolate::Current();
   const bool changed = trace_allocation != this->TraceAllocation(isolate);
   if (changed) {
@@ -2821,6 +2828,9 @@
     class_table->SetTraceAllocationFor(id(), trace_allocation);
     DisableAllocationStub();
   }
+#else
+  UNREACHABLE();
+#endif
 }
 
 
@@ -3078,6 +3088,13 @@
                            const Array& param_names,
                            const Array& param_values) const {
   ASSERT(Thread::Current()->IsMutatorThread());
+  if (id() < kInstanceCid) {
+    const Instance& exception = Instance::Handle(String::New(
+        "Cannot evaluate against a VM internal class"));
+    const Instance& stacktrace = Instance::Handle();
+    return UnhandledException::New(exception, stacktrace);
+  }
+
   const Function& eval_func =
       Function::Handle(EvaluateHelper(*this, expr, param_names, true));
   const Object& result =
@@ -4189,7 +4206,8 @@
 }
 
 
-RawField* Class::LookupFieldAllowPrivate(const String& name) const {
+RawField* Class::LookupFieldAllowPrivate(const String& name,
+                                         bool instance_only) const {
   // Use slow string compare, ignoring privacy name mangling.
   Thread* thread = Thread::Current();
   if (EnsureIsFinalized(thread) != Error::null()) {
@@ -4207,6 +4225,10 @@
   for (intptr_t i = 0; i < len; i++) {
     field ^= flds.At(i);
     field_name ^= field.name();
+    if (field.is_static() && instance_only) {
+      // If we only care about instance fields, skip statics.
+      continue;
+    }
     if (String::EqualsIgnoringPrivateKey(field_name, name)) {
       return field.raw();
     }
@@ -4216,7 +4238,7 @@
 
 
 RawField* Class::LookupInstanceFieldAllowPrivate(const String& name) const {
-  Field& field = Field::Handle(LookupFieldAllowPrivate(name));
+  Field& field = Field::Handle(LookupFieldAllowPrivate(name, true));
   if (!field.IsNull() && !field.is_static()) {
     return field.raw();
   }
@@ -5250,7 +5272,7 @@
 
 void Function::SetInstructionsSafe(const Code& value) const {
   StorePointer(&raw_ptr()->code_, value.raw());
-  StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint());
+  StoreNonPointer(&raw_ptr()->entry_point_, value.UncheckedEntryPoint());
 }
 
 
@@ -5272,7 +5294,6 @@
 
 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()));
 }
@@ -5302,7 +5323,7 @@
   if (FLAG_trace_deoptimization_verbose) {
     THR_Print("Disabling optimized code: '%s' entry: %#" Px "\n",
       ToFullyQualifiedCString(),
-      current_code.EntryPoint());
+      current_code.UncheckedEntryPoint());
   }
   current_code.DisableDartCode();
   const Error& error = Error::Handle(zone,
@@ -5884,6 +5905,9 @@
     // Native methods don't need to be optimized.
     return false;
   }
+  if (FLAG_precompiled_mode) {
+    return true;
+  }
   const intptr_t function_length = end_token_pos().Pos() - token_pos().Pos();
   if (is_optimizable() && (script() != Script::null()) &&
       (function_length < FLAG_huge_method_cutoff_in_tokens)) {
@@ -6568,7 +6592,7 @@
                     /* is_const = */ false,
                     /* is_abstract = */ false,
                     /* is_external = */ false,
-                    parent.is_native(),
+                    /* is_native = */ false,
                     parent_owner,
                     token_pos));
   result.set_parent_function(parent);
@@ -8687,6 +8711,11 @@
 }
 
 
+void Script::set_compile_time_constants(const Array& value) const {
+  StorePointer(&raw_ptr()->compile_time_constants_, value.raw());
+}
+
+
 RawGrowableObjectArray* Script::GenerateLineNumberArray() const {
   Zone* zone = Thread::Current()->zone();
   const GrowableObjectArray& info =
@@ -8797,6 +8826,11 @@
 }
 
 
+void Script::set_resolved_url(const String& value) const {
+  StorePointer(&raw_ptr()->resolved_url_, value.raw());
+}
+
+
 void Script::set_source(const String& value) const {
   StorePointer(&raw_ptr()->source_, value.raw());
 }
@@ -9059,10 +9093,20 @@
 RawScript* Script::New(const String& url,
                        const String& source,
                        RawScript::Kind kind) {
+  return Script::New(url, url, source, kind);
+}
+
+
+RawScript* Script::New(const String& url,
+                       const String& resolved_url,
+                       const String& source,
+                       RawScript::Kind kind) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const Script& result = Script::Handle(zone, Script::New());
   result.set_url(String::Handle(zone, Symbols::New(thread, url)));
+  result.set_resolved_url(
+      String::Handle(zone, Symbols::New(thread, resolved_url)));
   result.set_source(source);
   result.set_kind(kind);
   result.set_load_timestamp(FLAG_remove_script_timestamps_for_test
@@ -10304,18 +10348,10 @@
 }
 
 
-void Library::InitResolvedNamesCache(intptr_t size,
-                                     SnapshotReader* reader) const {
+void Library::InitResolvedNamesCache(intptr_t size) const {
   ASSERT(Thread::Current()->IsMutatorThread());
-  if (reader == NULL) {
-    StorePointer(&raw_ptr()->resolved_names_,
-                 HashTables::New<ResolvedNamesMap>(size));
-  } else {
-    intptr_t len = ResolvedNamesMap::ArrayLengthForNumOccupied(size);
-    *reader->ArrayHandle() ^= reader->NewArray(len);
-    StorePointer(&raw_ptr()->resolved_names_,
-                 HashTables::New<ResolvedNamesMap>(*reader->ArrayHandle()));
-  }
+  StorePointer(&raw_ptr()->resolved_names_,
+               HashTables::New<ResolvedNamesMap>(size));
 }
 
 
@@ -11463,7 +11499,7 @@
   } while ((part & 0x80) != 0);
 
   if ((shift < (sizeof(value) * 8)) && ((part & 0x40) != 0)) {
-    value |= static_cast<intptr_t>(-1) << shift;
+    value |= static_cast<intptr_t>(kUwordMax << shift);
   }
   return value;
 }
@@ -12457,6 +12493,12 @@
 }
 
 
+void ICData::ResetSwitchable(Zone* zone) const {
+  ASSERT(NumArgsTested() == 1);
+  set_ic_data_array(Array::Handle(zone, CachedEmptyICDataArray(1)));
+}
+
+
 const char* ICData::ToCString() const {
   const String& name = String::Handle(target_name());
   const intptr_t num_args = NumArgsTested();
@@ -12469,7 +12511,10 @@
 
 RawFunction* ICData::Owner() const {
   Object& obj = Object::Handle(raw_ptr()->owner_);
-  if (obj.IsFunction()) {
+  if (obj.IsNull()) {
+    ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
+    return Function::null();
+  } else if (obj.IsFunction()) {
     return Function::Cast(obj).raw();
   } else {
     ICData& original = ICData::Handle();
@@ -12834,10 +12879,20 @@
 }
 
 
+bool ICData::ValidateInterceptor(const Function& target) const {
+  ObjectStore* store = Isolate::Current()->object_store();
+  ASSERT((target.raw() == store->simple_instance_of_true_function()) ||
+         (target.raw() == store->simple_instance_of_false_function()));
+  const String& instance_of_name = String::Handle(
+      Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw());
+  ASSERT(target_name() == instance_of_name.raw());
+  return true;
+}
+
 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
                       const Function& target) const {
   ASSERT(!target.IsNull());
-  ASSERT(target.name() == target_name());
+  ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
   DEBUG_ASSERT(!HasCheck(class_ids));
   ASSERT(NumArgsTested() > 1);  // Otherwise use 'AddReceiverCheck'.
   ASSERT(class_ids.length() == NumArgsTested());
@@ -12934,10 +12989,6 @@
 }
 
 
-void ICData::ValidateSentinelLocations() const {
-}
-
-
 void ICData::AddReceiverCheck(intptr_t receiver_class_id,
                               const Function& target,
                               intptr_t count) const {
@@ -12971,7 +13022,7 @@
     ASSERT(target.HasCode());
     const Code& code = Code::Handle(target.CurrentCode());
     const Smi& entry_point =
-        Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
+        Smi::Handle(Smi::FromAlignedAddress(code.UncheckedEntryPoint()));
     data.SetAt(data_pos + 1, code);
     data.SetAt(data_pos + 2, entry_point);
   }
@@ -13377,12 +13428,10 @@
 }
 
 
-RawArray* ICData::NewEmptyICDataArray(intptr_t num_args_tested) {
+RawArray* ICData::CachedEmptyICDataArray(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);
+  ASSERT(num_args_tested < kCachedICDataArrayCount);
+  return cached_icdata_arrays_[num_args_tested];
 }
 
 
@@ -13429,16 +13478,6 @@
 }
 
 
-void ICData::ResetData() const {
-  // Number of array elements in one test entry.
-  intptr_t len = TestEntryLength();
-  // IC data array must be null terminated (sentinel entry).
-  const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
-  set_ic_data_array(ic_data);
-  WriteSentinel(ic_data, len);
-}
-
-
 RawICData* ICData::New() {
   ICData& result = ICData::Handle();
   {
@@ -13474,7 +13513,7 @@
                                                       num_args_tested,
                                                       is_static_call));
   result.set_ic_data_array(
-      Array::Handle(zone, NewEmptyICDataArray(num_args_tested)));
+      Array::Handle(zone, CachedEmptyICDataArray(num_args_tested)));
   return result.raw();
 }
 
@@ -13520,95 +13559,6 @@
 }
 
 
-static Token::Kind RecognizeArithmeticOp(const String& name) {
-  ASSERT(name.IsSymbol());
-  if (name.raw() == Symbols::Plus().raw()) {
-    return Token::kADD;
-  } else if (name.raw() == Symbols::Minus().raw()) {
-    return Token::kSUB;
-  } else if (name.raw() == Symbols::Star().raw()) {
-    return Token::kMUL;
-  } else if (name.raw() == Symbols::Slash().raw()) {
-    return Token::kDIV;
-  } else if (name.raw() == Symbols::TruncDivOperator().raw()) {
-    return Token::kTRUNCDIV;
-  } else if (name.raw() == Symbols::Percent().raw()) {
-    return Token::kMOD;
-  } else if (name.raw() == Symbols::BitOr().raw()) {
-    return Token::kBIT_OR;
-  } else if (name.raw() == Symbols::Ampersand().raw()) {
-    return Token::kBIT_AND;
-  } else if (name.raw() == Symbols::Caret().raw()) {
-    return Token::kBIT_XOR;
-  } else if (name.raw() == Symbols::LeftShiftOperator().raw()) {
-    return Token::kSHL;
-  } else if (name.raw() == Symbols::RightShiftOperator().raw()) {
-    return Token::kSHR;
-  } else if (name.raw() == Symbols::Tilde().raw()) {
-    return Token::kBIT_NOT;
-  } else if (name.raw() == Symbols::UnaryMinus().raw()) {
-    return Token::kNEGATE;
-  }
-  return Token::kILLEGAL;
-}
-
-
-bool ICData::HasRangeFeedback() const {
-  const String& target = String::Handle(target_name());
-  const Token::Kind token_kind = RecognizeArithmeticOp(target);
-  if (!Token::IsBinaryArithmeticOperator(token_kind) &&
-      !Token::IsUnaryArithmeticOperator(token_kind)) {
-    return false;
-  }
-
-  bool initialized = false;
-  const intptr_t len = NumberOfChecks();
-  GrowableArray<intptr_t> class_ids;
-  for (intptr_t i = 0; i < len; i++) {
-    if (IsUsedAt(i)) {
-      initialized = true;
-      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)) {
-          return false;
-        }
-      }
-    }
-  }
-
-  return initialized;
-}
-
-
-ICData::RangeFeedback ICData::DecodeRangeFeedbackAt(intptr_t idx) const {
-  ASSERT((0 <= idx) && (idx < 3));
-  const uint32_t raw_feedback =
-      RangeFeedbackBits::decode(raw_ptr()->state_bits_);
-  const uint32_t feedback =
-      (raw_feedback >> (idx * kBitsPerRangeFeedback)) & kRangeFeedbackMask;
-  if ((feedback & kInt64RangeBit) != 0) {
-    return kInt64Range;
-  }
-
-  if ((feedback & kUint32RangeBit) != 0) {
-    if ((feedback & kSignedRangeBit) == 0) {
-      return kUint32Range;
-    }
-
-    // Check if Smi is large enough to accomodate Int33: a mixture of Uint32
-    // and negative Int32 values.
-    return (kSmiBits < 33) ? kInt64Range : kSmiRange;
-  }
-
-  if ((feedback & kInt32RangeBit) != 0) {
-    return kInt32Range;
-  }
-
-  return kSmiRange;
-}
-
-
 Code::Comments& Code::Comments::New(intptr_t count) {
   Comments* comments;
   if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) {
@@ -13742,7 +13692,7 @@
                                      uint32_t* deopt_flags) const {
   ASSERT(is_optimized());
   const Instructions& instrs = Instructions::Handle(instructions());
-  uword code_entry = instrs.EntryPoint();
+  uword code_entry = instrs.PayloadStart();
   const Array& table = Array::Handle(deopt_info_array());
   if (table.IsNull()) {
     ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
@@ -13770,7 +13720,7 @@
 intptr_t Code::BinarySearchInSCallTable(uword pc) const {
   NoSafepointScope no_safepoint;
   const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_);
-  RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - EntryPoint()));
+  RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - PayloadStart()));
   intptr_t imin = 0;
   intptr_t imax = table.Length() / kSCallTableEntryLength;
   while (imax >= imin) {
@@ -13844,16 +13794,18 @@
 
 
 void Code::Disassemble(DisassemblyFormatter* formatter) const {
+#ifndef PRODUCT
   if (!FLAG_support_disassembler) {
     return;
   }
   const Instructions& instr = Instructions::Handle(instructions());
-  uword start = instr.EntryPoint();
+  uword start = instr.PayloadStart();
   if (formatter == NULL) {
     Disassembler::Disassemble(start, start + instr.size(), *this);
   } else {
     Disassembler::Disassemble(start, start + instr.size(), formatter, *this);
   }
+#endif
 }
 
 
@@ -14032,15 +13984,15 @@
 
   // 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()),
+  MemoryRegion region(reinterpret_cast<void*>(instrs.PayloadStart()),
                       instrs.size());
   assembler->FinalizeInstructions(region);
-  CPU::FlushICache(instrs.EntryPoint(), instrs.size());
+  CPU::FlushICache(instrs.PayloadStart(), instrs.size());
 
   code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
 #ifndef PRODUCT
   CodeObservers::NotifyAll(name,
-                           instrs.EntryPoint(),
+                           instrs.PayloadStart(),
                            assembler->prologue_offset(),
                            instrs.size(),
                            optimized);
@@ -14146,13 +14098,13 @@
 RawCode* Code::FindCode(uword pc, int64_t timestamp) {
   Code& code = Code::Handle(Code::LookupCode(pc));
   if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
-      (code.EntryPoint() == pc)) {
+      (code.PayloadStart() == pc)) {
     // Found code in isolate.
     return code.raw();
   }
   code ^= Code::LookupCodeInVmIsolate(pc);
   if (!code.IsNull() && (code.compile_timestamp() == timestamp) &&
-      (code.EntryPoint() == pc)) {
+      (code.PayloadStart() == pc)) {
     // Found code in VM isolate.
     return code.raw();
   }
@@ -14161,7 +14113,7 @@
 
 
 TokenPosition Code::GetTokenIndexOfPC(uword pc) const {
-  uword pc_offset = pc - EntryPoint();
+  uword pc_offset = pc - PayloadStart();
   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
   while (iter.MoveNext()) {
@@ -14180,7 +14132,7 @@
   while (iter.MoveNext()) {
     if (iter.DeoptId() == deopt_id) {
       uword pc_offset = iter.PcOffset();
-      uword pc = EntryPoint() + pc_offset;
+      uword pc = PayloadStart() + pc_offset;
       ASSERT(ContainsInstructionAt(pc));
       return pc;
     }
@@ -14190,7 +14142,7 @@
 
 
 intptr_t Code::GetDeoptIdForOsr(uword pc) const {
-  uword pc_offset = pc - EntryPoint();
+  uword pc_offset = pc - PayloadStart();
   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kOsrEntry);
   while (iter.MoveNext()) {
@@ -14205,10 +14157,10 @@
 const char* Code::ToCString() const {
   Zone* zone = Thread::Current()->zone();
   if (IsStubCode()) {
-    const char* name = StubCode::NameOfStub(EntryPoint());
+    const char* name = StubCode::NameOfStub(UncheckedEntryPoint());
     return zone->PrintToString("[stub: %s]", name);
   } else {
-    return zone->PrintToString("Code entry:%" Px, EntryPoint());
+    return zone->PrintToString("Code entry:%" Px, UncheckedEntryPoint());
   }
 }
 
@@ -14219,7 +14171,7 @@
     // Regular stub.
     Thread* thread = Thread::Current();
     Zone* zone = thread->zone();
-    const char* name = StubCode::NameOfStub(EntryPoint());
+    const char* name = StubCode::NameOfStub(UncheckedEntryPoint());
     ASSERT(name != NULL);
     char* stub_name = OS::SCreate(zone,
         "%s%s", Symbols::StubPrefix().ToCString(), name);
@@ -14298,14 +14250,15 @@
   // 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());
+                  Instructions::UncheckedEntryPoint(instructions));
+  StoreNonPointer(&raw_ptr()->checked_entry_point_,
+                  Instructions::CheckedEntryPoint(instructions));
 }
 
 
 uword Code::GetLazyDeoptPc() const {
   return (lazy_deopt_pc_offset() != kInvalidPc)
-      ? EntryPoint() + lazy_deopt_pc_offset() : 0;
+      ? PayloadStart() + lazy_deopt_pc_offset() : 0;
 }
 
 
@@ -15365,6 +15318,25 @@
 }
 
 
+#if defined(DEBUG)
+bool Instance::CheckIsCanonical(Thread* thread) const {
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+  Instance& result = Instance::Handle(zone);
+  const Class& cls = Class::Handle(zone, this->clazz());
+  SafepointMutexLocker ml(isolate->constant_canonicalization_mutex());
+  result ^= cls.LookupCanonicalInstance(zone, *this);
+  // TODO(johnmccutchan) : Temporary workaround for issue (26988).
+  if ((result.raw() != raw()) &&
+      isolate->HasAttemptedReload() &&
+      (GetClassId() == kImmutableArrayCid)) {
+    return true;
+  }
+  return (result.raw() == this->raw());
+}
+#endif  // DEBUG
+
+
 RawAbstractType* Instance::GetType() const {
   if (IsNull()) {
     return Type::NullType();
@@ -16813,7 +16785,8 @@
         }
       } else if (!type_args.IsSubvectorEquivalent(other_type_args,
                                                   from_index,
-                                                  num_type_params)) {
+                                                  num_type_params,
+                                                  trail)) {
         return false;
       }
 #ifdef DEBUG
@@ -17172,6 +17145,38 @@
 }
 
 
+#if defined(DEBUG)
+bool Type::CheckIsCanonical(Thread* thread) const {
+  if (IsMalformed()) {
+    return true;
+  }
+  if (type_class() == Object::dynamic_class()) {
+    return (raw() == Object::dynamic_type().raw());
+  }
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+  AbstractType& type = Type::Handle(zone);
+  const Class& cls = Class::Handle(zone, type_class());
+
+  // Fast canonical lookup/registry for simple types.
+  if (!cls.IsGeneric() && !cls.IsClosureClass() && !cls.IsTypedefClass()) {
+    ASSERT(!IsFunctionType());
+    type = cls.CanonicalType();
+    return (raw() == type.raw());
+  }
+
+  ObjectStore* object_store = isolate->object_store();
+  {
+    SafepointMutexLocker ml(isolate->type_canonicalization_mutex());
+    CanonicalTypeSet table(zone, object_store->canonical_types());
+    type ^= table.GetOrNull(CanonicalTypeKey(*this));
+    object_store->set_canonical_types(table.Release());
+  }
+  return (raw() == type.raw());
+}
+#endif  // DEBUG
+
+
 RawString* Type::EnumerateURIs() const {
   if (IsDynamicType() || IsVoidType()) {
     return Symbols::Empty().raw();
@@ -17434,6 +17439,14 @@
 }
 
 
+#if defined(DEBUG)
+bool TypeRef::CheckIsCanonical(Thread* thread) const {
+  AbstractType& ref_type = AbstractType::Handle(type());
+  return ref_type.CheckIsCanonical(thread);
+}
+#endif  // DEBUG
+
+
 RawString* TypeRef::EnumerateURIs() const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -18097,11 +18110,11 @@
     case kDoubleCid:
       return Double::NewCanonical(Double::Cast(*this).value());
     case kBigintCid: {
+      if (this->IsCanonical()) {
+        return this->raw();
+      }
       Zone* zone = thread->zone();
       Isolate* isolate = thread->isolate();
-      if (!CheckAndCanonicalizeFields(thread, error_str)) {
-        return Instance::null();
-      }
       Bigint& result = Bigint::Handle(zone);
       const Class& cls = Class::Handle(zone, this->clazz());
       intptr_t index = 0;
@@ -18141,6 +18154,38 @@
 }
 
 
+#if defined(DEBUG)
+bool Number::CheckIsCanonical(Thread* thread) const {
+  intptr_t cid = GetClassId();
+  intptr_t idx = 0;
+  Zone* zone = thread->zone();
+  const Class& cls = Class::Handle(zone, this->clazz());
+  switch (cid) {
+    case kSmiCid:
+      return true;
+    case kMintCid: {
+      Mint& result = Mint::Handle(zone);
+      result ^= cls.LookupCanonicalMint(zone, Mint::Cast(*this).value(), &idx);
+      return (result.raw() == this->raw());
+    }
+    case kDoubleCid: {
+      Double& dbl = Double::Handle(zone);
+      dbl ^= cls.LookupCanonicalDouble(zone, Double::Cast(*this).value(), &idx);
+      return (dbl.raw() == this->raw());
+    }
+    case kBigintCid: {
+      Bigint& result = Bigint::Handle(zone);
+      result ^= cls.LookupCanonicalBigint(zone, Bigint::Cast(*this), &idx);
+      return (result.raw() == this->raw());
+    }
+    default:
+      UNREACHABLE();
+  }
+  return false;
+}
+#endif  // DEBUG
+
+
 const char* Number::ToCString() const {
   // Number is an interface. No instances of Number should exist.
   UNREACHABLE();
@@ -19841,6 +19886,15 @@
 }
 
 
+#if defined(DEBUG)
+bool String::CheckIsCanonical(Thread* thread) const {
+  Zone* zone = thread->zone();
+  const String& str = String::Handle(zone, Symbols::Lookup(thread, *this));
+  return (str.raw() == this->raw());
+}
+#endif  // DEBUG
+
+
 RawString* String::New(const char* cstr, Heap::Space space) {
   ASSERT(cstr != NULL);
   intptr_t array_len = strlen(cstr);
@@ -21361,6 +21415,7 @@
 
 void Array::MakeImmutable() const {
   if (IsImmutable()) return;
+  ASSERT(!IsCanonical());
   NoSafepointScope no_safepoint;
   uword tags = raw_ptr()->tags_;
   uword old_tags;
@@ -22317,7 +22372,7 @@
     } else {
       code = CodeAtFrame(i);
       ASSERT(function.raw() == code.function());
-      uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i));
+      uword pc = code.PayloadStart() + Smi::Value(PcOffsetAtFrame(i));
       if (code.is_optimized() &&
           expand_inlined() &&
           !FLAG_precompiled_runtime) {
@@ -22330,8 +22385,8 @@
             ASSERT(function.raw() == code.function());
             uword pc = it.pc();
             ASSERT(pc != 0);
-            ASSERT(code.EntryPoint() <= pc);
-            ASSERT(pc < (code.EntryPoint() + code.Size()));
+            ASSERT(code.PayloadStart() <= pc);
+            ASSERT(pc < (code.PayloadStart() + code.Size()));
             total_len += PrintOneStacktrace(
                 zone, &frame_strings, pc, function, code, *frame_index);
             (*frame_index)++;  // To account for inlined frames.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 143cf9e..b219ab7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1157,13 +1157,14 @@
 
   bool IsPrivate() const;
 
+  // Returns an array of instance and static fields defined by this class.
   RawArray* fields() const { return raw_ptr()->fields_; }
   void SetFields(const Array& value) const;
   void AddField(const Field& field) const;
   void AddFields(const GrowableArray<const Field*>& fields) const;
 
-  // Returns an array of all fields of this class and its superclasses indexed
-  // by offset in words.
+  // Returns an array of all instance fields of this class and its superclasses
+  // indexed by offset in words.
   RawArray* OffsetToFieldMap() const;
 
   // Returns true if non-static fields are defined.
@@ -1194,7 +1195,8 @@
   RawField* LookupInstanceField(const String& name) const;
   RawField* LookupStaticField(const String& name) const;
   RawField* LookupField(const String& name) const;
-  RawField* LookupFieldAllowPrivate(const String& name) const;
+  RawField* LookupFieldAllowPrivate(const String& name,
+                                    bool instance_only = false) const;
   RawField* LookupInstanceFieldAllowPrivate(const String& name) const;
   RawField* LookupStaticFieldAllowPrivate(const String& name) const;
 
@@ -1326,6 +1328,7 @@
   void DisableAllocationStub() const;
 
   RawArray* constants() const;
+  void set_constants(const Array& value) const;
 
   intptr_t FindInvocationDispatcherFunctionIndex(const Function& needle) const;
   RawFunction* InvocationDispatcherFunctionFromIndex(intptr_t idx) const;
@@ -1398,11 +1401,22 @@
   void ReplaceEnum(const Class& old_enum) const;
   void CopyStaticFieldValues(const Class& old_cls) const;
   void PatchFieldsAndFunctions() const;
+  void MigrateImplicitStaticClosures(IsolateReloadContext* context,
+                                     const Class& new_cls) const;
   void CopyCanonicalConstants(const Class& old_cls) const;
   void CopyCanonicalType(const Class& old_cls) const;
-  bool CanReload(const Class& replacement) const;
+  void CheckReload(const Class& replacement,
+                   IsolateReloadContext* context) const;
 
  private:
+  bool CanReloadFinalized(const Class& replacement,
+                          IsolateReloadContext* context) const;
+  bool CanReloadPreFinalized(const Class& replacement,
+                             IsolateReloadContext* context) const;
+
+  // Tells whether instances need morphing for reload.
+  bool RequiresInstanceMorphing(const Class& replacement) const;
+
   template <class FakeObject> static RawClass* NewCommon(intptr_t index);
 
   enum MemberKind {
@@ -1459,8 +1473,6 @@
   RawString* GenerateUserVisibleName() const;
   void set_state_bits(intptr_t bits) const;
 
-  void set_constants(const Array& value) const;
-
   void set_canonical_type(const Type& value) const;
   RawType* canonical_type() const;
 
@@ -1841,8 +1853,8 @@
 
   bool IsImmutable() const;
 
-  void Reset() const;
-  void ResetData() const;
+  void Reset(Zone* zone) const;
+  void ResetSwitchable(Zone* zone) const;
 
   // Note: only deopts with reasons before Unknown in this list are recorded in
   // the ICData. All other reasons are used purely for informational messages
@@ -1861,7 +1873,6 @@
     V(CheckClass)                                                              \
     V(CheckArrayBound)                                                         \
     V(AtCall)                                                                  \
-    V(Uint32Load)                                                              \
     V(GuardField)                                                              \
     V(TestCids)                                                                \
     V(NumReasons)                                                              \
@@ -1949,7 +1960,6 @@
   RawArray* FindFreeIndex(intptr_t* index) const;
 
   void DebugDump() const;
-  void ValidateSentinelLocations() const;
 
   // Returns true if this is a two arg smi operation.
   bool AddSmiSmiCheckForFastSmiStubs() const;
@@ -2055,78 +2065,6 @@
   void GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first,
                              GrowableArray<intptr_t>* second) const;
 
-  // Range feedback tracking functionality.
-
-  // For arithmetic operations we store range information for inputs and the
-  // result. The goal is to discover:
-  //
-  //    - on 32-bit platforms:
-  //         - when Mint operation is actually a int32/uint32 operation;
-  //         - when Smi operation produces non-smi results;
-  //
-  //    - on 64-bit platforms:
-  //         - when Smi operation is actually int32/uint32 operation;
-  //         - when Mint operation produces non-smi results;
-  //
-  enum RangeFeedback {
-    kSmiRange,
-    kInt32Range,
-    kUint32Range,
-    kInt64Range
-  };
-
-  // We use 4 bits per operand/result feedback. Our lattice allows us to
-  // express the following states:
-  //
-  //   - usmi   0000 [used only on 32bit platforms]
-  //   - smi    0001
-  //   - uint31 0010
-  //   - int32  0011
-  //   - uint32 0100
-  //   - int33  x1x1
-  //   - int64  1xxx
-  //
-  // DecodeRangeFeedbackAt() helper maps these states into the RangeFeedback
-  // enumeration.
-  enum RangeFeedbackLatticeBits {
-    kSignedRangeBit = 1 << 0,
-    kInt32RangeBit = 1 << 1,
-    kUint32RangeBit = 1 << 2,
-    kInt64RangeBit = 1 << 3,
-    kBitsPerRangeFeedback = 4,
-    kRangeFeedbackMask = (1 << kBitsPerRangeFeedback) - 1,
-    kRangeFeedbackSlots = 3
-  };
-
-  static bool IsValidRangeFeedbackIndex(intptr_t index) {
-    return (0 <= index) && (index < kRangeFeedbackSlots);
-  }
-
-  static intptr_t RangeFeedbackShift(intptr_t index) {
-    return (index * kBitsPerRangeFeedback) + kRangeFeedbackPos;
-  }
-
-  static const char* RangeFeedbackToString(RangeFeedback feedback) {
-    switch (feedback) {
-      case kSmiRange:
-        return "smi";
-      case kInt32Range:
-        return "int32";
-      case kUint32Range:
-        return "uint32";
-      case kInt64Range:
-        return "int64";
-      default:
-        UNREACHABLE();
-        return "?";
-    }
-  }
-
-  // It is only meaningful to interpret range feedback stored in the ICData
-  // when all checks are Mint or Smi.
-  bool HasRangeFeedback() const;
-  RangeFeedback DecodeRangeFeedbackAt(intptr_t idx) const;
-
   void PrintToJSONArray(const JSONArray& jsarray,
                         TokenPosition token_pos,
                         bool is_static_call) const;
@@ -2164,14 +2102,14 @@
   void set_ic_data_array(const Array& value) const;
   void set_state_bits(uint32_t bits) const;
 
+  bool ValidateInterceptor(const Function& target) const;
+
   enum {
     kNumArgsTestedPos = 0,
     kNumArgsTestedSize = 2,
     kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize,
     kDeoptReasonSize = kLastRecordedDeoptReason + 1,
-    kRangeFeedbackPos = kDeoptReasonPos + kDeoptReasonSize,
-    kRangeFeedbackSize = kBitsPerRangeFeedback * kRangeFeedbackSlots,
-    kStaticCallPos = kRangeFeedbackPos + kRangeFeedbackSize,
+    kStaticCallPos = kDeoptReasonPos + kDeoptReasonSize,
     kStaticCallSize = 1,
   };
 
@@ -2183,11 +2121,6 @@
                                           uint32_t,
                                           ICData::kDeoptReasonPos,
                                           ICData::kDeoptReasonSize> {};
-  class RangeFeedbackBits : public BitField<uint32_t,
-                                            uint32_t,
-                                            ICData::kRangeFeedbackPos,
-                                            ICData::kRangeFeedbackSize> {};
-
   class StaticCallBit : public BitField<uint32_t,
                                         bool,
                                         ICData::kStaticCallPos,
@@ -2199,7 +2132,7 @@
 
   intptr_t TestEntryLength() const;
   static RawArray* NewNonCachedEmptyICDataArray(intptr_t num_args_tested);
-  static RawArray* NewEmptyICDataArray(intptr_t num_args_tested);
+  static RawArray* CachedEmptyICDataArray(intptr_t num_args_tested);
   static RawICData* NewDescriptor(Zone* zone,
                                   const Function& owner,
                                   const String& target_name,
@@ -2814,8 +2747,8 @@
   void set_modifier(RawFunction::AsyncModifier value) const;
 
   // 'was_compiled' is true if the function was compiled once in this
-  // VM instantiation. It independent from presence of type feedback
-  // (ic_data_array) and code, whihc may be loaded from a snapshot.
+  // VM instantiation. It is independent from presence of type feedback
+  // (ic_data_array) and code, which may be loaded from a snapshot.
   void set_was_compiled(bool value) const {
     StoreNonPointer(&raw_ptr()->was_compiled_, value ? 1 : 0);
   }
@@ -3048,6 +2981,7 @@
   virtual RawString* DictionaryName() const { return name(); }
 
   bool is_static() const { return StaticBit::decode(raw_ptr()->kind_bits_); }
+  bool is_instance() const { return !is_static(); }
   bool is_final() const { return FinalBit::decode(raw_ptr()->kind_bits_); }
   bool is_const() const { return ConstBit::decode(raw_ptr()->kind_bits_); }
   bool is_reflectable() const {
@@ -3463,6 +3397,9 @@
 class Script : public Object {
  public:
   RawString* url() const { return raw_ptr()->url_; }
+
+  // The actual url which was loaded from disk, if provided by the embedder.
+  RawString* resolved_url() const { return raw_ptr()->resolved_url_; }
   bool HasSource() const;
   RawString* Source() const;
   RawString* GenerateSource() const;  // Generates source code from Tokenstream.
@@ -3477,6 +3414,11 @@
   // The load time in milliseconds since epoch.
   int64_t load_timestamp() const { return raw_ptr()->load_timestamp_; }
 
+  RawArray* compile_time_constants() const {
+    return raw_ptr()->compile_time_constants_;
+  }
+  void set_compile_time_constants(const Array& value) const;
+
   RawTokenStream* tokens() const { return raw_ptr()->tokens_; }
 
   void Tokenize(const String& private_key,
@@ -3513,8 +3455,14 @@
                         const String& source,
                         RawScript::Kind kind);
 
+  static RawScript* New(const String& url,
+                        const String& resolved_url,
+                        const String& source,
+                        RawScript::Kind kind);
+
  private:
   void set_url(const String& value) const;
+  void set_resolved_url(const String& value) const;
   void set_source(const String& value) const;
   void set_kind(RawScript::Kind value) const;
   void set_load_timestamp(int64_t value) const;
@@ -3524,6 +3472,7 @@
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Script, Object);
   friend class Class;
+  friend class Precompiler;
 };
 
 
@@ -3807,7 +3756,8 @@
   // the library-specific key.
   static const char kPrivateKeySeparator = '@';
 
-  bool CanReload(const Library& replacement) const;
+  void CheckReload(const Library& replacement,
+                   IsolateReloadContext* context) const;
 
  private:
   static const int kInitialImportsCapacity = 4;
@@ -3823,8 +3773,7 @@
   void InitClassDictionary() const;
 
   RawArray* resolved_names() const { return raw_ptr()->resolved_names_; }
-  void InitResolvedNamesCache(intptr_t size,
-                              SnapshotReader* reader = NULL) const;
+  void InitResolvedNamesCache(intptr_t size) const;
   void AllocateExportedNamesCache() const;
   void InitExportedNamesCache() const;
   static void InvalidateExportedNamesCaches();
@@ -4012,13 +3961,48 @@
  public:
   intptr_t size() const { return raw_ptr()->size_; }  // Excludes HeaderSize().
 
-  uword EntryPoint() const {
-    return EntryPoint(raw());
+  uword PayloadStart() const {
+    return PayloadStart(raw());
   }
-  static uword EntryPoint(RawInstructions* instr) {
+  uword UncheckedEntryPoint() const {
+    return UncheckedEntryPoint(raw());
+  }
+  uword CheckedEntryPoint() const {
+    return CheckedEntryPoint(raw());
+  }
+  static uword PayloadStart(RawInstructions* instr) {
     return reinterpret_cast<uword>(instr->ptr()) + HeaderSize();
   }
 
+#if defined(TARGET_ARCH_IA32)
+  static const intptr_t kCheckedEntryOffset = 0;
+  static const intptr_t kUncheckedEntryOffset = 0;
+#elif defined(TARGET_ARCH_X64)
+  static const intptr_t kCheckedEntryOffset = 23;
+  static const intptr_t kUncheckedEntryOffset = 44;
+#elif defined(TARGET_ARCH_ARM)
+  static const intptr_t kCheckedEntryOffset = 12;
+  static const intptr_t kUncheckedEntryOffset = 36;
+#elif defined(TARGET_ARCH_ARM64)
+  static const intptr_t kCheckedEntryOffset = 24;
+  static const intptr_t kUncheckedEntryOffset = 48;
+#elif defined(TARGET_ARCH_MIPS)
+  static const intptr_t kCheckedEntryOffset = 16;
+  static const intptr_t kUncheckedEntryOffset = 56;
+#elif defined(TARGET_ARCH_DBC)
+  static const intptr_t kCheckedEntryOffset = 0;
+  static const intptr_t kUncheckedEntryOffset = 0;
+#else
+#error Missing entry offsets for current architecture
+#endif
+
+  static uword UncheckedEntryPoint(RawInstructions* instr) {
+    return PayloadStart(instr) + kUncheckedEntryOffset;
+  }
+  static uword CheckedEntryPoint(RawInstructions* instr) {
+    return PayloadStart(instr) + kCheckedEntryOffset;
+  }
+
   static const intptr_t kMaxElements = (kMaxInt32 -
                                         (sizeof(RawInstructions) +
                                          sizeof(RawObject) +
@@ -4043,9 +4027,9 @@
     return Utils::RoundUp(sizeof(RawInstructions), alignment);
   }
 
-  static RawInstructions* FromEntryPoint(uword entry_point) {
+  static RawInstructions* FromUncheckedEntryPoint(uword entry_point) {
     return reinterpret_cast<RawInstructions*>(
-        entry_point - HeaderSize() + kHeapObjectTag);
+        entry_point - HeaderSize() - kUncheckedEntryOffset + kHeapObjectTag);
   }
 
   bool Equals(const Instructions& other) const {
@@ -4497,6 +4481,9 @@
   static intptr_t entry_point_offset() {
     return OFFSET_OF(RawCode, entry_point_);
   }
+  static intptr_t checked_entry_point_offset() {
+    return OFFSET_OF(RawCode, checked_entry_point_);
+  }
 
   RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
   static intptr_t object_pool_offset() {
@@ -4516,8 +4503,14 @@
   }
   void set_is_alive(bool value) const;
 
-  uword EntryPoint() const {
-    return Instructions::Handle(instructions()).EntryPoint();
+  uword PayloadStart() const {
+    return Instructions::PayloadStart(instructions());
+  }
+  uword UncheckedEntryPoint() const {
+    return Instructions::UncheckedEntryPoint(instructions());
+  }
+  uword CheckedEntryPoint() const {
+    return Instructions::CheckedEntryPoint(instructions());
   }
   intptr_t Size() const {
     const Instructions& instr = Instructions::Handle(instructions());
@@ -4528,7 +4521,7 @@
   }
   bool ContainsInstructionAt(uword addr) const {
     const Instructions& instr = Instructions::Handle(instructions());
-    const uword offset = addr - instr.EntryPoint();
+    const uword offset = addr - instr.PayloadStart();
     return offset < static_cast<uword>(instr.size());
   }
 
@@ -4554,7 +4547,7 @@
 
   // Used during reloading (see object_reload.cc). Calls Reset on all ICDatas
   // that are embedded inside the Code object.
-  void ResetICDatas() const;
+  void ResetICDatas(Zone* zone) const;
 
   TokenPosition GetTokenPositionAt(intptr_t offset) const;
 
@@ -5318,6 +5311,11 @@
   virtual bool CheckAndCanonicalizeFields(Thread* thread,
                                           const char** error_str) const;
 
+#if defined(DEBUG)
+  // Check if instance is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const;
+#endif  // DEBUG
+
   RawObject* GetField(const Field& field) const {
     return *FieldAddr(field);
   }
@@ -5398,7 +5396,6 @@
   RawObject** NativeFieldsAddr() const {
     return FieldAddrAtOffset(sizeof(RawObject));
   }
-
   void SetFieldAtOffset(intptr_t offset, const Object& value) const {
     StorePointer(FieldAddrAtOffset(offset), value.raw());
   }
@@ -5408,6 +5405,18 @@
     return sizeof(RawInstance);
   }
 
+  // The follwoing raw methods are used for morphing.
+  // They are needed due to the extraction of the class in IsValidFieldOffset.
+  RawObject** RawFieldAddrAtOffset(intptr_t offset) const {
+    return reinterpret_cast<RawObject**>(raw_value() - kHeapObjectTag + offset);
+  }
+  RawObject* RawGetFieldAtOffset(intptr_t offset) const {
+    return *RawFieldAddrAtOffset(offset);
+  }
+  void RawSetFieldAtOffset(intptr_t offset, const Object& value) const {
+    StorePointer(RawFieldAddrAtOffset(offset), value.raw());
+  }
+
   // TODO(iposva): Determine if this gets in the way of Smi.
   HEAP_OBJECT_IMPLEMENTATION(Instance, Object);
   friend class ByteBuffer;
@@ -5421,6 +5430,7 @@
   friend class InstanceSerializationCluster;
   friend class InstanceDeserializationCluster;
   friend class ClassDeserializationCluster;  // vtable
+  friend class InstanceMorpher;
 };
 
 
@@ -5552,6 +5562,14 @@
   // Return the canonical version of this type.
   virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
 
+#if defined(DEBUG)
+  // Check if abstract type is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const {
+    UNREACHABLE();
+    return false;
+  }
+#endif  // DEBUG
+
   // Return the object associated with the receiver in the trail or
   // AbstractType::null() if the receiver is not contained in the trail.
   RawAbstractType* OnlyBuddyInTrail(TrailPtr trail) const;
@@ -5743,6 +5761,10 @@
       const Class& new_owner,
       TrailPtr trail = NULL) const;
   virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+#if defined(DEBUG)
+  // Check if type is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const;
+#endif  // DEBUG
   virtual RawString* EnumerateURIs() const;
 
   virtual intptr_t Hash() const;
@@ -5871,6 +5893,10 @@
       const Class& new_owner,
       TrailPtr trail = NULL) const;
   virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+#if defined(DEBUG)
+  // Check if typeref is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const;
+#endif  // DEBUG
   virtual RawString* EnumerateURIs() const;
 
   virtual intptr_t Hash() const;
@@ -5946,6 +5972,12 @@
   virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const {
     return raw();
   }
+#if defined(DEBUG)
+  // Check if type parameter is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const {
+    return true;
+  }
+#endif  // DEBUG
   virtual RawString* EnumerateURIs() const;
 
   virtual intptr_t Hash() const;
@@ -6036,6 +6068,12 @@
   virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const {
     return raw();
   }
+#if defined(DEBUG)
+  // Check if bounded type is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const {
+    return true;
+  }
+#endif  // DEBUG
   virtual RawString* EnumerateURIs() const;
 
   virtual intptr_t Hash() const;
@@ -6124,6 +6162,11 @@
   virtual RawInstance* CheckAndCanonicalize(Thread* thread,
                                             const char** error_str) const;
 
+#if defined(DEBUG)
+  // Check if number is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const;
+#endif  // DEBUG
+
  private:
   OBJECT_IMPLEMENTATION(Number, Instance);
 
@@ -6600,6 +6643,11 @@
   virtual RawInstance* CheckAndCanonicalize(Thread* thread,
                                             const char** error_str) const;
 
+#if defined(DEBUG)
+  // Check if string is canonical.
+  virtual bool CheckIsCanonical(Thread* thread) const;
+#endif  // DEBUG
+
   bool IsSymbol() const { return raw()->IsCanonical(); }
 
   bool IsOneByteString() const {
@@ -8531,9 +8579,7 @@
 
 
 DART_FORCE_INLINE void Object::SetRaw(RawObject* value) {
-  // NOTE: The assignment "raw_ = value" should be the first statement in
-  // this function. Also do not use 'value' in this function after the
-  // assignment (use 'raw_' instead).
+  NoSafepointScope no_safepoint_scope;
   raw_ = value;
   if ((reinterpret_cast<uword>(value) & kSmiTagMask) == kSmiTag) {
     set_vtable(Smi::handle_vtable_);
@@ -8560,14 +8606,14 @@
 
 
 intptr_t Field::Offset() const {
-  ASSERT(!is_static());  // Valid only for dart instance fields.
+  ASSERT(is_instance());  // Valid only for dart instance fields.
   intptr_t value = Smi::Value(raw_ptr()->value_.offset_);
   return (value * kWordSize);
 }
 
 
 void Field::SetOffset(intptr_t offset_in_bytes) const {
-  ASSERT(!is_static());  // Valid only for dart instance fields.
+  ASSERT(is_instance());  // Valid only for dart instance fields.
   ASSERT(kWordSize != 0);
   StorePointer(&raw_ptr()->value_.offset_,
                Smi::New(offset_in_bytes / kWordSize));
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index bbecac7..b5a5cac 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -319,6 +319,36 @@
     }
   }
 
+  bool ShouldStop(RawObject* obj) {
+    // A static field is considered a root from a language point of view.
+    if (obj->IsField()) {
+      const Field& field = Field::Handle(static_cast<RawField*>(obj));
+      return field.is_static();
+    }
+    return false;
+  }
+
+  void StartList() {
+    was_last_array_ = false;
+  }
+
+  intptr_t HideNDescendant(RawObject* obj) {
+    // A GrowableObjectArray overwrites its internal storage.
+    // Keeping both of them in the list is redundant.
+    if (was_last_array_ && obj->IsGrowableObjectArray()) {
+      was_last_array_ = false;
+      return 1;
+    }
+    // A LinkedHasMap overwrites its internal storage.
+    // Keeping both of them in the list is redundant.
+    if (was_last_array_ && obj->IsLinkedHashMap()) {
+      was_last_array_ = false;
+      return 1;
+    }
+    was_last_array_ = obj->IsArray();
+    return 0;
+  }
+
   virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
     if (it->Get() != obj_) {
       if (ShouldSkip(it->Get())) {
@@ -330,7 +360,10 @@
       HANDLESCOPE(thread_);
       Object& current = Object::Handle();
       Smi& offset_from_parent = Smi::Handle();
+      StartList();
       do {
+        // We collapse the backingstore of some internal objects.
+        length_ -= HideNDescendant(it->Get());
         intptr_t obj_index = length_ * 2;
         intptr_t offset_index = obj_index + 1;
         if (!path_.IsNull() && offset_index < path_.Length()) {
@@ -340,7 +373,7 @@
           path_.SetAt(offset_index, offset_from_parent);
         }
         ++length_;
-      } while (it->MoveToParent());
+      } while (!ShouldStop(it->Get()) && it->MoveToParent());
       return kAbort;
     }
   }
@@ -350,6 +383,7 @@
   RawObject* obj_;
   const Array& path_;
   intptr_t length_;
+  bool was_last_array_;
 };
 
 
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index f9c5ad9..dd15a1f 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -4,6 +4,7 @@
 
 #include "vm/object.h"
 
+#include "vm/hash_table.h"
 #include "vm/isolate_reload.h"
 #include "vm/log.h"
 #include "vm/resolver.h"
@@ -14,9 +15,9 @@
 #ifndef PRODUCT
 
 DECLARE_FLAG(bool, trace_reload);
+DECLARE_FLAG(bool, trace_reload_verbose);
 DECLARE_FLAG(bool, two_args_smi_icd);
 
-#define IRC (Isolate::Current()->reload_context())
 
 class ObjectReloadUtils : public AllStatic {
   static void DumpLibraryDictionary(const Library& lib) {
@@ -56,7 +57,7 @@
 }
 
 
-void Code::ResetICDatas() const {
+void Code::ResetICDatas(Zone* zone) const {
   // Iterate over the Code's object pool and reset all ICDatas.
 #ifdef TARGET_ARCH_IA32
   // IA32 does not have an object pool, but, we can iterate over all
@@ -64,10 +65,10 @@
   if (!is_alive()) {
     return;
   }
-  const Instructions& instrs = Instructions::Handle(instructions());
+  const Instructions& instrs = Instructions::Handle(zone, instructions());
   ASSERT(!instrs.IsNull());
-  uword base_address = instrs.EntryPoint();
-  Object& object = Object::Handle();
+  uword base_address = instrs.PayloadStart();
+  Object& object = Object::Handle(zone);
   intptr_t offsets_length = pointer_offsets_length();
   const int32_t* offsets = raw_ptr()->data();
   for (intptr_t i = 0; i < offsets_length; i++) {
@@ -80,12 +81,12 @@
     }
     object = raw_object;
     if (object.IsICData()) {
-      ICData::Cast(object).Reset();
+      ICData::Cast(object).Reset(zone);
     }
   }
 #else
-  const ObjectPool& pool = ObjectPool::Handle(object_pool());
-  Object& object = Object::Handle();
+  const ObjectPool& pool = ObjectPool::Handle(zone, object_pool());
+  Object& object = Object::Handle(zone);
   ASSERT(!pool.IsNull());
   for (intptr_t i = 0; i < pool.Length(); i++) {
     ObjectPool::EntryType entry_type = pool.InfoAt(i);
@@ -94,7 +95,7 @@
     }
     object = pool.ObjectAt(i);
     if (object.IsICData()) {
-      ICData::Cast(object).Reset();
+      ICData::Cast(object).Reset(zone);
     }
   }
 #endif
@@ -141,6 +142,8 @@
 
 void Class::CopyCanonicalConstants(const Class& old_cls) const {
   if (is_enum_class()) {
+    // We do not copy enum classes's canonical constants because we explicitly
+    // become the old enum values to the new enum values.
     return;
   }
 #if defined(DEBUG)
@@ -171,31 +174,47 @@
 }
 
 
-static intptr_t IndexOfEnum(const Array& enum_names, const String& name) {
-  ASSERT(!enum_names.IsNull());
-  ASSERT(!name.IsNull());
-  String& enum_name = String::Handle();
-  for (intptr_t i = 0; i < enum_names.Length(); i++) {
-    enum_name = String::RawCast(enum_names.At(i));
-    ASSERT(!enum_name.IsNull());
-    if (enum_name.Equals(name)) {
-      return i;
-    }
+class EnumMapTraits {
+ public:
+  static bool ReportStats() { return false; }
+  static const char* Name() { return "EnumMapTraits"; }
+
+  static bool IsMatch(const Object& a, const Object& b) {
+    return a.raw() == b.raw();
   }
 
-  return -1;
-}
+  static uword Hash(const Object& obj) {
+    ASSERT(obj.IsString());
+    return String::Cast(obj).Hash();
+  }
+};
 
 
-static void UpdateEnumIndex(const Instance& enum_value,
-                            const Field& enum_index_field,
-                            const intptr_t index) {
-  enum_value.SetField(enum_index_field, Smi::Handle(Smi::New(index)));
-}
-
-
-// TODO(johnmccutchan): The code in the class finalizer canonicalizes all
-// instances and the values array. We probably should do the same thing.
+// Given an old enum class, add become mappings from old values to new values.
+// Some notes about how we reload enums below:
+//
+// When an enum is reloaded the following three things can happen, possibly
+// simultaneously.
+//
+// 1) A new enum value is added.
+//   This case is handled automatically.
+// 2) Enum values are reordered.
+//   We pair old and new enums and the old enums 'become' the new ones so
+//   the ordering is always correct (i.e. enum indicies match slots in values
+//   array)
+// 3) An existing enum value is removed.
+//   We leave old enum values that have no mapping to the reloaded class
+//   in the heap. This means that if a programmer does the following:
+//   enum Foo { A, B }; var x = Foo.A;
+//   *reload*
+//   enum Foo { B };
+//   *reload*
+//   enum Foo { A, B }; expect(identical(x, Foo.A));
+//   The program will fail because we were not able to pair Foo.A on the second
+//   reload.
+//
+//   Deleted enum values still in the heap continue to function but their
+//   index field will not be valid.
 void Class::ReplaceEnum(const Class& old_enum) const {
   // We only do this for finalized enum classes.
   ASSERT(is_enum_class());
@@ -204,160 +223,108 @@
   ASSERT(old_enum.is_finalized());
 
   Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
   IsolateReloadContext* reload_context = Isolate::Current()->reload_context();
   ASSERT(reload_context != NULL);
 
-  TIR_Print("ReplaceEnum `%s` (%" Pd " and %" Pd ")\n",
-            ToCString(), id(), old_enum.id());
+  Array& enum_fields = Array::Handle(zone);
+  Field& field = Field::Handle(zone);
+  String& enum_ident = String::Handle();
+  Instance& old_enum_value = Instance::Handle(zone);
+  Instance& enum_value = Instance::Handle(zone);
+  // The E.values array.
+  Instance& old_enum_values = Instance::Handle(zone);
+  // The E.values array.
+  Instance& enum_values = Instance::Handle(zone);
+  Array& enum_map_storage = Array::Handle(zone,
+      HashTables::New<UnorderedHashMap<EnumMapTraits> >(4));
+  ASSERT(!enum_map_storage.IsNull());
 
-  // Grab '_enum_names' from |old_enum|.
-  const Field& old_enum_names_field = Field::Handle(
-      old_enum.LookupStaticFieldAllowPrivate(Symbols::_EnumNames()));
-  ASSERT(!old_enum_names_field.IsNull());
-  const Array& old_enum_names =
-      Array::Handle(Array::RawCast(old_enum_names_field.StaticValue()));
-  ASSERT(!old_enum_names.IsNull());
+  TIR_Print("Replacing enum `%s`\n", String::Handle(Name()).ToCString());
 
-  // Grab 'values' from |old_enum|.
-  const Field& old_enum_values_field = Field::Handle(
-      old_enum.LookupStaticField(Symbols::Values()));
-  ASSERT(!old_enum_values_field.IsNull());
-  const Array& old_enum_values =
-      Array::Handle(Array::RawCast(old_enum_values_field.StaticValue()));
-  ASSERT(!old_enum_values.IsNull());
-
-  // Grab _enum_names from |this|.
-  const Field& enum_names_field = Field::Handle(
-      LookupStaticFieldAllowPrivate(Symbols::_EnumNames()));
-  ASSERT(!enum_names_field.IsNull());
-  Array& enum_names =
-      Array::Handle(Array::RawCast(enum_names_field.StaticValue()));
-  ASSERT(!enum_names.IsNull());
-
-  // Grab values from |this|.
-  const Field& enum_values_field = Field::Handle(
-      LookupStaticField(Symbols::Values()));
-  ASSERT(!enum_values_field.IsNull());
-  Array& enum_values =
-      Array::Handle(Array::RawCast(enum_values_field.StaticValue()));
-  ASSERT(!enum_values.IsNull());
-
-  // Grab the |index| field.
-  const Field& index_field =
-      Field::Handle(old_enum.LookupInstanceField(Symbols::Index()));
-  ASSERT(!index_field.IsNull());
-
-  // Build list of enum from |old_enum| that aren't present in |this|.
-  // This array holds pairs: (name, value).
-  const GrowableObjectArray& to_add =
-      GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld));
-  const String& enum_class_name = String::Handle(UserVisibleName());
-  String& enum_name = String::Handle();
-  String& enum_field_name = String::Handle();
-  Object& enum_value = Object::Handle();
-  Field& enum_field = Field::Handle();
-
-  TIR_Print("New version of enum has %" Pd " elements\n",
-            enum_values.Length());
-  TIR_Print("Old version of enum had %" Pd " elements\n",
-            old_enum_values.Length());
-
-  for (intptr_t i = 0; i < old_enum_names.Length(); i++) {
-    enum_name = String::RawCast(old_enum_names.At(i));
-    const intptr_t index_in_new_cls = IndexOfEnum(enum_names, enum_name);
-    if (index_in_new_cls < 0) {
-      // Doesn't exist in new enum, add.
-      TIR_Print("Adding enum value `%s` to %s\n",
-                enum_name.ToCString(),
-                this->ToCString());
-      enum_value = old_enum_values.At(i);
-      ASSERT(!enum_value.IsNull());
-      to_add.Add(enum_name);
-      to_add.Add(enum_value);
-    } else {
-      // Exists in both the new and the old.
-      TIR_Print("Moving enum value `%s` to %" Pd "\n",
-                enum_name.ToCString(),
-                index_in_new_cls);
-      // Grab old value.
-      enum_value = old_enum_values.At(i);
-      // Update index to the be new index.
-      UpdateEnumIndex(Instance::Cast(enum_value),
-                      index_field,
-                      index_in_new_cls);
-      // Chop off the 'EnumClass.'
-      enum_field_name = String::SubString(enum_name,
-                                          enum_class_name.Length() + 1);
-      ASSERT(!enum_field_name.IsNull());
-      // Grab the static field.
-      enum_field = LookupStaticField(enum_field_name);
-      ASSERT(!enum_field.IsNull());
-      // Use old value with updated index.
-      enum_field.SetStaticValue(Instance::Cast(enum_value), true);
-      enum_values.SetAt(index_in_new_cls, enum_value);
-      enum_names.SetAt(index_in_new_cls, enum_name);
+  {
+    UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw());
+    // Build a map of all enum name -> old enum instance.
+    enum_fields = old_enum.fields();
+    for (intptr_t i = 0; i < enum_fields.Length(); i++) {
+      field = Field::RawCast(enum_fields.At(i));
+      enum_ident = field.name();
+      if (!field.is_static()) {
+        // Enum instances are only held in static fields.
+        continue;
+      }
+      if (enum_ident.Equals(Symbols::Values())) {
+        old_enum_values = field.StaticValue();
+        // Non-enum instance.
+        continue;
+      }
+      old_enum_value = field.StaticValue();
+      ASSERT(!old_enum_value.IsNull());
+      VTIR_Print("Element %s being added to mapping\n", enum_ident.ToCString());
+      bool update = enum_map.UpdateOrInsert(enum_ident, old_enum_value);
+      VTIR_Print("Element %s added to mapping\n", enum_ident.ToCString());
+      ASSERT(!update);
     }
+    // The storage given to the map may have been reallocated, remember the new
+    // address.
+    enum_map_storage = enum_map.Release().raw();
   }
 
-  if (to_add.Length() == 0) {
-    // Nothing to do.
-    TIR_Print("Found no missing enums in %s\n", ToCString());
-    return;
+  bool enums_deleted = false;
+  {
+    UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw());
+    // Add a become mapping from the old instances to the new instances.
+    enum_fields = fields();
+    for (intptr_t i = 0; i < enum_fields.Length(); i++) {
+      field = Field::RawCast(enum_fields.At(i));
+      enum_ident = field.name();
+      if (!field.is_static()) {
+        // Enum instances are only held in static fields.
+        continue;
+      }
+      if (enum_ident.Equals(Symbols::Values())) {
+        enum_values = field.StaticValue();
+        // Non-enum instance.
+        continue;
+      }
+      enum_value = field.StaticValue();
+      ASSERT(!enum_value.IsNull());
+      old_enum_value ^= enum_map.GetOrNull(enum_ident);
+      if (old_enum_value.IsNull()) {
+        VTIR_Print("New element %s was not found in mapping\n",
+                   enum_ident.ToCString());
+      } else {
+        VTIR_Print("Adding element `%s` to become mapping\n",
+                   enum_ident.ToCString());
+        bool removed = enum_map.Remove(enum_ident);
+        ASSERT(removed);
+        reload_context->AddEnumBecomeMapping(old_enum_value, enum_value);
+      }
+    }
+    enums_deleted = enum_map.NumOccupied() > 0;
+    // The storage given to the map may have been reallocated, remember the new
+    // address.
+    enum_map_storage = enum_map.Release().raw();
   }
 
-  // Grow the values and enum_names arrays.
-  const intptr_t offset = enum_names.Length();
-  const intptr_t num_to_add = to_add.Length() / 2;
-  ASSERT(offset == enum_values.Length());
-  enum_names = Array::Grow(enum_names,
-                           enum_names.Length() + num_to_add,
-                           Heap::kOld);
-  enum_values = Array::Grow(enum_values,
-                            enum_values.Length() + num_to_add,
-                            Heap::kOld);
+  // Map the old E.values array to the new E.values array.
+  ASSERT(!old_enum_values.IsNull());
+  ASSERT(!enum_values.IsNull());
+  reload_context->AddEnumBecomeMapping(old_enum_values, enum_values);
 
-  // Install new names and values into the grown arrays. Also, update
-  // the index of the new enum values and add static fields for the new
-  // enum values.
-  Field& enum_value_field = Field::Handle();
-  for (intptr_t i = 0; i < num_to_add; i++) {
-    const intptr_t target_index = offset + i;
-    enum_name = String::RawCast(to_add.At(i * 2));
-    enum_value = to_add.At(i * 2 + 1);
-
-    // Update the enum value's index into the new arrays.
-    TIR_Print("Updating index of %s in %s to %" Pd "\n",
-              enum_name.ToCString(),
-              ToCString(),
-              target_index);
-    UpdateEnumIndex(Instance::Cast(enum_value), index_field, target_index);
-
-    enum_names.SetAt(target_index, enum_name);
-    enum_values.SetAt(target_index, enum_value);
-
-    // Install new static field into class.
-    // Chop off the 'EnumClass.'
-    enum_field_name = String::SubString(enum_name,
-                                        enum_class_name.Length() + 1);
-    ASSERT(!enum_field_name.IsNull());
-    enum_field_name = Symbols::New(thread, enum_field_name);
-    enum_value_field = Field::New(enum_field_name,
-                                  /* is_static = */ true,
-                                  /* is_final = */ true,
-                                  /* is_const = */ true,
-                                  /* is_reflectable = */ true,
-                                  *this,
-                                  Object::dynamic_type(),
-                                  token_pos());
-    enum_value_field.set_has_initializer(false);
-    enum_value_field.SetStaticValue(Instance::Cast(enum_value), true);
-    enum_value_field.RecordStore(Instance::Cast(enum_value));
-    AddField(enum_value_field);
+  if (enums_deleted && FLAG_trace_reload_verbose) {
+    // TODO(johnmccutchan): Add this to the reload 'notices' list.
+    VTIR_Print("The following enum values were deleted and are forever lost in "
+               "the heap:\n");
+    UnorderedHashMap<EnumMapTraits> enum_map(enum_map_storage.raw());
+    UnorderedHashMap<EnumMapTraits>::Iterator it(&enum_map);
+    while (it.MoveNext()) {
+      const intptr_t entry = it.Current();
+      enum_ident = String::RawCast(enum_map.GetKey(entry));
+      ASSERT(!enum_ident.IsNull());
+    }
+    enum_map.Release();
   }
-
-  // Replace the arrays stored in the static fields.
-  enum_names_field.SetStaticValue(enum_names, true);
-  enum_values_field.SetStaticValue(enum_values, true);
 }
 
 
@@ -406,161 +373,387 @@
 }
 
 
-bool Class::CanReload(const Class& replacement) const {
-  ASSERT(IsolateReloadContext::IsSameClass(*this, replacement));
+void Class::MigrateImplicitStaticClosures(IsolateReloadContext* irc,
+                                          const Class& new_cls) const {
+  const Array& funcs = Array::Handle(functions());
+  Function& old_func = Function::Handle();
+  String& selector = String::Handle();
+  Function& new_func = Function::Handle();
+  Instance& old_closure = Instance::Handle();
+  Instance& new_closure = Instance::Handle();
+  for (intptr_t i = 0; i < funcs.Length(); i++) {
+    old_func ^= funcs.At(i);
+    if (old_func.is_static() &&
+      old_func.HasImplicitClosureFunction()) {
+      selector = old_func.name();
+      new_func = new_cls.LookupFunction(selector);
+      if (!new_func.IsNull() && new_func.is_static()) {
+        old_func = old_func.ImplicitClosureFunction();
+        old_closure = old_func.ImplicitStaticClosure();
+        new_func = new_func.ImplicitClosureFunction();
+        new_closure = new_func.ImplicitStaticClosure();
+        irc->AddBecomeMapping(old_closure, new_closure);
+      }
+    }
+  }
+}
 
-  if (is_enum_class() && !replacement.is_enum_class()) {
-    IRC->ReportError(String::Handle(String::NewFormatted(
-        "Enum class cannot be redefined to be a non-enum class: %s",
-        ToCString())));
-    return false;
+
+class EnumClassConflict : public ClassReasonForCancelling {
+ public:
+  EnumClassConflict(Zone* zone, const Class& from, const Class& to)
+      : ClassReasonForCancelling(zone, from, to) { }
+
+  RawString* ToString() {
+    return String::NewFormatted(
+        from_.is_enum_class()
+        ? "Enum class cannot be redefined to be a non-enum class: %s"
+        : "Class cannot be redefined to be a enum class: %s",
+        from_.ToCString());
+  }
+};
+
+
+class EnsureFinalizedError : public ClassReasonForCancelling {
+ public:
+  EnsureFinalizedError(Zone* zone,
+                       const Class& from,
+                       const Class& to,
+                       const Error& error)
+      : ClassReasonForCancelling(zone, from, to), error_(error) { }
+
+ private:
+  const Error& error_;
+
+  RawError* ToError() { return error_.raw(); }
+
+  RawString* ToString() {
+    return String::New(error_.ToErrorCString());
+  }
+};
+
+
+class NativeFieldsConflict : public ClassReasonForCancelling {
+ public:
+  NativeFieldsConflict(Zone* zone, const Class& from, const Class& to)
+      : ClassReasonForCancelling(zone, from, to) { }
+
+ private:
+  RawString* ToString() {
+    return String::NewFormatted(
+        "Number of native fields changed in %s", from_.ToCString());
+  }
+};
+
+
+class TypeParametersChanged : public ClassReasonForCancelling {
+ public:
+  TypeParametersChanged(Zone* zone, const Class& from, const Class& to)
+      : ClassReasonForCancelling(zone, from, to) {}
+
+  RawString* ToString() {
+    return String::NewFormatted(
+        "Limitation: type parameters have changed for %s", from_.ToCString());
   }
 
-  if (!is_enum_class() && replacement.is_enum_class()) {
-    IRC->ReportError(String::Handle(String::NewFormatted(
-        "Class cannot be redefined to be a enum class: %s",
-        ToCString())));
-    return false;
+  void AppendTo(JSONArray* array) {
+    JSONObject jsobj(array);
+    jsobj.AddProperty("type", "ReasonForCancellingReload");
+    jsobj.AddProperty("kind", "TypeParametersChanged");
+    jsobj.AddProperty("class", to_);
+    jsobj.AddProperty("message",
+                      "Limitation: changing type parameters "
+                      "does not work with hot reload.");
+  }
+};
+
+
+class PreFinalizedConflict :  public ClassReasonForCancelling {
+ public:
+  PreFinalizedConflict(Zone* zone, const Class& from, const Class& to)
+      : ClassReasonForCancelling(zone, from, to) {}
+
+ private:
+  RawString* ToString() {
+    return String::NewFormatted(
+        "Original class ('%s') is prefinalized and replacement class "
+        "('%s') is not ",
+        from_.ToCString(), to_.ToCString());
+  }
+};
+
+
+class InstanceSizeConflict :  public ClassReasonForCancelling {
+ public:
+  InstanceSizeConflict(Zone* zone, const Class& from, const Class& to)
+      : ClassReasonForCancelling(zone, from, to) {}
+
+ private:
+  RawString* ToString() {
+    return String::NewFormatted(
+        "Instance size mismatch between '%s' (%" Pd ") and replacement "
+        "'%s' ( %" Pd ")",
+        from_.ToCString(),
+        from_.instance_size(),
+        to_.ToCString(),
+        to_.instance_size());
+  }
+};
+
+
+class UnimplementedDeferredLibrary : public ReasonForCancelling {
+ public:
+  UnimplementedDeferredLibrary(Zone* zone,
+                               const Library& from,
+                               const Library& to,
+                               const String& name)
+      : ReasonForCancelling(zone), from_(from), to_(to), name_(name) {}
+
+ private:
+  const Library& from_;
+  const Library& to_;
+  const String& name_;
+
+  RawString* ToString() {
+    const String& lib_url = String::Handle(to_.url());
+    from_.ToCString();
+    return String::NewFormatted(
+        "Reloading support for deferred loading has not yet been implemented:"
+        " library '%s' has deferred import '%s'",
+        lib_url.ToCString(), name_.ToCString());
+  }
+};
+
+
+// This is executed before interating over the instances.
+void Class::CheckReload(const Class& replacement,
+                        IsolateReloadContext* context) const {
+  ASSERT(IsolateReloadContext::IsSameClass(*this, replacement));
+
+  // Class cannot change enum property.
+  if (is_enum_class() != replacement.is_enum_class()) {
+    context->AddReasonForCancelling(
+        new(context->zone())
+            EnumClassConflict(context->zone(), *this, replacement));
+    return;
   }
 
   if (is_finalized()) {
+    // Ensure the replacement class is also finalized.
     const Error& error =
         Error::Handle(replacement.EnsureIsFinalized(Thread::Current()));
     if (!error.IsNull()) {
-      IRC->ReportError(error);
-      return false;
+      context->AddReasonForCancelling(
+          new(context->zone())
+              EnsureFinalizedError(context->zone(), *this, replacement, error));
+      return;  // No reason to check other properties.
     }
+    ASSERT(replacement.is_finalized());
     TIR_Print("Finalized replacement class for %s\n", ToCString());
   }
 
-  // At this point the original and replacement must be in the same state.
-  ASSERT(is_finalized() == replacement.is_finalized());
+  // Native field count cannot change.
+  if (num_native_fields() != replacement.num_native_fields()) {
+      context->AddReasonForCancelling(
+          new(context->zone())
+              NativeFieldsConflict(context->zone(), *this, replacement));
+      return;
+  }
+
+  // Just checking.
+  ASSERT(is_enum_class() == replacement.is_enum_class());
+  ASSERT(num_native_fields() == replacement.num_native_fields());
 
   if (is_finalized()) {
-    // Get the field maps for both classes. These field maps walk the class
-    // hierarchy.
-    const Array& fields =
-        Array::Handle(OffsetToFieldMap());
-    const Array& replacement_fields =
-        Array::Handle(replacement.OffsetToFieldMap());
-
-    // Check that the size of the instance is the same.
-    if (fields.Length() != replacement_fields.Length()) {
-      IRC->ReportError(String::Handle(String::NewFormatted(
-          "Number of instance fields changed in %s", ToCString())));
-      return false;
-    }
-
-    // Check that we have the same next field offset. This check is not
-    // redundant with the one above because the instance OffsetToFieldMap
-    // array length is based on the instance size (which may be aligned up).
-    if (next_field_offset() != replacement.next_field_offset()) {
-      IRC->ReportError(String::Handle(String::NewFormatted(
-          "Number of instance fields changed in %s", ToCString())));
-      return false;
-    }
-
-    if (NumTypeArguments() != replacement.NumTypeArguments()) {
-      IRC->ReportError(String::Handle(String::NewFormatted(
-          "Number of type arguments changed in %s", ToCString())));
-      return false;
-    }
-
-    // Verify that field names / offsets match across the entire hierarchy.
-    Field& field = Field::Handle();
-    String& field_name = String::Handle();
-    Field& replacement_field = Field::Handle();
-    String& replacement_field_name = String::Handle();
-    for (intptr_t i = 0; i < fields.Length(); i++) {
-      if (fields.At(i) == Field::null()) {
-        ASSERT(replacement_fields.At(i) == Field::null());
-        continue;
-      }
-      field = Field::RawCast(fields.At(i));
-      replacement_field = Field::RawCast(replacement_fields.At(i));
-      field_name = field.name();
-      replacement_field_name = replacement_field.name();
-      if (!field_name.Equals(replacement_field_name)) {
-        IRC->ReportError(String::Handle(String::NewFormatted(
-            "Name of instance field changed ('%s' vs '%s') in '%s'",
-            field_name.ToCString(),
-            replacement_field_name.ToCString(),
-            ToCString())));
-        return false;
-      }
-    }
-  } else if (is_prefinalized()) {
-    if (!replacement.is_prefinalized()) {
-      IRC->ReportError(String::Handle(String::NewFormatted(
-          "Original class ('%s') is prefinalized and replacement class "
-          "('%s') is not ",
-          ToCString(), replacement.ToCString())));
-      return false;
-    }
-    if (instance_size() != replacement.instance_size()) {
-     IRC->ReportError(String::Handle(String::NewFormatted(
-         "Instance size mismatch between '%s' (%" Pd ") and replacement "
-         "'%s' ( %" Pd ")",
-         ToCString(),
-         instance_size(),
-         replacement.ToCString(),
-         replacement.instance_size())));
-     return false;
-    }
+    if (!CanReloadFinalized(replacement, context)) return;
   }
+  if (is_prefinalized()) {
+    if (!CanReloadPreFinalized(replacement, context)) return;
+  }
+  ASSERT(is_finalized() == replacement.is_finalized());
+  TIR_Print("Class `%s` can be reloaded (%" Pd " and %" Pd ")\n",
+            ToCString(), id(), replacement.id());
+}
 
-  // native field count check.
-  if (num_native_fields() != replacement.num_native_fields()) {
-    IRC->ReportError(String::Handle(String::NewFormatted(
-        "Number of native fields changed in %s", ToCString())));
+
+
+bool Class::RequiresInstanceMorphing(const Class& replacement) const {
+  // Get the field maps for both classes. These field maps walk the class
+  // hierarchy.
+  const Array& fields = Array::Handle(OffsetToFieldMap());
+  const Array& replacement_fields
+      = Array::Handle(replacement.OffsetToFieldMap());
+
+  // Check that the size of the instance is the same.
+  if (fields.Length() != replacement_fields.Length()) return true;
+
+  // Check that we have the same next field offset. This check is not
+  // redundant with the one above because the instance OffsetToFieldMap
+  // array length is based on the instance size (which may be aligned up).
+  if (next_field_offset() != replacement.next_field_offset()) return true;
+
+  // Verify that field names / offsets match across the entire hierarchy.
+  Field& field = Field::Handle();
+  String& field_name = String::Handle();
+  Field& replacement_field = Field::Handle();
+  String& replacement_field_name = String::Handle();
+
+  for (intptr_t i = 0; i < fields.Length(); i++) {
+    if (fields.At(i) == Field::null()) {
+      ASSERT(replacement_fields.At(i) == Field::null());
+      continue;
+    }
+    field = Field::RawCast(fields.At(i));
+    replacement_field = Field::RawCast(replacement_fields.At(i));
+    field_name = field.name();
+    replacement_field_name = replacement_field.name();
+    if (!field_name.Equals(replacement_field_name)) return true;
+  }
+  return false;
+}
+
+
+bool Class::CanReloadFinalized(const Class& replacement,
+                               IsolateReloadContext* context) const {
+  // Make sure the declaration types matches for the two classes.
+  // ex. class A<int,B> {} cannot be replace with class A<B> {}.
+
+  const AbstractType& dt = AbstractType::Handle(DeclarationType());
+  const AbstractType& replacement_dt =
+      AbstractType::Handle(replacement.DeclarationType());
+  if (!dt.Equals(replacement_dt)) {
+    context->AddReasonForCancelling(
+        new(context->zone())
+            TypeParametersChanged(context->zone(), *this, replacement));
     return false;
   }
-
-  // TODO(johnmccutchan) type parameter count check.
-
-  TIR_Print("Class `%s` can be reloaded (%" Pd " and %" Pd ")\n",
-            ToCString(),
-            id(),
-            replacement.id());
+  if (RequiresInstanceMorphing(replacement)) {
+    context->AddInstanceMorpher(
+        new(context->zone())
+            InstanceMorpher(context->zone(), *this, replacement));
+  }
   return true;
 }
 
 
-bool Library::CanReload(const Library& replacement) const {
+bool Class::CanReloadPreFinalized(const Class& replacement,
+                                  IsolateReloadContext* context) const {
+  // The replacement class must also prefinalized.
+  if (!replacement.is_prefinalized()) {
+      context->AddReasonForCancelling(
+          new(context->zone())
+              PreFinalizedConflict(context->zone(), *this, replacement));
+      return false;
+  }
+  // Check the instance sizes are equal.
+  if (instance_size() != replacement.instance_size()) {
+      context->AddReasonForCancelling(
+          new(context->zone())
+              InstanceSizeConflict(context->zone(), *this, replacement));
+      return false;
+  }
   return true;
 }
 
 
+void Library::CheckReload(const Library& replacement,
+                          IsolateReloadContext* context) const {
+  // TODO(26878): If the replacement library uses deferred loading,
+  // reject it.  We do not yet support reloading deferred libraries.
+  LibraryPrefix& prefix = LibraryPrefix::Handle();
+  LibraryPrefixIterator it(replacement);
+  while (it.HasNext()) {
+    prefix = it.GetNext();
+    if (prefix.is_deferred_load()) {
+      const String& prefix_name = String::Handle(prefix.name());
+      context->AddReasonForCancelling(
+          new(context->zone())
+              UnimplementedDeferredLibrary(context->zone(),
+                                           *this, replacement, prefix_name));
+      return;
+    }
+  }
+}
+
+
 static const Function* static_call_target = NULL;
 
-void ICData::Reset() const {
+
+void ICData::Reset(Zone* zone) const {
   if (is_static_call()) {
-    const Function& old_target = Function::Handle(GetTargetAt(0));
+    const Function& old_target = Function::Handle(zone, GetTargetAt(0));
     if (old_target.IsNull()) {
       FATAL("old_target is NULL.\n");
     }
     static_call_target = &old_target;
+
+    const String& selector = String::Handle(zone, old_target.name());
+    Function& new_target = Function::Handle(zone);
     if (!old_target.is_static()) {
-      // TODO(johnmccutchan): Improve this.
-      TIR_Print("Cannot rebind super-call to %s from %s\n",
-                old_target.ToCString(),
-                Object::Handle(Owner()).ToCString());
-      return;
+      if (old_target.kind() == RawFunction::kConstructor) {
+        return;  // Super constructor call.
+      }
+      Function& caller = Function::Handle(zone);
+      caller ^= Owner();
+      ASSERT(!caller.is_static());
+      Class& cls = Class::Handle(zone, caller.Owner());
+      if (cls.raw() == old_target.Owner()) {
+        // Dispatcher.
+        if (caller.IsImplicitClosureFunction()) {
+          return;  // Tear-off.
+        }
+        if (caller.kind() == RawFunction::kNoSuchMethodDispatcher) {
+          // TODO(rmacnak): noSuchMethod might have been redefined.
+          return;
+        }
+        const Function& caller_parent =
+            Function::Handle(zone, caller.parent_function());
+        if (!caller_parent.IsNull()) {
+          if (caller_parent.kind() == RawFunction::kInvokeFieldDispatcher) {
+            return;  // Call-through-getter.
+          }
+        }
+        FATAL2("Unexpected dispatcher-like call site: %s from %s\n",
+               selector.ToCString(), caller.ToQualifiedCString());
+      }
+      // Super call.
+      cls = cls.SuperClass();
+      while (!cls.IsNull()) {
+        // TODO(rmacnak): Should use Resolver::ResolveDynamicAnyArgs to handle
+        // method-extractors and call-through-getters, but we're in a no
+        // safepoint scope here.
+        new_target = cls.LookupDynamicFunction(selector);
+        if (!new_target.IsNull()) {
+          break;
+        }
+        cls = cls.SuperClass();
+      }
+    } else {
+      // This can be incorrect if the call site was an unqualified invocation.
+      const Class& cls = Class::Handle(zone, old_target.Owner());
+      new_target = cls.LookupStaticFunction(selector);
     }
-    const String& selector = String::Handle(old_target.name());
-    const Class& cls = Class::Handle(old_target.Owner());
-    const Function& new_target =
-        Function::Handle(cls.LookupStaticFunction(selector));
-    if (new_target.IsNull()) {
-      // TODO(johnmccutchan): Improve this.
-      TIR_Print("Cannot rebind static call to %s from %s\n",
-                old_target.ToCString(),
-                Object::Handle(Owner()).ToCString());
+
+    const Array& args_desc_array = Array::Handle(zone, arguments_descriptor());
+    ArgumentsDescriptor args_desc(args_desc_array);
+    if (new_target.IsNull() ||
+        !new_target.AreValidArguments(args_desc, NULL)) {
+      // TODO(rmacnak): Patch to a NSME stub.
+      VTIR_Print("Cannot rebind static call to %s from %s\n",
+                 old_target.ToCString(),
+                 Object::Handle(zone, Owner()).ToCString());
       return;
     }
     ClearAndSetStaticTarget(new_target);
   } else {
-    ClearWithSentinel();
+    intptr_t num_args = NumArgsTested();
+    if (num_args == 2) {
+      ClearWithSentinel();
+    } else {
+      const Array& data_array =
+          Array::Handle(zone, CachedEmptyICDataArray(num_args));
+      set_ic_data_array(data_array);
+    }
   }
 }
 
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 7eab800..322d856 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -834,7 +834,7 @@
   AddCommonObjectProperties(&jsobj, "Code", ref);
   jsobj.AddFixedServiceId("code/%" Px64"-%" Px "",
                           compile_timestamp(),
-                          EntryPoint());
+                          PayloadStart());
   const String& qualified_name = String::Handle(QualifiedName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, qualified_name, vm_name);
@@ -868,8 +868,8 @@
     func.AddProperty("name", vm_name.ToCString());
     AddNameProperties(&func, vm_name, vm_name);
   }
-  jsobj.AddPropertyF("_startAddress", "%" Px "", EntryPoint());
-  jsobj.AddPropertyF("_endAddress", "%" Px "", EntryPoint() + Size());
+  jsobj.AddPropertyF("_startAddress", "%" Px "", PayloadStart());
+  jsobj.AddPropertyF("_endAddress", "%" Px "", PayloadStart() + Size());
   jsobj.AddProperty("_alive", is_alive());
   const ObjectPool& object_pool = ObjectPool::Handle(GetObjectPool());
   jsobj.AddProperty("_objectPool", object_pool);
@@ -1135,15 +1135,15 @@
   JSONObject jsobj(stream);
   PrintSharedInstanceJSON(&jsobj, ref);
   jsobj.AddProperty("kind", "Type");
-  if (IsCanonical()) {
+  if (HasResolvedTypeClass()) {
     const Class& type_cls = Class::Handle(type_class());
     if (type_cls.CanonicalType() == raw()) {
       intptr_t cid = type_cls.id();
       jsobj.AddFixedServiceId("classes/%" Pd "/types/%d", cid, 0);
-      jsobj.AddProperty("typeClass", type_cls);
     } else {
       jsobj.AddServiceId(*this);
     }
+    jsobj.AddProperty("typeClass", type_cls);
   } else {
     jsobj.AddServiceId(*this);
   }
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index e1ca9dd..e0bf805 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -89,8 +89,10 @@
     lookup_port_handler_(Function::null()),
     empty_uint32_array_(TypedData::null()),
     handle_message_function_(Function::null()),
+    simple_instance_of_function_(Function::null()),
+    simple_instance_of_true_function_(Function::null()),
+    simple_instance_of_false_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()),
@@ -120,6 +122,7 @@
 }
 
 
+#ifndef PRODUCT
 void ObjectStore::PrintToJSONObject(JSONObject* jsobj) {
   if (!FLAG_support_service) {
     return;
@@ -136,6 +139,7 @@
 #undef PRINT_OBJECT_STORE_FIELD
   }
 }
+#endif  // !PRODUCT
 
 
 RawError* ObjectStore::PreallocateObjects() {
@@ -202,6 +206,16 @@
 }
 
 
+RawFunction* ObjectStore::PrivateObjectLookup(const String& name) {
+  const Library& core_lib = Library::Handle(core_library());
+  const String& mangled = String::ZoneHandle(core_lib.PrivateName(name));
+  const Class& cls = Class::Handle(object_class());
+  const Function& result = Function::Handle(cls.LookupDynamicFunction(mangled));
+  ASSERT(!result.IsNull());
+  return result.raw();
+}
+
+
 void ObjectStore::InitKnownObjects() {
 #ifdef DART_PRECOMPILED_RUNTIME
   // These objects are only needed for code generation.
@@ -228,6 +242,14 @@
   const Library& internal_lib = Library::Handle(internal_library());
   cls = internal_lib.LookupClass(Symbols::Symbol());
   set_symbol_class(cls);
+
+  // Cache the core private functions used for fast instance of checks.
+  simple_instance_of_function_ =
+      PrivateObjectLookup(Symbols::_simpleInstanceOf());
+  simple_instance_of_true_function_ =
+      PrivateObjectLookup(Symbols::_simpleInstanceOfTrue());
+  simple_instance_of_false_function_ =
+      PrivateObjectLookup(Symbols::_simpleInstanceOfFalse());
 #endif
 }
 
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 6ab93de..e6d6293 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -440,13 +440,6 @@
     return OFFSET_OF(ObjectStore, library_load_error_table_);
   }
 
-  RawArray* compile_time_constants() const {
-    return compile_time_constants_;
-  }
-  void set_compile_time_constants(const Array& value) {
-    compile_time_constants_ = value.raw();
-  }
-
   RawArray* unique_dynamic_targets() const {
     return unique_dynamic_targets_;
   }
@@ -486,6 +479,16 @@
     megamorphic_miss_function_ = func.raw();
   }
 
+  RawFunction* simple_instance_of_function() const {
+    return simple_instance_of_function_;
+  }
+  RawFunction* simple_instance_of_true_function() const {
+    return simple_instance_of_true_function_;
+  }
+  RawFunction* simple_instance_of_false_function() const {
+    return simple_instance_of_false_function_;
+  }
+
   // Visit all object pointers.
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
@@ -498,11 +501,16 @@
 
   static void Init(Isolate* isolate);
 
+#ifndef PRODUCT
   void PrintToJSONObject(JSONObject* jsobj);
+#endif
 
  private:
   ObjectStore();
 
+  // Finds a core library private method in Object.
+  RawFunction* PrivateObjectLookup(const String& name);
+
 #define OBJECT_STORE_FIELD_LIST(V)                                             \
   V(RawClass*, object_class_)                                                  \
   V(RawType*, object_type_)                                                    \
@@ -578,14 +586,17 @@
   V(RawFunction*, lookup_port_handler_)                                        \
   V(RawTypedData*, empty_uint32_array_)                                        \
   V(RawFunction*, handle_message_function_)                                    \
+  V(RawFunction*, simple_instance_of_function_)                                \
+  V(RawFunction*, simple_instance_of_true_function_)                           \
+  V(RawFunction*, simple_instance_of_false_function_)                          \
   V(RawArray*, library_load_error_table_)                                      \
-  V(RawArray*, compile_time_constants_)                                        \
   V(RawArray*, unique_dynamic_targets_)                                        \
   V(RawGrowableObjectArray*, token_objects_)                                   \
   V(RawArray*, token_objects_map_)                                             \
   V(RawGrowableObjectArray*, megamorphic_cache_table_)                         \
   V(RawCode*, megamorphic_miss_code_)                                          \
   V(RawFunction*, megamorphic_miss_function_)                                  \
+  // Please remember the last entry must be referred in the 'to' function below.
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&object_class_); }
 #define DECLARE_OBJECT_STORE_FIELD(type, name)                                 \
@@ -598,7 +609,7 @@
   RawObject** to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kCore:
-        return reinterpret_cast<RawObject**>(&compile_time_constants_);
+        return reinterpret_cast<RawObject**>(&library_load_error_table_);
       case Snapshot::kAppWithJIT:
       case Snapshot::kAppNoJIT:
         return to();
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 05ddd32..52ab426 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2713,8 +2713,9 @@
   Code& code = Code::Handle(Code::FinalizeCode(function, &_assembler_));
   function.AttachCode(code);
   const Instructions& instructions = Instructions::Handle(code.instructions());
-  uword entry_point = instructions.EntryPoint();
-  EXPECT_EQ(instructions.raw(), Instructions::FromEntryPoint(entry_point));
+  uword entry_point = instructions.UncheckedEntryPoint();
+  EXPECT_EQ(instructions.raw(),
+            Instructions::FromUncheckedEntryPoint(entry_point));
   const Object& result = Object::Handle(
       DartEntry::InvokeFunction(function, Array::empty_array()));
   EXPECT_EQ(1, Smi::Cast(result).Value());
@@ -2731,8 +2732,9 @@
   Code& code = Code::Handle(Code::FinalizeCode(function, &_assembler_));
   function.AttachCode(code);
   Instructions& instructions = Instructions::Handle(code.instructions());
-  uword entry_point = instructions.EntryPoint();
-  EXPECT_EQ(instructions.raw(), Instructions::FromEntryPoint(entry_point));
+  uword entry_point = instructions.UncheckedEntryPoint();
+  EXPECT_EQ(instructions.raw(),
+            Instructions::FromUncheckedEntryPoint(entry_point));
   // Try writing into the generated code, expected to crash.
   *(reinterpret_cast<char*>(entry_point) + 1) = 1;
   if (!FLAG_write_protect_code) {
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index a86889b4..3b9ac0d 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -100,6 +100,9 @@
   // Returns number of available processor cores.
   static int NumberOfAvailableProcessors();
 
+  // Returns the maximium resident set size of this process.
+  static uintptr_t MaxRSS();
+
   // Sleep the currently executing thread for millis ms.
   static void Sleep(int64_t millis);
 
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 89cfbe9..c7cc8c5 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -251,6 +251,15 @@
 }
 
 
+uintptr_t OS::MaxRSS() {
+  struct rusage usage;
+  usage.ru_maxrss = 0;
+  int r = getrusage(RUSAGE_SELF, &usage);
+  ASSERT(r == 0);
+  return usage.ru_maxrss * KB;
+}
+
+
 void OS::Sleep(int64_t millis) {
   int64_t micros = millis * kMicrosecondsPerMillisecond;
   SleepMicros(micros);
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 10faf1c..af41362 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -7,21 +7,29 @@
 
 #include "vm/os.h"
 
+#include <errno.h>
 #include <magenta/syscalls.h>
 #include <magenta/types.h>
 
 #include "platform/assert.h"
+#include "vm/zone.h"
 
 namespace dart {
 
+#ifndef PRODUCT
+
+DEFINE_FLAG(bool, generate_perf_events_symbols, false,
+    "Generate events symbols for profiling with perf");
+
+#endif  // !PRODUCT
+
 const char* OS::Name() {
   return "fuchsia";
 }
 
 
 intptr_t OS::ProcessId() {
-  UNIMPLEMENTED();
-  return 0;
+  return static_cast<intptr_t>(getpid());
 }
 
 
@@ -49,25 +57,24 @@
 
 
 int64_t OS::GetCurrentTimeMicros() {
-  return _magenta_current_time() / 1000;
+  return mx_current_time() / 1000;
 }
 
 
 int64_t OS::GetCurrentMonotonicTicks() {
-  UNIMPLEMENTED();
-  return 0;
+  return mx_current_time();
 }
 
 
 int64_t OS::GetCurrentMonotonicFrequency() {
-  UNIMPLEMENTED();
-  return 0;
+  return kNanosecondsPerSecond;
 }
 
 
 int64_t OS::GetCurrentMonotonicMicros() {
-  UNIMPLEMENTED();
-  return 0;
+  int64_t ticks = GetCurrentMonotonicTicks();
+  ASSERT(GetCurrentMonotonicFrequency() == kNanosecondsPerSecond);
+  return ticks / kNanosecondsPerMicrosecond;
 }
 
 
@@ -78,27 +85,62 @@
 
 
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
-  UNIMPLEMENTED();
-  return NULL;
+  const int kMinimumAlignment = 16;
+  ASSERT(Utils::IsPowerOfTwo(alignment));
+  ASSERT(alignment >= kMinimumAlignment);
+  void* p = memalign(alignment, size);
+  if (p == NULL) {
+    UNREACHABLE();
+  }
+  return p;
 }
 
 
 void OS::AlignedFree(void* ptr) {
-  UNIMPLEMENTED();
+  free(ptr);
 }
 
 
 // TODO(5411554):  May need to hoist these architecture dependent code
-// into a architecture specific file e.g: os_ia32_linux.cc
+// into a architecture specific file e.g: os_ia32_fuchsia.cc
 intptr_t OS::ActivationFrameAlignment() {
-  UNIMPLEMENTED();
-  return 0;
+#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
+    defined(TARGET_ARCH_ARM64)
+  const int kMinimumAlignment = 16;
+#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_DBC)
+  const int kMinimumAlignment = 8;
+#else
+#error Unsupported architecture.
+#endif
+  intptr_t alignment = kMinimumAlignment;
+  // TODO(5411554): Allow overriding default stack alignment for
+  // testing purposes.
+  // Flags::DebugIsInt("stackalign", &alignment);
+  ASSERT(Utils::IsPowerOfTwo(alignment));
+  ASSERT(alignment >= kMinimumAlignment);
+  return alignment;
 }
 
 
 intptr_t OS::PreferredCodeAlignment() {
-  UNIMPLEMENTED();
-  return 0;
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM64) ||                                              \
+    defined(TARGET_ARCH_DBC)
+  const int kMinimumAlignment = 32;
+#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
+  const int kMinimumAlignment = 16;
+#else
+#error Unsupported architecture.
+#endif
+  intptr_t alignment = kMinimumAlignment;
+  // TODO(5411554): Allow overriding default code alignment for
+  // testing purposes.
+  // Flags::DebugIsInt("codealign", &alignment);
+  ASSERT(Utils::IsPowerOfTwo(alignment));
+  ASSERT(alignment >= kMinimumAlignment);
+  ASSERT(alignment <= OS::kMaxPreferredCodeAlignment);
+  return alignment;
 }
 
 
@@ -109,18 +151,25 @@
 
 
 int OS::NumberOfAvailableProcessors() {
+  return sysconf(_SC_NPROCESSORS_CONF);
+}
+
+
+uintptr_t OS::MaxRSS() {
   UNIMPLEMENTED();
   return 0;
 }
 
 
 void OS::Sleep(int64_t millis) {
-  UNIMPLEMENTED();
+  mx_nanosleep(
+      millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond);
 }
 
 
 void OS::SleepMicros(int64_t micros) {
-  UNIMPLEMENTED();
+  mx_nanosleep(
+      micros * kNanosecondsPerMicrosecond);
 }
 
 
@@ -130,19 +179,20 @@
 
 
 char* OS::StrNDup(const char* s, intptr_t n) {
-  UNIMPLEMENTED();
-  return NULL;
+  return strndup(s, n);
 }
 
 
 intptr_t OS::StrNLen(const char* s, intptr_t n) {
-  UNIMPLEMENTED();
-  return 0;
+  return strnlen(s, n);
 }
 
 
 void OS::Print(const char* format, ...) {
-  UNIMPLEMENTED();
+  va_list args;
+  va_start(args, format);
+  VFPrint(stdout, format, args);
+  va_end(args);
 }
 
 
@@ -153,37 +203,81 @@
 
 
 int OS::SNPrint(char* str, size_t size, const char* format, ...) {
-  UNIMPLEMENTED();
-  return 0;
+  va_list args;
+  va_start(args, format);
+  int retval = VSNPrint(str, size, format, args);
+  va_end(args);
+  return retval;
 }
 
 
 int OS::VSNPrint(char* str, size_t size, const char* format, va_list args) {
-  UNIMPLEMENTED();
-  return 0;
+  int retval = vsnprintf(str, size, format, args);
+  if (retval < 0) {
+    FATAL1("Fatal error in OS::VSNPrint with format '%s'", format);
+  }
+  return retval;
 }
 
 
 char* OS::SCreate(Zone* zone, const char* format, ...) {
-  UNIMPLEMENTED();
-  return NULL;
+  va_list args;
+  va_start(args, format);
+  char* buffer = VSCreate(zone, format, args);
+  va_end(args);
+  return buffer;
 }
 
 
 char* OS::VSCreate(Zone* zone, const char* format, va_list args) {
-  UNIMPLEMENTED();
-  return NULL;
+  // Measure.
+  va_list measure_args;
+  va_copy(measure_args, args);
+  intptr_t len = VSNPrint(NULL, 0, format, measure_args);
+  va_end(measure_args);
+
+  char* buffer;
+  if (zone) {
+    buffer = zone->Alloc<char>(len + 1);
+  } else {
+    buffer = reinterpret_cast<char*>(malloc(len + 1));
+  }
+  ASSERT(buffer != NULL);
+
+  // Print.
+  va_list print_args;
+  va_copy(print_args, args);
+  VSNPrint(buffer, len + 1, format, print_args);
+  va_end(print_args);
+  return buffer;
 }
 
 
 bool OS::StringToInt64(const char* str, int64_t* value) {
-  UNIMPLEMENTED();
-  return false;
+  ASSERT(str != NULL && strlen(str) > 0 && value != NULL);
+  int32_t base = 10;
+  char* endptr;
+  int i = 0;
+  if (str[0] == '-') {
+    i = 1;
+  }
+  if ((str[i] == '0') &&
+      (str[i + 1] == 'x' || str[i + 1] == 'X') &&
+      (str[i + 2] != '\0')) {
+    base = 16;
+  }
+  errno = 0;
+  *value = strtoll(str, &endptr, base);
+  return ((errno == 0) && (endptr != str) && (*endptr == 0));
 }
 
 
 void OS::RegisterCodeObservers() {
-  UNIMPLEMENTED();
+#ifndef PRODUCT
+  if (FLAG_generate_perf_events_symbols) {
+    UNIMPLEMENTED();
+  }
+#endif  // !PRODUCT
 }
 
 
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index df05e17..58efa89 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -260,6 +260,15 @@
 }
 
 
+uintptr_t OS::MaxRSS() {
+  struct rusage usage;
+  usage.ru_maxrss = 0;
+  int r = getrusage(RUSAGE_SELF, &usage);
+  ASSERT(r == 0);
+  return usage.ru_maxrss * KB;
+}
+
+
 void OS::Sleep(int64_t millis) {
   int64_t micros = millis * kMicrosecondsPerMillisecond;
   SleepMicros(micros);
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 3806ed5..cecee6f 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -241,6 +241,15 @@
 }
 
 
+uintptr_t OS::MaxRSS() {
+  struct rusage usage;
+  usage.ru_maxrss = 0;
+  int r = getrusage(RUSAGE_SELF, &usage);
+  ASSERT(r == 0);
+  return usage.ru_maxrss;
+}
+
+
 void OS::Sleep(int64_t millis) {
   int64_t micros = millis * kMicrosecondsPerMillisecond;
   SleepMicros(micros);
diff --git a/runtime/vm/os_thread_fuchsia.cc b/runtime/vm/os_thread_fuchsia.cc
index c3e8d25..536f11f 100644
--- a/runtime/vm/os_thread_fuchsia.cc
+++ b/runtime/vm/os_thread_fuchsia.cc
@@ -47,17 +47,13 @@
 
 static void ComputeTimeSpecMicros(struct timespec* ts, int64_t micros) {
   // time in nanoseconds.
-  mx_time_t now = _magenta_current_time();
+  mx_time_t now = mx_current_time();
   mx_time_t target = now + (micros * kNanosecondsPerMicrosecond);
   int64_t secs = target / kNanosecondsPerSecond;
   int64_t nanos = target - (secs * kNanosecondsPerSecond);
 
-  ts->tv_sec += secs;
-  ts->tv_nsec += nanos;
-  if (ts->tv_nsec >= kNanosecondsPerSecond) {
-    ts->tv_sec += 1;
-    ts->tv_nsec -= kNanosecondsPerSecond;
-  }
+  ts->tv_sec = secs;
+  ts->tv_nsec = nanos;
 }
 
 
@@ -169,8 +165,7 @@
 
 #ifndef PRODUCT
 ThreadId OSThread::GetCurrentThreadTraceId() {
-  UNIMPLEMENTED();
-  return 0;
+  return pthread_self();
 }
 #endif  // PRODUCT
 
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 7236a91..809b0ad 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -9,6 +9,7 @@
 
 #include <malloc.h>  // NOLINT
 #include <process.h>  // NOLINT
+#include <psapi.h>  // NOLINT
 #include <time.h>  // NOLINT
 
 #include "platform/utils.h"
@@ -235,6 +236,13 @@
 }
 
 
+uintptr_t OS::MaxRSS() {
+  PROCESS_MEMORY_COUNTERS pmc;
+  GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
+  return pmc.PeakWorkingSetSize;
+}
+
+
 void OS::Sleep(int64_t millis) {
   ::Sleep(millis);
 }
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index a10d097..2f894b5 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -969,7 +969,7 @@
   {
     MonitorLocker ml(tasks_lock());
     set_tasks(tasks() - 1);
-    ml.Notify();
+    ml.NotifyAll();
   }
 }
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index babc538..e9e6e93 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -48,8 +48,11 @@
 // committed to the current version.
 DEFINE_FLAG(bool, conditional_directives, true,
     "Enable conditional directives");
+DEFINE_FLAG(bool, initializing_formal_access, false,
+    "Make initializing formal parameters visible in initializer list.");
 DEFINE_FLAG(bool, warn_super, false,
     "Warning if super initializer not last in initializer list.");
+DEFINE_FLAG(bool, warn_patch, false, "Warn on old-style patch syntax.");
 DEFINE_FLAG(bool, await_is_keyword, false,
     "await and yield are treated as proper keywords in synchronous code.");
 
@@ -697,12 +700,23 @@
     for (int i = 0; i < num_params; i++) {
       ParamDesc& param = (*parameters)[i];
       ASSERT(param.var != NULL);
-      if (!param.is_field_initializer) {
+      if (FLAG_initializing_formal_access || !param.is_field_initializer) {
         param.var->set_invisible(invisible);
       }
     }
   }
 
+  void HideInitFormals() {
+    const intptr_t num_params = parameters->length();
+    for (int i = 0; i < num_params; i++) {
+      ParamDesc& param = (*parameters)[i];
+      if (param.is_field_initializer) {
+        ASSERT(param.var != NULL);
+        param.var->set_invisible(true);
+      }
+    }
+  }
+
   void SetImplicitlyFinal() {
     implicitly_final = true;
   }
@@ -1547,18 +1561,13 @@
       &Symbols::ClosureParameter(),
       &Object::dynamic_type());
 
-  const Function& parent = Function::ZoneHandle(func.parent_function());
+  const Function& parent = Function::Handle(func.parent_function());
   if (parent.IsImplicitSetterFunction()) {
     const TokenPosition ident_pos = func.token_pos();
     ASSERT(IsIdentifier());
-    const String& field_name = *CurrentLiteral();
-    const Class& field_class = Class::ZoneHandle(Z, parent.Owner());
-    const Field& field =
-        Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name));
-    const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type());
     params.AddFinalParameter(ident_pos,
                              &Symbols::Value(),
-                             &field_type);
+                             &Object::dynamic_type());
     ASSERT(func.num_fixed_parameters() == 2);  // closure, value.
   } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) {
     const bool allow_explicit_default_values = true;
@@ -1591,7 +1600,76 @@
     }
     func_args->set_names(arg_names);
   }
-  StaticCallNode* call = new StaticCallNode(token_pos, parent, func_args);
+
+  const String& func_name = String::ZoneHandle(parent.name());
+  const Class& owner = Class::Handle(parent.Owner());
+  Function& target = Function::ZoneHandle(owner.LookupFunction(func_name));
+  if (target.raw() != parent.raw()) {
+    ASSERT(Isolate::Current()->HasAttemptedReload());
+    if (target.IsNull() ||
+        (target.is_static() != parent.is_static()) ||
+        (target.kind() != parent.kind())) {
+      target = Function::null();
+    }
+  }
+
+  AstNode* call = NULL;
+  // Check the target still exists and has compatible parameters. If not,
+  // throw NSME/call nSM instead of forwarding the call. Note we compare the
+  // parent not func because func has an extra parameter for the closure
+  // receiver.
+  if (!target.IsNull() &&
+      (parent.num_fixed_parameters() == target.num_fixed_parameters())) {
+    call = new StaticCallNode(token_pos, target, func_args);
+  } else if (!parent.is_static()) {
+    ASSERT(Isolate::Current()->HasAttemptedReload());
+    // If a subsequent reload reintroduces the target in the middle of the
+    // Invocation object being constructed, we won't be able to successfully
+    // deopt because the generated AST will change.
+    func.SetIsOptimizable(false);
+
+    ArgumentListNode* arguments = BuildNoSuchMethodArguments(
+        token_pos, func_name, *func_args, NULL, false);
+    const intptr_t kNumArguments = 2;  // Receiver, InvocationMirror.
+    ArgumentsDescriptor args_desc(
+        Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments)));
+    Function& no_such_method = Function::ZoneHandle(Z,
+    Resolver::ResolveDynamicForReceiverClass(owner,
+                                             Symbols::NoSuchMethod(),
+                                             args_desc));
+    if (no_such_method.IsNull()) {
+      // If noSuchMethod(i) is not found, call Object:noSuchMethod.
+      no_such_method ^= Resolver::ResolveDynamicForReceiverClass(
+          Class::Handle(Z, I->object_store()->object_class()),
+          Symbols::NoSuchMethod(),
+          args_desc);
+    }
+    call = new StaticCallNode(token_pos, no_such_method, arguments);
+  } else {
+    ASSERT(Isolate::Current()->HasAttemptedReload());
+    // If a subsequent reload reintroduces the target in the middle of the
+    // arguments array being constructed, we won't be able to successfully
+    // deopt because the generated AST will change.
+    func.SetIsOptimizable(false);
+
+    InvocationMirror::Type im_type;
+    if (parent.IsImplicitGetterFunction()) {
+      im_type = InvocationMirror::kGetter;
+    } else if (parent.IsImplicitSetterFunction()) {
+      im_type = InvocationMirror::kSetter;
+    } else {
+      im_type = InvocationMirror::kMethod;
+    }
+    call = ThrowNoSuchMethodError(TokenPos(),
+                                  owner,
+                                  func_name,
+                                  func_args,
+                                  InvocationMirror::kStatic,
+                                  im_type,
+                                  NULL);  // No existing function.
+  }
+
+  ASSERT(call != NULL);
   ReturnNode* return_node = new ReturnNode(token_pos, call);
   current_block_->statements->Add(return_node);
   return CloseBlock();
@@ -1889,6 +1967,7 @@
   TRACE_PARSER("ParseFormalParameter");
   ParamDesc parameter;
   bool var_seen = false;
+  bool final_seen = false;
   bool this_seen = false;
 
   if (evaluate_metadata && (CurrentToken() == Token::kAT)) {
@@ -1899,6 +1978,7 @@
 
   if (CurrentToken() == Token::kFINAL) {
     ConsumeToken();
+    final_seen = true;
     parameter.is_final = true;
   } else if (CurrentToken() == Token::kVAR) {
     ConsumeToken();
@@ -1913,6 +1993,9 @@
     ExpectToken(Token::kPERIOD);
     this_seen = true;
     parameter.is_field_initializer = true;
+    if (FLAG_initializing_formal_access) {
+      parameter.is_final = true;
+    }
   }
   if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) {
     ConsumeToken();
@@ -1954,6 +2037,9 @@
     ExpectToken(Token::kPERIOD);
     this_seen = true;
     parameter.is_field_initializer = true;
+    if (FLAG_initializing_formal_access) {
+      parameter.is_final = true;
+    }
   }
 
   // At this point, we must see an identifier for the parameter name.
@@ -1983,7 +2069,11 @@
     // This parameter is probably a closure. If we saw the keyword 'var'
     // or 'final', a closure is not legal here and we ignore the
     // opening parens.
-    if (!var_seen && !parameter.is_final) {
+    // TODO(hausner): The language spec appears to allow var and final
+    // in signature types when used with initializing formals:
+    // fieldFormalParameter:
+    // metadata finalConstVarOrType? this ‘.’ identifier formalParameterList? ;
+    if (!var_seen && !final_seen) {
       // The parsed parameter type is actually the function result type.
       const AbstractType& result_type =
           AbstractType::Handle(Z, parameter.type->raw());
@@ -2406,19 +2496,6 @@
                                                AstNode* receiver) {
   Function& implicit_closure_function =
       Function::ZoneHandle(Z, func.ImplicitClosureFunction());
-  if (receiver != NULL) {
-    // If we create an implicit instance closure from inside a closure of a
-    // parameterized class, make sure that the receiver is captured as
-    // instantiator.
-    if (FunctionLevel() > 0) {
-      const Type& signature_type = Type::Handle(Z,
-          implicit_closure_function.SignatureType());
-      const Class& scope_class = Class::Handle(Z, signature_type.type_class());
-      if (scope_class.IsGeneric()) {
-        CaptureInstantiator();
-      }
-    }
-  }
   return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL);
 }
 
@@ -3202,7 +3279,6 @@
         // Thus, they are set to be invisible when added to the scope.
         LocalVariable* p = param.var;
         ASSERT(p != NULL);
-        ASSERT(p->is_invisible());
         AstNode* value = new LoadLocalNode(param.name_pos, p);
         EnsureExpressionTemp();
         AstNode* initializer =
@@ -3232,6 +3308,9 @@
 
   // Parsing of initializers done. Now we parse the constructor body.
   OpenBlock();  // Block to collect constructor body nodes.
+  if (FLAG_initializing_formal_access) {
+    params.HideInitFormals();
+  }
   if (CurrentToken() == Token::kLBRACE) {
     // We checked in the top-level parse phase that a redirecting
     // constructor does not have a body.
@@ -3387,17 +3466,6 @@
     ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
     ASSERT(func.NumParameters() == params.parameters->length());
 
-    // Check whether the function has any field initializer formal parameters,
-    // which are not allowed in non-constructor functions.
-    if (params.has_field_initializer) {
-      for (int i = 0; i < params.parameters->length(); i++) {
-        ParamDesc& param = (*params.parameters)[i];
-        if (param.is_field_initializer) {
-          ReportError(param.name_pos,
-                      "field initializer only allowed in constructors");
-        }
-      }
-    }
     // Populate function scope with the formal parameters.
     AddFormalParamsToScope(&params, current_block_->scope);
 
@@ -3971,6 +4039,12 @@
   if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) {
     func.set_is_reflectable(false);
   }
+  if (is_patch_source() && IsPatchAnnotation(method->metadata_pos)) {
+    // Currently, we just ignore the patch annotation. If the function
+    // name already exists in the patched class, this function will replace
+    // the one in the patched class.
+    method->metadata_pos = TokenPosition::kNoSource;
+  }
   if (FLAG_enable_mirrors && (method->metadata_pos.IsReal())) {
     library_.AddFunctionMetadata(func, method->metadata_pos);
   }
@@ -4071,6 +4145,11 @@
     class_field.set_has_initializer(has_initializer);
     members->AddField(class_field);
     field->field_ = &class_field;
+    if (is_patch_source() && IsPatchAnnotation(field->metadata_pos)) {
+      // Currently, we just ignore the patch annotation on fields.
+      // All fields in the patch class are added to the patched class.
+      field->metadata_pos = TokenPosition::kNoSource;
+    }
     if (FLAG_enable_mirrors && (field->metadata_pos.IsReal())) {
       library_.AddFieldMetadata(class_field, field->metadata_pos);
     }
@@ -4416,6 +4495,8 @@
         ReportError("missing 'var', 'final', 'const' or type"
                     " in field declaration");
       }
+    } else if (member.type->IsVoidType()) {
+      ReportError(member.name_pos, "field may not be 'void'");
     }
     ParseFieldDefinition(members, &member);
   } else {
@@ -4483,12 +4564,11 @@
   bool is_patch = false;
   bool is_abstract = false;
   TokenPosition declaration_pos =
-      metadata_pos.IsReal() ? metadata_pos : TokenPos();
-  if (is_patch_source() &&
-      (CurrentToken() == Token::kIDENT) &&
-      CurrentLiteral()->Equals("patch")) {
-    ConsumeToken();
+    metadata_pos.IsReal() ? metadata_pos : TokenPos();
+  if (is_patch_source() && IsPatchAnnotation(metadata_pos)) {
     is_patch = true;
+    metadata_pos = TokenPosition::kNoSource;
+    declaration_pos = TokenPos();
   } else if (CurrentToken() == Token::kABSTRACT) {
     is_abstract = true;
     ConsumeToken();
@@ -4673,11 +4753,7 @@
   is_top_level_ = true;
   String& class_name = String::Handle(Z, cls.Name());
   SkipMetadata();
-  if (is_patch_source() &&
-      (CurrentToken() == Token::kIDENT) &&
-      CurrentLiteral()->Equals("patch")) {
-    ConsumeToken();
-  } else if (CurrentToken() == Token::kABSTRACT) {
+  if (CurrentToken() == Token::kABSTRACT) {
     ConsumeToken();
   }
   ExpectToken(Token::kCLASS);
@@ -4743,6 +4819,10 @@
   TRACE_PARSER("ParseEnumDefinition");
   INC_STAT(thread(), num_classes_parsed, 1);
 
+  const Class& helper_class =
+      Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper()));
+  ASSERT(!helper_class.IsNull());
+
   SkipMetadata();
   ExpectToken(Token::kENUM);
 
@@ -4754,9 +4834,9 @@
   const Type& int_type = Type::Handle(Z, Type::IntType());
   index_field = Field::New(Symbols::Index(),
                            false,  // Not static.
-                           true,  // Field is final.
+                           true,   // Field is final.
                            false,  // Not const.
-                           true,  // Is reflectable.
+                           true,   // Is reflectable.
                            cls,
                            int_type,
                            cls.token_pos());
@@ -4782,18 +4862,12 @@
   AddFormalParamsToFunction(&params, getter);
   enum_members.AddFunction(getter);
 
-  GrowableObjectArray& enum_names = GrowableObjectArray::Handle(Z,
-      GrowableObjectArray::New(8, Heap::kOld));
-  const String& name_prefix =
-      String::Handle(String::Concat(enum_name, Symbols::Dot()));
-
   ASSERT(IsIdentifier());
   ASSERT(CurrentLiteral()->raw() == cls.Name());
 
   ConsumeToken();  // Enum type name.
   ExpectToken(Token::kLBRACE);
   Field& enum_value = Field::Handle(Z);
-  String& enum_value_name = String::Handle(Z);
   intptr_t i = 0;
   GrowableArray<String*> declared_names(8);
 
@@ -4841,14 +4915,6 @@
     enum_value.RecordStore(ordinal_value);
     i++;
 
-    // For the user-visible name of the enumeration value, we need to
-    // unmangle private names.
-    if (enum_ident->CharAt(0) == '_') {
-      *enum_ident = String::ScrubName(*enum_ident);
-    }
-    enum_value_name = Symbols::FromConcat(T, name_prefix, *enum_ident);
-    enum_names.Add(enum_value_name, Heap::kOld);
-
     ConsumeToken();  // Enum value name.
     if (CurrentToken() == Token::kCOMMA) {
       ConsumeToken();
@@ -4856,10 +4922,6 @@
   }
   ExpectToken(Token::kRBRACE);
 
-  const Class& helper_class =
-      Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper()));
-  ASSERT(!helper_class.IsNull());
-
   // Add static field 'const List values'.
   Field& values_field = Field::ZoneHandle(Z);
   values_field = Field::New(Symbols::Values(),
@@ -4878,16 +4940,35 @@
   values_field.SetStaticValue(values_array, true);
   values_field.RecordStore(values_array);
 
-  // Create a static field that contains the list of enumeration names.
-  // Clone the _enum_names field from the helper class.
-  Field& names_field = Field::Handle(Z,
-      helper_class.LookupStaticFieldAllowPrivate(Symbols::_EnumNames()));
-  ASSERT(!names_field.IsNull());
-  names_field = names_field.Clone(cls);
-  enum_members.AddField(names_field);
-  const Array& names_array = Array::Handle(Array::MakeArray(enum_names));
-  names_field.SetStaticValue(names_array, true);
-  names_field.RecordStore(names_array);
+  // Clone the _name field from the helper class.
+  Field& _name_field = Field::Handle(Z,
+      helper_class.LookupInstanceFieldAllowPrivate(Symbols::_name()));
+  ASSERT(!_name_field.IsNull());
+  _name_field = _name_field.Clone(cls);
+  enum_members.AddField(_name_field);
+
+  // Add an implicit getter function for the _name field. We use the field's
+  // name directly here so that the private key matches those of the other
+  // cloned helper functions and fields.
+  const Type& string_type = Type::Handle(Z, Type::StringType());
+  const String& name_getter_name = String::Handle(Z,
+      Field::GetterSymbol(String::Handle(_name_field.name())));
+  Function& name_getter = Function::Handle(Z);
+  name_getter = Function::New(name_getter_name,
+                              RawFunction::kImplicitGetter,
+                              /* is_static = */ false,
+                              /* is_const = */ true,
+                              /* is_abstract = */ false,
+                              /* is_external = */ false,
+                              /* is_native = */ false,
+                              cls,
+                              cls.token_pos());
+  name_getter.set_result_type(string_type);
+  name_getter.set_is_debuggable(false);
+  ParamList name_params;
+  name_params.AddReceiver(&Object::dynamic_type(), cls.token_pos());
+  AddFormalParamsToFunction(&name_params, name_getter);
+  enum_members.AddFunction(name_getter);
 
   // Clone the toString() function from the helper class.
   Function& to_string_func = Function::Handle(Z,
@@ -5197,6 +5278,19 @@
 }
 
 
+bool Parser::IsPatchAnnotation(TokenPosition pos) {
+  if (pos == TokenPosition::kNoSource) {
+    return false;
+  }
+  TokenPosition saved_pos = TokenPos();
+  SetPosition(pos);
+  ExpectToken(Token::kAT);
+  bool is_patch = IsSymbol(Symbols::Patch());
+  SetPosition(saved_pos);
+  return is_patch;
+}
+
+
 TokenPosition Parser::SkipMetadata() {
   if (CurrentToken() != Token::kAT) {
     return TokenPosition::kNoSource;
@@ -5539,12 +5633,9 @@
   const bool is_static = true;
   bool is_external = false;
   bool is_patch = false;
-  if (is_patch_source() &&
-      (CurrentToken() == Token::kIDENT) &&
-      CurrentLiteral()->Equals("patch") &&
-      (LookaheadToken(1) != Token::kLPAREN)) {
-    ConsumeToken();
+  if (is_patch_source() && IsPatchAnnotation(metadata_pos)) {
     is_patch = true;
+    metadata_pos = TokenPosition::kNoSource;
   } else if (CurrentToken() == Token::kEXTERNAL) {
     ConsumeToken();
     is_external = true;
@@ -5662,11 +5753,9 @@
   bool is_external = false;
   bool is_patch = false;
   AbstractType& result_type = AbstractType::Handle(Z);
-  if (is_patch_source() &&
-      (CurrentToken() == Token::kIDENT) &&
-      CurrentLiteral()->Equals("patch")) {
-    ConsumeToken();
+  if (is_patch_source() && IsPatchAnnotation(metadata_pos)) {
     is_patch = true;
+    metadata_pos = TokenPosition::kNoSource;
   } else if (CurrentToken() == Token::kEXTERNAL) {
     ConsumeToken();
     is_external = true;
@@ -6210,9 +6299,6 @@
     } else if ((CurrentToken() == Token::kABSTRACT) &&
         (LookaheadToken(1) == Token::kCLASS)) {
       ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
-    } else if (is_patch_source() && IsSymbol(Symbols::Patch()) &&
-               (LookaheadToken(1) == Token::kCLASS)) {
-      ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
     } else {
       set_current_class(toplevel_class);
       if (IsVariableDeclaration()) {
@@ -7397,6 +7483,12 @@
     ParamDesc& param_desc = (*params->parameters)[i];
     func.SetParameterTypeAt(i, *param_desc.type);
     func.SetParameterNameAt(i, *param_desc.name);
+    if (param_desc.is_field_initializer && !func.IsGenerativeConstructor()) {
+      // Redirecting constructors are detected later in ParseConstructor.
+      ReportError(param_desc.name_pos,
+                  "only generative constructors may have "
+                  "initializing formal parameters");
+    }
   }
 }
 
@@ -7422,7 +7514,10 @@
     if (param_desc.is_final) {
       parameter->set_is_final();
     }
-    if (param_desc.is_field_initializer) {
+    if (FLAG_initializing_formal_access) {
+      // Field initializer parameters are implicitly final.
+      ASSERT(!param_desc.is_field_initializer || param_desc.is_final);
+    } else if (param_desc.is_field_initializer) {
       parameter->set_invisible(true);
     }
   }
@@ -8068,18 +8163,10 @@
   const TokenPosition saved_pos = TokenPos();
   bool is_external = false;
   SkipMetadata();
-  if (is_top_level_) {
-    if (is_patch_source() &&
-        (CurrentToken() == Token::kIDENT) &&
-        CurrentLiteral()->Equals("patch") &&
-        (LookaheadToken(1) != Token::kLPAREN)) {
-      // Skip over 'patch' for top-level function declarations in patch sources.
-      ConsumeToken();
-    } else if (CurrentToken() == Token::kEXTERNAL) {
-      // Skip over 'external' for top-level function declarations.
-      is_external = true;
-      ConsumeToken();
-    }
+  if (is_top_level_ && (CurrentToken() == Token::kEXTERNAL)) {
+    // Skip over 'external' for top-level function declarations.
+    is_external = true;
+    ConsumeToken();
   }
   if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
     // Possibly a function without explicit return type.
@@ -8114,9 +8201,7 @@
 
 bool Parser::IsTopLevelAccessor() {
   const TokenPosition saved_pos = TokenPos();
-  if (is_patch_source() && IsSymbol(Symbols::Patch())) {
-    ConsumeToken();
-  } else if (CurrentToken() == Token::kEXTERNAL) {
+  if (CurrentToken() == Token::kEXTERNAL) {
     ConsumeToken();
   }
   if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
@@ -8724,16 +8809,20 @@
 
   // Parse stream expression.
   ExpectToken(Token::kIN);
+
+  // Open a block for the iterator variable and the try-finally statement
+  // that contains the loop. Ensure that the block starts at a different
+  // token position than the following loop block. Both blocks can allocate
+  // contexts and if they have a matching token position range,
+  // it can be an issue (cf. bug 26941).
+  OpenBlock();
+  const Block* await_for_block = current_block_;
+
   const TokenPosition stream_expr_pos = TokenPos();
   AstNode* stream_expr =
       ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
   ExpectToken(Token::kRPAREN);
 
-  // Open a block for the iterator variable and the try-finally
-  // statement that contains the loop.
-  OpenBlock();
-  const Block* loop_block = current_block_;
-
   // Build creation of implicit StreamIterator.
   // var :for-in-iter = new StreamIterator(stream_expr).
   const Class& stream_iterator_cls =
@@ -8983,8 +9072,8 @@
                          try_index,
                          finally_clause);
 
-  ASSERT(current_block_ == loop_block);
-  loop_block->statements->Add(try_catch_node);
+  ASSERT(current_block_ == await_for_block);
+  await_for_block->statements->Add(try_catch_node);
 
   return CloseBlock();  // Implicit block around while loop.
 }
@@ -12148,21 +12237,21 @@
 }
 
 
-void Parser::InsertCachedConstantValue(const String& url,
+void Parser::InsertCachedConstantValue(const Script& script,
                                        TokenPosition token_pos,
                                        const Instance& value) {
   ASSERT(Thread::Current()->IsMutatorThread());
-  Isolate* isolate = Isolate::Current();
-  ConstantPosKey key(url, token_pos);
-  if (isolate->object_store()->compile_time_constants() == Array::null()) {
-    const intptr_t kInitialConstMapSize = 16;
-    isolate->object_store()->set_compile_time_constants(
+  const intptr_t kInitialConstMapSize = 16;
+  ASSERT(!script.InVMHeap());
+  if (script.compile_time_constants() == Array::null()) {
+    const Array& array =
         Array::Handle(HashTables::New<ConstantsMap>(kInitialConstMapSize,
-                                                    Heap::kNew)));
+                                                    Heap::kNew));
+    script.set_compile_time_constants(array);
   }
-  ConstantsMap constants(isolate->object_store()->compile_time_constants());
-  constants.InsertNewOrGetValue(key, value);
-  isolate->object_store()->set_compile_time_constants(constants.Release());
+  ConstantsMap constants(script.compile_time_constants());
+  constants.InsertNewOrGetValue(token_pos, value);
+  script.set_compile_time_constants(constants.Release());
 }
 
 
@@ -12173,26 +12262,20 @@
     // evaluated only once.
     return;
   }
-  const String& url = String::Handle(Z, script_.url());
-  InsertCachedConstantValue(url, token_pos, value);
-  if (FLAG_compiler_stats) {
-    ConstantsMap constants(isolate()->object_store()->compile_time_constants());
-    thread_->compiler_stats()->num_cached_consts = constants.NumOccupied();
-    constants.Release();
-  }
+  InsertCachedConstantValue(script_, token_pos, value);
 }
 
 
 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) {
-  if (isolate()->object_store()->compile_time_constants() == Array::null()) {
+  bool is_present = false;
+  ASSERT(!script_.InVMHeap());
+  if (script_.compile_time_constants() == Array::null()) {
     return false;
   }
-  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);
+  ConstantsMap constants(script_.compile_time_constants());
+  *value ^= constants.GetOrNull(token_pos, &is_present);
   // Mutator compiler thread may add constants while background compiler
-  // is running , and thus change the value of 'compile_time_constants';
+  // 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) {
@@ -12244,6 +12327,8 @@
     // not been evaluated. If the field is const, call the static getter method
     // to evaluate the expression and canonicalize the value.
     if (field.is_const()) {
+      NoReloadScope no_reload_scope(isolate(), thread());
+      NoOOBMessageScope no_msg_scope(thread());
       field.SetStaticValue(Object::transition_sentinel());
       const int kNumArguments = 0;  // no arguments.
       const Function& func = Function::Handle(Z,
@@ -12301,6 +12386,8 @@
     const TypeArguments& type_arguments,
     const Function& constructor,
     ArgumentListNode* arguments) {
+  NoReloadScope no_reload_scope(isolate(), thread());
+  NoOOBMessageScope no_msg_scope(thread());
   // Factories have one extra argument: the type arguments.
   // Constructors have 1 extra arguments: receiver.
   const int kNumExtraArgs = 1;
@@ -13815,6 +13902,8 @@
 
 
 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) {
+  NoReloadScope no_reload_scope(isolate(), thread());
+  NoOOBMessageScope no_msg_scope(thread());
   const Class& cls = Class::Handle(
       Z, Library::LookupCoreClass(Symbols::StringBase()));
   ASSERT(!cls.IsNull());
@@ -14162,6 +14251,8 @@
 // be a compile time constant.
 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos,
                                           AstNode* expr) {
+  NoReloadScope no_reload_scope(isolate(), thread());
+  NoOOBMessageScope no_msg_scope(thread());
   if (expr->IsLiteralNode()) {
     return expr->AsLiteralNode()->literal();
   } else if (expr->IsLoadLocalNode() &&
@@ -14637,7 +14728,7 @@
 }
 
 
-void Parser::InsertCachedConstantValue(const String& url,
+void Parser::InsertCachedConstantValue(const Script& script,
                                        TokenPosition token_pos,
                                        const Instance& value) {
   UNREACHABLE();
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 815f978..d2644b7 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -39,61 +39,44 @@
 class TopLevel;
 class RecursionChecker;
 
-// 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, TokenPosition pos)
-      : script_url(url), token_pos(pos) { }
-  const String& script_url;
-  TokenPosition token_pos;
-};
-
-
+// We cache compile time constants during compilation.  This allows us
+// to look them up when the same code gets compiled again.  During
+// background compilation, we are not able to evaluate the constants
+// so this cache is necessary to support background compilation.
+//
+// We cache the constants with the script itself. This is helpful during isolate
+// reloading, as it allows us to reference the compile time constants associated
+// with a particular version of a script. The map key is simply the
+// TokenPosition where the constant is defined.
 class ConstMapKeyEqualsTraits {
  public:
   static const char* Name() { return "ConstMapKeyEqualsTraits"; }
   static bool ReportStats() { return false; }
 
   static bool IsMatch(const Object& a, const Object& 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));
+    const Smi& key1 = Smi::Cast(a);
+    const Smi& key2 = Smi::Cast(b);
+    return (key1.Value() == key2.Value());
   }
-  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.value() == Smi::Value(Smi::RawCast(key2.At(1))));
+  static bool IsMatch(const TokenPosition& key1, const Object& b) {
+    const Smi& key2 = Smi::Cast(b);
+    return (key1.value() == key2.Value());
   }
   static uword Hash(const Object& obj) {
-    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);
+    const Smi& key = Smi::Cast(obj);
+    return HashValue(key.Value());
   }
-  static uword Hash(const ConstantPosKey& key) {
-    return HashValue(String::HashRawSymbol(key.script_url.raw()),
-                     key.token_pos.value());
+  static uword Hash(const TokenPosition& key) {
+    return HashValue(key.value());
   }
-  // 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.value())));
-    return key_obj.raw();;
+  // Used by CacheConstantValue if a new constant is added to the map.
+  static RawObject* NewKey(const TokenPosition& key) {
+    return Smi::New(key.value());
   }
 
  private:
-  static uword HashValue(intptr_t url_hash, intptr_t pos) {
-    return url_hash * pos % (Smi::kMaxValue - 13);
+  static uword HashValue(intptr_t pos) {
+    return pos % (Smi::kMaxValue - 13);
   }
 };
 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap;
@@ -278,7 +261,7 @@
   // given static field.
   static ParsedFunction* ParseStaticFieldInitializer(const Field& field);
 
-  static void InsertCachedConstantValue(const String& url,
+  static void InsertCachedConstantValue(const Script& script,
                                         TokenPosition token_pos,
                                         const Instance& value);
 
@@ -418,6 +401,7 @@
   void SkipToMatchingParenthesis();
   void SkipBlock();
   TokenPosition SkipMetadata();
+  bool IsPatchAnnotation(TokenPosition pos);
   void SkipTypeArguments();
   void SkipType(bool allow_void);
   void SkipInitializers();
@@ -617,8 +601,7 @@
   ClosureNode* CreateImplicitClosureNode(const Function& func,
                                          TokenPosition token_pos,
                                          AstNode* receiver);
-  static void AddFormalParamsToFunction(const ParamList* params,
-                                        const Function& func);
+  void AddFormalParamsToFunction(const ParamList* params, const Function& func);
   void AddFormalParamsToScope(const ParamList* params, LocalScope* scope);
 
   SequenceNode* ParseConstructor(const Function& func);
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 8ef15c5..d5513d5 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -216,7 +216,8 @@
   }
   handler->ClosePort(port);
   if (!handler->HasLivePorts() && handler->OwnedByPortMap()) {
-    delete handler;
+    // Delete handler as soon as it isn't busy with a task.
+    handler->RequestDeletion();
   }
   return true;
 }
@@ -303,6 +304,7 @@
 
 void PortMap::PrintPortsForMessageHandler(MessageHandler* handler,
                                           JSONStream* stream) {
+#ifndef PRODUCT
   if (!FLAG_support_service) {
     return;
   }
@@ -324,6 +326,7 @@
       }
     }
   }
+#endif
 }
 
 
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 35df46b..e919a52 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -240,8 +240,8 @@
       DropTypeArguments();
 
       // Clear these before dropping classes as they may hold onto otherwise
-      // dead instances of classes we will remove.
-      I->object_store()->set_compile_time_constants(Array::null_array());
+      // dead instances of classes we will remove or otherwise unused symbols.
+      DropScriptData();
       I->object_store()->set_unique_dynamic_targets(Array::null_array());
       Class& null_class = Class::Handle(Z);
       I->object_store()->set_future_class(null_class);
@@ -516,6 +516,70 @@
     if (!changed_) {
       TraceConstFunctions();
     }
+    CollectCallbackFields();
+  }
+}
+
+
+void Precompiler::CollectCallbackFields() {
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  Class& subcls = Class::Handle(Z);
+  Array& fields = Array::Handle(Z);
+  Field& field = Field::Handle(Z);
+  Function& function = Function::Handle(Z);
+  Function& dispatcher = Function::Handle(Z);
+  Array& args_desc = Array::Handle(Z);
+  AbstractType& field_type = AbstractType::Handle(Z);
+  String& field_name = String::Handle(Z);
+  GrowableArray<intptr_t> cids;
+
+  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.is_allocated()) continue;
+
+      fields = cls.fields();
+      for (intptr_t k = 0; k < fields.Length(); k++) {
+        field ^= fields.At(k);
+        if (field.is_static()) continue;
+        field_type = field.type();
+        if (!field_type.IsFunctionType()) continue;
+        field_name = field.name();
+        if (!IsSent(field_name)) continue;
+        // Create arguments descriptor with fixed parameters from
+        // signature of field_type.
+        function = Type::Cast(field_type).signature();
+        if (function.HasOptionalParameters()) continue;
+        if (FLAG_trace_precompiler) {
+          THR_Print("Found callback field %s\n", field_name.ToCString());
+        }
+        args_desc =
+            ArgumentsDescriptor::New(function.num_fixed_parameters());
+        cids.Clear();
+        if (T->cha()->ConcreteSubclasses(cls, &cids)) {
+          for (intptr_t j = 0; j < cids.length(); ++j) {
+            subcls ^= I->class_table()->At(cids[j]);
+            if (subcls.is_allocated()) {
+              // Add dispatcher to cls.
+              dispatcher = subcls.GetInvocationDispatcher(
+                  field_name,
+                  args_desc,
+                  RawFunction::kInvokeFieldDispatcher,
+                  /* create_if_absent = */ true);
+              if (FLAG_trace_precompiler) {
+                THR_Print("Added invoke-field-dispatcher for %s to %s\n",
+                          field_name.ToCString(), subcls.ToCString());
+              }
+              AddFunction(dispatcher);
+            }
+          }
+        }
+      }
+    }
   }
 }
 
@@ -1319,7 +1383,7 @@
       functions = cls.functions();
       for (intptr_t j = 0; j < functions.Length(); j++) {
         function ^= functions.At(j);
-        bool retain = function.HasCode();
+        bool retain = enqueued_functions_.Lookup(&function) != NULL;
         if (!retain && function.HasImplicitClosureFunction()) {
           // It can happen that all uses of an implicit closure inline their
           // target function, leaving the target function uncompiled. Keep
@@ -1339,7 +1403,7 @@
   closures = isolate()->object_store()->closure_functions();
   for (intptr_t j = 0; j < closures.Length(); j++) {
     function ^= closures.At(j);
-    bool retain = function.HasCode();
+    bool retain = enqueued_functions_.Lookup(&function) != NULL;
     if (retain) {
       AddTypesOf(function);
 
@@ -1560,6 +1624,24 @@
 }
 
 
+void Precompiler::DropScriptData() {
+  Library& lib = Library::Handle(Z);
+  Array& scripts = Array::Handle(Z);
+  Script& script = Script::Handle(Z);
+  const TokenStream& null_tokens = TokenStream::Handle(Z);
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    scripts = lib.LoadedScripts();
+    for (intptr_t j = 0; j < scripts.Length(); j++) {
+      script ^= scripts.At(j);
+      script.set_compile_time_constants(Array::null_array());
+      script.set_source(String::null_string());
+      script.set_tokens(null_tokens);
+    }
+  }
+}
+
+
 void Precompiler::TraceTypesFromRetainedClasses() {
   Library& lib = Library::Handle(Z);
   Class& cls = Class::Handle(Z);
@@ -1793,7 +1875,7 @@
           // stub.
           ASSERT(target_.HasCode());
           target_code_ ^= target_.CurrentCode();
-          uword pc = pc_offset_.Value() + code_.EntryPoint();
+          uword pc = pc_offset_.Value() + code_.PayloadStart();
           CodePatcher::PatchStaticCallAt(pc, code_, target_code_);
         }
       }
@@ -1828,13 +1910,12 @@
   class SwitchICCallsVisitor : public FunctionVisitor {
    public:
     explicit SwitchICCallsVisitor(Zone* zone) :
+        zone_(zone),
         code_(Code::Handle(zone)),
         pool_(ObjectPool::Handle(zone)),
         entry_(Object::Handle(zone)),
         ic_(ICData::Handle(zone)),
-        target_(Function::Handle(zone)),
-        target_code_(Code::Handle(zone)),
-        entry_point_(Smi::Handle(zone)) {
+        target_code_(Code::Handle(zone)) {
     }
 
     void Visit(const Function& function) {
@@ -1848,28 +1929,10 @@
         if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue;
         entry_ = pool_.ObjectAt(i);
         if (entry_.IsICData()) {
+          // The only IC calls generated by precompilation are for switchable
+          // calls.
           ic_ ^= entry_.raw();
-
-          // Only single check ICs are SwitchableCalls that use the ICLookup
-          // stubs. Some operators like + have ICData that check the types of
-          // arguments in addition to the receiver and use special stubs
-          // with fast paths for Smi operations.
-          if (ic_.NumArgsTested() != 1) continue;
-
-          for (intptr_t j = 0; j < ic_.NumberOfChecks(); j++) {
-            entry_ = ic_.GetTargetOrCodeAt(j);
-            if (entry_.IsFunction()) {
-              target_ ^= entry_.raw();
-              ASSERT(target_.HasCode());
-              target_code_ = target_.CurrentCode();
-              entry_point_ = Smi::FromAlignedAddress(target_code_.EntryPoint());
-              ic_.SetCodeAt(j, target_code_);
-              ic_.SetEntryPointAt(j, entry_point_);
-            } else {
-              // We've already seen and switched this ICData.
-              ASSERT(entry_.IsCode());
-            }
-          }
+          ic_.ResetSwitchable(zone_);
         } else if (entry_.raw() ==
                    StubCode::ICLookupThroughFunction_entry()->code()) {
           target_code_ = StubCode::ICLookupThroughCode_entry()->code();
@@ -1879,13 +1942,12 @@
     }
 
    private:
+    Zone* zone_;
     Code& code_;
     ObjectPool& pool_;
     Object& entry_;
     ICData& ic_;
-    Function& target_;
     Code& target_code_;
-    Smi& entry_point_;
   };
 
   ASSERT(!I->compilation_allowed());
@@ -2659,6 +2721,9 @@
           sinking->DetachMaterializations();
         }
 
+        // Replace bounds check instruction with a generic one.
+        optimizer.ReplaceArrayBoundChecks();
+
         // Compute and store graph informations (call & instruction counts)
         // to be later used by the inliner.
         FlowGraphInliner::CollectGraphInfo(flow_graph, true);
@@ -2826,7 +2891,7 @@
     if (trace_compiler) {
       THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
                 function.ToFullyQualifiedCString(),
-                Code::Handle(function.CurrentCode()).EntryPoint(),
+                Code::Handle(function.CurrentCode()).PayloadStart(),
                 Code::Handle(function.CurrentCode()).Size(),
                 per_compile_timer.TotalElapsedTime());
     }
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index 6ec2ed3..ad7f0ca 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -299,6 +299,7 @@
   void ProcessFunction(const Function& function);
   void CheckForNewDynamicFunctions();
   void TraceConstFunctions();
+  void CollectCallbackFields();
 
   void TraceForRetainedFunctions();
   void DropFunctions();
@@ -306,6 +307,7 @@
   void TraceTypesFromRetainedClasses();
   void DropTypes();
   void DropTypeArguments();
+  void DropScriptData();
   void DropClasses();
   void DropLibraries();
 
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 394d795..ddd5b26 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -53,7 +53,7 @@
 
 bool Profiler::initialized_ = false;
 SampleBuffer* Profiler::sample_buffer_ = NULL;
-
+ProfilerCounters Profiler::counters_;
 
 void Profiler::InitOnce() {
   // Place some sane restrictions on user controlled flags.
@@ -68,6 +68,8 @@
   NativeSymbolResolver::InitOnce();
   ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period);
   ThreadInterrupter::Startup();
+  // Zero counters.
+  memset(&counters_, 0, sizeof(counters_));
   initialized_ = true;
 }
 
@@ -201,14 +203,14 @@
 
   // Returns offset into code object.
   intptr_t RelativePC() {
-    ASSERT(pc() >= code_.EntryPoint());
-    return static_cast<intptr_t>(pc() - code_.EntryPoint());
+    ASSERT(pc() >= code_.PayloadStart());
+    return static_cast<intptr_t>(pc() - code_.PayloadStart());
   }
 
   uint8_t* CodePointer(intptr_t offset) {
     const intptr_t size = code_.Size();
     ASSERT(offset < size);
-    uint8_t* code_pointer = reinterpret_cast<uint8_t*>(code_.EntryPoint());
+    uint8_t* code_pointer = reinterpret_cast<uint8_t*>(code_.PayloadStart());
     code_pointer += offset;
     return code_pointer;
   }
@@ -333,12 +335,12 @@
   char* native_symbol_name =
       NativeSymbolResolver::LookupSymbolName(pc, &start);
   if (native_symbol_name == NULL) {
-    OS::Print("Frame[%" Pd "] = `unknown symbol` [0x%" Px "]\n",
-              frame_index, pc);
+    OS::PrintErr("Frame[%" Pd "] = `unknown symbol` [0x%" Px "]\n",
+                 frame_index, pc);
   } else {
-    OS::Print("Frame[%" Pd "] = `%s` [0x%" Px "]\n",
-              frame_index, native_symbol_name, pc);
-    free(native_symbol_name);
+    OS::PrintErr("Frame[%" Pd "] = `%s` [0x%" Px "]\n",
+                 frame_index, native_symbol_name, pc);
+    NativeSymbolResolver::FreeSymbolName(native_symbol_name);
   }
 }
 
@@ -349,8 +351,8 @@
   if (code.IsNull()) {
     DumpStackFrame(frame_index, pc);
   } else {
-    OS::Print("Frame[%" Pd "] = Dart:`%s` [0x%" Px "]\n",
-              frame_index, code.ToCString(), pc);
+    OS::PrintErr("Frame[%" Pd "] = Dart:`%s` [0x%" Px "]\n",
+                 frame_index, code.ToCString(), pc);
   }
 }
 
@@ -769,7 +771,9 @@
                           ProfilerDartStackWalker* dart_stack_walker,
                           uword pc,
                           uword fp,
-                          uword sp) {
+                          uword sp,
+                          ProfilerCounters* counters) {
+  ASSERT(counters != NULL);
 #if defined(TARGET_OS_WINDOWS)
   // Use structured exception handling to trap guard page access on Windows.
   __try {
@@ -783,14 +787,18 @@
 
   if (FLAG_profile_vm) {
     // Always walk the native stack collecting both native and Dart frames.
+    counters->stack_walker_native++;
     native_stack_walker->walk();
   } else if (StubCode::HasBeenInitialized() && exited_dart_code) {
+    counters->stack_walker_dart_exit++;
     // We have a valid exit frame info, use the Dart stack walker.
     dart_exit_stack_walker->walk();
   } else if (StubCode::HasBeenInitialized() && in_dart_code) {
+    counters->stack_walker_dart++;
     // We are executing Dart code. We have frame pointers.
     dart_stack_walker->walk();
   } else {
+    counters->stack_walker_none++;
     sample->SetAt(0, pc);
   }
 
@@ -940,8 +948,18 @@
 
 
 void Profiler::DumpStackTrace(bool native_stack_trace) {
+  // Allow only one stack trace to prevent recursively printing stack traces if
+  // we hit an assert while printing the stack.
+  static uintptr_t started_dump = 0;
+  if (AtomicOperations::FetchAndIncrement(&started_dump) != 0) {
+    OS::PrintErr("Aborting re-entrant request for stack trace.\n");
+    return;
+  }
+
   Thread* thread = Thread::Current();
-  ASSERT(thread != NULL);
+  if (thread == NULL) {
+    return;
+  }
   OSThread* os_thread = thread->os_thread();
   ASSERT(os_thread != NULL);
   Isolate* isolate = thread->isolate();
@@ -951,9 +969,9 @@
 
   const bool exited_dart_code = thread->HasExitedDartCode();
 
-  OS::Print("Dumping %s stack trace for thread %" Px "\n",
-            native_stack_trace ? "native" : "dart-only",
-            OSThread::ThreadIdToIntPtr(os_thread->trace_id()));
+  OS::PrintErr("Dumping %s stack trace for thread %" Px "\n",
+               native_stack_trace ? "native" : "dart-only",
+               OSThread::ThreadIdToIntPtr(os_thread->trace_id()));
 
   uintptr_t sp = Thread::GetCurrentStackPointer();
   uintptr_t fp = 0;
@@ -965,7 +983,7 @@
   uword stack_upper = 0;
 
   if (!InitialRegisterCheck(pc, fp, sp)) {
-    OS::Print(
+    OS::PrintErr(
         "Stack dump aborted because InitialRegisterCheck.\n");
     return;
   }
@@ -975,7 +993,7 @@
                                         sp,
                                         &stack_lower,
                                         &stack_upper)) {
-    OS::Print(
+    OS::PrintErr(
         "Stack dump aborted because GetAndValidateIsolateStackBounds.\n");
     return;
   }
@@ -1006,7 +1024,7 @@
                                               fp,
                                               sp);
   }
-  OS::Print("-- End of DumpStackTrace");
+  OS::PrintErr("-- End of DumpStackTrace");
 }
 
 
@@ -1119,6 +1137,7 @@
 
   // Thread is not doing VM work.
   if (thread->task_kind() == Thread::kUnknownTask) {
+    counters_.bail_out_unknown_task++;
     return;
   }
 
@@ -1127,6 +1146,7 @@
     // 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.
+    counters_.bail_out_jump_to_exception_handler++;
     return;
   }
 
@@ -1157,15 +1177,18 @@
   }
 
   if (!CheckIsolate(isolate)) {
+    counters_.bail_out_check_isolate++;
     return;
   }
 
   if (thread->IsMutatorThread() && isolate->IsDeoptimizing()) {
+    counters_.single_frame_sample_deoptimizing++;
     SampleThreadSingleFrame(thread, pc);
     return;
   }
 
   if (!InitialRegisterCheck(pc, fp, sp)) {
+    counters_.single_frame_sample_register_check++;
     SampleThreadSingleFrame(thread, pc);
     return;
   }
@@ -1177,6 +1200,7 @@
                                         sp,
                                         &stack_lower,
                                         &stack_upper)) {
+    counters_.single_frame_sample_get_and_validate_stack_bounds++;
     // Could not get stack boundary.
     SampleThreadSingleFrame(thread, pc);
     return;
@@ -1234,7 +1258,8 @@
                 &dart_stack_walker,
                 pc,
                 fp,
-                sp);
+                sp,
+                &counters_);
 }
 
 
@@ -1244,8 +1269,8 @@
 }
 
 
-uword CodeDescriptor::Entry() const {
-  return code_.EntryPoint();
+uword CodeDescriptor::Start() const {
+  return code_.PayloadStart();
 }
 
 
@@ -1320,11 +1345,11 @@
   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);
+    ASSERT(a->Start() < b->Start());
+    ASSERT(FindCode(a->Start()) == a);
+    ASSERT(FindCode(b->Start()) == b);
+    ASSERT(FindCode(a->Start() + a->Size() - 1) == a);
+    ASSERT(FindCode(b->Start() + b->Size() - 1) == b);
   }
 #endif
 }
@@ -1345,7 +1370,7 @@
     intptr_t step = count / 2;
     current += step;
     const CodeDescriptor* cd = At(current);
-    if (pc >= cd->Entry()) {
+    if (pc >= cd->Start()) {
       first = ++current;
       count -= step + 1;
     } else {
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index b6b2417..be4f049 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -27,6 +27,23 @@
 class SampleBuffer;
 class ProfileTrieNode;
 
+struct ProfilerCounters {
+  // Count of bail out reasons:
+  int64_t bail_out_unknown_task;
+  int64_t bail_out_jump_to_exception_handler;
+  int64_t bail_out_check_isolate;
+  // Count of single frame sampling reasons:
+  int64_t single_frame_sample_deoptimizing;
+  int64_t single_frame_sample_register_check;
+  int64_t single_frame_sample_get_and_validate_stack_bounds;
+  // Count of stack walkers used:
+  int64_t stack_walker_native;
+  int64_t stack_walker_dart_exit;
+  int64_t stack_walker_dart;
+  int64_t stack_walker_none;
+};
+
+
 class Profiler : public AllStatic {
  public:
   static void InitOnce();
@@ -54,6 +71,11 @@
   static void SampleThread(Thread* thread,
                            const InterruptedThreadState& state);
 
+  static ProfilerCounters counters() {
+    // Copies the counter values.
+    return counters_;
+  }
+
  private:
   // Does not walk the thread's stack.
   static void SampleThreadSingleFrame(Thread* thread, uintptr_t pc);
@@ -61,6 +83,8 @@
 
   static SampleBuffer* sample_buffer_;
 
+  static ProfilerCounters counters_;
+
   friend class Thread;
 };
 
@@ -399,7 +423,7 @@
  public:
   explicit CodeDescriptor(const Code& code);
 
-  uword Entry() const;
+  uword Start() const;
 
   uword Size() const;
 
@@ -415,8 +439,8 @@
   }
 
   bool Contains(uword pc) const {
-    uword end = Entry() + Size();
-    return (pc >= Entry()) && (pc < end);
+    uword end = Start() + Size();
+    return (pc >= Start()) && (pc < end);
   }
 
   static int Compare(CodeDescriptor* const* a,
@@ -424,12 +448,12 @@
     ASSERT(a != NULL);
     ASSERT(b != NULL);
 
-    uword a_entry = (*a)->Entry();
-    uword b_entry = (*b)->Entry();
+    uword a_start = (*a)->Start();
+    uword b_start = (*b)->Start();
 
-    if (a_entry < b_entry) {
+    if (a_start < b_start) {
       return -1;
-    } else if (a_entry > b_entry) {
+    } else if (a_start > b_start) {
       return 1;
     } else {
       return 0;
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 6b3d839..eb99c43 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -1181,7 +1181,7 @@
                        const Code& code,
                        ProcessedSample* sample,
                        intptr_t frame_index) {
-    intptr_t offset = pc - code.EntryPoint();
+    intptr_t offset = pc - code.PayloadStart();
     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.
@@ -1341,8 +1341,8 @@
       ASSERT(!code.IsNull());
       RegisterLiveProfileCode(
           new ProfileCode(ProfileCode::kDartCode,
-                          code.EntryPoint(),
-                          code.EntryPoint() + code.Size(),
+                          code.PayloadStart(),
+                          code.PayloadStart() + code.Size(),
                           code.compile_timestamp(),
                           code));
     }
@@ -2448,6 +2448,41 @@
   obj->AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
   obj->AddPropertyTimeMicros("timeOriginMicros", min_time());
   obj->AddPropertyTimeMicros("timeExtentMicros", GetTimeSpan());
+
+  ProfilerCounters counters = Profiler::counters();
+  {
+    JSONObject counts(obj, "counters");
+    counts.AddProperty64(
+        "bail_out_unknown_task",
+        counters.bail_out_unknown_task);
+    counts.AddProperty64(
+        "bail_out_jump_to_exception_handler",
+        counters.bail_out_jump_to_exception_handler);
+    counts.AddProperty64(
+        "bail_out_check_isolate",
+        counters.bail_out_check_isolate);
+    counts.AddProperty64(
+        "single_frame_sample_deoptimizing",
+        counters.single_frame_sample_deoptimizing);
+    counts.AddProperty64(
+        "single_frame_sample_register_check",
+        counters.single_frame_sample_register_check);
+    counts.AddProperty64(
+        "single_frame_sample_get_and_validate_stack_bounds",
+        counters.single_frame_sample_get_and_validate_stack_bounds);
+    counts.AddProperty64(
+        "stack_walker_native",
+        counters.stack_walker_native);
+    counts.AddProperty64(
+        "stack_walker_dart_exit",
+        counters.stack_walker_dart_exit);
+    counts.AddProperty64(
+        "stack_walker_dart",
+        counters.stack_walker_dart);
+    counts.AddProperty64(
+        "stack_walker_none",
+        counters.stack_walker_none);
+  }
 }
 
 
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 4ab49bd..8bb6232 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -2393,7 +2393,7 @@
 
   while (it.MoveNext()) {
     if (it.TokenPos() == tp) {
-      return it.PcOffset() + code.EntryPoint();
+      return it.PcOffset() + code.PayloadStart();
     }
   }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index dd8ff93..1e975d7 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -593,6 +593,7 @@
   friend class ApiMessageReader;  // GetClassId
   friend class Serializer;  // GetClassId
   friend class Array;
+  friend class Become;  // GetClassId
   friend class Bigint;
   friend class ByteBuffer;
   friend class Closure;
@@ -640,6 +641,9 @@
   friend class NativeEntry;  // GetClassId
   friend class Simulator;
   friend class SimulatorHelpers;
+  friend class ObjectLocator;
+  friend class InstanceMorpher;  // GetClassId
+  friend class VerifyCanonicalVisitor;
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
@@ -995,9 +999,11 @@
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->url_); }
   RawString* url_;
+  RawString* resolved_url_;
+  RawArray* compile_time_constants_;
   RawTokenStream* tokens_;
   RawString* source_;
-  RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->source_); }
+  RawObject** to() {return reinterpret_cast<RawObject**>(&ptr()->source_); }
   RawObject** to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
       case Snapshot::kAppNoJIT:
@@ -1098,6 +1104,7 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(Code);
 
   uword entry_point_;
+  uword checked_entry_point_;
 
   RawObject** from() {
     return reinterpret_cast<RawObject**>(&ptr()->active_instructions_);
@@ -1170,7 +1177,6 @@
   Entry* first_entry() { return &ptr()->data()[0]; }
 
   friend class Object;
-  friend class SnapshotReader;
 };
 
 
@@ -1253,7 +1259,6 @@
   const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
 
   friend class Object;
-  friend class SnapshotReader;
 };
 
 
@@ -1270,7 +1275,6 @@
   const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
 
   friend class Object;
-  friend class SnapshotReader;
 };
 
 
@@ -1297,8 +1301,6 @@
   // Variable length data follows here (bitmap of the stack layout).
   uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
   const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
-
-  friend class SnapshotReader;
 };
 
 
@@ -1372,7 +1374,6 @@
   }
 
   friend class Object;
-  friend class SnapshotReader;
 };
 
 
@@ -1402,7 +1403,6 @@
   HandlerInfo* data() { OPEN_ARRAY_START(HandlerInfo, intptr_t); }
 
   friend class Object;
-  friend class SnapshotReader;
 };
 
 
@@ -1501,8 +1501,7 @@
     return NULL;
   }
   int32_t deopt_id_;     // Deoptimization id corresponding to this IC.
-  uint32_t state_bits_;  // Number of arguments tested in IC, deopt reasons,
-                         // range feedback.
+  uint32_t state_bits_;  // Number of arguments tested in IC, deopt reasons.
 #if defined(TAG_IC_DATA)
   intptr_t tag_;  // Debugging, verifying that the icdata is assigned to the
                   // same instruction again. Store -1 or Instruction::Tag.
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index c2448a3..d94ce4e 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -14,16 +14,6 @@
 
 DECLARE_FLAG(bool, remove_script_timestamps_for_test);
 
-#define NEW_OBJECT(type)                                                       \
-  ((Snapshot::IsFull(kind)) ? reader->New##type() : type::New())
-
-#define NEW_OBJECT_WITH_LEN(type, len)                                         \
-  ((Snapshot::IsFull(kind)) ? reader->New##type(len) : type::New(len))
-
-#define NEW_OBJECT_WITH_LEN_SPACE(type, len, kind)                             \
-  ((Snapshot::IsFull(kind)) ?                                                  \
-  reader->New##type(len) : type::New(len, HEAP_SPACE(kind)))
-
 #define OFFSET_OF_FROM(obj)                                                    \
   obj.raw()->from() - reinterpret_cast<RawObject**>(obj.raw()->ptr())
 
@@ -48,21 +38,16 @@
 
   Class& cls = Class::ZoneHandle(reader->zone(), Class::null());
   bool is_in_fullsnapshot = reader->Read<bool>();
-  if (Snapshot::IsFull(kind) ||
-      (kind == Snapshot::kScript && !is_in_fullsnapshot)) {
+  if ((kind == Snapshot::kScript) && !is_in_fullsnapshot) {
     // Read in the base information.
     classid_t class_id = reader->ReadClassIDValue();
 
     // Allocate class object of specified kind.
-    if (Snapshot::IsFull(kind)) {
-      cls = reader->NewClass(class_id);
+    if (class_id < kNumPredefinedCids) {
+      ASSERT((class_id >= kInstanceCid) && (class_id <= kMirrorReferenceCid));
+      cls = reader->isolate()->class_table()->At(class_id);
     } else {
-      if (class_id < kNumPredefinedCids) {
-        ASSERT((class_id >= kInstanceCid) && (class_id <= kMirrorReferenceCid));
-        cls = reader->isolate()->class_table()->At(class_id);
-      } else {
-        cls = Class::NewInstanceClass();
-      }
+      cls = Class::NewInstanceClass();
     }
     reader->AddBackRef(object_id, &cls, kIsDeserialized);
 
@@ -85,7 +70,7 @@
                        cls.raw()->to_snapshot(kind),
                        kAsReference);
     cls.StorePointer(&cls.raw_ptr()->dependent_code_, Array::null());
-    ASSERT(!cls.IsInFullSnapshot() || (Snapshot::IsFull(kind)));
+    ASSERT(!cls.IsInFullSnapshot());
   } else {
     cls ^= reader->ReadClassId(object_id);
     ASSERT((kind == Snapshot::kMessage) || cls.IsInFullSnapshot());
@@ -113,8 +98,7 @@
   // to be interpreted.
   writer->Write<bool>(is_in_fullsnapshot);
 
-  if (Snapshot::IsFull(kind) ||
-      (kind == Snapshot::kScript && !is_in_fullsnapshot)) {
+  if ((kind == Snapshot::kScript) && !is_in_fullsnapshot) {
     // Write out all the non object pointer fields.
     // NOTE: cpp_vtable_ is not written.
     classid_t class_id = ptr()->id_;
@@ -160,7 +144,7 @@
 
   // Allocate unresolved class object.
   UnresolvedClass& unresolved_class = UnresolvedClass::ZoneHandle(
-      reader->zone(), NEW_OBJECT(UnresolvedClass));
+      reader->zone(), UnresolvedClass::New());
   reader->AddBackRef(object_id, &unresolved_class, kIsDeserialized);
 
   // Set all non object fields.
@@ -228,10 +212,11 @@
   bool typeclass_is_in_fullsnapshot = reader->Read<bool>();
 
   // Allocate type object.
-  Type& type = Type::ZoneHandle(reader->zone(), NEW_OBJECT(Type));
+  Type& type = Type::ZoneHandle(reader->zone(), Type::New());
   bool is_canonical = RawObject::IsCanonical(tags);
   bool defer_canonicalization = is_canonical &&
-      (!Snapshot::IsFull(kind) && typeclass_is_in_fullsnapshot);
+      ((kind == Snapshot::kMessage) ||
+       (!Snapshot::IsFull(kind) && typeclass_is_in_fullsnapshot));
   reader->AddBackRef(object_id, &type, kIsDeserialized, defer_canonicalization);
 
   // Set all non object fields.
@@ -309,7 +294,7 @@
 
   // Allocate type ref object.
   TypeRef& type_ref = TypeRef::ZoneHandle(
-      reader->zone(), NEW_OBJECT(TypeRef));
+      reader->zone(), TypeRef::New());
   reader->AddBackRef(object_id, &type_ref, kIsDeserialized);
 
   // Set all the object fields.
@@ -349,7 +334,7 @@
 
   // Allocate type parameter object.
   TypeParameter& type_parameter = TypeParameter::ZoneHandle(
-      reader->zone(), NEW_OBJECT(TypeParameter));
+      reader->zone(), TypeParameter::New());
   reader->AddBackRef(object_id, &type_parameter, kIsDeserialized);
 
   // Set all non object fields.
@@ -413,7 +398,7 @@
 
   // Allocate bounded type object.
   BoundedType& bounded_type = BoundedType::ZoneHandle(
-      reader->zone(), NEW_OBJECT(BoundedType));
+      reader->zone(), BoundedType::New());
   reader->AddBackRef(object_id, &bounded_type, kIsDeserialized);
 
   // Set all the object fields.
@@ -473,7 +458,7 @@
   intptr_t len = reader->ReadSmiValue();
 
   TypeArguments& type_arguments = TypeArguments::ZoneHandle(
-      reader->zone(), NEW_OBJECT_WITH_LEN_SPACE(TypeArguments, len, kind));
+      reader->zone(), TypeArguments::New(len, HEAP_SPACE(kind)));
   bool is_canonical = RawObject::IsCanonical(tags);
   bool defer_canonicalization = is_canonical && (!Snapshot::IsFull(kind));
   reader->AddBackRef(object_id,
@@ -482,12 +467,7 @@
                      defer_canonicalization);
 
   // Set the instantiations field, which is only read from a full snapshot.
-  if (Snapshot::IsFull(kind)) {
-    *(reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
-    type_arguments.set_instantiations(*(reader->ArrayHandle()));
-  } else {
-    type_arguments.set_instantiations(Object::zero_array());
-  }
+  type_arguments.set_instantiations(Object::zero_array());
 
   // Now set all the type fields.
   intptr_t offset = type_arguments.TypeAddr(0) -
@@ -523,11 +503,6 @@
   // Write out the length field.
   writer->Write<RawObject*>(ptr()->length_);
 
-  // Write out the instantiations field, but only in a full snapshot.
-  if (Snapshot::IsFull(kind)) {
-    writer->WriteObjectImpl(ptr()->instantiations_, kAsInlinedObject);
-  }
-
   // Write out the individual types.
   intptr_t len = Smi::Value(ptr()->length_);
   for (intptr_t i = 0; i < len; i++) {
@@ -542,16 +517,16 @@
                                     Snapshot::Kind kind,
                                     bool as_reference) {
   ASSERT(reader != NULL);
+  ASSERT(kind == Snapshot::kScript);
 
   // Allocate function object.
   PatchClass& cls = PatchClass::ZoneHandle(reader->zone(),
-                                            NEW_OBJECT(PatchClass));
+                                           PatchClass::New());
   reader->AddBackRef(object_id, &cls, kIsDeserialized);
 
   // Set all the object fields.
   READ_OBJECT_FIELDS(cls, cls.raw()->from(), cls.raw()->to(), kAsReference);
 
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
   return cls.raw();
 }
 
@@ -561,7 +536,7 @@
                             Snapshot::Kind kind,
                             bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -580,24 +555,8 @@
                               intptr_t tags,
                               Snapshot::Kind kind,
                               bool as_reference) {
-  ASSERT(reader != NULL);
-  ASSERT(Snapshot::IsFull(kind));
-
-  // Allocate closure object.
-  Closure& closure = Closure::ZoneHandle(
-      reader->zone(), NEW_OBJECT(Closure));
-  reader->AddBackRef(object_id, &closure, kIsDeserialized);
-
-  // Set all the object fields.
-  READ_OBJECT_FIELDS(closure,
-                     closure.raw()->from(), closure.raw()->to(),
-                     kAsReference);
-
-  // Set the canonical bit.
-  if (RawObject::IsCanonical(tags)) {
-    closure.SetCanonical();
-  }
-  return closure.raw();
+  UNREACHABLE();
+  return Closure::null();
 }
 
 
@@ -606,27 +565,18 @@
                          Snapshot::Kind kind,
                          bool as_reference) {
   ASSERT(writer != NULL);
-  if ((kind == Snapshot::kMessage) || (kind == Snapshot::kScript)) {
-    // Check if closure is serializable, throw an exception otherwise.
-    RawFunction* func = writer->IsSerializableClosure(this);
-    if (func != Function::null()) {
-      writer->WriteStaticImplicitClosure(object_id,
-                                         func,
-                                         writer->GetObjectTags(this));
-      return;
-    }
+  ASSERT((kind == Snapshot::kMessage) || (kind == Snapshot::kScript));
+
+  // Check if closure is serializable, throw an exception otherwise.
+  RawFunction* func = writer->IsSerializableClosure(this);
+  if (func != Function::null()) {
+    writer->WriteStaticImplicitClosure(object_id,
+                                       func,
+                                       writer->GetObjectTags(this));
+    return;
   }
 
-  // Write out the serialization header value for this object.
-  writer->WriteInlinedObjectHeader(object_id);
-
-  // Write out the class and tags information.
-  writer->WriteIndexedObject(kClosureCid);
-  writer->WriteTags(writer->GetObjectTags(this));
-
-  // Write out all the object pointer fields.
-  SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  UNREACHABLE();
 }
 
 
@@ -636,11 +586,11 @@
                                       Snapshot::Kind kind,
                                       bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Allocate closure data object.
-  ClosureData& data = ClosureData::ZoneHandle(
-      reader->zone(), NEW_OBJECT(ClosureData));
+  ClosureData& data = ClosureData::ZoneHandle(reader->zone(),
+                                              ClosureData::New());
   reader->AddBackRef(object_id, &data, kIsDeserialized);
 
   // Set all the object fields.
@@ -657,7 +607,7 @@
                              Snapshot::Kind kind,
                              bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -669,8 +619,7 @@
   // Context scope.
   if (ptr()->context_scope_ == Object::empty_context_scope().raw()) {
     writer->WriteVMIsolateObject(kEmptyContextScopeObject);
-  } else if (ptr()->context_scope_->ptr()->is_implicit_ ||
-             (kind == Snapshot::kAppWithJIT)) {
+  } else if (ptr()->context_scope_->ptr()->is_implicit_) {
     writer->WriteObjectImpl(ptr()->context_scope_, kAsInlinedObject);
   } else {
     // We don't write non implicit context scopes in the snapshot.
@@ -694,11 +643,11 @@
                                               Snapshot::Kind kind,
                                               bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Allocate redirection data object.
-  RedirectionData& data = RedirectionData::ZoneHandle(
-      reader->zone(), NEW_OBJECT(RedirectionData));
+  RedirectionData& data = RedirectionData::ZoneHandle(reader->zone(),
+                                                      RedirectionData::New());
   reader->AddBackRef(object_id, &data, kIsDeserialized);
 
   // Set all the object fields.
@@ -715,7 +664,7 @@
                                  Snapshot::Kind kind,
                                  bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -736,13 +685,13 @@
                                 Snapshot::Kind kind,
                                 bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   bool is_in_fullsnapshot = reader->Read<bool>();
-  if ((Snapshot::IsFull(kind)) || !is_in_fullsnapshot) {
+  if (!is_in_fullsnapshot) {
     // Allocate function object.
-    Function& func = Function::ZoneHandle(
-        reader->zone(), NEW_OBJECT(Function));
+    Function& func = Function::ZoneHandle(reader->zone(),
+                                          Function::New());
     reader->AddBackRef(object_id, &func, kIsDeserialized);
 
     // Set all the non object fields. Read the token positions now but
@@ -754,17 +703,10 @@
     func.set_kind_tag(reader->Read<uint32_t>());
     func.set_token_pos(TokenPosition::SnapshotDecode(token_pos));
     func.set_end_token_pos(TokenPosition::SnapshotDecode(end_token_pos));
-    if (kind == Snapshot::kAppNoJIT) {
-      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<int8_t>());
-      func.set_optimized_instruction_count(reader->Read<uint16_t>());
-      func.set_optimized_call_site_count(reader->Read<uint16_t>());
-    }
+    func.set_usage_counter(reader->Read<int32_t>());
+    func.set_deoptimization_counter(reader->Read<int8_t>());
+    func.set_optimized_instruction_count(reader->Read<uint16_t>());
+    func.set_optimized_call_site_count(reader->Read<uint16_t>());
     func.set_was_compiled(false);
 
     // Set all the object fields.
@@ -772,34 +714,15 @@
                        func.raw()->from(), func.raw()->to_snapshot(),
                        kAsReference);
     // Initialize all fields that are not part of the snapshot.
-    if (kind == Snapshot::kAppNoJIT) {
-      // Read the code object and fixup entry point.
-      func.ClearICDataArray();
-      func.ClearCode();
-      (*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
-      func.SetInstructions(*reader->CodeHandle());
-    } else if (kind == Snapshot::kAppWithJIT) {
+    bool is_optimized = func.usage_counter() != 0;
+    if (is_optimized) {
+      // Read the ic data array as the function is an optimized one.
       (*reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference);
       func.set_ic_data_array(*reader->ArrayHandle());
-      (*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
-      func.set_unoptimized_code(*reader->CodeHandle());
-      if (!reader->CodeHandle()->IsNull()) {
-        func.SetInstructions(*reader->CodeHandle());
-        func.set_was_compiled(true);
-      } else {
-        func.ClearCode();
-      }
     } else {
-      bool is_optimized = func.usage_counter() != 0;
-      if (is_optimized) {
-        // Read the ic data array as the function is an optimized one.
-        (*reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference);
-        func.set_ic_data_array(*reader->ArrayHandle());
-      } else {
-        func.ClearICDataArray();
-      }
-      func.ClearCode();
+      func.ClearICDataArray();
     }
+    func.ClearCode();
     return func.raw();
   } else {
     return reader->ReadFunctionId(object_id);
@@ -812,7 +735,7 @@
                           Snapshot::Kind kind,
                           bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
   bool is_in_fullsnapshot = false;
   bool owner_is_class = false;
   if ((kind == Snapshot::kScript) && !Function::IsSignatureFunction(this)) {
@@ -837,7 +760,7 @@
   // to be interpreted.
   writer->Write<bool>(is_in_fullsnapshot);
 
-  if (Snapshot::IsFull(kind) || !is_in_fullsnapshot) {
+  if (!is_in_fullsnapshot) {
     bool is_optimized = Code::IsOptimized(ptr()->code_);
 
     // Write out all the non object fields.
@@ -846,31 +769,19 @@
     writer->Write<int16_t>(ptr()->num_fixed_parameters_);
     writer->Write<int16_t>(ptr()->num_optional_parameters_);
     writer->Write<uint32_t>(ptr()->kind_tag_);
-    if (kind == Snapshot::kAppNoJIT) {
-      // Omit fields used to support de/reoptimization.
+    if (is_optimized) {
+      writer->Write<int32_t>(FLAG_optimization_counter_threshold);
     } else {
-      if (is_optimized) {
-        writer->Write<int32_t>(FLAG_optimization_counter_threshold);
-      } else {
-        writer->Write<int32_t>(0);
-      }
-      writer->Write<int8_t>(ptr()->deoptimization_counter_);
-      writer->Write<uint16_t>(ptr()->optimized_instruction_count_);
-      writer->Write<uint16_t>(ptr()->optimized_call_site_count_);
+      writer->Write<int32_t>(0);
     }
+    writer->Write<int8_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);
     visitor.VisitPointers(from(), to_snapshot());
-    if (kind == Snapshot::kAppNoJIT) {
-      ASSERT(ptr()->ic_data_array_ == Array::null());
-      ASSERT((ptr()->code_ == ptr()->unoptimized_code_) ||
-             (ptr()->unoptimized_code_ == Code::null()));
-      writer->WriteObjectImpl(ptr()->code_, kAsInlinedObject);
-    } else if (kind == Snapshot::kAppWithJIT) {
-      writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
-      writer->WriteObjectImpl(ptr()->unoptimized_code_, kAsInlinedObject);
-    } else if (is_optimized) {
+    if (is_optimized) {
       // Write out the ic data array as the function is optimized.
       writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
     }
@@ -886,22 +797,17 @@
                           Snapshot::Kind kind,
                           bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Allocate field object.
-  Field& field = Field::ZoneHandle(reader->zone(), NEW_OBJECT(Field));
+  Field& field = Field::ZoneHandle(reader->zone(), Field::New());
   reader->AddBackRef(object_id, &field, kIsDeserialized);
 
   // Set all non object fields.
-  if (kind == Snapshot::kAppNoJIT) {
-    field.set_token_pos(TokenPosition::kNoSource);
-    ASSERT(!FLAG_use_field_guards);
-  } else {
-    field.set_token_pos(
-        TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
-    field.set_guarded_cid(reader->Read<int32_t>());
-    field.set_is_nullable(reader->Read<int32_t>());
-  }
+  field.set_token_pos(
+      TokenPosition::SnapshotDecode(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.
@@ -929,7 +835,7 @@
                        Snapshot::Kind kind,
                        bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -939,11 +845,9 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  if (kind != Snapshot::kAppNoJIT) {
-    writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
-    writer->Write<int32_t>(ptr()->guarded_cid_);
-    writer->Write<int32_t>(ptr()->is_nullable_);
-  }
+  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
+  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.
@@ -954,11 +858,7 @@
   writer->WriteObjectImpl(ptr()->type_, kAsReference);
   // Write out the initial static value or field offset.
   if (Field::StaticBit::decode(ptr()->kind_bits_)) {
-    if (kind == Snapshot::kAppNoJIT) {
-      // For precompiled static fields, the value was already reset and
-      // initializer_ now contains a Function.
-      writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
-    } else if (Field::ConstBit::decode(ptr()->kind_bits_)) {
+    if (Field::ConstBit::decode(ptr()->kind_bits_)) {
       // Do not reset const fields.
       writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
     } else {
@@ -969,15 +869,9 @@
     writer->WriteObjectImpl(ptr()->value_.offset_, kAsReference);
   }
   // Write out the initializer function or saved initial value.
-  if (kind == Snapshot::kAppNoJIT) {
-    writer->WriteObjectImpl(ptr()->initializer_.precompiled_, kAsReference);
-  } else {
-    writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
-  }
-  if (kind != Snapshot::kAppNoJIT) {
-    // Write out the guarded list length.
-    writer->WriteObjectImpl(ptr()->guarded_list_length_, kAsReference);
-  }
+  writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
+  // Write out the guarded list length.
+  writer->WriteObjectImpl(ptr()->guarded_list_length_, kAsReference);
 }
 
 
@@ -990,8 +884,8 @@
   ASSERT(kind != Snapshot::kMessage);
 
   // Create the literal token object.
-  LiteralToken& literal_token = LiteralToken::ZoneHandle(
-      reader->zone(), NEW_OBJECT(LiteralToken));
+  LiteralToken& literal_token = LiteralToken::ZoneHandle(reader->zone(),
+                                                         LiteralToken::New());
   reader->AddBackRef(object_id, &literal_token, kIsDeserialized);
 
   // Read the token attributes.
@@ -1036,14 +930,14 @@
                                       Snapshot::Kind kind,
                                       bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Read the length so that we can determine number of tokens to read.
   intptr_t len = reader->ReadSmiValue();
 
   // Create the token stream object.
-  TokenStream& token_stream = TokenStream::ZoneHandle(
-      reader->zone(), NEW_OBJECT_WITH_LEN(TokenStream, len));
+  TokenStream& token_stream = TokenStream::ZoneHandle(reader->zone(),
+                                                      TokenStream::New(len));
   reader->AddBackRef(object_id, &token_stream, kIsDeserialized);
 
   // Read the stream of tokens into the TokenStream object for script
@@ -1070,7 +964,7 @@
                              Snapshot::Kind kind,
                              bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1098,10 +992,10 @@
                             Snapshot::Kind kind,
                             bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Allocate script object.
-  Script& script = Script::ZoneHandle(reader->zone(), NEW_OBJECT(Script));
+  Script& script = Script::ZoneHandle(reader->zone(), Script::New());
   reader->AddBackRef(object_id, &script, kIsDeserialized);
 
   script.StoreNonPointer(&script.raw_ptr()->line_offset_,
@@ -1139,7 +1033,7 @@
                         bool as_reference) {
   ASSERT(writer != NULL);
   ASSERT(tokens_ != TokenStream::null());
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1178,7 +1072,7 @@
     ASSERT(library.is_in_fullsnapshot());
   } else {
     // Allocate library object.
-    library = NEW_OBJECT(Library);
+    library = Library::New();
 
     // Set all non object fields.
     library.StoreNonPointer(&library.raw_ptr()->index_,
@@ -1193,9 +1087,6 @@
                             reader->Read<bool>());
     library.StoreNonPointer(&library.raw_ptr()->debuggable_,
                             reader->Read<bool>());
-    if (Snapshot::IsFull(kind)) {
-      is_in_fullsnapshot = true;
-    }
     library.StoreNonPointer(&library.raw_ptr()->is_in_fullsnapshot_,
                             is_in_fullsnapshot);
     // The native resolver and symbolizer are not serialized.
@@ -1213,13 +1104,9 @@
     }
     // Initialize cache of resolved names.
     const intptr_t kInitialNameCacheSize = 64;
-    if (!Snapshot::IsFull(kind)) {
-      // The cache of resolved names in library scope is not serialized.
-      library.InitResolvedNamesCache(kInitialNameCacheSize);
-      library.Register(reader->thread());
-    } else {
-      library.InitResolvedNamesCache(kInitialNameCacheSize, reader);
-    }
+    // The cache of resolved names in library scope is not serialized.
+    library.InitResolvedNamesCache(kInitialNameCacheSize);
+    library.Register(reader->thread());
     library.StorePointer(&library.raw_ptr()->exported_names_, Array::null());
     // Initialize cache of loaded scripts.
     library.StorePointer(&library.raw_ptr()->loaded_scripts_, Array::null());
@@ -1251,7 +1138,7 @@
     // Write out library URL so that it can be looked up when reading.
     writer->WriteObjectImpl(ptr()->url_, kAsInlinedObject);
   } else {
-    ASSERT((Snapshot::IsFull(kind)) || !ptr()->is_in_fullsnapshot_);
+    ASSERT(!ptr()->is_in_fullsnapshot_);
     // Write out all non object fields.
     ASSERT(ptr()->index_ != static_cast<classid_t>(-1));
     writer->WriteClassIDValue(ptr()->index_);
@@ -1279,11 +1166,11 @@
                                           Snapshot::Kind kind,
                                           bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Allocate library prefix object.
-  LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(
-      reader->zone(), NEW_OBJECT(LibraryPrefix));
+  LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(reader->zone(),
+                                                    LibraryPrefix::New());
   reader->AddBackRef(object_id, &prefix, kIsDeserialized);
 
   // Set all non object fields.
@@ -1298,10 +1185,6 @@
                      prefix.raw()->from(),
                      prefix.raw()->to_snapshot(kind),
                      kAsReference);
-  if (kind == Snapshot::kAppNoJIT) {
-    prefix.StorePointer(&prefix.raw_ptr()->imports_,
-                        Object::empty_array().raw());
-  }
   prefix.StorePointer(&prefix.raw_ptr()->dependent_code_,
                       Array::null());
 
@@ -1314,7 +1197,7 @@
                                Snapshot::Kind kind,
                                bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1340,11 +1223,10 @@
                                   Snapshot::Kind kind,
                                   bool as_reference) {
   ASSERT(reader != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Allocate Namespace object.
-  Namespace& ns = Namespace::ZoneHandle(
-      reader->zone(), NEW_OBJECT(Namespace));
+  Namespace& ns = Namespace::ZoneHandle(reader->zone(), Namespace::New());
   reader->AddBackRef(object_id, &ns, kIsDeserialized);
 
   // Set all the object fields.
@@ -1359,7 +1241,7 @@
                            Snapshot::Kind kind,
                            bool as_reference) {
   ASSERT(writer != NULL);
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1532,7 +1414,7 @@
   if (num_vars == 0) {
     context ^= reader->object_store()->empty_context();
   } else {
-    context ^= NEW_OBJECT_WITH_LEN(Context, num_vars);
+    context ^= Context::New(num_vars);
 
     // Set all the object fields.
     // TODO(5411462): Need to assert No GC can happen here, even though
@@ -1583,12 +1465,7 @@
   bool is_implicit = reader->Read<bool>();
   if (is_implicit) {
     ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
-    if (Snapshot::IsFull(kind)) {
-      context_scope = reader->NewContextScope(1);
-      context_scope.set_is_implicit(true);
-    } else {
-      context_scope = ContextScope::New(1, true);
-    }
+    context_scope = ContextScope::New(1, true);
     reader->AddBackRef(object_id, &context_scope, kIsDeserialized);
 
     *reader->TypeHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
@@ -1602,19 +1479,6 @@
     context_scope.SetContextIndexAt(0, 0);
     context_scope.SetContextLevelAt(0, 0);
     return context_scope.raw();
-  } else if (kind == Snapshot::kAppWithJIT) {
-    int32_t num_vars = reader->Read<int32_t>();
-
-    ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
-    context_scope = reader->NewContextScope(num_vars);
-    context_scope.set_is_implicit(false);
-    reader->AddBackRef(object_id, &context_scope, kIsDeserialized);
-
-    READ_OBJECT_FIELDS(context_scope,
-                       context_scope.raw()->from(),
-                       context_scope.raw()->to(num_vars),
-                       kAsInlinedObject);
-    return context_scope.raw();
   }
   UNREACHABLE();
   return NULL;
@@ -1645,23 +1509,6 @@
     writer->WriteObjectImpl(var->type, kAsInlinedObject);
 
     return;
-  } else if (kind == Snapshot::kAppWithJIT) {
-    // Write out the serialization header value for this object.
-    writer->WriteInlinedObjectHeader(object_id);
-
-    // Write out the class and tags information.
-    writer->WriteVMIsolateObject(kContextScopeCid);
-    writer->WriteTags(writer->GetObjectTags(this));
-
-    // Write out is_implicit flag for the context scope.
-    writer->Write<bool>(false);
-    int32_t num_vars = ptr()->num_variables_;
-    writer->Write<int32_t>(num_vars);
-
-    SnapshotWriterVisitor visitor(writer, kAsInlinedObject);
-    visitor.VisitPointers(from(), to(num_vars));
-
-    return;
   }
   UNREACHABLE();
 }
@@ -1672,9 +1519,9 @@
                             intptr_t tags,
                             Snapshot::Kind kind,
                             bool as_reference) {
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
-  ICData& result = ICData::ZoneHandle(reader->zone(), NEW_OBJECT(ICData));
+  ICData& result = ICData::ZoneHandle(reader->zone(), ICData::New());
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
   result.set_deopt_id(reader->Read<int32_t>());
@@ -1688,9 +1535,6 @@
                      result.raw()->from(),
                      result.raw()->to_snapshot(kind),
                      kAsReference);
-  if (kind == Snapshot::kAppNoJIT) {
-    result.set_owner(Function::Handle(reader->zone()));
-  }
 
   return result.raw();
 }
@@ -1700,7 +1544,7 @@
                         intptr_t object_id,
                         Snapshot::Kind kind,
                         bool as_reference) {
-  ASSERT((kind == Snapshot::kScript) || (Snapshot::IsFull(kind)));
+  ASSERT(kind == Snapshot::kScript);
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1787,7 +1631,7 @@
 
   // Allocate ApiError object.
   ApiError& api_error =
-      ApiError::ZoneHandle(reader->zone(), NEW_OBJECT(ApiError));
+      ApiError::ZoneHandle(reader->zone(), ApiError::New());
   reader->AddBackRef(object_id, &api_error, kIsDeserialized);
 
   // Set all the object fields.
@@ -1827,7 +1671,7 @@
 
   // Allocate LanguageError object.
   LanguageError& language_error =
-      LanguageError::ZoneHandle(reader->zone(), NEW_OBJECT(LanguageError));
+      LanguageError::ZoneHandle(reader->zone(), LanguageError::New());
   reader->AddBackRef(object_id, &language_error, kIsDeserialized);
 
   // Set all non object fields.
@@ -1875,7 +1719,7 @@
                                                     Snapshot::Kind kind,
                                                     bool as_reference) {
   UnhandledException& result = UnhandledException::ZoneHandle(
-      reader->zone(), NEW_OBJECT(UnhandledException));
+      reader->zone(), UnhandledException::New());
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
   // Set all the object fields.
@@ -1931,19 +1775,11 @@
   // Create an Instance object or get canonical one if it is a canonical
   // constant.
   Instance& obj = Instance::ZoneHandle(reader->zone(), Instance::null());
-  if (Snapshot::IsFull(kind)) {
-    obj = reader->NewInstance();
-    // Set the canonical bit.
-    if (RawObject::IsCanonical(tags)) {
-      obj.SetCanonical();
-    }
-  } else {
-    obj ^= Object::Allocate(kInstanceCid,
-                            Instance::InstanceSize(),
-                            HEAP_SPACE(kind));
-    if (RawObject::IsCanonical(tags)) {
-      obj = obj.CheckAndCanonicalize(reader->thread(), NULL);
-    }
+  obj ^= Object::Allocate(kInstanceCid,
+                          Instance::InstanceSize(),
+                          HEAP_SPACE(kind));
+  if (RawObject::IsCanonical(tags)) {
+    obj = obj.CheckAndCanonicalize(reader->thread(), NULL);
   }
   reader->AddBackRef(object_id, &obj, kIsDeserialized);
 
@@ -1987,24 +1823,16 @@
 
   // Create a Mint object or get canonical one if it is a canonical constant.
   Mint& mint = Mint::ZoneHandle(reader->zone(), Mint::null());
-  if (Snapshot::IsFull(kind)) {
-    mint = reader->NewMint(value);
-    // Set the canonical bit.
-    if (RawObject::IsCanonical(tags)) {
-      mint.SetCanonical();
-    }
+  // When reading a script snapshot we need to canonicalize only those object
+  // references that are objects from the core library (loaded from a
+  // full snapshot). Objects that are only in the script need not be
+  // canonicalized as they are already canonical.
+  // When reading a message snapshot we always have to canonicalize.
+  if (RawObject::IsCanonical(tags)) {
+    mint = Mint::NewCanonical(value);
+    ASSERT(mint.IsCanonical());
   } else {
-    // When reading a script snapshot we need to canonicalize only those object
-    // references that are objects from the core library (loaded from a
-    // full snapshot). Objects that are only in the script need not be
-    // canonicalized as they are already canonical.
-    // When reading a message snapshot we always have to canonicalize.
-    if (RawObject::IsCanonical(tags)) {
-      mint = Mint::NewCanonical(value);
-      ASSERT(mint.IsCanonical());
-    } else {
-      mint = Mint::New(value, HEAP_SPACE(kind));
-    }
+    mint = Mint::New(value, HEAP_SPACE(kind));
   }
   reader->AddBackRef(object_id, &mint, kIsDeserialized);
   return mint.raw();
@@ -2037,7 +1865,7 @@
   ASSERT(reader != NULL);
 
   // Allocate bigint object.
-  Bigint& obj = Bigint::ZoneHandle(reader->zone(), NEW_OBJECT(Bigint));
+  Bigint& obj = Bigint::ZoneHandle(reader->zone(), Bigint::New());
   reader->AddBackRef(object_id, &obj, kIsDeserialized);
 
   // Set all the object fields.
@@ -2049,14 +1877,9 @@
   // When reading a script snapshot or a message snapshot we always have
   // to canonicalize the object.
   if (RawObject::IsCanonical(tags)) {
-    if (Snapshot::IsFull(kind)) {
-      // Set the canonical bit.
-      obj.SetCanonical();
-    } else {
-      obj ^= obj.CheckAndCanonicalize(reader->thread(), NULL);
-      ASSERT(!obj.IsNull());
-      ASSERT(obj.IsCanonical());
-    }
+    obj ^= obj.CheckAndCanonicalize(reader->thread(), NULL);
+    ASSERT(!obj.IsNull());
+    ASSERT(obj.IsCanonical());
   }
   return obj.raw();
 }
@@ -2093,23 +1916,15 @@
 
   // Create a Double object or get canonical one if it is a canonical constant.
   Double& dbl = Double::ZoneHandle(reader->zone(), Double::null());
-  if (Snapshot::IsFull(kind)) {
-    dbl = reader->NewDouble(value);
-    // Set the canonical bit.
-    if (RawObject::IsCanonical(tags)) {
-      dbl.SetCanonical();
-    }
+  // When reading a script snapshot we need to canonicalize only those object
+  // references that are objects from the core library (loaded from a
+  // full snapshot). Objects that are only in the script need not be
+  // canonicalized as they are already canonical.
+  if (RawObject::IsCanonical(tags)) {
+    dbl = Double::NewCanonical(value);
+    ASSERT(dbl.IsCanonical());
   } else {
-    // When reading a script snapshot we need to canonicalize only those object
-    // references that are objects from the core library (loaded from a
-    // full snapshot). Objects that are only in the script need not be
-    // canonicalized as they are already canonical.
-    if (RawObject::IsCanonical(tags)) {
-      dbl = Double::NewCanonical(value);
-      ASSERT(dbl.IsCanonical());
-    } else {
-      dbl = Double::New(value, HEAP_SPACE(kind));
-    }
+    dbl = Double::New(value, HEAP_SPACE(kind));
   }
   reader->AddBackRef(object_id, &dbl, kIsDeserialized);
   return dbl.raw();
@@ -2193,28 +2008,10 @@
   // Read the length so that we can determine instance size to allocate.
   ASSERT(reader != NULL);
   intptr_t len = reader->ReadSmiValue();
-  intptr_t hash = reader->ReadSmiValue();
   String& str_obj = String::ZoneHandle(reader->zone(), String::null());
 
-  if (Snapshot::IsFull(kind)) {
-    // We currently only expect the Dart mutator to read snapshots.
-    reader->isolate()->AssertCurrentThreadIsMutator();
-    ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0);
-    RawOneByteString* obj = reader->NewOneByteString(len);
-    str_obj = obj;
-    if (RawObject::IsCanonical(tags)) {
-      str_obj.SetCanonical();
-    }
-    str_obj.SetHash(hash);
-    if (len > 0) {
-      uint8_t* raw_ptr = CharAddr(str_obj, 0);
-      reader->ReadBytes(raw_ptr, len);
-    }
-    ASSERT((hash == 0) || (String::Hash(str_obj, 0, str_obj.Length()) == hash));
-  } else {
-    String::ReadFromImpl<OneByteString, uint8_t>(
-        reader, &str_obj, len, tags, Symbols::FromLatin1, kind);
-  }
+  String::ReadFromImpl<OneByteString, uint8_t>(
+      reader, &str_obj, len, tags, Symbols::FromLatin1, kind);
   reader->AddBackRef(object_id, &str_obj, kIsDeserialized);
   return raw(str_obj);
 }
@@ -2228,28 +2025,10 @@
   // Read the length so that we can determine instance size to allocate.
   ASSERT(reader != NULL);
   intptr_t len = reader->ReadSmiValue();
-  intptr_t hash = reader->ReadSmiValue();
   String& str_obj = String::ZoneHandle(reader->zone(), String::null());
 
-  if (Snapshot::IsFull(kind)) {
-    RawTwoByteString* obj = reader->NewTwoByteString(len);
-    str_obj = obj;
-    if (RawObject::IsCanonical(tags)) {
-      str_obj.SetCanonical();
-    }
-    str_obj.SetHash(hash);
-    NoSafepointScope no_safepoint;
-    uint16_t* raw_ptr = (len > 0)? CharAddr(str_obj, 0) : NULL;
-    for (intptr_t i = 0; i < len; i++) {
-      ASSERT(CharAddr(str_obj, i) == raw_ptr);  // Will trigger assertions.
-      *raw_ptr = reader->Read<uint16_t>();
-      raw_ptr += 1;
-    }
-    ASSERT(String::Hash(str_obj, 0, str_obj.Length()) == hash);
-  } else {
-    String::ReadFromImpl<TwoByteString, uint16_t>(
-        reader, &str_obj, len, tags, Symbols::FromUTF16, kind);
-  }
+  String::ReadFromImpl<TwoByteString, uint16_t>(
+      reader, &str_obj, len, tags, Symbols::FromUTF16, kind);
   reader->AddBackRef(object_id, &str_obj, kIsDeserialized);
   return raw(str_obj);
 }
@@ -2262,7 +2041,6 @@
                           intptr_t class_id,
                           intptr_t tags,
                           RawSmi* length,
-                          RawSmi* hash,
                           T* data) {
   ASSERT(writer != NULL);
   intptr_t len = Smi::Value(length);
@@ -2277,9 +2055,6 @@
   // Write out the length field.
   writer->Write<RawObject*>(length);
 
-  // Write out the hash field.
-  writer->Write<RawObject*>(hash);
-
   // Write out the string.
   if (len > 0) {
     if (class_id == kOneByteStringCid) {
@@ -2303,7 +2078,6 @@
                 kOneByteStringCid,
                 writer->GetObjectTags(this),
                 ptr()->length_,
-                ptr()->hash_,
                 ptr()->data());
 }
 
@@ -2318,7 +2092,6 @@
                 kTwoByteStringCid,
                 writer->GetObjectTags(this),
                 ptr()->length_,
-                ptr()->hash_,
                 ptr()->data());
 }
 
@@ -2356,7 +2129,6 @@
                 kOneByteStringCid,
                 writer->GetObjectTags(this),
                 ptr()->length_,
-                ptr()->hash_,
                 ptr()->external_data_->data());
 }
 
@@ -2372,7 +2144,6 @@
                 kTwoByteStringCid,
                 writer->GetObjectTags(this),
                 ptr()->length_,
-                ptr()->hash_,
                 ptr()->external_data_->data());
 }
 
@@ -2414,7 +2185,7 @@
   }
   if (array == NULL) {
     array = &(Array::ZoneHandle(reader->zone(),
-                                NEW_OBJECT_WITH_LEN_SPACE(Array, len, kind)));
+                                Array::New(len, HEAP_SPACE(kind))));
     reader->AddBackRef(object_id, array, state);
   }
   if (!as_reference) {
@@ -2446,18 +2217,14 @@
   if (array == NULL) {
     array = &(Array::ZoneHandle(
         reader->zone(),
-        NEW_OBJECT_WITH_LEN_SPACE(ImmutableArray, len, kind)));
+        ImmutableArray::New(len, HEAP_SPACE(kind))));
     reader->AddBackRef(object_id, array, state);
   }
   if (!as_reference) {
     // Read all the individual elements for inlined objects.
     reader->ArrayReadFrom(object_id, *array, len, tags);
     if (RawObject::IsCanonical(tags)) {
-      if (Snapshot::IsFull(kind)) {
-        array->SetCanonical();
-      } else {
-        *array ^= array->CheckAndCanonicalize(reader->thread(), NULL);
-      }
+      *array ^= array->CheckAndCanonicalize(reader->thread(), NULL);
     }
   }
   return raw(*array);
@@ -2503,11 +2270,7 @@
   // Read the length so that we can determine instance size to allocate.
   GrowableObjectArray& array = GrowableObjectArray::ZoneHandle(
       reader->zone(), GrowableObjectArray::null());
-  if (Snapshot::IsFull(kind)) {
-    array = reader->NewGrowableObjectArray();
-  } else {
-    array = GrowableObjectArray::New(0, HEAP_SPACE(kind));
-  }
+  array = GrowableObjectArray::New(0, HEAP_SPACE(kind));
   reader->AddBackRef(object_id, &array, kIsDeserialized);
 
   // Read type arguments of growable array object.
@@ -2562,17 +2325,13 @@
 
   LinkedHashMap& map = LinkedHashMap::ZoneHandle(
       reader->zone(), LinkedHashMap::null());
-  if (Snapshot::IsFull(kind) || kind == Snapshot::kScript) {
+  if (kind == Snapshot::kScript) {
     // The immutable maps that seed map literals are not yet VM-internal, so
     // we don't reach this.
     UNREACHABLE();
   } else {
     // Since the map might contain itself as a key or value, allocate first.
-    if (Snapshot::IsFull(kind)) {
-      map = reader->NewLinkedHashMap();
-    } else {
-      map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind));
-    }
+    map = LinkedHashMap::NewUninitialized(HEAP_SPACE(kind));
   }
   reader->AddBackRef(object_id, &map, kIsDeserialized);
 
@@ -2593,9 +2352,7 @@
       Utils::RoundUpToPowerOfTwo(used_data),
       static_cast<uintptr_t>(LinkedHashMap::kInitialIndexSize));
   Array& data = Array::ZoneHandle(reader->zone(),
-                                  NEW_OBJECT_WITH_LEN_SPACE(Array,
-                                                            data_size,
-                                                            kind));
+                                  Array::New(data_size, HEAP_SPACE(kind)));
   map.SetData(data);
   map.SetDeletedKeys(0);
 
@@ -2620,7 +2377,7 @@
                                intptr_t object_id,
                                Snapshot::Kind kind,
                                bool as_reference) {
-  if (Snapshot::IsFull(kind) || kind == Snapshot::kScript) {
+  if (kind == Snapshot::kScript) {
     // The immutable maps that seed map literals are not yet VM-internal, so
     // we don't reach this.
   }
@@ -2682,11 +2439,7 @@
   // Create a Float32x4 object.
   Float32x4& simd = Float32x4::ZoneHandle(reader->zone(),
                                           Float32x4::null());
-  if (Snapshot::IsFull(kind)) {
-    simd = reader->NewFloat32x4(value0, value1, value2, value3);
-  } else {
-    simd = Float32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
-  }
+  simd = Float32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
   reader->AddBackRef(object_id, &simd, kIsDeserialized);
   return simd.raw();
 }
@@ -2727,12 +2480,7 @@
 
   // Create a Float32x4 object.
   Int32x4& simd = Int32x4::ZoneHandle(reader->zone(), Int32x4::null());
-
-  if (Snapshot::IsFull(kind)) {
-    simd = reader->NewInt32x4(value0, value1, value2, value3);
-  } else {
-    simd = Int32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
-  }
+  simd = Int32x4::New(value0, value1, value2, value3, HEAP_SPACE(kind));
   reader->AddBackRef(object_id, &simd, kIsDeserialized);
   return simd.raw();
 }
@@ -2772,11 +2520,7 @@
   // Create a Float64x2 object.
   Float64x2& simd = Float64x2::ZoneHandle(reader->zone(),
                                           Float64x2::null());
-  if (Snapshot::IsFull(kind)) {
-    simd = reader->NewFloat64x2(value0, value1);
-  } else {
-    simd = Float64x2::New(value0, value1, HEAP_SPACE(kind));
-  }
+  simd = Float64x2::New(value0, value1, HEAP_SPACE(kind));
   reader->AddBackRef(object_id, &simd, kIsDeserialized);
   return simd.raw();
 }
@@ -2816,9 +2560,8 @@
 
   intptr_t cid = RawObject::ClassIdTag::decode(tags);
   intptr_t len = reader->ReadSmiValue();
-  TypedData& result = TypedData::ZoneHandle(reader->zone(),
-      (Snapshot::IsFull(kind)) ? reader->NewTypedData(cid, len)
-                                : TypedData::New(cid, len, HEAP_SPACE(kind)));
+  TypedData& result = TypedData::ZoneHandle(
+      reader->zone(), TypedData::New(cid, len, HEAP_SPACE(kind)));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
   // Setup the array elements.
@@ -2866,14 +2609,9 @@
   // When reading a script snapshot or a message snapshot we always have
   // to canonicalize the object.
   if (RawObject::IsCanonical(tags)) {
-    if (Snapshot::IsFull(kind)) {
-      // Set the canonical bit.
-      result.SetCanonical();
-    } else {
-      result ^= result.CheckAndCanonicalize(reader->thread(), NULL);
-      ASSERT(!result.IsNull());
-      ASSERT(result.IsCanonical());
-    }
+    result ^= result.CheckAndCanonicalize(reader->thread(), NULL);
+    ASSERT(!result.IsNull());
+    ASSERT(result.IsCanonical());
   }
   return result.raw();
 }
@@ -3129,21 +2867,6 @@
                                     intptr_t tags,
                                     Snapshot::Kind kind,
                                     bool as_reference) {
-  if (Snapshot::IsFull(kind)) {
-    Stacktrace& result = Stacktrace::ZoneHandle(reader->zone(),
-                                                reader->NewStacktrace());
-    reader->AddBackRef(object_id, &result, kIsDeserialized);
-
-    bool expand_inlined = reader->Read<bool>();
-    result.set_expand_inlined(expand_inlined);
-
-    // Set all the object fields.
-    READ_OBJECT_FIELDS(result,
-                       result.raw()->from(), result.raw()->to(),
-                       kAsReference);
-
-    return result.raw();
-  }
   UNREACHABLE();  // Stacktraces are not sent in a snapshot.
   return Stacktrace::null();
 }
@@ -3153,29 +2876,10 @@
                             intptr_t object_id,
                             Snapshot::Kind kind,
                             bool as_reference) {
-  if (Snapshot::IsFull(kind)) {
-    ASSERT(writer != NULL);
-    ASSERT(this == Isolate::Current()->object_store()->
-           preallocated_stack_trace());
-
-    // Write out the serialization header value for this object.
-    writer->WriteInlinedObjectHeader(object_id);
-
-    // Write out the class and tags information.
-    writer->WriteIndexedObject(kStacktraceCid);
-    writer->WriteTags(writer->GetObjectTags(this));
-
-    writer->Write(ptr()->expand_inlined_);
-
-    // Write out all the object pointer fields.
-    SnapshotWriterVisitor visitor(writer, kAsReference);
-    visitor.VisitPointers(from(), to());
-  } else {
-    // Stacktraces are not allowed in other snapshot forms.
-    writer->SetWriteException(Exceptions::kArgument,
-                              "Illegal argument in isolate message"
-                              " : (object is a stacktrace)");
-  }
+  ASSERT(kind == Snapshot::kMessage);
+  writer->SetWriteException(Exceptions::kArgument,
+                            "Illegal argument in isolate message"
+                            " : (object is a stacktrace)");
 }
 
 
@@ -3187,7 +2891,7 @@
   ASSERT(reader != NULL);
 
   // Allocate RegExp object.
-  RegExp& regex = RegExp::ZoneHandle(reader->zone(), NEW_OBJECT(RegExp));
+  RegExp& regex = RegExp::ZoneHandle(reader->zone(), RegExp::New());
   reader->AddBackRef(object_id, &regex, kIsDeserialized);
 
   // Read and Set all the other fields.
@@ -3244,8 +2948,8 @@
   ASSERT(reader != NULL);
 
   // Allocate the weak property object.
-  WeakProperty& weak_property = WeakProperty::ZoneHandle(
-      reader->zone(), NEW_OBJECT(WeakProperty));
+  WeakProperty& weak_property = WeakProperty::ZoneHandle(reader->zone(),
+                                                         WeakProperty::New());
   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 f119a25..9edfbf6 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -5251,13 +5251,7 @@
   const intptr_t kParamCount = RegExpMacroAssembler::kParamCount;
 
   Function& fn = Function::Handle(zone, Function::New(
-      // Append the regexp pattern to the function name.
-      String::Handle(zone, Symbols::New(thread,
-          String::Handle(zone, String::Concat(
-              String::Handle(zone, String::Concat(
-                  Symbols::ColonMatcher(),
-                  Symbols::ColonSpace(), Heap::kOld)),
-              String::Handle(regexp.pattern()), Heap::kOld)))),
+      Symbols::ColonMatcher(),
       RawFunction::kIrregexpFunction,
       true,  // Static.
       false,  // Not const.
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index 60e46a0..51ac960 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -33,6 +33,7 @@
   V(OptimizeInvokedFunction)                                                   \
   V(TraceICCall)                                                               \
   V(PatchStaticCall)                                                           \
+  V(RangeError)                                                                \
   V(ReThrow)                                                                   \
   V(StackOverflow)                                                             \
   V(Throw)                                                                     \
@@ -43,6 +44,7 @@
   V(InitStaticField)                                                           \
   V(GrowRegExpStack)                                                           \
   V(CompileFunction)                                                           \
+  V(MonomorphicMiss)                                                           \
 
 #define LEAF_RUNTIME_ENTRY_LIST(V)                                             \
   V(void, PrintStopMessage, const char*)                                       \
diff --git a/runtime/vm/safepoint.cc b/runtime/vm/safepoint.cc
index 6cbd0f7..7f5d92d 100644
--- a/runtime/vm/safepoint.cc
+++ b/runtime/vm/safepoint.cc
@@ -41,12 +41,14 @@
     : isolate_(isolate),
       safepoint_lock_(new Monitor()),
       number_threads_not_at_safepoint_(0),
-      safepoint_in_progress_(false) {
+      safepoint_operation_count_(0),
+      owner_(NULL) {
 }
 
 
 SafepointHandler::~SafepointHandler() {
-  ASSERT(safepoint_in_progress_ == false);
+  ASSERT(owner_ == NULL);
+  ASSERT(safepoint_operation_count_ == 0);
   delete safepoint_lock_;
   safepoint_lock_ = NULL;
   isolate_ = NULL;
@@ -63,12 +65,19 @@
 
     // Now check to see if a safepoint operation is already in progress
     // for this isolate, block if an operation is in progress.
-    while (safepoint_in_progress()) {
+    while (SafepointInProgress()) {
+      // If we are recursively invoking a Safepoint operation then we
+      // just increment the count and return, otherwise we wait for the
+      // safepoint operation to be done.
+      if (owner_ == T) {
+        increment_safepoint_operation_count();
+        return;
+      }
       sl.WaitWithSafepointCheck(T);
     }
 
-    // Set safepoint in progress by this thread.
-    set_safepoint_in_progress(true);
+    // Set safepoint in progress state by this thread.
+    SetSafepointInProgress(T);
 
     // Go over the active thread list and ensure that all threads active
     // in the isolate reach a safepoint.
@@ -101,9 +110,13 @@
       Monitor::WaitResult retval = sl.Wait(1000);
       if (retval == Monitor::kTimedOut) {
         num_attempts += 1;
-        OS::Print("Attempt:%" Pd " waiting for %d threads to check in\n",
-                  num_attempts,
-                  number_threads_not_at_safepoint_);
+        if (num_attempts > 10) {
+          // We have been waiting too long, start logging this as we might
+          // have an issue where a thread is not checking in for a safepoint.
+          OS::Print("Attempt:%" Pd " waiting for %d threads to check in\n",
+                    num_attempts,
+                    number_threads_not_at_safepoint_);
+        }
       }
     }
   }
@@ -114,6 +127,14 @@
   // First resume all the threads which are blocked for the safepoint
   // operation.
   MonitorLocker sl(threads_lock());
+
+  // First check if we are in a recursive safepoint operation, in that case
+  // we just decrement safepoint_operation_count and return.
+  ASSERT(SafepointInProgress());
+  if (safepoint_operation_count() > 1) {
+    decrement_safepoint_operation_count();
+    return;
+  }
   Thread* current = isolate()->thread_registry()->active_list();
   while (current != NULL) {
     MonitorLocker tl(current->thread_lock());
@@ -127,10 +148,10 @@
     }
     current = current->next();
   }
-  // Now set the safepoint_in_progress_ flag to false and notify all threads
+  // Now reset the safepoint_in_progress_ state and notify all threads
   // that are waiting to enter the isolate or waiting to start another
   // safepoint operation.
-  set_safepoint_in_progress(false);
+  ResetSafepointInProgress(T);
   sl.NotifyAll();
 }
 
diff --git a/runtime/vm/safepoint.h b/runtime/vm/safepoint.h
index 58afb49..15c2c98 100644
--- a/runtime/vm/safepoint.h
+++ b/runtime/vm/safepoint.h
@@ -33,21 +33,45 @@
   void EnterSafepointUsingLock(Thread* T);
   void ExitSafepointUsingLock(Thread* T);
 
-  void SafepointThreads(Thread* T);
-  void ResumeThreads(Thread* T);
-
   void BlockForSafepoint(Thread* T);
 
  private:
+  void SafepointThreads(Thread* T);
+  void ResumeThreads(Thread* T);
+
   Isolate* isolate() const { return isolate_; }
   Monitor* threads_lock() const { return isolate_->threads_lock(); }
-  bool safepoint_in_progress() const {
+  bool SafepointInProgress() const {
     ASSERT(threads_lock()->IsOwnedByCurrentThread());
-    return safepoint_in_progress_;
+    return ((safepoint_operation_count_ > 0) && (owner_ != NULL));
   }
-  void set_safepoint_in_progress(bool value) {
+  void SetSafepointInProgress(Thread* T) {
     ASSERT(threads_lock()->IsOwnedByCurrentThread());
-    safepoint_in_progress_ = value;
+    ASSERT(owner_ == NULL);
+    ASSERT(safepoint_operation_count_ == 0);
+    safepoint_operation_count_ = 1;
+    owner_ = T;
+  }
+  void ResetSafepointInProgress(Thread* T) {
+    ASSERT(threads_lock()->IsOwnedByCurrentThread());
+    ASSERT(owner_ == T);
+    ASSERT(safepoint_operation_count_ == 1);
+    safepoint_operation_count_ = 0;
+    owner_ = NULL;
+  }
+  int32_t safepoint_operation_count() const {
+    ASSERT(threads_lock()->IsOwnedByCurrentThread());
+    return safepoint_operation_count_;
+  }
+  void increment_safepoint_operation_count() {
+    ASSERT(threads_lock()->IsOwnedByCurrentThread());
+    ASSERT(safepoint_operation_count_ < kMaxInt32);
+    safepoint_operation_count_ += 1;
+  }
+  void decrement_safepoint_operation_count() {
+    ASSERT(threads_lock()->IsOwnedByCurrentThread());
+    ASSERT(safepoint_operation_count_ > 0);
+    safepoint_operation_count_ -= 1;
   }
 
   Isolate* isolate_;
@@ -57,8 +81,14 @@
   Monitor* safepoint_lock_;
   int32_t number_threads_not_at_safepoint_;
 
-  // Flag to indicate if a safepoint operation is currently in progress.
-  bool safepoint_in_progress_;
+  // Count that indicates if a safepoint operation is currently in progress
+  // and also tracks the number of recursive safepoint operations on the
+  // same thread.
+  int32_t safepoint_operation_count_;
+
+  // If a safepoint operation is currently in progress, this field contains
+  // the thread that initiated the safepoint operation, otherwise it is NULL.
+  Thread* owner_;
 
   friend class Isolate;
   friend class SafepointOperationScope;
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index d1bfd3f..cb028ce 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -124,14 +124,14 @@
       new_addr = ForwardedAddr(header);
     } else {
       intptr_t size = raw_obj->Size();
-      intptr_t cid = raw_obj->GetClassId();
-      ClassTable* class_table = isolate()->class_table();
+      NOT_IN_PRODUCT(intptr_t cid = raw_obj->GetClassId());
+      NOT_IN_PRODUCT(ClassTable* class_table = isolate()->class_table());
       // Check whether object should be promoted.
       if (scavenger_->survivor_end_ <= raw_addr) {
         // Not a survivor of a previous scavenge. Just copy the object into the
         // to space.
         new_addr = scavenger_->TryAllocate(size);
-        class_table->UpdateLiveNew(cid, size);
+        NOT_IN_PRODUCT(class_table->UpdateLiveNew(cid, size));
       } else {
         // TODO(iposva): Experiment with less aggressive promotion. For example
         // a coin toss determines if an object is promoted or whether it should
@@ -146,11 +146,11 @@
           // be traversed later.
           scavenger_->PushToPromotedStack(new_addr);
           bytes_promoted_ += size;
-          class_table->UpdateAllocatedOld(cid, size);
+          NOT_IN_PRODUCT(class_table->UpdateAllocatedOld(cid, size));
         } else {
           // Promotion did not succeed. Copy into the to space instead.
           new_addr = scavenger_->TryAllocate(size);
-          class_table->UpdateLiveNew(cid, size);
+          NOT_IN_PRODUCT(class_table->UpdateLiveNew(cid, size));
         }
       }
       // During a scavenge we always succeed to at least copy all of the
@@ -487,6 +487,7 @@
 
 void Scavenger::IterateObjectIdTable(Isolate* isolate,
                                      ScavengerVisitor* visitor) {
+#ifndef PRODUCT
   if (!FLAG_support_service) {
     return;
   }
@@ -497,6 +498,7 @@
     return;
   }
   ring->VisitPointers(visitor);
+#endif  // !PRODUCT
 }
 
 
@@ -858,6 +860,7 @@
 }
 
 
+#ifndef PRODUCT
 void Scavenger::PrintToJSONObject(JSONObject* object) const {
   if (!FLAG_support_service) {
     return;
@@ -885,6 +888,7 @@
   space.AddProperty64("external", ExternalInWords() * kWordSize);
   space.AddProperty("time", MicrosecondsToSeconds(gc_time_micros()));
 }
+#endif  // !PRODUCT
 
 
 void Scavenger::AllocateExternal(intptr_t size) {
diff --git a/runtime/vm/scavenger.h b/runtime/vm/scavenger.h
index 5e7dcb1..8fce1a4 100644
--- a/runtime/vm/scavenger.h
+++ b/runtime/vm/scavenger.h
@@ -204,7 +204,9 @@
     return collections_;
   }
 
+#ifndef PRODUCT
   void PrintToJSONObject(JSONObject* object) const;
+#endif  // !PRODUCT
 
   void AllocateExternal(intptr_t size);
   void FreeExternal(intptr_t size);
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index e209d3b..a6864b3 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -1339,12 +1339,13 @@
 
 
 static bool GetStack(Thread* thread, JSONStream* js) {
-  if (!thread->isolate()->compilation_allowed()) {
+  Isolate* isolate = thread->isolate();
+  if (isolate->debugger() == NULL) {
     js->PrintError(kFeatureDisabled,
-        "Cannot get stack when running a precompiled program.");
+                   "Cannot get stack when debugger disabled.");
     return true;
   }
-  Isolate* isolate = thread->isolate();
+  ASSERT(isolate->compilation_allowed());
   DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
   // Do we want the complete script object and complete local variable objects?
   // This is true for dump requests.
@@ -2005,21 +2006,37 @@
   Smi& slot_offset = Smi::Handle();
   Class& element_class = Class::Handle();
   Array& element_field_map = Array::Handle();
+  LinkedHashMap& map = LinkedHashMap::Handle();
+  Array& map_data = Array::Handle();
   Field& field = Field::Handle();
   limit = Utils::Minimum(limit, length);
   for (intptr_t i = 0; i < limit; ++i) {
     JSONObject jselement(&elements);
     element = path.At(i * 2);
-    jselement.AddProperty("index", i);
     jselement.AddProperty("value", element);
-    // Interpret the word offset from parent as list index or instance field.
-    // TODO(koda): User-friendly interpretation for map entries.
+    // Interpret the word offset from parent as list index, map key
+    // or instance field.
     if (i > 0) {
       slot_offset ^= path.At((i * 2) - 1);
-      if (element.IsArray()) {
+      jselement.AddProperty("offset", slot_offset.Value());
+      if (element.IsArray() || element.IsGrowableObjectArray()) {
         intptr_t element_index = slot_offset.Value() -
             (Array::element_offset(0) >> kWordSizeLog2);
         jselement.AddProperty("parentListIndex", element_index);
+      } else if (element.IsLinkedHashMap()) {
+        map = static_cast<RawLinkedHashMap*>(path.At(i * 2));
+        map_data = map.data();
+        intptr_t element_index = slot_offset.Value() -
+            (Array::element_offset(0) >> kWordSizeLog2);
+        LinkedHashMap::Iterator iterator(map);
+        while (iterator.MoveNext()) {
+          if (iterator.CurrentKey() == map_data.At(element_index) ||
+              iterator.CurrentValue() == map_data.At(element_index)) {
+            element = iterator.CurrentKey();
+            jselement.AddProperty("parentMapKey", element);
+            break;
+          }
+        }
       } else if (element.IsInstance()) {
         element_class ^= element.clazz();
         element_field_map = element_class.OffsetToFieldMap();
@@ -2456,6 +2473,7 @@
 
 static const MethodParameter* reload_sources_params[] = {
   RUNNABLE_ISOLATE_PARAMETER,
+  new BoolParameter("force", false),
   NULL,
 };
 
@@ -2488,19 +2506,11 @@
                    "This isolate cannot reload sources right now.");
     return true;
   }
+  const bool force_reload =
+      BoolParameter::Parse(js->LookupParam("force"), false);
 
-  isolate->ReloadSources();
+  isolate->ReloadSources(js, force_reload);
 
-  const Error& error = Error::Handle(isolate->sticky_reload_error());
-
-  if (error.IsNull()) {
-    PrintSuccess(js);
-  } else {
-    // Clear the sticky error.
-    isolate->clear_sticky_reload_error();
-    js->PrintError(kIsolateReloadFailed,
-                   "Isolate reload failed: %s", error.ToErrorCString());
-  }
   return true;
 }
 
@@ -3792,6 +3802,7 @@
   jsobj.AddProperty("version", Version::String());
   jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart");
   jsobj.AddProperty64("pid", OS::ProcessId());
+  jsobj.AddProperty64("_maxRSS", OS::MaxRSS());
   int64_t start_time_millis = (vm_isolate->start_time() /
                                kMicrosecondsPerMillisecond);
   jsobj.AddPropertyTimeMillis("startTime", start_time_millis);
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 6e3c180..7aab061 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1535,7 +1535,7 @@
   //   Type
   string name [optional];
 
-  // The corresponding Class if this Type is canonical.
+  // The corresponding Class if this Type has a resolved typeClass.
   //
   // Provided for instance kinds:
   //   Type
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 94af480..3ff1e1b 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -23,6 +23,8 @@
       extension_rpc_(NULL),
       exception_(NULL),
       reload_error_(NULL),
+      spawn_token_(NULL),
+      spawn_error_(NULL),
       at_async_jump_(false),
       inspectee_(NULL),
       gc_stats_(NULL),
@@ -69,6 +71,8 @@
       return "ServiceExtensionAdded";
     case kIsolateReload:
       return "IsolateReload";
+    case kIsolateSpawn:
+      return "IsolateSpawn";
     case kPauseStart:
       return "PauseStart";
     case kPauseExit:
@@ -122,6 +126,7 @@
     case kIsolateExit:
     case kIsolateUpdate:
     case kIsolateReload:
+    case kIsolateSpawn:
     case kServiceExtensionAdded:
       return &Service::isolate_stream;
 
@@ -183,6 +188,16 @@
       jsobj.AddProperty("reloadError", *(reload_error()));
     }
   }
+  if (kind() == kIsolateSpawn) {
+    ASSERT(spawn_token() != NULL);
+    jsobj.AddPropertyStr("spawnToken", *(spawn_token()));
+    if (spawn_error_ == NULL) {
+      jsobj.AddProperty("status", "success");
+    } else {
+      jsobj.AddProperty("status", "failure");
+      jsobj.AddPropertyStr("spawnError", *(spawn_error()));
+    }
+  }
   if (kind() == kServiceExtensionAdded) {
     ASSERT(extension_rpc_ != NULL);
     jsobj.AddProperty("extensionRPC", extension_rpc_->ToCString());
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index d6bc92e..cd48844 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -29,6 +29,7 @@
     kIsolateExit,            // Isolate has exited
     kIsolateUpdate,          // Isolate identity information has changed
     kIsolateReload,          // Result of a reload request
+    kIsolateSpawn,           // Result of an isolate spawn request
     kServiceExtensionAdded,  // A service extension was registered
 
     kPauseStart,         // --pause-isolates-on-start
@@ -158,6 +159,24 @@
     reload_error_ = error;
   }
 
+  const String* spawn_token() const {
+    ASSERT(kind_ == kIsolateSpawn);
+    return spawn_token_;
+  }
+  void set_spawn_token(const String* error) {
+    ASSERT(kind_ == kIsolateSpawn);
+    spawn_token_ = error;
+  }
+
+  const String* spawn_error() const {
+    ASSERT(kind_ == kIsolateSpawn);
+    return spawn_error_;
+  }
+  void set_spawn_error(const String* error) {
+    ASSERT(kind_ == kIsolateSpawn);
+    spawn_error_ = error;
+  }
+
   bool at_async_jump() const {
     return at_async_jump_;
   }
@@ -232,6 +251,8 @@
   const String* extension_rpc_;
   const Object* exception_;
   const Error* reload_error_;
+  const String* spawn_token_;
+  const String* spawn_error_;
   bool at_async_jump_;
   const Object* inspectee_;
   const Heap::GCStats* gc_stats_;
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index e85a5c0..c5e2e75 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -23,8 +23,6 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, shutdown);
-
 #define Z (T->zone())
 
 
@@ -333,7 +331,9 @@
                                                    NULL,
                                                    &error));
     if (isolate == NULL) {
-      OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
+      if (FLAG_trace_service) {
+        OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
+      }
       ServiceIsolate::SetServiceIsolate(NULL);
       ServiceIsolate::FinishedInitializing();
       ServiceIsolate::FinishedExiting();
@@ -462,9 +462,6 @@
 
 
 void ServiceIsolate::KillServiceIsolate() {
-  if (!FLAG_shutdown) {
-    return;
-  }
   {
     MonitorLocker ml(monitor_);
     shutting_down_ = true;
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index c272b4c..8a19298 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -115,6 +115,50 @@
 }
 
 
+TEST_CASE(Service_IsolateStickyError) {
+  const char* kScript =
+      "main() => throw 'HI THERE STICKY';\n";
+
+  Isolate* isolate = thread->isolate();
+  isolate->set_is_runnable(true);
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  Library& vmlib = Library::Handle();
+  vmlib ^= Api::UnwrapHandle(lib);
+  EXPECT(!vmlib.IsNull());
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT(Dart_IsUnhandledExceptionError(result));
+  EXPECT(!Dart_HasStickyError());
+  EXPECT(Thread::Current()->sticky_error() == Error::null());
+
+  {
+    TransitionNativeToVM transition(thread);
+
+    JSONStream js;
+    isolate->PrintJSON(&js, false);
+    // No error property and no PauseExit state.
+    EXPECT_NOTSUBSTRING("\"error\":", js.ToCString());
+    EXPECT_NOTSUBSTRING("HI THERE STICKY", js.ToCString());
+    EXPECT_NOTSUBSTRING("PauseExit", js.ToCString());
+  }
+
+  // Set the sticky error.
+  Dart_SetStickyError(result);
+  EXPECT(Dart_HasStickyError());
+
+  {
+    TransitionNativeToVM transition(thread);
+
+    JSONStream js;
+    isolate->PrintJSON(&js, false);
+    // Error and PauseExit set.
+    EXPECT_SUBSTRING("\"error\":", js.ToCString());
+    EXPECT_SUBSTRING("HI THERE STICKY", js.ToCString());
+    EXPECT_SUBSTRING("PauseExit", js.ToCString());
+  }
+}
+
+
 TEST_CASE(Service_IdZones) {
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
@@ -184,7 +228,7 @@
   const Code& code_c = Code::Handle(function_c.CurrentCode());
   EXPECT(!code_c.IsNull());
   // Use the entry of the code object as it's reference.
-  uword entry = code_c.EntryPoint();
+  uword entry = code_c.PayloadStart();
   int64_t compile_timestamp = code_c.compile_timestamp();
   EXPECT_GT(code_c.Size(), 16);
   uword last = entry + code_c.Size();
diff --git a/runtime/vm/signal_handler_android.cc b/runtime/vm/signal_handler_android.cc
index 64670de..8812c63 100644
--- a/runtime/vm/signal_handler_android.cc
+++ b/runtime/vm/signal_handler_android.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
+#include "vm/instructions.h"
 #include "vm/simulator.h"
 #include "vm/signal_handler.h"
 #if defined(TARGET_OS_ANDROID)
@@ -65,20 +66,11 @@
 
 
 uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
-  uintptr_t sp = 0;
-
-#if defined(HOST_ARCH_IA32)
-  sp = static_cast<uintptr_t>(mcontext.gregs[REG_ESP]);
-#elif defined(HOST_ARCH_X64)
-  sp = static_cast<uintptr_t>(mcontext.gregs[REG_RSP]);
-#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[19]);
+#if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
+  return static_cast<uintptr_t>(mcontext.regs[SPREG]);
 #else
-#error Unsupported architecture.
-#endif  // HOST_ARCH_...
-  return sp;
+  return GetCStackPointer(mcontext);
+#endif
 }
 
 
diff --git a/runtime/vm/signal_handler_linux.cc b/runtime/vm/signal_handler_linux.cc
index 1df46f0..b867c00 100644
--- a/runtime/vm/signal_handler_linux.cc
+++ b/runtime/vm/signal_handler_linux.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
+#include "vm/instructions.h"
 #include "vm/simulator.h"
 #include "vm/signal_handler.h"
 #if defined(TARGET_OS_LINUX)
@@ -72,7 +73,7 @@
 
 uintptr_t SignalHandler::GetDartStackPointer(const mcontext_t& mcontext) {
 #if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
-  return static_cast<uintptr_t>(mcontext.regs[19]);
+  return static_cast<uintptr_t>(mcontext.regs[SPREG]);
 #else
   return GetCStackPointer(mcontext);
 #endif
diff --git a/runtime/vm/signal_handler_macos.cc b/runtime/vm/signal_handler_macos.cc
index bfcc42c..75c9c09 100644
--- a/runtime/vm/signal_handler_macos.cc
+++ b/runtime/vm/signal_handler_macos.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/globals.h"
+#include "vm/instructions.h"
 #include "vm/simulator.h"
 #include "vm/signal_handler.h"
 #if defined(TARGET_OS_MACOS)
@@ -68,7 +69,7 @@
 
 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]);
+  return static_cast<uintptr_t>(mcontext->__ss.__x[SPREG]);
 #else
   return GetCStackPointer(mcontext);
 #endif
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 24c934b..3077c8b6 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -247,7 +247,7 @@
 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
                                                             uword pc) {
   TokenPosition token_pos = TokenPosition::kNoSource;
-  uword pc_offset = pc - code.EntryPoint();
+  uword pc_offset = pc - code.PayloadStart();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
@@ -1531,7 +1531,7 @@
         Redirection* redirection = Redirection::FromSvcInstruction(instr);
         uword external = redirection->external_function();
         if (IsTracingExecution()) {
-          OS::Print("Call to host function at 0x%" Pd "\n", external);
+          THR_Print("Call to host function at 0x%" Pd "\n", external);
         }
 
         if ((redirection->call_kind() == kRuntimeCall) ||
@@ -3607,13 +3607,13 @@
 void Simulator::InstructionDecode(Instr* instr) {
   pc_modified_ = false;
   if (IsTracingExecution()) {
-    OS::Print("%" Pu64 " ", icount_);
+    THR_Print("%" Pu64 " ", icount_);
     const uword start = reinterpret_cast<uword>(instr);
     const uword end = start + Instr::kInstrSize;
     if (FLAG_support_disassembler) {
       Disassembler::Disassemble(start, end);
     } else {
-      OS::Print("Disassembler not supported in this mode.\n");
+      THR_Print("Disassembler not supported in this mode.\n");
     }
   }
   if (instr->ConditionField() == kSpecialCondition) {
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index b3cac8b..610b857 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -265,7 +265,7 @@
 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
                                                             uword pc) {
   TokenPosition token_pos = TokenPosition::kNoSource;
-  uword pc_offset = pc - code.EntryPoint();
+  uword pc_offset = pc - code.PayloadStart();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
@@ -1603,7 +1603,7 @@
     Redirection* redirection = Redirection::FromHltInstruction(instr);
     uword external = redirection->external_function();
     if (IsTracingExecution()) {
-      OS::Print("Call to host function at 0x%" Pd "\n", external);
+      THR_Print("Call to host function at 0x%" Pd "\n", external);
     }
 
     if ((redirection->call_kind() == kRuntimeCall) ||
@@ -3406,13 +3406,13 @@
 void Simulator::InstructionDecode(Instr* instr) {
   pc_modified_ = false;
   if (IsTracingExecution()) {
-    OS::Print("%" Pu64 " ", icount_);
+    THR_Print("%" Pu64 " ", icount_);
     const uword start = reinterpret_cast<uword>(instr);
     const uword end = start + Instr::kInstrSize;
     if (FLAG_support_disassembler) {
       Disassembler::Disassemble(start, end);
     } else {
-      OS::Print("Disassembler not supported in this mode.\n");
+      THR_Print("Disassembler not supported in this mode.\n");
     }
   }
 
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index b1c648d..c26cb75 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -122,6 +122,17 @@
     f->ptr()->usage_counter_++;
   }
 
+  DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries,
+                                                      intptr_t offset,
+                                                      intptr_t args_tested) {
+    const intptr_t count_offset = ICData::CountIndexFor(args_tested);
+    const intptr_t raw_smi_old =
+        reinterpret_cast<intptr_t>(entries[offset + count_offset]);
+    const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1);
+    *reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) =
+        raw_smi_new;
+  }
+
   DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs,
                                                              RawObject* rhs) {
     if (lhs == rhs) {
@@ -588,7 +599,8 @@
                                                 RawObjectPool** pp,
                                                 uint32_t** pc,
                                                 RawObject*** FP,
-                                                RawObject*** SP) {
+                                                RawObject*** SP,
+                                                bool optimized) {
   ASSERT(icdata->GetClassId() == kICDataCid);
 
   const intptr_t kCheckedArgs = 1;
@@ -599,7 +611,8 @@
 
   bool found = false;
   const intptr_t length = Smi::Value(cache->length_);
-  for (intptr_t i = 0;
+  intptr_t i;
+  for (i = 0;
        i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if (cache->data()[i + 0] == receiver_cid) {
       top[0] = cache->data()[i + kCheckedArgs];
@@ -608,7 +621,11 @@
     }
   }
 
-  if (!found) {
+  if (found) {
+    if (!optimized) {
+      SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs);
+    }
+  } else {
     InlineCacheMiss(
         kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP);
   }
@@ -626,7 +643,8 @@
                                                 RawObjectPool** pp,
                                                 uint32_t** pc,
                                                 RawObject*** FP,
-                                                RawObject*** SP) {
+                                                RawObject*** SP,
+                                                bool optimized) {
   ASSERT(icdata->GetClassId() == kICDataCid);
 
   const intptr_t kCheckedArgs = 2;
@@ -638,7 +656,8 @@
 
   bool found = false;
   const intptr_t length = Smi::Value(cache->length_);
-  for (intptr_t i = 0;
+  intptr_t i;
+  for (i = 0;
        i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if ((cache->data()[i + 0] == receiver_cid) &&
         (cache->data()[i + 1] == arg0_cid)) {
@@ -648,7 +667,11 @@
     }
   }
 
-  if (!found) {
+  if (found) {
+    if (!optimized) {
+      SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs);
+    }
+  } else {
     InlineCacheMiss(
         kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP);
   }
@@ -762,12 +785,8 @@
     ASSERT(Bytecode::IsCallOpcode(*pc));                                       \
     const uint16_t kidx = Bytecode::DecodeD(*pc);                              \
     const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));           \
-    RawObject** data = icdata->ptr()->ic_data_->ptr()->data();                 \
-    const intptr_t count_offset = ICData::CountIndexFor(2);                    \
-    const intptr_t raw_smi_old =                                               \
-        reinterpret_cast<intptr_t>(data[count_offset]);                        \
-    const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1);               \
-    *reinterpret_cast<intptr_t*>(&data[count_offset]) = raw_smi_new;           \
+    RawObject** entries = icdata->ptr()->ic_data_->ptr()->data();              \
+    SimulatorHelpers::IncrementICUsageCount(entries, 0, 2);                    \
   } while (0);                                                                 \
 
 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the
@@ -779,7 +798,9 @@
     const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]);                   \
     const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]);                   \
     ResultT* slot = reinterpret_cast<ResultT*>(SP - 1);                        \
-    if (LIKELY(AreBothSmis(lhs, rhs) && !Func(lhs, rhs, slot))) {              \
+    if (LIKELY(!thread->isolate()->single_step()) &&                           \
+        LIKELY(AreBothSmis(lhs, rhs) &&                                        \
+        !Func(lhs, rhs, slot))) {                                              \
       SMI_FASTPATH_ICDATA_INC;                                                 \
       /* Fast path succeeded. Skip the generic call that follows. */           \
       pc++;                                                                    \
@@ -1374,7 +1395,7 @@
   }
 
   {
-    BYTECODE(StaticCall, A_D);
+    BYTECODE(IndirectStaticCall, A_D);
 
     // Check if single stepping.
     if (thread->isolate()->single_step()) {
@@ -1386,6 +1407,13 @@
     // Invoke target function.
     {
       const uint16_t argc = rA;
+      // Lookup the funciton in the ICData.
+      RawObject* ic_data_obj = SP[0];
+      RawICData* ic_data = RAW_CAST(ICData, ic_data_obj);
+      RawObject** data = ic_data->ptr()->ic_data_->ptr()->data();
+      SimulatorHelpers::IncrementICUsageCount(data, 0, 0);
+      SP[0] = data[ICData::TargetIndexFor(
+          ic_data->ptr()->state_bits_ & 0x3)];
       RawObject** call_base = SP - argc;
       RawObject** call_top = SP;  // *SP contains function
       argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD));
@@ -1396,6 +1424,16 @@
   }
 
   {
+    BYTECODE(StaticCall, A_D);
+    const uint16_t argc = rA;
+    RawObject** call_base = SP - argc;
+    RawObject** call_top = SP;  // *SP contains function
+    argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD));
+    Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP);
+    DISPATCH();
+  }
+
+  {
     BYTECODE(InstanceCall1, A_D);
 
     // Check if single stepping.
@@ -1415,8 +1453,9 @@
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(
           RAW_CAST(Function, icdata->ptr()->owner_));
-      InstanceCall1(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall1(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    false /* optimized */);
     }
 
     DISPATCH();
@@ -1440,8 +1479,9 @@
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(
           RAW_CAST(Function, icdata->ptr()->owner_));
-      InstanceCall2(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall2(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    false /* optimized */);
     }
 
     DISPATCH();
@@ -1459,8 +1499,9 @@
 
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
-      InstanceCall1(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall1(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    true /* optimized */);
     }
 
     DISPATCH();
@@ -1478,14 +1519,35 @@
 
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
-      InstanceCall2(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall2(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    true /* optimized */);
     }
 
     DISPATCH();
   }
 
   {
+    BYTECODE(PushPolymorphicInstanceCall, A_D);
+    const uint8_t argc = rA;
+    const intptr_t cids_length = rD;
+    RawObject** args = SP - argc + 1;
+    const intptr_t receiver_cid = SimulatorHelpers::GetClassId(args[0]);
+    for (intptr_t i = 0; i < 2*cids_length; i+=2) {
+      const intptr_t icdata_cid = Bytecode::DecodeD(*(pc + i));
+      if (receiver_cid == icdata_cid) {
+        RawFunction* target =
+            RAW_CAST(Function, LOAD_CONSTANT(Bytecode::DecodeD(*(pc + i + 1))));
+        *++SP = target;
+        pc++;
+        break;
+      }
+    }
+    pc += 2 * cids_length;
+    DISPATCH();
+  }
+
+  {
     BYTECODE(NativeBootstrapCall, 0);
     RawFunction* function = FrameFunction(FP);
     RawObject** incoming_args =
@@ -1694,6 +1756,316 @@
     DISPATCH();
   }
 
+  {
+    BYTECODE(ShrImm, A_B_C);
+    const uint8_t shift = rC;
+    const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]) >> kSmiTagSize;
+    *reinterpret_cast<intptr_t*>(&FP[rA]) = (lhs >> shift) << kSmiTagSize;
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(Min, A_B_C);
+    const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]);
+    const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]);
+    FP[rA] = reinterpret_cast<RawObject*>((lhs < rhs) ? lhs : rhs);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(Max, A_B_C);
+    const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rB]);
+    const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rC]);
+    FP[rA] = reinterpret_cast<RawObject*>((lhs > rhs) ? lhs : rhs);
+    DISPATCH();
+  }
+
+#if defined(ARCH_IS_64_BIT)
+  {
+    BYTECODE(WriteIntoDouble, A_D);
+    const double value = bit_cast<double, RawObject*>(FP[rD]);
+    RawDouble* box = RAW_CAST(Double, *SP--);
+    box->ptr()->value_ = value;
+    FP[rA] = box;
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(UnboxDouble, A_D);
+    const RawDouble* box = RAW_CAST(Double, FP[rD]);
+    FP[rA] = bit_cast<RawObject*, double>(box->ptr()->value_);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(CheckedUnboxDouble, A_D);
+    const intptr_t box_cid = SimulatorHelpers::GetClassId(FP[rD]);
+    if (box_cid == kSmiCid) {
+      const intptr_t value = reinterpret_cast<intptr_t>(FP[rD]) >> kSmiTagSize;
+      const double result = static_cast<double>(value);
+      FP[rA] = bit_cast<RawObject*, double>(result);
+      pc++;
+    } else if (box_cid == kDoubleCid) {
+      const RawDouble* box = RAW_CAST(Double, FP[rD]);
+      FP[rA] = bit_cast<RawObject*, double>(box->ptr()->value_);
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DoubleToSmi, A_D);
+    const double value = bit_cast<double, RawObject*>(FP[rD]);
+    if (!isnan(value)) {
+      const intptr_t result = static_cast<intptr_t>(value);
+      if ((result <= Smi::kMaxValue) && (result >= Smi::kMinValue)) {
+        FP[rA] = reinterpret_cast<RawObject*>(result << kSmiTagSize);
+        pc++;
+      }
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(SmiToDouble, A_D);
+    const intptr_t value = reinterpret_cast<intptr_t>(FP[rD]) >> kSmiTagSize;
+    const double result = static_cast<double>(value);
+    FP[rA] = bit_cast<RawObject*, double>(result);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DAdd, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    FP[rA] = bit_cast<RawObject*, double>(lhs + rhs);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DSub, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    FP[rA] = bit_cast<RawObject*, double>(lhs - rhs);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMul, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    FP[rA] = bit_cast<RawObject*, double>(lhs * rhs);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DDiv, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    const double result = lhs / rhs;
+    FP[rA] = bit_cast<RawObject*, double>(result);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DNeg, A_D);
+    const double value = bit_cast<double, RawObject*>(FP[rD]);
+    FP[rA] = bit_cast<RawObject*, double>(-value);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DSqrt, A_D);
+    const double value = bit_cast<double, RawObject*>(FP[rD]);
+    FP[rA] = bit_cast<RawObject*, double>(sqrt(value));
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DSin, A_D);
+    const double value = bit_cast<double, RawObject*>(FP[rD]);
+    FP[rA] = bit_cast<RawObject*, double>(sin(value));
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DCos, A_D);
+    const double value = bit_cast<double, RawObject*>(FP[rD]);
+    FP[rA] = bit_cast<RawObject*, double>(cos(value));
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DPow, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    const double result = pow(lhs, rhs);
+    FP[rA] = bit_cast<RawObject*, double>(result);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMod, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    const double result = DartModulo(lhs, rhs);
+    FP[rA] = bit_cast<RawObject*, double>(result);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMin, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    FP[rA] = bit_cast<RawObject*, double>(fmin(lhs, rhs));
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMax, A_B_C);
+    const double lhs = bit_cast<double, RawObject*>(FP[rB]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rC]);
+    FP[rA] = bit_cast<RawObject*, double>(fmax(lhs, rhs));
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(LoadFloat64Indexed, A_B_C);
+    ASSERT(RawObject::IsTypedDataClassId(FP[rB]->GetClassId()));
+    RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rB]);
+    RawSmi* index = RAW_CAST(Smi, FP[rC]);
+    ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
+    double* data = reinterpret_cast<double*>(array->ptr()->data());
+    FP[rA] = bit_cast<RawObject*, double>(data[Smi::Value(index)]);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(StoreFloat64Indexed, A_B_C);
+    ASSERT(RawObject::IsTypedDataClassId(FP[rA]->GetClassId()));
+    RawTypedData* array = reinterpret_cast<RawTypedData*>(FP[rA]);
+    RawSmi* index = RAW_CAST(Smi, FP[rB]);
+    ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
+    double* data = reinterpret_cast<double*>(array->ptr()->data());
+    data[Smi::Value(index)] = bit_cast<double, RawObject*>(FP[rC]);
+    DISPATCH();
+  }
+#else  // defined(ARCH_IS_64_BIT)
+  {
+    BYTECODE(WriteIntoDouble, A_D);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(UnboxDouble, A_D);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(CheckedUnboxDouble, A_D);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DoubleToSmi, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(SmiToDouble, A_D);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DAdd, A_B_C);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DSub, A_B_C);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMul, A_B_C);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DDiv, A_B_C);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DNeg, A_D);
+    UNIMPLEMENTED();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DSqrt, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DSin, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DCos, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DPow, A_B_C);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMod, A_B_C);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMin, A_B_C);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(DMax, A_B_C);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(LoadFloat64Indexed, A_B_C);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(StoreFloat64Indexed, A_B_C);
+    UNREACHABLE();
+    DISPATCH();
+  }
+#endif  // defined(ARCH_IS_64_BIT)
+
   // Return and return like instructions (Instrinsic).
   {
     RawObject* result;  // result to return to the caller.
@@ -2058,6 +2430,27 @@
   }
 
   {
+    BYTECODE(TestCids, A_D);
+    const intptr_t cid = SimulatorHelpers::GetClassId(FP[rA]);
+    const intptr_t num_cases = rD;
+    for (intptr_t i = 0; i < num_cases; i++) {
+      ASSERT(Bytecode::DecodeOpcode(pc[i]) == Bytecode::kNop);
+      intptr_t test_target = Bytecode::DecodeA(pc[i]);
+      intptr_t test_cid = Bytecode::DecodeD(pc[i]);
+      if (cid == test_cid) {
+        if (test_target != 0) {
+          pc += 1;  // Match true.
+        } else {
+          pc += 2;  // Match false.
+        }
+        break;
+      }
+    }
+    pc += num_cases;
+    DISPATCH();
+  }
+
+  {
     BYTECODE(CheckSmi, 0);
     intptr_t obj = reinterpret_cast<intptr_t>(FP[rA]);
     if ((obj & kSmiTagMask) == kSmiTag) {
@@ -2067,8 +2460,20 @@
   }
 
   {
+    BYTECODE(CheckEitherNonSmi, A_D);
+    const intptr_t obj1 = reinterpret_cast<intptr_t>(FP[rA]);
+    const intptr_t obj2 = reinterpret_cast<intptr_t>(FP[rD]);
+    const intptr_t tag = (obj1 | obj2) & kSmiTagMask;
+    if (tag != kSmiTag) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
     BYTECODE(CheckClassId, A_D);
-    const intptr_t actual_cid = SimulatorHelpers::GetClassId(FP[rA]);
+    const intptr_t actual_cid =
+        reinterpret_cast<intptr_t>(FP[rA]) >> kSmiTagSize;
     const intptr_t desired_cid = rD;
     pc += (actual_cid == desired_cid) ? 1 : 0;
     DISPATCH();
@@ -2194,6 +2599,172 @@
   }
 
   {
+    BYTECODE(IfLe, A_D);
+    const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rA]);
+    const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rD]);
+    if (lhs > rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfLt, A_D);
+    const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rA]);
+    const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rD]);
+    if (lhs >= rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfGe, A_D);
+    const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rA]);
+    const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rD]);
+    if (lhs < rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfGt, A_D);
+    const intptr_t lhs = reinterpret_cast<intptr_t>(FP[rA]);
+    const intptr_t rhs = reinterpret_cast<intptr_t>(FP[rD]);
+    if (lhs <= rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfULe, A_D);
+    const uintptr_t lhs = reinterpret_cast<uintptr_t>(FP[rA]);
+    const uintptr_t rhs = reinterpret_cast<uintptr_t>(FP[rD]);
+    if (lhs > rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfULt, A_D);
+    const uintptr_t lhs = reinterpret_cast<uintptr_t>(FP[rA]);
+    const uintptr_t rhs = reinterpret_cast<uintptr_t>(FP[rD]);
+    if (lhs >= rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfUGe, A_D);
+    const uintptr_t lhs = reinterpret_cast<uintptr_t>(FP[rA]);
+    const uintptr_t rhs = reinterpret_cast<uintptr_t>(FP[rD]);
+    if (lhs < rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfUGt, A_D);
+    const uintptr_t lhs = reinterpret_cast<uintptr_t>(FP[rA]);
+    const uintptr_t rhs = reinterpret_cast<uintptr_t>(FP[rD]);
+    if (lhs <= rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+#if defined(ARCH_IS_64_BIT)
+  {
+    BYTECODE(IfDEq, A_D);
+    const double lhs = bit_cast<double, RawObject*>(FP[rA]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rD]);
+    pc += (lhs == rhs) ? 0 : 1;
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDNe, A_D);
+    const double lhs = bit_cast<double, RawObject*>(FP[rA]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rD]);
+    pc += (lhs != rhs) ? 0 : 1;
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDLe, A_D);
+    const double lhs = bit_cast<double, RawObject*>(FP[rA]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rD]);
+    pc += (lhs <= rhs) ? 0 : 1;
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDLt, A_D);
+    const double lhs = bit_cast<double, RawObject*>(FP[rA]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rD]);
+    pc += (lhs < rhs) ? 0 : 1;
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDGe, A_D);
+    const double lhs = bit_cast<double, RawObject*>(FP[rA]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rD]);
+    pc += (lhs >= rhs) ? 0 : 1;
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDGt, A_D);
+    const double lhs = bit_cast<double, RawObject*>(FP[rA]);
+    const double rhs = bit_cast<double, RawObject*>(FP[rD]);
+    pc += (lhs > rhs) ? 0 : 1;
+    DISPATCH();
+  }
+#else  // defined(ARCH_IS_64_BIT)
+  {
+    BYTECODE(IfDEq, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDNe, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDLe, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDLt, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDGe, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfDGt, A_D);
+    UNREACHABLE();
+    DISPATCH();
+  }
+#endif  // defined(ARCH_IS_64_BIT)
+
+  {
     BYTECODE(IfEqStrictNum, A_D);
     RawObject* lhs = FP[rA];
     RawObject* rhs = FP[rD];
@@ -2254,11 +2825,9 @@
   {
     BYTECODE(StoreIndexedTOS, 0);
     SP -= 3;
-    RawArray* array = static_cast<RawArray*>(SP[1]);
-    RawSmi* index = static_cast<RawSmi*>(SP[2]);
+    RawArray* array = RAW_CAST(Array, SP[1]);
+    RawSmi* index = RAW_CAST(Smi, SP[2]);
     RawObject* value = SP[3];
-    ASSERT(array->GetClassId() == kArrayCid);
-    ASSERT(!index->IsHeapObject());
     ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
     array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
     DISPATCH();
@@ -2266,17 +2835,42 @@
 
   {
     BYTECODE(StoreIndexed, A_B_C);
-    RawArray* array = static_cast<RawArray*>(FP[rA]);
-    RawSmi* index = static_cast<RawSmi*>(FP[rB]);
+    RawArray* array = RAW_CAST(Array, FP[rA]);
+    RawSmi* index = RAW_CAST(Smi, FP[rB]);
     RawObject* value = FP[rC];
-    ASSERT(array->GetClassId() == kArrayCid);
-    ASSERT(!index->IsHeapObject());
     ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
     array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
     DISPATCH();
   }
 
   {
+    BYTECODE(LoadIndexed, A_B_C);
+    RawArray* array = RAW_CAST(Array, FP[rB]);
+    RawSmi* index = RAW_CAST(Smi, FP[rC]);
+    ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
+    FP[rA] = array->ptr()->data()[Smi::Value(index)];
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(LoadOneByteStringIndexed, A_B_C);
+    RawOneByteString* array = RAW_CAST(OneByteString, FP[rB]);
+    RawSmi* index = RAW_CAST(Smi, FP[rC]);
+    ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
+    FP[rA] = Smi::New(array->ptr()->data()[Smi::Value(index)]);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(LoadTwoByteStringIndexed, A_B_C);
+    RawTwoByteString* array = RAW_CAST(TwoByteString, FP[rB]);
+    RawSmi* index = RAW_CAST(Smi, FP[rC]);
+    ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
+    FP[rA] = Smi::New(array->ptr()->data()[Smi::Value(index)]);
+    DISPATCH();
+  }
+
+  {
     BYTECODE(Deopt, A_D);
     const bool is_lazy = rD == 0;
 
@@ -2422,6 +3016,7 @@
   return 0;
 }
 
+
 void Simulator::Longjmp(uword pc,
                         uword sp,
                         uword fp,
@@ -2459,5 +3054,4 @@
 
 }  // namespace dart
 
-
 #endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/simulator_dbc.h b/runtime/vm/simulator_dbc.h
index 7172bbe..2cbadce 100644
--- a/runtime/vm/simulator_dbc.h
+++ b/runtime/vm/simulator_dbc.h
@@ -127,7 +127,7 @@
               RawObject** call_top,
               RawObjectPool** pp,
               uint32_t** pc,
-              RawObject*** B,
+              RawObject*** FP,
               RawObject*** SP);
 
   void InlineCacheMiss(int checked_args,
@@ -136,7 +136,7 @@
                        RawObject** call_base,
                        RawObject** top,
                        uint32_t* pc,
-                       RawObject** B, RawObject** SP);
+                       RawObject** FP, RawObject** SP);
 
   void InstanceCall1(Thread* thread,
                      RawICData* icdata,
@@ -145,7 +145,8 @@
                      RawArray** argdesc,
                      RawObjectPool** pp,
                      uint32_t** pc,
-                     RawObject*** B, RawObject*** SP);
+                     RawObject*** FP, RawObject*** SP,
+                     bool optimized);
 
   void InstanceCall2(Thread* thread,
                      RawICData* icdata,
@@ -154,7 +155,8 @@
                      RawArray** argdesc,
                      RawObjectPool** pp,
                      uint32_t** pc,
-                     RawObject*** B, RawObject*** SP);
+                     RawObject*** FP, RawObject*** SP,
+                     bool optimized);
 
   // Longjmp support for exceptions.
   SimulatorSetjmpBuffer* last_setjmp_buffer() {
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index d980ca1..eb03c49 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -258,7 +258,7 @@
 TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
                                                      uword pc) {
   TokenPosition token_pos = TokenPosition::kNoSource;
-  uword pc_offset = pc - code.EntryPoint();
+  uword pc_offset = pc - code.PayloadStart();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
@@ -1242,7 +1242,7 @@
       Redirection* redirection = Redirection::FromBreakInstruction(instr);
       uword external = redirection->external_function();
       if (IsTracingExecution()) {
-        OS::Print("Call to host function at 0x%" Pd "\n", external);
+        THR_Print("Call to host function at 0x%" Pd "\n", external);
       }
 
       if ((redirection->call_kind() == kRuntimeCall) ||
@@ -1994,13 +1994,13 @@
 
 void Simulator::InstructionDecode(Instr* instr) {
   if (IsTracingExecution()) {
-    OS::Print("%" Pu64 " ", icount_);
+    THR_Print("%" Pu64 " ", icount_);
     const uword start = reinterpret_cast<uword>(instr);
     const uword end = start + Instr::kInstrSize;
     if (FLAG_support_disassembler) {
       Disassembler::Disassemble(start, end);
     } else {
-      OS::Print("Disassembler not supported in this mode.\n");
+      THR_Print("Disassembler not supported in this mode.\n");
     }
   }
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 4195995..d6891e2 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -166,14 +166,10 @@
 SnapshotReader::SnapshotReader(
     const uint8_t* buffer,
     intptr_t size,
-    const uint8_t* instructions_buffer,
-    const uint8_t* data_buffer,
     Snapshot::Kind kind,
     ZoneGrowableArray<BackRefNode>* backward_refs,
     Thread* thread)
     : BaseReader(buffer, size),
-      instructions_buffer_(instructions_buffer),
-      data_buffer_(data_buffer),
       kind_(kind),
       thread_(thread),
       zone_(thread->zone()),
@@ -192,19 +188,12 @@
       stream_(TokenStream::Handle(zone_)),
       data_(ExternalTypedData::Handle(zone_)),
       typed_data_(TypedData::Handle(zone_)),
-      code_(Code::Handle(zone_)),
       function_(Function::Handle(zone_)),
-      megamorphic_cache_(MegamorphicCache::Handle(zone_)),
       error_(UnhandledException::Handle(zone_)),
       max_vm_isolate_object_id_(
           (Snapshot::IsFull(kind)) ?
               Object::vm_isolate_snapshot_object_table().Length() : 0),
-      backward_references_(backward_refs),
-      instructions_reader_(NULL) {
-  if (instructions_buffer != NULL) {
-    instructions_reader_ =
-        new InstructionsReader(instructions_buffer, data_buffer);
-  }
+      backward_references_(backward_refs) {
 }
 
 
@@ -220,9 +209,7 @@
         (*backward_references_)[i].set_state(kIsDeserialized);
       }
     }
-    if (!Snapshot::IsFull(kind())) {
-      ProcessDeferredCanonicalizations();
-    }
+    ProcessDeferredCanonicalizations();
     return obj.raw();
   } else {
     // An error occurred while reading, return the error object.
@@ -480,11 +467,7 @@
     instance_size = cls_.instance_size();
     ASSERT(instance_size > 0);
     // Allocate the instance and read in all the fields for the object.
-    if (Snapshot::IsFull(kind_)) {
-      *result ^= AllocateUninitialized(cls_.id(), instance_size);
-    } else {
-      *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
-    }
+    *result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_));
   } else {
     cls_ ^= ReadObjectImpl(kAsInlinedObject);
     ASSERT(!cls_.IsNull());
@@ -522,21 +505,9 @@
       // snapshot (kFull, kScript) with asserts.
       offset += kWordSize;
     }
-    if (Snapshot::IsFull(kind_)) {
-      // We create an uninitialized object in the case of full snapshots, so
-      // we need to initialize any remaining padding area with the Null object.
-      while (offset < instance_size) {
-        result->SetFieldAtOffset(offset, Object::null_object());
-        offset += kWordSize;
-      }
-    }
     if (RawObject::IsCanonical(tags)) {
-      if (Snapshot::IsFull(kind_)) {
-        result->SetCanonical();
-      } else {
-        *result = result->CheckAndCanonicalize(thread(), NULL);
-        ASSERT(!result->IsNull());
-      }
+      *result = result->CheckAndCanonicalize(thread(), NULL);
+      ASSERT(!result->IsNull());
     }
   }
   return result->raw();
@@ -681,418 +652,16 @@
 }
 
 
-#define ALLOC_NEW_OBJECT_WITH_LEN(type, length)                                \
-  ASSERT(Snapshot::IsFull(kind_));                                            \
-  ASSERT_NO_SAFEPOINT_SCOPE();                                                 \
-  Raw##type* obj = reinterpret_cast<Raw##type*>(                               \
-      AllocateUninitialized(k##type##Cid, type::InstanceSize(length)));        \
-  obj->StoreSmi(&(obj->ptr()->length_), Smi::New(length));                     \
-  return obj;                                                                  \
-
-
-RawArray* SnapshotReader::NewArray(intptr_t len) {
-  ALLOC_NEW_OBJECT_WITH_LEN(Array, len);
-}
-
-
-RawImmutableArray* SnapshotReader::NewImmutableArray(intptr_t len) {
-  ALLOC_NEW_OBJECT_WITH_LEN(ImmutableArray, len);
-}
-
-
-RawOneByteString* SnapshotReader::NewOneByteString(intptr_t len) {
-  ALLOC_NEW_OBJECT_WITH_LEN(OneByteString, len);
-}
-
-
-RawTwoByteString* SnapshotReader::NewTwoByteString(intptr_t len) {
-  ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, len);
-}
-
-
-RawTypeArguments* SnapshotReader::NewTypeArguments(intptr_t len) {
-  ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, len);
-}
-
-
-RawObjectPool* SnapshotReader::NewObjectPool(intptr_t len) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawObjectPool* obj = reinterpret_cast<RawObjectPool*>(
-      AllocateUninitialized(kObjectPoolCid, ObjectPool::InstanceSize(len)));
-  obj->ptr()->length_ = len;
-  return obj;
-}
-
-
-RawLocalVarDescriptors* SnapshotReader::NewLocalVarDescriptors(
-    intptr_t num_entries) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawLocalVarDescriptors* obj = reinterpret_cast<RawLocalVarDescriptors*>(
-      AllocateUninitialized(kLocalVarDescriptorsCid,
-                            LocalVarDescriptors::InstanceSize(num_entries)));
-  obj->ptr()->num_entries_ = num_entries;
-  return obj;
-}
-
-
-RawExceptionHandlers* SnapshotReader::NewExceptionHandlers(
-    intptr_t num_entries) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawExceptionHandlers* obj = reinterpret_cast<RawExceptionHandlers*>(
-      AllocateUninitialized(kExceptionHandlersCid,
-                            ExceptionHandlers::InstanceSize(num_entries)));
-  obj->ptr()->num_entries_ = num_entries;
-  return obj;
-}
-
-
-RawPcDescriptors* SnapshotReader::NewPcDescriptors(intptr_t len) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawPcDescriptors* obj = reinterpret_cast<RawPcDescriptors*>(
-      AllocateUninitialized(kPcDescriptorsCid,
-                            PcDescriptors::InstanceSize(len)));
-  obj->ptr()->length_ = len;
-  return obj;
-}
-
-
-RawCodeSourceMap* SnapshotReader::NewCodeSourceMap(intptr_t len) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawCodeSourceMap* obj = reinterpret_cast<RawCodeSourceMap*>(
-      AllocateUninitialized(kCodeSourceMapCid,
-                            CodeSourceMap::InstanceSize(len)));
-  obj->ptr()->length_ = len;
-  return obj;
-}
-
-
-RawStackmap* SnapshotReader::NewStackmap(intptr_t len) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawStackmap* obj = reinterpret_cast<RawStackmap*>(
-      AllocateUninitialized(kStackmapCid, Stackmap::InstanceSize(len)));
-  obj->ptr()->length_ = len;
-  return obj;
-}
-
-
-RawContextScope* SnapshotReader::NewContextScope(intptr_t num_variables) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawContextScope* obj = reinterpret_cast<RawContextScope*>(
-      AllocateUninitialized(kContextScopeCid,
-                            ContextScope::InstanceSize(num_variables)));
-  obj->ptr()->num_variables_ = num_variables;
-  return obj;
-}
-
-
-RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) {
-  ASSERT(pointer_offsets_length == 0);
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawCode* obj = reinterpret_cast<RawCode*>(
-      AllocateUninitialized(kCodeCid, Code::InstanceSize(0)));
-  return obj;
-}
-
-
-RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  stream_ = reinterpret_cast<RawTokenStream*>(
-      AllocateUninitialized(kTokenStreamCid, TokenStream::InstanceSize()));
-  uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress());
-  ASSERT(array != NULL);
-  Advance(len);
-  data_ = reinterpret_cast<RawExternalTypedData*>(
-      AllocateUninitialized(kExternalTypedDataUint8ArrayCid,
-                            ExternalTypedData::InstanceSize()));
-  data_.SetData(array);
-  data_.SetLength(len);
-  stream_.SetStream(data_);
-  return stream_.raw();
-}
-
-
-RawContext* SnapshotReader::NewContext(intptr_t num_variables) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawContext* obj = reinterpret_cast<RawContext*>(
-      AllocateUninitialized(kContextCid, Context::InstanceSize(num_variables)));
-  obj->ptr()->num_variables_ = num_variables;
-  return obj;
-}
-
-
-RawClass* SnapshotReader::NewClass(intptr_t class_id) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  if (class_id < kNumPredefinedCids) {
-    ASSERT((class_id >= kInstanceCid) &&
-           (class_id <= kNullCid));
-    return isolate()->class_table()->At(class_id);
-  }
-  RawClass* obj = reinterpret_cast<RawClass*>(
-      AllocateUninitialized(kClassCid, Class::InstanceSize()));
-  Instance fake;
-  obj->ptr()->handle_vtable_ = fake.vtable();
-  cls_ = obj;
-  cls_.set_id(class_id);
-  isolate()->RegisterClassAt(class_id, cls_);
-  return cls_.raw();
-}
-
-
-RawInstance* SnapshotReader::NewInstance() {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawInstance* obj = reinterpret_cast<RawInstance*>(
-      AllocateUninitialized(kInstanceCid, Instance::InstanceSize()));
-  return obj;
-}
-
-
-RawMint* SnapshotReader::NewMint(int64_t value) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawMint* obj = reinterpret_cast<RawMint*>(
-      AllocateUninitialized(kMintCid, Mint::InstanceSize()));
-  obj->ptr()->value_ = value;
-  return obj;
-}
-
-
-RawDouble* SnapshotReader::NewDouble(double value) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawDouble* obj = reinterpret_cast<RawDouble*>(
-      AllocateUninitialized(kDoubleCid, Double::InstanceSize()));
-  obj->ptr()->value_ = value;
-  return obj;
-}
-
-
-RawTypedData* SnapshotReader::NewTypedData(intptr_t class_id, intptr_t len) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  const intptr_t lengthInBytes = len * TypedData::ElementSizeInBytes(class_id);
-  RawTypedData* obj = reinterpret_cast<RawTypedData*>(
-      AllocateUninitialized(class_id, TypedData::InstanceSize(lengthInBytes)));
-  obj->StoreSmi(&(obj->ptr()->length_), Smi::New(len));
-  return obj;
-}
-
-
-#define ALLOC_NEW_OBJECT(type)                                                 \
-  ASSERT(Snapshot::IsFull(kind_));                                            \
-  ASSERT_NO_SAFEPOINT_SCOPE();                                                 \
-  return reinterpret_cast<Raw##type*>(                                         \
-      AllocateUninitialized(k##type##Cid, type::InstanceSize()));              \
-
-
-RawBigint* SnapshotReader::NewBigint() {
-  ALLOC_NEW_OBJECT(Bigint);
-}
-
-
-RawUnresolvedClass* SnapshotReader::NewUnresolvedClass() {
-  ALLOC_NEW_OBJECT(UnresolvedClass);
-}
-
-
-RawType* SnapshotReader::NewType() {
-  ALLOC_NEW_OBJECT(Type);
-}
-
-
-RawTypeRef* SnapshotReader::NewTypeRef() {
-  ALLOC_NEW_OBJECT(TypeRef);
-}
-
-
-RawTypeParameter* SnapshotReader::NewTypeParameter() {
-  ALLOC_NEW_OBJECT(TypeParameter);
-}
-
-
-RawBoundedType* SnapshotReader::NewBoundedType() {
-  ALLOC_NEW_OBJECT(BoundedType);
-}
-
-
-RawMixinAppType* SnapshotReader::NewMixinAppType() {
-  ALLOC_NEW_OBJECT(MixinAppType);
-}
-
-
-RawPatchClass* SnapshotReader::NewPatchClass() {
-  ALLOC_NEW_OBJECT(PatchClass);
-}
-
-
-RawClosure* SnapshotReader::NewClosure() {
-  ALLOC_NEW_OBJECT(Closure);
-}
-
-
-RawClosureData* SnapshotReader::NewClosureData() {
-  ALLOC_NEW_OBJECT(ClosureData);
-}
-
-
-RawRedirectionData* SnapshotReader::NewRedirectionData() {
-  ALLOC_NEW_OBJECT(RedirectionData);
-}
-
-
-RawFunction* SnapshotReader::NewFunction() {
-  ALLOC_NEW_OBJECT(Function);
-}
-
-
-RawICData* SnapshotReader::NewICData() {
-  ALLOC_NEW_OBJECT(ICData);
-}
-
-
-RawLinkedHashMap* SnapshotReader::NewLinkedHashMap() {
-  ALLOC_NEW_OBJECT(LinkedHashMap);
-}
-
-
-RawMegamorphicCache* SnapshotReader::NewMegamorphicCache() {
-  ALLOC_NEW_OBJECT(MegamorphicCache);
-}
-
-
-RawSubtypeTestCache* SnapshotReader::NewSubtypeTestCache() {
-  ALLOC_NEW_OBJECT(SubtypeTestCache);
-}
-
-
-RawField* SnapshotReader::NewField() {
-  ALLOC_NEW_OBJECT(Field);
-}
-
-
-RawLibrary* SnapshotReader::NewLibrary() {
-  ALLOC_NEW_OBJECT(Library);
-}
-
-
-RawLibraryPrefix* SnapshotReader::NewLibraryPrefix() {
-  ALLOC_NEW_OBJECT(LibraryPrefix);
-}
-
-
-RawNamespace* SnapshotReader::NewNamespace() {
-  ALLOC_NEW_OBJECT(Namespace);
-}
-
-
-RawScript* SnapshotReader::NewScript() {
-  ALLOC_NEW_OBJECT(Script);
-}
-
-
-RawLiteralToken* SnapshotReader::NewLiteralToken() {
-  ALLOC_NEW_OBJECT(LiteralToken);
-}
-
-
-RawGrowableObjectArray* SnapshotReader::NewGrowableObjectArray() {
-  ALLOC_NEW_OBJECT(GrowableObjectArray);
-}
-
-
-RawWeakProperty* SnapshotReader::NewWeakProperty() {
-  ALLOC_NEW_OBJECT(WeakProperty);
-}
-
-
-RawRegExp* SnapshotReader::NewRegExp() {
-  ALLOC_NEW_OBJECT(RegExp);
-}
-
-
-RawFloat32x4* SnapshotReader::NewFloat32x4(float v0, float v1, float v2,
-                                           float v3) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawFloat32x4* obj = reinterpret_cast<RawFloat32x4*>(
-      AllocateUninitialized(kFloat32x4Cid, Float32x4::InstanceSize()));
-  obj->ptr()->value_[0] = v0;
-  obj->ptr()->value_[1] = v1;
-  obj->ptr()->value_[2] = v2;
-  obj->ptr()->value_[3] = v3;
-  return obj;
-}
-
-
-RawInt32x4* SnapshotReader::NewInt32x4(uint32_t v0, uint32_t v1, uint32_t v2,
-                                       uint32_t v3) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawInt32x4* obj = reinterpret_cast<RawInt32x4*>(
-      AllocateUninitialized(kInt32x4Cid, Int32x4::InstanceSize()));
-  obj->ptr()->value_[0] = v0;
-  obj->ptr()->value_[1] = v1;
-  obj->ptr()->value_[2] = v2;
-  obj->ptr()->value_[3] = v3;
-  return obj;
-}
-
-
-RawFloat64x2* SnapshotReader::NewFloat64x2(double v0, double v1) {
-  ASSERT(Snapshot::IsFull(kind_));
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  RawFloat64x2* obj = reinterpret_cast<RawFloat64x2*>(
-      AllocateUninitialized(kFloat64x2Cid, Float64x2::InstanceSize()));
-  obj->ptr()->value_[0] = v0;
-  obj->ptr()->value_[1] = v1;
-  return obj;
-}
-
-
-RawApiError* SnapshotReader::NewApiError() {
-  ALLOC_NEW_OBJECT(ApiError);
-}
-
-
-RawLanguageError* SnapshotReader::NewLanguageError() {
-  ALLOC_NEW_OBJECT(LanguageError);
-}
-
-
-RawUnhandledException* SnapshotReader::NewUnhandledException() {
-  ALLOC_NEW_OBJECT(UnhandledException);
-}
-
-
 RawObject* SnapshotReader::NewInteger(int64_t value) {
   ASSERT((value & kSmiTagMask) == kSmiTag);
   value = value >> kSmiTagShift;
   if (Smi::IsValid(value)) {
     return Smi::New(static_cast<intptr_t>(value));
   }
-  if (Snapshot::IsFull(kind_)) {
-    return NewMint(value);
-  }
   return Mint::NewCanonical(value);
 }
 
 
-RawStacktrace* SnapshotReader::NewStacktrace() {
-  ALLOC_NEW_OBJECT(Stacktrace);
-}
-
-
 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions,
                                          RawCode* code) {
 #if defined(PRODUCT)
@@ -1207,7 +776,7 @@
     // 2. Write a label at the entry point.
     owner = code.owner();
     if (owner.IsNull()) {
-      const char* name = StubCode::NameOfStub(insns.EntryPoint());
+      const char* name = StubCode::NameOfStub(insns.UncheckedEntryPoint());
       assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
     } else if (owner.IsClass()) {
       str = Class::Cast(owner).Name();
@@ -1422,34 +991,6 @@
 }
 
 
-RawObject* SnapshotReader::AllocateUninitialized(intptr_t class_id,
-                                                 intptr_t size) {
-  ASSERT_NO_SAFEPOINT_SCOPE();
-  ASSERT(Utils::IsAligned(size, kObjectAlignment));
-
-  uword address =
-      old_space()->TryAllocateDataBumpLocked(size, PageSpace::kForceGrowth);
-  if (address == 0) {
-    // Use the preallocated out of memory exception to avoid calling
-    // into dart code or allocating any code.
-    // We do a longjmp at this point to unwind out of the entire
-    // read part and return the error object back.
-    const UnhandledException& error = UnhandledException::Handle(
-        object_store()->preallocated_unhandled_exception());
-    thread()->long_jump_base()->Jump(1, error);
-  }
-
-  RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
-  uword tags = 0;
-  ASSERT(class_id != kIllegalCid);
-  tags = RawObject::ClassIdTag::update(class_id, tags);
-  tags = RawObject::SizeTag::update(size, tags);
-  tags = RawObject::VMHeapObjectTag::update(is_vm_isolate(), tags);
-  raw_obj->ptr()->tags_ = tags;
-  return raw_obj;
-}
-
-
 #define READ_VM_SINGLETON_OBJ(id, obj)                                         \
   if (object_id == id) {                                                       \
     return obj;                                                                \
@@ -1520,10 +1061,8 @@
   if (IsObjectStoreClassId(class_id)) {
     return isolate()->class_table()->At(class_id);  // get singleton class.
   }
-  if (!Snapshot::IsFull(kind_)) {
-    if (IsObjectStoreTypeId(object_id)) {
-      return GetType(object_store(), object_id);  // return type obj.
-    }
+  if (IsObjectStoreTypeId(object_id)) {
+    return GetType(object_store(), object_id);  // return type obj.
   }
   ASSERT(object_id >= kMaxPredefinedObjectIds);
   intptr_t index = (object_id - kMaxPredefinedObjectIds);
@@ -1538,7 +1077,7 @@
 void SnapshotReader::AddPatchRecord(intptr_t object_id,
                                     intptr_t patch_object_id,
                                     intptr_t patch_offset) {
-  if (patch_object_id != kInvalidPatchIndex && !Snapshot::IsFull(kind())) {
+  if (patch_object_id != kInvalidPatchIndex) {
     ASSERT(object_id >= kMaxPredefinedObjectIds);
     intptr_t index = (object_id - kMaxPredefinedObjectIds);
     ASSERT(index >= max_vm_isolate_object_id_);
@@ -1623,8 +1162,6 @@
                                            Thread* thread)
     : SnapshotReader(buffer,
                      size,
-                     NULL, /* instructions_buffer */
-                     NULL, /* data_buffer */
                      Snapshot::kScript,
                      new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
                      thread) {
@@ -1641,8 +1178,6 @@
                                              Thread* thread)
     : SnapshotReader(buffer,
                      size,
-                     NULL, /* instructions_buffer */
-                     NULL, /* data_buffer */
                      Snapshot::kMessage,
                      new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
                      thread) {
@@ -1660,21 +1195,16 @@
                                ReAlloc alloc,
                                intptr_t initial_size,
                                ForwardList* forward_list,
-                               InstructionsWriter* instructions_writer,
-                               bool can_send_any_object,
-                               bool writing_vm_isolate)
+                               bool can_send_any_object)
     : BaseWriter(buffer, alloc, initial_size),
       thread_(thread),
       kind_(kind),
       object_store_(isolate()->object_store()),
       class_table_(isolate()->class_table()),
       forward_list_(forward_list),
-      instructions_writer_(instructions_writer),
       exception_type_(Exceptions::kNone),
       exception_msg_(NULL),
-      unmarked_objects_(false),
-      can_send_any_object_(can_send_any_object),
-      writing_vm_isolate_(writing_vm_isolate) {
+      can_send_any_object_(can_send_any_object) {
   ASSERT(forward_list_ != NULL);
 }
 
@@ -1766,47 +1296,25 @@
     }
   }
 
-  if (writing_vm_isolate_) {
-    // When we are writing the VM isolate snapshot, write out the object
-    // itself instead of a VM object id.
-    return false;
-  }
-
-  if (Snapshot::IsFull(kind())) {
-    // Check it is a predefined symbol in the VM isolate.
-    id = Symbols::LookupPredefinedSymbol(rawobj);
-    if (id != kInvalidIndex) {
-      WriteVMIsolateObject(id);
-      return true;
-    }
-
-    // Check if it is an object from the vm isolate snapshot object table.
-    id = FindVmSnapshotObject(rawobj);
-    if (id != kInvalidIndex) {
-      WriteIndexedObject(id);
-      return true;
-    }
+  // In the case of script snapshots or for messages we do not use
+  // the index into the vm isolate snapshot object table, instead we
+  // explicitly write the object out.
+  intptr_t object_id = forward_list_->FindObject(rawobj);
+  if (object_id != -1) {
+    WriteIndexedObject(object_id);
+    return true;
   } else {
-    // In the case of script snapshots or for messages we do not use
-    // the index into the vm isolate snapshot object table, instead we
-    // explicitly write the object out.
-    intptr_t object_id = forward_list_->FindObject(rawobj);
-    if (object_id != -1) {
-      WriteIndexedObject(object_id);
-      return true;
-    } else {
-      switch (id) {
-        VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE)
-        case kTypedDataUint32ArrayCid: {
-          object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized);
-          RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj);
-          raw_obj->WriteTo(this, object_id, kind(), false);
-          return true;
-        }
-        default:
-          OS::Print("class id = %" Pd "\n", id);
-          break;
+    switch (id) {
+      VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE)
+      case kTypedDataUint32ArrayCid: {
+        object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized);
+        RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj);
+        raw_obj->WriteTo(this, object_id, kind(), false);
+        return true;
       }
+      default:
+        OS::Print("class id = %" Pd "\n", id);
+        break;
     }
   }
 
@@ -1930,34 +1438,32 @@
 
   // Check if it is a code object in that case just write a Null object
   // as we do not want code objects in the snapshot.
-  if (cid == kCodeCid && !Snapshot::IncludesCode(kind_)) {
+  if (cid == kCodeCid) {
     WriteVMIsolateObject(kNullObject);
     return true;
   }
 
   // Check if classes are not being serialized and it is preinitialized type
   // or a predefined internal VM class in the object store.
-  if (!Snapshot::IsFull(kind_)) {
-    // Check if it is an internal VM class which is in the object store.
-    if (cid == kClassCid) {
-      RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
-      intptr_t class_id = raw_class->ptr()->id_;
-      if (IsObjectStoreClassId(class_id)) {
-        intptr_t object_id = ObjectIdFromClassId(class_id);
-        WriteIndexedObject(object_id);
-        return true;
-      }
-    }
-
-    // Now check it is a preinitialized type object.
-    RawType* raw_type = reinterpret_cast<RawType*>(rawobj);
-    intptr_t index = GetTypeIndex(object_store(), raw_type);
-    if (index != kInvalidIndex) {
-      WriteIndexedObject(index);
+  // Check if it is an internal VM class which is in the object store.
+  if (cid == kClassCid) {
+    RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
+    intptr_t class_id = raw_class->ptr()->id_;
+    if (IsObjectStoreClassId(class_id)) {
+      intptr_t object_id = ObjectIdFromClassId(class_id);
+      WriteIndexedObject(object_id);
       return true;
     }
   }
 
+  // Now check it is a preinitialized type object.
+  RawType* raw_type = reinterpret_cast<RawType*>(rawobj);
+  intptr_t index = GetTypeIndex(object_store(), raw_type);
+  if (index != kInvalidIndex) {
+    WriteIndexedObject(index);
+    return true;
+  }
+
   return false;
 }
 
@@ -2358,9 +1864,7 @@
                      alloc,
                      kInitialSize,
                      &forward_list_,
-                     NULL, /* instructions_writer */
-                     true, /* can_send_any_object */
-                     false /* writing_vm_isolate */),
+                     true /* can_send_any_object */),
       forward_list_(thread(), kMaxPredefinedObjectIds) {
   ASSERT(buffer != NULL);
   ASSERT(alloc != NULL);
@@ -2414,9 +1918,7 @@
                      alloc,
                      kInitialSize,
                      &forward_list_,
-                     NULL, /* instructions_writer */
-                     can_send_any_object,
-                     false /* writing_vm_isolate */),
+                     can_send_any_object),
       forward_list_(thread(), kMaxPredefinedObjectIds) {
   ASSERT(buffer != NULL);
   ASSERT(alloc != NULL);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 1d8f585..a2f8197 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -412,9 +412,7 @@
   TokenStream* StreamHandle() { return &stream_; }
   ExternalTypedData* DataHandle() { return &data_; }
   TypedData* TypedDataHandle() { return &typed_data_; }
-  Code* CodeHandle() { return &code_; }
   Function* FunctionHandle() { return &function_; }
-  MegamorphicCache* MegamorphicCacheHandle() { return &megamorphic_cache_; }
   Snapshot::Kind kind() const { return kind_; }
 
   // Reads an object.
@@ -435,79 +433,11 @@
   // Read version number of snapshot and verify.
   RawApiError* VerifyVersionAndFeatures();
 
-  // Helper functions for creating uninitialized versions
-  // of various object types. These are used when reading a
-  // full snapshot.
-  RawArray* NewArray(intptr_t len);
-  RawImmutableArray* NewImmutableArray(intptr_t len);
-  RawOneByteString* NewOneByteString(intptr_t len);
-  RawTwoByteString* NewTwoByteString(intptr_t len);
-  RawTypeArguments* NewTypeArguments(intptr_t len);
-  RawTokenStream* NewTokenStream(intptr_t len);
-  RawContext* NewContext(intptr_t num_variables);
-  RawClass* NewClass(intptr_t class_id);
-  RawInstance* NewInstance();
-  RawMint* NewMint(int64_t value);
-  RawBigint* NewBigint();
-  RawTypedData* NewTypedData(intptr_t class_id, intptr_t len);
-  RawDouble* NewDouble(double value);
-  RawUnresolvedClass* NewUnresolvedClass();
-  RawType* NewType();
-  RawTypeRef* NewTypeRef();
-  RawTypeParameter* NewTypeParameter();
-  RawBoundedType* NewBoundedType();
-  RawMixinAppType* NewMixinAppType();
-  RawPatchClass* NewPatchClass();
-  RawClosure* NewClosure();
-  RawClosureData* NewClosureData();
-  RawRedirectionData* NewRedirectionData();
-  RawFunction* NewFunction();
-  RawCode* NewCode(intptr_t pointer_offsets_length);
-  RawObjectPool* NewObjectPool(intptr_t length);
-  RawPcDescriptors* NewPcDescriptors(intptr_t length);
-  RawCodeSourceMap* NewCodeSourceMap(intptr_t length);
-  RawLocalVarDescriptors* NewLocalVarDescriptors(intptr_t num_entries);
-  RawExceptionHandlers* NewExceptionHandlers(intptr_t num_entries);
-  RawStackmap* NewStackmap(intptr_t length);
-  RawContextScope* NewContextScope(intptr_t num_variables);
-  RawICData* NewICData();
-  RawMegamorphicCache* NewMegamorphicCache();
-  RawSubtypeTestCache* NewSubtypeTestCache();
-  RawLinkedHashMap* NewLinkedHashMap();
-  RawField* NewField();
-  RawLibrary* NewLibrary();
-  RawLibraryPrefix* NewLibraryPrefix();
-  RawNamespace* NewNamespace();
-  RawScript* NewScript();
-  RawLiteralToken* NewLiteralToken();
-  RawGrowableObjectArray* NewGrowableObjectArray();
-  RawFloat32x4* NewFloat32x4(float v0, float v1, float v2, float v3);
-  RawInt32x4* NewInt32x4(uint32_t v0, uint32_t v1, uint32_t v2, uint32_t v3);
-  RawFloat64x2* NewFloat64x2(double v0, double v1);
-  RawApiError* NewApiError();
-  RawLanguageError* NewLanguageError();
-  RawUnhandledException* NewUnhandledException();
   RawObject* NewInteger(int64_t value);
-  RawStacktrace* NewStacktrace();
-  RawWeakProperty* NewWeakProperty();
-  RawRegExp* NewRegExp();
-
-  uword GetInstructionsAt(int32_t offset) {
-    return instructions_reader_->GetInstructionsAt(offset);
-  }
-
-  RawObject* GetObjectAt(int32_t offset) {
-    return instructions_reader_->GetObjectAt(offset);
-  }
-
-  const uint8_t* instructions_buffer_;
-  const uint8_t* data_buffer_;
 
  protected:
   SnapshotReader(const uint8_t* buffer,
                  intptr_t size,
-                 const uint8_t* instructions_buffer,
-                 const uint8_t* data_buffer,
                  Snapshot::Kind kind,
                  ZoneGrowableArray<BackRefNode>* backward_references,
                  Thread* thread);
@@ -520,9 +450,6 @@
   PageSpace* old_space() const { return old_space_; }
 
  private:
-  // Allocate uninitialized objects, this is used when reading a full snapshot.
-  RawObject* AllocateUninitialized(intptr_t class_id, intptr_t size);
-
   RawClass* ReadClassId(intptr_t object_id);
   RawFunction* ReadFunctionId(intptr_t object_id);
   RawObject* ReadStaticImplicitClosure(intptr_t object_id, intptr_t cls_header);
@@ -593,13 +520,10 @@
   TokenStream& stream_;  // Temporary token stream handle.
   ExternalTypedData& data_;  // Temporary stream data handle.
   TypedData& typed_data_;  // Temporary typed data handle.
-  Code& code_;  // Temporary code handle.
   Function& function_;  // Temporary function handle.
-  MegamorphicCache& megamorphic_cache_;  // Temporary megamorphic cache handle.
   UnhandledException& error_;  // Error handle.
   intptr_t max_vm_isolate_object_id_;
   ZoneGrowableArray<BackRefNode>* backward_references_;
-  InstructionsReader* instructions_reader_;
 
   friend class ApiError;
   friend class Array;
@@ -608,7 +532,6 @@
   friend class Class;
   friend class Closure;
   friend class ClosureData;
-  friend class Code;
   friend class Context;
   friend class ContextScope;
   friend class ExceptionHandlers;
@@ -617,23 +540,18 @@
   friend class GrowableObjectArray;
   friend class ICData;
   friend class ImmutableArray;
-  friend class Instructions;
   friend class RegExp;
   friend class LanguageError;
   friend class Library;
   friend class LibraryPrefix;
   friend class LinkedHashMap;
   friend class LiteralToken;
-  friend class LocalVarDescriptors;
-  friend class MegamorphicCache;
   friend class MirrorReference;
   friend class MixinAppType;
   friend class Namespace;
-  friend class ObjectPool;
   friend class PatchClass;
   friend class RedirectionData;
   friend class Script;
-  friend class Stacktrace;
   friend class SubtypeTestCache;
   friend class TokenStream;
   friend class Type;
@@ -945,9 +863,7 @@
                  ReAlloc alloc,
                  intptr_t initial_size,
                  ForwardList* forward_list,
-                 InstructionsWriter* instructions_writer,
-                 bool can_send_any_object,
-                 bool writing_vm_isolate = false);
+                 bool can_send_any_object);
 
  public:
   // Snapshot kind.
@@ -973,20 +889,11 @@
     exception_msg_ = msg;
   }
   bool can_send_any_object() const { return can_send_any_object_; }
-  bool writing_vm_isolate() const { return writing_vm_isolate_; }
   void ThrowException(Exceptions::ExceptionType type, const char* msg);
 
   // Write a version string for the snapshot.
   void WriteVersionAndFeatures();
 
-  int32_t GetInstructionsId(RawInstructions* instructions, RawCode* code) {
-    return instructions_writer_->GetOffsetFor(instructions, code);
-  }
-
-  int32_t GetObjectId(RawObject* raw) {
-    return instructions_writer_->GetObjectOffsetFor(raw);
-  }
-
   void WriteFunctionId(RawFunction* func, bool owner_is_class);
 
   RawFunction* IsSerializableClosure(RawClosure* closure);
@@ -1032,12 +939,9 @@
   ObjectStore* object_store_;  // Object store for common classes.
   ClassTable* class_table_;  // Class table for the class index to class lookup.
   ForwardList* forward_list_;
-  InstructionsWriter* instructions_writer_;
   Exceptions::ExceptionType exception_type_;  // Exception type.
   const char* exception_msg_;  // Message associated with exception.
-  bool unmarked_objects_;  // True if marked objects have been unmarked.
   bool can_send_any_object_;  // True if any Dart instance can be sent.
-  bool writing_vm_isolate_;
 
   friend class RawArray;
   friend class RawClass;
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index c5862e4..915358a 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -833,7 +833,6 @@
                        alloc,
                        kInitialSize,
                        &forward_list_,
-                       NULL, /* test_writer */
                        true /* can_send_any_object */),
         forward_list_(thread(), kMaxPredefinedObjectIds) {
     ASSERT(buffer != NULL);
@@ -1374,6 +1373,7 @@
 
     // Load the library.
     Dart_Handle import_lib = Dart_LoadLibrary(NewString("dart_import_lib"),
+                                              Dart_Null(),
                                               NewString(kLibScriptChars),
                                               0, 0);
     EXPECT_VALID(import_lib);
@@ -1436,6 +1436,7 @@
 
     // Load the library.
     Dart_Handle lib = Dart_LoadLibrary(NewString("dart_lib"),
+                                       Dart_Null(),
                                        NewString(kScriptChars),
                                        0, 0);
     EXPECT_VALID(lib);
@@ -1611,6 +1612,7 @@
 
     // Load the library.
     Dart_Handle import_lib = Dart_LoadLibrary(NewString("dart_import_lib"),
+                                              Dart_Null(),
                                               NewString(kLibScriptChars),
                                               0, 0);
     EXPECT_VALID(import_lib);
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 827407d..f93111e 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -108,9 +108,8 @@
     Array maps;
     maps = Array::null();
     Stackmap map;
-    const uword entry = reinterpret_cast<uword>(code.instructions()->ptr()) +
-                        Instructions::HeaderSize();
-    map = code.GetStackmap(pc() - entry, &maps, &map);
+    const uword start = Instructions::PayloadStart(code.instructions());
+    map = code.GetStackmap(pc() - start, &maps, &map);
     if (!map.IsNull()) {
 #if !defined(TARGET_ARCH_DBC)
       RawObject** first = reinterpret_cast<RawObject**>(sp());
@@ -260,7 +259,7 @@
   if (code.IsNull()) {
     return false;  // Stub frames do not have exception handlers.
   }
-  uword pc_offset = pc() - code.EntryPoint();
+  uword pc_offset = pc() - code.PayloadStart();
 
   REUSABLE_EXCEPTION_HANDLERS_HANDLESCOPE(thread);
   ExceptionHandlers& handlers = reused_exception_handlers_handle.Handle();
@@ -279,7 +278,7 @@
     if ((iter.PcOffset() == pc_offset) && (current_try_index != -1)) {
       RawExceptionHandlers::HandlerInfo handler_info;
       handlers.GetHandlerInfo(current_try_index, &handler_info);
-      *handler_pc = code.EntryPoint() + handler_info.handler_pc_offset;
+      *handler_pc = code.PayloadStart() + handler_info.handler_pc_offset;
       *needs_stacktrace = handler_info.needs_stacktrace;
       *has_catch_all = handler_info.has_catch_all;
       return true;
@@ -294,7 +293,7 @@
   if (code.IsNull()) {
     return TokenPosition::kNoSource;  // Stub frames do not have token_pos.
   }
-  uword pc_offset = pc() - code.EntryPoint();
+  uword pc_offset = pc() - code.PayloadStart();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   ASSERT(!descriptors.IsNull());
@@ -489,6 +488,7 @@
 InlinedFunctionsIterator::InlinedFunctionsIterator(const Code& code, uword pc)
   : index_(0),
     num_materializations_(0),
+    dest_frame_size_(0),
     code_(Code::Handle(code.raw())),
     deopt_info_(TypedData::Handle()),
     function_(Function::Handle()),
@@ -512,6 +512,7 @@
     ASSERT(!deopt_table.IsNull());
     DeoptInfo::Unpack(deopt_table, deopt_info_, &deopt_instructions_);
     num_materializations_ = DeoptInfo::NumMaterializations(deopt_instructions_);
+    dest_frame_size_ = DeoptInfo::FrameSize(deopt_info_);
     object_table_ = code_.GetObjectPool();
     Advance();
   }
@@ -550,7 +551,14 @@
        index++) {
     DeoptInstr* deopt_instr = deopt_instructions_[index];
     if (deopt_instr->kind() == DeoptInstr::kCallerFp) {
+#if defined(TARGET_ARCH_DBC)
+      // Stack on DBC is growing upwards but we record deopt commands
+      // in the same order we record them on other architectures as if
+      // the stack was growing downwards.
+      return dest_frame_size_ - index;
+#else
       return (index - num_materializations_);
+#endif
     }
   }
   UNREACHABLE();
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index dac3e5f..268ca4a 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -336,6 +336,7 @@
 
   intptr_t index_;
   intptr_t num_materializations_;
+  intptr_t dest_frame_size_;
   Code& code_;
   TypedData& deopt_info_;
   Function& function_;
@@ -346,9 +347,11 @@
   DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsIterator);
 };
 
+
 #if !defined(TARGET_ARCH_DBC)
-DART_FORCE_INLINE static uword LocalVarAddress(uword fp, intptr_t index) {
-  return fp + (index * kWordSize);
+DART_FORCE_INLINE static intptr_t LocalVarIndex(intptr_t fp_offset,
+                                                intptr_t var_index) {
+  return fp_offset + var_index;
 }
 
 
@@ -367,6 +370,12 @@
 static const uword kInterruptStackLimit = ~static_cast<uword>(0);
 #endif
 
+
+DART_FORCE_INLINE static uword LocalVarAddress(uword fp, intptr_t index) {
+  return fp + LocalVarIndex(0, index) * kWordSize;
+}
+
+
 }  // namespace dart
 
 #endif  // VM_STACK_FRAME_H_
diff --git a/runtime/vm/stack_frame_dbc.h b/runtime/vm/stack_frame_dbc.h
index a59a417..5d5ee78 100644
--- a/runtime/vm/stack_frame_dbc.h
+++ b/runtime/vm/stack_frame_dbc.h
@@ -10,7 +10,7 @@
 /* DBC Frame Layout
 
 IMPORTANT: On DBC stack is growing upwards which is different from all other
-architectures. This enables effecient addressing for locals via unsigned index.
+architectures. This enables efficient addressing for locals via unsigned index.
 
                |                    | <- TOS
 Callee frame   | ...                |
@@ -56,15 +56,17 @@
 static const int kFirstLocalSlotFromFp = -1;
 
 
-DART_FORCE_INLINE static uword LocalVarAddress(uword fp, intptr_t index) {
-  ASSERT(index != 0);
-  if (index > 0) {
-     return fp - index * kWordSize;
+DART_FORCE_INLINE static intptr_t LocalVarIndex(intptr_t fp_offset,
+                                                intptr_t var_index) {
+  ASSERT(var_index != 0);
+  if (var_index > 0) {
+    return fp_offset - var_index;
   } else {
-     return fp - (index + 1) * kWordSize;
+    return fp_offset - (var_index + 1);
   }
 }
 
+
 DART_FORCE_INLINE static uword ParamAddress(uword fp, intptr_t reverse_index) {
   return fp - (kDartFrameFixedSize + reverse_index) * kWordSize;
 }
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index a6992bf..f0eaf6d 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -28,9 +28,10 @@
 
 StubEntry::StubEntry(const Code& code)
     : code_(code.raw()),
-      entry_point_(code.EntryPoint()),
+      entry_point_(code.UncheckedEntryPoint()),
+      checked_entry_point_(code.CheckedEntryPoint()),
       size_(code.Size()),
-      label_(code.EntryPoint()) {
+      label_(code.UncheckedEntryPoint()) {
 }
 
 
@@ -183,20 +184,20 @@
         isolate->heap()->CollectAllGarbage();
       }
     }
+#ifndef PRODUCT
     if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
       LogBlock lb;
       THR_Print("Code for allocation stub '%s': {\n", name);
-#ifndef PRODUCT
       DisassembleToStdout formatter;
       stub.Disassemble(&formatter);
-#endif
       THR_Print("}\n");
       const ObjectPool& object_pool = ObjectPool::Handle(stub.object_pool());
       object_pool.DebugPrint();
     }
+#endif  // !PRODUCT
   }
   return stub.raw();
-#endif
+#endif  // !DBC
   UNIMPLEMENTED();
   return Code::null();
 }
@@ -229,6 +230,7 @@
   GenerateStub(&assembler);
   const Code& code = Code::Handle(
       Code::FinalizeCode(name, &assembler, false /* optimized */));
+#ifndef PRODUCT
   if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
     LogBlock lb;
     THR_Print("Code for stub '%s': {\n", name);
@@ -238,6 +240,7 @@
     const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool());
     object_pool.DebugPrint();
   }
+#endif  // !PRODUCT
   return code.raw();
 }
 
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index cecec5d..bb971e2 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -40,6 +40,7 @@
   V(ICLookupThroughFunction)                                                   \
   V(ICLookupThroughCode)                                                       \
   V(MegamorphicLookup)                                                         \
+  V(MonomorphicMiss)                                                           \
   V(FixAllocationStubTarget)                                                   \
   V(Deoptimize)                                                                \
   V(DeoptimizeLazy)                                                            \
@@ -54,8 +55,6 @@
   V(SmiAddInlineCache)                                                         \
   V(SmiSubInlineCache)                                                         \
   V(SmiEqualInlineCache)                                                       \
-  V(UnaryRangeCollectingInlineCache)                                           \
-  V(BinaryRangeCollectingInlineCache)                                          \
   V(OneArgOptimizedCheckInlineCache)                                           \
   V(TwoArgsOptimizedCheckInlineCache)                                          \
   V(ZeroArgsUnoptimizedStaticCall)                                             \
@@ -92,6 +91,7 @@
 
   const ExternalLabel& label() const { return label_; }
   uword EntryPoint() const { return entry_point_; }
+  uword CheckedEntryPoint() const { return checked_entry_point_; }
   RawCode* code() const { return code_; }
   intptr_t Size() const { return size_; }
 
@@ -101,6 +101,7 @@
  private:
   RawCode* code_;
   uword entry_point_;
+  uword checked_entry_point_;
   intptr_t size_;
   ExternalLabel label_;
 
@@ -155,8 +156,6 @@
 
   static const intptr_t kNoInstantiator = 0;
 
-  static void EmitMegamorphicLookup(Assembler* assembler);
-
  private:
   friend class MegamorphicCacheTable;
 
@@ -172,11 +171,6 @@
   VM_STUB_CODE_LIST(STUB_CODE_ENTRY);
 #undef STUB_CODE_ENTRY
 
-  enum RangeCollectionMode {
-    kCollectRanges,
-    kIgnoreRanges
-  };
-
   // Generate the stub and finalize the generated code into the stub
   // code executable area.
   static RawCode* Generate(const char* name,
@@ -190,7 +184,6 @@
       intptr_t num_args,
       const RuntimeEntry& handle_ic_miss,
       Token::Kind kind,
-      RangeCollectionMode range_collection_mode,
       bool optimized = false);
   static void GenerateUsageCounterIncrement(Assembler* assembler,
                                             Register temp_reg);
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 9a7429b..59bd06f 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1324,7 +1324,6 @@
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
     Token::Kind kind,
-    RangeCollectionMode range_collection_mode,
     bool optimized) {
   __ CheckCodePointer();
   ASSERT(num_args > 0);
@@ -1352,18 +1351,7 @@
     __ Bind(&done_stepping);
   }
 
-  __ Comment("Range feedback collection");
   Label not_smi_or_overflow;
-  if (range_collection_mode == kCollectRanges) {
-    ASSERT((num_args == 1) || (num_args == 2));
-    if (num_args == 2) {
-      __ ldr(R0, Address(SP, 1 * kWordSize));
-      __ UpdateRangeFeedback(R0, 0, R9, R1, R4, &not_smi_or_overflow);
-    }
-
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ 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);
   }
@@ -1478,31 +1466,8 @@
   __ Bind(&call_target_function);
   // R0: target function.
   __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
-  if (range_collection_mode == kCollectRanges) {
-    __ ldr(R1, Address(SP, 0 * kWordSize));
-    if (num_args == 2) {
-      __ ldr(R3, Address(SP, 1 * kWordSize));
-    }
-    __ EnterStubFrame();
-    if (num_args == 2) {
-      __ PushList((1 << R1) | (1 << R3) | (1 << R9));
-    } else {
-      __ PushList((1 << R1) | (1 << R9));
-    }
-    __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-    __ blx(R2);
-
-    Label done;
-    __ ldr(R9, Address(FP, kFirstLocalSlotFromFp * kWordSize));
-    __ UpdateRangeFeedback(R0, 2, R9, R1, R4, &done);
-    __ Bind(&done);
-    __ RestoreCodePointer();
-    __ LeaveStubFrame();
-    __ Ret();
-  } else {
-    __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-    __ bx(R2);
-  }
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+  __ bx(R2);
 
   if (FLAG_support_debugger && !optimized) {
     __ Bind(&stepping);
@@ -1532,8 +1497,7 @@
   GenerateNArgsCheckInlineCacheStub(assembler,
       1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1542,8 +1506,7 @@
   GenerateNArgsCheckInlineCacheStub(assembler,
       2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1552,44 +1515,21 @@
   GenerateNArgsCheckInlineCacheStub(assembler,
       2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kADD,
-      kCollectRanges);
+      Token::kADD);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
-      kIgnoreRanges);
-}
-
-
-void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
-}
-
-
-void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
 }
 
 
@@ -1598,7 +1538,7 @@
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1607,7 +1547,7 @@
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1681,16 +1621,14 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R8);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
 }
 
 
@@ -2048,58 +1986,60 @@
 }
 
 
-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.
-  __ LoadImmediate(IP, MegamorphicCache::kSpreadFactor);
-  __ mul(R3, R0, IP);
-  // R3: probe.
-
-  Label loop, update, load_target_function;
-  __ b(&loop);
-
-  __ Bind(&update);
-  __ add(R3, R3, Operand(Smi::RawValue(1)));
-  __ Bind(&loop);
-  __ and_(R3, R3, Operand(R1));
-  const intptr_t base = Array::data_offset();
-  // R3 is smi tagged, but table entries are two words, so LSL 2.
-  __ add(IP, R2, Operand(R3, LSL, 2));
-  __ ldr(R6, FieldAddress(IP, base));
-
-  ASSERT(kIllegalCid == 0);
-  __ tst(R6, Operand(R6));
-  __ b(&load_target_function, EQ);
-  __ cmp(R6, Operand(R0));
-  __ b(&update, NE);
-
-  __ 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()));
-}
-
-
 // Called from megamorphic calls.
 //  R0: receiver
 //  R9: MegamorphicCache (preserved)
 // Result:
-//  R1: target entry point
 //  CODE_REG: target Code
 //  R4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler);
-  __ Ret();
+  __ NoMonomorphicCheckedEntry();
+
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
+  // R0: receiver cid as Smi.
+  __ ldr(R2, FieldAddress(R9, MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R9, MegamorphicCache::mask_offset()));
+  // R2: cache buckets array.
+  // R1: mask.
+
+  // Compute the table index.
+  ASSERT(MegamorphicCache::kSpreadFactor == 7);
+  // Use reverse substract to multiply with 7 == 8 - 1.
+  __ rsb(R3, R0, Operand(R0, LSL, 3));
+  // R3: probe.
+  Label loop;
+  __ Bind(&loop);
+  __ and_(R3, R3, Operand(R1));
+
+  const intptr_t base = Array::data_offset();
+  // R3 is smi tagged, but table entries are two words, so LSL 2.
+  Label probe_failed;
+  __ add(IP, R2, Operand(R3, LSL, 2));
+  __ ldr(R6, FieldAddress(IP, base));
+  __ cmp(R6, Operand(R0));
+  __ b(&probe_failed, NE);
+
+  Label load_target;
+  __ Bind(&load_target);
+  // Call the target found in the cache.  For a class id match, this is a
+  // proper target for the given name and arguments descriptor.  If the
+  // illegal class id was found, the target is a cache miss handler that can
+  // be invoked as a normal Dart function.
+  __ ldr(R0, FieldAddress(IP, base + kWordSize));
+  __ ldr(R4, FieldAddress(R9, MegamorphicCache::arguments_descriptor_offset()));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+  __ bx(R1);
+
+  // Probe failed, check if it is a miss.
+  __ Bind(&probe_failed);
+  ASSERT(kIllegalCid == 0);
+  __ tst(R6, Operand(R6));
+  __ b(&load_target, EQ);  // branch if miss.
+
+  // Try next extry in the table.
+  __ AddImmediate(R3, Smi::RawValue(1));
+  __ b(&loop);
 }
 
 
@@ -2107,10 +2047,11 @@
 //  R0: receiver
 //  R9: ICData (preserved)
 // Result:
-//  R1: target entry point
 //  CODE_REG: target Code object
 //  R4: arguments descriptor
 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
   __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
   __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
@@ -2135,17 +2076,19 @@
   __ LoadFromOffset(kWord, R0, R8, target_offset);
   __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ Ret();
+  __ bx(R1);
 
   __ Bind(&miss);
   __ LoadIsolate(R2);
   __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
   __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ Ret();
+  __ bx(R1);
 }
 
 
 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
   __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
   __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
@@ -2170,13 +2113,34 @@
   const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
   __ ldr(R1, Address(R8, entry_offset));
   __ ldr(CODE_REG, Address(R8, code_offset));
-  __ Ret();
+  __ bx(R1);
 
   __ Bind(&miss);
   __ LoadIsolate(R2);
   __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
   __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ Ret();
+  __ bx(R1);
+}
+
+
+// Called from the monomorphic checked entry.
+//  R0: receiver
+void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(R0);  // Preserve receiver.
+
+  __ PushObject(Object::null_object());  // Result.
+  __ Push(R0);                           // Arg0: Receiver
+  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
+  __ Drop(1);
+  __ Pop(R9);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+  __ bx(R1);
 }
 
 
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 04dd0f4..fc092bd 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -1293,8 +1293,7 @@
 static void EmitFastSmiOp(Assembler* assembler,
                           Token::Kind kind,
                           intptr_t num_args,
-                          Label* not_smi_or_overflow,
-                          bool should_update_result_range) {
+                          Label* not_smi_or_overflow) {
   __ Comment("Fast Smi op");
   __ ldr(R0, Address(SP, + 0 * kWordSize));  // Right.
   __ ldr(R1, Address(SP, + 1 * kWordSize));  // Left.
@@ -1322,12 +1321,6 @@
     default: UNIMPLEMENTED();
   }
 
-  if (should_update_result_range) {
-    Label done;
-    __ UpdateRangeFeedback(R0, 2, R5, R1, R6, &done);
-    __ Bind(&done);
-  }
-
   // R5: IC data object (preserved).
   __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset());
   // R6: ic_data_array with check entries: classes and target functions.
@@ -1376,7 +1369,6 @@
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
     Token::Kind kind,
-    RangeCollectionMode range_collection_mode,
     bool optimized) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
@@ -1405,24 +1397,12 @@
     __ Bind(&done_stepping);
   }
 
-  __ Comment("Range feedback collection");
   Label not_smi_or_overflow;
-  if (range_collection_mode == kCollectRanges) {
-    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);
-    }
-
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow);
-  }
   if (kind != Token::kILLEGAL) {
     EmitFastSmiOp(assembler,
                   kind,
                   num_args,
-                  &not_smi_or_overflow,
-                  (range_collection_mode == kCollectRanges));
+                  &not_smi_or_overflow);
   }
   __ Bind(&not_smi_or_overflow);
 
@@ -1546,32 +1526,9 @@
   __ Comment("Call target");
   __ Bind(&call_target_function);
   // R0: target function.
-  if (range_collection_mode == kCollectRanges) {
-    __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset());
-    __ ldr(R1, Address(SP, 0 * kWordSize));
-    if (num_args == 2) {
-      __ ldr(R3, Address(SP, 1 * kWordSize));
-    }
-    __ EnterStubFrame();
-    __ Push(R5);
-    if (num_args == 2) {
-      __ Push(R3);
-    }
-    __ Push(R1);
-    __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-    __ blr(R2);
-
-    Label done;
-    __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize));
-    __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done);
-    __ Bind(&done);
-    __ LeaveStubFrame();
-    __ ret();
-  } else {
-    __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-    __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset());
-    __ br(R2);
-  }
+  __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
+  __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset());
+  __ br(R2);
 
   if (FLAG_support_debugger && !optimized) {
     __ Bind(&stepping);
@@ -1599,60 +1556,35 @@
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
 }
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
-      kIgnoreRanges);
-}
-
-
-void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
-}
-
-
-void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
 }
 
 
@@ -1661,7 +1593,7 @@
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1670,7 +1602,7 @@
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1744,16 +1676,14 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
 }
 
 
@@ -2098,58 +2028,78 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
-  __ LoadTaggedClassIdMayBeSmi(R0, R0);
-  // R0: class ID of the receiver (smi).
-  __ 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.
-  __ LoadImmediate(TMP, MegamorphicCache::kSpreadFactor);
-  __ mul(R3, R0, TMP);
-  // R3: probe.
-
-  Label loop, update, load_target_function;
-  __ b(&loop);
-
-  __ Bind(&update);
-  __ add(R3, R3, Operand(Smi::RawValue(1)));
-  __ Bind(&loop);
-  __ and_(R3, R3, Operand(R1));
-  const intptr_t base = Array::data_offset();
-  // R3 is smi tagged, but table entries are 16 bytes, so LSL 3.
-  __ add(TMP, R2, Operand(R3, LSL, 3));
-  __ ldr(R6, FieldAddress(TMP, base));
-
-  ASSERT(kIllegalCid == 0);
-  __ tst(R6, Operand(R6));
-  __ b(&load_target_function, EQ);
-  __ CompareRegisters(R6, R0);
-  __ b(&update, NE);
-
-  __ 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));
-  __ 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
 //  R5: MegamorphicCache (preserved)
 // Result:
-//  R1: target entry point
 //  CODE_REG: target Code
 //  R4: arguments descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler);
-  __ ret();
+  __ NoMonomorphicCheckedEntry();
+
+  // Jump if receiver is a smi.
+  Label smi_case;
+  __ TestImmediate(R0, kSmiTagMask);
+  __ b(&smi_case, EQ);
+
+  // Loads the cid of the object.
+  __ LoadClassId(R0, R0);
+
+  Label cid_loaded;
+  __ Bind(&cid_loaded);
+  __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset()));
+  // R2: cache buckets array.
+  // R1: mask.
+
+  // Make the cid into a smi.
+  __ SmiTag(R0);
+  // R0: class ID of the receiver (smi).
+
+  // Compute the table index.
+  ASSERT(MegamorphicCache::kSpreadFactor == 7);
+  // Use lsl and sub to multiply with 7 == 8 - 1.
+  __ LslImmediate(R3, R0, 3);
+  __ sub(R3, R3, Operand(R0));
+  // R3: probe.
+  Label loop;
+  __ Bind(&loop);
+  __ and_(R3, R3, Operand(R1));
+
+  const intptr_t base = Array::data_offset();
+  // R3 is smi tagged, but table entries are 16 bytes, so LSL 3.
+  __ add(TMP, R2, Operand(R3, LSL, 3));
+  __ ldr(R6, FieldAddress(TMP, base));
+  Label probe_failed;
+  __ CompareRegisters(R6, R0);
+  __ b(&probe_failed, NE);
+
+  Label load_target;
+  __ Bind(&load_target);
+  // Call the target found in the cache.  For a class id match, this is a
+  // proper target for the given name and arguments descriptor.  If the
+  // illegal class id was found, the target is a cache miss handler that can
+  // be invoked as a normal Dart function.
+  __ ldr(R0, FieldAddress(TMP, base + kWordSize));
+  __ ldr(R4, FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset()));
+  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+  __ br(R1);
+
+  // Probe failed, check if it is a miss.
+  __ Bind(&probe_failed);
+  ASSERT(kIllegalCid == 0);
+  __ tst(R6, Operand(R6));
+  __ b(&load_target, EQ);  // branch if miss.
+
+  // Try next extry in the table.
+  __ AddImmediate(R3, R3, Smi::RawValue(1));
+  __ b(&loop);
+
+  // Load cid for the Smi case.
+  __ Bind(&smi_case);
+  __ LoadImmediate(R0, kSmiCid);
+  __ b(&cid_loaded);
 }
 
 
@@ -2157,10 +2107,11 @@
 //  R0: receiver
 //  R5: ICData (preserved)
 // Result:
-//  R1: target entry point
 //  CODE_REG: target Code object
 //  R4: arguments descriptor
 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
   __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
   __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
@@ -2185,17 +2136,19 @@
   __ ldr(R0, Address(R8, target_offset));
   __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ret();
+  __ br(R1);
 
   __ Bind(&miss);
   __ LoadIsolate(R2);
   __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
   __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ ret();
+  __ br(R1);
 }
 
 
 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
   __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
   __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
@@ -2220,13 +2173,34 @@
   const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
   __ ldr(R1, Address(R8, entry_offset));
   __ ldr(CODE_REG, Address(R8, code_offset));
-  __ ret();
+  __ br(R1);
 
   __ Bind(&miss);
   __ LoadIsolate(R2);
   __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
   __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ ret();
+  __ br(R1);
+}
+
+
+// Called from the monomorphic checked entry.
+//  R0: receiver
+void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(R0);  // Preserve receiver.
+
+  __ PushObject(Object::null_object());  // Result.
+  __ Push(R0);                           // Arg0: Receiver
+  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
+  __ Drop(1);
+  __ Pop(R5);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+  __ br(R1);
 }
 
 
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 139a4a2..15b8aa9 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1278,7 +1278,6 @@
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
     Token::Kind kind,
-    RangeCollectionMode range_collection_mode,
     bool optimized) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
@@ -1303,19 +1302,7 @@
     __ j(NOT_EQUAL, &stepping);
     __ Bind(&done_stepping);
   }
-  __ Comment("Range feedback collection");
   Label not_smi_or_overflow;
-  if (range_collection_mode == kCollectRanges) {
-    ASSERT((num_args == 1) || (num_args == 2));
-    if (num_args == 2) {
-      __ movl(EAX, Address(ESP, + 2 * kWordSize));
-      __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, EDX, &not_smi_or_overflow);
-    }
-
-    __ movl(EAX, Address(ESP, + 1 * kWordSize));
-    __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, EDX,
-                           &not_smi_or_overflow);
-  }
   if (kind != Token::kILLEGAL) {
     EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
   }
@@ -1434,27 +1421,7 @@
   __ Comment("Call target");
   // EAX: Target function.
   __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
-  if (range_collection_mode == kCollectRanges) {
-    __ EnterStubFrame();
-    __ pushl(ECX);
-    const intptr_t arg_offset_words = num_args +
-                                      Assembler::kEnterStubFramePushedWords +
-                                      1;  // ECX
-    for (intptr_t i = 0; i < num_args; i++) {
-      __ movl(EDI, Address(ESP, arg_offset_words * kWordSize));
-      __ pushl(EDI);
-    }
-    __ call(EBX);
-
-    __ movl(ECX, Address(EBP, kFirstLocalSlotFromFp * kWordSize));
-    Label done;
-    __ UpdateRangeFeedback(EAX, 2, ECX, EBX, EDI, EDX, &done);
-    __ Bind(&done);
-    __ LeaveFrame();
-    __ ret();
-  } else {
-    __ jmp(EBX);
-  }
+  __ jmp(EBX);
 
   if (FLAG_support_debugger && !optimized) {
     __ Bind(&stepping);
@@ -1482,8 +1449,7 @@
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1491,8 +1457,7 @@
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1500,8 +1465,7 @@
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kADD,
-      kCollectRanges);
+      Token::kADD);
 }
 
 
@@ -1509,8 +1473,7 @@
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kSUB,
-      kCollectRanges);
+      Token::kSUB);
 }
 
 
@@ -1518,28 +1481,7 @@
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kEQ,
-      kIgnoreRanges);
-}
-
-
-void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
-}
-
-
-void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
+      Token::kEQ);
 }
 
 
@@ -1560,7 +1502,6 @@
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
       Token::kILLEGAL,
-      kIgnoreRanges,
       true /* optimized */);
 }
 
@@ -1571,7 +1512,6 @@
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
      Token::kILLEGAL,
-     kIgnoreRanges,
      true /* optimized */);
 }
 
@@ -1645,8 +1585,7 @@
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(
       assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1654,8 +1593,7 @@
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kStaticCallMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -2021,48 +1959,6 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
-  __ LoadTaggedClassIdMayBeSmi(EAX, EBX);
-  // EAX: class ID of the receiver (smi).
-  __ 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);
-  __ imull(ECX, Immediate(MegamorphicCache::kSpreadFactor));
-  // ECX: probe.
-
-  Label loop, update, load_target_function;
-  __ jmp(&loop);
-
-  __ Bind(&update);
-  __ addl(ECX, Immediate(Smi::RawValue(1)));
-  __ Bind(&loop);
-  __ andl(ECX, EBX);
-  const intptr_t base = Array::data_offset();
-  // ECX is smi tagged, but table entries are two words, so TIMES_4.
-  __ movl(EDX, FieldAddress(EDI, ECX, TIMES_4, base));
-
-  ASSERT(kIllegalCid == 0);
-  __ testl(EDX, EDX);
-  __ j(ZERO, &load_target_function, Assembler::kNearJump);
-  __ cmpl(EDX, EAX);
-  __ j(NOT_EQUAL, &update, Assembler::kNearJump);
-
-  __ 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));
-  __ popl(ECX);  // Restore MegamorphicCache.
-  __ movl(EDX,
-          FieldAddress(ECX, MegamorphicCache::arguments_descriptor_offset()));
-  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
-}
-
-
 // Called from megamorphic calls.
 //  EBX: receiver
 //  ECX: MegamorphicCache (preserved)
@@ -2070,16 +1966,73 @@
 //  EBX: target entry point
 //  EDX: argument descriptor
 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler);
-  __ ret();
-}
+  // Jump if receiver is a smi.
+  Label smi_case;
+  // Check if object (in tmp) is a Smi.
+  __ testl(EBX, Immediate(kSmiTagMask));
+  // Jump out of line for smi case.
+  __ j(ZERO, &smi_case, Assembler::kNearJump);
 
+  // Loads the cid of the instance.
+  __ LoadClassId(EAX, EBX);
+
+  Label cid_loaded;
+  __ Bind(&cid_loaded);
+  __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset()));
+  __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset()));
+  // EDI: cache buckets array.
+  // EBX: mask.
+
+  // Tag cid as a smi.
+  __ addl(EAX, EAX);
+
+  // Compute the table index.
+  ASSERT(MegamorphicCache::kSpreadFactor == 7);
+  // Use leal and subl multiply with 7 == 8 - 1.
+  __ leal(EDX, Address(EAX, TIMES_8, 0));
+  __ subl(EDX, EAX);
+
+  Label loop;
+  __ Bind(&loop);
+  __ andl(EDX, EBX);
+
+  const intptr_t base = Array::data_offset();
+  Label probe_failed;
+  // EDX is smi tagged, but table entries are two words, so TIMES_4.
+  __ cmpl(EAX, FieldAddress(EDI, EDX, TIMES_4, base));
+  __ j(NOT_EQUAL, &probe_failed, Assembler::kNearJump);
+
+  Label load_target;
+  __ Bind(&load_target);
+  // Call the target found in the cache.  For a class id match, this is a
+  // proper target for the given name and arguments descriptor.  If the
+  // illegal class id was found, the target is a cache miss handler that can
+  // be invoked as a normal Dart function.
+  __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, base + kWordSize));
+  __ movl(EDX,
+          FieldAddress(ECX, MegamorphicCache::arguments_descriptor_offset()));
+  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
+  __ ret();
+
+  __ Bind(&probe_failed);
+  // Probe failed, check if it is a miss.
+  __ cmpl(FieldAddress(EDI, EDX, TIMES_4, base), Immediate(kIllegalCid));
+  __ j(ZERO, &load_target, Assembler::kNearJump);
+
+  // Try next extry in the table.
+  __ AddImmediate(EDX, Immediate(Smi::RawValue(1)));
+  __ jmp(&loop);
+
+  // Load cid for the Smi case.
+  __ Bind(&smi_case);
+  __ movl(EAX, Immediate(kSmiCid));
+  __ jmp(&cid_loaded);
+}
 
 // Called from switchable IC calls.
 //  EBX: receiver
 //  ECX: ICData (preserved)
 // Result:
-//  EBX: target entry point
 //  EDX: arguments descriptor
 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) {
   __ int3();
@@ -2091,6 +2044,10 @@
 }
 
 
+void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+  __ int3();
+}
+
 
 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
   __ int3();
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index ef36894..dc5788b 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1403,7 +1403,6 @@
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
     Token::Kind kind,
-    RangeCollectionMode range_collection_mode,
     bool optimized) {
   __ Comment("NArgsCheckInlineCacheStub");
   ASSERT(num_args > 0);
@@ -1430,18 +1429,7 @@
     __ Bind(&done_stepping);
   }
 
-  __ Comment("Range feedback collection");
   Label not_smi_or_overflow;
-  if (range_collection_mode == kCollectRanges) {
-    ASSERT((num_args == 1) || (num_args == 2));
-    if (num_args == 2) {
-      __ lw(T0, Address(SP, 1 * kWordSize));
-      __ UpdateRangeFeedback(T0, 0, S5, T1, &not_smi_or_overflow);
-    }
-
-    __ lw(T0, Address(SP, 0 * kWordSize));
-    __ UpdateRangeFeedback(T0, num_args - 1, S5, T1, &not_smi_or_overflow);
-  }
   if (kind != Token::kILLEGAL) {
     EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
   }
@@ -1589,35 +1577,8 @@
   __ mov(T0, T3);
   Label is_compiled;
   __ lw(T4, FieldAddress(T0, Function::entry_point_offset()));
-  if (range_collection_mode == kCollectRanges) {
-    const intptr_t frame_size = num_args + 2;
-    __ lw(T3, Address(SP, 0 * kWordSize));
-    if (num_args == 2) {
-      __ lw(T1, Address(SP, 1 * kWordSize));
-    }
-    __ EnterStubFrame();
-    __ addiu(SP, SP, Immediate(- frame_size * kWordSize));
-    __ sw(RA, Address(SP, (frame_size - 1) * kWordSize));  // Return address.
-    __ sw(S5, Address(SP, (frame_size - 2) * kWordSize));  // Preserve IC data.
-    __ sw(T3, Address(SP, 0 * kWordSize));
-    if (num_args == 2) {
-      __ sw(T1, Address(SP, 1 * kWordSize));
-    }
-    __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
-    __ jalr(T4);
-    __ lw(S5, Address(SP, (frame_size - 2) * kWordSize));
-    __ lw(RA, Address(SP, (frame_size - 1) * kWordSize));
-    Label done;
-    __ UpdateRangeFeedback(V0, 2, S5, T1, &done);
-    __ Bind(&done);
-    __ addiu(SP, SP, Immediate(frame_size * kWordSize));
-    __ RestoreCodePointer();
-    __ LeaveStubFrame();
-    __ Ret();
-  } else {
-    __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
-    __ jr(T4);
-  }
+  __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
+  __ jr(T4);
 
   // Call single step callback in debugger.
   if (FLAG_support_debugger && !optimized) {
@@ -1650,60 +1611,35 @@
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
 }
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
-      kIgnoreRanges);
-}
-
-
-void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, T0);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
-}
-
-
-void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, T0);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
 }
 
 
@@ -1712,7 +1648,7 @@
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1721,7 +1657,7 @@
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1801,16 +1737,14 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
-      kIgnoreRanges);
+      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
 }
 
 
@@ -2212,7 +2146,14 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
+// Called from megamorphic calls.
+//  T0: receiver
+//  S5: MegamorphicCache (preserved)
+// Result:
+//  S4: arguments descriptor
+void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   __ LoadTaggedClassIdMayBeSmi(T0, T0);
   // T0: class ID of the receiver (smi).
   __ lw(S4, FieldAddress(S5, MegamorphicCache::arguments_descriptor_offset()));
@@ -2253,19 +2194,7 @@
 
   __ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
   __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
-}
-
-
-// Called from megamorphic calls.
-//  T0: receiver
-//  S5: MegamorphicCache (preserved)
-// Result:
-//  T1: target entry point
-//  CODE_REG: target Code
-//  S4: arguments descriptor
-void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler);
-  __ Ret();
+  __ jr(T1);
 }
 
 
@@ -2273,10 +2202,11 @@
 //  T0: receiver
 //  S5: ICData (preserved)
 // Result:
-//  T1: target entry point
 //  CODE_REG: target Code object
 //  S4: arguments descriptor
 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
   __ lw(T6, FieldAddress(S5, ICData::ic_data_offset()));
   __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
@@ -2300,17 +2230,19 @@
   __ lw(T0, Address(T6, target_offset));
   __ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
   __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
-  __ Ret();
+  __ jr(T1);
 
   __ Bind(&miss);
   __ LoadIsolate(T2);
   __ lw(CODE_REG, Address(T2, Isolate::ic_miss_code_offset()));
   __ lw(T1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ Ret();
+  __ jr(T1);
 }
 
 
 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
   __ lw(T6, FieldAddress(S5, ICData::ic_data_offset()));
   __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
@@ -2334,13 +2266,34 @@
   const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
   __ lw(T1, Address(T6, entry_offset));
   __ lw(CODE_REG, Address(T6, code_offset));
-  __ Ret();
+  __ jr(T1);
 
   __ Bind(&miss);
   __ LoadIsolate(T2);
   __ lw(CODE_REG, Address(T2, Isolate::ic_miss_code_offset()));
   __ lw(T1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ Ret();
+  __ jr(T1);
+}
+
+
+// Called from the monomorphic checked entry.
+//  T0: receiver
+void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(T0);  // Preserve receiver.
+
+  __ PushObject(Object::null_object());  // Result.
+  __ Push(T0);                           // Arg0: Receiver
+  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
+  __ Drop(1);
+  __ Pop(S5);  // result = IC
+
+  __ Pop(T0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ lw(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+  __ lw(T1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+  __ jr(T1);
 }
 
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 45edaf4..251d463 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -783,7 +783,6 @@
   // Set up arguments for the Dart call.
   Label push_arguments;
   Label done_push_arguments;
-  __ testq(RBX, RBX);  // check if there are arguments.
   __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
   __ movq(RAX, Immediate(0));
   __ Bind(&push_arguments);
@@ -1227,8 +1226,7 @@
 static void EmitFastSmiOp(Assembler* assembler,
                           Token::Kind kind,
                           intptr_t num_args,
-                          Label* not_smi_or_overflow,
-                          bool should_update_result_range) {
+                          Label* not_smi_or_overflow) {
   __ Comment("Fast Smi op");
   ASSERT(num_args == 2);
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Right
@@ -1262,14 +1260,6 @@
     default: UNIMPLEMENTED();
   }
 
-
-  if (should_update_result_range) {
-    Label done;
-    __ movq(RSI, RAX);
-    __ UpdateRangeFeedback(RSI, 2, RBX, RCX, &done);
-    __ Bind(&done);
-  }
-
   // RBX: IC data object (preserved).
   __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
   // R13: ic_data_array with check entries: classes and target functions.
@@ -1318,7 +1308,6 @@
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
     Token::Kind kind,
-    RangeCollectionMode range_collection_mode,
     bool optimized) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
@@ -1344,25 +1333,13 @@
     __ Bind(&done_stepping);
   }
 
-  __ Comment("Range feedback collection");
   Label not_smi_or_overflow;
-  if (range_collection_mode == kCollectRanges) {
-    ASSERT((num_args == 1) || (num_args == 2));
-    if (num_args == 2) {
-      __ movq(RAX, Address(RSP, + 2 * kWordSize));
-      __ UpdateRangeFeedback(RAX, 0, RBX, RCX, &not_smi_or_overflow);
-    }
-
-    __ movq(RAX, Address(RSP, + 1 * kWordSize));
-    __ UpdateRangeFeedback(RAX, (num_args - 1), RBX, RCX, &not_smi_or_overflow);
-  }
   if (kind != Token::kILLEGAL) {
     EmitFastSmiOp(
         assembler,
         kind,
         num_args,
-        &not_smi_or_overflow,
-        range_collection_mode == kCollectRanges);
+        &not_smi_or_overflow);
   }
   __ Bind(&not_smi_or_overflow);
 
@@ -1475,34 +1452,9 @@
   __ Bind(&call_target_function);
   // RAX: Target function.
   Label is_compiled;
-  if (range_collection_mode == kCollectRanges) {
-    __ movq(R13, FieldAddress(RAX, Function::code_offset()));
-    __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-    __ movq(R8, Address(RSP, + 1 * kWordSize));
-    if (num_args == 2) {
-      __ movq(R9, Address(RSP, + 2 * kWordSize));
-    }
-    __ EnterStubFrame();
-    __ pushq(RBX);
-    if (num_args == 2) {
-      __ pushq(R9);
-    }
-    __ pushq(R8);
-    __ movq(CODE_REG, R13);
-    __ call(RCX);
-
-    Label done;
-    __ movq(RDX, RAX);
-    __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize));
-    __ UpdateRangeFeedback(RDX, 2, RBX, RCX, &done);
-    __ Bind(&done);
-    __ LeaveStubFrame();
-    __ ret();
-  } else {
-    __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-    __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-    __ jmp(RCX);
-  }
+  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
+  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
+  __ jmp(RCX);
 
   if (FLAG_support_debugger && !optimized) {
     __ Bind(&stepping);
@@ -1531,8 +1483,7 @@
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1540,8 +1491,7 @@
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1549,8 +1499,7 @@
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kADD,
-      kCollectRanges);
+      Token::kADD);
 }
 
 
@@ -1558,8 +1507,7 @@
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kSUB,
-      kCollectRanges);
+      Token::kSUB);
 }
 
 
@@ -1567,28 +1515,7 @@
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kEQ,
-      kIgnoreRanges);
-}
-
-
-void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
-}
-
-
-void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kCollectRanges);
+      Token::kEQ);
 }
 
 
@@ -1609,7 +1536,7 @@
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
       kInlineCacheMissHandlerOneArgRuntimeEntry,
       Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1619,7 +1546,7 @@
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
       kInlineCacheMissHandlerTwoArgsRuntimeEntry,
       Token::kILLEGAL,
-      kIgnoreRanges, true /* optimized */);
+      true /* optimized */);
 }
 
 
@@ -1702,8 +1629,7 @@
       assembler,
       1,
       kStaticCallMissHandlerOneArgRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -1712,8 +1638,7 @@
   GenerateNArgsCheckInlineCacheStub(assembler,
       2,
       kStaticCallMissHandlerTwoArgsRuntimeEntry,
-      Token::kILLEGAL,
-      kIgnoreRanges);
+      Token::kILLEGAL);
 }
 
 
@@ -2083,57 +2008,76 @@
 }
 
 
-void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
-  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
-  // RAX: class ID of the receiver (smi).
-  __ movq(R10,
-          FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset()));
-  __ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset()));
+// Called from megamorphic calls.
+//  RDI: receiver
+//  RBX: MegamorphicCache (preserved)
+// Result:
+//  CODE_REG: target Code
+//  R10: arguments descriptor
+void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
+  // Jump if receiver is a smi.
+  Label smi_case;
+  __ testq(RDI, Immediate(kSmiTagMask));
+  // Jump out of line for smi case.
+  __ j(ZERO, &smi_case, Assembler::kNearJump);
+
+  // Loads the cid of the object.
+  __ LoadClassId(RAX, RDI);
+
+  Label cid_loaded;
+  __ Bind(&cid_loaded);
   __ movq(R9, FieldAddress(RBX, MegamorphicCache::mask_offset()));
-  // R10: arguments descriptor (result).
+  __ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset()));
+  // R9: mask.
   // RDI: cache buckets array.
-  // RBX: mask.
-  __ movq(RCX, RAX);
-  __ imulq(RCX, Immediate(MegamorphicCache::kSpreadFactor));
 
-  Label loop, update, load_target_function;
-  __ jmp(&loop);
+  // Tag cid as a smi.
+  __ addq(RAX, RAX);
 
-  __ Bind(&update);
-  __ AddImmediate(RCX, Immediate(Smi::RawValue(1)));
+  // Compute the table index.
+  ASSERT(MegamorphicCache::kSpreadFactor == 7);
+  // Use leaq and subq multiply with 7 == 8 - 1.
+  __ leaq(RCX, Address(RAX, TIMES_8, 0));
+  __ subq(RCX, RAX);
+
+  Label loop;
   __ Bind(&loop);
   __ andq(RCX, R9);
+
   const intptr_t base = Array::data_offset();
   // RCX is smi tagged, but table entries are two words, so TIMES_8.
-  __ movq(RDX, FieldAddress(RDI, RCX, TIMES_8, base));
+  Label probe_failed;
+  __ cmpq(RAX, FieldAddress(RDI, RCX, TIMES_8, base));
+  __ j(NOT_EQUAL, &probe_failed, Assembler::kNearJump);
 
-  ASSERT(kIllegalCid == 0);
-  __ testq(RDX, RDX);
-  __ j(ZERO, &load_target_function, Assembler::kNearJump);
-  __ cmpq(RDX, RAX);
-  __ j(NOT_EQUAL, &update, Assembler::kNearJump);
-
-  __ Bind(&load_target_function);
+  Label load_target;
+  __ Bind(&load_target);
   // Call the target found in the cache.  For a class id match, this is a
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize));
+  __ movq(R10,
+          FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset()));
   __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
   __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-}
+  __ jmp(RCX);
 
+  // Probe failed, check if it is a miss.
+  __ Bind(&probe_failed);
+  __ cmpq(FieldAddress(RDI, RCX, TIMES_8, base), Immediate(kIllegalCid));
+  __ j(ZERO, &load_target, Assembler::kNearJump);
 
-// Called from megamorphic calls.
-//  RDI: receiver
-//  RBX: MegamorphicCache (preserved)
-// Result:
-//  RCX: target entry point
-//  CODE_REG: target Code
-//  R10: arguments descriptor
-void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
-  EmitMegamorphicLookup(assembler);
-  __ ret();
+  // Try next extry in the table.
+  __ AddImmediate(RCX, Immediate(Smi::RawValue(1)));
+  __ jmp(&loop);
+
+  // Load cid for the Smi case.
+  __ Bind(&smi_case);
+  __ movq(RAX, Immediate(kSmiCid));
+  __ jmp(&cid_loaded);
 }
 
 
@@ -2141,10 +2085,11 @@
 //  RDI: receiver
 //  RBX: ICData (preserved)
 // Result:
-//  RCX: target entry point
 //  CODE_REG: target Code object
 //  R10: arguments descriptor
 void StubCode::GenerateICLookupThroughFunctionStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
 
   __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
@@ -2172,17 +2117,19 @@
   __ movq(RAX, Address(R13, target_offset));
   __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
   __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ ret();
+  __ jmp(RCX);
 
   __ Bind(&miss);
   __ LoadIsolate(RAX);
   __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset()));
   __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ ret();
+  __ jmp(RCX);
 }
 
 
 void StubCode::GenerateICLookupThroughCodeStub(Assembler* assembler) {
+  __ NoMonomorphicCheckedEntry();
+
   Label loop, found, miss;
 
   __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
@@ -2210,13 +2157,34 @@
   const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
   __ movq(RCX, Address(R13, entry_offset));
   __ movq(CODE_REG, Address(R13, code_offset));
-  __ ret();
+  __ jmp(RCX);
 
   __ Bind(&miss);
   __ LoadIsolate(RAX);
   __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset()));
   __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ ret();
+  __ jmp(RCX);
+}
+
+
+// Called from the monomorphic checked entry.
+//  RDI: receiver
+void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(RDI);  // Preserve receiver.
+
+  __ PushObject(Object::null_object());  // Result.
+  __ pushq(RDI);                         // Arg0: Receiver
+  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
+  __ popq(RBX);
+  __ popq(RBX);  // result = IC
+
+  __ popq(RDI);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+  __ jmp(RCX);
 }
 
 
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 5e6a165..97d74af 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -298,7 +298,6 @@
   V(BooleanExpression, "boolean expression")                                   \
   V(MegamorphicMiss, "megamorphic_miss")                                       \
   V(CommaSpace, ", ")                                                          \
-  V(ColonSpace, ": ")                                                          \
   V(RParenArrow, ") => ")                                                      \
   V(SpaceExtendsSpace, " extends ")                                            \
   V(SpaceWhereNewLine, " where\n")                                             \
@@ -311,6 +310,9 @@
   V(TwoNewlines, "\n\n")                                                       \
   V(TwoSpaces, "  ")                                                           \
   V(_instanceOf, "_instanceOf")                                                \
+  V(_simpleInstanceOf, "_simpleInstanceOf")                                    \
+  V(_simpleInstanceOfTrue, "_simpleInstanceOfTrue")                            \
+  V(_simpleInstanceOfFalse, "_simpleInstanceOfFalse")                          \
   V(_instanceOfSmi, "_instanceOfSmi")                                          \
   V(_instanceOfNum, "_instanceOfNum")                                          \
   V(_instanceOfInt, "_instanceOfInt")                                          \
@@ -393,6 +395,7 @@
   V(_runPendingImmediateCallback, "_runPendingImmediateCallback")              \
   V(DartLibrary, "dart.library.")                                              \
   V(DartLibraryMirrors, "dart.library.mirrors")                                \
+  V(_name, "_name")                                                            \
 
 
 // Contains a list of frequently used strings in a canonicalized form. This
diff --git a/runtime/vm/tags.cc b/runtime/vm/tags.cc
index fa3cc67..ccb52ab 100644
--- a/runtime/vm/tags.cc
+++ b/runtime/vm/tags.cc
@@ -137,6 +137,7 @@
 }
 
 
+#ifndef PRODUCT
 void VMTagCounters::PrintToJSONObject(JSONObject* obj) {
   if (!FLAG_support_service) {
     return;
@@ -154,6 +155,7 @@
     }
   }
 }
+#endif  // !PRODUCT
 
 
 const char* UserTags::TagName(uword tag_id) {
diff --git a/runtime/vm/tags.h b/runtime/vm/tags.h
index 3279c82..8c6ef65 100644
--- a/runtime/vm/tags.h
+++ b/runtime/vm/tags.h
@@ -98,7 +98,9 @@
 
   int64_t count(uword tag);
 
+#ifndef PRODUCT
   void PrintToJSONObject(JSONObject* obj);
+#endif  // !PRODUCT
 
  private:
   int64_t counters_[VMTag::kNumVMTags];
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 69e7820..5115963 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -97,7 +97,7 @@
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
       safepoint_state_(0),
-      execution_state_(kThreadInVM),
+      execution_state_(kThreadInNative),
       next_(NULL) {
 NOT_IN_PRODUCT(
   dart_stream_ = Timeline::GetDartStream();
@@ -642,6 +642,12 @@
 
 
 bool Thread::ObjectAtOffset(intptr_t offset, Object* object) {
+  if (Isolate::Current() == Dart::vm_isolate()) {
+    // --disassemble-stubs runs before all the references through
+    // thread have targets
+    return false;
+  }
+
 #define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value)       \
   if (Thread::member_name##offset() == offset) {                               \
     *object = expr;                                                            \
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 1ce083a..2e56a8e 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -87,6 +87,10 @@
     StubCode::InvokeDartCode_entry()->code(), NULL)                            \
   V(RawCode*, call_to_runtime_stub_,                                           \
     StubCode::CallToRuntime_entry()->code(), NULL)                             \
+  V(RawCode*, monomorphic_miss_stub_,                                          \
+    StubCode::MonomorphicMiss_entry()->code(), NULL)                           \
+  V(RawCode*, ic_lookup_through_code_stub_,                                    \
+    StubCode::ICLookupThroughCode_entry()->code(), NULL)                       \
 
 #endif
 
@@ -105,6 +109,8 @@
     StubCode::UpdateStoreBuffer_entry()->EntryPoint(), 0)                      \
   V(uword, call_to_runtime_entry_point_,                                       \
     StubCode::CallToRuntime_entry()->EntryPoint(), 0)                          \
+  V(uword, megamorphic_lookup_checked_entry_,                                  \
+    StubCode::MegamorphicLookup_entry()->CheckedEntryPoint(), 0)               \
 
 #endif
 
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index adf2a34..dd2c6df 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -26,6 +26,7 @@
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames);
   void PrepareForGC();
+  Thread* mutator_thread() const { return mutator_thread_; }
 
  private:
   Thread* active_list() const { return active_list_; }
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index d0deba9..dc2edac 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -405,6 +405,25 @@
 }
 
 
+// Test case for recursive safepoint operations.
+VM_TEST_CASE(RecursiveSafepointTest1) {
+  intptr_t count = 0;
+  {
+    SafepointOperationScope safepoint_scope(thread);
+    count += 1;
+    {
+      SafepointOperationScope safepoint_scope(thread);
+      count += 1;
+      {
+        SafepointOperationScope safepoint_scope(thread);
+        count += 1;
+      }
+    }
+  }
+  EXPECT(count == 3);
+}
+
+
 VM_TEST_CASE(ThreadIterator_Count) {
   intptr_t thread_count_0 = 0;
   intptr_t thread_count_1 = 0;
@@ -525,6 +544,46 @@
 }
 
 
+// Test recursive safepoint operation scopes with other threads trying
+// to also start a safepoint operation scope.
+VM_TEST_CASE(RecursiveSafepointTest2) {
+  Isolate* isolate = thread->isolate();
+  Monitor monitor;
+  intptr_t expected_count = 0;
+  intptr_t total_done = 0;
+  intptr_t exited = 0;
+  for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
+    Dart::thread_pool()->Run(new SafepointTestTask(
+        isolate, &monitor, &expected_count, &total_done, &exited));
+  }
+  bool all_helpers = false;
+  do {
+    SafepointOperationScope safepoint_scope(thread);
+    {
+      SafepointOperationScope safepoint_scope(thread);
+      MonitorLocker ml(&monitor);
+      if (expected_count == SafepointTestTask::kTaskCount) {
+        all_helpers = true;
+      }
+    }
+  } while (!all_helpers);
+  String& label = String::Handle(String::New("foo"));
+  UserTag& tag = UserTag::Handle(UserTag::New(label));
+  isolate->set_current_tag(tag);
+  bool all_exited = false;
+  do {
+    SafepointOperationScope safepoint_scope(thread);
+    {
+      SafepointOperationScope safepoint_scope(thread);
+      MonitorLocker ml(&monitor);
+      if (exited == SafepointTestTask::kTaskCount) {
+        all_exited = true;
+      }
+    }
+  } while (!all_exited);
+}
+
+
 class AllocAndGCTask : public ThreadPool::Task {
  public:
   AllocAndGCTask(Isolate* isolate,
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index b0c773e..b507c00 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -74,24 +74,45 @@
 }
 
 
-static bool IsImportableTestLib(const char* url_name) {
-  const char* kImportTestLibUri = "test:importable_lib";
-  static const intptr_t kImportTestLibUriLen = strlen(kImportTestLibUri);
-  return (strncmp(url_name, kImportTestLibUri, kImportTestLibUriLen) == 0);
+struct TestLibEntry {
+  const char* url;
+  const char* source;
+};
+
+
+static MallocGrowableArray<TestLibEntry>* test_libs_ = NULL;
+
+
+void TestCase::AddTestLib(const char* url, const char* source) {
+  if (test_libs_ == NULL) {
+    test_libs_ = new MallocGrowableArray<TestLibEntry>();
+  }
+  // If the test lib is already added, replace the source.
+  for (intptr_t i = 0; i < test_libs_->length(); i++) {
+    if (strcmp(url, (*test_libs_)[i].url) == 0) {
+      (*test_libs_)[i].source = source;
+      return;
+    }
+  }
+  TestLibEntry entry;
+  entry.url = url;
+  entry.source = source;
+  test_libs_->Add(entry);
 }
 
 
-static Dart_Handle ImportableTestLibSource() {
-  const char* kScript =
-      "importedFunc() => 'a';\n"
-      "importedIntFunc() => 4;\n"
-      "class ImportedMixin {\n"
-      "  mixinFunc() => 'mixin';\n"
-      "}\n";
-  return DartUtils::NewString(kScript);
+const char* TestCase::GetTestLib(const char* url) {
+  if (test_libs_ == NULL) {
+    return NULL;
+  }
+  for (intptr_t i = 0; i < test_libs_->length(); i++) {
+    if (strcmp(url, (*test_libs_)[i].url) == 0) {
+      return (*test_libs_)[i].source;
+    }
+  }
+  return NULL;
 }
 
-
 #ifndef PRODUCT
 static bool IsIsolateReloadTestLib(const char* url_name) {
   const char* kIsolateReloadTestLibUri = "test:isolate_reload_helper";
@@ -155,6 +176,7 @@
     ASSERT(script_source != NULL);
     OSThread::SetThreadLocal(script_reload_key, 0);
     return Dart_LoadScript(url,
+                           Dart_Null(),
                            NewString(script_source),
                            0,
                            0);
@@ -190,13 +212,15 @@
       return DartUtils::NewError("Do not know how to load '%s'", url_chars);
     }
   }
-  if (IsImportableTestLib(url_chars)) {
-    return Dart_LoadLibrary(url, ImportableTestLibSource(), 0, 0);
+  const char* lib_source = TestCase::GetTestLib(url_chars);
+  if (lib_source != NULL) {
+    Dart_Handle source = Dart_NewStringFromCString(lib_source);
+    return Dart_LoadLibrary(url, Dart_Null(), source, 0, 0);
   }
   NOT_IN_PRODUCT(
   if (IsIsolateReloadTestLib(url_chars)) {
     Dart_Handle library =
-        Dart_LoadLibrary(url, IsolateReloadTestLibSource(), 0, 0);
+        Dart_LoadLibrary(url, Dart_Null(), IsolateReloadTestLibSource(), 0, 0);
     DART_CHECK_VALID(library);
     Dart_SetNativeResolver(library, IsolateReloadTestNativeResolver, 0);
     return library;
@@ -204,28 +228,28 @@
   if (is_io_library) {
     ASSERT(tag == Dart_kSourceTag);
     return Dart_LoadSource(library,
-                           url,
+                           url, Dart_Null(),
                            Builtin::PartSource(Builtin::kIOLibrary,
                                                url_chars),
                            0, 0);
   }
+  Dart_Handle resolved_url = url;
+  const char* resolved_url_chars = url_chars;
   if (IsPackageSchemeURL(url_chars)) {
-    Dart_Handle resolved_uri = ResolvePackageUri(url_chars);
-    DART_CHECK_VALID(resolved_uri);
-    url_chars = NULL;
-    Dart_Handle result = Dart_StringToCString(resolved_uri, &url_chars);
-    if (Dart_IsError(result)) {
-      return Dart_NewApiError("accessing url characters failed");
+    resolved_url = ResolvePackageUri(url_chars);
+    DART_CHECK_VALID(resolved_url);
+    if (Dart_IsError(Dart_StringToCString(resolved_url, &resolved_url_chars))) {
+      return Dart_NewApiError("unable to convert resolved uri to string");
     }
   }
   // Do sync loading since unit_test doesn't support async.
-  Dart_Handle source = DartUtils::ReadStringFromFile(url_chars);
+  Dart_Handle source = DartUtils::ReadStringFromFile(resolved_url_chars);
   EXPECT_VALID(source);
   if (tag == Dart_kImportTag) {
-    return Dart_LoadLibrary(url, source, 0, 0);
+    return Dart_LoadLibrary(url, resolved_url, source, 0, 0);
   } else {
     ASSERT(tag == Dart_kSourceTag);
-    return Dart_LoadSource(library, url, source, 0, 0);
+    return Dart_LoadSource(library, url, resolved_url, source, 0, 0);
   }
 }
 
@@ -238,7 +262,7 @@
   Dart_Handle source = NewString(script);
   Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
   EXPECT_VALID(result);
-  Dart_Handle lib = Dart_LoadScript(url, source, 0, 0);
+  Dart_Handle lib = Dart_LoadScript(url, Dart_Null(), source, 0, 0);
   DART_CHECK_VALID(lib);
   result = Dart_SetNativeResolver(lib, resolver, NULL);
   DART_CHECK_VALID(result);
@@ -266,22 +290,29 @@
 
 Dart_Handle TestCase::TriggerReload() {
   Isolate* isolate = Isolate::Current();
-
+  JSONStream js;
+  bool success = false;
   {
     TransitionNativeToVM transition(Thread::Current());
-    isolate->ReloadSources(/* test_mode = */ true);
+    success = isolate->ReloadSources(&js,
+                                     false,  // force_reload
+                                     true);  // dont_delete_reload_context
+    fprintf(stderr, "RELOAD REPORT:\n%s\n", js.ToCString());
   }
 
-  return Dart_FinalizeLoading(false);
+  if (success) {
+    return Dart_FinalizeLoading(false);
+  } else {
+    return Dart_Null();
+  }
 }
 
 
 Dart_Handle TestCase::GetReloadErrorOrRootLibrary() {
   Isolate* isolate = Isolate::Current();
 
-  if (isolate->reload_context() != NULL) {
-    // We should only have a reload context hanging around if an error occurred.
-    ASSERT(isolate->reload_context()->has_error());
+  if (isolate->reload_context() != NULL &&
+      isolate->reload_context()->reload_aborted()) {
     // Return a handle to the error.
     return Api::NewHandle(Thread::Current(),
                           isolate->reload_context()->error());
@@ -298,7 +329,18 @@
     return result;
   }
 
-  return GetReloadErrorOrRootLibrary();
+  result = GetReloadErrorOrRootLibrary();
+
+  {
+    Thread* thread = Thread::Current();
+    TransitionNativeToVM transition(thread);
+    Isolate* isolate = thread->isolate();
+    if (isolate->reload_context() != NULL) {
+      isolate->DeleteReloadContext();
+    }
+  }
+
+  return result;
 }
 
 
@@ -360,14 +402,16 @@
   code_ = Code::FinalizeCode(function, assembler_);
   code_.set_owner(function);
   code_.set_exception_handlers(Object::empty_exception_handlers());
+#ifndef PRODUCT
   if (FLAG_disassemble) {
     OS::Print("Code for test '%s' {\n", name_);
     const Instructions& instructions =
         Instructions::Handle(code_.instructions());
-    uword start = instructions.EntryPoint();
+    uword start = instructions.PayloadStart();
     Disassembler::Disassemble(start, start + assembler_->CodeSize());
     OS::Print("}\n");
   }
+#endif  // !PRODUCT
 }
 
 
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index ac7645a..189515f 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -314,6 +314,9 @@
   // Helper function which reloads the current isolate using |script|.
   static Dart_Handle ReloadTestScript(const char* script);
 
+  static void AddTestLib(const char* url, const char* source);
+  static const char* GetTestLib(const char* url);
+
  private:
   static Dart_Isolate CreateIsolate(const uint8_t* buffer, const char* name);
 
@@ -377,7 +380,8 @@
 
   const Code& code() const { return code_; }
 
-  uword entry() const { return code_.EntryPoint(); }
+  uword payload_start() const { return code_.PayloadStart(); }
+  uword entry() const { return code_.UncheckedEntryPoint(); }
 
   // Invoke/InvokeWithCodeAndThread is used to call assembler test functions
   // using the ABI calling convention.
diff --git a/runtime/vm/verifier.cc b/runtime/vm/verifier.cc
index 18a7874..de125bf 100644
--- a/runtime/vm/verifier.cc
+++ b/runtime/vm/verifier.cc
@@ -82,4 +82,22 @@
   delete allocated_set;
 }
 
+
+#if defined(DEBUG)
+VerifyCanonicalVisitor::VerifyCanonicalVisitor(Thread* thread)
+    : thread_(thread),
+      instanceHandle_(Instance::Handle(thread->zone())) {
+}
+
+
+void VerifyCanonicalVisitor::VisitObject(RawObject* obj) {
+  if (obj->GetClassId() >= kInstanceCid) {
+    if (obj->IsCanonical()) {
+      instanceHandle_ ^= obj;
+      ASSERT(instanceHandle_.CheckIsCanonical(thread_));
+    }
+  }
+}
+#endif  // defined(DEBUG)
+
 }  // namespace dart
diff --git a/runtime/vm/verifier.h b/runtime/vm/verifier.h
index a34d7f6..8ae222d 100644
--- a/runtime/vm/verifier.h
+++ b/runtime/vm/verifier.h
@@ -81,6 +81,21 @@
   DISALLOW_COPY_AND_ASSIGN(VerifyWeakPointersVisitor);
 };
 
+
+#if defined(DEBUG)
+class VerifyCanonicalVisitor : public ObjectVisitor {
+ public:
+  explicit VerifyCanonicalVisitor(Thread* thread);
+  virtual void VisitObject(RawObject* obj);
+
+ private:
+  Thread* thread_;
+  Instance& instanceHandle_;
+
+  DISALLOW_COPY_AND_ASSIGN(VerifyCanonicalVisitor);
+};
+#endif  // defined(DEBUG)
+
 }  // namespace dart
 
 #endif  // VM_VERIFIER_H_
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h
index 270d3cf..6e43cb4 100644
--- a/runtime/vm/virtual_memory.h
+++ b/runtime/vm/virtual_memory.h
@@ -24,6 +24,7 @@
   // The reserved memory is unmapped on destruction.
   ~VirtualMemory();
 
+  int32_t handle() const { return handle_; }
   uword start() const { return region_.start(); }
   uword end() const { return region_.end(); }
   void* address() const { return region_.pointer(); }
@@ -82,9 +83,10 @@
 
   // This constructor is only used internally when reserving new virtual spaces.
   // It does not reserve any virtual address space on its own.
-  explicit VirtualMemory(const MemoryRegion& region) :
+  explicit VirtualMemory(const MemoryRegion& region, int32_t handle = 0) :
       region_(region.pointer(), region.size()),
       reserved_size_(region.size()),
+      handle_(handle),
       embedder_allocated_(false) { }
 
   MemoryRegion region_;
@@ -93,6 +95,8 @@
   // Its start coincides with region_, but its size might not, due to Truncate.
   intptr_t reserved_size_;
 
+  int32_t handle_;
+
   static uword page_size_;
 
   // True for a region provided by the embedder.
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc
index f84e2ef..16aa834 100644
--- a/runtime/vm/virtual_memory_android.cc
+++ b/runtime/vm/virtual_memory_android.cc
@@ -83,7 +83,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc
index da32045..6e7d439 100644
--- a/runtime/vm/virtual_memory_fuchsia.cc
+++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -7,9 +7,11 @@
 
 #include "vm/virtual_memory.h"
 
+#include <magenta/syscalls.h>
 #include <unistd.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "vm/memory_region.h"
 #include "vm/os.h"
 
 namespace dart {
@@ -23,31 +25,65 @@
 
 
 VirtualMemory* VirtualMemory::ReserveInternal(intptr_t size) {
-  UNIMPLEMENTED();
-  return NULL;
+  mx_handle_t vmo = mx_vm_object_create(size);
+  if (vmo <= 0) {
+    return NULL;
+  }
+
+  // TODO(zra): map with PERM_NONE, when that works, and relax with
+  // Commit and Protect when they are implemented.
+  // Issue MG-161.
+  const int prot = MX_VM_FLAG_PERM_READ |
+                   MX_VM_FLAG_PERM_WRITE |
+                   MX_VM_FLAG_PERM_EXECUTE;
+  uintptr_t addr;
+  mx_status_t status = mx_process_vm_map(0, vmo, 0, size, &addr, prot);
+  if (status != NO_ERROR) {
+    mx_handle_close(vmo);
+    FATAL("VirtualMemory::ReserveInternal FAILED");
+    return NULL;
+  }
+
+  MemoryRegion region(reinterpret_cast<void*>(addr), size);
+  return new VirtualMemory(region, vmo);
 }
 
 
 VirtualMemory::~VirtualMemory() {
-  UNIMPLEMENTED();
+  if (!embedder_allocated()) {
+    // TODO(zra): Use reserved_size_.
+    // Issue MG-162.
+    mx_status_t status = mx_process_vm_unmap(
+        0, reinterpret_cast<uintptr_t>(address()), 0 /*reserved_size_*/);
+    if (status != NO_ERROR) {
+      FATAL("VirtualMemory::~VirtualMemory: unamp FAILED");
+    }
+
+    status = mx_handle_close(handle());
+    if (status != NO_ERROR) {
+      FATAL("VirtualMemory::~VirtualMemory: handle_close FAILED");
+    }
+  }
 }
 
 
 bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
-  UNIMPLEMENTED();
+  // TODO(zra): It should be possible to free a subsegment after
+  // Issue MG-162 is addressed.
   return false;
 }
 
 
 bool VirtualMemory::Commit(uword addr, intptr_t size, bool executable) {
-  UNIMPLEMENTED();
-  return false;
+  // TODO(zra): Implement when the protections for a mapping can be changed.
+  // Issue MG-133.
+  return true;
 }
 
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
-  UNIMPLEMENTED();
-  return false;
+  // TODO(zra): Implement when Fuchsia has an mprotect-like call.
+  return true;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc
index 8973345..0228f68 100644
--- a/runtime/vm/virtual_memory_linux.cc
+++ b/runtime/vm/virtual_memory_linux.cc
@@ -82,7 +82,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc
index 1d23ead..484ad78 100644
--- a/runtime/vm/virtual_memory_macos.cc
+++ b/runtime/vm/virtual_memory_macos.cc
@@ -83,7 +83,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index 8ea8fa5..2584613 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -66,7 +66,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 0f6754f..743727a 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -35,7 +35,7 @@
   // Computes the address of the nth byte in this segment.
   uword address(int n) { return reinterpret_cast<uword>(this) + n; }
 
-  static void Delete(Segment* segment) { delete[] segment; }
+  static void Delete(Segment* segment) { free(segment); }
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(Segment);
 };
@@ -57,16 +57,17 @@
 
 Zone::Segment* Zone::Segment::New(intptr_t size, Zone::Segment* next) {
   ASSERT(size >= 0);
-  Segment* result = reinterpret_cast<Segment*>(new uint8_t[size]);
-  ASSERT(Utils::IsAligned(result->start(), Zone::kAlignment));
-  if (result != NULL) {
-#ifdef DEBUG
-    // Zap the entire allocated segment (including the header).
-    memset(result, kZapUninitializedByte, size);
-#endif
-    result->next_ = next;
-    result->size_ = size;
+  Segment* result = reinterpret_cast<Segment*>(malloc(size));
+  if (result == NULL) {
+    FATAL("Out of memory.\n");
   }
+  ASSERT(Utils::IsAligned(result->start(), Zone::kAlignment));
+#ifdef DEBUG
+  // Zap the entire allocated segment (including the header).
+  memset(result, kZapUninitializedByte, size);
+#endif
+  result->next_ = next;
+  result->size_ = size;
   return result;
 }
 
diff --git a/samples-dev/swarm/UIState.dart b/samples-dev/swarm/UIState.dart
index dffb1c7..2d40843 100644
--- a/samples-dev/swarm/UIState.dart
+++ b/samples-dev/swarm/UIState.dart
@@ -60,7 +60,8 @@
     // TODO(jmesserly): [state] should be an Object, and we should pass it to
     // the state parameter instead of as a #hash URL. Right now we're working
     //  around b/4582542.
-    window.history.pushState(null, '${document.title}#$state');
+    window.history.pushState(null,
+        '${document.title}', '${document.title}#$state');
   }
 
   /**
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/FxUtil.dart b/samples-dev/swarm/swarm_ui_lib/touch/FxUtil.dart
index 82d0a54..aa084e8 100644
--- a/samples-dev/swarm/swarm_ui_lib/touch/FxUtil.dart
+++ b/samples-dev/swarm/swarm_ui_lib/touch/FxUtil.dart
@@ -68,11 +68,18 @@
    */
   static Coordinate computeRelativePosition(Element element, Element target) {
     final testPoint = new Point(0, 0);
+    /*
     final pagePoint =
         window.convertPointFromNodeToPage(element, testPoint);
     final pointRelativeToTarget =
         window.convertPointFromPageToNode(target, pagePoint);
     return new Coordinate(pointRelativeToTarget.x, pointRelativeToTarget.y);
+    */
+    // TODO(sra): Test this version that avoids the nonstandard
+    // `convertPointFromPageToNode`.
+    var eRect = element.getBoundingClientRect();
+    var tRect = target.getBoundingClientRect();
+    return new Coordinate(eRect.left - tRect.left, eRect.top - tRect.top);
   }
 
   /** Clear a -webkit-transform from an element. */
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/Scrollbar.dart b/samples-dev/swarm/swarm_ui_lib/touch/Scrollbar.dart
index 1c2a6f2..1ac758c 100644
--- a/samples-dev/swarm/swarm_ui_lib/touch/Scrollbar.dart
+++ b/samples-dev/swarm/swarm_ui_lib/touch/Scrollbar.dart
@@ -155,7 +155,7 @@
     }
   }
 
-  void _onStart(UIEvent e) {
+  void _onStart(/*MouseEvent | Touch*/ e) {
     Element elementOver = e.target;
     if (elementOver == _verticalElement ||
         elementOver == _horizontalElement) {
@@ -196,7 +196,7 @@
     }
   }
 
-  void _onMove(UIEvent e) {
+  void _onMove(/*MouseEvent | Touch*/ e) {
     if (!_scrollBarDragInProgress) {
       return;
     }
diff --git a/samples-dev/swarm/swarm_ui_lib/touch/TouchUtil.dart b/samples-dev/swarm/swarm_ui_lib/touch/TouchUtil.dart
index d7992f7..8b82181 100644
--- a/samples-dev/swarm/swarm_ui_lib/touch/TouchUtil.dart
+++ b/samples-dev/swarm/swarm_ui_lib/touch/TouchUtil.dart
@@ -271,4 +271,5 @@
   Point get page { throw new UnimplementedError(); }
   List get path { throw new UnimplementedError(); }
   Point get screen { throw new UnimplementedError(); }
+  /*InputDevice*/ get sourceDevice { throw new UnimplementedError(); }
 }
diff --git a/samples/samples.status b/samples/samples.status
index 1fa1d28..c01c0d9 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -18,10 +18,6 @@
 [ $compiler == dart2analyzer ]
 build_dart: Skip
 
-[ $compiler == dart2dart ]
-# Skip until we stabilize language tests.
-*: Skip
-
 [ $arch == arm ]
 sample_extension/test/sample_extension_test: Skip # Issue 14705
 
diff --git a/sdk/bin/pub b/sdk/bin/pub
index 50f0d1d..a8514ea 100755
--- a/sdk/bin/pub
+++ b/sdk/bin/pub
@@ -29,6 +29,13 @@
 unset VM_OPTIONS
 declare -a VM_OPTIONS
 
+if [[ `uname` == 'Darwin' ]];
+then
+  OUT_DIR="$BIN_DIR"/../../xcodebuild/
+else
+  OUT_DIR="$BIN_DIR"/../../out/
+fi
+
 # Allow extra VM options to be passed in through an environment variable.
 if [[ $DART_VM_OPTIONS ]]; then
   read -a OPTIONS <<< "$DART_VM_OPTIONS"
@@ -37,7 +44,29 @@
 
 if [ -z "$DART_CONFIGURATION" ];
 then
-  DART_CONFIGURATION="ReleaseX64"
+  DIRS=$( ls "$OUT_DIR" )
+  # list of possible configurations in decreasing desirability
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
+    "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"    "ReleaseMIPS"
+    "DebugARM"      "DebugARM64"      "DebugARMV5TE"      "DebugMIPS")
+  DART_CONFIGURATION="None"
+  for CONFIG in ${CONFIGS[*]}
+  do
+    for DIR in $DIRS;
+    do
+      if [ "$CONFIG" = "$DIR" ];
+      then
+        # choose most desirable configuration that is available and break
+        DART_CONFIGURATION="$DIR"
+        break 2
+      fi
+    done
+  done
+  if [ "$DART_CONFIGURATION" = "None" ]
+  then
+    echo "No valid dart configuration found in $OUT_DIR"
+    exit 1
+  fi
 fi
 
 if [[ `uname` == 'Darwin' ]];
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 9004574..129ce01 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -587,15 +587,17 @@
 @patch
 class Uri {
   @patch
-  static bool get _isWindows => false;
-
-  @patch
   static Uri get base {
     String uri = Primitives.currentUri();
     if (uri != null) return Uri.parse(uri);
     throw new UnsupportedError("'Uri.base' is not supported");
   }
+}
 
+@patch
+class _Uri {
+  @patch
+  static bool get _isWindows => false;
 
   // Matches a String that _uriEncodes to itself regardless of the kind of
   // component.  This corresponds to [_unreservedTable], i.e. characters that
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index 907da4e..1f9748c 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -66,20 +66,55 @@
 
   int toInt() {
     if (this >= _MIN_INT32 && this <= _MAX_INT32) {
+      // 0 and -0.0 handled here.
       return JS('int', '# | 0', this);
     }
     if (JS('bool', r'isFinite(#)', this)) {
       return JS('int', r'# + 0', truncateToDouble());  // Converts -0.0 to +0.0.
     }
-    // This is either NaN, Infinity or -Infinity.
-    throw new UnsupportedError(JS("String", '"" + #', this));
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS("String", '"" + # + ".toInt()"', this));
   }
 
   int truncate() => toInt();
 
-  int ceil() => ceilToDouble().toInt();
+  int ceil() {
+    if (this >= 0) {
+      if (this <= _MAX_INT32) {
+        int truncated = JS('int', '# | 0', this);  // converts -0.0 to 0.
+        return this == truncated ? truncated : truncated + 1;
+      }
+    } else {
+      if (this >= _MIN_INT32) {
+        return JS('int', '# | 0', this);
+      }
+    }
+    var d = JS('num', 'Math.ceil(#)', this);
+    if (JS('bool', r'isFinite(#)', d)) {
+      return JS('int', r'#', d);
+    }
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS("String", '"" + # + ".ceil()"', this));
+  }
 
-  int floor() => floorToDouble().toInt();
+  int floor() {
+    if (this >= 0) {
+      if (this <= _MAX_INT32) {
+        return JS('int', '# | 0', this);
+      }
+    } else {
+      if (this >= _MIN_INT32) {
+        int truncated = JS('int', '# | 0', this);
+        return this == truncated ? truncated : truncated - 1;
+      }
+    }
+    var d = JS('num', 'Math.floor(#)', this);
+    if (JS('bool', r'isFinite(#)', d)) {
+      return JS('int', r'#', d);
+    }
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS("String", '"" + # + ".floor()"', this));
+  }
 
   int round() {
     if (this > 0) {
@@ -96,8 +131,8 @@
       // some JavaScript VMs can be a slow path.
       return JS('int', r'0 - Math.round(0 - #)', this);
     }
-    // This is either NaN, Infinity or -Infinity.
-    throw new UnsupportedError(JS("String", '"" + #', this));
+    // [this] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(JS("String", '"" + # + ".round()"', this));
   }
 
   double ceilToDouble() => JS('num', r'Math.ceil(#)', this);
@@ -246,23 +281,43 @@
   bool _isInt32(value) => JS('bool', '(# | 0) === #', value, value);
 
   int operator ~/(num other) {
+    if (other is !num) throw argumentErrorValue(other);
     if (false) _tdivFast(other); // Ensure resolution.
-    if (_isInt32(this) && _isInt32(other) && 0 != other && -1 != other) {
-      return JS('int', r'(# / #) | 0', this, other);
-    } else {
-      return _tdivSlow(other);
+    if (_isInt32(this)) {
+      if (other >= 1 || other < -1) {
+        return JS('int', r'(# / #) | 0', this, other);
+      }
     }
+    return _tdivSlow(other);
   }
 
   int _tdivFast(num other) {
+    // [other] is known to be a number outside the range [-1, 1).
     return _isInt32(this)
         ? JS('int', r'(# / #) | 0', this, other)
-        : (JS('num', r'# / #', this, other)).toInt();
+        : _tdivSlow(other);
   }
 
   int _tdivSlow(num other) {
-    if (other is !num) throw argumentErrorValue(other);
-    return (JS('num', r'# / #', this, other)).toInt();
+    var quotient = JS('num', r'# / #', this, other);
+    if (quotient >= _MIN_INT32 && quotient <= _MAX_INT32) {
+      // This path includes -0.0 and +0.0.
+      return JS('int', '# | 0', quotient);
+    }
+    if (quotient > 0) {
+      // This path excludes the special cases -0.0, NaN and -Infinity, leaving
+      // only +Infinity, for which a direct test is faster than [isFinite].
+      if (JS('bool', r'# !== (1/0)', quotient)) {
+        return JS('int', r'Math.floor(#)', quotient);
+      }
+    } else if (JS('bool', '# > (-1/0)', quotient)) {
+      // This test excludes NaN and -Infinity.
+      return JS('int', r'Math.ceil(#)', quotient);
+    }
+
+    // [quotient] is either NaN, Infinity or -Infinity.
+    throw new UnsupportedError(
+        "Result of truncating division is $quotient: $this ~/ $other");
   }
 
   // TODO(ngeoffray): Move the bit operations below to [JSInt] and
diff --git a/sdk/lib/_internal/js_runtime/lib/mirror_helper.dart b/sdk/lib/_internal/js_runtime/lib/mirror_helper.dart
deleted file mode 100644
index 9c3024f..0000000
--- a/sdk/lib/_internal/js_runtime/lib/mirror_helper.dart
+++ /dev/null
@@ -1,25 +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.
-/**
- * Helps dealing with reflection in the case that the source code has been
- * changed as a result of compiling with dart2dart.
- */
-library _mirror_helper;
-
-import 'dart:mirrors';
-
-/// The compiler will replace this variable with a map containing all the
-/// renames made in dart2dart.
-const Map<String, String> _SYMBOLS = null;
-
-/// This method is a wrapper for MirrorSystem.getName() and will be inlined and
-/// called in the generated output Dart code.
-String helperGetName(Symbol sym) {
-  var name = MirrorSystem.getName(sym);
-  if (_SYMBOLS.containsKey(name)) {
-    return _SYMBOLS[name];
-  } else {
-    return name;
-  }
-}
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index e304873..b439338 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -116,6 +116,12 @@
       maturity: Maturity.STABLE,
       dart2jsPath: "js/dart2js/js_dart2js.dart"),
 
+  "js_util": const LibraryInfo(
+      "js_util/dartium/js_util_dartium.dart",
+      categories: "Client",
+      maturity: Maturity.STABLE,
+      dart2jsPath: "js_util/dart2js/js_util_dart2js.dart"),
+
   "math": const LibraryInfo(
       "math/math.dart",
       categories: "Client,Server,Embedded",
@@ -221,14 +227,6 @@
       documented: false,
       platforms: DART2JS_PLATFORM),
 
-  // TODO(ahe): This library is only for dart2dart, perhaps it should use a
-  // different platform.
-  "_mirror_helper": const LibraryInfo(
-      "_internal/js_runtime/lib/mirror_helper.dart",
-      categories: "",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
   "_js_embedded_names": const LibraryInfo(
       "_internal/js_runtime/lib/shared/embedded_names.dart",
       categories: "",
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index e0e0617..b4d9c24 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -433,7 +433,7 @@
    * with a `test` parameter, instead of handling both value and error in a
    * single [then] call.
    */
-  Future/*<S>*/ then/*<S>*/(/*=S*/ onValue(T value), { Function onError });
+  Future/*<S>*/ then/*<S>*/(onValue(T value), { Function onError });
 
   /**
    * Handles errors emitted by this [Future].
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 24f83f8..b81a7fe 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -194,14 +194,26 @@
 }
 
 /**
- * This class wraps zones for delegation.
+ * An adapted view of the parent zone.
  *
- * When forwarding to parent zones one can't just invoke the parent zone's
- * exposed functions (like [Zone.run]), but one needs to provide more
- * information (like the zone the `run` was initiated). Zone callbacks thus
- * receive more information including this [ZoneDelegate] class. When delegating
- * to the parent zone one should go through the given instance instead of
- * directly invoking the parent zone.
+ * This class allows the implementation of a zone method to invoke methods on
+ * the parent zone while retaining knowledge of the originating zone.
+ *
+ * Custom zones (created through [Zone.fork] or [runZoned]) can provide
+ * implementations of most methods of zones. This is similar to overriding
+ * methods on [Zone], except that this mechanism doesn't require subclassing.
+ *
+ * A custom zone function (provided through a [ZoneSpecification]) typically
+ * records or wraps its parameters and then delegates the operation to its
+ * parent zone using the provided [ZoneDelegate].
+ *
+ * While zones have access to their parent zone (through [Zone.parent]) it is
+ * recommended to call the methods on the provided parent delegate for two
+ * reasons:
+ * 1. the delegate methods take an additional `zone` argument which is the
+ *   zone the action has been initiated in.
+ * 2. delegate calls are more efficient, since the implementation knows how
+ *   to skip zones that would just delegate to their parents.
  */
 abstract class ZoneDelegate {
   /*=R*/ handleUncaughtError/*<R>*/(
@@ -224,117 +236,266 @@
 }
 
 /**
- * A Zone represents the asynchronous version of a dynamic extent. Asynchronous
- * callbacks are executed in the zone they have been queued in. For example,
- * the callback of a `future.then` is executed in the same zone as the one where
- * the `then` was invoked.
+ * A zone represents an environment that remains stable across asynchronous
+ * calls.
+ *
+ * Code is always executed in the context of a zone, available as
+ * [Zone.current]. The initial `main` function runs in the context of the
+ * default zone ([Zone.ROOT]). Code can be run in a different zone using either
+ * [runZoned], to create a new zone, or [Zone.run] to run code in the context of
+ * an existing zone likely created using [Zone.fork].
+ *
+ * Developers can create a new zone that overrides some of the functionality of
+ * an existing zone. For example, custom zones can replace of modify the
+ * behavior of `print`, timers, microtasks or how uncaught errors are handled.
+ *
+ * The [Zone] class is not subclassable, but users can provide custom zones by
+ * forking an existing zone (usually [Zone.current]) with a [ZoneSpecification].
+ * This is similar to creating a new class that extends the base `Zone` class
+ * and that overrides some methods, except without actually creating a new
+ * class. Instead the overriding methods are provided as functions that
+ * explicitly take the equivalent of their own class, the "super" class and the
+ * `this` object as parameters.
+ *
+ * Asynchronous callbacks always run in the context of the zone where they were
+ * scheduled. This is implemented using two steps:
+ * 1. the callback is first registered using one of [registerCallback],
+ *   [registerUnaryCallback], or [registerBinaryCallback]. This allows the zone
+ *   to record that a callback exists and potentially modify it (by returning a
+ *   different callback). The code doing the registration (e.g., `Future.then`)
+ *   also remembers the current zone so that it can later run the callback in
+ *   that zone.
+ * 2. At a later point the registered callback is run in the remembered zone.
+ *
+ * This is all handled internally by the platform code and most users don't need
+ * to worry about it. However, developers of new asynchronous operations,
+ * provided by the underlying system or through native extensions, must follow
+ * the protocol to be zone compatible.
+ *
+ * For convenience, zones provide [bindCallback] (and the corresponding
+ * [bindUnaryCallback] or [bindBinaryCallback]) to make it easier to respect the
+ * zone contract: these functions first invoke the corresponding `register`
+ * functions and then wrap the returned function so that it runs in the current
+ * zone when it is later asynchronously invoked.
  */
 abstract class Zone {
   // Private constructor so that it is not possible instantiate a Zone class.
   Zone._();
 
-  /** The root zone that is implicitly created. */
+  /**
+   * The root zone.
+   *
+   * All isolate entry functions (`main` or spawned functions) start running in
+   * the root zone (that is, [Zone.current] is identical to [Zone.ROOT] when the
+   * entry function is called). If no custom zone is created, the rest of the
+   * program always runs in the root zone.
+   *
+   * The root zone implements the default behavior of all zone operations.
+   * Many methods, like [registerCallback] do the bare minimum required of the
+   * function, and are only provided as a hook for custom zones. Others, like
+   * [scheduleMicrotask], interact with the underlying system to implement the
+   * desired behavior.
+   */
   static const Zone ROOT = _ROOT_ZONE;
 
   /** The currently running zone. */
   static Zone _current = _ROOT_ZONE;
 
+  /** The zone that is currently active. */
   static Zone get current => _current;
 
+  /**
+   * Handles uncaught asynchronous errors.
+   *
+   * There are two kind of asynchronous errors that are handled by this
+   * function:
+   * 1. Uncaught errors that were thrown in asynchronous callbacks, for example,
+   *   a `throw` in the function passed to [Timer.run].
+   * 2. Asynchronous errors that are pushed through [Future] and [Stream]
+   *   chains, but for which no child registered an error handler.
+   *   Most asynchronous classes, like [Future] or [Stream] push errors to their
+   *   listeners. Errors are propagated this way until either a listener handles
+   *   the error (for example with [Future.catchError]), or no listener is
+   *   available anymore. In the latter case, futures and streams invoke the
+   *   zone's [handleUncaughtError].
+   *
+   * By default, when handled by the root zone, uncaught asynchronous errors are
+   * treated like uncaught synchronous exceptions.
+   */
   /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace);
 
   /**
-   * Returns the parent zone.
+   * The parent zone of the this zone.
    *
-   * Returns `null` if `this` is the [ROOT] zone.
+   * Is `null` if `this` is the [ROOT] zone.
+   *
+   * Zones are created by [fork] on an existing zone, or by [runZoned] which
+   * forks the [current] zone. The new zone's parent zone is the zone it was
+   * forked from.
    */
   Zone get parent;
 
   /**
    * The error zone is the one that is responsible for dealing with uncaught
    * errors.
-   * Errors are not allowed to cross between zones with different error-zones.
    *
-   * This is the closest parent or ancestor zone of this zone that has a custom
+   * This is the closest parent zone of this zone that provides a
    * [handleUncaughtError] method.
+   *
+   * Asynchronous errors never cross zone boundaries between zones with
+   * different error handlers.
+   *
+   * Example:
+   * ```
+   * import 'dart:async';
+   *
+   * main() {
+   *   var future;
+   *   runZoned(() {
+   *     // The asynchronous error is caught by the custom zone which prints
+   *     // 'asynchronous error'.
+   *     future = new Future.error("asynchronous error");
+   *   }, onError: (e) { print(e); });  // Creates a zone with an error handler.
+   *   // The following `catchError` handler is never invoked, because the
+   *   // custom zone created by the call to `runZoned` provides an
+   *   // error handler.
+   *   future.catchError((e) { throw "is never reached"; });
+   * }
+   * ```
+   *
+   * Note that errors cannot enter a child zone with a different error handler
+   * either:
+   * ```
+   * import 'dart:async';
+   *
+   * main() {
+   *   runZoned(() {
+   *     // The following asynchronous error is *not* caught by the `catchError`
+   *     // in the nested zone, since errors are not to cross zone boundaries
+   *     // with different error handlers.
+   *     // Instead the error is handled by the current error handler,
+   *     // printing "Caught by outer zone: asynchronous error".
+   *     var future = new Future.error("asynchronous error");
+   *     runZoned(() {
+   *       future.catchError((e) { throw "is never reached"; });
+   *     }, onError: (e) { throw "is never reached"; });
+   *   }, onError: (e) { print("Caught by outer zone: $e"); });
+   * }
+   * ```
    */
   Zone get errorZone;
 
   /**
    * Returns true if `this` and [otherZone] are in the same error zone.
    *
-   * Two zones are in the same error zone if they inherit their
-   * [handleUncaughtError] callback from the same [errorZone].
+   * Two zones are in the same error zone if they have the same [errorZone].
    */
   bool inSameErrorZone(Zone otherZone);
 
   /**
    * Creates a new zone as a child of `this`.
    *
-   * The new zone will have behavior like the current zone, except where
-   * overridden by functions in [specification].
+   * The new zone uses the closures in the given [specification] to override
+   * the current's zone behavior. All specification entries that are `null`
+   * inherit the behavior from the parent zone (`this`).
    *
-   * The new zone will have the same stored values (accessed through
-   * `operator []`) as this zone, but updated with the keys and values
-   * in [zoneValues]. If a key is in both this zone's values and in
-   * `zoneValues`, the new zone will use the value from `zoneValues``.
+   * The new zone inherits the stored values (accessed through [operator []])
+   * of this zone and updates them with values from [zoneValues], which either
+   * adds new values or overrides existing ones.
+   *
+   * Note that the fork operation is interceptible. A zone can thus change
+   * the zone specification (or zone values), giving the forking zone full
+   * control over the child zone.
    */
-  Zone fork({ ZoneSpecification specification,
-              Map zoneValues });
+  Zone fork({ZoneSpecification specification,
+             Map zoneValues});
 
   /**
-   * Executes the given function [f] in this zone.
+   * Executes [action] in this zone.
+   *
+   * By default (as implemented in the [ROOT] zone), runs [action]
+   * with [current] set to this zone.
+   *
+   * If [action] throws, the synchronous exception is not caught by the zone's
+   * error handler. Use [runGuarded] to achieve that.
+   *
+   * Since the root zone is the only zone that can modify the value of
+   * [current], custom zones intercepting run should always delegate to their
+   * parent zone. They may take actions before and after the call.
    */
-  /*=R*/ run/*<R>*/(/*=R*/ f());
+  /*=R*/ run/*<R>*/(/*=R*/ action());
 
   /**
-   * Executes the given callback [f] with argument [arg] in this zone.
+   * Executes the given [action] with [argument] in this zone.
+   *
+   * As [run] except that [action] is called with one [argument] instead of
+   * none.
    */
-  /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg);
+  /*=R*/ runUnary/*<R, T>*/(/*=R*/ action(/*=T*/ argument), /*=T*/ argument);
 
   /**
-   * Executes the given callback [f] with argument [arg1] and [arg2] in this
+   * Executes the given [action] with [argument1] and [argument2] in this
    * zone.
+   *
+   * As [run] except that [action] is called with two arguments instead of none.
    */
   /*=R*/ runBinary/*<R, T1, T2>*/(
-      /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
+      /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2), /*=T1*/ argument1,
+      /*=T2*/ argument2);
 
   /**
-   * Executes the given function [f] in this zone.
+   * Executes the given [action] in this zone and catches synchronous
+   * errors.
    *
-   * Same as [run] but catches uncaught errors and gives them to
-   * [handleUncaughtError].
+   * This function is equivalent to:
+   * ```
+   * try {
+   *   return this.run(action);
+   * } catch (e, s) {
+   *   return this.handleUncaughtError(e, s);
+   * }
+   * ```
+   *
+   * See [run].
    */
-  /*=R*/ runGuarded/*<R>*/(/*=R*/ f());
+  /*=R*/ runGuarded/*<R>*/(/*=R*/ action());
 
   /**
-   * Executes the given callback [f] in this zone.
+   * Executes the given [action] with [argument] in this zone and
+   * catches synchronous errors.
    *
-   * Same as [runUnary] but catches uncaught errors and gives them to
-   * [handleUncaughtError].
+   * See [runGuarded].
    */
-  /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg);
+  /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ action(/*=T*/ argument),
+      /*=T*/ argument);
 
   /**
-   * Executes the given callback [f] in this zone.
+   * Executes the given [action] with [argument1] and [argument2] in this
+   * zone and catches synchronous errors.
    *
-   * Same as [runBinary] but catches uncaught errors and gives them to
-   * [handleUncaughtError].
+   * See [runGuarded].
    */
   /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
-      /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
+      /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2), /*=T1*/ argument1,
+      /*=T2*/ argument2);
 
   /**
    * Registers the given callback in this zone.
    *
-   * It is good practice to register asynchronous or delayed callbacks before
-   * invoking [run]. This gives the zone a chance to wrap the callback and
-   * to store information with the callback. For example, a zone may decide
+   * When implementing an asynchronous primitive that uses callbacks, the
+   * callback must be registered using [registerCallback] at the point where the
+   * user provides the callback. This allows zones to record other information
+   * that they need at the same time, perhaps even wrapping the callback, so
+   * that the callback is prepared when it is later run in the same zones
+   * (using [run]). For example, a zone may decide
    * to store the stack trace (at the time of the registration) with the
    * callback.
    *
-   * Returns a potentially new callback that should be used in place of the
-   * given [callback].
+   * Returns the callback that should be used in place of the provided
+   * [callback]. Frequently zones simply return the original callback.
+   *
+   * Custom zones may intercept this operation. The default implementation in
+   * [Zone.ROOT] returns the original callback unchanged.
    */
   ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback());
 
@@ -357,58 +518,79 @@
   /**
    *  Equivalent to:
    *
-   *      ZoneCallback registered = registerCallback(f);
+   *      ZoneCallback registered = this.registerCallback(action);
    *      if (runGuarded) return () => this.runGuarded(registered);
    *      return () => this.run(registered);
    *
    */
   ZoneCallback/*<R>*/ bindCallback/*<R>*/(
-      /*=R*/ f(), { bool runGuarded: true });
+      /*=R*/ action(), { bool runGuarded: true });
 
   /**
    *  Equivalent to:
    *
-   *      ZoneCallback registered = registerUnaryCallback(f);
+   *      ZoneCallback registered = this.registerUnaryCallback(action);
    *      if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg);
    *      return (arg) => thin.runUnary(registered, arg);
    */
   ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
-      /*=R*/ f(/*=T*/ arg), { bool runGuarded: true });
+      /*=R*/ action(/*=T*/ argument), { bool runGuarded: true });
 
   /**
    *  Equivalent to:
    *
-   *      ZoneCallback registered = registerBinaryCallback(f);
+   *      ZoneCallback registered = registerBinaryCallback(action);
    *      if (runGuarded) {
    *        return (arg1, arg2) => this.runBinaryGuarded(registered, arg);
    *      }
    *      return (arg1, arg2) => thin.runBinary(registered, arg1, arg2);
    */
   ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
-      /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true });
+      /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2),
+      { bool runGuarded: true });
 
   /**
-   * Intercepts errors when added programmatically to a `Future` or `Stream`.
+   * Intercepts errors when added programatically to a `Future` or `Stream`.
    *
-   * When caling [Completer.completeError], [Stream.addError],
-   * or [Future] constructors that take an error or a callback that may throw,
-   * the current zone is allowed to intercept and replace the error.
+   * When calling [Completer.completeError], [Stream.addError],
+   * or some [Future] constructors, the current zone is allowed to intercept
+   * and replace the error.
    *
-   * When other libraries use intermediate controllers or completers, such
-   * calls may contain errors that have already been processed.
+   * Future constructors invoke this function when the error is received
+   * directly, for example with [Future.error], or when the error is caught
+   * synchronously, for example with [Future.sync].
    *
-   * Return `null` if no replacement is desired.
-   * The original error is used unchanged in that case.
-   * Otherwise return an instance of [AsyncError] holding
-   * the new pair of error and stack trace.
-   * If the [AsyncError.error] is `null`, it is replaced by a [NullThrownError].
+   * There is no guarantee that an error is only sent through [errorCallback]
+   * once. Libraries that use intermediate controllers or completers might
+   * end up invoking [errorCallback] multiple times.
+   *
+   * Returns `null` if no replacement is desired. Otherwise returns an instance
+   * of [AsyncError] holding the new pair of error and stack trace.
+   *
+   * Although not recommended, the returned instance may have its `error` member
+   * ([AsyncError.error]) be equal to `null` in which case the error should be
+   * replaced by a [NullThrownError].
+   *
+   * Custom zones may intercept this operation.
+   *
+   * Implementations of a new asynchronous primitive that converts synchronous
+   * errors to asynchronous errors rarely need to invoke [errorCallback], since
+   * errors are usually reported through future completers or stream
+   * controllers.
    */
   AsyncError errorCallback(Object error, StackTrace stackTrace);
 
   /**
-   * Runs [f] asynchronously in this zone.
+   * Runs [action] asynchronously in this zone.
+   *
+   * The global `scheduleMicrotask` delegates to the current zone's
+   * [scheduleMicrotask]. The root zone's implementation interacts with the
+   * underlying system to schedule the given callback as a microtask.
+   *
+   * Custom zones may intercept this operation (for example to wrap the given
+   * callback [action]).
    */
-  void scheduleMicrotask(void f());
+  void scheduleMicrotask(void action());
 
   /**
    * Creates a Timer where the callback is executed in this zone.
@@ -422,6 +604,24 @@
 
   /**
    * Prints the given [line].
+   *
+   * The global `print` function delegates to the current zone's [print]
+   * function which makes it possible to intercept printing.
+   *
+   * Example:
+   * ```
+   * import 'dart:async';
+   *
+   * main() {
+   *   runZoned(() {
+   *     // Ends up printing: "Intercepted: in zone".
+   *     print("in zone");
+   *   }, zoneSpecification: new ZoneSpecification(
+   *       print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
+   *     parent.print(zone, "Intercepted: $line");
+   *   }));
+   * }
+   * ```
    */
   void print(String line);
 
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 3e7c1cb..aa9292e 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -181,6 +181,17 @@
    *
    * The returned [Iterable] is lazy, and calls [f] for each element
    * of this every time it's iterated.
+   *
+   * Example:
+   *
+   *     var pairs = [[1, 2], [3, 4]];
+   *     var flattened = pairs.expand((pair) => pair).toList();
+   *     print(flattened); // => [1, 2, 3, 4];
+   *
+   *     var input = [1, 2, 3];
+   *     var duplicated = input.expand((i) => [i, i]).toList();
+   *     print(duplicated); // => [1, 1, 2, 2, 3, 3]
+   *
    */
   Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) =>
       new ExpandIterable<E, dynamic/*=T*/>(this, f);
@@ -208,7 +219,6 @@
     return false;
   }
 
-
   /**
    * Applies the function [f] to each element of this collection in iteration
    * order.
@@ -316,7 +326,6 @@
     return buffer.toString();
   }
 
-
   /**
    * Checks whether any element of this iterable satisfies [test].
    *
@@ -382,7 +391,7 @@
    */
   bool get isNotEmpty => !isEmpty;
 
-   /**
+  /**
    * Returns a lazy iterable of the [count] first elements of this iterable.
    *
    * The returned `Iterable` may contain fewer than `count` elements, if `this`
@@ -480,7 +489,7 @@
     E result;
     do {
       result = it.current;
-    } while(it.moveNext());
+    } while (it.moveNext());
     return result;
   }
 
@@ -506,7 +515,7 @@
    * function is returned.
    * If [orElse] is omitted, it defaults to throwing a [StateError].
    */
-  E firstWhere(bool test(E element), { E orElse() }) {
+  E firstWhere(bool test(E element), {E orElse()}) {
     for (E element in this) {
       if (test(element)) return element;
     }
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 5718ca8..d7f911b 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -4,6 +4,24 @@
 
 part of dart.core;
 
+// Frequently used character codes.
+const int _SPACE = 0x20;
+const int _PERCENT = 0x25;
+const int _PLUS = 0x2B;
+const int _DOT = 0x2E;
+const int _SLASH = 0x2F;
+const int _COLON = 0x3A;
+const int _UPPER_CASE_A = 0x41;
+const int _UPPER_CASE_Z = 0x5A;
+const int _LEFT_BRACKET = 0x5B;
+const int _BACKSLASH = 0x5C;
+const int _RIGHT_BRACKET = 0x5D;
+const int _LOWER_CASE_A = 0x61;
+const int _LOWER_CASE_F = 0x66;
+const int _LOWER_CASE_Z = 0x7A;
+
+const String _hexDigits = "0123456789ABCDEF";
+
 /**
  * A parsed URI, such as a URL.
  *
@@ -15,77 +33,17 @@
  * [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 {
+abstract class Uri {
   /**
-   * The scheme component of the URI.
+   * Returns the natural base URI for the current platform.
    *
-   * Returns the empty string if there is no scheme component.
+   * When running in a browser this is the current URL of the current page
+   * (from `window.location.href`).
    *
-   * A URI scheme is case insensitive.
-   * The returned scheme is canonicalized to lowercase letters.
+   * When not running in a browser this is the file URI referencing
+   * the current working directory.
    */
-  // We represent the missing scheme as an empty string.
-  // A valid scheme cannot be empty.
-  final String scheme;
-
-  /**
-   * The user-info part of the authority.
-   *
-   * Does not distinguish between an empty user-info and an absent one.
-   * The value is always non-null.
-   * Is considered absent if [_host] is `null`.
-   */
-  final String _userInfo;
-
-  /**
-   * The host name of the URI.
-   *
-   * Set to `null` if there is no authority in the URI.
-   * The host name is the only mandatory part of an authority, so we use
-   * it to mark whether an authority part was present or not.
-   */
-  final String _host;
-
-  /**
-   * The port number part of the authority.
-   *
-   * The port. Set to null if there is no port. Normalized to null if
-   * the port is the default port for the scheme.
-   */
-  int _port;
-
-  /**
-   * The path of the URI.
-   *
-   * Always non-null.
-   */
-  String _path;
-
-  // The query content, or null if there is no query.
-  final String _query;
-
-  // The fragment content, or null if there is no fragment.
-  final String _fragment;
-
-  /**
-   * Cache the computed return value of [pathSegements].
-   */
-  List<String> _pathSegments;
-
-  /**
-   * Cache the computed return value of [queryParameters].
-   */
-  Map<String, String> _queryParameters;
-  Map<String, List<String>> _queryParameterLists;
-
-  /// Internal non-verifying constructor. Only call with validated arguments.
-  Uri._internal(this.scheme,
-                this._userInfo,
-                this._host,
-                this._port,
-                this._path,
-                this._query,
-                this._fragment);
+  external static Uri get base;
 
   /**
    * Creates a new URI from its components.
@@ -158,39 +116,15 @@
    * general delimiters, are escaped if necessary.
    * If `fragment` is omitted or `null`, the URI has no fragment part.
    */
-  factory Uri({String scheme : "",
-               String userInfo : "",
+  factory Uri({String scheme,
+               String userInfo,
                String host,
                int port,
                String path,
                Iterable<String> pathSegments,
                String query,
                Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
-               String fragment}) {
-    scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme));
-    userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
-    host = _makeHost(host, 0, _stringOrNullLength(host), false);
-    // Special case this constructor for backwards compatibility.
-    if (query == "") query = null;
-    query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
-    fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment));
-    port = _makePort(port, scheme);
-    bool isFile = (scheme == "file");
-    if (host == null &&
-        (userInfo.isNotEmpty || port != null || isFile)) {
-      host = "";
-    }
-    bool hasAuthority = (host != null);
-    path = _makePath(path, 0, _stringOrNullLength(path), pathSegments,
-                     scheme, hasAuthority);
-    if (scheme.isEmpty && host == null && !path.startsWith('/')) {
-      path = _normalizeRelativePath(path);
-    } else {
-      path = _removeDotSegments(path);
-    }
-    return new Uri._internal(scheme, userInfo, host, port,
-                             path, query, fragment);
-  }
+               String fragment}) = _Uri;
 
   /**
    * Creates a new `http` URI from authority, path and query.
@@ -227,9 +161,7 @@
    */
   factory Uri.http(String authority,
                    String unencodedPath,
-                   [Map<String, String> queryParameters]) {
-    return _makeHttpUri("http", authority, unencodedPath, queryParameters);
-  }
+                   [Map<String, String> queryParameters]) = _Uri.http;
 
   /**
    * Creates a new `https` URI from authority, path and query.
@@ -239,424 +171,7 @@
    */
   factory Uri.https(String authority,
                     String unencodedPath,
-                    [Map<String, String> queryParameters]) {
-    return _makeHttpUri("https", authority, unencodedPath, queryParameters);
-  }
-
-  /**
-   * Returns the authority component.
-   *
-   * The authority is formatted from the [userInfo], [host] and [port]
-   * parts.
-   *
-   * Returns the empty string if there is no authority component.
-   */
-  String get authority {
-    if (!hasAuthority) return "";
-    var sb = new StringBuffer();
-    _writeAuthority(sb);
-    return sb.toString();
-  }
-
-  /**
-   * Returns the user info part of the authority component.
-   *
-   * Returns the empty string if there is no user info in the
-   * authority component.
-   */
-  String get userInfo => _userInfo;
-
-  /**
-   * Returns the host part of the authority component.
-   *
-   * Returns the empty string if there is no authority component and
-   * hence no host.
-   *
-   * If the host is an IP version 6 address, the surrounding `[` and `]` is
-   * removed.
-   *
-   * The host string is case-insensitive.
-   * The returned host name is canonicalized to lower-case
-   * with upper-case percent-escapes.
-   */
-  String get host {
-    if (_host == null) return "";
-    if (_host.startsWith('[')) {
-      return _host.substring(1, _host.length - 1);
-    }
-    return _host;
-  }
-
-  /**
-   * Returns the port part of the authority component.
-   *
-   * Returns the defualt port if there is no port number in the authority
-   * component. That's 80 for http, 443 for https, and 0 for everything else.
-   */
-  int get port {
-    if (_port == null) return _defaultPort(scheme);
-    return _port;
-  }
-
-  // The default port for the scheme of this Uri..
-  static int _defaultPort(String scheme) {
-    if (scheme == "http") return 80;
-    if (scheme == "https") return 443;
-    return 0;
-  }
-
-  /**
-   * Returns the path component.
-   *
-   * The returned path is encoded. To get direct access to the decoded
-   * path use [pathSegments].
-   *
-   * Returns the empty string if there is no path component.
-   */
-  String get path => _path;
-
-  /**
-   * Returns the query component. The returned query is encoded. To get
-   * direct access to the decoded query use [queryParameters].
-   *
-   * Returns the empty string if there is no query component.
-   */
-  String get query => (_query == null) ? "" : _query;
-
-  /**
-   * Returns the fragment identifier component.
-   *
-   * Returns the empty string if there is no fragment identifier
-   * component.
-   */
-  String get fragment => (_fragment == null) ? "" : _fragment;
-
-  /**
-   * Creates a new `Uri` object by parsing a URI string.
-   *
-   * If [start] and [end] are provided, only the substring from `start`
-   * to `end` is parsed as a URI.
-   *
-   * If the string is not valid as a URI or URI reference,
-   * a [FormatException] is thrown.
-   */
-  static Uri parse(String uri, [int start = 0, int end]) {
-    // This parsing will not validate percent-encoding, IPv6, etc.
-    // When done splitting into parts, it will call, e.g., [_makeFragment]
-    // to do the final parsing.
-    //
-    // Important parts of the RFC 3986 used here:
-    // URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
-    //
-    // hier-part     = "//" authority path-abempty
-    //               / path-absolute
-    //               / path-rootless
-    //               / path-empty
-    //
-    // URI-reference = URI / relative-ref
-    //
-    // absolute-URI  = scheme ":" hier-part [ "?" query ]
-    //
-    // relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
-    //
-    // relative-part = "//" authority path-abempty
-    //               / path-absolute
-    //               / path-noscheme
-    //               / path-empty
-    //
-    // scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-    //
-    // authority     = [ userinfo "@" ] host [ ":" port ]
-    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
-    // host          = IP-literal / IPv4address / reg-name
-    // port          = *DIGIT
-    // reg-name      = *( unreserved / pct-encoded / sub-delims )
-    //
-    // path          = path-abempty    ; begins with "/" or is empty
-    //               / path-absolute   ; begins with "/" but not "//"
-    //               / path-noscheme   ; begins with a non-colon segment
-    //               / path-rootless   ; begins with a segment
-    //               / path-empty      ; zero characters
-    //
-    // path-abempty  = *( "/" segment )
-    // path-absolute = "/" [ segment-nz *( "/" segment ) ]
-    // path-noscheme = segment-nz-nc *( "/" segment )
-    // path-rootless = segment-nz *( "/" segment )
-    // path-empty    = 0<pchar>
-    //
-    // segment       = *pchar
-    // segment-nz    = 1*pchar
-    // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
-    //               ; non-zero-length segment without any colon ":"
-    //
-    // pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
-    //
-    // query         = *( pchar / "/" / "?" )
-    //
-    // fragment      = *( pchar / "/" / "?" )
-    const int EOI = -1;
-
-    String scheme = "";
-    String userinfo = "";
-    String host = null;
-    int port = null;
-    String path = null;
-    String query = null;
-    String fragment = null;
-    if (end == null) end = uri.length;
-
-    int index = start;
-    int pathStart = start;
-    // End of input-marker.
-    int char = EOI;
-
-    void parseAuth() {
-      if (index == end) {
-        char = EOI;
-        return;
-      }
-      int authStart = index;
-      int lastColon = -1;
-      int lastAt = -1;
-      char = uri.codeUnitAt(index);
-      while (index < end) {
-        char = uri.codeUnitAt(index);
-        if (char == _SLASH || char == _QUESTION || char == _NUMBER_SIGN) {
-          break;
-        }
-        if (char == _AT_SIGN) {
-          lastAt = index;
-          lastColon = -1;
-        } else if (char == _COLON) {
-          lastColon = index;
-        } else if (char == _LEFT_BRACKET) {
-          lastColon = -1;
-          int endBracket = uri.indexOf(']', index + 1);
-          if (endBracket == -1) {
-            index = end;
-            char = EOI;
-            break;
-          } else {
-            index = endBracket;
-          }
-        }
-        index++;
-        char = EOI;
-      }
-      int hostStart = authStart;
-      int hostEnd = index;
-      if (lastAt >= 0) {
-        userinfo = _makeUserInfo(uri, authStart, lastAt);
-        hostStart = lastAt + 1;
-      }
-      if (lastColon >= 0) {
-        int portNumber;
-        if (lastColon + 1 < index) {
-          portNumber = 0;
-          for (int i = lastColon + 1; i < index; i++) {
-            int digit = uri.codeUnitAt(i);
-            if (_ZERO > digit || _NINE < digit) {
-              _fail(uri, i, "Invalid port number");
-            }
-            portNumber = portNumber * 10 + (digit - _ZERO);
-          }
-        }
-        port = _makePort(portNumber, scheme);
-        hostEnd = lastColon;
-      }
-      host = _makeHost(uri, hostStart, hostEnd, true);
-      if (index < end) {
-        char = uri.codeUnitAt(index);
-      }
-    }
-
-    // When reaching path parsing, the current character is known to not
-    // be part of the path.
-    const int NOT_IN_PATH = 0;
-    // When reaching path parsing, the current character is part
-    // of the a non-empty path.
-    const int IN_PATH = 1;
-    // When reaching authority parsing, authority is possible.
-    // This is only true at start or right after scheme.
-    const int ALLOW_AUTH = 2;
-
-    // Current state.
-    // Initialized to the default value that is used when exiting the
-    // scheme loop by reaching the end of input.
-    // All other breaks set their own state.
-    int state = NOT_IN_PATH;
-    int i = index;  // Temporary alias for index to avoid bug 19550 in dart2js.
-    while (i < end) {
-      char = uri.codeUnitAt(i);
-      if (char == _QUESTION || char == _NUMBER_SIGN) {
-        state = NOT_IN_PATH;
-        break;
-      }
-      if (char == _SLASH) {
-        state = (i == start) ? ALLOW_AUTH : IN_PATH;
-        break;
-      }
-      if (char == _COLON) {
-        if (i == start) _fail(uri, start, "Invalid empty scheme");
-        scheme = _makeScheme(uri, start, i);
-        i++;
-        if (scheme == "data") {
-          // This generates a URI that is (potentially) not path normalized.
-          // Applying part normalization to a non-hierarchial URI isn't
-          // meaningful.
-          return UriData._parse(uri, i, null).uri;
-        }
-        pathStart = i;
-        if (i == end) {
-          char = EOI;
-          state = NOT_IN_PATH;
-        } else {
-          char = uri.codeUnitAt(i);
-          if (char == _QUESTION || char == _NUMBER_SIGN) {
-            state = NOT_IN_PATH;
-          } else if (char == _SLASH) {
-            state = ALLOW_AUTH;
-          } else {
-            state = IN_PATH;
-          }
-        }
-        break;
-      }
-      i++;
-      char = EOI;
-    }
-    index = i;  // Remove alias when bug is fixed.
-
-    if (state == ALLOW_AUTH) {
-      assert(char == _SLASH);
-      // Have seen one slash either at start or right after scheme.
-      // If two slashes, it's an authority, otherwise it's just the path.
-      index++;
-      if (index == end) {
-        char = EOI;
-        state = NOT_IN_PATH;
-      } else {
-        char = uri.codeUnitAt(index);
-        if (char == _SLASH) {
-          index++;
-          parseAuth();
-          pathStart = index;
-        }
-        if (char == _QUESTION || char == _NUMBER_SIGN || char == EOI) {
-          state = NOT_IN_PATH;
-        } else {
-          state = IN_PATH;
-        }
-      }
-    }
-
-    assert(state == IN_PATH || state == NOT_IN_PATH);
-    if (state == IN_PATH) {
-      // Characters from pathStart to index (inclusive) are known
-      // to be part of the path.
-      while (++index < end) {
-        char = uri.codeUnitAt(index);
-        if (char == _QUESTION || char == _NUMBER_SIGN) {
-          break;
-        }
-        char = EOI;
-      }
-      state = NOT_IN_PATH;
-    }
-
-    assert(state == NOT_IN_PATH);
-    bool hasAuthority = (host != null);
-    path = _makePath(uri, pathStart, index, null, scheme, hasAuthority);
-
-    if (char == _QUESTION) {
-      int numberSignIndex = -1;
-      for (int i = index + 1; i < end; i++) {
-        if (uri.codeUnitAt(i) == _NUMBER_SIGN) {
-          numberSignIndex = i;
-          break;
-        }
-      }
-      if (numberSignIndex < 0) {
-        query = _makeQuery(uri, index + 1, end, null);
-      } else {
-        query = _makeQuery(uri, index + 1, numberSignIndex, null);
-        fragment = _makeFragment(uri, numberSignIndex + 1, end);
-      }
-    } else if (char == _NUMBER_SIGN) {
-      fragment = _makeFragment(uri, index + 1, end);
-    }
-    return new Uri._internal(scheme,
-                             userinfo,
-                             host,
-                             port,
-                             path,
-                             query,
-                             fragment);
-  }
-
-  // Report a parse failure.
-  static void _fail(String uri, int index, String message) {
-    throw new FormatException(message, uri, index);
-  }
-
-  static Uri _makeHttpUri(String scheme,
-                          String authority,
-                          String unencodedPath,
-                          Map<String, String> queryParameters) {
-    var userInfo = "";
-    var host = null;
-    var port = null;
-
-    if (authority != null && authority.isNotEmpty) {
-      var hostStart = 0;
-      // Split off the user info.
-      bool hasUserInfo = false;
-      for (int i = 0; i < authority.length; i++) {
-        if (authority.codeUnitAt(i) == _AT_SIGN) {
-          hasUserInfo = true;
-          userInfo = authority.substring(0, i);
-          hostStart = i + 1;
-          break;
-        }
-      }
-      var hostEnd = hostStart;
-      if (hostStart < authority.length &&
-          authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
-        // IPv6 host.
-        for (; hostEnd < authority.length; hostEnd++) {
-          if (authority.codeUnitAt(hostEnd) == _RIGHT_BRACKET) break;
-        }
-        if (hostEnd == authority.length) {
-          throw new FormatException("Invalid IPv6 host entry.",
-                                    authority, hostStart);
-        }
-        parseIPv6Address(authority, hostStart + 1, hostEnd);
-        hostEnd++;  // Skip the closing bracket.
-        if (hostEnd != authority.length &&
-            authority.codeUnitAt(hostEnd) != _COLON) {
-          throw new FormatException("Invalid end of authority",
-                                    authority, hostEnd);
-        }
-      }
-      // Split host and port.
-      bool hasPort = false;
-      for (; hostEnd < authority.length; hostEnd++) {
-        if (authority.codeUnitAt(hostEnd) == _COLON) {
-          var portString = authority.substring(hostEnd + 1);
-          // We allow the empty port - falling back to initial value.
-          if (portString.isNotEmpty) port = int.parse(portString);
-          break;
-        }
-      }
-      host = authority.substring(hostStart, hostEnd);
-    }
-    return new Uri(scheme: scheme,
-                   userInfo: userInfo,
-                   host: host,
-                   port: port,
-                   pathSegments: unencodedPath.split("/"),
-                   queryParameters: queryParameters);
-  }
+                    [Map<String, String> queryParameters]) = _Uri.https;
 
   /**
    * Creates a new file URI from an absolute or relative file path.
@@ -669,9 +184,9 @@
    * With non-Windows semantics the slash ("/") is used to separate
    * path segments.
    *
-   * With Windows semantics, backslash ("\") and forward-slash ("/")
+   * With Windows semantics, backslash ("\\") and forward-slash ("/")
    * are used to separate path segments, except if the path starts
-   * with "\\?\" in which case, only backslash ("\") separates path
+   * with "\\\\?\\" in which case, only backslash ("\\") separates path
    * segments.
    *
    * If the path starts with a path separator an absolute URI is
@@ -739,11 +254,7 @@
    *
    * If the path passed is not a legal file path [ArgumentError] is thrown.
    */
-  factory Uri.file(String path, {bool windows}) {
-    windows = (windows == null) ? Uri._isWindows : windows;
-    return windows ? _makeWindowsFileUrl(path, false)
-                   : _makeFileUri(path, false);
-  }
+  factory Uri.file(String path, {bool windows}) = _Uri.file;
 
   /**
    * Like [Uri.file] except that a non-empty URI path ends in a slash.
@@ -752,11 +263,7 @@
    * then a slash is added to the returned URI's path.
    * In all other cases, the result is the same as returned by `Uri.file`.
    */
-  factory Uri.directory(String path, {bool windows}) {
-    windows = (windows == null) ? Uri._isWindows : windows;
-    return windows ? _makeWindowsFileUrl(path, true)
-                   : _makeFileUri(path, true);
-  }
+  factory Uri.directory(String path, {bool windows}) = _Uri.directory;
 
   /**
    * Creates a `data:` URI containing the [content] string.
@@ -827,16 +334,1280 @@
   }
 
   /**
-   * Returns the natural base URI for the current platform.
+   * The scheme component of the URI.
    *
-   * When running in a browser this is the current URL (from
-   * `window.location.href`).
+   * Returns the empty string if there is no scheme component.
    *
-   * When not running in a browser this is the file URI referencing
-   * the current working directory.
+   * A URI scheme is case insensitive.
+   * The returned scheme is canonicalized to lowercase letters.
    */
-  external static Uri get base;
+  String get scheme;
 
+  /**
+   * Returns the authority component.
+   *
+   * The authority is formatted from the [userInfo], [host] and [port]
+   * parts.
+   *
+   * Returns the empty string if there is no authority component.
+   */
+  String get authority;
+
+  /**
+   * Returns the user info part of the authority component.
+   *
+   * Returns the empty string if there is no user info in the
+   * authority component.
+   */
+  String get userInfo;
+
+  /**
+   * Returns the host part of the authority component.
+   *
+   * Returns the empty string if there is no authority component and
+   * hence no host.
+   *
+   * If the host is an IP version 6 address, the surrounding `[` and `]` is
+   * removed.
+   *
+   * The host string is case-insensitive.
+   * The returned host name is canonicalized to lower-case
+   * with upper-case percent-escapes.
+   */
+  String get host;
+
+  /**
+   * Returns the port part of the authority component.
+   *
+   * Returns the defualt port if there is no port number in the authority
+   * component. That's 80 for http, 443 for https, and 0 for everything else.
+   */
+  int get port;
+
+  /**
+   * Returns the path component.
+   *
+   * The returned path is encoded. To get direct access to the decoded
+   * path use [pathSegments].
+   *
+   * Returns the empty string if there is no path component.
+   */
+  String get path;
+
+  /**
+   * Returns the query component. The returned query is encoded. To get
+   * direct access to the decoded query use [queryParameters].
+   *
+   * Returns the empty string if there is no query component.
+   */
+  String get query;
+
+  /**
+   * Returns the fragment identifier component.
+   *
+   * Returns the empty string if there is no fragment identifier
+   * component.
+   */
+  String get fragment;
+
+  /**
+   * 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;
+
+  /**
+   * 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.
+   *
+   * Keys in the query string that have no value are mapped to the
+   * empty string.
+   * If a key occurs more than once in the query string, it is mapped to
+   * an arbitrary choice of possible value.
+   * The [queryParametersAll] getter can provide a map
+   * that maps keys to all of their values.
+   *
+   * The returned map is unmodifiable.
+   */
+  Map<String, String> get queryParameters;
+
+  /**
+   * 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.
+   *
+   * Keys are mapped to lists of their values. If a key occurs only once,
+   * its value is a singleton list. If a key occurs with no value, the
+   * empty string is used as the value for that occurrence.
+   *
+   * The returned map and the lists it contains are unmodifiable.
+   */
+  Map<String, List<String>> get queryParametersAll;
+
+  /**
+   * Returns whether the URI is absolute.
+   *
+   * A URI is an absolute URI in the sense of RFC 3986 if it has a scheme
+   * and no fragment.
+   */
+  bool get isAbsolute;
+
+  /**
+   * Returns whether the URI has a [scheme] component.
+   */
+  bool get hasScheme => scheme.isNotEmpty;
+
+  /**
+   * Returns whether the URI has an [authority] component.
+   */
+  bool get hasAuthority;
+
+  /**
+   * Returns whether the URI has an explicit port.
+   *
+   * If the port number is the default port number
+   * (zero for unrecognized schemes, with http (80) and https (443) being
+   * recognized),
+   * then the port is made implicit and omitted from the URI.
+   */
+  bool get hasPort;
+
+  /**
+   * Returns whether the URI has a query part.
+   */
+  bool get hasQuery;
+
+  /**
+   * Returns whether the URI has a fragment part.
+   */
+  bool get hasFragment;
+
+  /**
+   * Returns whether the URI has an empty path.
+   */
+  bool get hasEmptyPath;
+
+  /**
+   * Returns whether the URI has an absolute path (starting with '/').
+   */
+  bool get hasAbsolutePath;
+
+  /**
+   * Returns the origin of the URI in the form scheme://host:port for the
+   * schemes http and https.
+   *
+   * It is an error if the scheme is not "http" or "https".
+   *
+   * See: http://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin
+   */
+  String get origin;
+
+  /**
+   * Returns the file path from a file URI.
+   *
+   * The returned path has either Windows or non-Windows
+   * semantics.
+   *
+   * For non-Windows semantics the slash ("/") is used to separate
+   * path segments.
+   *
+   * For Windows semantics the backslash ("\\") separator is used to
+   * separate path segments.
+   *
+   * If the URI is absolute the path starts with a path separator
+   * unless Windows semantics is used and the first path segment is a
+   * drive letter. When Windows semantics is used a host component in
+   * the uri in interpreted as a file server and a UNC path is
+   * returned.
+   *
+   * The default for whether to use Windows or non-Windows semantics
+   * determined from the platform Dart is running on. When running in
+   * the standalone VM this is detected by the VM based on the
+   * operating system. When running in a browser non-Windows semantics
+   * is always used.
+   *
+   * To override the automatic detection of which semantics to use pass
+   * a value for [windows]. Passing `true` will use Windows
+   * semantics and passing `false` will use non-Windows semantics.
+   *
+   * If the URI ends with a slash (i.e. the last path component is
+   * empty) the returned file path will also end with a slash.
+   *
+   * With Windows semantics URIs starting with a drive letter cannot
+   * be relative to the current drive on the designated drive. That is
+   * for the URI `file:///c:abc` calling `toFilePath` will throw as a
+   * path segment cannot contain colon on Windows.
+   *
+   * Examples using non-Windows semantics (resulting of calling
+   * toFilePath in comment):
+   *
+   *     Uri.parse("xxx/yyy");  // xxx/yyy
+   *     Uri.parse("xxx/yyy/");  // xxx/yyy/
+   *     Uri.parse("file:///xxx/yyy");  // /xxx/yyy
+   *     Uri.parse("file:///xxx/yyy/");  // /xxx/yyy/
+   *     Uri.parse("file:///C:");  // /C:
+   *     Uri.parse("file:///C:a");  // /C:a
+   *
+   * Examples using Windows semantics (resulting URI in comment):
+   *
+   *     Uri.parse("xxx/yyy");  // xxx\yyy
+   *     Uri.parse("xxx/yyy/");  // xxx\yyy\
+   *     Uri.parse("file:///xxx/yyy");  // \xxx\yyy
+   *     Uri.parse("file:///xxx/yyy/");  // \xxx\yyy/
+   *     Uri.parse("file:///C:/xxx/yyy");  // C:\xxx\yyy
+   *     Uri.parse("file:C:xxx/yyy");  // Throws as a path segment
+   *                                   // cannot contain colon on Windows.
+   *     Uri.parse("file://server/share/file");  // \\server\share\file
+   *
+   * If the URI is not a file URI calling this throws
+   * [UnsupportedError].
+   *
+   * If the URI cannot be converted to a file path calling this throws
+   * [UnsupportedError].
+   */
+  // TODO(lrn): Deprecate and move functionality to File class or similar.
+  // The core libraries should not worry about the platform.
+  String toFilePath({bool windows});
+
+  /**
+   * 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;
+
+  /// Returns a hash code computed as `toString().hashCode`.
+  ///
+  /// This guarantees that URIs with the same normalized
+  int get hashCode;
+
+  /// A URI is equal to another URI with the same normalized representation.
+  bool operator==(Object other);
+
+  /// Returns the normalized string representation of the URI.
+  String toString();
+
+  /**
+   * Returns a new `Uri` based on this one, but with some parts replaced.
+   *
+   * This method takes the same parameters as the [new Uri] constructor,
+   * and they have the same meaning.
+   *
+   * At most one of [path] and [pathSegments] must be provided.
+   * Likewise, at most one of [query] and [queryParameters] must be provided.
+   *
+   * Each part that is not provided will default to the corresponding
+   * value from this `Uri` instead.
+   *
+   * This method is different from [Uri.resolve] which overrides in a
+   * hierarchial manner,
+   * and can instead replace each part of a `Uri` individually.
+   *
+   * Example:
+   *
+   *     Uri uri1 = Uri.parse("a://b@c:4/d/e?f#g");
+   *     Uri uri2 = uri1.replace(scheme: "A", path: "D/E/E", fragment: "G");
+   *     print(uri2);  // prints "A://b@c:4/D/E/E/?f#G"
+   *
+   * This method acts similarly to using the `new Uri` constructor with
+   * some of the arguments taken from this `Uri` . Example:
+   *
+   *     Uri uri3 = new Uri(
+   *         scheme: "A",
+   *         userInfo: uri1.userInfo,
+   *         host: uri1.host,
+   *         port: uri1.port,
+   *         path: "D/E/E",
+   *         query: uri1.query,
+   *         fragment: "G");
+   *     print(uri3);  // prints "A://b@c:4/D/E/E/?f#G"
+   *     print(uri2 == uri3);  // prints true.
+   *
+   * Using this method can be seen as a shorthand for the `Uri` constructor
+   * call above, but may also be slightly faster because the parts taken
+   * from this `Uri` need not be checked for validity again.
+   */
+  Uri replace({String scheme,
+               String userInfo,
+               String host,
+               int port,
+               String path,
+               Iterable<String> pathSegments,
+               String query,
+               Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
+               String fragment});
+
+  /**
+   * Returns a `Uri` that differs from this only in not having a fragment.
+   *
+   * If this `Uri` does not have a fragment, it is itself returned.
+   */
+  Uri removeFragment();
+
+  /**
+   * Resolve [reference] as an URI relative to `this`.
+   *
+   * First turn [reference] into a URI using [Uri.parse]. Then resolve the
+   * resulting URI relative to `this`.
+   *
+   * Returns the resolved URI.
+   *
+   * See [resolveUri] for details.
+   */
+  Uri resolve(String reference);
+
+  /**
+   * Resolve [reference] as an URI relative to `this`.
+   *
+   * 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").
+   *
+   * 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
+   * with a slash.
+   * In that case, the paths are combined without removing leading "..", and
+   * an empty path is not converted to "/".
+   */
+  Uri resolveUri(Uri reference);
+
+  /**
+   * Returns a URI where the path has been normalized.
+   *
+   * A normalized path does not contain `.` segments or non-leading `..`
+   * segments.
+   * Only a relative path with no scheme or authority may contain
+   * leading `..` segments,
+   * a path that starts with `/` will also drop any leading `..` segments.
+   *
+   * This uses the same normalization strategy as `new Uri().resolve(this)`.
+   *
+   * Does not change any part of the URI except the path.
+   *
+   * The default implementation of `Uri` always normalizes paths, so calling
+   * this function has no effect.
+   */
+  Uri normalizePath();
+
+  /**
+   * Creates a new `Uri` object by parsing a URI string.
+   *
+   * If [start] and [end] are provided, only the substring from `start`
+   * to `end` is parsed as a URI.
+   *
+   * If the string is not valid as a URI or URI reference,
+   * a [FormatException] is thrown.
+   */
+  static Uri parse(String uri, [int start = 0, int end]) {
+    // This parsing will not validate percent-encoding, IPv6, etc.
+    // When done splitting into parts, it will call, e.g., [_makeFragment]
+    // to do the final parsing.
+    //
+    // Important parts of the RFC 3986 used here:
+    // URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+    //
+    // hier-part     = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-rootless
+    //               / path-empty
+    //
+    // URI-reference = URI / relative-ref
+    //
+    // absolute-URI  = scheme ":" hier-part [ "?" query ]
+    //
+    // relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
+    //
+    // relative-part = "//" authority path-abempty
+    //               / path-absolute
+    //               / path-noscheme
+    //               / path-empty
+    //
+    // scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+    //
+    // authority     = [ userinfo "@" ] host [ ":" port ]
+    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
+    // host          = IP-literal / IPv4address / reg-name
+    // port          = *DIGIT
+    // reg-name      = *( unreserved / pct-encoded / sub-delims )
+    //
+    // path          = path-abempty    ; begins with "/" or is empty
+    //               / path-absolute   ; begins with "/" but not "//"
+    //               / path-noscheme   ; begins with a non-colon segment
+    //               / path-rootless   ; begins with a segment
+    //               / path-empty      ; zero characters
+    //
+    // path-abempty  = *( "/" segment )
+    // path-absolute = "/" [ segment-nz *( "/" segment ) ]
+    // path-noscheme = segment-nz-nc *( "/" segment )
+    // path-rootless = segment-nz *( "/" segment )
+    // path-empty    = 0<pchar>
+    //
+    // segment       = *pchar
+    // segment-nz    = 1*pchar
+    // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
+    //               ; non-zero-length segment without any colon ":"
+    //
+    // pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
+    //
+    // query         = *( pchar / "/" / "?" )
+    //
+    // fragment      = *( pchar / "/" / "?" )
+    end ??= uri.length;
+
+    // Special case data:URIs. Ignore case when testing.
+    if (end >= start + 5) {
+      int dataDelta = _startsWithData(uri, start);
+      if (dataDelta == 0) {
+        // The case is right.
+        if (start > 0 || end < uri.length) uri = uri.substring(start, end);
+        return UriData._parse(uri, 5, null).uri;
+      } else if (dataDelta == 0x20) {
+        return UriData._parse(uri.substring(start + 5, end), 0, null).uri;
+      }
+      // Otherwise the URI doesn't start with "data:" or any case variant of it.
+    }
+
+    // The following index-normalization belongs with the scanning, but is
+    // easier to do here because we already have extracted variables from the
+    // indices list.
+    var indices = new List<int>(8);//new List<int>.filled(8, start - 1);
+
+    // Set default values for each position.
+    // The value will either be correct in some cases where it isn't set
+    // by the scanner, or it is clearly recognizable as an unset value.
+    indices
+      ..[0] = 0
+      ..[_schemeEndIndex] = start - 1
+      ..[_hostStartIndex] = start - 1
+      ..[_notSimpleIndex] = start - 1
+      ..[_portStartIndex] = start
+      ..[_pathStartIndex] = start
+      ..[_queryStartIndex] = end
+      ..[_fragmentStartIndex] = end;
+    var state = _scan(uri, start, end, _uriStart, indices);
+    // Some states that should be non-simple, but the URI ended early.
+    // Paths that end at a ".." must be normalized to end in "../".
+    if (state >= _nonSimpleEndStates) {
+      indices[_notSimpleIndex] = end;
+    }
+    int schemeEnd = indices[_schemeEndIndex];
+    if (schemeEnd >= start) {
+      // Rescan the scheme part now that we know it's not a path.
+      state = _scan(uri, start, schemeEnd, _schemeStart, indices);
+      if (state == _schemeStart) {
+        // Empty scheme.
+        indices[_notSimpleIndex] = schemeEnd;
+      }
+    }
+    // The returned positions are limited by the scanners ability to write only
+    // one position per character, and only the current position.
+    // Scanning from left to right, we only know whether something is a scheme
+    // or a path when we see a `:` or `/`, and likewise we only know if the first
+    // `/` is part of the path or is leading an authority component when we see
+    // the next character.
+
+    int hostStart     = indices[_hostStartIndex] + 1;
+    int portStart     = indices[_portStartIndex];
+    int pathStart     = indices[_pathStartIndex];
+    int queryStart    = indices[_queryStartIndex];
+    int fragmentStart = indices[_fragmentStartIndex];
+
+    // We may discover scheme while handling special cases.
+    String scheme;
+
+    // Derive some positions that weren't set to normalize the indices.
+    // If pathStart isn't set (it's before scheme end or host start), then
+    // the path is empty.
+    if (fragmentStart < queryStart) queryStart = fragmentStart;
+    if (pathStart < hostStart || pathStart <= schemeEnd) {
+      pathStart = queryStart;
+    }
+    // If there is an authority with no port, set the port position
+    // to be at the end of the authority (equal to pathStart).
+    // This also handles a ":" in a user-info component incorrectly setting
+    // the port start position.
+    if (portStart < hostStart) portStart = pathStart;
+
+    assert(hostStart == start || schemeEnd <= hostStart);
+    assert(hostStart <= portStart);
+    assert(schemeEnd <= pathStart);
+    assert(portStart <= pathStart);
+    assert(pathStart <= queryStart);
+    assert(queryStart <= fragmentStart);
+
+    bool isSimple = indices[_notSimpleIndex] < start;
+
+    if (isSimple) {
+      // Check/do normalizations that weren't detected by the scanner.
+      // This includes removal of empty port or userInfo,
+      // or scheme specific port and path normalizations.
+      if (hostStart > schemeEnd + 3) {
+        // Always be non-simple if URI contains user-info.
+        // The scanner doesn't set the not-simple position in this case because
+        // it's setting the host-start position instead.
+        isSimple = false;
+      } else if (portStart > start && portStart + 1 == pathStart) {
+        // If the port is empty, it should be omitted.
+        // Pathological case, don't bother correcting it.
+        isSimple = false;
+      } else if (queryStart < end &&
+                 (queryStart == pathStart + 2 &&
+                  uri.startsWith("..", pathStart)) ||
+                 (queryStart > pathStart + 2 &&
+                  uri.startsWith("/..", queryStart - 3))) {
+        // The path ends in a ".." segment. This should be normalized to "../".
+        // We didn't detect this while scanning because a query or fragment was
+        // detected at the same time (which is why we only need to check this
+        // if there is something after the path).
+        isSimple = false;
+      } else {
+        // There are a few scheme-based normalizations that
+        // the scanner couldn't check.
+        // That means that the input is very close to simple, so just do
+        // the normalizations.
+        if (schemeEnd == start + 4) {
+          // Do scheme based normalizations for file, http.
+          if (uri.startsWith("file", start)) {
+            scheme = "file";
+            if (hostStart <= start) {
+              // File URIs should have an authority.
+              // Paths after an authority should be absolute.
+              String schemeAuth = "file://";
+              int delta = 2;
+              if (!uri.startsWith("/", pathStart)) {
+                schemeAuth = "file:///";
+                delta = 3;
+              }
+              uri = schemeAuth + uri.substring(pathStart, end);
+              schemeEnd -= start;
+              hostStart = 7;
+              portStart = 7;
+              pathStart = 7;
+              queryStart += delta - start;
+              fragmentStart += delta - start;
+              start = 0;
+              end = uri.length;
+            } else if (pathStart == queryStart) {
+              // Uri has authority and empty path. Add "/" as path.
+              if (start == 0 && end == uri.length) {
+                uri = uri.replaceRange(pathStart, queryStart, "/");
+                queryStart += 1;
+                fragmentStart += 1;
+                end += 1;
+              } else {
+                uri = "${uri.substring(start, pathStart)}/"
+                      "${uri.substring(queryStart, end)}";
+                schemeEnd -= start;
+                hostStart -= start;
+                portStart -= start;
+                pathStart -= start;
+                queryStart += 1 - start;
+                fragmentStart += 1 - start;
+                start = 0;
+                end = uri.length;
+              }
+            }
+          } else if (uri.startsWith("http", start)) {
+            scheme = "http";
+            // HTTP URIs should not have an explicit port of 80.
+            if (portStart > start && portStart + 3 == pathStart &&
+                uri.startsWith("80", portStart + 1)) {
+              if (start == 0 && end == uri.length) {
+                uri = uri.replaceRange(portStart, pathStart, "");
+                pathStart -= 3;
+                queryStart -= 3;
+                fragmentStart -= 3;
+                end -= 3;
+              } else {
+                uri = uri.substring(start, portStart) +
+                      uri.substring(pathStart, end);
+                schemeEnd -= start;
+                hostStart -= start;
+                portStart -= start;
+                pathStart -= 3 + start;
+                queryStart -= 3 + start;
+                fragmentStart -= 3 + start;
+                start = 0;
+                end = uri.length;
+              }
+            }
+          }
+        } else if (schemeEnd == start + 5 && uri.startsWith("https", start)) {
+          scheme = "https";
+          // HTTPS URIs should not have an explicit port of 443.
+          if (portStart > start && portStart + 4 == pathStart &&
+              uri.startsWith("443", portStart + 1)) {
+            if (start == 0 && end == uri.length) {
+              uri = uri.replaceRange(portStart, pathStart, "");
+              pathStart -= 4;
+              queryStart -= 4;
+              fragmentStart -= 4;
+              end -= 3;
+            } else {
+              uri = uri.substring(start, portStart) +
+                    uri.substring(pathStart, end);
+              schemeEnd -= start;
+              hostStart -= start;
+              portStart -= start;
+              pathStart -= 4 + start;
+              queryStart -= 4 + start;
+              fragmentStart -= 4 + start;
+              start = 0;
+              end = uri.length;
+            }
+          }
+        }
+      }
+    }
+
+    if (isSimple) {
+      if (start > 0 || end < uri.length) {
+        uri = uri.substring(start, end);
+        schemeEnd -= start;
+        hostStart -= start;
+        portStart -= start;
+        pathStart -= start;
+        queryStart -= start;
+        fragmentStart -= start;
+      }
+      return new _SimpleUri(uri, schemeEnd, hostStart, portStart, pathStart,
+                            queryStart, fragmentStart, scheme);
+
+    }
+
+    return new _Uri.notSimple(uri, start, end, schemeEnd, hostStart, portStart,
+                              pathStart, queryStart, fragmentStart, scheme);
+  }
+
+  /**
+   * Encode the string [component] using percent-encoding to make it
+   * safe for literal use as a URI component.
+   *
+   * All characters except uppercase and lowercase letters, digits and
+   * the characters `-_.!~*'()` are percent-encoded. This is the
+   * set of characters specified in RFC 2396 and the which is
+   * specified for the encodeUriComponent in ECMA-262 version 5.1.
+   *
+   * When manually encoding path segments or query components remember
+   * to encode each part separately before building the path or query
+   * string.
+   *
+   * For encoding the query part consider using
+   * [encodeQueryComponent].
+   *
+   * To avoid the need for explicitly encoding use the [pathSegments]
+   * and [queryParameters] optional named arguments when constructing
+   * a [Uri].
+   */
+  static String encodeComponent(String component) {
+    return _Uri._uriEncode(_Uri._unreserved2396Table, component, UTF8, false);
+  }
+
+  /**
+   * Encode the string [component] according to the HTML 4.01 rules
+   * for encoding the posting of a HTML form as a query string
+   * component.
+   *
+   * Encode the string [component] according to the HTML 4.01 rules
+   * for encoding the posting of a HTML form as a query string
+   * component.
+
+   * The component is first encoded to bytes using [encoding].
+   * The default is to use [UTF8] encoding, which preserves all
+   * the characters that don't need encoding.
+
+   * Then the resulting bytes are "percent-encoded". This transforms
+   * spaces (U+0020) to a plus sign ('+') and all bytes that are not
+   * the ASCII decimal digits, letters or one of '-._~' are written as
+   * a percent sign '%' followed by the two-digit hexadecimal
+   * representation of the byte.
+
+   * Note that the set of characters which are percent-encoded is a
+   * superset of what HTML 4.01 requires, since it refers to RFC 1738
+   * for reserved characters.
+   *
+   * When manually encoding query components remember to encode each
+   * part separately before building the query string.
+   *
+   * To avoid the need for explicitly encoding the query use the
+   * [queryParameters] optional named arguments when constructing a
+   * [Uri].
+   *
+   * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more
+   * details.
+   */
+  static String encodeQueryComponent(String component,
+                                     {Encoding encoding: UTF8}) {
+    return _Uri._uriEncode(_Uri._unreservedTable, component, encoding, true);
+  }
+
+  /**
+   * Decodes the percent-encoding in [encodedComponent].
+   *
+   * Note that decoding a URI component might change its meaning as
+   * some of the decoded characters could be characters with are
+   * delimiters for a given URI componene type. Always split a URI
+   * component using the delimiters for the component before decoding
+   * the individual parts.
+   *
+   * For handling the [path] and [query] components consider using
+   * [pathSegments] and [queryParameters] to get the separated and
+   * decoded component.
+   */
+  static String decodeComponent(String encodedComponent) {
+    return _Uri._uriDecode(encodedComponent, 0, encodedComponent.length,
+                           UTF8, false);
+  }
+
+  /**
+   * Decodes the percent-encoding in [encodedComponent], converting
+   * pluses to spaces.
+   *
+   * It will create a byte-list of the decoded characters, and then use
+   * [encoding] to decode the byte-list to a String. The default encoding is
+   * UTF-8.
+   */
+  static String decodeQueryComponent(
+      String encodedComponent,
+      {Encoding encoding: UTF8}) {
+    return _Uri._uriDecode(encodedComponent, 0, encodedComponent.length,
+                           encoding, true);
+  }
+
+  /**
+   * Encode the string [uri] using percent-encoding to make it
+   * safe for literal use as a full URI.
+   *
+   * All characters except uppercase and lowercase letters, digits and
+   * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This
+   * is the set of characters specified in in ECMA-262 version 5.1 for
+   * the encodeURI function .
+   */
+  static String encodeFull(String uri) {
+    return _Uri._uriEncode(_Uri._encodeFullTable, uri, UTF8, false);
+  }
+
+  /**
+   * Decodes the percent-encoding in [uri].
+   *
+   * Note that decoding a full URI might change its meaning as some of
+   * the decoded characters could be reserved characters. In most
+   * cases an encoded URI should be parsed into components using
+   * [Uri.parse] before decoding the separate components.
+   */
+  static String decodeFull(String uri) {
+    return _Uri._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]
+   * is the empty string an empty map is returned.
+   *
+   * Keys in the query string that have no value are mapped to the
+   * empty string.
+   *
+   * Each query component will be decoded using [encoding]. The default encoding
+   * is UTF-8.
+   */
+  static Map<String, String> splitQueryString(String query,
+                                              {Encoding encoding: UTF8}) {
+    return query.split("&").fold({}, (map, element) {
+      int index = element.indexOf("=");
+      if (index == -1) {
+        if (element != "") {
+          map[decodeQueryComponent(element, encoding: encoding)] = "";
+        }
+      } else if (index != 0) {
+        var key = element.substring(0, index);
+        var value = element.substring(index + 1);
+        map[decodeQueryComponent(key, encoding: encoding)] =
+            decodeQueryComponent(value, encoding: encoding);
+      }
+      return map;
+    });
+  }
+
+
+  /**
+   * Parse the [host] as an IP version 4 (IPv4) address, returning the address
+   * as a list of 4 bytes in network byte order (big endian).
+   *
+   * Throws a [FormatException] if [host] is not a valid IPv4 address
+   * representation.
+   */
+  static List<int> parseIPv4Address(String host) =>
+       _parseIPv4Address(host, 0, host.length);
+
+  /// Implementation of [parseIPv4Address] that can work on a substring.
+  static List<int> _parseIPv4Address(String host, int start, int end) {
+    void error(String msg, int position) {
+      throw new FormatException('Illegal IPv4 address, $msg', host, position);
+    }
+
+    var result = new Uint8List(4);
+    int partIndex = 0;
+    int partStart = start;
+    for (int i = start; i < end; i++) {
+      int char = host.codeUnitAt(i);
+      if (char != _DOT) {
+        if (char ^ 0x30 > 9) {
+          // Fail on a non-digit character.
+          error("invalid character", i);
+        }
+      } else {
+        if (partIndex == 3) {
+          error('IPv4 address should contain exactly 4 parts', i);
+        }
+        int part = int.parse(host.substring(partStart, i));
+        if (part > 255) {
+          error("each part must be in the range 0..255", partStart);
+        }
+        result[partIndex++] = part;
+        partStart = i + 1;
+      }
+    }
+
+    if (partIndex != 3) {
+      error('IPv4 address should contain exactly 4 parts', end);
+    }
+
+    int part = int.parse(host.substring(partStart, end));
+    if (part > 255) {
+      error("each part must be in the range 0..255", partStart);
+    }
+    result[partIndex] = part;
+
+    return result;
+  }
+
+  /**
+   * Parse the [host] as an IP version 6 (IPv6) address, returning the address
+   * as a list of 16 bytes in network byte order (big endian).
+   *
+   * Throws a [FormatException] if [host] is not a valid IPv6 address
+   * representation.
+   *
+   * Acts on the substring from [start] to [end]. If [end] is omitted, it
+   * defaults ot the end of the string.
+   *
+   * Some examples of IPv6 addresses:
+   *  * ::1
+   *  * FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
+   *  * 3ffe:2a00:100:7031::1
+   *  * ::FFFF:129.144.52.38
+   *  * 2010:836B:4179::836B:4179
+   */
+  static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
+    if (end == null) end = host.length;
+    // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, separated
+    // by `:`'s, with the following exceptions:
+    //
+    //  - One (and only one) wildcard (`::`) may be present, representing a fill
+    //    of 0's. The IPv6 `::` is thus 16 bytes of `0`.
+    //  - The last two parts may be replaced by an IPv4 "dotted-quad" address.
+
+    // Helper function for reporting a badly formatted IPv6 address.
+    void error(String msg, [position]) {
+      throw new FormatException('Illegal IPv6 address, $msg', host, position);
+    }
+
+    // Parse a hex block.
+    int parseHex(int start, int end) {
+      if (end - start > 4) {
+        error('an IPv6 part can only contain a maximum of 4 hex digits', start);
+      }
+      int value = int.parse(host.substring(start, end), radix: 16);
+      if (value < 0 || value > 0xFFFF) {
+        error('each part must be in the range of `0x0..0xFFFF`', start);
+      }
+      return value;
+    }
+
+    if (host.length < 2) error('address is too short');
+    List<int> parts = [];
+    bool wildcardSeen = false;
+    // Set if seeing a ".", suggesting that there is an IPv4 address.
+    bool seenDot = false;
+    int partStart = start;
+    // Parse all parts, except a potential last one.
+    for (int i = start; i < end; i++) {
+      int char = host.codeUnitAt(i);
+      if (char == _COLON) {
+        if (i == start) {
+          // If we see a `:` in the beginning, expect wildcard.
+          i++;
+          if (host.codeUnitAt(i) != _COLON) {
+            error('invalid start colon.', i);
+          }
+          partStart = i;
+        }
+        if (i == partStart) {
+          // Wildcard. We only allow one.
+          if (wildcardSeen) {
+            error('only one wildcard `::` is allowed', i);
+          }
+          wildcardSeen = true;
+          parts.add(-1);
+        } else {
+          // Found a single colon. Parse [partStart..i] as a hex entry.
+          parts.add(parseHex(partStart, i));
+        }
+        partStart = i + 1;
+      } else if (char == _DOT) {
+        seenDot = true;
+      }
+    }
+    if (parts.length == 0) error('too few parts');
+    bool atEnd = (partStart == end);
+    bool isLastWildcard = (parts.last == -1);
+    if (atEnd && !isLastWildcard) {
+      error('expected a part after last `:`', end);
+    }
+    if (!atEnd) {
+      if (!seenDot) {
+        parts.add(parseHex(partStart, end));
+      } else {
+        List<int> last = _parseIPv4Address(host, partStart, end);
+        parts.add(last[0] << 8 | last[1]);
+        parts.add(last[2] << 8 | last[3]);
+      }
+    }
+    if (wildcardSeen) {
+      if (parts.length > 7) {
+        error('an address with a wildcard must have less than 7 parts');
+      }
+    } else if (parts.length != 8) {
+      error('an address without a wildcard must contain exactly 8 parts');
+    }
+    List<int> bytes = new Uint8List(16);
+    for (int i = 0, index = 0; i < parts.length; i++) {
+      int value = parts[i];
+      if (value == -1) {
+        int wildCardLength = 9 - parts.length;
+        for (int j = 0; j < wildCardLength; j++) {
+          bytes[index] = 0;
+          bytes[index + 1] = 0;
+          index += 2;
+        }
+      } else {
+        bytes[index] = value >> 8;
+        bytes[index + 1] = value & 0xff;
+        index += 2;
+      }
+    }
+    return bytes;
+  }
+}
+
+class _Uri implements Uri {
+  // We represent the missing scheme as an empty string.
+  // A valid scheme cannot be empty.
+  final String scheme;
+
+  /**
+   * The user-info part of the authority.
+   *
+   * Does not distinguish between an empty user-info and an absent one.
+   * The value is always non-null.
+   * Is considered absent if [_host] is `null`.
+   */
+  final String _userInfo;
+
+  /**
+   * The host name of the URI.
+   *
+   * Set to `null` if there is no authority in the URI.
+   * The host name is the only mandatory part of an authority, so we use
+   * it to mark whether an authority part was present or not.
+   */
+  final String _host;
+
+  /**
+   * The port number part of the authority.
+   *
+   * The port. Set to null if there is no port. Normalized to null if
+   * the port is the default port for the scheme.
+   */
+  int _port;
+
+  /**
+   * The path of the URI.
+   *
+   * Always non-null.
+   */
+  String _path;
+
+  // The query content, or null if there is no query.
+  final String _query;
+
+  // The fragment content, or null if there is no fragment.
+  final String _fragment;
+
+  /**
+   * Cache the computed return value of [pathSegements].
+   */
+  List<String> _pathSegments;
+
+  /**
+   * Cache of the full normalized text representation of the URI.
+   */
+  String _text;
+
+  /**
+   * Cache of the hashCode of [_text].
+   *
+   * Is null until computed.
+   */
+  int _hashCodeCache;
+
+  /**
+   * Cache the computed return value of [queryParameters].
+   */
+  Map<String, String> _queryParameters;
+  Map<String, List<String>> _queryParameterLists;
+
+  /// Internal non-verifying constructor. Only call with validated arguments.
+  _Uri._internal(this.scheme,
+                 this._userInfo,
+                 this._host,
+                 this._port,
+                 this._path,
+                 this._query,
+                 this._fragment);
+
+  /// Create a [_Uri] from parts of [uri].
+  ///
+  /// The parameters specify the start/end of particular components of the URI.
+  /// The [scheme] may contain a string representing a normalized scheme
+  /// component if one has already been discovered.
+  factory _Uri.notSimple(String uri, int start, int end, int schemeEnd,
+                        int hostStart, int portStart, int pathStart,
+                        int queryStart, int fragmentStart, String scheme) {
+    if (scheme == null) {
+      scheme = "";
+      if (schemeEnd > start) {
+        scheme = _makeScheme(uri, start, schemeEnd);
+      } else if (schemeEnd == start) {
+        _fail(uri, start, "Invalid empty scheme");
+      }
+    }
+    String userInfo = "";
+    String host;
+    int port;
+    if (hostStart > start) {
+      int userInfoStart = schemeEnd + 3;
+      if (userInfoStart < hostStart) {
+        userInfo = _makeUserInfo(uri, userInfoStart, hostStart - 1);
+      }
+      host = _makeHost(uri, hostStart, portStart, false);
+      if (portStart + 1 < pathStart) {
+        // Should throw because invalid.
+        port = int.parse(uri.substring(portStart + 1, pathStart), onError: (_) {
+          throw new FormatException("Invalid port", uri, portStart + 1);
+        });
+        port = _makePort(port, scheme);
+      }
+    }
+    String path = _makePath(uri, pathStart, queryStart, null,
+                            scheme, host != null);
+    String query;
+    if (queryStart < fragmentStart) {
+      query = _makeQuery(uri, queryStart + 1, fragmentStart, null);
+    }
+    String fragment;
+    if (fragmentStart < end) {
+      fragment = _makeFragment(uri, fragmentStart + 1, end);
+    }
+    return new _Uri._internal(scheme,
+                              userInfo,
+                              host,
+                              port,
+                              path,
+                              query,
+                              fragment);
+  }
+
+  /// Implementation of [Uri.Uri].
+  factory _Uri({String scheme,
+                String userInfo,
+                String host,
+                int port,
+                String path,
+                Iterable<String> pathSegments,
+                String query,
+                Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
+                String fragment}) {
+    scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme));
+    userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
+    host = _makeHost(host, 0, _stringOrNullLength(host), false);
+    // Special case this constructor for backwards compatibility.
+    if (query == "") query = null;
+    query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
+    fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment));
+    port = _makePort(port, scheme);
+    bool isFile = (scheme == "file");
+    if (host == null &&
+        (userInfo.isNotEmpty || port != null || isFile)) {
+      host = "";
+    }
+    bool hasAuthority = (host != null);
+    path = _makePath(path, 0, _stringOrNullLength(path), pathSegments,
+                     scheme, hasAuthority);
+    if (scheme.isEmpty && host == null && !path.startsWith('/')) {
+      path = _normalizeRelativePath(path);
+    } else {
+      path = _removeDotSegments(path);
+    }
+    return new _Uri._internal(scheme, userInfo, host, port,
+                              path, query, fragment);
+  }
+
+  /// Implementation of [Uri.http].
+  factory _Uri.http(String authority,
+                    String unencodedPath,
+                    [Map<String, String> queryParameters]) {
+    return _makeHttpUri("http", authority, unencodedPath, queryParameters);
+  }
+
+  /// Implementation of [Uri.https].
+  factory _Uri.https(String authority,
+                     String unencodedPath,
+                     [Map<String, String> queryParameters]) {
+    return _makeHttpUri("https", authority, unencodedPath, queryParameters);
+  }
+
+  String get authority {
+    if (!hasAuthority) return "";
+    var sb = new StringBuffer();
+    _writeAuthority(sb);
+    return sb.toString();
+  }
+
+  String get userInfo => _userInfo;
+
+  String get host {
+    if (_host == null) return "";
+    if (_host.startsWith('[')) {
+      return _host.substring(1, _host.length - 1);
+    }
+    return _host;
+  }
+
+  int get port {
+    if (_port == null) return _defaultPort(scheme);
+    return _port;
+  }
+
+  // The default port for the scheme of this Uri.
+  static int _defaultPort(String scheme) {
+    if (scheme == "http") return 80;
+    if (scheme == "https") return 443;
+    return 0;
+  }
+
+  String get path => _path;
+
+  String get query => _query ?? "";
+
+  String get fragment => _fragment ?? "";
+
+  // Report a parse failure.
+  static void _fail(String uri, int index, String message) {
+    throw new FormatException(message, uri, index);
+  }
+
+  static Uri _makeHttpUri(String scheme,
+                          String authority,
+                          String unencodedPath,
+                          Map<String, String> queryParameters) {
+    var userInfo = "";
+    var host = null;
+    var port = null;
+
+    if (authority != null && authority.isNotEmpty) {
+      var hostStart = 0;
+      // Split off the user info.
+      bool hasUserInfo = false;
+      for (int i = 0; i < authority.length; i++) {
+        const int atSign = 0x40;
+        if (authority.codeUnitAt(i) == atSign) {
+          hasUserInfo = true;
+          userInfo = authority.substring(0, i);
+          hostStart = i + 1;
+          break;
+        }
+      }
+      var hostEnd = hostStart;
+      if (hostStart < authority.length &&
+          authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
+        // IPv6 host.
+        for (; hostEnd < authority.length; hostEnd++) {
+          if (authority.codeUnitAt(hostEnd) == _RIGHT_BRACKET) break;
+        }
+        if (hostEnd == authority.length) {
+          throw new FormatException("Invalid IPv6 host entry.",
+                                    authority, hostStart);
+        }
+        Uri.parseIPv6Address(authority, hostStart + 1, hostEnd);
+        hostEnd++;  // Skip the closing bracket.
+        if (hostEnd != authority.length &&
+            authority.codeUnitAt(hostEnd) != _COLON) {
+          throw new FormatException("Invalid end of authority",
+                                    authority, hostEnd);
+        }
+      }
+      // Split host and port.
+      bool hasPort = false;
+      for (; hostEnd < authority.length; hostEnd++) {
+        if (authority.codeUnitAt(hostEnd) == _COLON) {
+          var portString = authority.substring(hostEnd + 1);
+          // We allow the empty port - falling back to initial value.
+          if (portString.isNotEmpty) port = int.parse(portString);
+          break;
+        }
+      }
+      host = authority.substring(hostStart, hostEnd);
+    }
+    return new Uri(scheme: scheme,
+                   userInfo: userInfo,
+                   host: host,
+                   port: port,
+                   pathSegments: unencodedPath.split("/"),
+                   queryParameters: queryParameters);
+  }
+
+  /// Implementation of [Uri.file].
+  factory _Uri.file(String path, {bool windows}) {
+    windows = (windows == null) ? _Uri._isWindows : windows;
+    return windows ? _makeWindowsFileUrl(path, false)
+                   : _makeFileUri(path, false);
+  }
+
+  /// Implementation of [Uri.directory].
+  factory _Uri.directory(String path, {bool windows}) {
+    windows = (windows == null) ? _Uri._isWindows : windows;
+    return windows ? _makeWindowsFileUrl(path, true)
+                   : _makeFileUri(path, true);
+  }
+
+
+  /// Used internally in path-related constructors.
   external static bool get _isWindows;
 
   static _checkNonWindowsPathReservedCharacters(List<String> segments,
@@ -969,46 +1740,6 @@
     }
   }
 
-  /**
-   * Returns a new `Uri` based on this one, but with some parts replaced.
-   *
-   * This method takes the same parameters as the [new Uri] constructor,
-   * and they have the same meaning.
-   *
-   * At most one of [path] and [pathSegments] must be provided.
-   * Likewise, at most one of [query] and [queryParameters] must be provided.
-   *
-   * Each part that is not provided will default to the corresponding
-   * value from this `Uri` instead.
-   *
-   * This method is different from [Uri.resolve] which overrides in a
-   * hierarchial manner,
-   * and can instead replace each part of a `Uri` individually.
-   *
-   * Example:
-   *
-   *     Uri uri1 = Uri.parse("a://b@c:4/d/e?f#g");
-   *     Uri uri2 = uri1.replace(scheme: "A", path: "D/E/E", fragment: "G");
-   *     print(uri2);  // prints "A://b@c:4/D/E/E/?f#G"
-   *
-   * This method acts similarly to using the `new Uri` constructor with
-   * some of the arguments taken from this `Uri` . Example:
-   *
-   *     Uri uri3 = new Uri(
-   *         scheme: "A",
-   *         userInfo: uri1.userInfo,
-   *         host: uri1.host,
-   *         port: uri1.port,
-   *         path: "D/E/E",
-   *         query: uri1.query,
-   *         fragment: "G");
-   *     print(uri3);  // prints "A://b@c:4/D/E/E/?f#G"
-   *     print(uri2 == uri3);  // prints true.
-   *
-   * Using this method can be seen as a shorthand for the `Uri` constructor
-   * call above, but may also be slightly faster because the parts taken
-   * from this `Uri` need not be checked for validity again.
-   */
   Uri replace({String scheme,
                String userInfo,
                String host,
@@ -1024,7 +1755,7 @@
     bool schemeChanged = false;
     if (scheme != null) {
       scheme = _makeScheme(scheme, 0, scheme.length);
-      schemeChanged = true;
+      schemeChanged = (scheme != this.scheme);
     } else {
       scheme = this.scheme;
     }
@@ -1075,29 +1806,16 @@
       fragment = this._fragment;
     }
 
-    return new Uri._internal(
+    return new _Uri._internal(
         scheme, userInfo, host, port, path, query, fragment);
   }
 
-  /**
-   * Returns a `Uri` that differs from this only in not having a fragment.
-   *
-   * If this `Uri` does not have a fragment, it is itself returned.
-   */
   Uri removeFragment() {
     if (!this.hasFragment) return this;
-    return new Uri._internal(scheme, _userInfo, _host, _port,
+    return new _Uri._internal(scheme, _userInfo, _host, _port,
                              _path, _query, null);
   }
 
-  /**
-   * 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 {
     var result = _pathSegments;
     if (result != null) return result;
@@ -1114,43 +1832,14 @@
     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.
-   *
-   * Keys in the query string that have no value are mapped to the
-   * empty string.
-   * If a key occurs more than once in the query string, it is mapped to
-   * an arbitrary choice of possible value.
-   * The [queryParametersAll] getter can provide a map
-   * that maps keys to all of their values.
-   *
-   * The returned map is unmodifiable.
-   */
   Map<String, String> get queryParameters {
     if (_queryParameters == null) {
       _queryParameters =
-          new UnmodifiableMapView<String, String>(splitQueryString(query));
+          new UnmodifiableMapView<String, String>(Uri.splitQueryString(query));
     }
     return _queryParameters;
   }
 
-  /**
-   * 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.
-   *
-   * Keys are mapped to lists of their values. If a key occurs only once,
-   * its value is a singleton list. If a key occurs with no value, the
-   * empty string is used as the value for that occurrence.
-   *
-   * The returned map and the lists it contains are unmodifiable.
-   */
   Map<String, List<String>> get queryParametersAll {
     if (_queryParameterLists == null) {
       Map queryParameterLists = _splitQueryStringAll(query);
@@ -1164,22 +1853,6 @@
     return _queryParameterLists;
   }
 
-  /**
-   * Returns a URI where the path has been normalized.
-   *
-   * A normalized path does not contain `.` segments or non-leading `..`
-   * segments.
-   * Only a relative path with no scheme or authority may contain
-   * leading `..` segments,
-   * a path that starts with `/` will also drop any leading `..` segments.
-   *
-   * This uses the same normalization strategy as `new Uri().resolve(this)`.
-   *
-   * Does not change any part of the URI except the path.
-   *
-   * The default implementation of `Uri` always normalizes paths, so calling
-   * this function has no effect.
-   */
   Uri normalizePath() {
     String path = _normalizePath(_path, scheme, hasAuthority);
     if (identical(path, _path)) return this;
@@ -1212,7 +1885,7 @@
       if (host.codeUnitAt(end - 1) != _RIGHT_BRACKET) {
         _fail(host, start, 'Missing end `]` to match `[` in host');
       }
-      parseIPv6Address(host, start + 1, end - 1);
+      Uri.parseIPv6Address(host, start + 1, end - 1);
       // RFC 5952 requires hex digits to be lower case.
       return host.substring(start, end).toLowerCase();
     }
@@ -1220,7 +1893,7 @@
       // TODO(lrn): skip if too short to be a valid IPv6 address?
       for (int i = start; i < end; i++) {
         if (host.codeUnitAt(i) == _COLON) {
-          parseIPv6Address(host, start, end);
+          Uri.parseIPv6Address(host, start, end);
           return '[$host]';
         }
       }
@@ -1333,6 +2006,17 @@
     }
     scheme = scheme.substring(start, end);
     if (containsUpperCase) scheme = scheme.toLowerCase();
+    return _canonicalizeScheme(scheme);
+  }
+
+  // Canonicalize a few often-used scheme strings.
+  //
+  // This improves memory usage and makes comparison faster.
+  static String _canonicalizeScheme(String scheme) {
+    if (scheme == "http") return "http";
+    if (scheme == "file") return "file";
+    if (scheme == "https") return "https";
+    if (scheme == "package") return "package";
     return scheme;
   }
 
@@ -1382,11 +2066,13 @@
   static String _makeQuery(
       String query, int start, int end,
       Map<String, dynamic/*String|Iterable<String>*/> queryParameters) {
-    if (query == null && queryParameters == null) return null;
-    if (query != null && queryParameters != null) {
-      throw new ArgumentError('Both query and queryParameters specified');
+    if (query != null) {
+      if (queryParameters != null) {
+        throw new ArgumentError('Both query and queryParameters specified');
+      }
+      return _normalize(query, start, end, _queryCharTable);
     }
-    if (query != null) return _normalize(query, start, end, _queryCharTable);
+    if (queryParameters == null) return null;
 
     var result = new StringBuffer();
     var separator = "";
@@ -1419,8 +2105,6 @@
     return _normalize(fragment, start, end, _queryCharTable);
   }
 
-  static int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
-
   /**
    * Performs RFC 3986 Percent-Encoding Normalization.
    *
@@ -1465,10 +2149,11 @@
   // 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;
+    const int zeroDigit = 0x30;
+    int digit = char ^ zeroDigit;
     if (digit <= 9) return digit;
     int lowerCase = char | 0x20;
-    if (Uri._LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_F) {
+    if (_LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_F) {
       return lowerCase - (_LOWER_CASE_A - 10);
     }
     return -1;
@@ -1554,7 +2239,7 @@
             if (index + 1 < end) {
               int tail = component.codeUnitAt(index + 1);
               if ((tail & 0xFC00) == 0xDC00) {
-                // Tail surrogat.
+                // Tail surrogate.
                 sourceLength = 2;
                 char = 0x10000 | ((char & 0x3ff) << 10) | (tail & 0x3ff);
               }
@@ -1703,34 +2388,10 @@
     return output.join("/");
   }
 
-  /**
-   * Resolve [reference] as an URI relative to `this`.
-   *
-   * First turn [reference] into a URI using [Uri.parse]. Then resolve the
-   * resulting URI relative to `this`.
-   *
-   * Returns the resolved URI.
-   *
-   * See [resolveUri] for details.
-   */
   Uri resolve(String reference) {
     return resolveUri(Uri.parse(reference));
   }
 
-  /**
-   * Resolve [reference] as an URI relative to `this`.
-   *
-   * 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").
-   *
-   * 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
-   * with a slash.
-   * In that case, the paths are combined without removing leading "..", and
-   * an empty path is not converted to "/".
-   */
   Uri resolveUri(Uri reference) {
     // From RFC 3986.
     String targetScheme;
@@ -1776,11 +2437,17 @@
           } else {
             // This is the RFC 3986 behavior for merging.
             if (this.hasEmptyPath) {
-              if (!this.hasScheme && !this.hasAuthority) {
-                // Keep the path relative if no scheme or authority.
-                targetPath = reference.path;
+              if (!this.hasAuthority) {
+                if (!this.hasScheme) {
+                  // Keep the path relative if no scheme or authority.
+                  targetPath = reference.path;
+                } else {
+                  // Remove leading dot-segments if the path is put
+                  // beneath a scheme.
+                  targetPath = _removeDotSegments(reference.path);
+                }
               } else {
-                // Add path normalization on top of RFC algorithm.
+                // RFC algorithm for base with authority and empty path.
                 targetPath = _removeDotSegments("/" + reference.path);
               }
             } else {
@@ -1788,8 +2455,9 @@
               if (this.hasScheme || this.hasAuthority || this.hasAbsolutePath) {
                 targetPath = _removeDotSegments(mergedPath);
               } else {
-                // Non-RFC 3986 beavior. If both base and reference are relative
-                // path, allow the merged path to start with "..".
+                // Non-RFC 3986 behavior.
+                // If both base and reference are relative paths,
+                // allow the merged path to start with "..".
                 // The RFC only specifies the case where the base has a scheme.
                 targetPath = _normalizeRelativePath(mergedPath);
               }
@@ -1800,63 +2468,29 @@
       }
     }
     String fragment = reference.hasFragment ? reference.fragment : null;
-    return new Uri._internal(targetScheme,
-                             targetUserInfo,
-                             targetHost,
-                             targetPort,
-                             targetPath,
-                             targetQuery,
-                             fragment);
+    return new _Uri._internal(targetScheme,
+                              targetUserInfo,
+                              targetHost,
+                              targetPort,
+                              targetPath,
+                              targetQuery,
+                              fragment);
   }
 
-  /**
-   * Returns whether the URI has a [scheme] component.
-   */
   bool get hasScheme => scheme.isNotEmpty;
 
-  /**
-   * Returns whether the URI has an [authority] component.
-   */
   bool get hasAuthority => _host != null;
 
-  /**
-   * Returns whether the URI has an explicit port.
-   *
-   * If the port number is the default port number
-   * (zero for unrecognized schemes, with http (80) and https (443) being
-   * recognized),
-   * then the port is made implicit and omitted from the URI.
-   */
   bool get hasPort => _port != null;
 
-  /**
-   * Returns whether the URI has a query part.
-   */
   bool get hasQuery => _query != null;
 
-  /**
-   * Returns whether the URI has a fragment part.
-   */
   bool get hasFragment => _fragment != null;
 
-  /**
-   * Returns whether the URI has an empty path.
-   */
   bool get hasEmptyPath => _path.isEmpty;
 
-  /**
-   * Returns whether the URI has an absolute path (starting with '/').
-   */
   bool get hasAbsolutePath => _path.startsWith('/');
 
-  /**
-   * Returns the origin of the URI in the form scheme://host:port for the
-   * schemes http and https.
-   *
-   * It is an error if the scheme is not "http" or "https".
-   *
-   * See: http://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin
-   */
   String get origin {
     if (scheme == "" || _host == null || _host == "") {
       throw new StateError("Cannot use origin without a scheme: $this");
@@ -1869,69 +2503,6 @@
     return "$scheme://$_host:$_port";
   }
 
-  /**
-   * Returns the file path from a file URI.
-   *
-   * The returned path has either Windows or non-Windows
-   * semantics.
-   *
-   * For non-Windows semantics the slash ("/") is used to separate
-   * path segments.
-   *
-   * For Windows semantics the backslash ("\") separator is used to
-   * separate path segments.
-   *
-   * If the URI is absolute the path starts with a path separator
-   * unless Windows semantics is used and the first path segment is a
-   * drive letter. When Windows semantics is used a host component in
-   * the uri in interpreted as a file server and a UNC path is
-   * returned.
-   *
-   * The default for whether to use Windows or non-Windows semantics
-   * determined from the platform Dart is running on. When running in
-   * the standalone VM this is detected by the VM based on the
-   * operating system. When running in a browser non-Windows semantics
-   * is always used.
-   *
-   * To override the automatic detection of which semantics to use pass
-   * a value for [windows]. Passing `true` will use Windows
-   * semantics and passing `false` will use non-Windows semantics.
-   *
-   * If the URI ends with a slash (i.e. the last path component is
-   * empty) the returned file path will also end with a slash.
-   *
-   * With Windows semantics URIs starting with a drive letter cannot
-   * be relative to the current drive on the designated drive. That is
-   * for the URI `file:///c:abc` calling `toFilePath` will throw as a
-   * path segment cannot contain colon on Windows.
-   *
-   * Examples using non-Windows semantics (resulting of calling
-   * toFilePath in comment):
-   *
-   *     Uri.parse("xxx/yyy");  // xxx/yyy
-   *     Uri.parse("xxx/yyy/");  // xxx/yyy/
-   *     Uri.parse("file:///xxx/yyy");  // /xxx/yyy
-   *     Uri.parse("file:///xxx/yyy/");  // /xxx/yyy/
-   *     Uri.parse("file:///C:");  // /C:
-   *     Uri.parse("file:///C:a");  // /C:a
-   *
-   * Examples using Windows semantics (resulting URI in comment):
-   *
-   *     Uri.parse("xxx/yyy");  // xxx\yyy
-   *     Uri.parse("xxx/yyy/");  // xxx\yyy\
-   *     Uri.parse("file:///xxx/yyy");  // \xxx\yyy
-   *     Uri.parse("file:///xxx/yyy/");  // \xxx\yyy/
-   *     Uri.parse("file:///C:/xxx/yyy");  // C:\xxx\yyy
-   *     Uri.parse("file:C:xxx/yyy");  // Throws as a path segment
-   *                                   // cannot contain colon on Windows.
-   *     Uri.parse("file://server/share/file");  // \\server\share\file
-   *
-   * If the URI is not a file URI calling this throws
-   * [UnsupportedError].
-   *
-   * If the URI cannot be converted to a file path calling this throws
-   * [UnsupportedError].
-   */
   String toFilePath({bool windows}) {
     if (scheme != "" && scheme != "file") {
       throw new UnsupportedError(
@@ -1946,25 +2517,27 @@
           "Cannot extract a file path from a URI with a fragment component");
     }
     if (windows == null) windows = _isWindows;
-    return windows ? _toWindowsFilePath() : _toFilePath();
+    return windows ? _toWindowsFilePath(this) : _toFilePath();
   }
 
   String _toFilePath() {
-    if (host != "") {
+    if (hasAuthority && host != "") {
       throw new UnsupportedError(
           "Cannot extract a non-Windows file path from a file URI "
           "with an authority");
     }
+    // Use path segments to have any escapes unescaped.
+    var pathSegments = this.pathSegments;
     _checkNonWindowsPathReservedCharacters(pathSegments, false);
     var result = new StringBuffer();
-    if (_isPathAbsolute) result.write("/");
+    if (hasAbsolutePath) result.write("/");
     result.writeAll(pathSegments, "/");
     return result.toString();
   }
 
-  String _toWindowsFilePath() {
+  static String _toWindowsFilePath(Uri uri) {
     bool hasDriveLetter = false;
-    var segments = pathSegments;
+    var segments = uri.pathSegments;
     if (segments.length > 0 &&
         segments[0].length == 2 &&
         segments[0].codeUnitAt(1) == _COLON) {
@@ -1972,23 +2545,25 @@
       _checkWindowsPathReservedCharacters(segments, false, 1);
       hasDriveLetter = true;
     } else {
-      _checkWindowsPathReservedCharacters(segments, false);
+      _checkWindowsPathReservedCharacters(segments, false, 0);
     }
     var result = new StringBuffer();
-    if (_isPathAbsolute && !hasDriveLetter) result.write("\\");
-    if (host != "") {
-      result.write("\\");
-      result.write(host);
-      result.write("\\");
+    if (uri.hasAbsolutePath && !hasDriveLetter) result.write(r"\");
+    if (uri.hasAuthority) {
+      var host = uri.host;
+      if (host.isNotEmpty) {
+        result.write(r"\");
+        result.write(host);
+        result.write(r"\");
+      }
     }
-    result.writeAll(segments, "\\");
-    if (hasDriveLetter && segments.length == 1) result.write("\\");
+    result.writeAll(segments, r"\");
+    if (hasDriveLetter && segments.length == 1) result.write(r"\");
     return result.toString();
   }
 
   bool get _isPathAbsolute {
-    if (path == null || path.isEmpty) return false;
-    return path.startsWith('/');
+    return _path != null && _path.startsWith('/');
   }
 
   void _writeAuthority(StringSink ss) {
@@ -2014,8 +2589,13 @@
   UriData get data => (scheme == "data") ? new UriData.fromUri(this) : null;
 
   String toString() {
+    return _text ??= _initializeText();
+  }
+
+  String _initializeText() {
+    assert(_text == null);
     StringBuffer sb = new StringBuffer();
-    _addIfNonEmpty(sb, scheme, scheme, ':');
+    if (scheme.isNotEmpty) sb..write(scheme)..write(":");
     if (hasAuthority || path.startsWith("//") || (scheme == "file")) {
       // File URIS always have the authority, even if it is empty.
       // The empty URI means "localhost".
@@ -2023,192 +2603,31 @@
       _writeAuthority(sb);
     }
     sb.write(path);
-    if (_query != null) { sb..write("?")..write(_query); }
-    if (_fragment != null) { sb..write("#")..write(_fragment); }
+    if (_query != null) sb..write("?")..write(_query);
+    if (_fragment != null) sb..write("#")..write(_fragment);
     return sb.toString();
   }
 
   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;
+    if (identical(this, other)) return true;
+    if (other is Uri) {
+      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 false;
   }
 
   int get hashCode {
-    int combine(part, current) {
-      // The sum is truncated to 30 bits to make sure it fits into a Smi.
-      return (current * 31 + part.hashCode) & 0x3FFFFFFF;
-    }
-    return combine(scheme, combine(userInfo, combine(host, combine(port,
-        combine(path, combine(query, combine(fragment, 1)))))));
-  }
-
-  static void _addIfNonEmpty(StringBuffer sb, String test,
-                             String first, String second) {
-    if ("" != test) {
-      sb.write(first);
-      sb.write(second);
-    }
-  }
-
-  /**
-   * Encode the string [component] using percent-encoding to make it
-   * safe for literal use as a URI component.
-   *
-   * All characters except uppercase and lowercase letters, digits and
-   * the characters `-_.!~*'()` are percent-encoded. This is the
-   * set of characters specified in RFC 2396 and the which is
-   * specified for the encodeUriComponent in ECMA-262 version 5.1.
-   *
-   * When manually encoding path segments or query components remember
-   * to encode each part separately before building the path or query
-   * string.
-   *
-   * For encoding the query part consider using
-   * [encodeQueryComponent].
-   *
-   * To avoid the need for explicitly encoding use the [pathSegments]
-   * and [queryParameters] optional named arguments when constructing
-   * a [Uri].
-   */
-  static String encodeComponent(String component) {
-    return _uriEncode(_unreserved2396Table, component, UTF8, false);
-  }
-
-  /**
-   * Encode the string [component] according to the HTML 4.01 rules
-   * for encoding the posting of a HTML form as a query string
-   * component.
-   *
-   * Encode the string [component] according to the HTML 4.01 rules
-   * for encoding the posting of a HTML form as a query string
-   * component.
-
-   * The component is first encoded to bytes using [encoding].
-   * The default is to use [UTF8] encoding, which preserves all
-   * the characters that don't need encoding.
-
-   * Then the resulting bytes are "percent-encoded". This transforms
-   * spaces (U+0020) to a plus sign ('+') and all bytes that are not
-   * the ASCII decimal digits, letters or one of '-._~' are written as
-   * a percent sign '%' followed by the two-digit hexadecimal
-   * representation of the byte.
-
-   * Note that the set of characters which are percent-encoded is a
-   * superset of what HTML 4.01 requires, since it refers to RFC 1738
-   * for reserved characters.
-   *
-   * When manually encoding query components remember to encode each
-   * part separately before building the query string.
-   *
-   * To avoid the need for explicitly encoding the query use the
-   * [queryParameters] optional named arguments when constructing a
-   * [Uri].
-   *
-   * See http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more
-   * details.
-   */
-  static String encodeQueryComponent(String component,
-                                     {Encoding encoding: UTF8}) {
-    return _uriEncode(_unreservedTable, component, encoding, true);
-  }
-
-  /**
-   * Decodes the percent-encoding in [encodedComponent].
-   *
-   * Note that decoding a URI component might change its meaning as
-   * some of the decoded characters could be characters with are
-   * delimiters for a given URI componene type. Always split a URI
-   * component using the delimiters for the component before decoding
-   * the individual parts.
-   *
-   * For handling the [path] and [query] components consider using
-   * [pathSegments] and [queryParameters] to get the separated and
-   * decoded component.
-   */
-  static String decodeComponent(String encodedComponent) {
-    return _uriDecode(encodedComponent, 0, encodedComponent.length,
-                      UTF8, false);
-  }
-
-  /**
-   * Decodes the percent-encoding in [encodedComponent], converting
-   * pluses to spaces.
-   *
-   * It will create a byte-list of the decoded characters, and then use
-   * [encoding] to decode the byte-list to a String. The default encoding is
-   * UTF-8.
-   */
-  static String decodeQueryComponent(
-      String encodedComponent,
-      {Encoding encoding: UTF8}) {
-    return _uriDecode(encodedComponent, 0, encodedComponent.length,
-                      encoding, true);
-  }
-
-  /**
-   * Encode the string [uri] using percent-encoding to make it
-   * safe for literal use as a full URI.
-   *
-   * All characters except uppercase and lowercase letters, digits and
-   * the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This
-   * is the set of characters specified in in ECMA-262 version 5.1 for
-   * the encodeURI function .
-   */
-  static String encodeFull(String uri) {
-    return _uriEncode(_encodeFullTable, uri, UTF8, false);
-  }
-
-  /**
-   * Decodes the percent-encoding in [uri].
-   *
-   * Note that decoding a full URI might change its meaning as some of
-   * the decoded characters could be reserved characters. In most
-   * cases an encoded URI should be parsed into components using
-   * [Uri.parse] before decoding the separate components.
-   */
-  static String decodeFull(String 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]
-   * is the empty string an empty map is returned.
-   *
-   * Keys in the query string that have no value are mapped to the
-   * empty string.
-   *
-   * Each query component will be decoded using [encoding]. The default encoding
-   * is UTF-8.
-   */
-  static Map<String, String> splitQueryString(String query,
-                                              {Encoding encoding: UTF8}) {
-    return query.split("&").fold({}, (map, element) {
-      int index = element.indexOf("=");
-      if (index == -1) {
-        if (element != "") {
-          map[decodeQueryComponent(element, encoding: encoding)] = "";
-        }
-      } else if (index != 0) {
-        var key = element.substring(0, index);
-        var value = element.substring(index + 1);
-        map[Uri.decodeQueryComponent(key, encoding: encoding)] =
-            decodeQueryComponent(value, encoding: encoding);
-      }
-      return map;
-    });
+    return _hashCodeCache ??= toString().hashCode;
   }
 
   static List _createList() => [];
@@ -2251,175 +2670,6 @@
     return result;
   }
 
-  /**
-   * Parse the [host] as an IP version 4 (IPv4) address, returning the address
-   * as a list of 4 bytes in network byte order (big endian).
-   *
-   * Throws a [FormatException] if [host] is not a valid IPv4 address
-   * representation.
-   */
-  static List<int> parseIPv4Address(String host) {
-    void error(String msg) {
-      throw new FormatException('Illegal IPv4 address, $msg');
-    }
-    var bytes = host.split('.');
-    if (bytes.length != 4) {
-      error('IPv4 address should contain exactly 4 parts');
-    }
-    // TODO(ajohnsen): Consider using Uint8List.
-    return bytes
-        .map((byteString) {
-          int byte = int.parse(byteString);
-          if (byte < 0 || byte > 255) {
-            error('each part must be in the range of `0..255`');
-          }
-          return byte;
-        })
-        .toList();
-  }
-
-  /**
-   * Parse the [host] as an IP version 6 (IPv6) address, returning the address
-   * as a list of 16 bytes in network byte order (big endian).
-   *
-   * Throws a [FormatException] if [host] is not a valid IPv6 address
-   * representation.
-   *
-   * Acts on the substring from [start] to [end]. If [end] is omitted, it
-   * defaults ot the end of the string.
-   *
-   * Some examples of IPv6 addresses:
-   *  * ::1
-   *  * FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
-   *  * 3ffe:2a00:100:7031::1
-   *  * ::FFFF:129.144.52.38
-   *  * 2010:836B:4179::836B:4179
-   */
-  static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
-    if (end == null) end = host.length;
-    // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, seperated
-    // by `:`'s, with the following exceptions:
-    //
-    //  - One (and only one) wildcard (`::`) may be present, representing a fill
-    //    of 0's. The IPv6 `::` is thus 16 bytes of `0`.
-    //  - The last two parts may be replaced by an IPv4 address.
-    void error(String msg, [position]) {
-      throw new FormatException('Illegal IPv6 address, $msg', host, position);
-    }
-    int parseHex(int start, int end) {
-      if (end - start > 4) {
-        error('an IPv6 part can only contain a maximum of 4 hex digits', start);
-      }
-      int value = int.parse(host.substring(start, end), radix: 16);
-      if (value < 0 || value > (1 << 16) - 1) {
-        error('each part must be in the range of `0x0..0xFFFF`', start);
-      }
-      return value;
-    }
-    if (host.length < 2) error('address is too short');
-    List<int> parts = [];
-    bool wildcardSeen = false;
-    int partStart = start;
-    // Parse all parts, except a potential last one.
-    for (int i = start; i < end; i++) {
-      if (host.codeUnitAt(i) == _COLON) {
-        if (i == start) {
-          // If we see a `:` in the beginning, expect wildcard.
-          i++;
-          if (host.codeUnitAt(i) != _COLON) {
-            error('invalid start colon.', i);
-          }
-          partStart = i;
-        }
-        if (i == partStart) {
-          // Wildcard. We only allow one.
-          if (wildcardSeen) {
-            error('only one wildcard `::` is allowed', i);
-          }
-          wildcardSeen = true;
-          parts.add(-1);
-        } else {
-          // Found a single colon. Parse [partStart..i] as a hex entry.
-          parts.add(parseHex(partStart, i));
-        }
-        partStart = i + 1;
-      }
-    }
-    if (parts.length == 0) error('too few parts');
-    bool atEnd = (partStart == end);
-    bool isLastWildcard = (parts.last == -1);
-    if (atEnd && !isLastWildcard) {
-      error('expected a part after last `:`', end);
-    }
-    if (!atEnd) {
-      try {
-        parts.add(parseHex(partStart, end));
-      } catch (e) {
-        // Failed to parse the last chunk as hex. Try IPv4.
-        try {
-          List<int> last = parseIPv4Address(host.substring(partStart, end));
-          parts.add(last[0] << 8 | last[1]);
-          parts.add(last[2] << 8 | last[3]);
-        } catch (e) {
-          error('invalid end of IPv6 address.', partStart);
-        }
-      }
-    }
-    if (wildcardSeen) {
-      if (parts.length > 7) {
-        error('an address with a wildcard must have less than 7 parts');
-      }
-    } else if (parts.length != 8) {
-      error('an address without a wildcard must contain exactly 8 parts');
-    }
-    List<int> bytes = new Uint8List(16);
-    for (int i = 0, index = 0; i < parts.length; i++) {
-      int value = parts[i];
-      if (value == -1) {
-        int wildCardLength = 9 - parts.length;
-        for (int j = 0; j < wildCardLength; j++) {
-          bytes[index] = 0;
-          bytes[index + 1] = 0;
-          index += 2;
-        }
-      } else {
-        bytes[index] = value >> 8;
-        bytes[index + 1] = value & 0xff;
-        index += 2;
-      }
-    }
-    return bytes;
-  }
-
-  // Frequently used character codes.
-  static const int _SPACE = 0x20;
-  static const int _DOUBLE_QUOTE = 0x22;
-  static const int _NUMBER_SIGN = 0x23;
-  static const int _PERCENT = 0x25;
-  static const int _ASTERISK = 0x2A;
-  static const int _PLUS = 0x2B;
-  static const int _DOT = 0x2E;
-  static const int _SLASH = 0x2F;
-  static const int _ZERO = 0x30;
-  static const int _NINE = 0x39;
-  static const int _COLON = 0x3A;
-  static const int _LESS = 0x3C;
-  static const int _GREATER = 0x3E;
-  static const int _QUESTION = 0x3F;
-  static const int _AT_SIGN = 0x40;
-  static const int _UPPER_CASE_A = 0x41;
-  static const int _UPPER_CASE_F = 0x46;
-  static const int _UPPER_CASE_Z = 0x5A;
-  static const int _LEFT_BRACKET = 0x5B;
-  static const int _BACKSLASH = 0x5C;
-  static const int _RIGHT_BRACKET = 0x5D;
-  static const int _LOWER_CASE_A = 0x61;
-  static const int _LOWER_CASE_F = 0x66;
-  static const int _LOWER_CASE_Z = 0x7A;
-  static const int _BAR = 0x7C;
-
-  static const String _hexDigits = "0123456789ABCDEF";
-
   external static String _uriEncode(List<int> canonicalTable,
                                     String text,
                                     Encoding encoding,
@@ -2941,13 +3191,13 @@
         throw new ArgumentError.value(mimeType, "mimeType",
                                       "Invalid MIME type");
       }
-      buffer.write(Uri._uriEncode(_tokenCharTable,
-                                  mimeType.substring(0, slashIndex),
-                                  UTF8, false));
+      buffer.write(_Uri._uriEncode(_tokenCharTable,
+                                   mimeType.substring(0, slashIndex),
+                                   UTF8, false));
       buffer.write("/");
-      buffer.write(Uri._uriEncode(_tokenCharTable,
-                                  mimeType.substring(slashIndex + 1),
-                                  UTF8, false));
+      buffer.write(_Uri._uriEncode(_tokenCharTable,
+                                   mimeType.substring(slashIndex + 1),
+                                   UTF8, false));
     }
     if (charsetName != null) {
       if (indices != null) {
@@ -2955,7 +3205,7 @@
                ..add(buffer.length + 8);
       }
       buffer.write(";charset=");
-      buffer.write(Uri._uriEncode(_tokenCharTable, charsetName, UTF8, false));
+      buffer.write(_Uri._uriEncode(_tokenCharTable, charsetName, UTF8, false));
     }
     parameters?.forEach((var key, var value) {
       if (key.isEmpty) {
@@ -2968,10 +3218,10 @@
       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));
+      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));
+      buffer.write(_Uri._uriEncode(_tokenCharTable, value, UTF8, false));
     });
   }
 
@@ -2988,7 +3238,7 @@
     int slashIndex = -1;
     for (int i = 0; i < mimeType.length; i++) {
       var char = mimeType.codeUnitAt(i);
-      if (char != Uri._SLASH) continue;
+      if (char != _SLASH) continue;
       if (slashIndex < 0) {
         slashIndex = i;
         continue;
@@ -3008,7 +3258,7 @@
    * ````
    *
    * where `type`, `subtype`, `attribute` and `value` are specified in RFC-2045,
-   * and `data` is a sequnce of URI-characters (RFC-2396 `uric`).
+   * and `data` is a sequence 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
@@ -3019,13 +3269,22 @@
    * 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.
+   * content that can't be decoded successfully as a string.
    */
   static UriData parse(String uri) {
-    if (!uri.startsWith("data:")) {
-      throw new FormatException("Does not start with 'data:'", uri, 0);
+    if (uri.length >= 5) {
+      int dataDelta = _startsWithData(uri, 0);
+      if (dataDelta == 0) {
+        // Exact match on "data:".
+        return _parse(uri, 5, null);
+      }
+      if (dataDelta == 0x20) {
+        // Starts with a non-normalized "data" scheme containing upper-case
+        // letters. Parse anyway, but throw away the scheme.
+        return _parse(uri.substring(5), 0, null);
+      }
     }
-    return _parse(uri, 5, null);
+    throw new FormatException("Does not start with 'data:'", uri, 0);
   }
 
   /**
@@ -3050,7 +3309,7 @@
     // That's perfectly reasonable - data URIs are not hierarchical,
     // but it may make some consumers stumble.
     // Should we at least do escape normalization?
-    _uriCache = new Uri._internal("data", "", null, null, path, query, null);
+    _uriCache = new _Uri._internal("data", "", null, null, path, query, null);
     return _uriCache;
   }
 
@@ -3075,7 +3334,7 @@
     int start = _separatorIndices[0] + 1;
     int end = _separatorIndices[1];
     if (start == end) return "text/plain";
-    return Uri._uriDecode(_text, start, end, UTF8, false);
+    return _Uri._uriDecode(_text, start, end, UTF8, false);
   }
 
   /**
@@ -3096,8 +3355,8 @@
       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 _Uri._uriDecode(_text, keyEnd + 1, _separatorIndices[i + 2],
+                               UTF8, false);
       }
     }
     return "US-ASCII";
@@ -3155,8 +3414,8 @@
         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));
+          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;
@@ -3177,7 +3436,7 @@
    * 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
+   * if it is recognized by [Encoding.getByName], otherwise it defaults to
    * the [ASCII] encoding, which is the default encoding for data URIs
    * that do not specify an encoding.
    *
@@ -3199,7 +3458,7 @@
       var converter = BASE64.decoder.fuse(encoding.decoder);
       return converter.convert(text.substring(start));
     }
-    return Uri._uriDecode(text, start, text.length, encoding, false);
+    return _Uri._uriDecode(text, start, text.length, encoding, false);
   }
 
   /**
@@ -3222,8 +3481,8 @@
       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);
+      String key = _Uri._uriDecode(_text, start, equals, UTF8, false);
+      String value = _Uri._uriDecode(_text,equals + 1, end, UTF8, false);
       result[key] = value;
     }
     return result;
@@ -3306,9 +3565,9 @@
           ((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));
+        buffer.writeCharCode(_PERCENT);
+        buffer.writeCharCode(_hexDigits.codeUnitAt(byte >> 4));
+        buffer.writeCharCode(_hexDigits.codeUnitAt(byte & 0x0f));
       }
     }
     if ((byteOr & ~0xFF) != 0) {
@@ -3357,5 +3616,852 @@
   //  mark        =  "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
   //
   // This is the same characters as in a URI query (which is URI pchar plus '?')
-  static const _uricTable = Uri._queryCharTable;
+  static const _uricTable = _Uri._queryCharTable;
 }
+
+// --------------------------------------------------------------------
+// Constants used to read the scanner result.
+// The indices points into the table filled by [_scan] which contains
+// recognized positions in the scanned URI.
+// The `0` index is only used internally.
+
+/// Index of the position of that `:` after a scheme.
+const int _schemeEndIndex     = 1;
+/// Index of the position of the character just before the host name.
+const int _hostStartIndex     = 2;
+/// Index of the position of the `:` before a port value.
+const int _portStartIndex     = 3;
+/// Index of the position of the first character of a path.
+const int _pathStartIndex     = 4;
+/// Index of the position of the `?` before a query.
+const int _queryStartIndex    = 5;
+/// Index of the position of the `#` before a fragment.
+const int _fragmentStartIndex = 6;
+/// Index of a position where the URI was determined to be "non-simple".
+const int _notSimpleIndex     = 7;
+
+// Initial state for scanner.
+const int _uriStart           = 00;
+
+// If scanning of a URI terminates in this state or above,
+// consider the URI non-simple
+const int _nonSimpleEndStates = 14;
+
+// Initial state for scheme validation.
+const int _schemeStart        = 20;
+
+/// Transition tables used to scan a URI to determine its structure.
+///
+/// The tables represent a state machine with output.
+///
+/// To scan the URI, start in the [_uriStart] state, then read each character
+/// of the URI in order, from start to end, and for each character perform a
+/// transition to a new state while writing the current position into the output
+/// buffer at a designated index.
+///
+/// Each state, represented by an integer which is an index into
+/// [_scannerTables], has a set of transitions, one for each character.
+/// The transitions are encoded as a 5-bit integer representing the next state
+/// and a 3-bit index into the output table.
+///
+/// For URI scanning, only characters in the range U+0020 through U+007E are
+/// interesting, all characters outside that range are treated the same.
+/// The tables only contain 96 entries, representing that characters in the
+/// interesting range, plus one more to represent all values outside the range.
+/// The character entries are stored in one `Uint8List` per state, with the
+/// transition for a character at position `character ^ 0x60`,
+/// which maps the range U+0020 .. U+007F into positions 0 .. 95.
+/// All remaining characters are mapped to position 31 (`0x7f ^ 0x60`) which
+/// represents the transition for all remaining characters.
+final List<Uint8List> _scannerTables = _createTables();
+
+// ----------------------------------------------------------------------
+// Code to create the URI scanner table.
+
+/// Creates the tables for [_scannerTables] used by [Uri.parse].
+///
+/// See [_scannerTables] for the generated format.
+///
+/// The concrete tables are chosen as a trade-off between the number of states
+/// needed and the precision of the result.
+/// This allows definitely recognizing the general structure of the URI
+/// (presence and location of scheme, user-info, host, port, path, query and
+/// fragment) while at the same time detecting that some components are not
+/// in canonical form (anything containing a `%`, a host-name containing a
+/// capital letter). Since the scanner doesn't know whether something is a
+/// scheme or a path until it sees `:`, or user-info or host until it sees
+/// a `@`, a second pass is needed to validate the scheme and any user-info
+/// is considered non-canonical by default.
+///
+/// The states (starting from [_uriStart]) write positions while scanning
+/// a string from `start` to `end` as follows:
+///
+/// - [_schemeEndIndex]: Should be initialized to `start-1`.
+///   If the URI has a scheme, it is set to the position of the `:` after
+///   the scheme.
+/// - [_hostStartIndex]: Should be initialized to `start - 1`.
+///   If the URI has an authority, it is set to the character before the
+///   host name - either the second `/` in the `//` leading the authority,
+///   or the `@` after a user-info. Comparing this value to the scheme end
+///   position can be used to detect that there is a user-info component.
+/// - [_portStartIndex]: Should be initialized to `start`.
+///   Set to the position of the last `:` in an authority, and unchanged
+///   if there is no authority or no `:` in an authority.
+///   If this position is after the host start, there is a port, otherwise it
+///   is just marking a colon in the user-info component.
+/// - [_pathStartIndex]: Should be initialized to `start`.
+///   Is set to the first path character unless the path is empty.
+///   If the path is empty, the position is either unchanged (`start`) or
+///   the first slash of an authority. So, if the path start is before a
+///   host start or scheme end, the path is empty.
+/// - [_queryStartIndex]: Should be initialized to `end`.
+///   The position of the `?` leading a query if the URI contains a query.
+/// - [_fragmentStartIndex]: Should be initialized to `end`.
+///   The position of the `#` leading a fragment if the URI contains a fragment.
+/// - [_notSimpleIndex]: Should be initialized to `start - 1`.
+///   Set to another value if the URI is considered "not simple".
+///   This is elaborated below.
+///
+/// # Simple URIs
+/// A URI is considered "simple" if it is in a normalized form containing no
+/// escapes. This allows us to skip normalization and checking whether escapes
+/// are valid, and to extract components without worrying about unescaping.
+///
+/// The scanner computes a conservative approximation of being "simple".
+/// It rejects any URI with an escape, with a user-info component (mainly
+/// because they are rare and would increase the number of states in the
+/// scanner significantly), with an IPV6 host or with a capital letter in
+/// the scheme or host name (the scheme is handled in a second scan using
+/// a separate two-state table).
+/// Further, paths containing `..` or `.` path segments are considered
+/// non-simple except for pure relative paths (no scheme or authority) starting
+/// with a sequence of "../" segments.
+///
+/// The transition tables cannot detect a trailing ".." in the path,
+/// followed by a query or fragment, because the segment is not known to be
+/// complete until we are past it, and we then need to store the query/fragment
+/// start instead. This cast is checked manually post-scanning (such a path
+/// needs to be normalized to end in "../", so the URI shouldn't be considered
+/// simple).
+List<Uint8List> _createTables() {
+  // TODO(lrn): Use a precomputed table.
+
+  // Total number of states for the scanner.
+  const int stateCount         = 22;
+
+  // States used to scan a URI from scratch.
+  const int schemeOrPath       = 01;
+  const int authOrPath         = 02;
+  const int authOrPathSlash    = 03;
+  const int uinfoOrHost0       = 04;
+  const int uinfoOrHost        = 05;
+  const int uinfoOrPort0       = 06;
+  const int uinfoOrPort        = 07;
+  const int ipv6Host           = 08;
+  const int relPathSeg         = 09;
+  const int pathSeg            = 10;
+  const int path               = 11;
+  const int query              = 12;
+  const int fragment           = 13;
+  const int schemeOrPathDot    = 14;
+  const int schemeOrPathDot2   = 15;
+  const int relPathSegDot      = 16;
+  const int relPathSegDot2     = 17;
+  const int pathSegDot         = 18;
+  const int pathSegDot2        = 19;
+
+  // States used to validate a scheme after its end position has been found.
+  const int scheme0            = _schemeStart;
+  const int scheme             = 21;
+
+  // Constants encoding the write-index for the state transition into the top 5
+  // bits of a byte.
+  const int schemeEnd          = _schemeEndIndex     << 5;
+  const int hostStart          = _hostStartIndex     << 5;
+  const int portStart          = _portStartIndex     << 5;
+  const int pathStart          = _pathStartIndex     << 5;
+  const int queryStart         = _queryStartIndex    << 5;
+  const int fragmentStart      = _fragmentStartIndex << 5;
+  const int notSimple          = _notSimpleIndex     << 5;
+
+  /// The `unreserved` characters of RFC 3986.
+  const unreserved =
+      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~"  ;
+  /// The `sub-delim` characters of RFC 3986.
+  const subDelims = r"!$&'()*+,;=";
+  // The `pchar` characters of RFC 3986: characters that may occur in a path,
+  // excluding escapes.
+  const pchar = "$unreserved$subDelims";
+
+  var tables = new List<Uint8List>.generate(stateCount,
+      (_) => new Uint8List(96));
+
+  // Helper function which initialize the table for [state] with a default
+  // transition and returns the table.
+  Uint8List build(state, defaultTransition) =>
+      tables[state]..fillRange(0, 96, defaultTransition);
+
+  // Helper function which sets the transition for each character in [chars]
+  // to [transition] in the [target] table.
+  // The [chars] string must contain only characters in the U+0020 .. U+007E
+  // range.
+  void setChars(Uint8List target, String chars, int transition) {
+    for (int i = 0; i < chars.length; i++) {
+      var char = chars.codeUnitAt(i);
+      target[char ^ 0x60] = transition;
+    }
+  }
+
+  /// Helper function which sets the transition for all characters in the
+  /// range from `range[0]` to `range[1]` to [transition] in the [target] table.
+  ///
+  /// The [range] must be a two-character string where both characters are in
+  /// the U+0020 .. U+007E range and the former character must have a lower
+  /// code point than the latter.
+  void setRange(Uint8List target, String range, int transition) {
+    for (int i = range.codeUnitAt(0), n = range.codeUnitAt(1); i <= n; i++) {
+      target[i ^ 0x60] = transition;
+    }
+  }
+
+  // Create the transitions for each state.
+  var b;
+
+  // Validate as path, if it is a scheme, we handle it later.
+  b = build(_uriStart, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, ".", schemeOrPathDot);
+  setChars(b, ":", authOrPath | schemeEnd);  // Handle later.
+  setChars(b, "/", authOrPathSlash);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(schemeOrPathDot, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, ".", schemeOrPathDot2);
+  setChars(b, ':', authOrPath | schemeEnd);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(schemeOrPathDot2, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, "%", schemeOrPath | notSimple);
+  setChars(b, ':', authOrPath | schemeEnd);
+  setChars(b, "/", relPathSeg);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(schemeOrPath, schemeOrPath | notSimple);
+  setChars(b, pchar, schemeOrPath);
+  setChars(b, ':', authOrPath | schemeEnd);
+  setChars(b, "/", pathSeg);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(authOrPath, path | notSimple);
+  setChars(b, pchar, path | pathStart);
+  setChars(b, "/", authOrPathSlash | pathStart);
+  setChars(b, ".", pathSegDot | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(authOrPathSlash, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", uinfoOrHost0 | hostStart);
+  setChars(b, ".", pathSegDot);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrHost0, uinfoOrHost | notSimple);
+  setChars(b, pchar, uinfoOrHost);
+  setRange(b, "AZ", uinfoOrHost | notSimple);
+  setChars(b, ":", uinfoOrPort0 | portStart);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "[", ipv6Host | notSimple);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrHost, uinfoOrHost | notSimple);
+  setChars(b, pchar, uinfoOrHost);
+  setRange(b, "AZ", uinfoOrHost | notSimple);
+  setChars(b, ":", uinfoOrPort0 | portStart);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrPort0, uinfoOrPort | notSimple);
+  setRange(b, "19", uinfoOrPort);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(uinfoOrPort, uinfoOrPort | notSimple);
+  setRange(b, "09", uinfoOrPort);
+  setChars(b, "@", uinfoOrHost0 | hostStart);
+  setChars(b, "/", pathSeg | pathStart);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(ipv6Host, ipv6Host);
+  setChars(b, "]", uinfoOrHost);
+
+  b = build(relPathSeg, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", relPathSegDot);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(relPathSegDot, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", relPathSegDot2);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(relPathSegDot2, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", relPathSeg);
+  setChars(b, "?", query | queryStart);  // This should be non-simple.
+  setChars(b, "#", fragment | fragmentStart);  // This should be non-simple.
+
+  b = build(pathSeg, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", pathSegDot);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(pathSegDot, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, ".", pathSegDot2);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(pathSegDot2, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", pathSeg | notSimple);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(path, path | notSimple);
+  setChars(b, pchar, path);
+  setChars(b, "/", pathSeg);
+  setChars(b, "?", query | queryStart);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(query, query | notSimple);
+  setChars(b, pchar, query);
+  setChars(b, "?", query);
+  setChars(b, "#", fragment | fragmentStart);
+
+  b = build(fragment, fragment | notSimple);
+  setChars(b, pchar, fragment);
+  setChars(b, "?", fragment);
+
+  // A separate two-state validator for lower-case scheme names.
+  // Any non-scheme character or upper-case letter is marked as non-simple.
+  b = build(scheme0, scheme | notSimple);
+  setRange(b, "az", scheme);
+
+  b = build(scheme, scheme | notSimple);
+  setRange(b, "az", scheme);
+  setRange(b, "09", scheme);
+  setChars(b, "+-.", scheme);
+
+  return tables;
+}
+
+// --------------------------------------------------------------------
+// Code that uses the URI scanner table.
+
+/// Scan a string using the [_scannerTables] state machine.
+///
+/// Scans [uri] from [start] to [end], startig in state [state] and
+/// writing output into [indices].
+///
+/// Returns the final state.
+int _scan(String uri, int start, int end, int state, List<int> indices) {
+  var tables = _scannerTables;
+  assert(end <= uri.length);
+  for (int i = start; i < end; i++) {
+    var table = tables[state];
+    // Xor with 0x60 to move range 0x20-0x7f into 0x00-0x5f
+    int char = uri.codeUnitAt(i) ^ 0x60;
+    // Use 0x1f (nee 0x7f) to represent all unhandled characters.
+    if (char > 0x5f) char = 0x1f;
+    int transition = table[char];
+    state = transition & 0x1f;
+    indices[transition >> 5] = i;
+  }
+  return state;
+}
+
+class _SimpleUri implements Uri {
+  final String _uri;
+  final int _schemeEnd;
+  final int _hostStart;
+  final int _portStart;
+  final int _pathStart;
+  final int _queryStart;
+  final int _fragmentStart;
+  /// The scheme is often used to distinguish URIs.
+  /// To make comparisons more efficient, we cache the value, and
+  /// canonicalize a few known types.
+  String _schemeCache;
+  int _hashCodeCache;
+
+  _SimpleUri(
+      this._uri,
+      this._schemeEnd,
+      this._hostStart,
+      this._portStart,
+      this._pathStart,
+      this._queryStart,
+      this._fragmentStart,
+      this._schemeCache);
+
+  bool get hasScheme => _schemeEnd > 0;
+  bool get hasAuthority => _hostStart > 0;
+  bool get hasUserInfo => _hostStart > _schemeEnd + 4;
+  bool get hasPort => _hostStart > 0 && _portStart + 1 < _pathStart;
+  bool get hasQuery => _queryStart < _fragmentStart;
+  bool get hasFragment => _fragmentStart < _uri.length;
+
+  bool get _isFile => _schemeEnd == 4 && _uri.startsWith("file");
+  bool get _isHttp => _schemeEnd == 4 && _uri.startsWith("http");
+  bool get _isHttps => _schemeEnd == 5 && _uri.startsWith("https");
+  bool get _isPackage => _schemeEnd == 7 && _uri.startsWith("package");
+  bool _isScheme(String scheme) =>
+    _schemeEnd == scheme.length && _uri.startsWith(scheme);
+
+  bool get hasAbsolutePath => _uri.startsWith("/", _pathStart);
+  bool get hasEmptyPath => _pathStart == _queryStart;
+
+  bool get isAbsolute => hasScheme && !hasFragment;
+
+  String get scheme {
+    if (_schemeEnd <= 0) return "";
+    if (_schemeCache != null) return _schemeCache;
+    if (_isHttp) {
+      _schemeCache = "http";
+    } else if (_isHttps) {
+      _schemeCache = "https";
+    } else if (_isFile) {
+      _schemeCache = "file";
+    } else if (_isPackage) {
+      _schemeCache = "package";
+    } else {
+      _schemeCache = _uri.substring(0, _schemeEnd);
+    }
+    return _schemeCache;
+  }
+  String get authority => _hostStart > 0 ?
+      _uri.substring(_schemeEnd + 3, _pathStart) : "";
+  String get userInfo => (_hostStart > _schemeEnd + 3) ?
+      _uri.substring(_schemeEnd + 3, _hostStart - 1) : "";
+  String get host =>
+      _hostStart > 0 ? _uri.substring(_hostStart, _portStart) : "";
+  int get port {
+    if (hasPort) return int.parse(_uri.substring(_portStart + 1, _pathStart));
+    if (_isHttp) return 80;
+    if (_isHttps) return 443;
+    return 0;
+  }
+  String get path =>_uri.substring(_pathStart, _queryStart);
+  String get query => (_queryStart < _fragmentStart) ?
+     _uri.substring(_queryStart + 1, _fragmentStart) : "";
+  String get fragment => (_fragmentStart < _uri.length) ?
+     _uri.substring(_fragmentStart + 1) : "";
+
+  String get origin {
+    // Check original behavior - W3C spec is wonky!
+    bool isHttp = _isHttp;
+    if (_schemeEnd < 0 || _hostStart == _portStart) {
+      throw new StateError("Cannot use origin without a scheme: $this");
+    }
+    if (!isHttp && !_isHttps) {
+      throw new StateError(
+        "Origin is only applicable schemes http and https: $this");
+    }
+    if (_hostStart == _schemeEnd + 3) {
+      return _uri.substring(0, _pathStart);
+    }
+    // Need to drop anon-empty userInfo.
+    return _uri.substring(0, _schemeEnd + 3) +
+           _uri.substring(_hostStart, _pathStart);
+  }
+
+  List<String> get pathSegments {
+    int start = _pathStart;
+    int end = _queryStart;
+    if (_uri.startsWith("/", start)) start++;
+    if (start == end) return const <String>[];
+    List<String> parts = [];
+    for (int i = start; i < end; i++) {
+      var char = _uri.codeUnitAt(i);
+      if (char == _SLASH) {
+        parts.add(_uri.substring(start, i));
+        start = i + 1;
+      }
+    }
+    parts.add(_uri.substring(start, end));
+    return new List<String>.unmodifiable(parts);
+  }
+
+  Map<String, String> get queryParameters {
+    if (!hasQuery) return const <String, String>{};
+    return new UnmodifiableMapView<String, String>(
+        Uri.splitQueryString(query));
+  }
+
+  Map<String, List<String>> get queryParametersAll {
+    if (!hasQuery) return const <String, List<String>>{};
+    Map queryParameterLists = _Uri._splitQueryStringAll(query);
+    for (var key in queryParameterLists.keys) {
+      queryParameterLists[key] =
+          new List<String>.unmodifiable(queryParameterLists[key]);
+    }
+    return new Map<String, List<String>>.unmodifiable(queryParameterLists);
+  }
+
+  bool _isPort(String port) {
+    int portDigitStart = _portStart + 1;
+    return portDigitStart + port.length == _pathStart &&
+           _uri.startsWith(port, portDigitStart);
+  }
+
+  Uri normalizePath() => this;
+
+  Uri removeFragment() {
+    if (!hasFragment) return this;
+    return new _SimpleUri(
+      _uri.substring(0, _fragmentStart),
+      _schemeEnd, _hostStart, _portStart,
+      _pathStart, _queryStart, _fragmentStart, _schemeCache);
+  }
+
+  Uri replace({String scheme,
+               String userInfo,
+               String host,
+               int port,
+               String path,
+               Iterable<String> pathSegments,
+               String query,
+               Map<String, dynamic/*String|Iterable<String>*/> queryParameters,
+               String fragment}) {
+    bool schemeChanged = false;
+    if (scheme != null) {
+      scheme = _Uri._makeScheme(scheme, 0, scheme.length);
+      schemeChanged = !_isScheme(scheme);
+    } else {
+      scheme = this.scheme;
+    }
+    bool isFile = (scheme == "file");
+    if (userInfo != null) {
+      userInfo = _Uri._makeUserInfo(userInfo, 0, userInfo.length);
+    } else if (_hostStart > 0) {
+      userInfo = _uri.substring(_schemeEnd + 3, _hostStart);
+    } else {
+      userInfo = "";
+    }
+    if (port != null) {
+      port = _Uri._makePort(port, scheme);
+    } else {
+      port = this.hasPort ? this.port : null;
+      if (schemeChanged) {
+        // The default port might have changed.
+        port = _Uri._makePort(port, scheme);
+      }
+    }
+    if (host != null) {
+      host = _Uri._makeHost(host, 0, host.length, false);
+    } else if (_hostStart > 0) {
+      host = _uri.substring(_hostStart, _portStart);
+    } else if (userInfo.isNotEmpty || port != null || isFile) {
+      host = "";
+    }
+
+    bool hasAuthority = host != null;
+    if (path != null || pathSegments != null) {
+      path = _Uri._makePath(path, 0, _stringOrNullLength(path), pathSegments,
+                           scheme, hasAuthority);
+    } else {
+      path = _uri.substring(_pathStart, _queryStart);
+      if ((isFile || (hasAuthority && !path.isEmpty)) &&
+          !path.startsWith('/')) {
+        path = "/" + path;
+      }
+    }
+
+    if (query != null || queryParameters != null) {
+      query = _Uri._makeQuery(
+          query, 0, _stringOrNullLength(query), queryParameters);
+    } else if (_queryStart < _fragmentStart) {
+      query = _uri.substring(_queryStart + 1, _fragmentStart);
+    }
+
+    if (fragment != null) {
+      fragment = _Uri._makeFragment(fragment, 0, fragment.length);
+    } else if (_fragmentStart < _uri.length) {
+      fragment = _uri.substring(_fragmentStart + 1);
+    }
+
+    return new _Uri._internal(
+        scheme, userInfo, host, port, path, query, fragment);
+  }
+
+  Uri resolve(String reference) {
+    return resolveUri(Uri.parse(reference));
+  }
+
+  Uri resolveUri(Uri reference) {
+    if (reference is _SimpleUri) {
+      return _simpleMerge(this, reference);
+    }
+    return _toNonSimple().resolveUri(reference);
+  }
+
+  // Merge two simple URIs. This should always result in a prefix of
+  // one concatentated with a suffix of the other, possibly with a `/` in
+  // the middle of two merged paths, which is again simple.
+  // In a few cases, there might be a need for extra normalization, when
+  // resolving on top of a known scheme.
+  Uri _simpleMerge(_SimpleUri base, _SimpleUri ref) {
+    if (ref.hasScheme) return ref;
+    if (ref.hasAuthority) {
+      if (!base.hasScheme) return ref;
+      bool isSimple = true;
+      if (base._isFile) {
+        isSimple = !ref.hasEmptyPath;
+      } else if (base._isHttp) {
+        isSimple = !ref._isPort("80");
+      } else if (base._isHttps) {
+        isSimple = !ref._isPort("443");
+      }
+      if (isSimple) {
+        var delta = base._schemeEnd + 1;
+        var newUri = base._uri.substring(0, base._schemeEnd + 1) +
+                     ref._uri.substring(ref._schemeEnd + 1);
+        return new _SimpleUri(newUri,
+           base._schemeEnd,
+           ref._hostStart + delta,
+           ref._portStart + delta,
+           ref._pathStart + delta,
+           ref._queryStart + delta,
+           ref._fragmentStart + delta,
+           base._schemeCache);
+      } else {
+        // This will require normalization, so use the _Uri implementation.
+        return _toNonSimple().resolveUri(ref);
+      }
+    }
+    if (ref.hasEmptyPath) {
+      if (ref.hasQuery) {
+        int delta = base._queryStart - ref._queryStart;
+        var newUri = base._uri.substring(0, base._queryStart) +
+                     ref._uri.substring(ref._queryStart);
+        return new _SimpleUri(newUri,
+           base._schemeEnd,
+           base._hostStart,
+           base._portStart,
+           base._pathStart,
+           ref._queryStart + delta,
+           ref._fragmentStart + delta,
+           base._schemeCache);
+      }
+      if (ref.hasFragment) {
+        int delta = base._fragmentStart - ref._fragmentStart;
+        var newUri = base._uri.substring(0, base._fragmentStart) +
+                     ref._uri.substring(ref._fragmentStart);
+        return new _SimpleUri(newUri,
+           base._schemeEnd,
+           base._hostStart,
+           base._portStart,
+           base._pathStart,
+           base._queryStart,
+           ref._fragmentStart + delta,
+           base._schemeCache);
+      }
+      return base.removeFragment();
+    }
+    if (ref.hasAbsolutePath) {
+      var delta = base._pathStart - ref._pathStart;
+      var newUri = base._uri.substring(0, base._pathStart) +
+                   ref._uri.substring(ref._pathStart);
+      return new _SimpleUri(newUri,
+        base._schemeEnd,
+        base._hostStart,
+        base._portStart,
+        base._pathStart,
+        ref._queryStart + delta,
+        ref._fragmentStart + delta,
+        base._schemeCache);
+    }
+    if (base.hasEmptyPath && base.hasAuthority) {
+      // ref has relative non-empty path.
+      // Add a "/" in front, then leading "/../" segments are folded to "/".
+      int refStart = ref._pathStart;
+      while (ref._uri.startsWith("../", refStart)) {
+        refStart += 3;
+      }
+      var delta = base._pathStart - refStart + 1;
+      var newUri = "${base._uri.substring(0, base._pathStart)}/"
+                   "${ref._uri.substring(refStart)}";
+      return new _SimpleUri(newUri,
+        base._schemeEnd,
+        base._hostStart,
+        base._portStart,
+        base._pathStart,
+        ref._queryStart + delta,
+        ref._fragmentStart + delta,
+        base._schemeCache);
+    }
+    // Merge paths.
+    if (base._uri.startsWith("../", base._pathStart)) {
+      // Complex rare case, go slow.
+      return _toNonSimple().resolveUri(ref);
+    }
+
+    // The RFC 3986 algorithm merges the base path without its final segment
+    // (anything after the final "/", or everything if the base path doesn't
+    // contain any "/"), and the reference path.
+    // Then it removes "." and ".." segments using the remove-dot-segment
+    // algorithm.
+    // This code combines the two steps. It is simplified by knowing that
+    // the base path contains no "." or ".." segments, and the reference
+    // path can only contain leading ".." segments.
+
+    String baseUri = base._uri;
+    String refUri = ref._uri;
+    int baseStart = base._pathStart;
+    int baseEnd = base._queryStart;
+    int refStart = ref._pathStart;
+    int refEnd = ref._queryStart;
+    int backCount = 1;
+
+    int slashCount = 0;
+
+    // Count leading ".." segments in reference path.
+    while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) {
+      refStart += 3;
+      backCount += 1;
+    }
+
+    // Extra slash inserted between base and reference path parts if
+    // the base path contains any slashes.
+    // (We could use a slash from the base path in most cases, but not if
+    // we remove the entire base path).
+    String insert = "";
+    while (baseEnd > baseStart) {
+      baseEnd--;
+      int char = baseUri.codeUnitAt(baseEnd);
+      if (char == _SLASH) {
+        insert = "/";
+        backCount--;
+        if (backCount == 0) break;
+      }
+    }
+    // If the base URI has no scheme or authority (`_pathStart == 0`)
+    // and a relative path, and we reached the beginning of the path,
+    // we have a special case.
+    if (baseEnd == 0 && !base.hasAbsolutePath) {
+      // Non-RFC 3986 behavior when resolving a purely relative path on top of
+      // another relative path: Don't make the result absolute.
+      insert = "";
+    }
+
+    var delta = baseEnd - refStart + insert.length;
+    var newUri = "${base._uri.substring(0, baseEnd)}$insert"
+               "${ref._uri.substring(refStart)}";
+
+    return new _SimpleUri(newUri,
+      base._schemeEnd,
+      base._hostStart,
+      base._portStart,
+      base._pathStart,
+      ref._queryStart + delta,
+      ref._fragmentStart + delta,
+      base._schemeCache);
+  }
+
+  String toFilePath({bool windows}) {
+    if (_schemeEnd >= 0 && !_isFile) {
+      throw new UnsupportedError(
+          "Cannot extract a file path from a $scheme URI");
+    }
+    if (_queryStart < _uri.length) {
+      if (_queryStart < _fragmentStart) {
+        throw new UnsupportedError(
+            "Cannot extract a file path from a URI with a query component");
+      }
+      throw new UnsupportedError(
+          "Cannot extract a file path from a URI with a fragment component");
+    }
+    if (windows == null) windows = _Uri._isWindows;
+    return windows ? _Uri._toWindowsFilePath(this) : _toFilePath();
+  }
+
+  String _toFilePath() {
+    if (_hostStart < _portStart) {
+      // Has authority and non-empty host.
+      throw new UnsupportedError(
+        "Cannot extract a non-Windows file path from a file URI "
+        "with an authority");
+    }
+    return this.path;
+  }
+
+  UriData get data {
+    assert(scheme != "data");
+    return null;
+  }
+
+  int get hashCode => _hashCodeCache ??= _uri.hashCode;
+
+  bool operator==(Object other) {
+    if (identical(this, other)) return true;
+    if (other is Uri) return _uri == other.toString();
+    return false;
+  }
+
+  Uri _toNonSimple() {
+    return new _Uri._internal(
+      this.scheme,
+      this.userInfo,
+      this.hasAuthority ? this.host: null,
+      this.hasPort ? this.port : null,
+      this.path,
+      this.hasQuery ? this.query : null,
+      this.hasFragment ? this.fragment : null
+    );
+  }
+
+  String toString() => _uri;
+}
+
+/// Checks whether [text] starts with "data:" at position [start].
+///
+/// The text must be long enough to allow reading five characters
+/// from the [start] position.
+///
+/// Returns an integer value which is zero if text starts with all-lowercase
+/// "data:" and 0x20 if the text starts with "data:" that isn't all lower-case.
+/// All other values means the text starts with some other character.
+int _startsWithData(String text, int start) {
+  // Multiply by 3 to avoid a non-colon character making delta be 0x20.
+  int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3;
+  delta |= text.codeUnitAt(start)     ^ 0x64 /*d*/;
+  delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/;
+  delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/;
+  delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/;
+  return delta;
+}
+
+/// Helper function returning the length of a string, or `0` for `null`.
+int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
diff --git a/sdk/lib/dart2dart.platform b/sdk/lib/dart2dart.platform
deleted file mode 100644
index fd9d8ed..0000000
--- a/sdk/lib/dart2dart.platform
+++ /dev/null
@@ -1,48 +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.
-
-# 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
index 2e01cd9..38442ef 100644
--- a/sdk/lib/dart_client.platform
+++ b/sdk/lib/dart_client.platform
@@ -26,6 +26,7 @@
 io: unsupported:
 isolate: isolate/isolate.dart
 js: js/dart2js/js_dart2js.dart
+js_util: js_util/dart2js/js_util_dart2js.dart
 math: math/math.dart
 mirrors: mirrors/mirrors.dart
 nativewrappers: html/dart2js/nativewrappers.dart
diff --git a/sdk/lib/dart_server.platform b/sdk/lib/dart_server.platform
index 821a175..f275aff 100644
--- a/sdk/lib/dart_server.platform
+++ b/sdk/lib/dart_server.platform
@@ -35,6 +35,7 @@
 web_sql: unsupported:
 _chrome: unsupported:
 js: unsupported:
+js_util: unsupported:
 _mirror_helper: unsupported:
 _internal: internal/internal.dart
 _js_helper: _internal/js_runtime/lib/js_helper.dart
diff --git a/sdk/lib/dart_shared.platform b/sdk/lib/dart_shared.platform
index 539b868..ae47359 100644
--- a/sdk/lib/dart_shared.platform
+++ b/sdk/lib/dart_shared.platform
@@ -24,6 +24,7 @@
 io: io/io.dart
 isolate: isolate/isolate.dart
 js: js/dart2js/js_dart2js.dart
+js_util: js_util/dart2js/js_util_dart2js.dart
 math: math/math.dart
 mirrors: mirrors/mirrors.dart
 nativewrappers: html/dart2js/nativewrappers.dart
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index b4f835b..c26229d 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -11507,11 +11507,11 @@
            another.y <= top + height;
   }
 
-  Point get topLeft => new Point(this.left, this.top);
-  Point get topRight => new Point(this.left + this.width, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
+  Point get topLeft => new Point/*<num>*/(this.left, this.top);
+  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
+  Point get bottomRight => new Point/*<num>*/(this.left + this.width,
       this.top + this.height);
-  Point get bottomLeft => new Point(this.left,
+  Point get bottomLeft => new Point/*<num>*/(this.left,
       this.top + this.height);
 
     // To suppress missing implicit constructor warnings.
@@ -13865,13 +13865,13 @@
     bool sameAsParent = identical(current, parent);
     bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
     if (current == null || sameAsParent) {
-      if (foundAsParent) return new Point(0, 0);
+      if (foundAsParent) return new Point/*<num>*/(0, 0);
       throw new ArgumentError("Specified element is not a transitive offset "
           "parent of this element.");
     }
     Element parentOffset = current.offsetParent;
     Point p = Element._offsetToHelper(parentOffset, parent);
-    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
+    return new Point/*<num>*/(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
 
   static HtmlDocument _parseDocument;
@@ -17673,6 +17673,8 @@
 
   @DomName('Gamepad.buttons')
   @DocsEditable()
+  @Creates('JSExtendableArray|GamepadButton')
+  @Returns('JSExtendableArray')
   final List<GamepadButton> buttons;
 
   @DomName('Gamepad.connected')
@@ -24071,14 +24073,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point(_clientX, _clientY);
+  Point get client => new Point/*<num>*/(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @Experimental()
-  Point get movement => new Point(_movementX, _movementY);
+  Point get movement => new Point/*<num>*/(_movementX, _movementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -24091,7 +24093,7 @@
     if (JS('bool', '!!#.offsetX', this)) {
       var x = JS('int', '#.offsetX', this);
       var y = JS('int', '#.offsetY', this);
-      return new Point(x, y);
+      return new Point/*<num>*/(x, y);
     } else {
       // Firefox does not support offsetX.
       if (!(this.target is Element)) {
@@ -24100,21 +24102,21 @@
       }
       Element target = this.target;
       var point = (this.client - target.getBoundingClientRect().topLeft);
-      return new Point(point.x.toInt(), point.y.toInt());
+      return new Point/*<num>*/(point.x.toInt(), point.y.toInt());
     }
   }
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point(_screenX, _screenY);
+  Point get screen => new Point/*<num>*/(_screenX, _screenY);
 
   @DomName('MouseEvent.layerX')
   @DomName('MouseEvent.layerY')
-  Point get layer => new Point(_layerX, _layerY);
+  Point get layer => new Point/*<num>*/(_layerX, _layerY);
 
   @DomName('MouseEvent.pageX')
   @DomName('MouseEvent.pageY')
-  Point get page => new Point(_pageX, _pageY);
+  Point get page => new Point/*<num>*/(_pageX, _pageY);
 }
 // 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
@@ -32743,15 +32745,15 @@
 
   @DomName('Touch.clientX')
   @DomName('Touch.clientY')
-  Point get client => new Point(__clientX, __clientY);
+  Point get client => new Point/*<num>*/(__clientX, __clientY);
 
   @DomName('Touch.pageX')
   @DomName('Touch.pageY')
-  Point get page => new Point(__pageX, __pageY);
+  Point get page => new Point/*<num>*/(__pageX, __pageY);
 
   @DomName('Touch.screenX')
   @DomName('Touch.screenY')
-  Point get screen => new Point(__screenX, __screenY);
+  Point get screen => new Point/*<num>*/(__screenX, __screenY);
 
   @DomName('Touch.radiusX')
   @DocsEditable()
@@ -37486,11 +37488,11 @@
            another.y <= top + height;
   }
 
-  Point get topLeft => new Point(this.left, this.top);
-  Point get topRight => new Point(this.left + this.width, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
+  Point get topLeft => new Point/*<num>*/(this.left, this.top);
+  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
+  Point get bottomRight => new Point/*<num>*/(this.left + this.width,
       this.top + this.height);
-  Point get bottomLeft => new Point(this.left,
+  Point get bottomLeft => new Point/*<num>*/(this.left,
       this.top + this.height);
 
     // To suppress missing implicit constructor warnings.
@@ -37900,7 +37902,7 @@
     if (JS("bool", "# >>> 0 !== # || # >= #", index,
         index, index, length))
       throw new RangeError.index(index, this);
-    return JS("Gamepad", "#[#]", this, index);
+    return JS("Gamepad|Null", "#[#]", this, index);
   }
   void operator[]=(int index, Gamepad value) {
     throw new UnsupportedError("Cannot assign element of immutable List.");
@@ -37915,7 +37917,7 @@
 
   Gamepad get first {
     if (this.length > 0) {
-      return JS('Gamepad', '#[0]', this);
+      return JS('Gamepad|Null', '#[0]', this);
     }
     throw new StateError("No elements");
   }
@@ -37923,7 +37925,7 @@
   Gamepad get last {
     int len = this.length;
     if (len > 0) {
-      return JS('Gamepad', '#[#]', this, len - 1);
+      return JS('Gamepad|Null', '#[#]', this, len - 1);
     }
     throw new StateError("No elements");
   }
@@ -37931,7 +37933,7 @@
   Gamepad get single {
     int len = this.length;
     if (len == 1) {
-      return JS('Gamepad', '#[0]', this);
+      return JS('Gamepad|Null', '#[0]', this);
     }
     if (len == 0) throw new StateError("No elements");
     throw new StateError("More than one element");
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 68ec664..0b536b6 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -12112,11 +12112,11 @@
            another.y <= top + height;
   }
 
-  Point get topLeft => new Point(this.left, this.top);
-  Point get topRight => new Point(this.left + this.width, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
+  Point get topLeft => new Point/*<num>*/(this.left, this.top);
+  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
+  Point get bottomRight => new Point/*<num>*/(this.left + this.width,
       this.top + this.height);
-  Point get bottomLeft => new Point(this.left,
+  Point get bottomLeft => new Point/*<num>*/(this.left,
       this.top + this.height);
 
     // To suppress missing implicit constructor warnings.
@@ -14449,13 +14449,13 @@
     bool sameAsParent = current == parent;
     bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
     if (current == null || sameAsParent) {
-      if (foundAsParent) return new Point(0, 0);
+      if (foundAsParent) return new Point/*<num>*/(0, 0);
       throw new ArgumentError("Specified element is not a transitive offset "
           "parent of this element.");
     }
     Element parentOffset = current.offsetParent;
     Point p = Element._offsetToHelper(parentOffset, parent);
-    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
+    return new Point/*<num>*/(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
 
   static HtmlDocument _parseDocument;
@@ -26837,14 +26837,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point(_clientX, _clientY);
+  Point get client => new Point/*<num>*/(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @Experimental()
-  Point get movement => new Point(_movementX, _movementY);
+  Point get movement => new Point/*<num>*/(_movementX, _movementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -26853,19 +26853,19 @@
    * after the event has fired or if the element has CSS transforms affecting
    * it.
    */
-  Point get offset => new Point(_offsetX, _offsetY);
+  Point get offset => new Point/*<num>*/(_offsetX, _offsetY);
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point(_screenX, _screenY);
+  Point get screen => new Point/*<num>*/(_screenX, _screenY);
 
   @DomName('MouseEvent.layerX')
   @DomName('MouseEvent.layerY')
-  Point get layer => new Point(_layerX, _layerY);
+  Point get layer => new Point/*<num>*/(_layerX, _layerY);
 
   @DomName('MouseEvent.pageX')
   @DomName('MouseEvent.pageY')
-  Point get page => new Point(_pageX, _pageY);
+  Point get page => new Point/*<num>*/(_pageX, _pageY);
 }
 // 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
@@ -36962,15 +36962,15 @@
 
   @DomName('Touch.clientX')
   @DomName('Touch.clientY')
-  Point get client => new Point(__clientX, __clientY);
+  Point get client => new Point/*<num>*/(__clientX, __clientY);
 
   @DomName('Touch.pageX')
   @DomName('Touch.pageY')
-  Point get page => new Point(__pageX, __pageY);
+  Point get page => new Point/*<num>*/(__pageX, __pageY);
 
   @DomName('Touch.screenX')
   @DomName('Touch.screenY')
-  Point get screen => new Point(__screenX, __screenY);
+  Point get screen => new Point/*<num>*/(__screenX, __screenY);
 
   @DomName('Touch.radiusX')
   @DocsEditable()
@@ -41794,11 +41794,11 @@
            another.y <= top + height;
   }
 
-  Point get topLeft => new Point(this.left, this.top);
-  Point get topRight => new Point(this.left + this.width, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
+  Point get topLeft => new Point/*<num>*/(this.left, this.top);
+  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
+  Point get bottomRight => new Point/*<num>*/(this.left + this.width,
       this.top + this.height);
-  Point get bottomLeft => new Point(this.left,
+  Point get bottomLeft => new Point/*<num>*/(this.left,
       this.top + this.height);
 
     // To suppress missing implicit constructor warnings.
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 92d144f..73668e9 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -582,9 +582,9 @@
   List<int> readSync(int bytes);
 
   /**
-   * Reads into an existing List<int> from the file. If [start] is present, the
-   * bytes will be filled into [buffer] from at index [start], otherwise index
-   * 0. If [end] is present, the [end] - [start] bytes will be read into
+   * Reads into an existing [List<int>] from the file. If [start] is present,
+   * the bytes will be filled into [buffer] from at index [start], otherwise
+   * index 0. If [end] is present, the [end] - [start] bytes will be read into
    * [buffer], otherwise up to [buffer.length]. If [end] == [start] nothing
    * happends.
    *
@@ -593,8 +593,8 @@
   Future<int> readInto(List<int> buffer, [int start = 0, int end]);
 
   /**
-   * Synchronously reads into an existing List<int> from the file. If [start] is
-   * present, the bytes will be filled into [buffer] from at index [start],
+   * Synchronously reads into an existing [List<int>] from the file. If [start]
+   * is present, the bytes will be filled into [buffer] from at index [start],
    * otherwise index 0.  If [end] is present, the [end] - [start] bytes will be
    * read into [buffer], otherwise up to [buffer.length]. If [end] == [start]
    * nothing happends.
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index f39eafd..e0b22da 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -482,8 +482,8 @@
   /**
    * Returns a [bool] indicating whether this object's path is absolute.
    *
-   * On Windows, a path is absolute if it starts with \\ or a drive letter
-   * between a and z (upper or lower case) followed by :\ or :/.
+   * On Windows, a path is absolute if it starts with \\\\ or a drive letter
+   * between a and z (upper or lower case) followed by :\\ or :/.
    * On non-Windows, a path is absolute if it starts with /.
    */
   bool get isAbsolute {
@@ -624,7 +624,7 @@
   /**
    * Removes the final path component of a path, using the platform's
    * path separator to split the path.  Will not remove the root component
-   * of a Windows path, like "C:\" or "\\server_name\".
+   * of a Windows path, like "C:\\" or "\\\\server_name\\".
    * Ignores trailing path separators, and leaves no trailing path separators.
    */
   static String parentOf(String path) {
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 79bfaa5..d61835c 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -400,7 +400,7 @@
  * To set the value of a header use the `set()` method:
  *
  *     request.headers.set(HttpHeaders.CACHE_CONTROL,
-                           'max-age=3600, must-revalidate');
+ *                         'max-age=3600, must-revalidate');
  *
  * To retrieve the value of a header use the `value()` method:
  *
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 6b14ae2..3769b3f 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -760,12 +760,12 @@
         }
         maybeExpect("=");
         skipWS();
-        if(done()) {
+        if (done()) {
           parameters[name] = null;
           return;
         }
         String value = parseParameterValue();
-        if (name == 'charset' && this is _ContentType) {
+        if (name == 'charset' && this is _ContentType && value != null) {
           // Charset parameter of ContentTypes are always lower-case.
           value = value.toLowerCase();
         }
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 4b3e4a6..61bf1da 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -707,7 +707,7 @@
   return Function.apply(callback, [self]..addAll(arguments));
 }
 
-Function /*=F*/ allowInterop/*<F extends Function>*/(Function /*=F*/ f) {
+Function/*=F*/ allowInterop/*<F extends Function>*/(Function/*=F*/ f) {
   if (JS('bool', 'typeof(#) == "function"', f)) {
     // Already supports interop, just use the existing function.
     return f;
diff --git a/sdk/lib/js/dartium/cached_patches.dart b/sdk/lib/js/dartium/cached_patches.dart
index f9a46f2..fd9453e 100644
--- a/sdk/lib/js/dartium/cached_patches.dart
+++ b/sdk/lib/js/dartium/cached_patches.dart
@@ -16,7 +16,7 @@
  */
 const _UNDEFINED_JS_CONST = const Object();
 
-patch class AbstractWorker {
+@patch class AbstractWorker {
   static Type get instanceRuntimeType => AbstractWorkerImpl;
 
 }
@@ -25,7 +25,7 @@
   get runtimeType => AbstractWorker;
   toString() => super.toString();
 }
-patch class AnchorElement {
+@patch class AnchorElement {
   static Type get instanceRuntimeType => AnchorElementImpl;
 
 }
@@ -34,7 +34,7 @@
   get runtimeType => AnchorElement;
   toString() => super.toString();
 }
-patch class Animation {
+@patch class Animation {
   static Type get instanceRuntimeType => AnimationImpl;
 
 }
@@ -43,7 +43,7 @@
   get runtimeType => Animation;
   toString() => super.toString();
 }
-patch class AnimationEffectReadOnly {
+@patch class AnimationEffectReadOnly {
   static Type get instanceRuntimeType => AnimationEffectReadOnlyImpl;
 
 }
@@ -52,7 +52,7 @@
   get runtimeType => AnimationEffectReadOnly;
   toString() => super.toString();
 }
-patch class AnimationEffectTiming {
+@patch class AnimationEffectTiming {
   static Type get instanceRuntimeType => AnimationEffectTimingImpl;
 
 }
@@ -61,7 +61,7 @@
   get runtimeType => AnimationEffectTiming;
   toString() => super.toString();
 }
-patch class AnimationEvent {
+@patch class AnimationEvent {
   static Type get instanceRuntimeType => AnimationEventImpl;
 
 }
@@ -70,7 +70,7 @@
   get runtimeType => AnimationEvent;
   toString() => super.toString();
 }
-patch class AnimationPlayerEvent {
+@patch class AnimationPlayerEvent {
   static Type get instanceRuntimeType => AnimationPlayerEventImpl;
 
 }
@@ -79,7 +79,7 @@
   get runtimeType => AnimationPlayerEvent;
   toString() => super.toString();
 }
-patch class AnimationTimeline {
+@patch class AnimationTimeline {
   static Type get instanceRuntimeType => AnimationTimelineImpl;
 
 }
@@ -88,7 +88,7 @@
   get runtimeType => AnimationTimeline;
   toString() => super.toString();
 }
-patch class AppBannerPromptResult {
+@patch class AppBannerPromptResult {
   static Type get instanceRuntimeType => AppBannerPromptResultImpl;
 
 }
@@ -97,7 +97,7 @@
   get runtimeType => AppBannerPromptResult;
   toString() => super.toString();
 }
-patch class ApplicationCache {
+@patch class ApplicationCache {
   static Type get instanceRuntimeType => ApplicationCacheImpl;
 
 }
@@ -106,7 +106,7 @@
   get runtimeType => ApplicationCache;
   toString() => super.toString();
 }
-patch class ApplicationCacheErrorEvent {
+@patch class ApplicationCacheErrorEvent {
   static Type get instanceRuntimeType => ApplicationCacheErrorEventImpl;
 
 }
@@ -115,7 +115,7 @@
   get runtimeType => ApplicationCacheErrorEvent;
   toString() => super.toString();
 }
-patch class AreaElement {
+@patch class AreaElement {
   static Type get instanceRuntimeType => AreaElementImpl;
 
 }
@@ -124,7 +124,7 @@
   get runtimeType => AreaElement;
   toString() => super.toString();
 }
-patch class AudioElement {
+@patch class AudioElement {
   static Type get instanceRuntimeType => AudioElementImpl;
 
 }
@@ -133,7 +133,7 @@
   get runtimeType => AudioElement;
   toString() => super.toString();
 }
-patch class AudioTrack {
+@patch class AudioTrack {
   static Type get instanceRuntimeType => AudioTrackImpl;
 
 }
@@ -142,7 +142,7 @@
   get runtimeType => AudioTrack;
   toString() => super.toString();
 }
-patch class AudioTrackList {
+@patch class AudioTrackList {
   static Type get instanceRuntimeType => AudioTrackListImpl;
 
 }
@@ -151,7 +151,7 @@
   get runtimeType => AudioTrackList;
   toString() => super.toString();
 }
-patch class AutocompleteErrorEvent {
+@patch class AutocompleteErrorEvent {
   static Type get instanceRuntimeType => AutocompleteErrorEventImpl;
 
 }
@@ -160,7 +160,7 @@
   get runtimeType => AutocompleteErrorEvent;
   toString() => super.toString();
 }
-patch class BRElement {
+@patch class BRElement {
   static Type get instanceRuntimeType => BRElementImpl;
 
 }
@@ -169,7 +169,7 @@
   get runtimeType => BRElement;
   toString() => super.toString();
 }
-patch class BarProp {
+@patch class BarProp {
   static Type get instanceRuntimeType => BarPropImpl;
 
 }
@@ -178,7 +178,7 @@
   get runtimeType => BarProp;
   toString() => super.toString();
 }
-patch class BaseElement {
+@patch class BaseElement {
   static Type get instanceRuntimeType => BaseElementImpl;
 
 }
@@ -187,7 +187,7 @@
   get runtimeType => BaseElement;
   toString() => super.toString();
 }
-patch class BatteryManager {
+@patch class BatteryManager {
   static Type get instanceRuntimeType => BatteryManagerImpl;
 
 }
@@ -196,7 +196,7 @@
   get runtimeType => BatteryManager;
   toString() => super.toString();
 }
-patch class BeforeInstallPromptEvent {
+@patch class BeforeInstallPromptEvent {
   static Type get instanceRuntimeType => BeforeInstallPromptEventImpl;
 
 }
@@ -205,7 +205,7 @@
   get runtimeType => BeforeInstallPromptEvent;
   toString() => super.toString();
 }
-patch class BeforeUnloadEvent {
+@patch class BeforeUnloadEvent {
   static Type get instanceRuntimeType => BeforeUnloadEventImpl;
 
 }
@@ -214,7 +214,7 @@
   get runtimeType => BeforeUnloadEvent;
   toString() => super.toString();
 }
-patch class Blob {
+@patch class Blob {
   static Type get instanceRuntimeType => BlobImpl;
 
 }
@@ -223,7 +223,7 @@
   get runtimeType => Blob;
   toString() => super.toString();
 }
-patch class Bluetooth {
+@patch class Bluetooth {
   static Type get instanceRuntimeType => BluetoothImpl;
 
 }
@@ -232,7 +232,7 @@
   get runtimeType => Bluetooth;
   toString() => super.toString();
 }
-patch class BluetoothDevice {
+@patch class BluetoothDevice {
   static Type get instanceRuntimeType => BluetoothDeviceImpl;
 
 }
@@ -241,7 +241,7 @@
   get runtimeType => BluetoothDevice;
   toString() => super.toString();
 }
-patch class BluetoothGattCharacteristic {
+@patch class BluetoothGattCharacteristic {
   static Type get instanceRuntimeType => BluetoothGattCharacteristicImpl;
 
 }
@@ -250,7 +250,7 @@
   get runtimeType => BluetoothGattCharacteristic;
   toString() => super.toString();
 }
-patch class BluetoothGattRemoteServer {
+@patch class BluetoothGattRemoteServer {
   static Type get instanceRuntimeType => BluetoothGattRemoteServerImpl;
 
 }
@@ -259,7 +259,7 @@
   get runtimeType => BluetoothGattRemoteServer;
   toString() => super.toString();
 }
-patch class BluetoothGattService {
+@patch class BluetoothGattService {
   static Type get instanceRuntimeType => BluetoothGattServiceImpl;
 
 }
@@ -268,7 +268,7 @@
   get runtimeType => BluetoothGattService;
   toString() => super.toString();
 }
-patch class BluetoothUuid {
+@patch class BluetoothUuid {
   static Type get instanceRuntimeType => BluetoothUuidImpl;
 
 }
@@ -277,7 +277,7 @@
   get runtimeType => BluetoothUuid;
   toString() => super.toString();
 }
-patch class Body {
+@patch class Body {
   static Type get instanceRuntimeType => BodyImpl;
 
 }
@@ -286,7 +286,7 @@
   get runtimeType => Body;
   toString() => super.toString();
 }
-patch class BodyElement {
+@patch class BodyElement {
   static Type get instanceRuntimeType => BodyElementImpl;
 
 }
@@ -295,7 +295,7 @@
   get runtimeType => BodyElement;
   toString() => super.toString();
 }
-patch class ButtonElement {
+@patch class ButtonElement {
   static Type get instanceRuntimeType => ButtonElementImpl;
 
 }
@@ -304,7 +304,7 @@
   get runtimeType => ButtonElement;
   toString() => super.toString();
 }
-patch class CDataSection {
+@patch class CDataSection {
   static Type get instanceRuntimeType => CDataSectionImpl;
 
 }
@@ -313,7 +313,7 @@
   get runtimeType => CDataSection;
   toString() => super.toString();
 }
-patch class CacheStorage {
+@patch class CacheStorage {
   static Type get instanceRuntimeType => CacheStorageImpl;
 
 }
@@ -322,7 +322,7 @@
   get runtimeType => CacheStorage;
   toString() => super.toString();
 }
-patch class CanvasElement {
+@patch class CanvasElement {
   static Type get instanceRuntimeType => CanvasElementImpl;
 
 }
@@ -331,7 +331,7 @@
   get runtimeType => CanvasElement;
   toString() => super.toString();
 }
-patch class CanvasGradient {
+@patch class CanvasGradient {
   static Type get instanceRuntimeType => CanvasGradientImpl;
 
 }
@@ -340,7 +340,7 @@
   get runtimeType => CanvasGradient;
   toString() => super.toString();
 }
-patch class CanvasPattern {
+@patch class CanvasPattern {
   static Type get instanceRuntimeType => CanvasPatternImpl;
 
 }
@@ -349,7 +349,7 @@
   get runtimeType => CanvasPattern;
   toString() => super.toString();
 }
-patch class CanvasRenderingContext2D {
+@patch class CanvasRenderingContext2D {
   static Type get instanceRuntimeType => CanvasRenderingContext2DImpl;
 
 }
@@ -358,7 +358,7 @@
   get runtimeType => CanvasRenderingContext2D;
   toString() => super.toString();
 }
-patch class CharacterData {
+@patch class CharacterData {
   static Type get instanceRuntimeType => CharacterDataImpl;
 
 }
@@ -367,7 +367,7 @@
   get runtimeType => CharacterData;
   toString() => super.toString();
 }
-patch class ChildNode {
+@patch class ChildNode {
   static Type get instanceRuntimeType => ChildNodeImpl;
 
 }
@@ -376,7 +376,7 @@
   get runtimeType => ChildNode;
   toString() => super.toString();
 }
-patch class ChromiumValuebuffer {
+@patch class ChromiumValuebuffer {
   static Type get instanceRuntimeType => ChromiumValuebufferImpl;
 
 }
@@ -385,7 +385,7 @@
   get runtimeType => ChromiumValuebuffer;
   toString() => super.toString();
 }
-patch class CircularGeofencingRegion {
+@patch class CircularGeofencingRegion {
   static Type get instanceRuntimeType => CircularGeofencingRegionImpl;
 
 }
@@ -394,7 +394,7 @@
   get runtimeType => CircularGeofencingRegion;
   toString() => super.toString();
 }
-patch class Client {
+@patch class Client {
   static Type get instanceRuntimeType => ClientImpl;
 
 }
@@ -403,7 +403,7 @@
   get runtimeType => Client;
   toString() => super.toString();
 }
-patch class Clients {
+@patch class Clients {
   static Type get instanceRuntimeType => ClientsImpl;
 
 }
@@ -412,7 +412,7 @@
   get runtimeType => Clients;
   toString() => super.toString();
 }
-patch class ClipboardEvent {
+@patch class ClipboardEvent {
   static Type get instanceRuntimeType => ClipboardEventImpl;
 
 }
@@ -421,7 +421,7 @@
   get runtimeType => ClipboardEvent;
   toString() => super.toString();
 }
-patch class CloseEvent {
+@patch class CloseEvent {
   static Type get instanceRuntimeType => CloseEventImpl;
 
 }
@@ -430,7 +430,7 @@
   get runtimeType => CloseEvent;
   toString() => super.toString();
 }
-patch class Comment {
+@patch class Comment {
   static Type get instanceRuntimeType => CommentImpl;
 
 }
@@ -439,7 +439,7 @@
   get runtimeType => Comment;
   toString() => super.toString();
 }
-patch class CompositionEvent {
+@patch class CompositionEvent {
   static Type get instanceRuntimeType => CompositionEventImpl;
 
 }
@@ -448,7 +448,7 @@
   get runtimeType => CompositionEvent;
   toString() => super.toString();
 }
-patch class CompositorProxy {
+@patch class CompositorProxy {
   static Type get instanceRuntimeType => CompositorProxyImpl;
 
 }
@@ -457,7 +457,7 @@
   get runtimeType => CompositorProxy;
   toString() => super.toString();
 }
-patch class CompositorWorker {
+@patch class CompositorWorker {
   static Type get instanceRuntimeType => CompositorWorkerImpl;
 
 }
@@ -466,7 +466,7 @@
   get runtimeType => CompositorWorker;
   toString() => super.toString();
 }
-patch class CompositorWorkerGlobalScope {
+@patch class CompositorWorkerGlobalScope {
   static Type get instanceRuntimeType => CompositorWorkerGlobalScopeImpl;
 
 }
@@ -475,7 +475,7 @@
   get runtimeType => CompositorWorkerGlobalScope;
   toString() => super.toString();
 }
-patch class Console {
+@patch class Console {
   static Type get instanceRuntimeType => ConsoleImpl;
 
 }
@@ -484,7 +484,7 @@
   get runtimeType => Console;
   toString() => super.toString();
 }
-patch class ConsoleBase {
+@patch class ConsoleBase {
   static Type get instanceRuntimeType => ConsoleBaseImpl;
 
 }
@@ -493,7 +493,7 @@
   get runtimeType => ConsoleBase;
   toString() => super.toString();
 }
-patch class ContentElement {
+@patch class ContentElement {
   static Type get instanceRuntimeType => ContentElementImpl;
 
 }
@@ -502,7 +502,7 @@
   get runtimeType => ContentElement;
   toString() => super.toString();
 }
-patch class Coordinates {
+@patch class Coordinates {
   static Type get instanceRuntimeType => CoordinatesImpl;
 
 }
@@ -511,7 +511,7 @@
   get runtimeType => Coordinates;
   toString() => super.toString();
 }
-patch class Credential {
+@patch class Credential {
   static Type get instanceRuntimeType => CredentialImpl;
 
 }
@@ -520,7 +520,7 @@
   get runtimeType => Credential;
   toString() => super.toString();
 }
-patch class CredentialsContainer {
+@patch class CredentialsContainer {
   static Type get instanceRuntimeType => CredentialsContainerImpl;
 
 }
@@ -529,7 +529,7 @@
   get runtimeType => CredentialsContainer;
   toString() => super.toString();
 }
-patch class CrossOriginConnectEvent {
+@patch class CrossOriginConnectEvent {
   static Type get instanceRuntimeType => CrossOriginConnectEventImpl;
 
 }
@@ -538,7 +538,7 @@
   get runtimeType => CrossOriginConnectEvent;
   toString() => super.toString();
 }
-patch class CrossOriginServiceWorkerClient {
+@patch class CrossOriginServiceWorkerClient {
   static Type get instanceRuntimeType => CrossOriginServiceWorkerClientImpl;
 
 }
@@ -547,7 +547,7 @@
   get runtimeType => CrossOriginServiceWorkerClient;
   toString() => super.toString();
 }
-patch class Crypto {
+@patch class Crypto {
   static Type get instanceRuntimeType => CryptoImpl;
 
 }
@@ -556,7 +556,7 @@
   get runtimeType => Crypto;
   toString() => super.toString();
 }
-patch class CryptoKey {
+@patch class CryptoKey {
   static Type get instanceRuntimeType => CryptoKeyImpl;
 
 }
@@ -565,7 +565,7 @@
   get runtimeType => CryptoKey;
   toString() => super.toString();
 }
-patch class Css {
+@patch class Css {
   static Type get instanceRuntimeType => CssImpl;
 
 }
@@ -574,7 +574,7 @@
   get runtimeType => Css;
   toString() => super.toString();
 }
-patch class CssCharsetRule {
+@patch class CssCharsetRule {
   static Type get instanceRuntimeType => CssCharsetRuleImpl;
 
 }
@@ -583,7 +583,7 @@
   get runtimeType => CssCharsetRule;
   toString() => super.toString();
 }
-patch class CssFontFaceRule {
+@patch class CssFontFaceRule {
   static Type get instanceRuntimeType => CssFontFaceRuleImpl;
 
 }
@@ -592,7 +592,7 @@
   get runtimeType => CssFontFaceRule;
   toString() => super.toString();
 }
-patch class CssGroupingRule {
+@patch class CssGroupingRule {
   static Type get instanceRuntimeType => CssGroupingRuleImpl;
 
 }
@@ -601,7 +601,7 @@
   get runtimeType => CssGroupingRule;
   toString() => super.toString();
 }
-patch class CssImportRule {
+@patch class CssImportRule {
   static Type get instanceRuntimeType => CssImportRuleImpl;
 
 }
@@ -610,7 +610,7 @@
   get runtimeType => CssImportRule;
   toString() => super.toString();
 }
-patch class CssKeyframeRule {
+@patch class CssKeyframeRule {
   static Type get instanceRuntimeType => CssKeyframeRuleImpl;
 
 }
@@ -619,7 +619,7 @@
   get runtimeType => CssKeyframeRule;
   toString() => super.toString();
 }
-patch class CssKeyframesRule {
+@patch class CssKeyframesRule {
   static Type get instanceRuntimeType => CssKeyframesRuleImpl;
 
 }
@@ -628,7 +628,7 @@
   get runtimeType => CssKeyframesRule;
   toString() => super.toString();
 }
-patch class CssMediaRule {
+@patch class CssMediaRule {
   static Type get instanceRuntimeType => CssMediaRuleImpl;
 
 }
@@ -637,7 +637,7 @@
   get runtimeType => CssMediaRule;
   toString() => super.toString();
 }
-patch class CssPageRule {
+@patch class CssPageRule {
   static Type get instanceRuntimeType => CssPageRuleImpl;
 
 }
@@ -646,7 +646,7 @@
   get runtimeType => CssPageRule;
   toString() => super.toString();
 }
-patch class CssRule {
+@patch class CssRule {
   static Type get instanceRuntimeType => CssRuleImpl;
 
 }
@@ -655,7 +655,7 @@
   get runtimeType => CssRule;
   toString() => super.toString();
 }
-patch class CssStyleDeclaration {
+@patch class CssStyleDeclaration {
   static Type get instanceRuntimeType => CssStyleDeclarationImpl;
 
 }
@@ -664,7 +664,7 @@
   get runtimeType => CssStyleDeclaration;
   toString() => super.toString();
 }
-patch class CssStyleRule {
+@patch class CssStyleRule {
   static Type get instanceRuntimeType => CssStyleRuleImpl;
 
 }
@@ -673,7 +673,7 @@
   get runtimeType => CssStyleRule;
   toString() => super.toString();
 }
-patch class CssStyleSheet {
+@patch class CssStyleSheet {
   static Type get instanceRuntimeType => CssStyleSheetImpl;
 
 }
@@ -682,7 +682,7 @@
   get runtimeType => CssStyleSheet;
   toString() => super.toString();
 }
-patch class CssSupportsRule {
+@patch class CssSupportsRule {
   static Type get instanceRuntimeType => CssSupportsRuleImpl;
 
 }
@@ -691,7 +691,7 @@
   get runtimeType => CssSupportsRule;
   toString() => super.toString();
 }
-patch class CssViewportRule {
+@patch class CssViewportRule {
   static Type get instanceRuntimeType => CssViewportRuleImpl;
 
 }
@@ -700,7 +700,7 @@
   get runtimeType => CssViewportRule;
   toString() => super.toString();
 }
-patch class CustomEvent {
+@patch class CustomEvent {
   static Type get instanceRuntimeType => CustomEventImpl;
 
 }
@@ -709,7 +709,7 @@
   get runtimeType => CustomEvent;
   toString() => super.toString();
 }
-patch class DListElement {
+@patch class DListElement {
   static Type get instanceRuntimeType => DListElementImpl;
 
 }
@@ -718,7 +718,7 @@
   get runtimeType => DListElement;
   toString() => super.toString();
 }
-patch class DataListElement {
+@patch class DataListElement {
   static Type get instanceRuntimeType => DataListElementImpl;
 
 }
@@ -727,7 +727,7 @@
   get runtimeType => DataListElement;
   toString() => super.toString();
 }
-patch class DataTransfer {
+@patch class DataTransfer {
   static Type get instanceRuntimeType => DataTransferImpl;
 
 }
@@ -736,7 +736,7 @@
   get runtimeType => DataTransfer;
   toString() => super.toString();
 }
-patch class DataTransferItem {
+@patch class DataTransferItem {
   static Type get instanceRuntimeType => DataTransferItemImpl;
 
 }
@@ -745,7 +745,7 @@
   get runtimeType => DataTransferItem;
   toString() => super.toString();
 }
-patch class DataTransferItemList {
+@patch class DataTransferItemList {
   static Type get instanceRuntimeType => DataTransferItemListImpl;
 
 }
@@ -754,7 +754,7 @@
   get runtimeType => DataTransferItemList;
   toString() => super.toString();
 }
-patch class DedicatedWorkerGlobalScope {
+@patch class DedicatedWorkerGlobalScope {
   static Type get instanceRuntimeType => DedicatedWorkerGlobalScopeImpl;
 
 }
@@ -763,7 +763,7 @@
   get runtimeType => DedicatedWorkerGlobalScope;
   toString() => super.toString();
 }
-patch class DefaultSessionStartEvent {
+@patch class DefaultSessionStartEvent {
   static Type get instanceRuntimeType => DefaultSessionStartEventImpl;
 
 }
@@ -772,7 +772,7 @@
   get runtimeType => DefaultSessionStartEvent;
   toString() => super.toString();
 }
-patch class DeprecatedStorageInfo {
+@patch class DeprecatedStorageInfo {
   static Type get instanceRuntimeType => DeprecatedStorageInfoImpl;
 
 }
@@ -781,7 +781,7 @@
   get runtimeType => DeprecatedStorageInfo;
   toString() => super.toString();
 }
-patch class DeprecatedStorageQuota {
+@patch class DeprecatedStorageQuota {
   static Type get instanceRuntimeType => DeprecatedStorageQuotaImpl;
 
 }
@@ -790,7 +790,7 @@
   get runtimeType => DeprecatedStorageQuota;
   toString() => super.toString();
 }
-patch class DetailsElement {
+@patch class DetailsElement {
   static Type get instanceRuntimeType => DetailsElementImpl;
 
 }
@@ -799,7 +799,7 @@
   get runtimeType => DetailsElement;
   toString() => super.toString();
 }
-patch class DeviceAcceleration {
+@patch class DeviceAcceleration {
   static Type get instanceRuntimeType => DeviceAccelerationImpl;
 
 }
@@ -808,7 +808,7 @@
   get runtimeType => DeviceAcceleration;
   toString() => super.toString();
 }
-patch class DeviceLightEvent {
+@patch class DeviceLightEvent {
   static Type get instanceRuntimeType => DeviceLightEventImpl;
 
 }
@@ -817,7 +817,7 @@
   get runtimeType => DeviceLightEvent;
   toString() => super.toString();
 }
-patch class DeviceMotionEvent {
+@patch class DeviceMotionEvent {
   static Type get instanceRuntimeType => DeviceMotionEventImpl;
 
 }
@@ -826,7 +826,7 @@
   get runtimeType => DeviceMotionEvent;
   toString() => super.toString();
 }
-patch class DeviceOrientationEvent {
+@patch class DeviceOrientationEvent {
   static Type get instanceRuntimeType => DeviceOrientationEventImpl;
 
 }
@@ -835,7 +835,7 @@
   get runtimeType => DeviceOrientationEvent;
   toString() => super.toString();
 }
-patch class DeviceRotationRate {
+@patch class DeviceRotationRate {
   static Type get instanceRuntimeType => DeviceRotationRateImpl;
 
 }
@@ -844,7 +844,7 @@
   get runtimeType => DeviceRotationRate;
   toString() => super.toString();
 }
-patch class DialogElement {
+@patch class DialogElement {
   static Type get instanceRuntimeType => DialogElementImpl;
 
 }
@@ -853,7 +853,7 @@
   get runtimeType => DialogElement;
   toString() => super.toString();
 }
-patch class DirectoryEntry {
+@patch class DirectoryEntry {
   static Type get instanceRuntimeType => DirectoryEntryImpl;
 
 }
@@ -862,7 +862,7 @@
   get runtimeType => DirectoryEntry;
   toString() => super.toString();
 }
-patch class DirectoryReader {
+@patch class DirectoryReader {
   static Type get instanceRuntimeType => DirectoryReaderImpl;
 
 }
@@ -871,7 +871,7 @@
   get runtimeType => DirectoryReader;
   toString() => super.toString();
 }
-patch class DivElement {
+@patch class DivElement {
   static Type get instanceRuntimeType => DivElementImpl;
 
 }
@@ -880,7 +880,7 @@
   get runtimeType => DivElement;
   toString() => super.toString();
 }
-patch class Document {
+@patch class Document {
   static Type get instanceRuntimeType => DocumentImpl;
 
 }
@@ -889,7 +889,7 @@
   get runtimeType => Document;
   toString() => super.toString();
 }
-patch class DocumentFragment {
+@patch class DocumentFragment {
   static Type get instanceRuntimeType => DocumentFragmentImpl;
 
 }
@@ -898,7 +898,7 @@
   get runtimeType => DocumentFragment;
   toString() => super.toString();
 }
-patch class DomError {
+@patch class DomError {
   static Type get instanceRuntimeType => DomErrorImpl;
 
 }
@@ -907,7 +907,7 @@
   get runtimeType => DomError;
   toString() => super.toString();
 }
-patch class DomException {
+@patch class DomException {
   static Type get instanceRuntimeType => DomExceptionImpl;
 
 }
@@ -916,7 +916,7 @@
   get runtimeType => DomException;
   toString() => super.toString();
 }
-patch class DomImplementation {
+@patch class DomImplementation {
   static Type get instanceRuntimeType => DomImplementationImpl;
 
 }
@@ -925,7 +925,7 @@
   get runtimeType => DomImplementation;
   toString() => super.toString();
 }
-patch class DomIterator {
+@patch class DomIterator {
   static Type get instanceRuntimeType => DomIteratorImpl;
 
 }
@@ -934,7 +934,7 @@
   get runtimeType => DomIterator;
   toString() => super.toString();
 }
-patch class DomMatrix {
+@patch class DomMatrix {
   static Type get instanceRuntimeType => DomMatrixImpl;
 
 }
@@ -943,7 +943,7 @@
   get runtimeType => DomMatrix;
   toString() => super.toString();
 }
-patch class DomMatrixReadOnly {
+@patch class DomMatrixReadOnly {
   static Type get instanceRuntimeType => DomMatrixReadOnlyImpl;
 
 }
@@ -952,7 +952,7 @@
   get runtimeType => DomMatrixReadOnly;
   toString() => super.toString();
 }
-patch class DomParser {
+@patch class DomParser {
   static Type get instanceRuntimeType => DomParserImpl;
 
 }
@@ -961,7 +961,7 @@
   get runtimeType => DomParser;
   toString() => super.toString();
 }
-patch class DomPoint {
+@patch class DomPoint {
   static Type get instanceRuntimeType => DomPointImpl;
 
 }
@@ -970,7 +970,7 @@
   get runtimeType => DomPoint;
   toString() => super.toString();
 }
-patch class DomPointReadOnly {
+@patch class DomPointReadOnly {
   static Type get instanceRuntimeType => DomPointReadOnlyImpl;
 
 }
@@ -979,7 +979,7 @@
   get runtimeType => DomPointReadOnly;
   toString() => super.toString();
 }
-patch class DomRectReadOnly {
+@patch class DomRectReadOnly {
   static Type get instanceRuntimeType => DomRectReadOnlyImpl;
 
 }
@@ -988,7 +988,7 @@
   get runtimeType => DomRectReadOnly;
   toString() => super.toString();
 }
-patch class DomSettableTokenList {
+@patch class DomSettableTokenList {
   static Type get instanceRuntimeType => DomSettableTokenListImpl;
 
 }
@@ -997,7 +997,7 @@
   get runtimeType => DomSettableTokenList;
   toString() => super.toString();
 }
-patch class DomStringList {
+@patch class DomStringList {
   static Type get instanceRuntimeType => DomStringListImpl;
 
 }
@@ -1006,7 +1006,7 @@
   get runtimeType => DomStringList;
   toString() => super.toString();
 }
-patch class DomStringMap {
+@patch class DomStringMap {
   static Type get instanceRuntimeType => DomStringMapImpl;
 
 }
@@ -1015,7 +1015,7 @@
   get runtimeType => DomStringMap;
   toString() => super.toString();
 }
-patch class DomTokenList {
+@patch class DomTokenList {
   static Type get instanceRuntimeType => DomTokenListImpl;
 
 }
@@ -1024,7 +1024,7 @@
   get runtimeType => DomTokenList;
   toString() => super.toString();
 }
-patch class EffectModel {
+@patch class EffectModel {
   static Type get instanceRuntimeType => EffectModelImpl;
 
 }
@@ -1033,7 +1033,7 @@
   get runtimeType => EffectModel;
   toString() => super.toString();
 }
-patch class Element {
+@patch class Element {
   static Type get instanceRuntimeType => ElementImpl;
 
 }
@@ -1042,7 +1042,7 @@
   get runtimeType => Element;
   toString() => super.toString();
 }
-patch class EmbedElement {
+@patch class EmbedElement {
   static Type get instanceRuntimeType => EmbedElementImpl;
 
 }
@@ -1051,7 +1051,7 @@
   get runtimeType => EmbedElement;
   toString() => super.toString();
 }
-patch class Entry {
+@patch class Entry {
   static Type get instanceRuntimeType => EntryImpl;
 
 }
@@ -1060,7 +1060,7 @@
   get runtimeType => Entry;
   toString() => super.toString();
 }
-patch class ErrorEvent {
+@patch class ErrorEvent {
   static Type get instanceRuntimeType => ErrorEventImpl;
 
 }
@@ -1069,7 +1069,7 @@
   get runtimeType => ErrorEvent;
   toString() => super.toString();
 }
-patch class Event {
+@patch class Event {
   static Type get instanceRuntimeType => EventImpl;
 
 }
@@ -1078,7 +1078,7 @@
   get runtimeType => Event;
   toString() => super.toString();
 }
-patch class EventSource {
+@patch class EventSource {
   static Type get instanceRuntimeType => EventSourceImpl;
 
 }
@@ -1087,7 +1087,7 @@
   get runtimeType => EventSource;
   toString() => super.toString();
 }
-patch class EventTarget {
+@patch class EventTarget {
   static Type get instanceRuntimeType => EventTargetImpl;
 
 }
@@ -1096,7 +1096,7 @@
   get runtimeType => EventTarget;
   toString() => super.toString();
 }
-patch class ExtendableEvent {
+@patch class ExtendableEvent {
   static Type get instanceRuntimeType => ExtendableEventImpl;
 
 }
@@ -1105,7 +1105,7 @@
   get runtimeType => ExtendableEvent;
   toString() => super.toString();
 }
-patch class FederatedCredential {
+@patch class FederatedCredential {
   static Type get instanceRuntimeType => FederatedCredentialImpl;
 
 }
@@ -1114,7 +1114,7 @@
   get runtimeType => FederatedCredential;
   toString() => super.toString();
 }
-patch class FetchEvent {
+@patch class FetchEvent {
   static Type get instanceRuntimeType => FetchEventImpl;
 
 }
@@ -1123,7 +1123,7 @@
   get runtimeType => FetchEvent;
   toString() => super.toString();
 }
-patch class FieldSetElement {
+@patch class FieldSetElement {
   static Type get instanceRuntimeType => FieldSetElementImpl;
 
 }
@@ -1132,7 +1132,7 @@
   get runtimeType => FieldSetElement;
   toString() => super.toString();
 }
-patch class File {
+@patch class File {
   static Type get instanceRuntimeType => FileImpl;
 
 }
@@ -1141,7 +1141,7 @@
   get runtimeType => File;
   toString() => super.toString();
 }
-patch class FileEntry {
+@patch class FileEntry {
   static Type get instanceRuntimeType => FileEntryImpl;
 
 }
@@ -1150,7 +1150,7 @@
   get runtimeType => FileEntry;
   toString() => super.toString();
 }
-patch class FileError {
+@patch class FileError {
   static Type get instanceRuntimeType => FileErrorImpl;
 
 }
@@ -1159,7 +1159,7 @@
   get runtimeType => FileError;
   toString() => super.toString();
 }
-patch class FileList {
+@patch class FileList {
   static Type get instanceRuntimeType => FileListImpl;
 
 }
@@ -1168,7 +1168,7 @@
   get runtimeType => FileList;
   toString() => super.toString();
 }
-patch class FileReader {
+@patch class FileReader {
   static Type get instanceRuntimeType => FileReaderImpl;
 
 }
@@ -1177,7 +1177,7 @@
   get runtimeType => FileReader;
   toString() => super.toString();
 }
-patch class FileStream {
+@patch class FileStream {
   static Type get instanceRuntimeType => FileStreamImpl;
 
 }
@@ -1186,7 +1186,7 @@
   get runtimeType => FileStream;
   toString() => super.toString();
 }
-patch class FileSystem {
+@patch class FileSystem {
   static Type get instanceRuntimeType => FileSystemImpl;
 
 }
@@ -1195,7 +1195,7 @@
   get runtimeType => FileSystem;
   toString() => super.toString();
 }
-patch class FileWriter {
+@patch class FileWriter {
   static Type get instanceRuntimeType => FileWriterImpl;
 
 }
@@ -1204,7 +1204,7 @@
   get runtimeType => FileWriter;
   toString() => super.toString();
 }
-patch class FocusEvent {
+@patch class FocusEvent {
   static Type get instanceRuntimeType => FocusEventImpl;
 
 }
@@ -1213,7 +1213,7 @@
   get runtimeType => FocusEvent;
   toString() => super.toString();
 }
-patch class FontFace {
+@patch class FontFace {
   static Type get instanceRuntimeType => FontFaceImpl;
 
 }
@@ -1222,7 +1222,7 @@
   get runtimeType => FontFace;
   toString() => super.toString();
 }
-patch class FontFaceSet {
+@patch class FontFaceSet {
   static Type get instanceRuntimeType => FontFaceSetImpl;
 
 }
@@ -1231,7 +1231,7 @@
   get runtimeType => FontFaceSet;
   toString() => super.toString();
 }
-patch class FontFaceSetLoadEvent {
+@patch class FontFaceSetLoadEvent {
   static Type get instanceRuntimeType => FontFaceSetLoadEventImpl;
 
 }
@@ -1240,7 +1240,7 @@
   get runtimeType => FontFaceSetLoadEvent;
   toString() => super.toString();
 }
-patch class FormData {
+@patch class FormData {
   static Type get instanceRuntimeType => FormDataImpl;
 
 }
@@ -1249,7 +1249,7 @@
   get runtimeType => FormData;
   toString() => super.toString();
 }
-patch class FormElement {
+@patch class FormElement {
   static Type get instanceRuntimeType => FormElementImpl;
 
 }
@@ -1258,7 +1258,7 @@
   get runtimeType => FormElement;
   toString() => super.toString();
 }
-patch class Gamepad {
+@patch class Gamepad {
   static Type get instanceRuntimeType => GamepadImpl;
 
 }
@@ -1267,7 +1267,7 @@
   get runtimeType => Gamepad;
   toString() => super.toString();
 }
-patch class GamepadButton {
+@patch class GamepadButton {
   static Type get instanceRuntimeType => GamepadButtonImpl;
 
 }
@@ -1276,7 +1276,7 @@
   get runtimeType => GamepadButton;
   toString() => super.toString();
 }
-patch class GamepadEvent {
+@patch class GamepadEvent {
   static Type get instanceRuntimeType => GamepadEventImpl;
 
 }
@@ -1285,7 +1285,7 @@
   get runtimeType => GamepadEvent;
   toString() => super.toString();
 }
-patch class Geofencing {
+@patch class Geofencing {
   static Type get instanceRuntimeType => GeofencingImpl;
 
 }
@@ -1294,7 +1294,7 @@
   get runtimeType => Geofencing;
   toString() => super.toString();
 }
-patch class GeofencingEvent {
+@patch class GeofencingEvent {
   static Type get instanceRuntimeType => GeofencingEventImpl;
 
 }
@@ -1303,7 +1303,7 @@
   get runtimeType => GeofencingEvent;
   toString() => super.toString();
 }
-patch class GeofencingRegion {
+@patch class GeofencingRegion {
   static Type get instanceRuntimeType => GeofencingRegionImpl;
 
 }
@@ -1312,7 +1312,7 @@
   get runtimeType => GeofencingRegion;
   toString() => super.toString();
 }
-patch class Geolocation {
+@patch class Geolocation {
   static Type get instanceRuntimeType => GeolocationImpl;
 
 }
@@ -1321,7 +1321,7 @@
   get runtimeType => Geolocation;
   toString() => super.toString();
 }
-patch class Geoposition {
+@patch class Geoposition {
   static Type get instanceRuntimeType => GeopositionImpl;
 
 }
@@ -1330,7 +1330,7 @@
   get runtimeType => Geoposition;
   toString() => super.toString();
 }
-patch class GlobalEventHandlers {
+@patch class GlobalEventHandlers {
   static Type get instanceRuntimeType => GlobalEventHandlersImpl;
 
 }
@@ -1339,7 +1339,7 @@
   get runtimeType => GlobalEventHandlers;
   toString() => super.toString();
 }
-patch class HRElement {
+@patch class HRElement {
   static Type get instanceRuntimeType => HRElementImpl;
 
 }
@@ -1348,7 +1348,7 @@
   get runtimeType => HRElement;
   toString() => super.toString();
 }
-patch class HashChangeEvent {
+@patch class HashChangeEvent {
   static Type get instanceRuntimeType => HashChangeEventImpl;
 
 }
@@ -1357,7 +1357,7 @@
   get runtimeType => HashChangeEvent;
   toString() => super.toString();
 }
-patch class HeadElement {
+@patch class HeadElement {
   static Type get instanceRuntimeType => HeadElementImpl;
 
 }
@@ -1366,7 +1366,7 @@
   get runtimeType => HeadElement;
   toString() => super.toString();
 }
-patch class Headers {
+@patch class Headers {
   static Type get instanceRuntimeType => HeadersImpl;
 
 }
@@ -1375,7 +1375,7 @@
   get runtimeType => Headers;
   toString() => super.toString();
 }
-patch class HeadingElement {
+@patch class HeadingElement {
   static Type get instanceRuntimeType => HeadingElementImpl;
 
 }
@@ -1384,7 +1384,7 @@
   get runtimeType => HeadingElement;
   toString() => super.toString();
 }
-patch class History {
+@patch class History {
   static Type get instanceRuntimeType => HistoryImpl;
 
 }
@@ -1393,7 +1393,7 @@
   get runtimeType => History;
   toString() => super.toString();
 }
-patch class HmdvrDevice {
+@patch class HmdvrDevice {
   static Type get instanceRuntimeType => HmdvrDeviceImpl;
 
 }
@@ -1402,7 +1402,7 @@
   get runtimeType => HmdvrDevice;
   toString() => super.toString();
 }
-patch class HtmlCollection {
+@patch class HtmlCollection {
   static Type get instanceRuntimeType => HtmlCollectionImpl;
 
 }
@@ -1411,7 +1411,7 @@
   get runtimeType => HtmlCollection;
   toString() => super.toString();
 }
-patch class HtmlDocument {
+@patch class HtmlDocument {
   static Type get instanceRuntimeType => HtmlDocumentImpl;
 
 }
@@ -1420,7 +1420,7 @@
   get runtimeType => HtmlDocument;
   toString() => super.toString();
 }
-patch class HtmlElement {
+@patch class HtmlElement {
   static Type get instanceRuntimeType => HtmlElementImpl;
 
 }
@@ -1429,7 +1429,7 @@
   get runtimeType => HtmlElement;
   toString() => super.toString();
 }
-patch class HtmlFormControlsCollection {
+@patch class HtmlFormControlsCollection {
   static Type get instanceRuntimeType => HtmlFormControlsCollectionImpl;
 
 }
@@ -1438,7 +1438,7 @@
   get runtimeType => HtmlFormControlsCollection;
   toString() => super.toString();
 }
-patch class HtmlHtmlElement {
+@patch class HtmlHtmlElement {
   static Type get instanceRuntimeType => HtmlHtmlElementImpl;
 
 }
@@ -1447,7 +1447,7 @@
   get runtimeType => HtmlHtmlElement;
   toString() => super.toString();
 }
-patch class HtmlOptionsCollection {
+@patch class HtmlOptionsCollection {
   static Type get instanceRuntimeType => HtmlOptionsCollectionImpl;
 
 }
@@ -1456,7 +1456,7 @@
   get runtimeType => HtmlOptionsCollection;
   toString() => super.toString();
 }
-patch class HttpRequest {
+@patch class HttpRequest {
   static Type get instanceRuntimeType => HttpRequestImpl;
 
 }
@@ -1465,7 +1465,7 @@
   get runtimeType => HttpRequest;
   toString() => super.toString();
 }
-patch class HttpRequestEventTarget {
+@patch class HttpRequestEventTarget {
   static Type get instanceRuntimeType => HttpRequestEventTargetImpl;
 
 }
@@ -1474,7 +1474,7 @@
   get runtimeType => HttpRequestEventTarget;
   toString() => super.toString();
 }
-patch class HttpRequestUpload {
+@patch class HttpRequestUpload {
   static Type get instanceRuntimeType => HttpRequestUploadImpl;
 
 }
@@ -1483,7 +1483,7 @@
   get runtimeType => HttpRequestUpload;
   toString() => super.toString();
 }
-patch class IFrameElement {
+@patch class IFrameElement {
   static Type get instanceRuntimeType => IFrameElementImpl;
 
 }
@@ -1492,7 +1492,7 @@
   get runtimeType => IFrameElement;
   toString() => super.toString();
 }
-patch class ImageBitmap {
+@patch class ImageBitmap {
   static Type get instanceRuntimeType => ImageBitmapImpl;
 
 }
@@ -1501,7 +1501,7 @@
   get runtimeType => ImageBitmap;
   toString() => super.toString();
 }
-patch class ImageData {
+@patch class ImageData {
   static Type get instanceRuntimeType => ImageDataImpl;
 
 }
@@ -1510,7 +1510,7 @@
   get runtimeType => ImageData;
   toString() => super.toString();
 }
-patch class ImageElement {
+@patch class ImageElement {
   static Type get instanceRuntimeType => ImageElementImpl;
 
 }
@@ -1519,7 +1519,7 @@
   get runtimeType => ImageElement;
   toString() => super.toString();
 }
-patch class InjectedScriptHost {
+@patch class InjectedScriptHost {
   static Type get instanceRuntimeType => InjectedScriptHostImpl;
 
 }
@@ -1528,7 +1528,7 @@
   get runtimeType => InjectedScriptHost;
   toString() => super.toString();
 }
-patch class InputDevice {
+@patch class InputDevice {
   static Type get instanceRuntimeType => InputDeviceImpl;
 
 }
@@ -1537,7 +1537,7 @@
   get runtimeType => InputDevice;
   toString() => super.toString();
 }
-patch class InputElement {
+@patch class InputElement {
   static Type get instanceRuntimeType => InputElementImpl;
 
 }
@@ -1546,7 +1546,7 @@
   get runtimeType => InputElement;
   toString() => super.toString();
 }
-patch class KeyboardEvent {
+@patch class KeyboardEvent {
   static Type get instanceRuntimeType => KeyboardEventImpl;
 
 }
@@ -1555,7 +1555,7 @@
   get runtimeType => KeyboardEvent;
   toString() => super.toString();
 }
-patch class KeyframeEffect {
+@patch class KeyframeEffect {
   static Type get instanceRuntimeType => KeyframeEffectImpl;
 
 }
@@ -1564,7 +1564,7 @@
   get runtimeType => KeyframeEffect;
   toString() => super.toString();
 }
-patch class KeygenElement {
+@patch class KeygenElement {
   static Type get instanceRuntimeType => KeygenElementImpl;
 
 }
@@ -1573,7 +1573,7 @@
   get runtimeType => KeygenElement;
   toString() => super.toString();
 }
-patch class LIElement {
+@patch class LIElement {
   static Type get instanceRuntimeType => LIElementImpl;
 
 }
@@ -1582,7 +1582,7 @@
   get runtimeType => LIElement;
   toString() => super.toString();
 }
-patch class LabelElement {
+@patch class LabelElement {
   static Type get instanceRuntimeType => LabelElementImpl;
 
 }
@@ -1591,7 +1591,7 @@
   get runtimeType => LabelElement;
   toString() => super.toString();
 }
-patch class LegendElement {
+@patch class LegendElement {
   static Type get instanceRuntimeType => LegendElementImpl;
 
 }
@@ -1600,7 +1600,7 @@
   get runtimeType => LegendElement;
   toString() => super.toString();
 }
-patch class LinkElement {
+@patch class LinkElement {
   static Type get instanceRuntimeType => LinkElementImpl;
 
 }
@@ -1609,7 +1609,7 @@
   get runtimeType => LinkElement;
   toString() => super.toString();
 }
-patch class Location {
+@patch class Location {
   static Type get instanceRuntimeType => LocationImpl;
 
 }
@@ -1618,7 +1618,7 @@
   get runtimeType => Location;
   toString() => super.toString();
 }
-patch class MapElement {
+@patch class MapElement {
   static Type get instanceRuntimeType => MapElementImpl;
 
 }
@@ -1627,7 +1627,7 @@
   get runtimeType => MapElement;
   toString() => super.toString();
 }
-patch class MediaController {
+@patch class MediaController {
   static Type get instanceRuntimeType => MediaControllerImpl;
 
 }
@@ -1636,7 +1636,7 @@
   get runtimeType => MediaController;
   toString() => super.toString();
 }
-patch class MediaDeviceInfo {
+@patch class MediaDeviceInfo {
   static Type get instanceRuntimeType => MediaDeviceInfoImpl;
 
 }
@@ -1645,7 +1645,7 @@
   get runtimeType => MediaDeviceInfo;
   toString() => super.toString();
 }
-patch class MediaDevices {
+@patch class MediaDevices {
   static Type get instanceRuntimeType => MediaDevicesImpl;
 
 }
@@ -1654,7 +1654,7 @@
   get runtimeType => MediaDevices;
   toString() => super.toString();
 }
-patch class MediaElement {
+@patch class MediaElement {
   static Type get instanceRuntimeType => MediaElementImpl;
 
 }
@@ -1663,7 +1663,7 @@
   get runtimeType => MediaElement;
   toString() => super.toString();
 }
-patch class MediaEncryptedEvent {
+@patch class MediaEncryptedEvent {
   static Type get instanceRuntimeType => MediaEncryptedEventImpl;
 
 }
@@ -1672,7 +1672,7 @@
   get runtimeType => MediaEncryptedEvent;
   toString() => super.toString();
 }
-patch class MediaError {
+@patch class MediaError {
   static Type get instanceRuntimeType => MediaErrorImpl;
 
 }
@@ -1681,7 +1681,7 @@
   get runtimeType => MediaError;
   toString() => super.toString();
 }
-patch class MediaKeyError {
+@patch class MediaKeyError {
   static Type get instanceRuntimeType => MediaKeyErrorImpl;
 
 }
@@ -1690,7 +1690,7 @@
   get runtimeType => MediaKeyError;
   toString() => super.toString();
 }
-patch class MediaKeyEvent {
+@patch class MediaKeyEvent {
   static Type get instanceRuntimeType => MediaKeyEventImpl;
 
 }
@@ -1699,7 +1699,7 @@
   get runtimeType => MediaKeyEvent;
   toString() => super.toString();
 }
-patch class MediaKeyMessageEvent {
+@patch class MediaKeyMessageEvent {
   static Type get instanceRuntimeType => MediaKeyMessageEventImpl;
 
 }
@@ -1708,7 +1708,7 @@
   get runtimeType => MediaKeyMessageEvent;
   toString() => super.toString();
 }
-patch class MediaKeySession {
+@patch class MediaKeySession {
   static Type get instanceRuntimeType => MediaKeySessionImpl;
 
 }
@@ -1717,7 +1717,7 @@
   get runtimeType => MediaKeySession;
   toString() => super.toString();
 }
-patch class MediaKeyStatusMap {
+@patch class MediaKeyStatusMap {
   static Type get instanceRuntimeType => MediaKeyStatusMapImpl;
 
 }
@@ -1726,7 +1726,7 @@
   get runtimeType => MediaKeyStatusMap;
   toString() => super.toString();
 }
-patch class MediaKeySystemAccess {
+@patch class MediaKeySystemAccess {
   static Type get instanceRuntimeType => MediaKeySystemAccessImpl;
 
 }
@@ -1735,7 +1735,7 @@
   get runtimeType => MediaKeySystemAccess;
   toString() => super.toString();
 }
-patch class MediaKeys {
+@patch class MediaKeys {
   static Type get instanceRuntimeType => MediaKeysImpl;
 
 }
@@ -1744,7 +1744,7 @@
   get runtimeType => MediaKeys;
   toString() => super.toString();
 }
-patch class MediaList {
+@patch class MediaList {
   static Type get instanceRuntimeType => MediaListImpl;
 
 }
@@ -1753,7 +1753,7 @@
   get runtimeType => MediaList;
   toString() => super.toString();
 }
-patch class MediaQueryList {
+@patch class MediaQueryList {
   static Type get instanceRuntimeType => MediaQueryListImpl;
 
 }
@@ -1762,7 +1762,7 @@
   get runtimeType => MediaQueryList;
   toString() => super.toString();
 }
-patch class MediaQueryListEvent {
+@patch class MediaQueryListEvent {
   static Type get instanceRuntimeType => MediaQueryListEventImpl;
 
 }
@@ -1771,7 +1771,7 @@
   get runtimeType => MediaQueryListEvent;
   toString() => super.toString();
 }
-patch class MediaSession {
+@patch class MediaSession {
   static Type get instanceRuntimeType => MediaSessionImpl;
 
 }
@@ -1780,7 +1780,7 @@
   get runtimeType => MediaSession;
   toString() => super.toString();
 }
-patch class MediaSource {
+@patch class MediaSource {
   static Type get instanceRuntimeType => MediaSourceImpl;
 
 }
@@ -1789,7 +1789,7 @@
   get runtimeType => MediaSource;
   toString() => super.toString();
 }
-patch class MediaStream {
+@patch class MediaStream {
   static Type get instanceRuntimeType => MediaStreamImpl;
 
 }
@@ -1798,7 +1798,7 @@
   get runtimeType => MediaStream;
   toString() => super.toString();
 }
-patch class MediaStreamEvent {
+@patch class MediaStreamEvent {
   static Type get instanceRuntimeType => MediaStreamEventImpl;
 
 }
@@ -1807,7 +1807,7 @@
   get runtimeType => MediaStreamEvent;
   toString() => super.toString();
 }
-patch class MediaStreamTrack {
+@patch class MediaStreamTrack {
   static Type get instanceRuntimeType => MediaStreamTrackImpl;
 
 }
@@ -1816,7 +1816,7 @@
   get runtimeType => MediaStreamTrack;
   toString() => super.toString();
 }
-patch class MediaStreamTrackEvent {
+@patch class MediaStreamTrackEvent {
   static Type get instanceRuntimeType => MediaStreamTrackEventImpl;
 
 }
@@ -1825,7 +1825,7 @@
   get runtimeType => MediaStreamTrackEvent;
   toString() => super.toString();
 }
-patch class MemoryInfo {
+@patch class MemoryInfo {
   static Type get instanceRuntimeType => MemoryInfoImpl;
 
 }
@@ -1834,7 +1834,7 @@
   get runtimeType => MemoryInfo;
   toString() => super.toString();
 }
-patch class MenuElement {
+@patch class MenuElement {
   static Type get instanceRuntimeType => MenuElementImpl;
 
 }
@@ -1843,7 +1843,7 @@
   get runtimeType => MenuElement;
   toString() => super.toString();
 }
-patch class MenuItemElement {
+@patch class MenuItemElement {
   static Type get instanceRuntimeType => MenuItemElementImpl;
 
 }
@@ -1852,7 +1852,7 @@
   get runtimeType => MenuItemElement;
   toString() => super.toString();
 }
-patch class MessageChannel {
+@patch class MessageChannel {
   static Type get instanceRuntimeType => MessageChannelImpl;
 
 }
@@ -1861,7 +1861,7 @@
   get runtimeType => MessageChannel;
   toString() => super.toString();
 }
-patch class MessageEvent {
+@patch class MessageEvent {
   static Type get instanceRuntimeType => MessageEventImpl;
 
 }
@@ -1870,7 +1870,7 @@
   get runtimeType => MessageEvent;
   toString() => super.toString();
 }
-patch class MessagePort {
+@patch class MessagePort {
   static Type get instanceRuntimeType => MessagePortImpl;
 
 }
@@ -1879,7 +1879,7 @@
   get runtimeType => MessagePort;
   toString() => super.toString();
 }
-patch class MetaElement {
+@patch class MetaElement {
   static Type get instanceRuntimeType => MetaElementImpl;
 
 }
@@ -1888,7 +1888,7 @@
   get runtimeType => MetaElement;
   toString() => super.toString();
 }
-patch class Metadata {
+@patch class Metadata {
   static Type get instanceRuntimeType => MetadataImpl;
 
 }
@@ -1897,7 +1897,7 @@
   get runtimeType => Metadata;
   toString() => super.toString();
 }
-patch class MeterElement {
+@patch class MeterElement {
   static Type get instanceRuntimeType => MeterElementImpl;
 
 }
@@ -1906,7 +1906,7 @@
   get runtimeType => MeterElement;
   toString() => super.toString();
 }
-patch class MidiAccess {
+@patch class MidiAccess {
   static Type get instanceRuntimeType => MidiAccessImpl;
 
 }
@@ -1915,7 +1915,7 @@
   get runtimeType => MidiAccess;
   toString() => super.toString();
 }
-patch class MidiConnectionEvent {
+@patch class MidiConnectionEvent {
   static Type get instanceRuntimeType => MidiConnectionEventImpl;
 
 }
@@ -1924,7 +1924,7 @@
   get runtimeType => MidiConnectionEvent;
   toString() => super.toString();
 }
-patch class MidiInput {
+@patch class MidiInput {
   static Type get instanceRuntimeType => MidiInputImpl;
 
 }
@@ -1933,7 +1933,7 @@
   get runtimeType => MidiInput;
   toString() => super.toString();
 }
-patch class MidiInputMap {
+@patch class MidiInputMap {
   static Type get instanceRuntimeType => MidiInputMapImpl;
 
 }
@@ -1942,7 +1942,7 @@
   get runtimeType => MidiInputMap;
   toString() => super.toString();
 }
-patch class MidiMessageEvent {
+@patch class MidiMessageEvent {
   static Type get instanceRuntimeType => MidiMessageEventImpl;
 
 }
@@ -1951,7 +1951,7 @@
   get runtimeType => MidiMessageEvent;
   toString() => super.toString();
 }
-patch class MidiOutput {
+@patch class MidiOutput {
   static Type get instanceRuntimeType => MidiOutputImpl;
 
 }
@@ -1960,7 +1960,7 @@
   get runtimeType => MidiOutput;
   toString() => super.toString();
 }
-patch class MidiOutputMap {
+@patch class MidiOutputMap {
   static Type get instanceRuntimeType => MidiOutputMapImpl;
 
 }
@@ -1969,7 +1969,7 @@
   get runtimeType => MidiOutputMap;
   toString() => super.toString();
 }
-patch class MidiPort {
+@patch class MidiPort {
   static Type get instanceRuntimeType => MidiPortImpl;
 
 }
@@ -1978,7 +1978,7 @@
   get runtimeType => MidiPort;
   toString() => super.toString();
 }
-patch class MimeType {
+@patch class MimeType {
   static Type get instanceRuntimeType => MimeTypeImpl;
 
 }
@@ -1987,7 +1987,7 @@
   get runtimeType => MimeType;
   toString() => super.toString();
 }
-patch class MimeTypeArray {
+@patch class MimeTypeArray {
   static Type get instanceRuntimeType => MimeTypeArrayImpl;
 
 }
@@ -1996,7 +1996,7 @@
   get runtimeType => MimeTypeArray;
   toString() => super.toString();
 }
-patch class ModElement {
+@patch class ModElement {
   static Type get instanceRuntimeType => ModElementImpl;
 
 }
@@ -2005,7 +2005,7 @@
   get runtimeType => ModElement;
   toString() => super.toString();
 }
-patch class MouseEvent {
+@patch class MouseEvent {
   static Type get instanceRuntimeType => MouseEventImpl;
 
 }
@@ -2014,7 +2014,7 @@
   get runtimeType => MouseEvent;
   toString() => super.toString();
 }
-patch class MutationObserver {
+@patch class MutationObserver {
   static Type get instanceRuntimeType => MutationObserverImpl;
 
 }
@@ -2023,7 +2023,7 @@
   get runtimeType => MutationObserver;
   toString() => super.toString();
 }
-patch class MutationRecord {
+@patch class MutationRecord {
   static Type get instanceRuntimeType => MutationRecordImpl;
 
 }
@@ -2032,7 +2032,7 @@
   get runtimeType => MutationRecord;
   toString() => super.toString();
 }
-patch class Navigator {
+@patch class Navigator {
   static Type get instanceRuntimeType => NavigatorImpl;
 
 }
@@ -2041,7 +2041,7 @@
   get runtimeType => Navigator;
   toString() => super.toString();
 }
-patch class NavigatorCpu {
+@patch class NavigatorCpu {
   static Type get instanceRuntimeType => NavigatorCpuImpl;
 
 }
@@ -2050,7 +2050,7 @@
   get runtimeType => NavigatorCpu;
   toString() => super.toString();
 }
-patch class NavigatorID {
+@patch class NavigatorID {
   static Type get instanceRuntimeType => NavigatorIDImpl;
 
 }
@@ -2059,7 +2059,7 @@
   get runtimeType => NavigatorID;
   toString() => super.toString();
 }
-patch class NavigatorLanguage {
+@patch class NavigatorLanguage {
   static Type get instanceRuntimeType => NavigatorLanguageImpl;
 
 }
@@ -2068,7 +2068,7 @@
   get runtimeType => NavigatorLanguage;
   toString() => super.toString();
 }
-patch class NavigatorOnLine {
+@patch class NavigatorOnLine {
   static Type get instanceRuntimeType => NavigatorOnLineImpl;
 
 }
@@ -2077,7 +2077,7 @@
   get runtimeType => NavigatorOnLine;
   toString() => super.toString();
 }
-patch class NavigatorStorageUtils {
+@patch class NavigatorStorageUtils {
   static Type get instanceRuntimeType => NavigatorStorageUtilsImpl;
 
 }
@@ -2086,7 +2086,7 @@
   get runtimeType => NavigatorStorageUtils;
   toString() => super.toString();
 }
-patch class NavigatorUserMediaError {
+@patch class NavigatorUserMediaError {
   static Type get instanceRuntimeType => NavigatorUserMediaErrorImpl;
 
 }
@@ -2095,7 +2095,7 @@
   get runtimeType => NavigatorUserMediaError;
   toString() => super.toString();
 }
-patch class NetworkInformation {
+@patch class NetworkInformation {
   static Type get instanceRuntimeType => NetworkInformationImpl;
 
 }
@@ -2104,7 +2104,7 @@
   get runtimeType => NetworkInformation;
   toString() => super.toString();
 }
-patch class Node {
+@patch class Node {
   static Type get instanceRuntimeType => NodeImpl;
 
 }
@@ -2113,7 +2113,7 @@
   get runtimeType => Node;
   toString() => super.toString();
 }
-patch class NodeFilter {
+@patch class NodeFilter {
   static Type get instanceRuntimeType => NodeFilterImpl;
 
 }
@@ -2122,7 +2122,7 @@
   get runtimeType => NodeFilter;
   toString() => super.toString();
 }
-patch class NodeIterator {
+@patch class NodeIterator {
   static Type get instanceRuntimeType => NodeIteratorImpl;
 
 }
@@ -2131,7 +2131,7 @@
   get runtimeType => NodeIterator;
   toString() => super.toString();
 }
-patch class NodeList {
+@patch class NodeList {
   static Type get instanceRuntimeType => NodeListImpl;
 
 }
@@ -2140,7 +2140,7 @@
   get runtimeType => NodeList;
   toString() => super.toString();
 }
-patch class NonDocumentTypeChildNode {
+@patch class NonDocumentTypeChildNode {
   static Type get instanceRuntimeType => NonDocumentTypeChildNodeImpl;
 
 }
@@ -2149,7 +2149,7 @@
   get runtimeType => NonDocumentTypeChildNode;
   toString() => super.toString();
 }
-patch class NonElementParentNode {
+@patch class NonElementParentNode {
   static Type get instanceRuntimeType => NonElementParentNodeImpl;
 
 }
@@ -2158,7 +2158,7 @@
   get runtimeType => NonElementParentNode;
   toString() => super.toString();
 }
-patch class Notification {
+@patch class Notification {
   static Type get instanceRuntimeType => NotificationImpl;
 
 }
@@ -2167,7 +2167,7 @@
   get runtimeType => Notification;
   toString() => super.toString();
 }
-patch class NotificationEvent {
+@patch class NotificationEvent {
   static Type get instanceRuntimeType => NotificationEventImpl;
 
 }
@@ -2176,7 +2176,7 @@
   get runtimeType => NotificationEvent;
   toString() => super.toString();
 }
-patch class OListElement {
+@patch class OListElement {
   static Type get instanceRuntimeType => OListElementImpl;
 
 }
@@ -2185,7 +2185,7 @@
   get runtimeType => OListElement;
   toString() => super.toString();
 }
-patch class ObjectElement {
+@patch class ObjectElement {
   static Type get instanceRuntimeType => ObjectElementImpl;
 
 }
@@ -2194,7 +2194,7 @@
   get runtimeType => ObjectElement;
   toString() => super.toString();
 }
-patch class OptGroupElement {
+@patch class OptGroupElement {
   static Type get instanceRuntimeType => OptGroupElementImpl;
 
 }
@@ -2203,7 +2203,7 @@
   get runtimeType => OptGroupElement;
   toString() => super.toString();
 }
-patch class OptionElement {
+@patch class OptionElement {
   static Type get instanceRuntimeType => OptionElementImpl;
 
 }
@@ -2212,7 +2212,7 @@
   get runtimeType => OptionElement;
   toString() => super.toString();
 }
-patch class OutputElement {
+@patch class OutputElement {
   static Type get instanceRuntimeType => OutputElementImpl;
 
 }
@@ -2221,7 +2221,7 @@
   get runtimeType => OutputElement;
   toString() => super.toString();
 }
-patch class PageTransitionEvent {
+@patch class PageTransitionEvent {
   static Type get instanceRuntimeType => PageTransitionEventImpl;
 
 }
@@ -2230,7 +2230,7 @@
   get runtimeType => PageTransitionEvent;
   toString() => super.toString();
 }
-patch class ParagraphElement {
+@patch class ParagraphElement {
   static Type get instanceRuntimeType => ParagraphElementImpl;
 
 }
@@ -2239,7 +2239,7 @@
   get runtimeType => ParagraphElement;
   toString() => super.toString();
 }
-patch class ParamElement {
+@patch class ParamElement {
   static Type get instanceRuntimeType => ParamElementImpl;
 
 }
@@ -2248,7 +2248,7 @@
   get runtimeType => ParamElement;
   toString() => super.toString();
 }
-patch class ParentNode {
+@patch class ParentNode {
   static Type get instanceRuntimeType => ParentNodeImpl;
 
 }
@@ -2257,7 +2257,7 @@
   get runtimeType => ParentNode;
   toString() => super.toString();
 }
-patch class PasswordCredential {
+@patch class PasswordCredential {
   static Type get instanceRuntimeType => PasswordCredentialImpl;
 
 }
@@ -2266,7 +2266,7 @@
   get runtimeType => PasswordCredential;
   toString() => super.toString();
 }
-patch class Path2D {
+@patch class Path2D {
   static Type get instanceRuntimeType => Path2DImpl;
 
 }
@@ -2275,7 +2275,7 @@
   get runtimeType => Path2D;
   toString() => super.toString();
 }
-patch class Performance {
+@patch class Performance {
   static Type get instanceRuntimeType => PerformanceImpl;
 
 }
@@ -2284,7 +2284,7 @@
   get runtimeType => Performance;
   toString() => super.toString();
 }
-patch class PerformanceCompositeTiming {
+@patch class PerformanceCompositeTiming {
   static Type get instanceRuntimeType => PerformanceCompositeTimingImpl;
 
 }
@@ -2293,7 +2293,7 @@
   get runtimeType => PerformanceCompositeTiming;
   toString() => super.toString();
 }
-patch class PerformanceEntry {
+@patch class PerformanceEntry {
   static Type get instanceRuntimeType => PerformanceEntryImpl;
 
 }
@@ -2302,7 +2302,7 @@
   get runtimeType => PerformanceEntry;
   toString() => super.toString();
 }
-patch class PerformanceMark {
+@patch class PerformanceMark {
   static Type get instanceRuntimeType => PerformanceMarkImpl;
 
 }
@@ -2311,7 +2311,7 @@
   get runtimeType => PerformanceMark;
   toString() => super.toString();
 }
-patch class PerformanceMeasure {
+@patch class PerformanceMeasure {
   static Type get instanceRuntimeType => PerformanceMeasureImpl;
 
 }
@@ -2320,7 +2320,7 @@
   get runtimeType => PerformanceMeasure;
   toString() => super.toString();
 }
-patch class PerformanceNavigation {
+@patch class PerformanceNavigation {
   static Type get instanceRuntimeType => PerformanceNavigationImpl;
 
 }
@@ -2329,7 +2329,7 @@
   get runtimeType => PerformanceNavigation;
   toString() => super.toString();
 }
-patch class PerformanceRenderTiming {
+@patch class PerformanceRenderTiming {
   static Type get instanceRuntimeType => PerformanceRenderTimingImpl;
 
 }
@@ -2338,7 +2338,7 @@
   get runtimeType => PerformanceRenderTiming;
   toString() => super.toString();
 }
-patch class PerformanceResourceTiming {
+@patch class PerformanceResourceTiming {
   static Type get instanceRuntimeType => PerformanceResourceTimingImpl;
 
 }
@@ -2347,7 +2347,7 @@
   get runtimeType => PerformanceResourceTiming;
   toString() => super.toString();
 }
-patch class PerformanceTiming {
+@patch class PerformanceTiming {
   static Type get instanceRuntimeType => PerformanceTimingImpl;
 
 }
@@ -2356,7 +2356,7 @@
   get runtimeType => PerformanceTiming;
   toString() => super.toString();
 }
-patch class PeriodicSyncEvent {
+@patch class PeriodicSyncEvent {
   static Type get instanceRuntimeType => PeriodicSyncEventImpl;
 
 }
@@ -2365,7 +2365,7 @@
   get runtimeType => PeriodicSyncEvent;
   toString() => super.toString();
 }
-patch class PeriodicSyncManager {
+@patch class PeriodicSyncManager {
   static Type get instanceRuntimeType => PeriodicSyncManagerImpl;
 
 }
@@ -2374,7 +2374,7 @@
   get runtimeType => PeriodicSyncManager;
   toString() => super.toString();
 }
-patch class PeriodicSyncRegistration {
+@patch class PeriodicSyncRegistration {
   static Type get instanceRuntimeType => PeriodicSyncRegistrationImpl;
 
 }
@@ -2383,7 +2383,7 @@
   get runtimeType => PeriodicSyncRegistration;
   toString() => super.toString();
 }
-patch class PermissionStatus {
+@patch class PermissionStatus {
   static Type get instanceRuntimeType => PermissionStatusImpl;
 
 }
@@ -2392,7 +2392,7 @@
   get runtimeType => PermissionStatus;
   toString() => super.toString();
 }
-patch class Permissions {
+@patch class Permissions {
   static Type get instanceRuntimeType => PermissionsImpl;
 
 }
@@ -2401,7 +2401,7 @@
   get runtimeType => Permissions;
   toString() => super.toString();
 }
-patch class PictureElement {
+@patch class PictureElement {
   static Type get instanceRuntimeType => PictureElementImpl;
 
 }
@@ -2410,7 +2410,7 @@
   get runtimeType => PictureElement;
   toString() => super.toString();
 }
-patch class Plugin {
+@patch class Plugin {
   static Type get instanceRuntimeType => PluginImpl;
 
 }
@@ -2419,7 +2419,7 @@
   get runtimeType => Plugin;
   toString() => super.toString();
 }
-patch class PluginArray {
+@patch class PluginArray {
   static Type get instanceRuntimeType => PluginArrayImpl;
 
 }
@@ -2428,7 +2428,7 @@
   get runtimeType => PluginArray;
   toString() => super.toString();
 }
-patch class PluginPlaceholderElement {
+@patch class PluginPlaceholderElement {
   static Type get instanceRuntimeType => PluginPlaceholderElementImpl;
 
 }
@@ -2437,7 +2437,7 @@
   get runtimeType => PluginPlaceholderElement;
   toString() => super.toString();
 }
-patch class PointerEvent {
+@patch class PointerEvent {
   static Type get instanceRuntimeType => PointerEventImpl;
 
 }
@@ -2446,7 +2446,7 @@
   get runtimeType => PointerEvent;
   toString() => super.toString();
 }
-patch class PopStateEvent {
+@patch class PopStateEvent {
   static Type get instanceRuntimeType => PopStateEventImpl;
 
 }
@@ -2455,7 +2455,7 @@
   get runtimeType => PopStateEvent;
   toString() => super.toString();
 }
-patch class PositionError {
+@patch class PositionError {
   static Type get instanceRuntimeType => PositionErrorImpl;
 
 }
@@ -2464,7 +2464,7 @@
   get runtimeType => PositionError;
   toString() => super.toString();
 }
-patch class PositionSensorVRDevice {
+@patch class PositionSensorVRDevice {
   static Type get instanceRuntimeType => PositionSensorVRDeviceImpl;
 
 }
@@ -2473,7 +2473,7 @@
   get runtimeType => PositionSensorVRDevice;
   toString() => super.toString();
 }
-patch class PreElement {
+@patch class PreElement {
   static Type get instanceRuntimeType => PreElementImpl;
 
 }
@@ -2482,7 +2482,7 @@
   get runtimeType => PreElement;
   toString() => super.toString();
 }
-patch class Presentation {
+@patch class Presentation {
   static Type get instanceRuntimeType => PresentationImpl;
 
 }
@@ -2491,7 +2491,7 @@
   get runtimeType => Presentation;
   toString() => super.toString();
 }
-patch class PresentationAvailability {
+@patch class PresentationAvailability {
   static Type get instanceRuntimeType => PresentationAvailabilityImpl;
 
 }
@@ -2500,7 +2500,7 @@
   get runtimeType => PresentationAvailability;
   toString() => super.toString();
 }
-patch class PresentationSession {
+@patch class PresentationSession {
   static Type get instanceRuntimeType => PresentationSessionImpl;
 
 }
@@ -2509,7 +2509,7 @@
   get runtimeType => PresentationSession;
   toString() => super.toString();
 }
-patch class ProcessingInstruction {
+@patch class ProcessingInstruction {
   static Type get instanceRuntimeType => ProcessingInstructionImpl;
 
 }
@@ -2518,7 +2518,7 @@
   get runtimeType => ProcessingInstruction;
   toString() => super.toString();
 }
-patch class ProgressElement {
+@patch class ProgressElement {
   static Type get instanceRuntimeType => ProgressElementImpl;
 
 }
@@ -2527,7 +2527,7 @@
   get runtimeType => ProgressElement;
   toString() => super.toString();
 }
-patch class ProgressEvent {
+@patch class ProgressEvent {
   static Type get instanceRuntimeType => ProgressEventImpl;
 
 }
@@ -2536,7 +2536,7 @@
   get runtimeType => ProgressEvent;
   toString() => super.toString();
 }
-patch class PromiseRejectionEvent {
+@patch class PromiseRejectionEvent {
   static Type get instanceRuntimeType => PromiseRejectionEventImpl;
 
 }
@@ -2545,7 +2545,7 @@
   get runtimeType => PromiseRejectionEvent;
   toString() => super.toString();
 }
-patch class PushEvent {
+@patch class PushEvent {
   static Type get instanceRuntimeType => PushEventImpl;
 
 }
@@ -2554,7 +2554,7 @@
   get runtimeType => PushEvent;
   toString() => super.toString();
 }
-patch class PushManager {
+@patch class PushManager {
   static Type get instanceRuntimeType => PushManagerImpl;
 
 }
@@ -2563,7 +2563,7 @@
   get runtimeType => PushManager;
   toString() => super.toString();
 }
-patch class PushMessageData {
+@patch class PushMessageData {
   static Type get instanceRuntimeType => PushMessageDataImpl;
 
 }
@@ -2572,7 +2572,7 @@
   get runtimeType => PushMessageData;
   toString() => super.toString();
 }
-patch class PushSubscription {
+@patch class PushSubscription {
   static Type get instanceRuntimeType => PushSubscriptionImpl;
 
 }
@@ -2581,7 +2581,7 @@
   get runtimeType => PushSubscription;
   toString() => super.toString();
 }
-patch class QuoteElement {
+@patch class QuoteElement {
   static Type get instanceRuntimeType => QuoteElementImpl;
 
 }
@@ -2590,7 +2590,7 @@
   get runtimeType => QuoteElement;
   toString() => super.toString();
 }
-patch class Range {
+@patch class Range {
   static Type get instanceRuntimeType => RangeImpl;
 
 }
@@ -2599,7 +2599,7 @@
   get runtimeType => Range;
   toString() => super.toString();
 }
-patch class ReadableByteStream {
+@patch class ReadableByteStream {
   static Type get instanceRuntimeType => ReadableByteStreamImpl;
 
 }
@@ -2608,7 +2608,7 @@
   get runtimeType => ReadableByteStream;
   toString() => super.toString();
 }
-patch class ReadableByteStreamReader {
+@patch class ReadableByteStreamReader {
   static Type get instanceRuntimeType => ReadableByteStreamReaderImpl;
 
 }
@@ -2617,7 +2617,7 @@
   get runtimeType => ReadableByteStreamReader;
   toString() => super.toString();
 }
-patch class ReadableStream {
+@patch class ReadableStream {
   static Type get instanceRuntimeType => ReadableStreamImpl;
 
 }
@@ -2626,7 +2626,7 @@
   get runtimeType => ReadableStream;
   toString() => super.toString();
 }
-patch class ReadableStreamReader {
+@patch class ReadableStreamReader {
   static Type get instanceRuntimeType => ReadableStreamReaderImpl;
 
 }
@@ -2635,7 +2635,7 @@
   get runtimeType => ReadableStreamReader;
   toString() => super.toString();
 }
-patch class RelatedEvent {
+@patch class RelatedEvent {
   static Type get instanceRuntimeType => RelatedEventImpl;
 
 }
@@ -2644,7 +2644,7 @@
   get runtimeType => RelatedEvent;
   toString() => super.toString();
 }
-patch class RtcDataChannel {
+@patch class RtcDataChannel {
   static Type get instanceRuntimeType => RtcDataChannelImpl;
 
 }
@@ -2653,7 +2653,7 @@
   get runtimeType => RtcDataChannel;
   toString() => super.toString();
 }
-patch class RtcDataChannelEvent {
+@patch class RtcDataChannelEvent {
   static Type get instanceRuntimeType => RtcDataChannelEventImpl;
 
 }
@@ -2662,7 +2662,7 @@
   get runtimeType => RtcDataChannelEvent;
   toString() => super.toString();
 }
-patch class RtcDtmfSender {
+@patch class RtcDtmfSender {
   static Type get instanceRuntimeType => RtcDtmfSenderImpl;
 
 }
@@ -2671,7 +2671,7 @@
   get runtimeType => RtcDtmfSender;
   toString() => super.toString();
 }
-patch class RtcDtmfToneChangeEvent {
+@patch class RtcDtmfToneChangeEvent {
   static Type get instanceRuntimeType => RtcDtmfToneChangeEventImpl;
 
 }
@@ -2680,7 +2680,7 @@
   get runtimeType => RtcDtmfToneChangeEvent;
   toString() => super.toString();
 }
-patch class RtcIceCandidate {
+@patch class RtcIceCandidate {
   static Type get instanceRuntimeType => RtcIceCandidateImpl;
 
 }
@@ -2689,7 +2689,7 @@
   get runtimeType => RtcIceCandidate;
   toString() => super.toString();
 }
-patch class RtcIceCandidateEvent {
+@patch class RtcIceCandidateEvent {
   static Type get instanceRuntimeType => RtcIceCandidateEventImpl;
 
 }
@@ -2698,7 +2698,7 @@
   get runtimeType => RtcIceCandidateEvent;
   toString() => super.toString();
 }
-patch class RtcPeerConnection {
+@patch class RtcPeerConnection {
   static Type get instanceRuntimeType => RtcPeerConnectionImpl;
 
 }
@@ -2707,7 +2707,7 @@
   get runtimeType => RtcPeerConnection;
   toString() => super.toString();
 }
-patch class RtcSessionDescription {
+@patch class RtcSessionDescription {
   static Type get instanceRuntimeType => RtcSessionDescriptionImpl;
 
 }
@@ -2716,7 +2716,7 @@
   get runtimeType => RtcSessionDescription;
   toString() => super.toString();
 }
-patch class RtcStatsReport {
+@patch class RtcStatsReport {
   static Type get instanceRuntimeType => RtcStatsReportImpl;
 
 }
@@ -2725,7 +2725,7 @@
   get runtimeType => RtcStatsReport;
   toString() => super.toString();
 }
-patch class RtcStatsResponse {
+@patch class RtcStatsResponse {
   static Type get instanceRuntimeType => RtcStatsResponseImpl;
 
 }
@@ -2734,7 +2734,7 @@
   get runtimeType => RtcStatsResponse;
   toString() => super.toString();
 }
-patch class Screen {
+@patch class Screen {
   static Type get instanceRuntimeType => ScreenImpl;
 
 }
@@ -2743,7 +2743,7 @@
   get runtimeType => Screen;
   toString() => super.toString();
 }
-patch class ScreenOrientation {
+@patch class ScreenOrientation {
   static Type get instanceRuntimeType => ScreenOrientationImpl;
 
 }
@@ -2752,7 +2752,7 @@
   get runtimeType => ScreenOrientation;
   toString() => super.toString();
 }
-patch class ScriptElement {
+@patch class ScriptElement {
   static Type get instanceRuntimeType => ScriptElementImpl;
 
 }
@@ -2761,7 +2761,7 @@
   get runtimeType => ScriptElement;
   toString() => super.toString();
 }
-patch class ScrollState {
+@patch class ScrollState {
   static Type get instanceRuntimeType => ScrollStateImpl;
 
 }
@@ -2770,7 +2770,7 @@
   get runtimeType => ScrollState;
   toString() => super.toString();
 }
-patch class SecurityPolicyViolationEvent {
+@patch class SecurityPolicyViolationEvent {
   static Type get instanceRuntimeType => SecurityPolicyViolationEventImpl;
 
 }
@@ -2779,7 +2779,7 @@
   get runtimeType => SecurityPolicyViolationEvent;
   toString() => super.toString();
 }
-patch class SelectElement {
+@patch class SelectElement {
   static Type get instanceRuntimeType => SelectElementImpl;
 
 }
@@ -2788,7 +2788,7 @@
   get runtimeType => SelectElement;
   toString() => super.toString();
 }
-patch class Selection {
+@patch class Selection {
   static Type get instanceRuntimeType => SelectionImpl;
 
 }
@@ -2797,7 +2797,7 @@
   get runtimeType => Selection;
   toString() => super.toString();
 }
-patch class ServicePort {
+@patch class ServicePort {
   static Type get instanceRuntimeType => ServicePortImpl;
 
 }
@@ -2806,7 +2806,7 @@
   get runtimeType => ServicePort;
   toString() => super.toString();
 }
-patch class ServicePortCollection {
+@patch class ServicePortCollection {
   static Type get instanceRuntimeType => ServicePortCollectionImpl;
 
 }
@@ -2815,7 +2815,7 @@
   get runtimeType => ServicePortCollection;
   toString() => super.toString();
 }
-patch class ServicePortConnectEvent {
+@patch class ServicePortConnectEvent {
   static Type get instanceRuntimeType => ServicePortConnectEventImpl;
 
 }
@@ -2824,7 +2824,7 @@
   get runtimeType => ServicePortConnectEvent;
   toString() => super.toString();
 }
-patch class ServiceWorkerContainer {
+@patch class ServiceWorkerContainer {
   static Type get instanceRuntimeType => ServiceWorkerContainerImpl;
 
 }
@@ -2833,7 +2833,7 @@
   get runtimeType => ServiceWorkerContainer;
   toString() => super.toString();
 }
-patch class ServiceWorkerGlobalScope {
+@patch class ServiceWorkerGlobalScope {
   static Type get instanceRuntimeType => ServiceWorkerGlobalScopeImpl;
 
 }
@@ -2842,7 +2842,7 @@
   get runtimeType => ServiceWorkerGlobalScope;
   toString() => super.toString();
 }
-patch class ServiceWorkerMessageEvent {
+@patch class ServiceWorkerMessageEvent {
   static Type get instanceRuntimeType => ServiceWorkerMessageEventImpl;
 
 }
@@ -2851,7 +2851,7 @@
   get runtimeType => ServiceWorkerMessageEvent;
   toString() => super.toString();
 }
-patch class ServiceWorkerRegistration {
+@patch class ServiceWorkerRegistration {
   static Type get instanceRuntimeType => ServiceWorkerRegistrationImpl;
 
 }
@@ -2860,7 +2860,7 @@
   get runtimeType => ServiceWorkerRegistration;
   toString() => super.toString();
 }
-patch class ShadowElement {
+@patch class ShadowElement {
   static Type get instanceRuntimeType => ShadowElementImpl;
 
 }
@@ -2869,7 +2869,7 @@
   get runtimeType => ShadowElement;
   toString() => super.toString();
 }
-patch class ShadowRoot {
+@patch class ShadowRoot {
   static Type get instanceRuntimeType => ShadowRootImpl;
 
 }
@@ -2878,7 +2878,7 @@
   get runtimeType => ShadowRoot;
   toString() => super.toString();
 }
-patch class SharedArrayBuffer {
+@patch class SharedArrayBuffer {
   static Type get instanceRuntimeType => SharedArrayBufferImpl;
 
 }
@@ -2887,7 +2887,7 @@
   get runtimeType => SharedArrayBuffer;
   toString() => super.toString();
 }
-patch class SharedWorker {
+@patch class SharedWorker {
   static Type get instanceRuntimeType => SharedWorkerImpl;
 
 }
@@ -2896,7 +2896,7 @@
   get runtimeType => SharedWorker;
   toString() => super.toString();
 }
-patch class SharedWorkerGlobalScope {
+@patch class SharedWorkerGlobalScope {
   static Type get instanceRuntimeType => SharedWorkerGlobalScopeImpl;
 
 }
@@ -2905,7 +2905,7 @@
   get runtimeType => SharedWorkerGlobalScope;
   toString() => super.toString();
 }
-patch class SourceBuffer {
+@patch class SourceBuffer {
   static Type get instanceRuntimeType => SourceBufferImpl;
 
 }
@@ -2914,7 +2914,7 @@
   get runtimeType => SourceBuffer;
   toString() => super.toString();
 }
-patch class SourceBufferList {
+@patch class SourceBufferList {
   static Type get instanceRuntimeType => SourceBufferListImpl;
 
 }
@@ -2923,7 +2923,7 @@
   get runtimeType => SourceBufferList;
   toString() => super.toString();
 }
-patch class SourceElement {
+@patch class SourceElement {
   static Type get instanceRuntimeType => SourceElementImpl;
 
 }
@@ -2932,7 +2932,7 @@
   get runtimeType => SourceElement;
   toString() => super.toString();
 }
-patch class SourceInfo {
+@patch class SourceInfo {
   static Type get instanceRuntimeType => SourceInfoImpl;
 
 }
@@ -2941,7 +2941,7 @@
   get runtimeType => SourceInfo;
   toString() => super.toString();
 }
-patch class SpanElement {
+@patch class SpanElement {
   static Type get instanceRuntimeType => SpanElementImpl;
 
 }
@@ -2950,7 +2950,7 @@
   get runtimeType => SpanElement;
   toString() => super.toString();
 }
-patch class SpeechGrammar {
+@patch class SpeechGrammar {
   static Type get instanceRuntimeType => SpeechGrammarImpl;
 
 }
@@ -2959,7 +2959,7 @@
   get runtimeType => SpeechGrammar;
   toString() => super.toString();
 }
-patch class SpeechGrammarList {
+@patch class SpeechGrammarList {
   static Type get instanceRuntimeType => SpeechGrammarListImpl;
 
 }
@@ -2968,7 +2968,7 @@
   get runtimeType => SpeechGrammarList;
   toString() => super.toString();
 }
-patch class SpeechRecognition {
+@patch class SpeechRecognition {
   static Type get instanceRuntimeType => SpeechRecognitionImpl;
 
 }
@@ -2977,7 +2977,7 @@
   get runtimeType => SpeechRecognition;
   toString() => super.toString();
 }
-patch class SpeechRecognitionAlternative {
+@patch class SpeechRecognitionAlternative {
   static Type get instanceRuntimeType => SpeechRecognitionAlternativeImpl;
 
 }
@@ -2986,7 +2986,7 @@
   get runtimeType => SpeechRecognitionAlternative;
   toString() => super.toString();
 }
-patch class SpeechRecognitionError {
+@patch class SpeechRecognitionError {
   static Type get instanceRuntimeType => SpeechRecognitionErrorImpl;
 
 }
@@ -2995,7 +2995,7 @@
   get runtimeType => SpeechRecognitionError;
   toString() => super.toString();
 }
-patch class SpeechRecognitionEvent {
+@patch class SpeechRecognitionEvent {
   static Type get instanceRuntimeType => SpeechRecognitionEventImpl;
 
 }
@@ -3004,7 +3004,7 @@
   get runtimeType => SpeechRecognitionEvent;
   toString() => super.toString();
 }
-patch class SpeechRecognitionResult {
+@patch class SpeechRecognitionResult {
   static Type get instanceRuntimeType => SpeechRecognitionResultImpl;
 
 }
@@ -3013,7 +3013,7 @@
   get runtimeType => SpeechRecognitionResult;
   toString() => super.toString();
 }
-patch class SpeechSynthesis {
+@patch class SpeechSynthesis {
   static Type get instanceRuntimeType => SpeechSynthesisImpl;
 
 }
@@ -3022,7 +3022,7 @@
   get runtimeType => SpeechSynthesis;
   toString() => super.toString();
 }
-patch class SpeechSynthesisEvent {
+@patch class SpeechSynthesisEvent {
   static Type get instanceRuntimeType => SpeechSynthesisEventImpl;
 
 }
@@ -3031,7 +3031,7 @@
   get runtimeType => SpeechSynthesisEvent;
   toString() => super.toString();
 }
-patch class SpeechSynthesisUtterance {
+@patch class SpeechSynthesisUtterance {
   static Type get instanceRuntimeType => SpeechSynthesisUtteranceImpl;
 
 }
@@ -3040,7 +3040,7 @@
   get runtimeType => SpeechSynthesisUtterance;
   toString() => super.toString();
 }
-patch class SpeechSynthesisVoice {
+@patch class SpeechSynthesisVoice {
   static Type get instanceRuntimeType => SpeechSynthesisVoiceImpl;
 
 }
@@ -3049,7 +3049,7 @@
   get runtimeType => SpeechSynthesisVoice;
   toString() => super.toString();
 }
-patch class StashedMessagePort {
+@patch class StashedMessagePort {
   static Type get instanceRuntimeType => StashedMessagePortImpl;
 
 }
@@ -3058,7 +3058,7 @@
   get runtimeType => StashedMessagePort;
   toString() => super.toString();
 }
-patch class StashedPortCollection {
+@patch class StashedPortCollection {
   static Type get instanceRuntimeType => StashedPortCollectionImpl;
 
 }
@@ -3067,7 +3067,7 @@
   get runtimeType => StashedPortCollection;
   toString() => super.toString();
 }
-patch class Storage {
+@patch class Storage {
   static Type get instanceRuntimeType => StorageImpl;
 
 }
@@ -3076,7 +3076,7 @@
   get runtimeType => Storage;
   toString() => super.toString();
 }
-patch class StorageEvent {
+@patch class StorageEvent {
   static Type get instanceRuntimeType => StorageEventImpl;
 
 }
@@ -3085,7 +3085,7 @@
   get runtimeType => StorageEvent;
   toString() => super.toString();
 }
-patch class StorageInfo {
+@patch class StorageInfo {
   static Type get instanceRuntimeType => StorageInfoImpl;
 
 }
@@ -3094,7 +3094,7 @@
   get runtimeType => StorageInfo;
   toString() => super.toString();
 }
-patch class StorageQuota {
+@patch class StorageQuota {
   static Type get instanceRuntimeType => StorageQuotaImpl;
 
 }
@@ -3103,7 +3103,7 @@
   get runtimeType => StorageQuota;
   toString() => super.toString();
 }
-patch class StyleElement {
+@patch class StyleElement {
   static Type get instanceRuntimeType => StyleElementImpl;
 
 }
@@ -3112,7 +3112,7 @@
   get runtimeType => StyleElement;
   toString() => super.toString();
 }
-patch class StyleMedia {
+@patch class StyleMedia {
   static Type get instanceRuntimeType => StyleMediaImpl;
 
 }
@@ -3121,7 +3121,7 @@
   get runtimeType => StyleMedia;
   toString() => super.toString();
 }
-patch class StyleSheet {
+@patch class StyleSheet {
   static Type get instanceRuntimeType => StyleSheetImpl;
 
 }
@@ -3130,7 +3130,7 @@
   get runtimeType => StyleSheet;
   toString() => super.toString();
 }
-patch class SyncEvent {
+@patch class SyncEvent {
   static Type get instanceRuntimeType => SyncEventImpl;
 
 }
@@ -3139,7 +3139,7 @@
   get runtimeType => SyncEvent;
   toString() => super.toString();
 }
-patch class SyncManager {
+@patch class SyncManager {
   static Type get instanceRuntimeType => SyncManagerImpl;
 
 }
@@ -3148,7 +3148,7 @@
   get runtimeType => SyncManager;
   toString() => super.toString();
 }
-patch class SyncRegistration {
+@patch class SyncRegistration {
   static Type get instanceRuntimeType => SyncRegistrationImpl;
 
 }
@@ -3157,7 +3157,7 @@
   get runtimeType => SyncRegistration;
   toString() => super.toString();
 }
-patch class TableCaptionElement {
+@patch class TableCaptionElement {
   static Type get instanceRuntimeType => TableCaptionElementImpl;
 
 }
@@ -3166,7 +3166,7 @@
   get runtimeType => TableCaptionElement;
   toString() => super.toString();
 }
-patch class TableCellElement {
+@patch class TableCellElement {
   static Type get instanceRuntimeType => TableCellElementImpl;
 
 }
@@ -3175,7 +3175,7 @@
   get runtimeType => TableCellElement;
   toString() => super.toString();
 }
-patch class TableColElement {
+@patch class TableColElement {
   static Type get instanceRuntimeType => TableColElementImpl;
 
 }
@@ -3184,7 +3184,7 @@
   get runtimeType => TableColElement;
   toString() => super.toString();
 }
-patch class TableElement {
+@patch class TableElement {
   static Type get instanceRuntimeType => TableElementImpl;
 
 }
@@ -3193,7 +3193,7 @@
   get runtimeType => TableElement;
   toString() => super.toString();
 }
-patch class TableRowElement {
+@patch class TableRowElement {
   static Type get instanceRuntimeType => TableRowElementImpl;
 
 }
@@ -3202,7 +3202,7 @@
   get runtimeType => TableRowElement;
   toString() => super.toString();
 }
-patch class TableSectionElement {
+@patch class TableSectionElement {
   static Type get instanceRuntimeType => TableSectionElementImpl;
 
 }
@@ -3211,7 +3211,7 @@
   get runtimeType => TableSectionElement;
   toString() => super.toString();
 }
-patch class TemplateElement {
+@patch class TemplateElement {
   static Type get instanceRuntimeType => TemplateElementImpl;
 
 }
@@ -3220,7 +3220,7 @@
   get runtimeType => TemplateElement;
   toString() => super.toString();
 }
-patch class Text {
+@patch class Text {
   static Type get instanceRuntimeType => TextImpl;
 
 }
@@ -3229,7 +3229,7 @@
   get runtimeType => Text;
   toString() => super.toString();
 }
-patch class TextAreaElement {
+@patch class TextAreaElement {
   static Type get instanceRuntimeType => TextAreaElementImpl;
 
 }
@@ -3238,7 +3238,7 @@
   get runtimeType => TextAreaElement;
   toString() => super.toString();
 }
-patch class TextEvent {
+@patch class TextEvent {
   static Type get instanceRuntimeType => TextEventImpl;
 
 }
@@ -3247,7 +3247,7 @@
   get runtimeType => TextEvent;
   toString() => super.toString();
 }
-patch class TextMetrics {
+@patch class TextMetrics {
   static Type get instanceRuntimeType => TextMetricsImpl;
 
 }
@@ -3256,7 +3256,7 @@
   get runtimeType => TextMetrics;
   toString() => super.toString();
 }
-patch class TextTrack {
+@patch class TextTrack {
   static Type get instanceRuntimeType => TextTrackImpl;
 
 }
@@ -3265,7 +3265,7 @@
   get runtimeType => TextTrack;
   toString() => super.toString();
 }
-patch class TextTrackCue {
+@patch class TextTrackCue {
   static Type get instanceRuntimeType => TextTrackCueImpl;
 
 }
@@ -3274,7 +3274,7 @@
   get runtimeType => TextTrackCue;
   toString() => super.toString();
 }
-patch class TextTrackCueList {
+@patch class TextTrackCueList {
   static Type get instanceRuntimeType => TextTrackCueListImpl;
 
 }
@@ -3283,7 +3283,7 @@
   get runtimeType => TextTrackCueList;
   toString() => super.toString();
 }
-patch class TextTrackList {
+@patch class TextTrackList {
   static Type get instanceRuntimeType => TextTrackListImpl;
 
 }
@@ -3292,7 +3292,7 @@
   get runtimeType => TextTrackList;
   toString() => super.toString();
 }
-patch class TimeRanges {
+@patch class TimeRanges {
   static Type get instanceRuntimeType => TimeRangesImpl;
 
 }
@@ -3301,7 +3301,7 @@
   get runtimeType => TimeRanges;
   toString() => super.toString();
 }
-patch class TitleElement {
+@patch class TitleElement {
   static Type get instanceRuntimeType => TitleElementImpl;
 
 }
@@ -3310,7 +3310,7 @@
   get runtimeType => TitleElement;
   toString() => super.toString();
 }
-patch class Touch {
+@patch class Touch {
   static Type get instanceRuntimeType => TouchImpl;
 
 }
@@ -3319,7 +3319,7 @@
   get runtimeType => Touch;
   toString() => super.toString();
 }
-patch class TouchEvent {
+@patch class TouchEvent {
   static Type get instanceRuntimeType => TouchEventImpl;
 
 }
@@ -3328,7 +3328,7 @@
   get runtimeType => TouchEvent;
   toString() => super.toString();
 }
-patch class TouchList {
+@patch class TouchList {
   static Type get instanceRuntimeType => TouchListImpl;
 
 }
@@ -3337,7 +3337,7 @@
   get runtimeType => TouchList;
   toString() => super.toString();
 }
-patch class TrackDefault {
+@patch class TrackDefault {
   static Type get instanceRuntimeType => TrackDefaultImpl;
 
 }
@@ -3346,7 +3346,7 @@
   get runtimeType => TrackDefault;
   toString() => super.toString();
 }
-patch class TrackDefaultList {
+@patch class TrackDefaultList {
   static Type get instanceRuntimeType => TrackDefaultListImpl;
 
 }
@@ -3355,7 +3355,7 @@
   get runtimeType => TrackDefaultList;
   toString() => super.toString();
 }
-patch class TrackElement {
+@patch class TrackElement {
   static Type get instanceRuntimeType => TrackElementImpl;
 
 }
@@ -3364,7 +3364,7 @@
   get runtimeType => TrackElement;
   toString() => super.toString();
 }
-patch class TrackEvent {
+@patch class TrackEvent {
   static Type get instanceRuntimeType => TrackEventImpl;
 
 }
@@ -3373,7 +3373,7 @@
   get runtimeType => TrackEvent;
   toString() => super.toString();
 }
-patch class TransitionEvent {
+@patch class TransitionEvent {
   static Type get instanceRuntimeType => TransitionEventImpl;
 
 }
@@ -3382,7 +3382,7 @@
   get runtimeType => TransitionEvent;
   toString() => super.toString();
 }
-patch class TreeWalker {
+@patch class TreeWalker {
   static Type get instanceRuntimeType => TreeWalkerImpl;
 
 }
@@ -3391,7 +3391,7 @@
   get runtimeType => TreeWalker;
   toString() => super.toString();
 }
-patch class UIEvent {
+@patch class UIEvent {
   static Type get instanceRuntimeType => UIEventImpl;
 
 }
@@ -3400,7 +3400,7 @@
   get runtimeType => UIEvent;
   toString() => super.toString();
 }
-patch class UListElement {
+@patch class UListElement {
   static Type get instanceRuntimeType => UListElementImpl;
 
 }
@@ -3409,7 +3409,7 @@
   get runtimeType => UListElement;
   toString() => super.toString();
 }
-patch class UnknownElement {
+@patch class UnknownElement {
   static Type get instanceRuntimeType => UnknownElementImpl;
 
 }
@@ -3418,7 +3418,7 @@
   get runtimeType => UnknownElement;
   toString() => super.toString();
 }
-patch class Url {
+@patch class Url {
   static Type get instanceRuntimeType => UrlImpl;
 
 }
@@ -3427,7 +3427,7 @@
   get runtimeType => Url;
   toString() => super.toString();
 }
-patch class UrlUtils {
+@patch class UrlUtils {
   static Type get instanceRuntimeType => UrlUtilsImpl;
 
 }
@@ -3436,7 +3436,7 @@
   get runtimeType => UrlUtils;
   toString() => super.toString();
 }
-patch class UrlUtilsReadOnly {
+@patch class UrlUtilsReadOnly {
   static Type get instanceRuntimeType => UrlUtilsReadOnlyImpl;
 
 }
@@ -3445,7 +3445,7 @@
   get runtimeType => UrlUtilsReadOnly;
   toString() => super.toString();
 }
-patch class VRDevice {
+@patch class VRDevice {
   static Type get instanceRuntimeType => VRDeviceImpl;
 
 }
@@ -3454,7 +3454,7 @@
   get runtimeType => VRDevice;
   toString() => super.toString();
 }
-patch class VREyeParameters {
+@patch class VREyeParameters {
   static Type get instanceRuntimeType => VREyeParametersImpl;
 
 }
@@ -3463,7 +3463,7 @@
   get runtimeType => VREyeParameters;
   toString() => super.toString();
 }
-patch class VRFieldOfView {
+@patch class VRFieldOfView {
   static Type get instanceRuntimeType => VRFieldOfViewImpl;
 
 }
@@ -3472,7 +3472,7 @@
   get runtimeType => VRFieldOfView;
   toString() => super.toString();
 }
-patch class VRPositionState {
+@patch class VRPositionState {
   static Type get instanceRuntimeType => VRPositionStateImpl;
 
 }
@@ -3481,7 +3481,7 @@
   get runtimeType => VRPositionState;
   toString() => super.toString();
 }
-patch class ValidityState {
+@patch class ValidityState {
   static Type get instanceRuntimeType => ValidityStateImpl;
 
 }
@@ -3490,7 +3490,7 @@
   get runtimeType => ValidityState;
   toString() => super.toString();
 }
-patch class VideoElement {
+@patch class VideoElement {
   static Type get instanceRuntimeType => VideoElementImpl;
 
 }
@@ -3499,7 +3499,7 @@
   get runtimeType => VideoElement;
   toString() => super.toString();
 }
-patch class VideoPlaybackQuality {
+@patch class VideoPlaybackQuality {
   static Type get instanceRuntimeType => VideoPlaybackQualityImpl;
 
 }
@@ -3508,7 +3508,7 @@
   get runtimeType => VideoPlaybackQuality;
   toString() => super.toString();
 }
-patch class VideoTrack {
+@patch class VideoTrack {
   static Type get instanceRuntimeType => VideoTrackImpl;
 
 }
@@ -3517,7 +3517,7 @@
   get runtimeType => VideoTrack;
   toString() => super.toString();
 }
-patch class VideoTrackList {
+@patch class VideoTrackList {
   static Type get instanceRuntimeType => VideoTrackListImpl;
 
 }
@@ -3526,7 +3526,7 @@
   get runtimeType => VideoTrackList;
   toString() => super.toString();
 }
-patch class VttCue {
+@patch class VttCue {
   static Type get instanceRuntimeType => VttCueImpl;
 
 }
@@ -3535,7 +3535,7 @@
   get runtimeType => VttCue;
   toString() => super.toString();
 }
-patch class VttRegion {
+@patch class VttRegion {
   static Type get instanceRuntimeType => VttRegionImpl;
 
 }
@@ -3544,7 +3544,7 @@
   get runtimeType => VttRegion;
   toString() => super.toString();
 }
-patch class VttRegionList {
+@patch class VttRegionList {
   static Type get instanceRuntimeType => VttRegionListImpl;
 
 }
@@ -3553,7 +3553,7 @@
   get runtimeType => VttRegionList;
   toString() => super.toString();
 }
-patch class WebSocket {
+@patch class WebSocket {
   static Type get instanceRuntimeType => WebSocketImpl;
 
 }
@@ -3562,7 +3562,7 @@
   get runtimeType => WebSocket;
   toString() => super.toString();
 }
-patch class WheelEvent {
+@patch class WheelEvent {
   static Type get instanceRuntimeType => WheelEventImpl;
 
 }
@@ -3571,7 +3571,7 @@
   get runtimeType => WheelEvent;
   toString() => super.toString();
 }
-patch class Window {
+@patch class Window {
   static Type get instanceRuntimeType => WindowImpl;
 
 }
@@ -3580,7 +3580,7 @@
   get runtimeType => Window;
   toString() => super.toString();
 }
-patch class WindowBase64 {
+@patch class WindowBase64 {
   static Type get instanceRuntimeType => WindowBase64Impl;
 
 }
@@ -3589,7 +3589,7 @@
   get runtimeType => WindowBase64;
   toString() => super.toString();
 }
-patch class WindowClient {
+@patch class WindowClient {
   static Type get instanceRuntimeType => WindowClientImpl;
 
 }
@@ -3598,7 +3598,7 @@
   get runtimeType => WindowClient;
   toString() => super.toString();
 }
-patch class WindowEventHandlers {
+@patch class WindowEventHandlers {
   static Type get instanceRuntimeType => WindowEventHandlersImpl;
 
 }
@@ -3607,7 +3607,7 @@
   get runtimeType => WindowEventHandlers;
   toString() => super.toString();
 }
-patch class Worker {
+@patch class Worker {
   static Type get instanceRuntimeType => WorkerImpl;
 
 }
@@ -3616,7 +3616,7 @@
   get runtimeType => Worker;
   toString() => super.toString();
 }
-patch class WorkerConsole {
+@patch class WorkerConsole {
   static Type get instanceRuntimeType => WorkerConsoleImpl;
 
 }
@@ -3625,7 +3625,7 @@
   get runtimeType => WorkerConsole;
   toString() => super.toString();
 }
-patch class WorkerGlobalScope {
+@patch class WorkerGlobalScope {
   static Type get instanceRuntimeType => WorkerGlobalScopeImpl;
 
 }
@@ -3634,7 +3634,7 @@
   get runtimeType => WorkerGlobalScope;
   toString() => super.toString();
 }
-patch class WorkerPerformance {
+@patch class WorkerPerformance {
   static Type get instanceRuntimeType => WorkerPerformanceImpl;
 
 }
@@ -3643,7 +3643,7 @@
   get runtimeType => WorkerPerformance;
   toString() => super.toString();
 }
-patch class XPathEvaluator {
+@patch class XPathEvaluator {
   static Type get instanceRuntimeType => XPathEvaluatorImpl;
 
 }
@@ -3652,7 +3652,7 @@
   get runtimeType => XPathEvaluator;
   toString() => super.toString();
 }
-patch class XPathExpression {
+@patch class XPathExpression {
   static Type get instanceRuntimeType => XPathExpressionImpl;
 
 }
@@ -3661,7 +3661,7 @@
   get runtimeType => XPathExpression;
   toString() => super.toString();
 }
-patch class XPathNSResolver {
+@patch class XPathNSResolver {
   static Type get instanceRuntimeType => XPathNSResolverImpl;
 
 }
@@ -3670,7 +3670,7 @@
   get runtimeType => XPathNSResolver;
   toString() => super.toString();
 }
-patch class XPathResult {
+@patch class XPathResult {
   static Type get instanceRuntimeType => XPathResultImpl;
 
 }
@@ -3679,7 +3679,7 @@
   get runtimeType => XPathResult;
   toString() => super.toString();
 }
-patch class XmlDocument {
+@patch class XmlDocument {
   static Type get instanceRuntimeType => XmlDocumentImpl;
 
 }
@@ -3688,7 +3688,7 @@
   get runtimeType => XmlDocument;
   toString() => super.toString();
 }
-patch class XmlSerializer {
+@patch class XmlSerializer {
   static Type get instanceRuntimeType => XmlSerializerImpl;
 
 }
@@ -3697,7 +3697,7 @@
   get runtimeType => XmlSerializer;
   toString() => super.toString();
 }
-patch class XsltProcessor {
+@patch class XsltProcessor {
   static Type get instanceRuntimeType => XsltProcessorImpl;
 
 }
@@ -3706,7 +3706,7 @@
   get runtimeType => XsltProcessor;
   toString() => super.toString();
 }
-patch class _Attr {
+@patch class _Attr {
   static Type get instanceRuntimeType => _AttrImpl;
 
 }
@@ -3715,7 +3715,7 @@
   get runtimeType => _Attr;
   toString() => super.toString();
 }
-patch class _Cache {
+@patch class _Cache {
   static Type get instanceRuntimeType => _CacheImpl;
 
 }
@@ -3724,7 +3724,7 @@
   get runtimeType => _Cache;
   toString() => super.toString();
 }
-patch class _CanvasPathMethods {
+@patch class _CanvasPathMethods {
   static Type get instanceRuntimeType => _CanvasPathMethodsImpl;
 
 }
@@ -3733,7 +3733,7 @@
   get runtimeType => _CanvasPathMethods;
   toString() => super.toString();
 }
-patch class _ClientRect {
+@patch class _ClientRect {
   static Type get instanceRuntimeType => _ClientRectImpl;
 
 }
@@ -3742,7 +3742,7 @@
   get runtimeType => _ClientRect;
   toString() => super.toString();
 }
-patch class _ClientRectList {
+@patch class _ClientRectList {
   static Type get instanceRuntimeType => _ClientRectListImpl;
 
 }
@@ -3751,7 +3751,7 @@
   get runtimeType => _ClientRectList;
   toString() => super.toString();
 }
-patch class _CssRuleList {
+@patch class _CssRuleList {
   static Type get instanceRuntimeType => _CssRuleListImpl;
 
 }
@@ -3760,7 +3760,7 @@
   get runtimeType => _CssRuleList;
   toString() => super.toString();
 }
-patch class _DOMFileSystemSync {
+@patch class _DOMFileSystemSync {
   static Type get instanceRuntimeType => _DOMFileSystemSyncImpl;
 
 }
@@ -3769,7 +3769,7 @@
   get runtimeType => _DOMFileSystemSync;
   toString() => super.toString();
 }
-patch class _DirectoryEntrySync {
+@patch class _DirectoryEntrySync {
   static Type get instanceRuntimeType => _DirectoryEntrySyncImpl;
 
 }
@@ -3778,7 +3778,7 @@
   get runtimeType => _DirectoryEntrySync;
   toString() => super.toString();
 }
-patch class _DirectoryReaderSync {
+@patch class _DirectoryReaderSync {
   static Type get instanceRuntimeType => _DirectoryReaderSyncImpl;
 
 }
@@ -3787,7 +3787,7 @@
   get runtimeType => _DirectoryReaderSync;
   toString() => super.toString();
 }
-patch class _DocumentType {
+@patch class _DocumentType {
   static Type get instanceRuntimeType => _DocumentTypeImpl;
 
 }
@@ -3796,7 +3796,7 @@
   get runtimeType => _DocumentType;
   toString() => super.toString();
 }
-patch class _DomRect {
+@patch class _DomRect {
   static Type get instanceRuntimeType => _DomRectImpl;
 
 }
@@ -3805,7 +3805,7 @@
   get runtimeType => _DomRect;
   toString() => super.toString();
 }
-patch class _EntrySync {
+@patch class _EntrySync {
   static Type get instanceRuntimeType => _EntrySyncImpl;
 
 }
@@ -3814,7 +3814,7 @@
   get runtimeType => _EntrySync;
   toString() => super.toString();
 }
-patch class _FileEntrySync {
+@patch class _FileEntrySync {
   static Type get instanceRuntimeType => _FileEntrySyncImpl;
 
 }
@@ -3823,7 +3823,7 @@
   get runtimeType => _FileEntrySync;
   toString() => super.toString();
 }
-patch class _FileReaderSync {
+@patch class _FileReaderSync {
   static Type get instanceRuntimeType => _FileReaderSyncImpl;
 
 }
@@ -3832,7 +3832,7 @@
   get runtimeType => _FileReaderSync;
   toString() => super.toString();
 }
-patch class _FileWriterSync {
+@patch class _FileWriterSync {
   static Type get instanceRuntimeType => _FileWriterSyncImpl;
 
 }
@@ -3841,7 +3841,7 @@
   get runtimeType => _FileWriterSync;
   toString() => super.toString();
 }
-patch class _GamepadList {
+@patch class _GamepadList {
   static Type get instanceRuntimeType => _GamepadListImpl;
 
 }
@@ -3850,7 +3850,7 @@
   get runtimeType => _GamepadList;
   toString() => super.toString();
 }
-patch class _HTMLAllCollection {
+@patch class _HTMLAllCollection {
   static Type get instanceRuntimeType => _HTMLAllCollectionImpl;
 
 }
@@ -3859,7 +3859,7 @@
   get runtimeType => _HTMLAllCollection;
   toString() => super.toString();
 }
-patch class _HTMLAppletElement {
+@patch class _HTMLAppletElement {
   static Type get instanceRuntimeType => _HTMLAppletElementImpl;
 
 }
@@ -3868,7 +3868,7 @@
   get runtimeType => _HTMLAppletElement;
   toString() => super.toString();
 }
-patch class _HTMLDirectoryElement {
+@patch class _HTMLDirectoryElement {
   static Type get instanceRuntimeType => _HTMLDirectoryElementImpl;
 
 }
@@ -3877,7 +3877,7 @@
   get runtimeType => _HTMLDirectoryElement;
   toString() => super.toString();
 }
-patch class _HTMLFontElement {
+@patch class _HTMLFontElement {
   static Type get instanceRuntimeType => _HTMLFontElementImpl;
 
 }
@@ -3886,7 +3886,7 @@
   get runtimeType => _HTMLFontElement;
   toString() => super.toString();
 }
-patch class _HTMLFrameElement {
+@patch class _HTMLFrameElement {
   static Type get instanceRuntimeType => _HTMLFrameElementImpl;
 
 }
@@ -3895,7 +3895,7 @@
   get runtimeType => _HTMLFrameElement;
   toString() => super.toString();
 }
-patch class _HTMLFrameSetElement {
+@patch class _HTMLFrameSetElement {
   static Type get instanceRuntimeType => _HTMLFrameSetElementImpl;
 
 }
@@ -3904,7 +3904,7 @@
   get runtimeType => _HTMLFrameSetElement;
   toString() => super.toString();
 }
-patch class _HTMLMarqueeElement {
+@patch class _HTMLMarqueeElement {
   static Type get instanceRuntimeType => _HTMLMarqueeElementImpl;
 
 }
@@ -3913,7 +3913,7 @@
   get runtimeType => _HTMLMarqueeElement;
   toString() => super.toString();
 }
-patch class _NamedNodeMap {
+@patch class _NamedNodeMap {
   static Type get instanceRuntimeType => _NamedNodeMapImpl;
 
 }
@@ -3922,7 +3922,7 @@
   get runtimeType => _NamedNodeMap;
   toString() => super.toString();
 }
-patch class _PagePopupController {
+@patch class _PagePopupController {
   static Type get instanceRuntimeType => _PagePopupControllerImpl;
 
 }
@@ -3931,7 +3931,7 @@
   get runtimeType => _PagePopupController;
   toString() => super.toString();
 }
-patch class _RadioNodeList {
+@patch class _RadioNodeList {
   static Type get instanceRuntimeType => _RadioNodeListImpl;
 
 }
@@ -3940,7 +3940,7 @@
   get runtimeType => _RadioNodeList;
   toString() => super.toString();
 }
-patch class _Request {
+@patch class _Request {
   static Type get instanceRuntimeType => _RequestImpl;
 
 }
@@ -3949,7 +3949,7 @@
   get runtimeType => _Request;
   toString() => super.toString();
 }
-patch class _ResourceProgressEvent {
+@patch class _ResourceProgressEvent {
   static Type get instanceRuntimeType => _ResourceProgressEventImpl;
 
 }
@@ -3958,7 +3958,7 @@
   get runtimeType => _ResourceProgressEvent;
   toString() => super.toString();
 }
-patch class _Response {
+@patch class _Response {
   static Type get instanceRuntimeType => _ResponseImpl;
 
 }
@@ -3967,7 +3967,7 @@
   get runtimeType => _Response;
   toString() => super.toString();
 }
-patch class _ServiceWorker {
+@patch class _ServiceWorker {
   static Type get instanceRuntimeType => _ServiceWorkerImpl;
 
 }
@@ -3976,7 +3976,7 @@
   get runtimeType => _ServiceWorker;
   toString() => super.toString();
 }
-patch class _SpeechRecognitionResultList {
+@patch class _SpeechRecognitionResultList {
   static Type get instanceRuntimeType => _SpeechRecognitionResultListImpl;
 
 }
@@ -3985,7 +3985,7 @@
   get runtimeType => _SpeechRecognitionResultList;
   toString() => super.toString();
 }
-patch class _StyleSheetList {
+@patch class _StyleSheetList {
   static Type get instanceRuntimeType => _StyleSheetListImpl;
 
 }
@@ -3994,7 +3994,7 @@
   get runtimeType => _StyleSheetList;
   toString() => super.toString();
 }
-patch class _SubtleCrypto {
+@patch class _SubtleCrypto {
   static Type get instanceRuntimeType => _SubtleCryptoImpl;
 
 }
@@ -4003,7 +4003,7 @@
   get runtimeType => _SubtleCrypto;
   toString() => super.toString();
 }
-patch class _WebKitCSSMatrix {
+@patch class _WebKitCSSMatrix {
   static Type get instanceRuntimeType => _WebKitCSSMatrixImpl;
 
 }
@@ -4012,7 +4012,7 @@
   get runtimeType => _WebKitCSSMatrix;
   toString() => super.toString();
 }
-patch class _WindowTimers {
+@patch class _WindowTimers {
   static Type get instanceRuntimeType => _WindowTimersImpl;
 
 }
@@ -4021,7 +4021,7 @@
   get runtimeType => _WindowTimers;
   toString() => super.toString();
 }
-patch class _WorkerLocation {
+@patch class _WorkerLocation {
   static Type get instanceRuntimeType => _WorkerLocationImpl;
 
 }
@@ -4030,7 +4030,7 @@
   get runtimeType => _WorkerLocation;
   toString() => super.toString();
 }
-patch class _WorkerNavigator {
+@patch class _WorkerNavigator {
   static Type get instanceRuntimeType => _WorkerNavigatorImpl;
 
 }
@@ -4039,7 +4039,7 @@
   get runtimeType => _WorkerNavigator;
   toString() => super.toString();
 }
-patch class _XMLHttpRequestProgressEvent {
+@patch class _XMLHttpRequestProgressEvent {
   static Type get instanceRuntimeType => _XMLHttpRequestProgressEventImpl;
 
 }
@@ -4058,7 +4058,7 @@
  */
 const _UNDEFINED_JS_CONST = const Object();
 
-patch class Cursor {
+@patch class Cursor {
   static Type get instanceRuntimeType => CursorImpl;
 
 }
@@ -4067,7 +4067,7 @@
   get runtimeType => Cursor;
   toString() => super.toString();
 }
-patch class CursorWithValue {
+@patch class CursorWithValue {
   static Type get instanceRuntimeType => CursorWithValueImpl;
 
 }
@@ -4076,7 +4076,7 @@
   get runtimeType => CursorWithValue;
   toString() => super.toString();
 }
-patch class Database {
+@patch class Database {
   static Type get instanceRuntimeType => DatabaseImpl;
 
 }
@@ -4085,7 +4085,7 @@
   get runtimeType => Database;
   toString() => super.toString();
 }
-patch class IdbFactory {
+@patch class IdbFactory {
   static Type get instanceRuntimeType => IdbFactoryImpl;
 
 }
@@ -4094,7 +4094,7 @@
   get runtimeType => IdbFactory;
   toString() => super.toString();
 }
-patch class Index {
+@patch class Index {
   static Type get instanceRuntimeType => IndexImpl;
 
 }
@@ -4103,7 +4103,7 @@
   get runtimeType => Index;
   toString() => super.toString();
 }
-patch class KeyRange {
+@patch class KeyRange {
   static Type get instanceRuntimeType => KeyRangeImpl;
 
 }
@@ -4112,7 +4112,7 @@
   get runtimeType => KeyRange;
   toString() => super.toString();
 }
-patch class ObjectStore {
+@patch class ObjectStore {
   static Type get instanceRuntimeType => ObjectStoreImpl;
 
 }
@@ -4121,7 +4121,7 @@
   get runtimeType => ObjectStore;
   toString() => super.toString();
 }
-patch class OpenDBRequest {
+@patch class OpenDBRequest {
   static Type get instanceRuntimeType => OpenDBRequestImpl;
 
 }
@@ -4130,7 +4130,7 @@
   get runtimeType => OpenDBRequest;
   toString() => super.toString();
 }
-patch class Request {
+@patch class Request {
   static Type get instanceRuntimeType => RequestImpl;
 
 }
@@ -4139,7 +4139,7 @@
   get runtimeType => Request;
   toString() => super.toString();
 }
-patch class Transaction {
+@patch class Transaction {
   static Type get instanceRuntimeType => TransactionImpl;
 
 }
@@ -4148,7 +4148,7 @@
   get runtimeType => Transaction;
   toString() => super.toString();
 }
-patch class VersionChangeEvent {
+@patch class VersionChangeEvent {
   static Type get instanceRuntimeType => VersionChangeEventImpl;
 
 }
@@ -4167,7 +4167,7 @@
  */
 const _UNDEFINED_JS_CONST = const Object();
 
-patch class ActiveInfo {
+@patch class ActiveInfo {
   static Type get instanceRuntimeType => ActiveInfoImpl;
 
 }
@@ -4176,7 +4176,7 @@
   get runtimeType => ActiveInfo;
   toString() => super.toString();
 }
-patch class AngleInstancedArrays {
+@patch class AngleInstancedArrays {
   static Type get instanceRuntimeType => AngleInstancedArraysImpl;
 
 }
@@ -4185,7 +4185,7 @@
   get runtimeType => AngleInstancedArrays;
   toString() => super.toString();
 }
-patch class Buffer {
+@patch class Buffer {
   static Type get instanceRuntimeType => BufferImpl;
 
 }
@@ -4194,7 +4194,7 @@
   get runtimeType => Buffer;
   toString() => super.toString();
 }
-patch class ChromiumSubscribeUniform {
+@patch class ChromiumSubscribeUniform {
   static Type get instanceRuntimeType => ChromiumSubscribeUniformImpl;
 
 }
@@ -4203,7 +4203,7 @@
   get runtimeType => ChromiumSubscribeUniform;
   toString() => super.toString();
 }
-patch class CompressedTextureAtc {
+@patch class CompressedTextureAtc {
   static Type get instanceRuntimeType => CompressedTextureAtcImpl;
 
 }
@@ -4212,7 +4212,7 @@
   get runtimeType => CompressedTextureAtc;
   toString() => super.toString();
 }
-patch class CompressedTextureETC1 {
+@patch class CompressedTextureETC1 {
   static Type get instanceRuntimeType => CompressedTextureETC1Impl;
 
 }
@@ -4221,7 +4221,7 @@
   get runtimeType => CompressedTextureETC1;
   toString() => super.toString();
 }
-patch class CompressedTexturePvrtc {
+@patch class CompressedTexturePvrtc {
   static Type get instanceRuntimeType => CompressedTexturePvrtcImpl;
 
 }
@@ -4230,7 +4230,7 @@
   get runtimeType => CompressedTexturePvrtc;
   toString() => super.toString();
 }
-patch class CompressedTextureS3TC {
+@patch class CompressedTextureS3TC {
   static Type get instanceRuntimeType => CompressedTextureS3TCImpl;
 
 }
@@ -4239,7 +4239,7 @@
   get runtimeType => CompressedTextureS3TC;
   toString() => super.toString();
 }
-patch class ContextEvent {
+@patch class ContextEvent {
   static Type get instanceRuntimeType => ContextEventImpl;
 
 }
@@ -4248,7 +4248,7 @@
   get runtimeType => ContextEvent;
   toString() => super.toString();
 }
-patch class DebugRendererInfo {
+@patch class DebugRendererInfo {
   static Type get instanceRuntimeType => DebugRendererInfoImpl;
 
 }
@@ -4257,7 +4257,7 @@
   get runtimeType => DebugRendererInfo;
   toString() => super.toString();
 }
-patch class DebugShaders {
+@patch class DebugShaders {
   static Type get instanceRuntimeType => DebugShadersImpl;
 
 }
@@ -4266,7 +4266,7 @@
   get runtimeType => DebugShaders;
   toString() => super.toString();
 }
-patch class DepthTexture {
+@patch class DepthTexture {
   static Type get instanceRuntimeType => DepthTextureImpl;
 
 }
@@ -4275,7 +4275,7 @@
   get runtimeType => DepthTexture;
   toString() => super.toString();
 }
-patch class DrawBuffers {
+@patch class DrawBuffers {
   static Type get instanceRuntimeType => DrawBuffersImpl;
 
 }
@@ -4284,7 +4284,7 @@
   get runtimeType => DrawBuffers;
   toString() => super.toString();
 }
-patch class EXTsRgb {
+@patch class EXTsRgb {
   static Type get instanceRuntimeType => EXTsRgbImpl;
 
 }
@@ -4293,7 +4293,7 @@
   get runtimeType => EXTsRgb;
   toString() => super.toString();
 }
-patch class ExtBlendMinMax {
+@patch class ExtBlendMinMax {
   static Type get instanceRuntimeType => ExtBlendMinMaxImpl;
 
 }
@@ -4302,7 +4302,7 @@
   get runtimeType => ExtBlendMinMax;
   toString() => super.toString();
 }
-patch class ExtFragDepth {
+@patch class ExtFragDepth {
   static Type get instanceRuntimeType => ExtFragDepthImpl;
 
 }
@@ -4311,7 +4311,7 @@
   get runtimeType => ExtFragDepth;
   toString() => super.toString();
 }
-patch class ExtShaderTextureLod {
+@patch class ExtShaderTextureLod {
   static Type get instanceRuntimeType => ExtShaderTextureLodImpl;
 
 }
@@ -4320,7 +4320,7 @@
   get runtimeType => ExtShaderTextureLod;
   toString() => super.toString();
 }
-patch class ExtTextureFilterAnisotropic {
+@patch class ExtTextureFilterAnisotropic {
   static Type get instanceRuntimeType => ExtTextureFilterAnisotropicImpl;
 
 }
@@ -4329,7 +4329,7 @@
   get runtimeType => ExtTextureFilterAnisotropic;
   toString() => super.toString();
 }
-patch class Framebuffer {
+@patch class Framebuffer {
   static Type get instanceRuntimeType => FramebufferImpl;
 
 }
@@ -4338,7 +4338,7 @@
   get runtimeType => Framebuffer;
   toString() => super.toString();
 }
-patch class LoseContext {
+@patch class LoseContext {
   static Type get instanceRuntimeType => LoseContextImpl;
 
 }
@@ -4347,7 +4347,7 @@
   get runtimeType => LoseContext;
   toString() => super.toString();
 }
-patch class OesElementIndexUint {
+@patch class OesElementIndexUint {
   static Type get instanceRuntimeType => OesElementIndexUintImpl;
 
 }
@@ -4356,7 +4356,7 @@
   get runtimeType => OesElementIndexUint;
   toString() => super.toString();
 }
-patch class OesStandardDerivatives {
+@patch class OesStandardDerivatives {
   static Type get instanceRuntimeType => OesStandardDerivativesImpl;
 
 }
@@ -4365,7 +4365,7 @@
   get runtimeType => OesStandardDerivatives;
   toString() => super.toString();
 }
-patch class OesTextureFloat {
+@patch class OesTextureFloat {
   static Type get instanceRuntimeType => OesTextureFloatImpl;
 
 }
@@ -4374,7 +4374,7 @@
   get runtimeType => OesTextureFloat;
   toString() => super.toString();
 }
-patch class OesTextureFloatLinear {
+@patch class OesTextureFloatLinear {
   static Type get instanceRuntimeType => OesTextureFloatLinearImpl;
 
 }
@@ -4383,7 +4383,7 @@
   get runtimeType => OesTextureFloatLinear;
   toString() => super.toString();
 }
-patch class OesTextureHalfFloat {
+@patch class OesTextureHalfFloat {
   static Type get instanceRuntimeType => OesTextureHalfFloatImpl;
 
 }
@@ -4392,7 +4392,7 @@
   get runtimeType => OesTextureHalfFloat;
   toString() => super.toString();
 }
-patch class OesTextureHalfFloatLinear {
+@patch class OesTextureHalfFloatLinear {
   static Type get instanceRuntimeType => OesTextureHalfFloatLinearImpl;
 
 }
@@ -4401,7 +4401,7 @@
   get runtimeType => OesTextureHalfFloatLinear;
   toString() => super.toString();
 }
-patch class OesVertexArrayObject {
+@patch class OesVertexArrayObject {
   static Type get instanceRuntimeType => OesVertexArrayObjectImpl;
 
 }
@@ -4410,7 +4410,7 @@
   get runtimeType => OesVertexArrayObject;
   toString() => super.toString();
 }
-patch class Program {
+@patch class Program {
   static Type get instanceRuntimeType => ProgramImpl;
 
 }
@@ -4419,7 +4419,7 @@
   get runtimeType => Program;
   toString() => super.toString();
 }
-patch class Query {
+@patch class Query {
   static Type get instanceRuntimeType => QueryImpl;
 
 }
@@ -4428,7 +4428,7 @@
   get runtimeType => Query;
   toString() => super.toString();
 }
-patch class Renderbuffer {
+@patch class Renderbuffer {
   static Type get instanceRuntimeType => RenderbufferImpl;
 
 }
@@ -4437,7 +4437,7 @@
   get runtimeType => Renderbuffer;
   toString() => super.toString();
 }
-patch class RenderingContext {
+@patch class RenderingContext {
   static Type get instanceRuntimeType => RenderingContextImpl;
 
 }
@@ -4446,7 +4446,7 @@
   get runtimeType => RenderingContext;
   toString() => super.toString();
 }
-patch class RenderingContext2 {
+@patch class RenderingContext2 {
   static Type get instanceRuntimeType => RenderingContext2Impl;
 
 }
@@ -4455,7 +4455,7 @@
   get runtimeType => RenderingContext2;
   toString() => super.toString();
 }
-patch class Sampler {
+@patch class Sampler {
   static Type get instanceRuntimeType => SamplerImpl;
 
 }
@@ -4464,7 +4464,7 @@
   get runtimeType => Sampler;
   toString() => super.toString();
 }
-patch class Shader {
+@patch class Shader {
   static Type get instanceRuntimeType => ShaderImpl;
 
 }
@@ -4473,7 +4473,7 @@
   get runtimeType => Shader;
   toString() => super.toString();
 }
-patch class ShaderPrecisionFormat {
+@patch class ShaderPrecisionFormat {
   static Type get instanceRuntimeType => ShaderPrecisionFormatImpl;
 
 }
@@ -4482,7 +4482,7 @@
   get runtimeType => ShaderPrecisionFormat;
   toString() => super.toString();
 }
-patch class Sync {
+@patch class Sync {
   static Type get instanceRuntimeType => SyncImpl;
 
 }
@@ -4491,7 +4491,7 @@
   get runtimeType => Sync;
   toString() => super.toString();
 }
-patch class Texture {
+@patch class Texture {
   static Type get instanceRuntimeType => TextureImpl;
 
 }
@@ -4500,7 +4500,7 @@
   get runtimeType => Texture;
   toString() => super.toString();
 }
-patch class TransformFeedback {
+@patch class TransformFeedback {
   static Type get instanceRuntimeType => TransformFeedbackImpl;
 
 }
@@ -4509,7 +4509,7 @@
   get runtimeType => TransformFeedback;
   toString() => super.toString();
 }
-patch class UniformLocation {
+@patch class UniformLocation {
   static Type get instanceRuntimeType => UniformLocationImpl;
 
 }
@@ -4518,7 +4518,7 @@
   get runtimeType => UniformLocation;
   toString() => super.toString();
 }
-patch class VertexArrayObject {
+@patch class VertexArrayObject {
   static Type get instanceRuntimeType => VertexArrayObjectImpl;
 
 }
@@ -4527,7 +4527,7 @@
   get runtimeType => VertexArrayObject;
   toString() => super.toString();
 }
-patch class VertexArrayObjectOes {
+@patch class VertexArrayObjectOes {
   static Type get instanceRuntimeType => VertexArrayObjectOesImpl;
 
 }
@@ -4536,7 +4536,7 @@
   get runtimeType => VertexArrayObjectOes;
   toString() => super.toString();
 }
-patch class _WebGL2RenderingContextBase {
+@patch class _WebGL2RenderingContextBase {
   static Type get instanceRuntimeType => _WebGL2RenderingContextBaseImpl;
 
 }
@@ -4545,7 +4545,7 @@
   get runtimeType => _WebGL2RenderingContextBase;
   toString() => super.toString();
 }
-patch class _WebGLRenderingContextBase {
+@patch class _WebGLRenderingContextBase {
   static Type get instanceRuntimeType => _WebGLRenderingContextBaseImpl;
 
 }
@@ -4564,7 +4564,7 @@
  */
 const _UNDEFINED_JS_CONST = const Object();
 
-patch class SqlDatabase {
+@patch class SqlDatabase {
   static Type get instanceRuntimeType => SqlDatabaseImpl;
 
 }
@@ -4573,7 +4573,7 @@
   get runtimeType => SqlDatabase;
   toString() => super.toString();
 }
-patch class SqlError {
+@patch class SqlError {
   static Type get instanceRuntimeType => SqlErrorImpl;
 
 }
@@ -4582,7 +4582,7 @@
   get runtimeType => SqlError;
   toString() => super.toString();
 }
-patch class SqlResultSet {
+@patch class SqlResultSet {
   static Type get instanceRuntimeType => SqlResultSetImpl;
 
 }
@@ -4591,7 +4591,7 @@
   get runtimeType => SqlResultSet;
   toString() => super.toString();
 }
-patch class SqlResultSetRowList {
+@patch class SqlResultSetRowList {
   static Type get instanceRuntimeType => SqlResultSetRowListImpl;
 
 }
@@ -4600,7 +4600,7 @@
   get runtimeType => SqlResultSetRowList;
   toString() => super.toString();
 }
-patch class SqlTransaction {
+@patch class SqlTransaction {
   static Type get instanceRuntimeType => SqlTransactionImpl;
 
 }
@@ -4619,7 +4619,7 @@
  */
 const _UNDEFINED_JS_CONST = const Object();
 
-patch class AElement {
+@patch class AElement {
   static Type get instanceRuntimeType => AElementImpl;
 
 }
@@ -4628,7 +4628,7 @@
   get runtimeType => AElement;
   toString() => super.toString();
 }
-patch class Angle {
+@patch class Angle {
   static Type get instanceRuntimeType => AngleImpl;
 
 }
@@ -4637,7 +4637,7 @@
   get runtimeType => Angle;
   toString() => super.toString();
 }
-patch class AnimateElement {
+@patch class AnimateElement {
   static Type get instanceRuntimeType => AnimateElementImpl;
 
 }
@@ -4646,7 +4646,7 @@
   get runtimeType => AnimateElement;
   toString() => super.toString();
 }
-patch class AnimateMotionElement {
+@patch class AnimateMotionElement {
   static Type get instanceRuntimeType => AnimateMotionElementImpl;
 
 }
@@ -4655,7 +4655,7 @@
   get runtimeType => AnimateMotionElement;
   toString() => super.toString();
 }
-patch class AnimateTransformElement {
+@patch class AnimateTransformElement {
   static Type get instanceRuntimeType => AnimateTransformElementImpl;
 
 }
@@ -4664,7 +4664,7 @@
   get runtimeType => AnimateTransformElement;
   toString() => super.toString();
 }
-patch class AnimatedAngle {
+@patch class AnimatedAngle {
   static Type get instanceRuntimeType => AnimatedAngleImpl;
 
 }
@@ -4673,7 +4673,7 @@
   get runtimeType => AnimatedAngle;
   toString() => super.toString();
 }
-patch class AnimatedBoolean {
+@patch class AnimatedBoolean {
   static Type get instanceRuntimeType => AnimatedBooleanImpl;
 
 }
@@ -4682,7 +4682,7 @@
   get runtimeType => AnimatedBoolean;
   toString() => super.toString();
 }
-patch class AnimatedEnumeration {
+@patch class AnimatedEnumeration {
   static Type get instanceRuntimeType => AnimatedEnumerationImpl;
 
 }
@@ -4691,7 +4691,7 @@
   get runtimeType => AnimatedEnumeration;
   toString() => super.toString();
 }
-patch class AnimatedInteger {
+@patch class AnimatedInteger {
   static Type get instanceRuntimeType => AnimatedIntegerImpl;
 
 }
@@ -4700,7 +4700,7 @@
   get runtimeType => AnimatedInteger;
   toString() => super.toString();
 }
-patch class AnimatedLength {
+@patch class AnimatedLength {
   static Type get instanceRuntimeType => AnimatedLengthImpl;
 
 }
@@ -4709,7 +4709,7 @@
   get runtimeType => AnimatedLength;
   toString() => super.toString();
 }
-patch class AnimatedLengthList {
+@patch class AnimatedLengthList {
   static Type get instanceRuntimeType => AnimatedLengthListImpl;
 
 }
@@ -4718,7 +4718,7 @@
   get runtimeType => AnimatedLengthList;
   toString() => super.toString();
 }
-patch class AnimatedNumber {
+@patch class AnimatedNumber {
   static Type get instanceRuntimeType => AnimatedNumberImpl;
 
 }
@@ -4727,7 +4727,7 @@
   get runtimeType => AnimatedNumber;
   toString() => super.toString();
 }
-patch class AnimatedNumberList {
+@patch class AnimatedNumberList {
   static Type get instanceRuntimeType => AnimatedNumberListImpl;
 
 }
@@ -4736,7 +4736,7 @@
   get runtimeType => AnimatedNumberList;
   toString() => super.toString();
 }
-patch class AnimatedPreserveAspectRatio {
+@patch class AnimatedPreserveAspectRatio {
   static Type get instanceRuntimeType => AnimatedPreserveAspectRatioImpl;
 
 }
@@ -4745,7 +4745,7 @@
   get runtimeType => AnimatedPreserveAspectRatio;
   toString() => super.toString();
 }
-patch class AnimatedRect {
+@patch class AnimatedRect {
   static Type get instanceRuntimeType => AnimatedRectImpl;
 
 }
@@ -4754,7 +4754,7 @@
   get runtimeType => AnimatedRect;
   toString() => super.toString();
 }
-patch class AnimatedString {
+@patch class AnimatedString {
   static Type get instanceRuntimeType => AnimatedStringImpl;
 
 }
@@ -4763,7 +4763,7 @@
   get runtimeType => AnimatedString;
   toString() => super.toString();
 }
-patch class AnimatedTransformList {
+@patch class AnimatedTransformList {
   static Type get instanceRuntimeType => AnimatedTransformListImpl;
 
 }
@@ -4772,7 +4772,7 @@
   get runtimeType => AnimatedTransformList;
   toString() => super.toString();
 }
-patch class AnimationElement {
+@patch class AnimationElement {
   static Type get instanceRuntimeType => AnimationElementImpl;
 
 }
@@ -4781,7 +4781,7 @@
   get runtimeType => AnimationElement;
   toString() => super.toString();
 }
-patch class CircleElement {
+@patch class CircleElement {
   static Type get instanceRuntimeType => CircleElementImpl;
 
 }
@@ -4790,7 +4790,7 @@
   get runtimeType => CircleElement;
   toString() => super.toString();
 }
-patch class ClipPathElement {
+@patch class ClipPathElement {
   static Type get instanceRuntimeType => ClipPathElementImpl;
 
 }
@@ -4799,7 +4799,7 @@
   get runtimeType => ClipPathElement;
   toString() => super.toString();
 }
-patch class DefsElement {
+@patch class DefsElement {
   static Type get instanceRuntimeType => DefsElementImpl;
 
 }
@@ -4808,7 +4808,7 @@
   get runtimeType => DefsElement;
   toString() => super.toString();
 }
-patch class DescElement {
+@patch class DescElement {
   static Type get instanceRuntimeType => DescElementImpl;
 
 }
@@ -4817,7 +4817,7 @@
   get runtimeType => DescElement;
   toString() => super.toString();
 }
-patch class DiscardElement {
+@patch class DiscardElement {
   static Type get instanceRuntimeType => DiscardElementImpl;
 
 }
@@ -4826,7 +4826,7 @@
   get runtimeType => DiscardElement;
   toString() => super.toString();
 }
-patch class EllipseElement {
+@patch class EllipseElement {
   static Type get instanceRuntimeType => EllipseElementImpl;
 
 }
@@ -4835,7 +4835,7 @@
   get runtimeType => EllipseElement;
   toString() => super.toString();
 }
-patch class FEBlendElement {
+@patch class FEBlendElement {
   static Type get instanceRuntimeType => FEBlendElementImpl;
 
 }
@@ -4844,7 +4844,7 @@
   get runtimeType => FEBlendElement;
   toString() => super.toString();
 }
-patch class FEColorMatrixElement {
+@patch class FEColorMatrixElement {
   static Type get instanceRuntimeType => FEColorMatrixElementImpl;
 
 }
@@ -4853,7 +4853,7 @@
   get runtimeType => FEColorMatrixElement;
   toString() => super.toString();
 }
-patch class FEComponentTransferElement {
+@patch class FEComponentTransferElement {
   static Type get instanceRuntimeType => FEComponentTransferElementImpl;
 
 }
@@ -4862,7 +4862,7 @@
   get runtimeType => FEComponentTransferElement;
   toString() => super.toString();
 }
-patch class FECompositeElement {
+@patch class FECompositeElement {
   static Type get instanceRuntimeType => FECompositeElementImpl;
 
 }
@@ -4871,7 +4871,7 @@
   get runtimeType => FECompositeElement;
   toString() => super.toString();
 }
-patch class FEConvolveMatrixElement {
+@patch class FEConvolveMatrixElement {
   static Type get instanceRuntimeType => FEConvolveMatrixElementImpl;
 
 }
@@ -4880,7 +4880,7 @@
   get runtimeType => FEConvolveMatrixElement;
   toString() => super.toString();
 }
-patch class FEDiffuseLightingElement {
+@patch class FEDiffuseLightingElement {
   static Type get instanceRuntimeType => FEDiffuseLightingElementImpl;
 
 }
@@ -4889,7 +4889,7 @@
   get runtimeType => FEDiffuseLightingElement;
   toString() => super.toString();
 }
-patch class FEDisplacementMapElement {
+@patch class FEDisplacementMapElement {
   static Type get instanceRuntimeType => FEDisplacementMapElementImpl;
 
 }
@@ -4898,7 +4898,7 @@
   get runtimeType => FEDisplacementMapElement;
   toString() => super.toString();
 }
-patch class FEDistantLightElement {
+@patch class FEDistantLightElement {
   static Type get instanceRuntimeType => FEDistantLightElementImpl;
 
 }
@@ -4907,7 +4907,7 @@
   get runtimeType => FEDistantLightElement;
   toString() => super.toString();
 }
-patch class FEFloodElement {
+@patch class FEFloodElement {
   static Type get instanceRuntimeType => FEFloodElementImpl;
 
 }
@@ -4916,7 +4916,7 @@
   get runtimeType => FEFloodElement;
   toString() => super.toString();
 }
-patch class FEFuncAElement {
+@patch class FEFuncAElement {
   static Type get instanceRuntimeType => FEFuncAElementImpl;
 
 }
@@ -4925,7 +4925,7 @@
   get runtimeType => FEFuncAElement;
   toString() => super.toString();
 }
-patch class FEFuncBElement {
+@patch class FEFuncBElement {
   static Type get instanceRuntimeType => FEFuncBElementImpl;
 
 }
@@ -4934,7 +4934,7 @@
   get runtimeType => FEFuncBElement;
   toString() => super.toString();
 }
-patch class FEFuncGElement {
+@patch class FEFuncGElement {
   static Type get instanceRuntimeType => FEFuncGElementImpl;
 
 }
@@ -4943,7 +4943,7 @@
   get runtimeType => FEFuncGElement;
   toString() => super.toString();
 }
-patch class FEFuncRElement {
+@patch class FEFuncRElement {
   static Type get instanceRuntimeType => FEFuncRElementImpl;
 
 }
@@ -4952,7 +4952,7 @@
   get runtimeType => FEFuncRElement;
   toString() => super.toString();
 }
-patch class FEGaussianBlurElement {
+@patch class FEGaussianBlurElement {
   static Type get instanceRuntimeType => FEGaussianBlurElementImpl;
 
 }
@@ -4961,7 +4961,7 @@
   get runtimeType => FEGaussianBlurElement;
   toString() => super.toString();
 }
-patch class FEImageElement {
+@patch class FEImageElement {
   static Type get instanceRuntimeType => FEImageElementImpl;
 
 }
@@ -4970,7 +4970,7 @@
   get runtimeType => FEImageElement;
   toString() => super.toString();
 }
-patch class FEMergeElement {
+@patch class FEMergeElement {
   static Type get instanceRuntimeType => FEMergeElementImpl;
 
 }
@@ -4979,7 +4979,7 @@
   get runtimeType => FEMergeElement;
   toString() => super.toString();
 }
-patch class FEMergeNodeElement {
+@patch class FEMergeNodeElement {
   static Type get instanceRuntimeType => FEMergeNodeElementImpl;
 
 }
@@ -4988,7 +4988,7 @@
   get runtimeType => FEMergeNodeElement;
   toString() => super.toString();
 }
-patch class FEMorphologyElement {
+@patch class FEMorphologyElement {
   static Type get instanceRuntimeType => FEMorphologyElementImpl;
 
 }
@@ -4997,7 +4997,7 @@
   get runtimeType => FEMorphologyElement;
   toString() => super.toString();
 }
-patch class FEOffsetElement {
+@patch class FEOffsetElement {
   static Type get instanceRuntimeType => FEOffsetElementImpl;
 
 }
@@ -5006,7 +5006,7 @@
   get runtimeType => FEOffsetElement;
   toString() => super.toString();
 }
-patch class FEPointLightElement {
+@patch class FEPointLightElement {
   static Type get instanceRuntimeType => FEPointLightElementImpl;
 
 }
@@ -5015,7 +5015,7 @@
   get runtimeType => FEPointLightElement;
   toString() => super.toString();
 }
-patch class FESpecularLightingElement {
+@patch class FESpecularLightingElement {
   static Type get instanceRuntimeType => FESpecularLightingElementImpl;
 
 }
@@ -5024,7 +5024,7 @@
   get runtimeType => FESpecularLightingElement;
   toString() => super.toString();
 }
-patch class FESpotLightElement {
+@patch class FESpotLightElement {
   static Type get instanceRuntimeType => FESpotLightElementImpl;
 
 }
@@ -5033,7 +5033,7 @@
   get runtimeType => FESpotLightElement;
   toString() => super.toString();
 }
-patch class FETileElement {
+@patch class FETileElement {
   static Type get instanceRuntimeType => FETileElementImpl;
 
 }
@@ -5042,7 +5042,7 @@
   get runtimeType => FETileElement;
   toString() => super.toString();
 }
-patch class FETurbulenceElement {
+@patch class FETurbulenceElement {
   static Type get instanceRuntimeType => FETurbulenceElementImpl;
 
 }
@@ -5051,7 +5051,7 @@
   get runtimeType => FETurbulenceElement;
   toString() => super.toString();
 }
-patch class FilterElement {
+@patch class FilterElement {
   static Type get instanceRuntimeType => FilterElementImpl;
 
 }
@@ -5060,7 +5060,7 @@
   get runtimeType => FilterElement;
   toString() => super.toString();
 }
-patch class FilterPrimitiveStandardAttributes {
+@patch class FilterPrimitiveStandardAttributes {
   static Type get instanceRuntimeType => FilterPrimitiveStandardAttributesImpl;
 
 }
@@ -5069,7 +5069,7 @@
   get runtimeType => FilterPrimitiveStandardAttributes;
   toString() => super.toString();
 }
-patch class FitToViewBox {
+@patch class FitToViewBox {
   static Type get instanceRuntimeType => FitToViewBoxImpl;
 
 }
@@ -5078,7 +5078,7 @@
   get runtimeType => FitToViewBox;
   toString() => super.toString();
 }
-patch class ForeignObjectElement {
+@patch class ForeignObjectElement {
   static Type get instanceRuntimeType => ForeignObjectElementImpl;
 
 }
@@ -5087,7 +5087,7 @@
   get runtimeType => ForeignObjectElement;
   toString() => super.toString();
 }
-patch class GElement {
+@patch class GElement {
   static Type get instanceRuntimeType => GElementImpl;
 
 }
@@ -5096,7 +5096,7 @@
   get runtimeType => GElement;
   toString() => super.toString();
 }
-patch class GeometryElement {
+@patch class GeometryElement {
   static Type get instanceRuntimeType => GeometryElementImpl;
 
 }
@@ -5105,7 +5105,7 @@
   get runtimeType => GeometryElement;
   toString() => super.toString();
 }
-patch class GraphicsElement {
+@patch class GraphicsElement {
   static Type get instanceRuntimeType => GraphicsElementImpl;
 
 }
@@ -5114,7 +5114,7 @@
   get runtimeType => GraphicsElement;
   toString() => super.toString();
 }
-patch class ImageElement {
+@patch class ImageElement {
   static Type get instanceRuntimeType => ImageElementImpl;
 
 }
@@ -5123,7 +5123,7 @@
   get runtimeType => ImageElement;
   toString() => super.toString();
 }
-patch class Length {
+@patch class Length {
   static Type get instanceRuntimeType => LengthImpl;
 
 }
@@ -5132,7 +5132,7 @@
   get runtimeType => Length;
   toString() => super.toString();
 }
-patch class LengthList {
+@patch class LengthList {
   static Type get instanceRuntimeType => LengthListImpl;
 
 }
@@ -5141,7 +5141,7 @@
   get runtimeType => LengthList;
   toString() => super.toString();
 }
-patch class LineElement {
+@patch class LineElement {
   static Type get instanceRuntimeType => LineElementImpl;
 
 }
@@ -5150,7 +5150,7 @@
   get runtimeType => LineElement;
   toString() => super.toString();
 }
-patch class LinearGradientElement {
+@patch class LinearGradientElement {
   static Type get instanceRuntimeType => LinearGradientElementImpl;
 
 }
@@ -5159,7 +5159,7 @@
   get runtimeType => LinearGradientElement;
   toString() => super.toString();
 }
-patch class MarkerElement {
+@patch class MarkerElement {
   static Type get instanceRuntimeType => MarkerElementImpl;
 
 }
@@ -5168,7 +5168,7 @@
   get runtimeType => MarkerElement;
   toString() => super.toString();
 }
-patch class MaskElement {
+@patch class MaskElement {
   static Type get instanceRuntimeType => MaskElementImpl;
 
 }
@@ -5177,7 +5177,7 @@
   get runtimeType => MaskElement;
   toString() => super.toString();
 }
-patch class Matrix {
+@patch class Matrix {
   static Type get instanceRuntimeType => MatrixImpl;
 
 }
@@ -5186,7 +5186,7 @@
   get runtimeType => Matrix;
   toString() => super.toString();
 }
-patch class MetadataElement {
+@patch class MetadataElement {
   static Type get instanceRuntimeType => MetadataElementImpl;
 
 }
@@ -5195,7 +5195,7 @@
   get runtimeType => MetadataElement;
   toString() => super.toString();
 }
-patch class Number {
+@patch class Number {
   static Type get instanceRuntimeType => NumberImpl;
 
 }
@@ -5204,7 +5204,7 @@
   get runtimeType => Number;
   toString() => super.toString();
 }
-patch class NumberList {
+@patch class NumberList {
   static Type get instanceRuntimeType => NumberListImpl;
 
 }
@@ -5213,7 +5213,7 @@
   get runtimeType => NumberList;
   toString() => super.toString();
 }
-patch class PathElement {
+@patch class PathElement {
   static Type get instanceRuntimeType => PathElementImpl;
 
 }
@@ -5222,7 +5222,7 @@
   get runtimeType => PathElement;
   toString() => super.toString();
 }
-patch class PathSeg {
+@patch class PathSeg {
   static Type get instanceRuntimeType => PathSegImpl;
 
 }
@@ -5231,7 +5231,7 @@
   get runtimeType => PathSeg;
   toString() => super.toString();
 }
-patch class PathSegArcAbs {
+@patch class PathSegArcAbs {
   static Type get instanceRuntimeType => PathSegArcAbsImpl;
 
 }
@@ -5240,7 +5240,7 @@
   get runtimeType => PathSegArcAbs;
   toString() => super.toString();
 }
-patch class PathSegArcRel {
+@patch class PathSegArcRel {
   static Type get instanceRuntimeType => PathSegArcRelImpl;
 
 }
@@ -5249,7 +5249,7 @@
   get runtimeType => PathSegArcRel;
   toString() => super.toString();
 }
-patch class PathSegClosePath {
+@patch class PathSegClosePath {
   static Type get instanceRuntimeType => PathSegClosePathImpl;
 
 }
@@ -5258,7 +5258,7 @@
   get runtimeType => PathSegClosePath;
   toString() => super.toString();
 }
-patch class PathSegCurvetoCubicAbs {
+@patch class PathSegCurvetoCubicAbs {
   static Type get instanceRuntimeType => PathSegCurvetoCubicAbsImpl;
 
 }
@@ -5267,7 +5267,7 @@
   get runtimeType => PathSegCurvetoCubicAbs;
   toString() => super.toString();
 }
-patch class PathSegCurvetoCubicRel {
+@patch class PathSegCurvetoCubicRel {
   static Type get instanceRuntimeType => PathSegCurvetoCubicRelImpl;
 
 }
@@ -5276,7 +5276,7 @@
   get runtimeType => PathSegCurvetoCubicRel;
   toString() => super.toString();
 }
-patch class PathSegCurvetoCubicSmoothAbs {
+@patch class PathSegCurvetoCubicSmoothAbs {
   static Type get instanceRuntimeType => PathSegCurvetoCubicSmoothAbsImpl;
 
 }
@@ -5285,7 +5285,7 @@
   get runtimeType => PathSegCurvetoCubicSmoothAbs;
   toString() => super.toString();
 }
-patch class PathSegCurvetoCubicSmoothRel {
+@patch class PathSegCurvetoCubicSmoothRel {
   static Type get instanceRuntimeType => PathSegCurvetoCubicSmoothRelImpl;
 
 }
@@ -5294,7 +5294,7 @@
   get runtimeType => PathSegCurvetoCubicSmoothRel;
   toString() => super.toString();
 }
-patch class PathSegCurvetoQuadraticAbs {
+@patch class PathSegCurvetoQuadraticAbs {
   static Type get instanceRuntimeType => PathSegCurvetoQuadraticAbsImpl;
 
 }
@@ -5303,7 +5303,7 @@
   get runtimeType => PathSegCurvetoQuadraticAbs;
   toString() => super.toString();
 }
-patch class PathSegCurvetoQuadraticRel {
+@patch class PathSegCurvetoQuadraticRel {
   static Type get instanceRuntimeType => PathSegCurvetoQuadraticRelImpl;
 
 }
@@ -5312,7 +5312,7 @@
   get runtimeType => PathSegCurvetoQuadraticRel;
   toString() => super.toString();
 }
-patch class PathSegCurvetoQuadraticSmoothAbs {
+@patch class PathSegCurvetoQuadraticSmoothAbs {
   static Type get instanceRuntimeType => PathSegCurvetoQuadraticSmoothAbsImpl;
 
 }
@@ -5321,7 +5321,7 @@
   get runtimeType => PathSegCurvetoQuadraticSmoothAbs;
   toString() => super.toString();
 }
-patch class PathSegCurvetoQuadraticSmoothRel {
+@patch class PathSegCurvetoQuadraticSmoothRel {
   static Type get instanceRuntimeType => PathSegCurvetoQuadraticSmoothRelImpl;
 
 }
@@ -5330,7 +5330,7 @@
   get runtimeType => PathSegCurvetoQuadraticSmoothRel;
   toString() => super.toString();
 }
-patch class PathSegLinetoAbs {
+@patch class PathSegLinetoAbs {
   static Type get instanceRuntimeType => PathSegLinetoAbsImpl;
 
 }
@@ -5339,7 +5339,7 @@
   get runtimeType => PathSegLinetoAbs;
   toString() => super.toString();
 }
-patch class PathSegLinetoHorizontalAbs {
+@patch class PathSegLinetoHorizontalAbs {
   static Type get instanceRuntimeType => PathSegLinetoHorizontalAbsImpl;
 
 }
@@ -5348,7 +5348,7 @@
   get runtimeType => PathSegLinetoHorizontalAbs;
   toString() => super.toString();
 }
-patch class PathSegLinetoHorizontalRel {
+@patch class PathSegLinetoHorizontalRel {
   static Type get instanceRuntimeType => PathSegLinetoHorizontalRelImpl;
 
 }
@@ -5357,7 +5357,7 @@
   get runtimeType => PathSegLinetoHorizontalRel;
   toString() => super.toString();
 }
-patch class PathSegLinetoRel {
+@patch class PathSegLinetoRel {
   static Type get instanceRuntimeType => PathSegLinetoRelImpl;
 
 }
@@ -5366,7 +5366,7 @@
   get runtimeType => PathSegLinetoRel;
   toString() => super.toString();
 }
-patch class PathSegLinetoVerticalAbs {
+@patch class PathSegLinetoVerticalAbs {
   static Type get instanceRuntimeType => PathSegLinetoVerticalAbsImpl;
 
 }
@@ -5375,7 +5375,7 @@
   get runtimeType => PathSegLinetoVerticalAbs;
   toString() => super.toString();
 }
-patch class PathSegLinetoVerticalRel {
+@patch class PathSegLinetoVerticalRel {
   static Type get instanceRuntimeType => PathSegLinetoVerticalRelImpl;
 
 }
@@ -5384,7 +5384,7 @@
   get runtimeType => PathSegLinetoVerticalRel;
   toString() => super.toString();
 }
-patch class PathSegList {
+@patch class PathSegList {
   static Type get instanceRuntimeType => PathSegListImpl;
 
 }
@@ -5393,7 +5393,7 @@
   get runtimeType => PathSegList;
   toString() => super.toString();
 }
-patch class PathSegMovetoAbs {
+@patch class PathSegMovetoAbs {
   static Type get instanceRuntimeType => PathSegMovetoAbsImpl;
 
 }
@@ -5402,7 +5402,7 @@
   get runtimeType => PathSegMovetoAbs;
   toString() => super.toString();
 }
-patch class PathSegMovetoRel {
+@patch class PathSegMovetoRel {
   static Type get instanceRuntimeType => PathSegMovetoRelImpl;
 
 }
@@ -5411,7 +5411,7 @@
   get runtimeType => PathSegMovetoRel;
   toString() => super.toString();
 }
-patch class PatternElement {
+@patch class PatternElement {
   static Type get instanceRuntimeType => PatternElementImpl;
 
 }
@@ -5420,7 +5420,7 @@
   get runtimeType => PatternElement;
   toString() => super.toString();
 }
-patch class Point {
+@patch class Point {
   static Type get instanceRuntimeType => PointImpl;
 
 }
@@ -5429,7 +5429,7 @@
   get runtimeType => Point;
   toString() => super.toString();
 }
-patch class PointList {
+@patch class PointList {
   static Type get instanceRuntimeType => PointListImpl;
 
 }
@@ -5438,7 +5438,7 @@
   get runtimeType => PointList;
   toString() => super.toString();
 }
-patch class PolygonElement {
+@patch class PolygonElement {
   static Type get instanceRuntimeType => PolygonElementImpl;
 
 }
@@ -5447,7 +5447,7 @@
   get runtimeType => PolygonElement;
   toString() => super.toString();
 }
-patch class PolylineElement {
+@patch class PolylineElement {
   static Type get instanceRuntimeType => PolylineElementImpl;
 
 }
@@ -5456,7 +5456,7 @@
   get runtimeType => PolylineElement;
   toString() => super.toString();
 }
-patch class PreserveAspectRatio {
+@patch class PreserveAspectRatio {
   static Type get instanceRuntimeType => PreserveAspectRatioImpl;
 
 }
@@ -5465,7 +5465,7 @@
   get runtimeType => PreserveAspectRatio;
   toString() => super.toString();
 }
-patch class RadialGradientElement {
+@patch class RadialGradientElement {
   static Type get instanceRuntimeType => RadialGradientElementImpl;
 
 }
@@ -5474,7 +5474,7 @@
   get runtimeType => RadialGradientElement;
   toString() => super.toString();
 }
-patch class Rect {
+@patch class Rect {
   static Type get instanceRuntimeType => RectImpl;
 
 }
@@ -5483,7 +5483,7 @@
   get runtimeType => Rect;
   toString() => super.toString();
 }
-patch class RectElement {
+@patch class RectElement {
   static Type get instanceRuntimeType => RectElementImpl;
 
 }
@@ -5492,7 +5492,7 @@
   get runtimeType => RectElement;
   toString() => super.toString();
 }
-patch class ScriptElement {
+@patch class ScriptElement {
   static Type get instanceRuntimeType => ScriptElementImpl;
 
 }
@@ -5501,7 +5501,7 @@
   get runtimeType => ScriptElement;
   toString() => super.toString();
 }
-patch class SetElement {
+@patch class SetElement {
   static Type get instanceRuntimeType => SetElementImpl;
 
 }
@@ -5510,7 +5510,7 @@
   get runtimeType => SetElement;
   toString() => super.toString();
 }
-patch class StopElement {
+@patch class StopElement {
   static Type get instanceRuntimeType => StopElementImpl;
 
 }
@@ -5519,7 +5519,7 @@
   get runtimeType => StopElement;
   toString() => super.toString();
 }
-patch class StringList {
+@patch class StringList {
   static Type get instanceRuntimeType => StringListImpl;
 
 }
@@ -5528,7 +5528,7 @@
   get runtimeType => StringList;
   toString() => super.toString();
 }
-patch class StyleElement {
+@patch class StyleElement {
   static Type get instanceRuntimeType => StyleElementImpl;
 
 }
@@ -5537,7 +5537,7 @@
   get runtimeType => StyleElement;
   toString() => super.toString();
 }
-patch class SvgElement {
+@patch class SvgElement {
   static Type get instanceRuntimeType => SvgElementImpl;
 
 }
@@ -5546,7 +5546,7 @@
   get runtimeType => SvgElement;
   toString() => super.toString();
 }
-patch class SvgSvgElement {
+@patch class SvgSvgElement {
   static Type get instanceRuntimeType => SvgSvgElementImpl;
 
 }
@@ -5555,7 +5555,7 @@
   get runtimeType => SvgSvgElement;
   toString() => super.toString();
 }
-patch class SwitchElement {
+@patch class SwitchElement {
   static Type get instanceRuntimeType => SwitchElementImpl;
 
 }
@@ -5564,7 +5564,7 @@
   get runtimeType => SwitchElement;
   toString() => super.toString();
 }
-patch class SymbolElement {
+@patch class SymbolElement {
   static Type get instanceRuntimeType => SymbolElementImpl;
 
 }
@@ -5573,7 +5573,7 @@
   get runtimeType => SymbolElement;
   toString() => super.toString();
 }
-patch class TSpanElement {
+@patch class TSpanElement {
   static Type get instanceRuntimeType => TSpanElementImpl;
 
 }
@@ -5582,7 +5582,7 @@
   get runtimeType => TSpanElement;
   toString() => super.toString();
 }
-patch class Tests {
+@patch class Tests {
   static Type get instanceRuntimeType => TestsImpl;
 
 }
@@ -5591,7 +5591,7 @@
   get runtimeType => Tests;
   toString() => super.toString();
 }
-patch class TextContentElement {
+@patch class TextContentElement {
   static Type get instanceRuntimeType => TextContentElementImpl;
 
 }
@@ -5600,7 +5600,7 @@
   get runtimeType => TextContentElement;
   toString() => super.toString();
 }
-patch class TextElement {
+@patch class TextElement {
   static Type get instanceRuntimeType => TextElementImpl;
 
 }
@@ -5609,7 +5609,7 @@
   get runtimeType => TextElement;
   toString() => super.toString();
 }
-patch class TextPathElement {
+@patch class TextPathElement {
   static Type get instanceRuntimeType => TextPathElementImpl;
 
 }
@@ -5618,7 +5618,7 @@
   get runtimeType => TextPathElement;
   toString() => super.toString();
 }
-patch class TextPositioningElement {
+@patch class TextPositioningElement {
   static Type get instanceRuntimeType => TextPositioningElementImpl;
 
 }
@@ -5627,7 +5627,7 @@
   get runtimeType => TextPositioningElement;
   toString() => super.toString();
 }
-patch class TitleElement {
+@patch class TitleElement {
   static Type get instanceRuntimeType => TitleElementImpl;
 
 }
@@ -5636,7 +5636,7 @@
   get runtimeType => TitleElement;
   toString() => super.toString();
 }
-patch class Transform {
+@patch class Transform {
   static Type get instanceRuntimeType => TransformImpl;
 
 }
@@ -5645,7 +5645,7 @@
   get runtimeType => Transform;
   toString() => super.toString();
 }
-patch class TransformList {
+@patch class TransformList {
   static Type get instanceRuntimeType => TransformListImpl;
 
 }
@@ -5654,7 +5654,7 @@
   get runtimeType => TransformList;
   toString() => super.toString();
 }
-patch class UnitTypes {
+@patch class UnitTypes {
   static Type get instanceRuntimeType => UnitTypesImpl;
 
 }
@@ -5663,7 +5663,7 @@
   get runtimeType => UnitTypes;
   toString() => super.toString();
 }
-patch class UriReference {
+@patch class UriReference {
   static Type get instanceRuntimeType => UriReferenceImpl;
 
 }
@@ -5672,7 +5672,7 @@
   get runtimeType => UriReference;
   toString() => super.toString();
 }
-patch class UseElement {
+@patch class UseElement {
   static Type get instanceRuntimeType => UseElementImpl;
 
 }
@@ -5681,7 +5681,7 @@
   get runtimeType => UseElement;
   toString() => super.toString();
 }
-patch class ViewElement {
+@patch class ViewElement {
   static Type get instanceRuntimeType => ViewElementImpl;
 
 }
@@ -5690,7 +5690,7 @@
   get runtimeType => ViewElement;
   toString() => super.toString();
 }
-patch class ViewSpec {
+@patch class ViewSpec {
   static Type get instanceRuntimeType => ViewSpecImpl;
 
 }
@@ -5699,7 +5699,7 @@
   get runtimeType => ViewSpec;
   toString() => super.toString();
 }
-patch class ZoomAndPan {
+@patch class ZoomAndPan {
   static Type get instanceRuntimeType => ZoomAndPanImpl;
 
 }
@@ -5708,7 +5708,7 @@
   get runtimeType => ZoomAndPan;
   toString() => super.toString();
 }
-patch class ZoomEvent {
+@patch class ZoomEvent {
   static Type get instanceRuntimeType => ZoomEventImpl;
 
 }
@@ -5717,7 +5717,7 @@
   get runtimeType => ZoomEvent;
   toString() => super.toString();
 }
-patch class _GradientElement {
+@patch class _GradientElement {
   static Type get instanceRuntimeType => _GradientElementImpl;
 
 }
@@ -5726,7 +5726,7 @@
   get runtimeType => _GradientElement;
   toString() => super.toString();
 }
-patch class _SVGComponentTransferFunctionElement {
+@patch class _SVGComponentTransferFunctionElement {
   static Type get instanceRuntimeType => _SVGComponentTransferFunctionElementImpl;
 
 }
@@ -5735,7 +5735,7 @@
   get runtimeType => _SVGComponentTransferFunctionElement;
   toString() => super.toString();
 }
-patch class _SVGCursorElement {
+@patch class _SVGCursorElement {
   static Type get instanceRuntimeType => _SVGCursorElementImpl;
 
 }
@@ -5744,7 +5744,7 @@
   get runtimeType => _SVGCursorElement;
   toString() => super.toString();
 }
-patch class _SVGFEDropShadowElement {
+@patch class _SVGFEDropShadowElement {
   static Type get instanceRuntimeType => _SVGFEDropShadowElementImpl;
 
 }
@@ -5753,7 +5753,7 @@
   get runtimeType => _SVGFEDropShadowElement;
   toString() => super.toString();
 }
-patch class _SVGMPathElement {
+@patch class _SVGMPathElement {
   static Type get instanceRuntimeType => _SVGMPathElementImpl;
 
 }
@@ -5772,7 +5772,7 @@
  */
 const _UNDEFINED_JS_CONST = const Object();
 
-patch class AnalyserNode {
+@patch class AnalyserNode {
   static Type get instanceRuntimeType => AnalyserNodeImpl;
 
 }
@@ -5781,7 +5781,7 @@
   get runtimeType => AnalyserNode;
   toString() => super.toString();
 }
-patch class AudioBuffer {
+@patch class AudioBuffer {
   static Type get instanceRuntimeType => AudioBufferImpl;
 
 }
@@ -5790,7 +5790,7 @@
   get runtimeType => AudioBuffer;
   toString() => super.toString();
 }
-patch class AudioBufferSourceNode {
+@patch class AudioBufferSourceNode {
   static Type get instanceRuntimeType => AudioBufferSourceNodeImpl;
 
 }
@@ -5799,7 +5799,7 @@
   get runtimeType => AudioBufferSourceNode;
   toString() => super.toString();
 }
-patch class AudioContext {
+@patch class AudioContext {
   static Type get instanceRuntimeType => AudioContextImpl;
 
 }
@@ -5808,7 +5808,7 @@
   get runtimeType => AudioContext;
   toString() => super.toString();
 }
-patch class AudioDestinationNode {
+@patch class AudioDestinationNode {
   static Type get instanceRuntimeType => AudioDestinationNodeImpl;
 
 }
@@ -5817,7 +5817,7 @@
   get runtimeType => AudioDestinationNode;
   toString() => super.toString();
 }
-patch class AudioListener {
+@patch class AudioListener {
   static Type get instanceRuntimeType => AudioListenerImpl;
 
 }
@@ -5826,7 +5826,7 @@
   get runtimeType => AudioListener;
   toString() => super.toString();
 }
-patch class AudioNode {
+@patch class AudioNode {
   static Type get instanceRuntimeType => AudioNodeImpl;
 
 }
@@ -5835,7 +5835,7 @@
   get runtimeType => AudioNode;
   toString() => super.toString();
 }
-patch class AudioParam {
+@patch class AudioParam {
   static Type get instanceRuntimeType => AudioParamImpl;
 
 }
@@ -5844,7 +5844,7 @@
   get runtimeType => AudioParam;
   toString() => super.toString();
 }
-patch class AudioProcessingEvent {
+@patch class AudioProcessingEvent {
   static Type get instanceRuntimeType => AudioProcessingEventImpl;
 
 }
@@ -5853,7 +5853,7 @@
   get runtimeType => AudioProcessingEvent;
   toString() => super.toString();
 }
-patch class AudioSourceNode {
+@patch class AudioSourceNode {
   static Type get instanceRuntimeType => AudioSourceNodeImpl;
 
 }
@@ -5862,7 +5862,7 @@
   get runtimeType => AudioSourceNode;
   toString() => super.toString();
 }
-patch class BiquadFilterNode {
+@patch class BiquadFilterNode {
   static Type get instanceRuntimeType => BiquadFilterNodeImpl;
 
 }
@@ -5871,7 +5871,7 @@
   get runtimeType => BiquadFilterNode;
   toString() => super.toString();
 }
-patch class ChannelMergerNode {
+@patch class ChannelMergerNode {
   static Type get instanceRuntimeType => ChannelMergerNodeImpl;
 
 }
@@ -5880,7 +5880,7 @@
   get runtimeType => ChannelMergerNode;
   toString() => super.toString();
 }
-patch class ChannelSplitterNode {
+@patch class ChannelSplitterNode {
   static Type get instanceRuntimeType => ChannelSplitterNodeImpl;
 
 }
@@ -5889,7 +5889,7 @@
   get runtimeType => ChannelSplitterNode;
   toString() => super.toString();
 }
-patch class ConvolverNode {
+@patch class ConvolverNode {
   static Type get instanceRuntimeType => ConvolverNodeImpl;
 
 }
@@ -5898,7 +5898,7 @@
   get runtimeType => ConvolverNode;
   toString() => super.toString();
 }
-patch class DelayNode {
+@patch class DelayNode {
   static Type get instanceRuntimeType => DelayNodeImpl;
 
 }
@@ -5907,7 +5907,7 @@
   get runtimeType => DelayNode;
   toString() => super.toString();
 }
-patch class DynamicsCompressorNode {
+@patch class DynamicsCompressorNode {
   static Type get instanceRuntimeType => DynamicsCompressorNodeImpl;
 
 }
@@ -5916,7 +5916,7 @@
   get runtimeType => DynamicsCompressorNode;
   toString() => super.toString();
 }
-patch class GainNode {
+@patch class GainNode {
   static Type get instanceRuntimeType => GainNodeImpl;
 
 }
@@ -5925,7 +5925,7 @@
   get runtimeType => GainNode;
   toString() => super.toString();
 }
-patch class MediaElementAudioSourceNode {
+@patch class MediaElementAudioSourceNode {
   static Type get instanceRuntimeType => MediaElementAudioSourceNodeImpl;
 
 }
@@ -5934,7 +5934,7 @@
   get runtimeType => MediaElementAudioSourceNode;
   toString() => super.toString();
 }
-patch class MediaStreamAudioDestinationNode {
+@patch class MediaStreamAudioDestinationNode {
   static Type get instanceRuntimeType => MediaStreamAudioDestinationNodeImpl;
 
 }
@@ -5943,7 +5943,7 @@
   get runtimeType => MediaStreamAudioDestinationNode;
   toString() => super.toString();
 }
-patch class MediaStreamAudioSourceNode {
+@patch class MediaStreamAudioSourceNode {
   static Type get instanceRuntimeType => MediaStreamAudioSourceNodeImpl;
 
 }
@@ -5952,7 +5952,7 @@
   get runtimeType => MediaStreamAudioSourceNode;
   toString() => super.toString();
 }
-patch class OfflineAudioCompletionEvent {
+@patch class OfflineAudioCompletionEvent {
   static Type get instanceRuntimeType => OfflineAudioCompletionEventImpl;
 
 }
@@ -5961,7 +5961,7 @@
   get runtimeType => OfflineAudioCompletionEvent;
   toString() => super.toString();
 }
-patch class OfflineAudioContext {
+@patch class OfflineAudioContext {
   static Type get instanceRuntimeType => OfflineAudioContextImpl;
 
 }
@@ -5970,7 +5970,7 @@
   get runtimeType => OfflineAudioContext;
   toString() => super.toString();
 }
-patch class OscillatorNode {
+@patch class OscillatorNode {
   static Type get instanceRuntimeType => OscillatorNodeImpl;
 
 }
@@ -5979,7 +5979,7 @@
   get runtimeType => OscillatorNode;
   toString() => super.toString();
 }
-patch class PannerNode {
+@patch class PannerNode {
   static Type get instanceRuntimeType => PannerNodeImpl;
 
 }
@@ -5988,7 +5988,7 @@
   get runtimeType => PannerNode;
   toString() => super.toString();
 }
-patch class PeriodicWave {
+@patch class PeriodicWave {
   static Type get instanceRuntimeType => PeriodicWaveImpl;
 
 }
@@ -5997,7 +5997,7 @@
   get runtimeType => PeriodicWave;
   toString() => super.toString();
 }
-patch class ScriptProcessorNode {
+@patch class ScriptProcessorNode {
   static Type get instanceRuntimeType => ScriptProcessorNodeImpl;
 
 }
@@ -6006,7 +6006,7 @@
   get runtimeType => ScriptProcessorNode;
   toString() => super.toString();
 }
-patch class StereoPannerNode {
+@patch class StereoPannerNode {
   static Type get instanceRuntimeType => StereoPannerNodeImpl;
 
 }
@@ -6015,7 +6015,7 @@
   get runtimeType => StereoPannerNode;
   toString() => super.toString();
 }
-patch class WaveShaperNode {
+@patch class WaveShaperNode {
   static Type get instanceRuntimeType => WaveShaperNodeImpl;
 
 }
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index 4d1d682..fbda496 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -106,6 +106,11 @@
 final bool CHECK_JS_INVOCATIONS = true;
 
 final String _DART_RESERVED_NAME_PREFIX = r'JS$';
+// If a private class is defined to use @JS we need to inject a non-private
+// class with a name that will not cause collisions in the library so we can
+// make JSObject implement that interface even though it is in a different
+// library.
+final String escapePrivateClassPrefix = r'$JSImplClass23402893498';
 
 String _stripReservedNamePrefix(String name) =>
     name.startsWith(_DART_RESERVED_NAME_PREFIX)
@@ -133,6 +138,114 @@
 @Deprecated("Internal Use Only")
 Iterable<mirrors.ClassMirror> get jsInterfaceTypes => _jsInterfaceTypes;
 
+class _StringLiteralEscape {
+  // Character code constants.
+  static const int BACKSPACE = 0x08;
+  static const int TAB = 0x09;
+  static const int NEWLINE = 0x0a;
+  static const int CARRIAGE_RETURN = 0x0d;
+  static const int FORM_FEED = 0x0c;
+  static const int QUOTE = 0x22;
+  static const int CHAR_$ = 0x24;
+  static const int CHAR_0 = 0x30;
+  static const int BACKSLASH = 0x5c;
+  static const int CHAR_b = 0x62;
+  static const int CHAR_f = 0x66;
+  static const int CHAR_n = 0x6e;
+  static const int CHAR_r = 0x72;
+  static const int CHAR_t = 0x74;
+  static const int CHAR_u = 0x75;
+
+  final StringSink _sink;
+
+  _StringLiteralEscape(this._sink);
+
+  void writeString(String string) {
+    _sink.write(string);
+  }
+
+  void writeStringSlice(String string, int start, int end) {
+    _sink.write(string.substring(start, end));
+  }
+
+  void writeCharCode(int charCode) {
+    _sink.writeCharCode(charCode);
+  }
+
+  /// ('0' + x) or ('a' + x - 10)
+  static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
+
+  /// Write, and suitably escape, a string's content as a JSON string literal.
+  void writeStringContent(String s) {
+    // Identical to JSON string literal escaping except that we also escape $.
+    int offset = 0;
+    final int length = s.length;
+    for (int i = 0; i < length; i++) {
+      int charCode = s.codeUnitAt(i);
+      if (charCode > BACKSLASH) continue;
+      if (charCode < 32) {
+        if (i > offset) writeStringSlice(s, offset, i);
+        offset = i + 1;
+        writeCharCode(BACKSLASH);
+        switch (charCode) {
+          case BACKSPACE:
+            writeCharCode(CHAR_b);
+            break;
+          case TAB:
+            writeCharCode(CHAR_t);
+            break;
+          case NEWLINE:
+            writeCharCode(CHAR_n);
+            break;
+          case FORM_FEED:
+            writeCharCode(CHAR_f);
+            break;
+          case CARRIAGE_RETURN:
+            writeCharCode(CHAR_r);
+            break;
+          default:
+            writeCharCode(CHAR_u);
+            writeCharCode(CHAR_0);
+            writeCharCode(CHAR_0);
+            writeCharCode(hexDigit((charCode >> 4) & 0xf));
+            writeCharCode(hexDigit(charCode & 0xf));
+            break;
+        }
+      } else if (charCode == QUOTE ||
+          charCode == BACKSLASH ||
+          charCode == CHAR_$) {
+        if (i > offset) writeStringSlice(s, offset, i);
+        offset = i + 1;
+        writeCharCode(BACKSLASH);
+        writeCharCode(charCode);
+      }
+    }
+    if (offset == 0) {
+      writeString(s);
+    } else if (offset < length) {
+      writeStringSlice(s, offset, length);
+    }
+  }
+
+  /**
+   * Serialize a [num], [String], [bool], [Null], [List] or [Map] value.
+   *
+   * Returns true if the value is one of these types, and false if not.
+   * If a value is both a [List] and a [Map], it's serialized as a [List].
+   */
+  bool writeStringLiteral(String str) {
+    writeString('"');
+    writeStringContent(str);
+    writeString('"');
+  }
+}
+
+String _escapeString(String str) {
+  StringBuffer output = new StringBuffer();
+  new _StringLiteralEscape(output)..writeStringLiteral(str);
+  return output.toString();
+}
+
 /// A collection of methods where all methods have the same name.
 /// This class is intended to optimize whether a specific invocation is
 /// appropritate for at least some of the methods in the collection.
@@ -183,8 +296,8 @@
         // Not enough positional arguments.
         return false;
       }
-      if (!_checkType(
-          invocation.positionalArguments[i], parameters[i].type)) return false;
+      if (!_checkType(invocation.positionalArguments[i], parameters[i].type))
+        return false;
     }
     if (invocation.namedArguments.isNotEmpty) {
       var startNamed;
@@ -203,8 +316,9 @@
         for (var j = startNamed; j < parameters.length; j++) {
           var p = parameters[j];
           if (p.simpleName == name) {
-            if (!_checkType(invocation.namedArguments[name],
-                parameters[j].type)) return false;
+            if (!_checkType(
+                invocation.namedArguments[name], parameters[j].type))
+              return false;
             match = true;
             break;
           }
@@ -340,7 +454,9 @@
 
 _getJsMemberName(mirrors.DeclarationMirror mirror) {
   var name = _getJsName(mirror);
-  return name == null || name.isEmpty ? _getDeclarationName(mirror) : name;
+  return name == null || name.isEmpty
+      ? _stripReservedNamePrefix(_getDeclarationName(mirror))
+      : name;
 }
 
 // TODO(jacobr): handle setters correctyl.
@@ -350,7 +466,7 @@
     assert(name.endsWith("="));
     name = name.substring(0, name.length - 1);
   }
-  return _stripReservedNamePrefix(name);
+  return name;
 }
 
 final _JS_LIBRARY_PREFIX = "js_library";
@@ -364,7 +480,7 @@
     ..write('${_JS_LIBRARY_PREFIX}.JsNative.getProperty(' * parts.length)
     ..write("${_JS_LIBRARY_PREFIX}.context");
   for (var p in parts) {
-    sb.write(", '$p')");
+    sb.write(", ${_escapeString(p)})");
   }
   return sb.toString();
 }
@@ -375,13 +491,13 @@
 String _accessJsPathSetter(String path) {
   var parts = path.split(".");
   return "${_JS_LIBRARY_PREFIX}.JsNative.setProperty(${_accessJsPathHelper(parts.getRange(0, parts.length - 1))
-      }, '${parts.last}', v)";
+      }, ${_escapeString(parts.last)}, v)";
 }
 
 String _accessJsPathCallMethodHelper(String path) {
   var parts = path.split(".");
   return "${_JS_LIBRARY_PREFIX}.JsNative.callMethod(${_accessJsPathHelper(parts.getRange(0, parts.length - 1))
-      }, '${parts.last}',";
+      }, ${_escapeString(parts.last)},";
 }
 
 @Deprecated("Internal Use Only")
@@ -398,12 +514,11 @@
   } else if (isStatic) {
     sb.write("static");
   } else {
-    sb.write("patch");
+    sb.write("@patch");
   }
   sb.write(" ");
   if (declaration.isGetter) {
-    sb.write(
-        "get $name => ${_accessJsPath(path)};");
+    sb.write("get $name => ${_accessJsPath(path)};");
   } else if (declaration.isSetter) {
     sb.write("set $name(v) {\n"
         "  ${_JS_LIBRARY_PREFIX}.safeForTypedInterop(v);\n"
@@ -466,7 +581,8 @@
   return false;
 }
 
-List<String> _generateExternalMethods(List<String> libraryPaths, bool useCachedPatches) {
+List<String> _generateExternalMethods(
+    List<String> libraryPaths, bool useCachedPatches) {
   var staticCodegen = <String>[];
 
   if (libraryPaths.length == 0) {
@@ -484,7 +600,7 @@
         // the patches for this file.
         _generateLibraryCodegen(uri, library, staticCodegen);
       }
-    });    // End of library foreach
+    }); // End of library foreach
   } else {
     // Used to generate cached_patches.dart file for all IDL generated dart:
     // files to the WebKit DOM.
@@ -500,133 +616,141 @@
 }
 
 _generateLibraryCodegen(uri, library, staticCodegen) {
-    // Is it a dart generated library?
-    var dartLibrary = uri.scheme == 'dart';  
+  // Is it a dart generated library?
+  var dartLibrary = uri.scheme == 'dart';
 
-    var sb = new StringBuffer();
-    String jsLibraryName = _getJsName(library);
+  var sb = new StringBuffer();
+  String jsLibraryName = _getJsName(library);
 
-    // Sort by patch file by its declaration name.
-    var sortedDeclKeys = library.declarations.keys.toList();
-    sortedDeclKeys.sort((a, b) => mirrors.MirrorSystem.getName(a).compareTo(mirrors.MirrorSystem.getName(b)));
+  // Sort by patch file by its declaration name.
+  var sortedDeclKeys = library.declarations.keys.toList();
+  sortedDeclKeys.sort((a, b) => mirrors.MirrorSystem
+      .getName(a)
+      .compareTo(mirrors.MirrorSystem.getName(b)));
 
-    sortedDeclKeys.forEach((name) {
-      var declaration = library.declarations[name];
-      if (declaration is mirrors.MethodMirror) {
-        if ((_hasJsName(declaration) || jsLibraryName != null) &&
-            _isExternal(declaration)) {
-          addMemberHelper(declaration, jsLibraryName, sb);
-        }
-      } else if (declaration is mirrors.ClassMirror) {
-        mirrors.ClassMirror clazz = declaration;
-        var isDom = dartLibrary ? hasDomName(clazz) : false;
-        var isJsInterop = _hasJsName(clazz);
-        if (isDom || isJsInterop) {
-          // TODO(jacobr): verify class implements JavaScriptObject.
-          var className = mirrors.MirrorSystem.getName(clazz.simpleName);
-          var classNameImpl = '${className}Impl';
-          var sbPatch = new StringBuffer();
-          if (isJsInterop) {
-            String jsClassName = _getJsMemberName(clazz);
+  sortedDeclKeys.forEach((name) {
+    var declaration = library.declarations[name];
+    if (declaration is mirrors.MethodMirror) {
+      if ((_hasJsName(declaration) || jsLibraryName != null) &&
+          _isExternal(declaration)) {
+        addMemberHelper(declaration, jsLibraryName, sb);
+      }
+    } else if (declaration is mirrors.ClassMirror) {
+      mirrors.ClassMirror clazz = declaration;
+      var isDom = dartLibrary ? hasDomName(clazz) : false;
+      var isJsInterop = _hasJsName(clazz);
+      if (isDom || isJsInterop) {
+        // TODO(jacobr): verify class implements JavaScriptObject.
+        var className = mirrors.MirrorSystem.getName(clazz.simpleName);
+        bool isPrivateUserDefinedClass =
+            className.startsWith('_') && !dartLibrary;
+        var classNameImpl = '${className}Impl';
+        var sbPatch = new StringBuffer();
+        if (isJsInterop) {
+          String jsClassName = _getJsMemberName(clazz);
 
-            jsInterfaceTypes.add(clazz);
-            clazz.declarations.forEach((name, declaration) {
-              if (declaration is! mirrors.MethodMirror ||
-                  !_isExternal(declaration)) return;
-              if (declaration.isFactoryConstructor &&
-                  _isAnonymousClass(clazz)) {
-                sbPatch.write("  factory ${className}(");
-                int i = 0;
-                var args = <String>[];
-                for (var p in declaration.parameters) {
-                  args.add(mirrors.MirrorSystem.getName(p.simpleName));
-                  i++;
-                }
-                if (args.isNotEmpty) {
-                  sbPatch
-                    ..write('{')
-                    ..write(args
-                        .map((name) => '$name:${_UNDEFINED_VAR}')
-                        .join(", "))
-                    ..write('}');
-                }
-                sbPatch.write(") {\n"
-                    "    var ret = ${_JS_LIBRARY_PREFIX}.JsNative.newObject();\n");
-                i = 0;
-                for (var p in declaration.parameters) {
-                  assert(p.isNamed); // TODO(jacobr): throw.
-                  var name = args[i];
-                  var jsName = _stripReservedNamePrefix(
-                      mirrors.MirrorSystem.getName(p.simpleName));
-                  sbPatch.write("    if($name != ${_UNDEFINED_VAR}) {\n"
-                      "      ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($name);\n"
-                      "      ${_JS_LIBRARY_PREFIX}.JsNative.setProperty(ret, '$jsName', $name);\n"
-                      "    }\n");
-                  i++;
-                }
+          jsInterfaceTypes.add(clazz);
+          clazz.declarations.forEach((name, declaration) {
+            if (declaration is! mirrors.MethodMirror ||
+                !_isExternal(declaration)) return;
+            if (declaration.isFactoryConstructor && _isAnonymousClass(clazz)) {
+              sbPatch.write("  factory ${className}(");
+              int i = 0;
+              var args = <String>[];
+              for (var p in declaration.parameters) {
+                args.add(mirrors.MirrorSystem.getName(p.simpleName));
+                i++;
+              }
+              if (args.isNotEmpty) {
+                sbPatch
+                  ..write('{')
+                  ..write(
+                      args.map((name) => '$name:${_UNDEFINED_VAR}').join(", "))
+                  ..write('}');
+              }
+              sbPatch.write(") {\n"
+                  "    var ret = ${_JS_LIBRARY_PREFIX}.JsNative.newObject();\n");
+              i = 0;
+              for (var p in declaration.parameters) {
+                assert(p.isNamed); // TODO(jacobr): throw.
+                var name = args[i];
+                var jsName = _stripReservedNamePrefix(
+                    mirrors.MirrorSystem.getName(p.simpleName));
+                sbPatch.write("    if($name != ${_UNDEFINED_VAR}) {\n"
+                    "      ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($name);\n"
+                    "      ${_JS_LIBRARY_PREFIX}.JsNative.setProperty(ret, ${_escapeString(jsName)}, $name);\n"
+                    "    }\n");
+                i++;
+              }
 
-                sbPatch.write(
-                  "  return ret;"
+              sbPatch.write("  return ret;"
                   "}\n");
-              } else if (declaration.isConstructor ||
-                  declaration.isFactoryConstructor) {
-                sbPatch.write("  ");
-                addMemberHelper(
-                    declaration,
-                    (jsLibraryName != null && jsLibraryName.isNotEmpty)
-                        ? "${jsLibraryName}.${jsClassName}"
-                        : jsClassName,
-                    sbPatch,
-                    isStatic: true,
-                    memberName: className);
-              }
-            });   // End of clazz.declarations.forEach 
-
-            clazz.staticMembers.forEach((memberName, member) {
-              if (_isExternal(member)) {
-                sbPatch.write("  ");
-                addMemberHelper(
-                    member,
-                    (jsLibraryName != null && jsLibraryName.isNotEmpty)
-                        ? "${jsLibraryName}.${jsClassName}"
-                        : jsClassName,
-                    sbPatch,
-                    isStatic: true);
-              }
-            });
-          }
-          if (isDom) {
-            sbPatch.write("  static Type get instanceRuntimeType => ${classNameImpl};\n");
-          }
-          if (sbPatch.isNotEmpty) {
-            var typeVariablesClause = '';
-            if (!clazz.typeVariables.isEmpty) {
-              typeVariablesClause =
-                  '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(m.simpleName)).join(',')}>';
+            } else if (declaration.isConstructor ||
+                declaration.isFactoryConstructor) {
+              sbPatch.write("  ");
+              addMemberHelper(
+                  declaration,
+                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
+                      ? "${jsLibraryName}.${jsClassName}"
+                      : jsClassName,
+                  sbPatch,
+                  isStatic: true,
+                  memberName: className);
             }
-            sb.write("""
-patch class $className$typeVariablesClause {
+          }); // End of clazz.declarations.forEach
+
+          clazz.staticMembers.forEach((memberName, member) {
+            if (_isExternal(member)) {
+              sbPatch.write("  ");
+              addMemberHelper(
+                  member,
+                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
+                      ? "${jsLibraryName}.${jsClassName}"
+                      : jsClassName,
+                  sbPatch,
+                  isStatic: true);
+            }
+          });
+        }
+        if (isDom) {
+          sbPatch.write(
+              "  static Type get instanceRuntimeType => ${classNameImpl};\n");
+        }
+        if (isPrivateUserDefinedClass) {
+          sb.write("""
+class ${escapePrivateClassPrefix}${className} implements $className {}
+""");
+        }
+
+        if (sbPatch.isNotEmpty) {
+          var typeVariablesClause = '';
+          if (!clazz.typeVariables.isEmpty) {
+            typeVariablesClause =
+                '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(m.simpleName)).join(',')}>';
+          }
+          sb.write("""
+@patch class $className$typeVariablesClause {
 $sbPatch
 }
 """);
-            if (isDom) {
-              sb.write("""
+          if (isDom) {
+            sb.write("""
 class $classNameImpl$typeVariablesClause extends $className implements ${_JS_LIBRARY_PREFIX}.JSObjectInterfacesDom {
   ${classNameImpl}.internal_() : super.internal_();
   get runtimeType => $className;
   toString() => super.toString();
 }
 """);
-            }
           }
         }
       }
-    });
-    if (sb.isNotEmpty) {
-      staticCodegen
-        ..add(uri.toString())
-        ..add("${uri}_js_interop_patch.dart")
-        ..add("""
+    }
+  });
+  if (sb.isNotEmpty) {
+    staticCodegen
+      ..add(uri.toString())
+      ..add("${uri}_js_interop_patch.dart")
+      ..add("""
 import 'dart:js' as ${_JS_LIBRARY_PREFIX};
 
 /**
@@ -637,7 +761,7 @@
 
 ${sb}
 """);
-    }
+  }
 }
 
 // Remember the @JS type to compare annotation type.
@@ -667,11 +791,13 @@
  * signal to generate and emit the patches to stdout to be captured and put into
  * the file sdk/lib/js/dartium/cached_patches.dart
  */
-List<String> _generateInteropPatchFiles(List<String> libraryPaths, genCachedPatches) {
+List<String> _generateInteropPatchFiles(
+    List<String> libraryPaths, genCachedPatches) {
   // Cache the @JS Type.
   if (_atJsType == -1) setupJsTypeCache();
 
-  var ret = _generateExternalMethods(libraryPaths, genCachedPatches ? false : true);
+  var ret =
+      _generateExternalMethods(libraryPaths, genCachedPatches ? false : true);
   var libraryPrefixes = new Map<mirrors.LibraryMirror, String>();
   var prefixNames = new Set<String>();
   var sb = new StringBuffer();
@@ -685,6 +811,9 @@
 
   for (var typeMirror in jsInterfaceTypes) {
     mirrors.LibraryMirror libraryMirror = typeMirror.owner;
+    var location = libraryMirror.location;
+    var dartLibrary = location != null && location.sourceUri.scheme == 'dart';
+
     var prefixName;
     if (libraryPrefixes.containsKey(libraryMirror)) {
       prefixName = libraryPrefixes[libraryMirror];
@@ -705,8 +834,11 @@
     var isArray = typeMirror.isSubtypeOf(listMirror);
     var isFunction = typeMirror.isSubtypeOf(functionMirror);
     var isJSObject = typeMirror.isSubtypeOf(jsObjectMirror);
-    var fullName =
-        '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}';
+    var className = mirrors.MirrorSystem.getName(typeMirror.simpleName);
+    var isPrivateUserDefinedClass = className.startsWith('_') && !dartLibrary;
+    if (isPrivateUserDefinedClass)
+      className = '${escapePrivateClassPrefix}${className}';
+    var fullName = '${prefixName}.${className}';
     (isArray ? implementsArray : implements).add(fullName);
     if (!isArray && !isFunction && !isJSObject) {
       // For DOM classes we need to be a bit more conservative at tagging them
@@ -752,15 +884,15 @@
 abstract class JSObjectInterfacesDom $implementsClauseDom {
 }
 
-patch class JSObject {
+@patch class JSObject {
   static Type get instanceRuntimeType => JSObjectImpl;
 }
 
-patch class JSFunction {
+@patch class JSFunction {
   static Type get instanceRuntimeType => JSFunctionImpl;
 }
 
-patch class JSArray {
+@patch class JSArray {
   static Type get instanceRuntimeType => JSArrayImpl;
 }
 
@@ -945,25 +1077,27 @@
 
 _lookupType(o, bool isCrossFrame, bool isElement) {
   try {
-   var type = html_common.lookupType(o, isElement);
-   var typeMirror = mirrors.reflectType(type);
-   var legacyInteropConvertToNative = typeMirror.isSubtypeOf(mirrors.reflectType(html.Blob)) ||
-        typeMirror.isSubtypeOf(mirrors.reflectType(html.Event)) ||
-        typeMirror.isSubtypeOf(mirrors.reflectType(indexed_db.KeyRange)) ||
-        typeMirror.isSubtypeOf(mirrors.reflectType(html.ImageData)) ||
-        typeMirror.isSubtypeOf(mirrors.reflectType(html.Node)) ||
+    var type = html_common.lookupType(o, isElement);
+    var typeMirror = mirrors.reflectType(type);
+    var legacyInteropConvertToNative =
+        typeMirror.isSubtypeOf(mirrors.reflectType(html.Blob)) ||
+            typeMirror.isSubtypeOf(mirrors.reflectType(html.Event)) ||
+            typeMirror.isSubtypeOf(mirrors.reflectType(indexed_db.KeyRange)) ||
+            typeMirror.isSubtypeOf(mirrors.reflectType(html.ImageData)) ||
+            typeMirror.isSubtypeOf(mirrors.reflectType(html.Node)) ||
 //        TypedData is removed from this list as it is converted directly
 //        rather than flowing through the interceptor code path.
 //        typeMirror.isSubtypeOf(mirrors.reflectType(typed_data.TypedData)) ||
-        typeMirror.isSubtypeOf(mirrors.reflectType(html.Window));
-    if (isCrossFrame && !typeMirror.isSubtypeOf(mirrors.reflectType(html.Window))) {
+            typeMirror.isSubtypeOf(mirrors.reflectType(html.Window));
+    if (isCrossFrame &&
+        !typeMirror.isSubtypeOf(mirrors.reflectType(html.Window))) {
       // TODO(jacobr): evaluate using the true cross frame Window class, etc.
       // as well as triggering that legacy JS Interop returns raw JsObject
       // instances.
       legacyInteropConvertToNative = false;
     }
     return [type, legacyInteropConvertToNative];
-  } catch (e) { }
+  } catch (e) {}
   return [JSObject.instanceRuntimeType, false];
 }
 
@@ -1045,7 +1179,8 @@
 
   static JsObject _jsify(object) native "JsObject_jsify";
 
-  static JsObject _fromBrowserObject(object) native "JsObject_fromBrowserObject";
+  static JsObject _fromBrowserObject(object)
+      native "JsObject_fromBrowserObject";
 
   /**
    * Returns the value associated with [property] from the proxied JavaScript
@@ -1088,8 +1223,7 @@
     return _identityEquality(this, other);
   }
 
-  static bool _identityEquality(a, b)
-      native "JsObject_identityEquality";
+  static bool _identityEquality(a, b) native "JsObject_identityEquality";
 
   /**
    * Returns `true` if the JavaScript object contains the specified property
@@ -1148,7 +1282,6 @@
   _callMethodLegacy(String name, List args) native "JsObject_callMethodLegacy";
 }
 
-
 /// Base class for all JS objects used through dart:html and typed JS interop.
 @Deprecated("Internal Use Only")
 class JSObject extends _JSObjectBase {
@@ -1185,8 +1318,8 @@
         if (matches != null) return ret;
         if (ret is Function ||
             (ret is JsFunction /* shouldn't be needed in the future*/) &&
-                _allowedMethods.containsKey(
-                    invocation.memberName)) return ret; // Warning: we have not bound "this"... we could type check on the Function but that is of little value in Dart.
+                _allowedMethods.containsKey(invocation.memberName))
+          return ret; // Warning: we have not bound "this"... we could type check on the Function but that is of little value in Dart.
         throwError();
       } else {
         // TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
@@ -1195,8 +1328,8 @@
     } else if (invocation.isSetter) {
       if (CHECK_JS_INVOCATIONS) {
         var matches = _allowedSetters[invocation.memberName];
-        if (matches == null ||
-            !matches.checkInvocation(invocation)) throwError();
+        if (matches == null || !matches.checkInvocation(invocation))
+          throwError();
       }
       assert(name.endsWith("="));
       name = name.substring(0, name.length - 1);
@@ -1206,8 +1339,8 @@
       var matches;
       if (CHECK_JS_INVOCATIONS) {
         matches = _allowedMethods[invocation.memberName];
-        if (matches == null ||
-            !matches.checkInvocation(invocation)) throwError();
+        if (matches == null || !matches.checkInvocation(invocation))
+          throwError();
       }
       var ret = _callMethod(name, _buildArgs(invocation));
       if (CHECK_JS_INVOCATIONS) {
@@ -1287,7 +1420,8 @@
       a8 = _UNDEFINED,
       a9 = _UNDEFINED,
       a10 = _UNDEFINED]) {
-    return _apply(_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
+    return _apply(
+        _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
   }
 
   noSuchMethod(Invocation invocation) {
@@ -1299,7 +1433,8 @@
 
   dynamic _apply(List args, {thisArg}) native "JSFunction_apply";
 
-  static JSFunction _createWithThis(Function f) native "JSFunction_createWithThis";
+  static JSFunction _createWithThis(Function f)
+      native "JSFunction_createWithThis";
   static JSFunction _create(Function f) native "JSFunction_create";
 }
 
@@ -1314,11 +1449,16 @@
 
   static hasProperty(_JSObjectBase o, name) => o._hasProperty(name);
   static getProperty(_JSObjectBase o, name) => o._operator_getter(name);
-  static setProperty(_JSObjectBase o, name, value) => o._operator_setter(name, value);
-  static callMethod(_JSObjectBase o, String method, List args) => o._callMethod(method, args);
-  static instanceof(_JSObjectBase o, /*JsFunction|JSFunction*/ type) => o._instanceof(type);
-  static callConstructor0(_JSObjectBase constructor) native "JSNative_callConstructor0";
-  static callConstructor(_JSObjectBase constructor, List args) native "JSNative_callConstructor";
+  static setProperty(_JSObjectBase o, name, value) =>
+      o._operator_setter(name, value);
+  static callMethod(_JSObjectBase o, String method, List args) =>
+      o._callMethod(method, args);
+  static instanceof(_JSObjectBase o, /*JsFunction|JSFunction*/ type) =>
+      o._instanceof(type);
+  static callConstructor0(_JSObjectBase constructor)
+      native "JSNative_callConstructor0";
+  static callConstructor(_JSObjectBase constructor, List args)
+      native "JSNative_callConstructor";
 
   static toTypedObject(JsObject o) native "JSNative_toTypedObject";
 
@@ -1329,7 +1469,6 @@
   static JSFunction withThis(Function f) native "JsFunction_withThisNoWrap";
 }
 
-
 /**
  * Proxies a JavaScript Function object.
  */
@@ -1346,8 +1485,7 @@
    * Invokes the JavaScript function with arguments [args]. If [thisArg] is
    * supplied it is the value of `this` for the invocation.
    */
-  dynamic apply(List args, {thisArg}) =>
-      _apply(args, thisArg: thisArg);
+  dynamic apply(List args, {thisArg}) => _apply(args, thisArg: thisArg);
 
   dynamic _apply(List args, {thisArg}) native "JsFunction_apply";
 
@@ -1528,7 +1666,7 @@
 /// JavaScript. We may remove the need to call this method completely in the
 /// future if Dart2Js is refactored so that its function calling conventions
 /// are more compatible with JavaScript.
-Function /*=F*/ allowInterop/*<F extends Function>*/(Function /*=F*/ f) {
+Function/*=F*/ allowInterop/*<F extends Function>*/(Function/*=F*/ f) {
   if (f is JSFunction) {
     // The function is already a JSFunction... no need to do anything.
     return f;
@@ -1563,5 +1701,3 @@
     return ret;
   }
 }
-
-debugPrint(_) {}
\ No newline at end of file
diff --git a/sdk/lib/js_util/dart2js/js_util_dart2js.dart b/sdk/lib/js_util/dart2js/js_util_dart2js.dart
new file mode 100644
index 0000000..a587459
--- /dev/null
+++ b/sdk/lib/js_util/dart2js/js_util_dart2js.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utility methods to efficiently manipulate typed JSInterop objects in cases
+/// where the name to call is not known at runtime. You should only use these
+/// methods when the same effect cannot be achieved with @JS annotations.
+/// These methods would be extension methods on JSObject if Dart supported
+/// extension methods.
+library dart.js_util;
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:collection' show HashMap;
+
+/// WARNING: performance of this method is much worse than other uitil
+/// methods in this library. Only use this method as a last resort.
+///
+/// Recursively converts a JSON-like collection of Dart objects to a
+/// collection of JavaScript objects and returns a [JsObject] proxy to it.
+///
+/// [object] must be a [Map] or [Iterable], the contents of which are also
+/// converted. Maps and Iterables are copied to a new JavaScript object.
+/// Primitives and other transferrable values are directly converted to their
+/// JavaScript type, and all other objects are proxied.
+jsify(object) {
+  if ((object is! Map) && (object is! Iterable)) {
+    throw new ArgumentError("object must be a Map or Iterable");
+  }
+  return _convertDataTree(object);
+}
+
+_convertDataTree(data) {
+  var _convertedObjects = new HashMap.identity();
+
+  _convert(o) {
+    if (_convertedObjects.containsKey(o)) {
+      return _convertedObjects[o];
+    }
+    if (o is Map) {
+      final convertedMap = JS('=Object', '{}');
+      _convertedObjects[o] = convertedMap;
+      for (var key in o.keys) {
+        JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
+      }
+      return convertedMap;
+    } else if (o is Iterable) {
+      var convertedList = [];
+      _convertedObjects[o] = convertedList;
+      convertedList.addAll(o.map(_convert));
+      return convertedList;
+    } else {
+      return o;
+    }
+  }
+
+  return _convert(data);
+}
+
+newObject() => JS('=Object', '{}');
+
+hasProperty(o, name) => JS('bool', '# in #', name, o);
+getProperty(o, name) => JS('Object', '#[#]', o, name);
+setProperty(o, name, value) => JS('', '#[#]=#', o, name, value);
+
+callMethod(o, String method, List args) =>
+    JS('Object', '#[#].apply(#, #)', o, method, o, args);
+
+instanceof(o, Function type) => JS('bool', '# instanceof #', o, type);
+callConstructor(Function constr, List arguments) {
+  if (arguments == null) {
+    return JS('Object', 'new #()', constr);
+  }
+
+  if (JS('bool', '# instanceof Array', arguments)) {
+    int argumentCount = JS('int', '#.length', arguments);
+    switch (argumentCount) {
+      case 0:
+        return JS('Object', 'new #()', constr);
+
+      case 1:
+        var arg0 = JS('', '#[0]', arguments);
+        return JS('Object', 'new #(#)', constr, arg0);
+
+      case 2:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        return JS('Object', 'new #(#, #)', constr, arg0, arg1);
+
+      case 3:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        var arg2 = JS('', '#[2]', arguments);
+        return JS('Object', 'new #(#, #, #)', constr, arg0, arg1, arg2);
+
+      case 4:
+        var arg0 = JS('', '#[0]', arguments);
+        var arg1 = JS('', '#[1]', arguments);
+        var arg2 = JS('', '#[2]', arguments);
+        var arg3 = JS('', '#[3]', arguments);
+        return JS(
+            'Object', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3);
+    }
+  }
+
+  // The following code solves the problem of invoking a JavaScript
+  // constructor with an unknown number arguments.
+  // First bind the constructor to the argument list using bind.apply().
+  // The first argument to bind() is the binding of 't', so add 'null' to
+  // the arguments list passed to apply().
+  // After that, use the JavaScript 'new' operator which overrides any binding
+  // of 'this' with the new instance.
+  var args = [null]..addAll(arguments);
+  var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
+  // Without this line, calling factoryFunction as a constructor throws
+  JS('String', 'String(#)', factoryFunction);
+  // This could return an UnknownJavaScriptObject, or a native
+  // object for which there is an interceptor
+  return JS('Object', 'new #()', factoryFunction);
+
+  // TODO(sra): Investigate:
+  //
+  //     var jsObj = JS('', 'Object.create(#.prototype)', constr);
+  //     JS('', '#.apply(#, #)', constr, jsObj,
+  //         []..addAll(arguments.map(_convertToJS)));
+  //     return _wrapToDart(jsObj);
+}
diff --git a/sdk/lib/js_util/dartium/js_util_dartium.dart b/sdk/lib/js_util/dartium/js_util_dartium.dart
new file mode 100644
index 0000000..5f1226d
--- /dev/null
+++ b/sdk/lib/js_util/dartium/js_util_dartium.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Utility methods to efficiently manipulate typed JSInterop objects in cases
+/// where the name to call is not known at runtime. You should only use these
+/// methods when the same effect cannot be achieved with @JS annotations.
+/// These methods would be extension methods on JSObject if Dart supported
+/// extension methods.
+library dart.js_util;
+
+import 'dart:js';
+
+/// WARNING: performance of this method is much worse than other uitil
+/// methods in this library. Only use this method as a last resort.
+///
+/// Recursively converts a JSON-like collection of Dart objects to a
+/// collection of JavaScript objects and returns a [JsObject] proxy to it.
+///
+/// [object] must be a [Map] or [Iterable], the contents of which are also
+/// converted. Maps and Iterables are copied to a new JavaScript object.
+/// Primitives and other transferrable values are directly converted to their
+/// JavaScript type, and all other objects are proxied.
+jsify(object) {
+  if ((object is! Map) && (object is! Iterable)) {
+    throw new ArgumentError("object must be a Map or Iterable");
+  }
+  return JsNative.jsify(object);
+}
+
+JSObject newObject() => JsNative.newObject();
+
+hasProperty(JSObject o, name) => JsNative.hasProperty(o, name);
+getProperty(JSObject o, name) => JsNative.getProperty(o, name);
+setProperty(JSObject o, name, value) => JsNative.setProperty(o, name, value);
+callMethod(JSObject o, String method, List args) => JsNative.callMethod(o, method, args);
+instanceof(JSObject o, Function type) => JsNative.instanceof(o, type);
+callConstructor(JSObject constructor, List args) => JsNative.callConstructor(constructor, args);
diff --git a/sdk/lib/vmservice/devfs.dart b/sdk/lib/vmservice/devfs.dart
index 35af748..7f940b9 100644
--- a/sdk/lib/vmservice/devfs.dart
+++ b/sdk/lib/vmservice/devfs.dart
@@ -37,10 +37,18 @@
     }
     Uri pathUri;
     try {
-      pathUri = Uri.parse(path);
+      pathUri = new Uri.file(path);
     } on FormatException catch(e) {
       return null;
     }
+
+    try {
+      // Make sure that this pathUri can be converted to a file path.
+      pathUri.toFilePath();
+    } on UnsupportedError catch (e) {
+      return null;
+    }
+
     Uri resolvedUri = uri.resolveUri(pathUri);
     if (!resolvedUri.toString().startsWith(uri.toString())) {
       // Resolved uri must be within the filesystem's base uri.
@@ -113,6 +121,39 @@
     }
   }
 
+  Future<String> handlePutStream(Object fsName,
+                                 Object path,
+                                 Stream<List<int>> bytes) async {
+    // A dummy Message for error message construction.
+    Message message = new Message.forMethod('_writeDevFSFile');
+    var writeStreamFile = VMServiceEmbedderHooks.writeStreamFile;
+    if (writeStreamFile == null) {
+      return _encodeDevFSDisabledError(message);
+    }
+    if (fsName == null) {
+      return encodeMissingParamError(message, 'fsName');
+    }
+    if (fsName is! String) {
+      return encodeInvalidParamError(message, 'fsName');
+    }
+    var fs = _fsMap[fsName];
+    if (fs == null) {
+      return _encodeFileSystemDoesNotExistError(message, fsName);
+    }
+    if (path == null) {
+      return encodeMissingParamError(message, 'path');
+    }
+    if (path is! String) {
+      return encodeInvalidParamError(message, 'path');
+    }
+    Uri uri = fs.resolvePath(path);
+    if (uri == null) {
+      return encodeInvalidParamError(message, 'path');
+    }
+    await writeStreamFile(uri, bytes);
+    return encodeSuccess(message);
+  }
+
   Future<String> _listDevFS(Message message) async {
     var result = {};
     result['type'] = 'FileSystemList';
@@ -313,6 +354,10 @@
       return _encodeFileSystemDoesNotExistError(message, fsName);
     }
     var fileList = await listFiles(fs.uri);
+    // Remove any url-encoding in the filenames.
+    for (int i = 0; i < fileList.length; i++) {
+      fileList[i]['name'] = Uri.decodeFull(fileList[i]['name']);
+    }
     var result = { 'type': 'FSFileList', 'files': fileList };
     return encodeResult(message, result);
   }
diff --git a/sdk/lib/vmservice/message.dart b/sdk/lib/vmservice/message.dart
index 08bb5b1..0c02171 100644
--- a/sdk/lib/vmservice/message.dart
+++ b/sdk/lib/vmservice/message.dart
@@ -51,6 +51,9 @@
     return uri.pathSegments[0];
   }
 
+  Message.forMethod(String method)
+      : client = null, method = method, serial = '';
+
   Message.fromUri(this.client, Uri uri)
       : serial = '', method = _methodNameFromUri(uri) {
     params.addAll(uri.queryParameters);
@@ -130,6 +133,7 @@
       case '_writeDevFSFile':
       case '_writeDevFSFiles':
       case '_readDevFSFile':
+      case '_spawnUri':
         return true;
       default:
         return false;
@@ -182,4 +186,4 @@
 
 external bool sendIsolateServiceMessage(SendPort sp, List m);
 external void sendRootServiceMessage(List m);
-external void sendObjectRootServiceMessage(List m);
\ No newline at end of file
+external void sendObjectRootServiceMessage(List m);
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 4101023..25ceb6a 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -116,6 +116,9 @@
 /// Called to write a file.
 typedef Future WriteFileCallback(Uri path, List<int> bytes);
 
+/// Called to write a stream into a file.
+typedef Future WriteStreamFileCallback(Uri path, Stream<List<int>> bytes);
+
 /// Called to read a file.
 typedef Future<List<int>> ReadFileCallback(Uri path);
 
@@ -130,6 +133,7 @@
   static CreateTempDirCallback createTempDir;
   static DeleteDirCallback deleteDir;
   static WriteFileCallback writeFile;
+  static WriteStreamFileCallback writeStreamFile;
   static ReadFileCallback readFile;
   static ListFilesCallback listFiles;
 }
@@ -146,7 +150,7 @@
   /// A port used to receive events from the VM.
   final RawReceivePort eventPort;
 
-  final _devfs = new DevFS();
+  final devfs = new DevFS();
 
   void _addClient(Client client) {
     assert(client.streams.isEmpty);
@@ -206,7 +210,7 @@
     for (var client in clientsList) {
       client.disconnect();
     }
-    _devfs.cleanup();
+    devfs.cleanup();
     if (VMServiceEmbedderHooks.cleanup != null) {
       await VMServiceEmbedderHooks.cleanup();
     }
@@ -295,6 +299,37 @@
     return encodeSuccess(message);
   }
 
+  Future<String> _spawnUri(Message message) async {
+    var token = message.params['token'];
+    if (token == null) {
+      return encodeMissingParamError(message, 'token');
+    }
+    if (token is! String) {
+      return encodeInvalidParamError(message, 'token');
+    }
+    var uri = message.params['uri'];
+    if (uri == null) {
+      return encodeMissingParamError(message, 'uri');
+    }
+    if (uri is! String) {
+      return encodeInvalidParamError(message, 'uri');
+    }
+    var args = message.params['args'];
+    if (args != null &&
+        args is! List<String>) {
+      return encodeInvalidParamError(message, 'args');
+    }
+    var msg = message.params['message'];
+
+    Isolate.spawnUri(Uri.parse(uri), args, msg).then((isolate) {
+      _spawnUriNotify(isolate.controlPort, token);
+    }).catchError((e) {
+      _spawnUriNotify(e.toString(), token);
+    });
+
+    return encodeSuccess(message);
+  }
+
   // TODO(johnmccutchan): Turn this into a command line tool that uses the
   // service library.
   Future<String> _getCrashDump(Message message) async {
@@ -367,8 +402,11 @@
     if (message.method == 'streamCancel') {
       return _streamCancel(message);
     }
-    if (_devfs.shouldHandleMessage(message)) {
-      return _devfs.handleMessage(message);
+    if (message.method == '_spawnUri') {
+      return _spawnUri(message);
+    }
+    if (devfs.shouldHandleMessage(message)) {
+      return devfs.handleMessage(message);
     }
     if (message.params['isolateId'] != null) {
       return runningIsolates.route(message);
@@ -404,3 +442,6 @@
 
 /// Get the bytes to the tar archive.
 external Uint8List _requestAssets();
+
+/// Notify the vm service that an isolate has been spawned via rpc.
+external void _spawnUriNotify(obj, String token);
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index ac38baa..3dd54a8 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -354,7 +354,7 @@
 @DocsEditable()
 @DomName('ANGLEInstancedArrays')
 @Experimental() // untriaged
-@Native("ANGLEInstancedArrays")
+@Native("ANGLEInstancedArrays,ANGLE_instanced_arrays")
 class AngleInstancedArrays extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory AngleInstancedArrays._() { throw new UnsupportedError("Not supported"); }
@@ -469,7 +469,7 @@
 @DomName('WebGLCompressedTextureATC')
 // http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_atc/
 @Experimental()
-@Native("WebGLCompressedTextureATC")
+@Native("WebGLCompressedTextureATC,WEBGL_compressed_texture_atc")
 class CompressedTextureAtc extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory CompressedTextureAtc._() { throw new UnsupportedError("Not supported"); }
@@ -494,7 +494,7 @@
 @DocsEditable()
 @DomName('WebGLCompressedTextureETC1')
 @Experimental() // untriaged
-@Native("WebGLCompressedTextureETC1")
+@Native("WebGLCompressedTextureETC1,WEBGL_compressed_texture_etc1")
 class CompressedTextureETC1 extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory CompressedTextureETC1._() { throw new UnsupportedError("Not supported"); }
@@ -513,7 +513,7 @@
 @DomName('WebGLCompressedTexturePVRTC')
 // http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/
 @Experimental() // experimental
-@Native("WebGLCompressedTexturePVRTC")
+@Native("WebGLCompressedTexturePVRTC,WEBGL_compressed_texture_pvrtc")
 class CompressedTexturePvrtc extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory CompressedTexturePvrtc._() { throw new UnsupportedError("Not supported"); }
@@ -543,7 +543,7 @@
 @DomName('WebGLCompressedTextureS3TC')
 // http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
 @Experimental() // experimental
-@Native("WebGLCompressedTextureS3TC")
+@Native("WebGLCompressedTextureS3TC,WEBGL_compressed_texture_s3tc")
 class CompressedTextureS3TC extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory CompressedTextureS3TC._() { throw new UnsupportedError("Not supported"); }
@@ -602,7 +602,7 @@
 @DomName('WebGLDebugRendererInfo')
 // http://www.khronos.org/registry/webgl/extensions/WEBGL_debug_renderer_info/
 @Experimental() // experimental
-@Native("WebGLDebugRendererInfo")
+@Native("WebGLDebugRendererInfo,WEBGL_debug_renderer_info")
 class DebugRendererInfo extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory DebugRendererInfo._() { throw new UnsupportedError("Not supported"); }
@@ -624,7 +624,7 @@
 @DomName('WebGLDebugShaders')
 // http://www.khronos.org/registry/webgl/extensions/WEBGL_debug_shaders/
 @Experimental() // experimental
-@Native("WebGLDebugShaders")
+@Native("WebGLDebugShaders,WEBGL_debug_shaders")
 class DebugShaders extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory DebugShaders._() { throw new UnsupportedError("Not supported"); }
@@ -642,7 +642,7 @@
 @DomName('WebGLDepthTexture')
 // http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/
 @Experimental() // experimental
-@Native("WebGLDepthTexture")
+@Native("WebGLDepthTexture,WEBGL_depth_texture")
 class DepthTexture extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory DepthTexture._() { throw new UnsupportedError("Not supported"); }
@@ -660,7 +660,7 @@
 @DomName('WebGLDrawBuffers')
 // http://www.khronos.org/registry/webgl/specs/latest/
 @Experimental() // stable
-@Native("WebGLDrawBuffers")
+@Native("WebGLDrawBuffers,WEBGL_draw_buffers")
 class DrawBuffers extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory DrawBuffers._() { throw new UnsupportedError("Not supported"); }
@@ -814,7 +814,7 @@
 @DocsEditable()
 @DomName('EXTsRGB')
 @Experimental() // untriaged
-@Native("EXTsRGB")
+@Native("EXTsRGB,EXT_sRGB")
 class EXTsRgb extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory EXTsRgb._() { throw new UnsupportedError("Not supported"); }
@@ -847,7 +847,7 @@
 @DocsEditable()
 @DomName('EXTBlendMinMax')
 @Experimental() // untriaged
-@Native("EXTBlendMinMax")
+@Native("EXTBlendMinMax,EXT_blend_minmax")
 class ExtBlendMinMax extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory ExtBlendMinMax._() { throw new UnsupportedError("Not supported"); }
@@ -871,7 +871,7 @@
 @DomName('EXTFragDepth')
 // http://www.khronos.org/registry/webgl/extensions/EXT_frag_depth/
 @Experimental()
-@Native("EXTFragDepth")
+@Native("EXTFragDepth,EXT_frag_depth")
 class ExtFragDepth extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory ExtFragDepth._() { throw new UnsupportedError("Not supported"); }
@@ -884,7 +884,7 @@
 @DocsEditable()
 @DomName('EXTShaderTextureLOD')
 @Experimental() // untriaged
-@Native("EXTShaderTextureLOD")
+@Native("EXTShaderTextureLOD,EXT_shader_texture_lod")
 class ExtShaderTextureLod extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory ExtShaderTextureLod._() { throw new UnsupportedError("Not supported"); }
@@ -898,7 +898,7 @@
 @DomName('EXTTextureFilterAnisotropic')
 // http://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/
 @Experimental()
-@Native("EXTTextureFilterAnisotropic")
+@Native("EXTTextureFilterAnisotropic,EXT_texture_filter_anisotropic")
 class ExtTextureFilterAnisotropic extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory ExtTextureFilterAnisotropic._() { throw new UnsupportedError("Not supported"); }
@@ -933,7 +933,7 @@
 @DomName('WebGLLoseContext')
 // http://www.khronos.org/registry/webgl/extensions/WEBGL_lose_context/
 @Experimental()
-@Native("WebGLLoseContext,WebGLExtensionLoseContext")
+@Native("WebGLLoseContext,WebGLExtensionLoseContext,WEBGL_lose_context")
 class LoseContext extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory LoseContext._() { throw new UnsupportedError("Not supported"); }
@@ -955,7 +955,7 @@
 @DomName('OESElementIndexUint')
 // http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/
 @Experimental() // experimental
-@Native("OESElementIndexUint")
+@Native("OESElementIndexUint,OES_element_index_uint")
 class OesElementIndexUint extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory OesElementIndexUint._() { throw new UnsupportedError("Not supported"); }
@@ -969,7 +969,7 @@
 @DomName('OESStandardDerivatives')
 // http://www.khronos.org/registry/webgl/extensions/OES_standard_derivatives/
 @Experimental() // experimental
-@Native("OESStandardDerivatives")
+@Native("OESStandardDerivatives,OES_standard_derivatives")
 class OesStandardDerivatives extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory OesStandardDerivatives._() { throw new UnsupportedError("Not supported"); }
@@ -987,7 +987,7 @@
 @DomName('OESTextureFloat')
 // http://www.khronos.org/registry/webgl/extensions/OES_texture_float/
 @Experimental() // experimental
-@Native("OESTextureFloat")
+@Native("OESTextureFloat,OES_texture_float")
 class OesTextureFloat extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory OesTextureFloat._() { throw new UnsupportedError("Not supported"); }
@@ -1001,7 +1001,7 @@
 @DomName('OESTextureFloatLinear')
 // http://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/
 @Experimental()
-@Native("OESTextureFloatLinear")
+@Native("OESTextureFloatLinear,OES_texture_float_linear")
 class OesTextureFloatLinear extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory OesTextureFloatLinear._() { throw new UnsupportedError("Not supported"); }
@@ -1015,7 +1015,7 @@
 @DomName('OESTextureHalfFloat')
 // http://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/
 @Experimental() // experimental
-@Native("OESTextureHalfFloat")
+@Native("OESTextureHalfFloat,OES_texture_half_float")
 class OesTextureHalfFloat extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory OesTextureHalfFloat._() { throw new UnsupportedError("Not supported"); }
@@ -1033,7 +1033,7 @@
 @DomName('OESTextureHalfFloatLinear')
 // http://www.khronos.org/registry/webgl/extensions/OES_texture_half_float_linear/
 @Experimental()
-@Native("OESTextureHalfFloatLinear")
+@Native("OESTextureHalfFloatLinear,OES_texture_half_float_linear")
 class OesTextureHalfFloatLinear extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory OesTextureHalfFloatLinear._() { throw new UnsupportedError("Not supported"); }
@@ -1047,7 +1047,7 @@
 @DomName('OESVertexArrayObject')
 // http://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/
 @Experimental() // experimental
-@Native("OESVertexArrayObject")
+@Native("OESVertexArrayObject,OES_vertex_array_object")
 class OesVertexArrayObject extends Interceptor {
   // To suppress missing implicit constructor warnings.
   factory OesVertexArrayObject._() { throw new UnsupportedError("Not supported"); }
diff --git a/site/try/.gitignore b/site/try/.gitignore
deleted file mode 100644
index e142d1c..0000000
--- a/site/try/.gitignore
+++ /dev/null
@@ -1,5 +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.
-build_try.Makefile
-try_site.target.mk
diff --git a/site/try/Makefile b/site/try/Makefile
deleted file mode 100644
index 9bab88f..0000000
--- a/site/try/Makefile
+++ /dev/null
@@ -1,10 +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
-
-# TODO(ahe): Convert this to GYP.
-
-all:
-	../../sdk/bin/dart -Dlist_all_libraries=true ../../pkg/compiler/samples/jsonify/jsonify.dart sdk.dart
-	../../sdk/bin/dart jsonify.dart > sdk.json
-	../../sdk/bin/dart2js -Denable_ir=false leap.dart -oleap.dart.js
diff --git a/site/try/README b/site/try/README
deleted file mode 100644
index a23e257..0000000
--- a/site/try/README
+++ /dev/null
@@ -1 +0,0 @@
-See https://code.google.com/p/dart/wiki/TryDart.
diff --git a/site/try/add_time_stamp.py b/site/try/add_time_stamp.py
deleted file mode 100644
index adc0612..0000000
--- a/site/try/add_time_stamp.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-# 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 datetime
-import sys
-
-def Main():
-  (_, input_file_name, output_file_name) = sys.argv
-  if not input_file_name or not output_file_name:
-    raise Exception('Missing argument')
-
-  timestamp = str(datetime.datetime.now())
-
-  with open(input_file_name, 'r') as input_file:
-    with open(output_file_name, 'w') as output_file:
-      output_file.write(input_file.read().replace('@@TIMESTAMP@@', timestamp))
-
-
-if __name__ == '__main__':
-  sys.exit(Main())
diff --git a/site/try/app.yaml b/site/try/app.yaml
deleted file mode 100644
index f6c9eee..0000000
--- a/site/try/app.yaml
+++ /dev/null
@@ -1,118 +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.
-
-# App Engine configuration, see:
-# https://developers.google.com/appengine/docs/python/config/appconfig
-
-# The version number should be something like rSVN_REVISION.
-version: remember to edit app.yaml before deploying
-# This version name is used to create a new host, for example,
-# http://r31824.try-dart-lang.appspot.com/, which can be tested before going
-# live at http://try.dartlang.org/.  This is controlled from
-# https://appengine.google.com/deployment?&app_id=s~try-dart-lang
-
-application: try-dart-lang
-runtime: python27
-api_version: 1
-threadsafe: yes
-
-# Set "Cache-Control" and "Expires" HTTP headers to only cache for one second.
-# We do this because we frequently push new changes and rely on AppCache for
-# caching.  Once files are installed in AppCache, the site launches
-# immediately.
-#
-# Problem: PageSpeed Insights doesn't realize that we use AppCache and keeps
-# nagging about caching.
-# Solution: Ignore its advice about "Leverage browser caching".
-default_expiration: 1s
-
-handlers:
-- url: /packages/analyzer
-  static_dir: packages/analyzer
-  secure: always
-
-- url: /packages/args
-  static_dir: packages/args
-  secure: always
-
-- url: /packages/collection
-  static_dir: packages/collection
-  secure: always
-
-- url: /packages/crypto
-  static_dir: packages/crypto
-  secure: always
-
-- url: /packages/http
-  static_dir: packages/http
-  secure: always
-
-- url: /packages/http_parser
-  static_dir: packages/http_parser
-  secure: always
-
-- url: /packages/intl
-  static_dir: packages/intl
-  secure: always
-
-- url: /packages/logging
-  static_dir: packages/logging
-  secure: always
-
-- url: /packages/math
-  static_dir: packages/math
-  secure: always
-
-- url: /packages/path
-  static_dir: packages/path
-  secure: always
-
-- url: /packages/serialization
-  static_dir: packages/serialization
-  secure: always
-
-- url: /packages/stack_trace
-  static_dir: packages/stack_trace
-  secure: always
-
-- url: /packages/string_scanner
-  static_dir: packages/string_scanner
-  secure: always
-
-- url: /packages/unittest
-  static_dir: packages/unittest
-  secure: always
-
-- url: /packages/yaml
-  static_dir: packages/yaml
-  secure: always
-
-- url: /favicon\.ico
-  static_files: favicon.ico
-  upload: favicon\.ico
-  secure: always
-
-- url: /
-  static_files: index.html
-  upload: index.html
-  secure: always
-
-- url: /ssl.appcache
-  static_files: ssl.appcache
-  upload: ssl.appcache
-  secure: always
-
-- url: /(.*\.(html|js|png|css|dart|json))
-  static_files: \1
-  upload: (.*\.(html|js|png|css|dart|json))
-  secure: always
-
-- url: /css/fonts/fontawesome-webfont.woff
-  static_files: fontawesome-webfont.woff
-  upload: fontawesome-webfont.woff
-  secure: always
-
-libraries:
-- name: webapp2
-  version: "2.5.2"
diff --git a/site/try/bugs/isolate_worker_bug.dart b/site/try/bugs/isolate_worker_bug.dart
deleted file mode 100644
index 0f46014..0000000
--- a/site/try/bugs/isolate_worker_bug.dart
+++ /dev/null
@@ -1,16 +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.
-
-// Successful test: output div contains "future!".
-
-import 'dart:async';
-
-const greeting = "Hello, cool people doing nice things!";
-
-// Prints a greeting.
-void main() {
-  print(greeting);
-
-  new Future(() => print("future!"));
-}
diff --git a/site/try/bugs/single_line_delete.dart b/site/try/bugs/single_line_delete.dart
deleted file mode 100644
index 7971d7f..0000000
--- a/site/try/bugs/single_line_delete.dart
+++ /dev/null
@@ -1,17 +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.
-
-var greeting = "Hello, World!";
-
-void main() {
-  // Put cursor at end of previous line. Hit backspace.
-  // 1. Ensure this triggers a single-line change.
-  // 2. Ensure the cursor position is correct.
-  // Then restore the file and place the cursor at the end of the file. Delete
-  // each character in the file by holding down backspace. Verify that there
-  // are no exceptions and that the entire buffer is deleted.
-  // Then restore the file and place the cursor before the semicolon on the
-  // first line. Hit delete and verify that a character is deleted.
-  print(greeting);
-}
diff --git a/site/try/build_sdk_json.dart b/site/try/build_sdk_json.dart
deleted file mode 100644
index ec5b56b..0000000
--- a/site/try/build_sdk_json.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.
-
-import 'dart:io';
-import 'dart:convert';
-import 'package:compiler/src/util/uri_extras.dart' show relativize;
-
-main(List<String> arguments) async {
-  if (arguments.length == 0) {
-    print('usage: build_sdk_json.dart <out-path>');
-    exit(1);
-  }
-
-  var out = arguments[0];
-  List<Uri> sdkFiles = await collectSdkFiles();
-  new File(out).writeAsStringSync(emitSdkAsJson(sdkFiles));
-}
-
-Uri sdkRoot = Uri.base.resolveUri(Platform.script).resolve('../../');
-
-/// Collects a list of files that are part of the SDK.
-List<Uri> collectSdkFiles() {
-  var files = <Uri>[];
-  var sdkDir = new Directory.fromUri(sdkRoot.resolve('sdk/lib/'));
-  for (var entity in sdkDir.listSync(recursive: true)) {
-    if (entity is File &&
-        (entity.path.endsWith('.dart') || entity.path.endsWith('.platform'))) {
-      files.add(entity.uri);
-    }
-  }
-  return files;
-}
-
-/// Creates a string that encodes the contents of the sdk libraries in json.
-///
-/// The keys of the json file are sdk-relative paths to source files, and the
-/// values are the contents of the file.
-String emitSdkAsJson(List<Uri> paths) {
-  var map = <String, String>{};
-  for (var uri in paths) {
-    String filename = relativize(sdkRoot, uri, false);
-    var contents = new File.fromUri(uri).readAsStringSync();
-    map['sdk:/$filename'] = contents;
-  }
-  return JSON.encode(map);
-}
diff --git a/site/try/build_try.gyp b/site/try/build_try.gyp
deleted file mode 100644
index 07717a3..0000000
--- a/site/try/build_try.gyp
+++ /dev/null
@@ -1,192 +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
-
-{
-  'variables' : {
-    'script_suffix%': '',
-  },
-  'conditions' : [
-    ['OS=="win"', {
-      'variables' : {
-        'script_suffix': '.bat',
-      },
-    }],
-  ],
-  'targets': [
-    {
-      'target_name': 'try_site',
-      'type': 'none',
-      'dependencies': [
-        '../../runtime/dart-runtime.gyp:dart',
-        '../../create_sdk.gyp:create_sdk_internal',
-        '../../pkg/pkg.gyp:pkg_packages',
-      ],
-      'variables': {
-        'try_dart_static_files': [
-          'index.html',
-          'dartlang-style.css',
-          'line_numbers.css',
-          'iframe.html',
-          'iframe.js',
-          'dart-icon.png', # iOS icon.
-          'dart-iphone5.png', # iPhone 5 splash screen.
-          'dart-icon-196px.png', # Android icon.
-          'try-dart-screenshot.png', # Google+ screen shot.
-          'favicon.ico',
-
-          '<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
-          '<(SHARED_INTERMEDIATE_DIR)/compiler_isolate.dart.js',
-          '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
-        ],
-        'try_dart_hosted_package_directories': [
-          # These packages are uploaded to Try Dart and can be used in code
-          # there.
-          '../../pkg/analyzer/lib',
-          '../../third_party/pkg/collection/lib',
-          '../../third_party/pkg/crypto/lib',
-          '../../third_party/pkg/args/lib',
-          '../../third_party/pkg/http/lib',
-          '../../third_party/pkg/http_parser/lib',
-          '../../third_party/pkg/intl/lib',
-          '../../third_party/pkg/logging/lib',
-          '../../third_party/pkg/path/lib',
-          '../../third_party/pkg/stack_trace/lib',
-          '../../third_party/pkg/string_scanner/lib',
-          '../../third_party/pkg/unittest/lib',
-          '../../third_party/pkg/yaml/lib',
-        ],
-      },
-      'actions': [
-        {
-          'action_name': 'sdk_json',
-          'message': 'Creating sdk.json',
-          'inputs': [
-
-            # Depending on this file ensures that the SDK is built before this
-            # action is executed.
-            '<(PRODUCT_DIR)/dart-sdk/README',
-
-            # This dependency is redundant for now, as this directory is
-            # implicitly part of the dependencies for dart-sdk/README.
-            'build_sdk_json.dart',
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
-          ],
-          'action': [
-
-            '<(PRODUCT_DIR)/dart-sdk/bin/'
-            '<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
-
-            '--package-root=<(PRODUCT_DIR)/packages/',
-            'build_sdk_json.dart',
-            '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
-          ],
-        },
-        {
-          'action_name': 'compile',
-          'message': 'Creating leap.dart.js',
-          'inputs': [
-            # Depending on this file ensures that the SDK is built before this
-            # action is executed.
-            '<(PRODUCT_DIR)/dart-sdk/README',
-
-            # Ensure the packages directory is built first.
-            '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
-
-            '<!@(["python", "../../tools/list_files.py", "\\.dart$", "src"])',
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
-          ],
-          'action': [
-            '<(PRODUCT_DIR)/dart-sdk/bin/dart2js<(script_suffix)',
-            '-p<(PRODUCT_DIR)/packages/',
-            '-Denable_ir=false',
-            '--show-package-warnings',
-            'src/leap.dart',
-            '-o<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
-          ],
-        },
-        {
-          'action_name': 'compile_isolate',
-          'message': 'Creating compiler_isolate.dart.js',
-          'inputs': [
-            # Depending on this file ensures that the SDK is built before this
-            # action is executed.
-            '<(PRODUCT_DIR)/dart-sdk/README',
-
-            # Ensure the packages directory is built first.
-            '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
-
-            '<!@(["python", "../../tools/list_files.py", "\\.dart$", "src"])',
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/compiler_isolate.dart.js',
-          ],
-          'action': [
-            '<(PRODUCT_DIR)/dart-sdk/bin/dart2js<(script_suffix)',
-            '-p<(PRODUCT_DIR)/packages/',
-            '-Denable_ir=false',
-            '--show-package-warnings',
-            '--trust-type-annotations',
-            'src/compiler_isolate.dart',
-            '-o<(SHARED_INTERMEDIATE_DIR)/compiler_isolate.dart.js',
-          ],
-        },
-        {
-          'action_name': 'ssl_appcache',
-          'message': 'Creating ssl.appcache',
-          'inputs': [
-            'add_time_stamp.py',
-            'ssl.appcache',
-            '<@(try_dart_static_files)',
-            'build_try.gyp', # If the list of files changed.
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/ssl.appcache',
-          ],
-          # Try Dart! uses AppCache. Cached files are only validated when the
-          # manifest changes (not its timestamp, but its actual contents).
-          'action': [
-            'python',
-            'add_time_stamp.py',
-            'ssl.appcache',
-            '<(SHARED_INTERMEDIATE_DIR)/ssl.appcache',
-          ],
-        },
-        {
-          'action_name': 'make_pkg_packages',
-          'inputs': [
-            '../../tools/make_links.py',
-            '<@(try_dart_hosted_package_directories)',
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/try_dartlang_org_packages.stamp',
-            '<(PRODUCT_DIR)/try_dartlang_org/packages'
-          ],
-          'action': [
-            'python', '../../tools/make_links.py',
-            '--timestamp_file=<(SHARED_INTERMEDIATE_DIR)'
-            '/try_dartlang_org_packages.stamp',
-            '<(PRODUCT_DIR)/try_dartlang_org/packages',
-            '<@(_inputs)',
-          ],
-        },
-      ],
-      'copies': [
-        {
-          # Destination directory.
-          'destination': '<(PRODUCT_DIR)/try_dartlang_org/',
-          # List of files to be copied (creates implicit build dependencies).
-          'files': [
-            'app.yaml',
-            '<@(try_dart_static_files)',
-            '<(SHARED_INTERMEDIATE_DIR)/ssl.appcache',
-          ],
-        },
-      ],
-    },
-  ],
-}
diff --git a/site/try/create_manifest.sh b/site/try/create_manifest.sh
deleted file mode 100644
index 0f145ac..0000000
--- a/site/try/create_manifest.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/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.
-
-# Script to create AppCache manifest.
-
-echo CACHE MANIFEST
-
-date +'# %s'
-
-echo CACHE:
-
-PKG_DIR="$(cd $(dirname ${0})/../pkg ; pwd)"
-SDK_DIR="$(cd $(dirname ${0})/../sdk ; pwd)"
-LIVE_DIR="$(cd $(dirname ${0})/../web_editor ; pwd)"
-
-echo ${PKG_DIR}/browser/lib/dart.js | sed -e "s|$(pwd)/||"
-
-# find ${SDK_DIR} \
-#     \( -name dartdoc -o -name pub -o -name dartium \) -prune \
-#     -o -name \*.dart -print \
-#     | sed -e "s|$(pwd)/||"
-
-find ${LIVE_DIR} \
-    \( -name \*~ \) -prune \
-    -o -type f -print | sed -e "s|$(pwd)/||"
-
-echo iframe.html
-echo iframe.js
-echo dart-icon.png
-echo dart-iphone5.png
-
-echo NETWORK:
-echo '*'
diff --git a/site/try/dart-icon-196px.png b/site/try/dart-icon-196px.png
deleted file mode 100644
index fc454d7..0000000
--- a/site/try/dart-icon-196px.png
+++ /dev/null
Binary files differ
diff --git a/site/try/dart-icon.png b/site/try/dart-icon.png
deleted file mode 100644
index bc2c9f4..0000000
--- a/site/try/dart-icon.png
+++ /dev/null
Binary files differ
diff --git a/site/try/dart-iphone5.png b/site/try/dart-iphone5.png
deleted file mode 100644
index 9b2144c..0000000
--- a/site/try/dart-iphone5.png
+++ /dev/null
Binary files differ
diff --git a/site/try/dartlang-style.css b/site/try/dartlang-style.css
deleted file mode 100644
index d890ec6..0000000
--- a/site/try/dartlang-style.css
+++ /dev/null
@@ -1,38 +0,0 @@
-@import url(https://fonts.googleapis.com/css?family=Open+Sans:400|Montserrat:400);/*
- * Bootstrap v2.3.1
- *
- * Copyright 2012 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world @twitter by @mdo and @fat.
- */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:22px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.12766%;*margin-left:2.07447%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.12766%}.row-fluid .span12{width:100%;*width:99.94681%}.row-fluid .offset12{margin-left:104.25532%;*margin-left:104.14894%}.row-fluid .offset12:first-child{margin-left:102.12766%;*margin-left:102.02128%}.row-fluid .span11{width:91.48936%;*width:91.43617%}.row-fluid .offset11{margin-left:95.74468%;*margin-left:95.6383%}.row-fluid .offset11:first-child{margin-left:93.61702%;*margin-left:93.51064%}.row-fluid .span10{width:82.97872%;*width:82.92553%}.row-fluid .offset10{margin-left:87.23404%;*margin-left:87.12766%}.row-fluid .offset10:first-child{margin-left:85.10638%;*margin-left:85.0%}.row-fluid .span9{width:74.46809%;*width:74.41489%}.row-fluid .offset9{margin-left:78.7234%;*margin-left:78.61702%}.row-fluid .offset9:first-child{margin-left:76.59574%;*margin-left:76.48936%}.row-fluid .span8{width:65.95745%;*width:65.90426%}.row-fluid .offset8{margin-left:70.21277%;*margin-left:70.10638%}.row-fluid .offset8:first-child{margin-left:68.08511%;*margin-left:67.97872%}.row-fluid .span7{width:57.44681%;*width:57.39362%}.row-fluid .offset7{margin-left:61.70213%;*margin-left:61.59574%}.row-fluid .offset7:first-child{margin-left:59.57447%;*margin-left:59.46809%}.row-fluid .span6{width:48.93617%;*width:48.88298%}.row-fluid .offset6{margin-left:53.19149%;*margin-left:53.08511%}.row-fluid .offset6:first-child{margin-left:51.06383%;*margin-left:50.95745%}.row-fluid .span5{width:40.42553%;*width:40.37234%}.row-fluid .offset5{margin-left:44.68085%;*margin-left:44.57447%}.row-fluid .offset5:first-child{margin-left:42.55319%;*margin-left:42.44681%}.row-fluid .span4{width:31.91489%;*width:31.8617%}.row-fluid .offset4{margin-left:36.17021%;*margin-left:36.06383%}.row-fluid .offset4:first-child{margin-left:34.04255%;*margin-left:33.93617%}.row-fluid .span3{width:23.40426%;*width:23.35106%}.row-fluid .offset3{margin-left:27.65957%;*margin-left:27.55319%}.row-fluid .offset3:first-child{margin-left:25.53191%;*margin-left:25.42553%}.row-fluid .span2{width:14.89362%;*width:14.84043%}.row-fluid .offset2{margin-left:19.14894%;*margin-left:19.04255%}.row-fluid .offset2:first-child{margin-left:17.02128%;*margin-left:16.91489%}.row-fluid .span1{width:6.38298%;*width:6.32979%}.row-fluid .offset1{margin-left:10.6383%;*margin-left:10.53191%}.row-fluid .offset1:first-child{margin-left:8.51064%;*margin-left:8.40426%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:"";line-height:0}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0}.container-fluid:after{clear:both}p{margin:0 0 11px}.lead{margin-bottom:22px;font-size:21px;font-weight:200;line-height:33px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:gray}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:11px 0;font-family:inherit;font-weight:bold;line-height:22px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:44px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:10px;margin:22px 0 33px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 11px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:22px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;*zoom:1;padding-left:5px;padding-right:5px}dl{margin-bottom:22px}dt,dd{line-height:22px}dt{font-weight:bold}dd{margin-left:11px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:22px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 22px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:22px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:22px;font-style:normal;line-height:22px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap}pre{display:block;padding:10.5px;margin:0 0 11px;font-size:13px;line-height:22px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:22px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 22px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:22px;font-size:21px;line-height:44px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:16.5px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:22px}input,button,select,textarea{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:22px;padding:4px 6px;margin-bottom:11px;font-size:14px;line-height:22px;color:#555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:32px;*margin-top:4px;line-height:32px}select{width:220px;border:1px solid #ccc;background-color:#fff}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);cursor:not-allowed}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:22px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:21px 20px 22px;margin-top:22px;margin-bottom:22px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:11px}.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px}.input-append,.input-prepend{display:inline-block;margin-bottom:11px;vertical-align:middle;font-size:0;white-space:nowrap}.input-append input,.input-append select,.input-append .uneditable-input,.input-append .dropdown-menu,.input-append .popover,.input-prepend input,.input-prepend select,.input-prepend .uneditable-input,.input-prepend .dropdown-menu,.input-prepend .popover{font-size:14px}.input-append input,.input-append select,.input-append .uneditable-input,.input-prepend input,.input-prepend select,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-append select:focus,.input-append .uneditable-input:focus,.input-prepend input:focus,.input-prepend select:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:22px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:22px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-append .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .add-on,.input-prepend .btn,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-search textarea,.form-search select,.form-search .help-inline,.form-search .uneditable-input,.form-search .input-prepend,.form-search .input-append,.form-inline input,.form-inline textarea,.form-inline select,.form-inline .help-inline,.form-inline .uneditable-input,.form-inline .input-prepend,.form-inline .input-append,.form-horizontal input,.form-horizontal textarea,.form-horizontal select,.form-horizontal .help-inline,.form-horizontal .uneditable-input,.form-horizontal .input-prepend,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:11px}legend+.control-group{margin-top:22px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:22px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:11px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:22px}.table th,.table td{padding:8px;line-height:22px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}/*
- *  Font Awesome 3.0.1
- *  the iconic font designed for use with Twitter Bootstrap
- *  -------------------------------------------------------
- *  The full suite of pictographic icons, examples, and documentation
- *  can be found at: http://fortawesome.github.com/Font-Awesome/
- *
- *  License
- *  -------------------------------------------------------
- *  - The Font Awesome font is licensed under the SIL Open Font License - http://scripts.sil.org/OFL
- *  - Font Awesome CSS, LESS, and SASS files are licensed under the MIT License -
- *    http://opensource.org/licenses/mit-license.html
- *  - The Font Awesome pictograms are licensed under the CC BY 3.0 License - http://creativecommons.org/licenses/by/3.0/
- *  - Attribution is no longer required in Font Awesome 3.0, but much appreciated:
- *    "Font Awesome by Dave Gandy - http://fortawesome.github.com/Font-Awesome"
- *
- *  Contact
- *  -------------------------------------------------------
- *  Email: dave@davegandy.com
- *  Twitter: http://twitter.com/fortaweso_me
- *  Work: Lead Product Designer @ http://kyruus.com
- */@font-face{font-family:"FontAwesome";src:url('/css/fonts/fontawesome-webfont.eot?v=3.0.1');src:url('/css/fonts/fontawesome-webfont.eot?v=3.0.1?#iefix') format('eot'),url('/css/fonts/fontawesome-webfont.woff?v=3.0.1') format('woff'), url('/css/fonts/fontawesome-webfont.ttf?v=3.0.1') format('truetype');font-weight:normal;font-style:normal}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none}[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none}a [class^="icon-"],a [class*=" icon-"]{display:inline-block}.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em}.btn [class^="icon-"],.btn [class*=" icon-"],.nav [class^="icon-"],.nav [class*=" icon-"]{display:inline}.btn [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class^="icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block}.nav-tabs [class^="icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"],.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class^="icon-"],.nav-pills [class^="icon-"].icon-large,.nav-pills [class*=" icon-"],.nav-pills [class*=" icon-"].icon-large{line-height:.9em}li [class^="icon-"],li [class*=" icon-"],.nav li [class^="icon-"],.nav li [class*=" icon-"]{display:inline-block;width:1.25em;text-align:center}li [class^="icon-"].icon-large,li [class*=" icon-"].icon-large,.nav li [class^="icon-"].icon-large,.nav li [class*=" icon-"].icon-large{width:1.5625em}ul.icons{list-style-type:none;text-indent:-.75em}ul.icons li [class^="icon-"],ul.icons li [class*=" icon-"]{width:.75em}.icon-muted{color:#eee}.icon-border{border:solid 1px #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.pull-right{float:right}.pull-left{float:left}[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em}[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em}.btn [class^="icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em}.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em}.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em}.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em}.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em}.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}@-moz-document url-prefix(){.icon-spin{height:.9em}.btn .icon-spin{height:auto}.icon-spin.icon-large{height:1.25em}.btn .icon-spin.icon-large{height:.75em}}.icon-glass:before{content:"\f000"}.icon-music:before{content:"\f001"}.icon-search:before{content:"\f002"}.icon-envelope:before{content:"\f003"}.icon-heart:before{content:"\f004"}.icon-star:before{content:"\f005"}.icon-star-empty:before{content:"\f006"}.icon-user:before{content:"\f007"}.icon-film:before{content:"\f008"}.icon-th-large:before{content:"\f009"}.icon-th:before{content:"\f00a"}.icon-th-list:before{content:"\f00b"}.icon-ok:before{content:"\f00c"}.icon-remove:before{content:"\f00d"}.icon-zoom-in:before{content:"\f00e"}.icon-zoom-out:before{content:"\f010"}.icon-off:before{content:"\f011"}.icon-signal:before{content:"\f012"}.icon-cog:before{content:"\f013"}.icon-trash:before{content:"\f014"}.icon-home:before{content:"\f015"}.icon-file:before{content:"\f016"}.icon-time:before{content:"\f017"}.icon-road:before{content:"\f018"}.icon-download-alt:before{content:"\f019"}.icon-download:before{content:"\f01a"}.icon-upload:before{content:"\f01b"}.icon-inbox:before{content:"\f01c"}.icon-play-circle:before{content:"\f01d"}.icon-repeat:before{content:"\f01e"}.icon-refresh:before{content:"\f021"}.icon-list-alt:before{content:"\f022"}.icon-lock:before{content:"\f023"}.icon-flag:before{content:"\f024"}.icon-headphones:before{content:"\f025"}.icon-volume-off:before{content:"\f026"}.icon-volume-down:before{content:"\f027"}.icon-volume-up:before{content:"\f028"}.icon-qrcode:before{content:"\f029"}.icon-barcode:before{content:"\f02a"}.icon-tag:before{content:"\f02b"}.icon-tags:before{content:"\f02c"}.icon-book:before{content:"\f02d"}.icon-bookmark:before{content:"\f02e"}.icon-print:before{content:"\f02f"}.icon-camera:before{content:"\f030"}.icon-font:before{content:"\f031"}.icon-bold:before{content:"\f032"}.icon-italic:before{content:"\f033"}.icon-text-height:before{content:"\f034"}.icon-text-width:before{content:"\f035"}.icon-align-left:before{content:"\f036"}.icon-align-center:before{content:"\f037"}.icon-align-right:before{content:"\f038"}.icon-align-justify:before{content:"\f039"}.icon-list:before{content:"\f03a"}.icon-indent-left:before{content:"\f03b"}.icon-indent-right:before{content:"\f03c"}.icon-facetime-video:before{content:"\f03d"}.icon-picture:before{content:"\f03e"}.icon-pencil:before{content:"\f040"}.icon-map-marker:before{content:"\f041"}.icon-adjust:before{content:"\f042"}.icon-tint:before{content:"\f043"}.icon-edit:before{content:"\f044"}.icon-share:before{content:"\f045"}.icon-check:before{content:"\f046"}.icon-move:before{content:"\f047"}.icon-step-backward:before{content:"\f048"}.icon-fast-backward:before{content:"\f049"}.icon-backward:before{content:"\f04a"}.icon-play:before{content:"\f04b"}.icon-pause:before{content:"\f04c"}.icon-stop:before{content:"\f04d"}.icon-forward:before{content:"\f04e"}.icon-fast-forward:before{content:"\f050"}.icon-step-forward:before{content:"\f051"}.icon-eject:before{content:"\f052"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-plus-sign:before{content:"\f055"}.icon-minus-sign:before{content:"\f056"}.icon-remove-sign:before{content:"\f057"}.icon-ok-sign:before{content:"\f058"}.icon-question-sign:before{content:"\f059"}.icon-info-sign:before{content:"\f05a"}.icon-screenshot:before{content:"\f05b"}.icon-remove-circle:before{content:"\f05c"}.icon-ok-circle:before{content:"\f05d"}.icon-ban-circle:before{content:"\f05e"}.icon-arrow-left:before{content:"\f060"}.icon-arrow-right:before{content:"\f061"}.icon-arrow-up:before{content:"\f062"}.icon-arrow-down:before{content:"\f063"}.icon-share-alt:before{content:"\f064"}.icon-resize-full:before{content:"\f065"}.icon-resize-small:before{content:"\f066"}.icon-plus:before{content:"\f067"}.icon-minus:before{content:"\f068"}.icon-asterisk:before{content:"\f069"}.icon-exclamation-sign:before{content:"\f06a"}.icon-gift:before{content:"\f06b"}.icon-leaf:before{content:"\f06c"}.icon-fire:before{content:"\f06d"}.icon-eye-open:before{content:"\f06e"}.icon-eye-close:before{content:"\f070"}.icon-warning-sign:before{content:"\f071"}.icon-plane:before{content:"\f072"}.icon-calendar:before{content:"\f073"}.icon-random:before{content:"\f074"}.icon-comment:before{content:"\f075"}.icon-magnet:before{content:"\f076"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-retweet:before{content:"\f079"}.icon-shopping-cart:before{content:"\f07a"}.icon-folder-close:before{content:"\f07b"}.icon-folder-open:before{content:"\f07c"}.icon-resize-vertical:before{content:"\f07d"}.icon-resize-horizontal:before{content:"\f07e"}.icon-bar-chart:before{content:"\f080"}.icon-twitter-sign:before{content:"\f081"}.icon-facebook-sign:before{content:"\f082"}.icon-camera-retro:before{content:"\f083"}.icon-key:before{content:"\f084"}.icon-cogs:before{content:"\f085"}.icon-comments:before{content:"\f086"}.icon-thumbs-up:before{content:"\f087"}.icon-thumbs-down:before{content:"\f088"}.icon-star-half:before{content:"\f089"}.icon-heart-empty:before{content:"\f08a"}.icon-signout:before{content:"\f08b"}.icon-linkedin-sign:before{content:"\f08c"}.icon-pushpin:before{content:"\f08d"}.icon-external-link:before{content:"\f08e"}.icon-signin:before{content:"\f090"}.icon-trophy:before{content:"\f091"}.icon-github-sign:before{content:"\f092"}.icon-upload-alt:before{content:"\f093"}.icon-lemon:before{content:"\f094"}.icon-phone:before{content:"\f095"}.icon-check-empty:before{content:"\f096"}.icon-bookmark-empty:before{content:"\f097"}.icon-phone-sign:before{content:"\f098"}.icon-twitter:before{content:"\f099"}.icon-facebook:before{content:"\f09a"}.icon-github:before{content:"\f09b"}.icon-unlock:before{content:"\f09c"}.icon-credit-card:before{content:"\f09d"}.icon-rss:before{content:"\f09e"}.icon-hdd:before{content:"\f0a0"}.icon-bullhorn:before{content:"\f0a1"}.icon-bell:before{content:"\f0a2"}.icon-certificate:before{content:"\f0a3"}.icon-hand-right:before{content:"\f0a4"}.icon-hand-left:before{content:"\f0a5"}.icon-hand-up:before{content:"\f0a6"}.icon-hand-down:before{content:"\f0a7"}.icon-circle-arrow-left:before{content:"\f0a8"}.icon-circle-arrow-right:before{content:"\f0a9"}.icon-circle-arrow-up:before{content:"\f0aa"}.icon-circle-arrow-down:before{content:"\f0ab"}.icon-globe:before{content:"\f0ac"}.icon-wrench:before{content:"\f0ad"}.icon-tasks:before{content:"\f0ae"}.icon-filter:before{content:"\f0b0"}.icon-briefcase:before{content:"\f0b1"}.icon-fullscreen:before{content:"\f0b2"}.icon-group:before{content:"\f0c0"}.icon-link:before{content:"\f0c1"}.icon-cloud:before{content:"\f0c2"}.icon-beaker:before{content:"\f0c3"}.icon-cut:before{content:"\f0c4"}.icon-copy:before{content:"\f0c5"}.icon-paper-clip:before{content:"\f0c6"}.icon-save:before{content:"\f0c7"}.icon-sign-blank:before{content:"\f0c8"}.icon-reorder:before{content:"\f0c9"}.icon-list-ul:before{content:"\f0ca"}.icon-list-ol:before{content:"\f0cb"}.icon-strikethrough:before{content:"\f0cc"}.icon-underline:before{content:"\f0cd"}.icon-table:before{content:"\f0ce"}.icon-magic:before{content:"\f0d0"}.icon-truck:before{content:"\f0d1"}.icon-pinterest:before{content:"\f0d2"}.icon-pinterest-sign:before{content:"\f0d3"}.icon-google-plus-sign:before{content:"\f0d4"}.icon-google-plus:before{content:"\f0d5"}.icon-money:before{content:"\f0d6"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-columns:before{content:"\f0db"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-envelope-alt:before{content:"\f0e0"}.icon-linkedin:before{content:"\f0e1"}.icon-undo:before{content:"\f0e2"}.icon-legal:before{content:"\f0e3"}.icon-dashboard:before{content:"\f0e4"}.icon-comment-alt:before{content:"\f0e5"}.icon-comments-alt:before{content:"\f0e6"}.icon-bolt:before{content:"\f0e7"}.icon-sitemap:before{content:"\f0e8"}.icon-umbrella:before{content:"\f0e9"}.icon-paste:before{content:"\f0ea"}.icon-lightbulb:before{content:"\f0eb"}.icon-exchange:before{content:"\f0ec"}.icon-cloud-download:before{content:"\f0ed"}.icon-cloud-upload:before{content:"\f0ee"}.icon-user-md:before{content:"\f0f0"}.icon-stethoscope:before{content:"\f0f1"}.icon-suitcase:before{content:"\f0f2"}.icon-bell-alt:before{content:"\f0f3"}.icon-coffee:before{content:"\f0f4"}.icon-food:before{content:"\f0f5"}.icon-file-alt:before{content:"\f0f6"}.icon-building:before{content:"\f0f7"}.icon-hospital:before{content:"\f0f8"}.icon-ambulance:before{content:"\f0f9"}.icon-medkit:before{content:"\f0fa"}.icon-fighter-jet:before{content:"\f0fb"}.icon-beer:before{content:"\f0fc"}.icon-h-sign:before{content:"\f0fd"}.icon-plus-sign-alt:before{content:"\f0fe"}.icon-double-angle-left:before{content:"\f100"}.icon-double-angle-right:before{content:"\f101"}.icon-double-angle-up:before{content:"\f102"}.icon-double-angle-down:before{content:"\f103"}.icon-angle-left:before{content:"\f104"}.icon-angle-right:before{content:"\f105"}.icon-angle-up:before{content:"\f106"}.icon-angle-down:before{content:"\f107"}.icon-desktop:before{content:"\f108"}.icon-laptop:before{content:"\f109"}.icon-tablet:before{content:"\f10a"}.icon-mobile-phone:before{content:"\f10b"}.icon-circle-blank:before{content:"\f10c"}.icon-quote-left:before{content:"\f10d"}.icon-quote-right:before{content:"\f10e"}.icon-spinner:before{content:"\f110"}.icon-circle:before{content:"\f111"}.icon-reply:before{content:"\f112"}.icon-github-alt:before{content:"\f113"}.icon-folder-close-alt:before{content:"\f114"}.icon-folder-open-alt:before{content:"\f115"}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:10px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:22px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #0088cc,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0085c7', endColorstr='#0074ad', GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #0088cc,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0085c7', endColorstr='#0074ad', GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:default}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:22px;color:#000;text-shadow:0 1px 0 #fff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:22px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #fff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #fff, #e6e6e6);background-image:-o-linear-gradient(top, #fff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#e3e3e3', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006ecc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #0088cc,#0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0085c7', endColorstr='#0042c7', GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#f9a834;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb24b', endColorstr='#f39106', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#db4f4a;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b,#bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5a56', endColorstr='#b9352e', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462,#51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5ec35e', endColorstr='#4fa04f', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#4ab0ce;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de,#2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#57bedd', endColorstr='#2e93b0', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#373737;background-image:-moz-linear-gradient(top, #444, #222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444), to(#222));background-image:-webkit-linear-gradient(top, #444, #222);background-image:-o-linear-gradient(top, #444, #222);background-image:linear-gradient(to bottom, #444444,#222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#414141', endColorstr='#1f1f1f', GradientType=0);border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#090909 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{border-color:transparent;cursor:pointer;color:#08c;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{font-size:0;margin-top:11px;margin-bottom:11px}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);*padding-top:5px;*padding-bottom:5px}.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert,article.up-and-running-contents .note,article.up-and-running-contents .tip,article.up-and-running-contents .caution,article.up-and-running-contents .warning{padding:8px 35px 8px 14px;margin-bottom:22px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,article.up-and-running-contents .note,article.up-and-running-contents .tip,article.up-and-running-contents .caution,article.up-and-running-contents .warning,.alert h4,article.up-and-running-contents .note h4,article.up-and-running-contents .tip h4,article.up-and-running-contents .caution h4,article.up-and-running-contents .warning h4{color:#c09853}.alert h4,article.up-and-running-contents .note h4,article.up-and-running-contents .tip h4,article.up-and-running-contents .caution h4,article.up-and-running-contents .warning h4{margin:0}.alert .close,article.up-and-running-contents .note .close,article.up-and-running-contents .tip .close,article.up-and-running-contents .caution .close,article.up-and-running-contents .warning .close{position:relative;top:-2px;right:-21px;line-height:22px}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847}.alert-success h4{color:#468847}.alert-danger,article.up-and-running-contents .caution,article.up-and-running-contents .warning,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48}.alert-danger h4,article.up-and-running-contents .caution h4,article.up-and-running-contents .warning h4,.alert-error h4{color:#b94a48}.alert-info,article.up-and-running-contents .note,article.up-and-running-contents .tip{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad}.alert-info h4,article.up-and-running-contents .note h4,article.up-and-running-contents .tip h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-left:0;margin-bottom:22px;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:22px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:10px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-tabs:after,.nav-pills:before,.nav-pills:after{display:table;content:"";line-height:0}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:22px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{border-color:#ddd;z-index:2}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{border-top-color:#08c;border-bottom-color:#08c;margin-top:6px}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:0.01;filter:alpha(opacity=1)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-bottom-color:transparent;border-top-color:#ddd}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default}.navbar{overflow:visible;margin-bottom:22px;*position:relative;*z-index:2}.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #fff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #fff, #f2f2f2);background-image:-o-linear-gradient(top, #fff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff,#f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#f0f0f0', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065);*zoom:1}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{float:left;display:block;padding:9px 20px 9px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #fff}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:9px 15px 9px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333;text-decoration:none}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e6e6e6;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #f2f2f2, #e6e6e6);background-image:-o-linear-gradient(top, #f2f2f2, #e6e6e6);background-image:linear-gradient(to bottom, #f2f2f2,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f0f0f0', endColorstr='#e3e3e3', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e6e6e6;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);position:absolute;top:-7px;left:9px}.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:10px}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0,0,0,0.2);border-bottom:0;bottom:-7px;top:auto}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #fff;border-bottom:0;bottom:-6px;top:auto}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e6e6e6;color:#555}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222, #111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222), to(#111));background-image:-webkit-linear-gradient(top, #222, #111);background-image:-o-linear-gradient(top, #222, #111);background-image:linear-gradient(to bottom, #222222,#111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#1f1f1f', endColorstr='#0e0e0e', GradientType=0);border-color:#252525}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:hover,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#fff}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-left-color:#111;border-right-color:#222}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111;color:#fff}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15);outline:0}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515,#040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#131313', endColorstr='#020202', GradientType=0);border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 22px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #fff}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:22px 0}.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:22px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;background-color:transparent;cursor:default}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px}.pagination-mini ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>a,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px}.pagination-mini ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>a,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:22px 0;list-style:none;text-align:center;*zoom:1}.pager:before,.pager:after{display:table;content:"";line-height:0}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:default}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none}.modal.fade{-webkit-transition:"opacity .3s linear, top .3s ease-out";-moz-transition:"opacity .3s linear, top .3s ease-out";-o-transition:"opacity .3s linear, top .3s ease-out";transition:"opacity .3s linear, top .3s ease-out";top:-25%}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff;*zoom:1}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right .arrow:after{left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.popover.left .arrow:after{right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:22px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:22px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-left:9px;padding-right:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:22px;margin-bottom:22px;background-color:#f6f6f6;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5,#f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f2f2f2', endColorstr='#f6f6f6', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.progress .bar{width:0%;height:100%;color:#fff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#1498da', endColorstr='#047db9', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#de514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5a56', endColorstr='#c03b34', GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5db95d;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5ec35e', endColorstr='#55a655', GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4cb2d0;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#57bedd', endColorstr='#3298b5', GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#f9a834;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb24b', endColorstr='#f39106', GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255,255,255,0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255,255,255,0.15)), color-stop(0.75, rgba(255,255,255,0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:22px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:22px;line-height:1}.carousel-inner{overflow:hidden;width:100%;position:relative}.carousel-inner>.item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50)}.carousel-control.right{left:auto;right:15px}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{color:#fff;line-height:22px}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:33px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px}.hero-unit li{line-height:33px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}body{padding-top:60px}/*
- * Bootstrap Responsive v2.3.1
- *
- * Copyright 2012 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world @twitter by @mdo and @fat.
- */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none !important}.visible-tablet{display:none !important}.hidden-desktop{display:none !important}.visible-desktop{display:inherit !important}@media (min-width: 768px) and (max-width: 979px){.hidden-desktop{display:inherit !important}.visible-desktop{display:none !important}.visible-tablet{display:inherit !important}.hidden-tablet{display:none !important}}@media (max-width: 767px){.hidden-desktop{display:inherit !important}.visible-desktop{display:none !important}.visible-phone{display:inherit !important}.hidden-phone{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:inherit !important}.hidden-print{display:none !important}}@media (min-width: 1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.5641%;*margin-left:2.51091%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.5641%}.row-fluid .span12{width:100%;*width:99.94681%}.row-fluid .offset12{margin-left:105.12821%;*margin-left:105.02182%}.row-fluid .offset12:first-child{margin-left:102.5641%;*margin-left:102.45772%}.row-fluid .span11{width:91.45299%;*width:91.3998%}.row-fluid .offset11{margin-left:96.5812%;*margin-left:96.47481%}.row-fluid .offset11:first-child{margin-left:94.01709%;*margin-left:93.91071%}.row-fluid .span10{width:82.90598%;*width:82.85279%}.row-fluid .offset10{margin-left:88.03419%;*margin-left:87.92781%}.row-fluid .offset10:first-child{margin-left:85.47009%;*margin-left:85.3637%}.row-fluid .span9{width:74.35897%;*width:74.30578%}.row-fluid .offset9{margin-left:79.48718%;*margin-left:79.3808%}.row-fluid .offset9:first-child{margin-left:76.92308%;*margin-left:76.81669%}.row-fluid .span8{width:65.81197%;*width:65.75877%}.row-fluid .offset8{margin-left:70.94017%;*margin-left:70.83379%}.row-fluid .offset8:first-child{margin-left:68.37607%;*margin-left:68.26969%}.row-fluid .span7{width:57.26496%;*width:57.21177%}.row-fluid .offset7{margin-left:62.39316%;*margin-left:62.28678%}.row-fluid .offset7:first-child{margin-left:59.82906%;*margin-left:59.72268%}.row-fluid .span6{width:48.71795%;*width:48.66476%}.row-fluid .offset6{margin-left:53.84615%;*margin-left:53.73977%}.row-fluid .offset6:first-child{margin-left:51.28205%;*margin-left:51.17567%}.row-fluid .span5{width:40.17094%;*width:40.11775%}.row-fluid .offset5{margin-left:45.29915%;*margin-left:45.19276%}.row-fluid .offset5:first-child{margin-left:42.73504%;*margin-left:42.62866%}.row-fluid .span4{width:31.62393%;*width:31.57074%}.row-fluid .offset4{margin-left:36.75214%;*margin-left:36.64575%}.row-fluid .offset4:first-child{margin-left:34.18803%;*margin-left:34.08165%}.row-fluid .span3{width:23.07692%;*width:23.02373%}.row-fluid .offset3{margin-left:28.20513%;*margin-left:28.09875%}.row-fluid .offset3:first-child{margin-left:25.64103%;*margin-left:25.53464%}.row-fluid .span2{width:14.52991%;*width:14.47672%}.row-fluid .offset2{margin-left:19.65812%;*margin-left:19.55174%}.row-fluid .offset2:first-child{margin-left:17.09402%;*margin-left:16.98763%}.row-fluid .span1{width:5.98291%;*width:5.92971%}.row-fluid .offset1{margin-left:11.11111%;*margin-left:11.00473%}.row-fluid .offset1:first-child{margin-left:8.54701%;*margin-left:8.44063%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media (min-width: 768px) and (max-width: 979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.76243%;*margin-left:2.70924%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.76243%}.row-fluid .span12{width:100%;*width:99.94681%}.row-fluid .offset12{margin-left:105.52486%;*margin-left:105.41848%}.row-fluid .offset12:first-child{margin-left:102.76243%;*margin-left:102.65605%}.row-fluid .span11{width:91.43646%;*width:91.38327%}.row-fluid .offset11{margin-left:96.96133%;*margin-left:96.85494%}.row-fluid .offset11:first-child{margin-left:94.1989%;*margin-left:94.09251%}.row-fluid .span10{width:82.87293%;*width:82.81974%}.row-fluid .offset10{margin-left:88.39779%;*margin-left:88.29141%}.row-fluid .offset10:first-child{margin-left:85.63536%;*margin-left:85.52898%}.row-fluid .span9{width:74.30939%;*width:74.2562%}.row-fluid .offset9{margin-left:79.83425%;*margin-left:79.72787%}.row-fluid .offset9:first-child{margin-left:77.07182%;*margin-left:76.96544%}.row-fluid .span8{width:65.74586%;*width:65.69266%}.row-fluid .offset8{margin-left:71.27072%;*margin-left:71.16434%}.row-fluid .offset8:first-child{margin-left:68.50829%;*margin-left:68.4019%}.row-fluid .span7{width:57.18232%;*width:57.12913%}.row-fluid .offset7{margin-left:62.70718%;*margin-left:62.6008%}.row-fluid .offset7:first-child{margin-left:59.94475%;*margin-left:59.83837%}.row-fluid .span6{width:48.61878%;*width:48.56559%}.row-fluid .offset6{margin-left:54.14365%;*margin-left:54.03726%}.row-fluid .offset6:first-child{margin-left:51.38122%;*margin-left:51.27483%}.row-fluid .span5{width:40.05525%;*width:40.00206%}.row-fluid .offset5{margin-left:45.58011%;*margin-left:45.47373%}.row-fluid .offset5:first-child{margin-left:42.81768%;*margin-left:42.7113%}.row-fluid .span4{width:31.49171%;*width:31.43852%}.row-fluid .offset4{margin-left:37.01657%;*margin-left:36.91019%}.row-fluid .offset4:first-child{margin-left:34.25414%;*margin-left:34.14776%}.row-fluid .span3{width:22.92818%;*width:22.87499%}.row-fluid .offset3{margin-left:28.45304%;*margin-left:28.34666%}.row-fluid .offset3:first-child{margin-left:25.69061%;*margin-left:25.58422%}.row-fluid .span2{width:14.36464%;*width:14.31145%}.row-fluid .offset2{margin-left:19.8895%;*margin-left:19.78312%}.row-fluid .offset2:first-child{margin-left:17.12707%;*margin-left:17.02069%}.row-fluid .span1{width:5.8011%;*width:5.74791%}.row-fluid .offset1{margin-left:11.32597%;*margin-left:11.21958%}.row-fluid .offset1:first-child{margin-left:8.56354%;*margin-left:8.45715%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media (max-width: 767px){body{padding-left:20px;padding-right:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;clear:none;width:auto;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:32px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media (max-width: 480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0)}.page-header h1 small{display:block;line-height:22px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-left:10px;padding-right:10px}.media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;left:10px;right:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media (max-width: 979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:22px}.navbar-fixed-bottom{margin-top:22px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 11px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{margin-top:5px;padding:0}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:11px 15px;margin:11px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-left:10px;padding-right:10px}}@media (min-width: 980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important}}section{margin-bottom:1em}code{border:0;padding:0}table{margin-bottom:1em}.alert a,article.up-and-running-contents .note a,article.up-and-running-contents .tip a,article.up-and-running-contents .caution a,article.up-and-running-contents .warning a{color:#005580;text-decoration:underline}ol.toc li{list-style-type:none}.search-query{width:100px}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#008ed1;background-image:-moz-linear-gradient(top, #0081c6, #00a4e4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0081c6), to(#00a4e4));background-image:-webkit-linear-gradient(top, #0081c6, #00a4e4);background-image:-o-linear-gradient(top, #0081c6, #00a4e4);background-image:linear-gradient(to bottom, #0081c6,#00a4e4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#007ec1', endColorstr='#00a0df', GradientType=0);border-color:#00a4e4 #00a4e4 #006d98;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#00a4e4;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#00a4e4;*background-color:#0092cb}.btn-primary:active,.btn-primary.active{background-color:#007fb1 \9}.thumbnail{background-color:whitesmoke;padding:15px}.navbar a.brand{padding:6px 20px 0 20px}.navbar-search{margin-top:4px}.navbar li.share-button{padding:8px 8px 0 0}.navbar li.share-button a{padding:0}.navbar .nav li.dropdown .dropdown-toggle .caret,.navbar .nav li.dropdown.open .caret{border-top-color:#0081c6;border-bottom-color:#0081c6;opacity:1}article.homepage pre.prettyprint{font-size:12px}article.homepage h1{font-family:"Montserrat",sans-serif;text-transform:uppercase;-webkit-text-stroke:1px}article.homepage h2{color:#00a4e4;-webkit-text-stroke:0.5px}article.homepage section{margin-bottom:60px}article.homepage section .callouts h2{text-transform:uppercase;font-family:"Montserrat",sans-serif}article.homepage section .callouts p.img{text-align:center}article.homepage ul.buttons{text-align:center;list-style:none}article.homepage ul.buttons li{display:inline-block}article.homepage #top-mast{text-align:center;margin-bottom:30px}article.homepage #top-mast .logo{margin-bottom:36px;position:relative;left:-28px}article.homepage #top-mast .contents{padding-top:30px;background-repeat:no-repeat;background-position:center bottom}@media (min-width: 481px){article.homepage #top-mast .contents{background-image:url("/imgs/Dart_Background-large-white-dartboard.jpg")}}article.homepage #top-mast h1{font-size:40px;margin-bottom:18px}article.homepage #top-mast p{font-size:18px;font-weight:200;line-height:33px;color:inherit}article.homepage #top-mast ul.buttons{margin-top:40px}article.homepage #top-mast ul.buttons li{margin:0 1em;vertical-align:top;width:180px;height:73px}article.homepage .overview-transition{text-align:center}article.homepage .overview-transition h1{font-size:50px;margin-bottom:1em;color:#AAA}div.editor-current-version{font-style:italic;margin-bottom:11px}section.article div.author-and-date{font-style:italic;color:#A8A8A8;font-size:11px;line-height:14px}.nowrap{white-space:nowrap}label.os-choice{display:inline}a.permalink{margin-left:0.5em;display:none}.has-permalink:hover>a.permalink{display:inline}.book{margin-bottom:2em}.book img.cover{box-shadow:8px 8px 15px #CCC}.spec-commentary{color:green}.spec-rationale{color:blue;font-style:italic}.spec-change{background:yellow}footer{border-top:1px solid #CECECE;background-color:#EFEFEF;color:#999;font-size:13px;padding:70px 0;margin-top:50px}footer ul{list-style:none;margin:0}footer p{font-size:12px}footer .copyright{padding-top:30px;text-align:center}div.bad pre.prettyprint{border-radius:5px;background-image:linear-gradient(bottom, #fff2f2 16%,#ffcccc 86%);background-image:-o-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-moz-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-webkit-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-ms-linear-gradient(bottom, #fff2f2 16%, #fcc 86%);background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0.16, #fff2f2), color-stop(0.86, #fcc))}div.good pre.prettyprint{border-radius:5px;background-image:linear-gradient(bottom, #f3fff0 16%,#d5ffcc 86%);background-image:-o-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-moz-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-webkit-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-ms-linear-gradient(bottom, #f3fff0 16%, #d5ffcc 86%);background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0.16, #f3fff0), color-stop(0.86, #d5ffcc))}.good pre.prettyprint:before{content:"good";color:#696;float:right}.bad pre.prettyprint:before{content:"bad";color:red;float:right}pre.prettyprint .pln{color:#000}@media screen{pre.prettyprint .str{color:#d14}pre.prettyprint .kwd{color:#000;font-weight:bold}pre.prettyprint .com{color:#998}pre.prettyprint .typ{color:#445588;font-weight:bold}pre.prettyprint .lit{color:#099}pre.prettyprint .pun,pre.prettyprint .opn,pre.prettyprint .clo{color:#000}pre.prettyprint .tag{color:navy}pre.prettyprint .atn{color:teal}pre.prettyprint .atv{color:#d14}pre.prettyprint .dec,pre.prettyprint .var{color:teal}pre.prettyprint .fun{color:#900}}@media print, projection{pre.prettyprint .str{color:#d14}pre.prettyprint .kwd{color:#000;font-weight:bold}pre.prettyprint .com{color:#666}pre.prettyprint .typ{color:#445588;font-weight:bold}pre.prettyprint .lit{color:#099}pre.prettyprint .pun,pre.prettyprint .opn,pre.prettyprint .clo{color:#000}pre.prettyprint .tag{color:navy}pre.prettyprint .atn{color:teal}pre.prettyprint .atv{color:#d14}pre.prettyprint .dec,pre.prettyprint .var{color:teal}pre.prettyprint .fun{color:#900}}pre.prettyprint pre.prettyprint{font-size:12px}pre.prettyprint ol.linenums{margin-top:0;margin-bottom:0}pre.prettyprint li.L0,pre.prettyprint li.L1,pre.prettyprint li.L2,pre.prettyprint li.L3,pre.prettyprint li.L5,pre.prettyprint li.L6,pre.prettyprint li.L7,pre.prettyprint li.L8{list-style-type:none}pre.prettyprint li.L1,pre.prettyprint li.L3,pre.prettyprint li.L5,pre.prettyprint li.L7,pre.prettyprint li.L9{background:#eee}#tutorial-side{width:200px;position:fixed;top:85px}@media (min-width: 1200px){#tutorial-side{width:258px}}@media (min-width: 768px) and (max-width: 979px){#tutorial-side{width:158px}}@media (max-width: 767px){#tutorial-side{position:static;width:100%}}@media (max-width: 480px){#tutorial-side{position:static;width:100%}}#tutorial-toc{list-style-type:square;font-size:9pt;padding:10px;background-color:#DDFFDD;border-radius:10px;margin:0px 0px 15px 0px}#tutorial-toc ul{margin:0px 0px 0px 15px}#tutorial-toc li{line-height:120%}#tutorial-toc h4{padding-bottom:7px}#whats-the-point{list-style-type:square;font-size:9pt;padding:10px;background-color:#D8ECFD;border-radius:10px;margin:0px 0px 15px 0px}#whats-the-point ul{margin:0px 0px 0px 15px}#whats-the-point li{line-height:120%;padding-bottom:7px}#whats-the-point h4{padding-bottom:7px}#code-links{list-style-type:square;font-size:9pt;padding:10px;background-color:#FFE4E1;border-radius:10px;line-height:120%;margin:10px 0px 15px 0px}#code-links p{font-size:9pt;line-height:120%}#code-links ul{margin:0px 0px 0px 15px}#code-links li{line-height:120%;padding-bottom:7px}#code-links h4{padding-bottom:7px}.icon-info-sign{color:SlateBlue;font-size:18pt;vertical-align:middle}#under-construction{background-color:#F5E2FF;border-radius:10px;border-width:1px;margin:15px 50px 15px 50px;padding:10px}#under-construction h3{font-weight:bold;font-size:16pt}#under-construction .icon-wrench{font-size:24pt}#target-group{background-color:#F5E2FF;border-radius:10px;border-width:1px;margin:15px 10px 15px 10px;padding:10px}#target-group h3{font-weight:bold;font-size:16pt}#target-group .icon-wrench{font-size:24pt}.running-app-frame{border-style:solid;border-width:1px;border-radius:7px;background-color:WhiteSmoke;padding:5px}#dartisans-ribbon{position:fixed;top:0px;right:-95px;background:#00A4E4;color:white;-webkit-transform:rotateZ(40deg);-moz-transform:rotateZ(40deg);-ms-transform:rotateZ(40deg);-o-transform:rotateZ(40deg);transform:rotateZ(40deg);font-size:25px;padding:5px 70px;text-transform:uppercase;z-index:1000;-webkit-transform-origin:0 50%;-moz-transform-origin:0 50%;-ms-transform-origin:0 50%;-o-transform-origin:0 50%;transform-origin:0 50%;font-weight:600;-webkit-box-shadow:0px 0px 10px #222;-moz-box-shadow:0px 0px 10px #222;-ms-box-shadow:0px 0px 10px #222;-o-box-shadow:0px 0px 10px #222;box-shadow:0px 0px 10px #222;text-shadow:0px 0px 5px #000}@media (max-width: 979px){#dartisans-ribbon{top:-30px}}@media (max-width: 480px){#dartisans-ribbon{position:static}}#dartisans-ribbon .record{background-color:red;border-radius:50%;display:inline-block;width:15px;height:15px;margin-bottom:2px}article.up-and-running-contents #book-header{color:#999;font-size:13px;font-style:italic;text-align:center}article.up-and-running-contents span.remark{display:none}article.up-and-running-contents div.toc p:first-child b:first-child{display:none}article.up-and-running-contents dd dl{margin-top:0px}article.up-and-running-contents a.xref i{font-style:normal}@media print{.no-print{display:none}}
diff --git a/site/try/favicon.ico b/site/try/favicon.ico
deleted file mode 100644
index 50ea5b0..0000000
--- a/site/try/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/site/try/iframe.html b/site/try/iframe.html
deleted file mode 100644
index d92887b..0000000
--- a/site/try/iframe.html
+++ /dev/null
@@ -1,15 +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.
--->
-<!DOCTYPE html>
-<html lang="en" manifest="nossl.appcache">
-<head>
-<title>JavaScript output</title>
-<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
-</head>
-<body>
-<script type="application/javascript" src="iframe.js"></script>
-</body>
-</html>
diff --git a/site/try/iframe.js b/site/try/iframe.js
deleted file mode 100644
index d1460fd..0000000
--- a/site/try/iframe.js
+++ /dev/null
@@ -1,51 +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.
-
-function dartPrint(msg) {
-  window.parent.postMessage(String(msg), "*");
-}
-
-window.onerror = function (message, url, lineNumber) {
-  window.parent.postMessage(
-      ["error", {message: message, url: url, lineNumber: lineNumber}], "*");
-};
-
-function onMessageReceived(event) {
-  var data = event.data;
-  if (data instanceof Array) {
-    if (data.length == 2 && data[0] == 'source') {
-      var script = document.createElement('script');
-      script.innerHTML = data[1];
-      script.type = 'application/javascript';
-      document.head.appendChild(script);
-      return;
-    }
-  }
-}
-
-window.addEventListener("message", onMessageReceived, false);
-
-(function () {
-  function postScrollHeight() {
-    window.parent.postMessage(
-      ["scrollHeight", document.documentElement.scrollHeight], "*");
-  }
-
-  var mutationObserverConstructor =
-      window.MutationObserver ||
-      window.WebKitMutationObserver ||
-      window.MozMutationObserver;
-
-  var observer = new mutationObserverConstructor(function(mutations) {
-    postScrollHeight()
-    window.setTimeout(postScrollHeight, 500);
-  });
-
-  observer.observe(
-      document.body,
-      { attributes: true,
-        childList: true,
-        characterData: true,
-        subtree: true });
-})();
diff --git a/site/try/index.html b/site/try/index.html
deleted file mode 100644
index 9b318d2..0000000
--- a/site/try/index.html
+++ /dev/null
@@ -1,291 +0,0 @@
-<!DOCTYPE html>
-<!--
-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.
--->
-<html lang="en" manifest="ssl.appcache" itemscope itemtype="http://schema.org/Product">
-<head>
-<meta charset="utf-8">
-<title>Try Dart!</title>
-<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
-<!--
-TODO(ahe): Reduce the number of fonts used based on actual usage.
-
-See: http://www.google.com/fonts#UsePlace:use/Collection:Open+Sans:400,600,700,800,300
--->
-
-<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">
-<style>
-a.diagnostic {
-  color: inherit;
-  border-bottom: 2px dotted red;
-}
-a:hover.diagnostic {
-  text-decoration: none;
-}
-a.diagnostic>span {
-  display: none;
-  max-width: 70%;
-}
-a:hover.diagnostic>span.diagnostic, a:hover.diagnostic>span.alert {
-  display: block;
-  position: absolute;
-  /* left: 1em; */
-  /* top: 2em; */
-  right: 1%;
-}
-
-.offline {
-  transition: opacity 10s;
-  -webkit-transition: opacity 10s;
-}
-
-.offlineyay {
-  font-weight: bolder;
-  opacity: 0.0;
-}
-
-.dart-code-completion-holder {
-  position: relative;
-  display: inline-block;
-}
-
-.dart-code-completion-holder /deep/ *.dart-code-completion {
-  display: none;
-  position: absolute;
-  left: 0px;
-  min-width: 200px;
-  background: white;
-  foreground: black;
-  border: 1px solid black;
-  z-index: 10;
-  padding-left: 5px;
-}
-
-.dart-code-completion-holder.active /deep/ *.dart-code-completion {
-  display: block;
-}
-
-body /deep/ .dart-static {
-  width: 198px;
-  overflow: auto;
-}
-
-/*
- * TODO(ahe): There are problems with scroll bars on Macs, see:
- * http://stackoverflow.com/questions/7855590/how-can-i-prevent-scroll-bars-from-being-hidden-for-os-x-trackpad-users-in-webki
- * .dart-static::-webkit-scrollbar {
- *   -webkit-appearance: none;
- * }
- *
- * .dart-static::-webkit-scrollbar:vertical {
- *   width: 11px;
- * }
- *
- * .dart-static::-webkit-scrollbar:horizontal {
- *   height: 11px;
- * }
- *
- * .dart-static::-webkit-scrollbar-thumb {
- *   border-radius: 8px;
- *   border: 2px solid white; /* should match background, can't be transparent * /
- *   background-color: rgba(0, 0, 0, .5);
- * }
- *
- * .dart-static::-webkit-scrollbar-track {
- *   background-color: #fff;
- *   border-radius: 8px;
- * }
- */
-
-body /deep/ .dart-limited-height {
-  /* TODO(ahe): Make sure to compute this height to avoid jumping in the UI. */
-  max-height: 66px;
-}
-
-body /deep/ .dart-server {
-  width: 198px;
-  border-top: 1px solid black;
-}
-
-body /deep/ .activeEntry {
-  background: #86b4bf;
-}
-
-body /deep/ .doubleplusgood {
-  font-weight: 700;
-}
-
-body /deep/ .dart-entry {
-  max-width: 198px;
-  overflow: hidden;
-  white-space: nowrap;
-}
-
-body /deep/ .hazed-suggestion {
-  color: #aaa;
-}
-
-body /deep/ .hazed-suggestion:after {
-  content: " ";
-}
-
-.slider {
-  overflow-y: hidden;
-  height: 0;
-  max-height: 9999px;
-
-  transition-property: height;
-  transition-duration: .5s;
-  transition-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
-/* cubic-bezier(0, 1, 0.5, 1);*/
-}
-
-.myhidden {
-  position: absolute;
-  visibility: hidden;
-  height: auto;
-}
-
-.mainEditorPane {
-  white-space: pre;
-  /* Extra padding at the bottom to ensure display of error messages. */
-  padding: 19px 19px 70px 19px;
-}
-
-.lineNumber {
-}
-</style>
-
-<meta itemprop="name" content="Try Dart!">
-<meta itemprop="description" content="Write and run Dart code in your browser.  Dart is a class-based, object-oriented language with lexical scoping, closures, and optional static typing.">
-<meta name="description" content="Write and run Dart code in your browser.  Dart is a class-based, object-oriented language with lexical scoping, closures, and optional static typing.">
-<meta itemprop="image" content="try-dart-screenshot.png">
-
-<link rel="dart-sdk" href="sdk.json">
-<link rel="benchmark-DeltaBlue" href="benchmarks/DeltaBlue.dart">
-<link rel="benchmark-Richards" href="benchmarks/Richards.dart">
-<link rel="benchmark-base" href="benchmarks/benchmark_base.dart">
-
-<link href="favicon.ico" rel="icon" type="image/x-icon">
-
-<meta name="viewport" content="initial-scale=1.0">
-
-<!-- Chrome Mobile (Android) "Add to home screen" support -->
-<meta name="mobile-web-app-capable" content="yes">
-<link rel="shortcut icon" sizes="196x196" href="dart-icon-196px.png">
-
-<!-- iOS "Add to Home Screen" support -->
-<meta name="apple-mobile-web-app-capable" content="yes">
-<link rel="apple-touch-icon" href="dart-icon-196px.png">
-<meta names="apple-mobile-web-app-status-bar-style" content="black">
-<link rel="apple-touch-startup-image"
-      media="(device-width: 320px)
-         and (device-height: 568px)
-         and (-webkit-device-pixel-ratio: 2)"
-      href="dart-iphone5.png">
-
-<!-- Enable Google Analytics -->
-<script type="text/javascript">
-if (document.cookie.split(new RegExp('; *')).indexOf('org-trydart-AutomatedTest=true') == -1) {
-  window.parent && window.parent.postMessage('Enabling Analytics.', '*');
-  var _gaq = _gaq || [];
-  _gaq.push(['_setAccount', 'UA-26406144-2']);
-  _gaq.push(['_trackPageview']);
-
-  (function() {
-    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-  })();
-}
-</script>
-</head>
-<body>
-<div class="navbar navbar-fixed-top">
-<div class="navbar-inner">
-<div class="container">
-<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></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>
-<li><a href="//api.dartlang.org/" target="_blank">API Reference</a></li>
-</ul>
-<form class="navbar-search pull-right hidden-phone" action="//www.dartlang.org/search.html" id="cse-search-box" target="_blank">
-<input type="hidden" name="ie" value="UTF-8">
-<input type="hidden" name="hl" value="en">
-<input type="search" name="q" class="search-query" id="q" autocomplete="off" placeholder="Search">
-</form>
-<ul class="nav pull-right"><li><a><span id="appcache-status" class="offline">offline status</span></a></li></ul>
-
-
-</div>
-</div>
-</div>
-
-<div id="settings-dialog" class="myhidden container-fluid">
-  <div class="row-fluid">
-    <div class="span12">
-      <div>
-        <h3>Settings</h3>
-        <div id="settings-body">
-        </div>
-        <div>
-          <a href="#" class="btn btn-primary" id="settings-done">Close</a>
-        </div>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="container-fluid">
-<article class="homepage">
-<section>
-<div class="callouts row-fluid">
-<div class="span6" id="try-dart-column">
-<h2><i class="icon-play"></i> Try Dart! <select id="code-picker"></select></h2>
-</div>
-<div class="span6" id="run-dart-column">
-<h2><i class="icon-cogs"></i> See Dart</h2>
-</div>
-</div>
-</section>
-</article>
-</div>
-
-<footer>
-<div class="container">
-<div class="row copyright">
-<div class="span8 offset2">
-<p>
-Except as otherwise <a href="http://code.google.com/policies.html#restrictions">noted</a>, the content of this page is licensed under the <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>, and code samples are licensed under the <a href="http://code.google.com/google_bsd_license.html">BSD License</a>.
-</p>
-<p>
-<a href="//www.dartlang.org/tos.html">Terms of Service</a> —
-<a href="http://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>
-</p>
-</div>
-</div>
-</div>
-</footer>
-<!--
-<script type="application/javascript" src="https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/browser/lib/dart.js"></script>
-<script type="application/dart" src="leap.dart"></script>
--->
-<script type="application/javascript">
-  if (self.localStorage &&
-      !Object.prototype.hasOwnProperty.call(
-          self.localStorage, 'hasSelectionModify')) {
-    self.localStorage.hasSelectionModify =
-        typeof window.getSelection().modify != 'undefined';
-  }
-</script>
-<script type="application/javascript" src="leap.dart.js"></script>
-</body>
-</html>
diff --git a/site/try/line_numbers.css b/site/try/line_numbers.css
deleted file mode 100644
index 786d555..0000000
--- a/site/try/line_numbers.css
+++ /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.
- */
-
-.mainEditorPane {
-  padding: 0px;
-  counter-reset: dart-line-number;
-}
-
-.lineNumber {
-  padding-left: 3.5em;
-}
-
-.lineNumber:before {
-  counter-increment: dart-line-number;
-  content: counter(dart-line-number) " ";
-  position: absolute;
-  left: 0px;
-  width: 3em;
-  text-align: right;
-  background-color: lightgoldenrodyellow;
-}
diff --git a/site/try/nossl.appcache b/site/try/nossl.appcache
deleted file mode 100644
index 0c660f0..0000000
--- a/site/try/nossl.appcache
+++ /dev/null
@@ -1,10 +0,0 @@
-CACHE MANIFEST
-# 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.
-
-# @@TIMESTAMP@@
-
-FALLBACK:
-/leap.dart.js /nossl.js
-/ /nossl.html
diff --git a/site/try/nossl.html b/site/try/nossl.html
deleted file mode 100644
index 18b3d71..0000000
--- a/site/try/nossl.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<!--
-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.
--->
-<html lang="en">
-<head>
-<meta charset="utf-8">
-<title>Page has moved.</title>
-<meta http-equiv="refresh" content="0;URL='https://try.dartlang.org/'" />
-</head>
-<body>
-<p>This page has moved to <a href="https://try.dartlang.org/">https://try.dartlang.org/</a></p>
-</body>
-</html>
diff --git a/site/try/nossl.js b/site/try/nossl.js
deleted file mode 100644
index 50608b9..0000000
--- a/site/try/nossl.js
+++ /dev/null
@@ -1,19 +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.
-
-try {
-  document.location = 'https://try.dartlang.org/';
-} catch (e) {
-  // Ignored.
-}
-
-document.documentElement.innerHTML = (
-'<head>' +
-'<meta charset="utf-8">' +
-'<meta http-equiv="refresh" content="0;URL=\'https://try.dartlang.org/\'" />' +
-'<title>Redirecting</title>' +
-'</head>' +
-'<body>' +
-'<p>This page has moved to <a href="https://try.dartlang.org/">https://try.dartlang.org/</a>.</p>' +
-'</body>');
diff --git a/site/try/not_found.html b/site/try/not_found.html
deleted file mode 100644
index ecd6203..0000000
--- a/site/try/not_found.html
+++ /dev/null
@@ -1,15 +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>
-    <title>Missing Resource</title>
-    <meta charset="UTF-8">
-  </head>
-  <body>
-    <h1>Missing Resource</h1>
-  </body>
-</html>
diff --git a/site/try/poi/Makefile b/site/try/poi/Makefile
deleted file mode 100644
index 82f4bc2..0000000
--- a/site/try/poi/Makefile
+++ /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.
-
-# This Makefile is used to run the analyzer on the sources of poi.dart.
-# Unfortunately, we have to ignore some hints either due to bugs in the
-# analyzer, or due to patterns in dart2js (for example, unused imports of
-# helpers.dart).
-#
-# The purpose of this Makefile is to be used from inside Emacs to fix any valid
-# warning or hints reported. The whitelist is maintained as needed by those who
-# use this Makefile.
-
-SDK_DIR=../../../xcodebuild/ReleaseIA32/dart-sdk
-PACKAGE_ROOT=../../../xcodebuild/ReleaseIA32/packages/
-
-all:
-	@echo $(SDK_DIR)/bin/dartanalyzer -p $(PACKAGE_ROOT) repeat_poi.dart
-	@$(SDK_DIR)/bin/dartanalyzer -p $(PACKAGE_ROOT) \
-	--package-warnings --machine ../poi/repeat_poi.dart 2>&1 \
-	| grep -v DEPRECATED_MEMBER_USE \
-	| grep -v DEAD_CODE \
-	| grep -v -E 'INFO\|HINT\|ARGUMENT_TYPE_NOT_ASSIGNABLE\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/cps_ir/optimizers\.dart\|7\|8\|27\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/dart2jslib\.dart\|26\|8\|22\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/dart_types\.dart\|17\|8\|22\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/elements/elements\.dart\|[0-9]+\|8\|25\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/elements/modelx\.dart\|[0-9]+\|8\|25\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/js_emitter/js_emitter\.dart\|[0-9]+\|8\|25\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/library_loader\.dart\|25\|8\|22\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/patch_parser\.dart\|[0-9]+\|8\|22\|' \
-	| grep -v -E 'INFO\|HINT\|UNUSED_IMPORT\|.*/compiler/src/resolution/class_members\.dart\|22\|8\|25\|' \
-	| sed -e "s,$(PWD)/,," \
-	| awk -F'|' '{print $$4 ":" $$5 ":" $$6 ":\n [" n$$3 "]" $$8 }' \
diff --git a/site/try/poi/patcher.js b/site/try/poi/patcher.js
deleted file mode 100644
index d6f0c4b..0000000
--- a/site/try/poi/patcher.js
+++ /dev/null
@@ -1,15 +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.
-
-;(function(orig) {
-  function patcher(main, args) {
-    this.$dart_patch && this.$dart_unsafe_eval.patch($dart_patch);
-    if (orig) {
-      return orig(main, args);
-    } else {
-      return main(args);
-    }
-  }
-  this.dartMainRunner = patcher;
-})(this.dartMainRunner);
diff --git a/site/try/poi/poi.dart b/site/try/poi/poi.dart
deleted file mode 100644
index cb04b8d..0000000
--- a/site/try/poi/poi.dart
+++ /dev/null
@@ -1,572 +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 trydart.poi;
-
-import 'dart:async' show
-    Completer,
-    Future;
-
-import 'dart:io' as io;
-
-import 'dart:convert' show
-    UTF8;
-
-import 'package:dart2js_incremental/dart2js_incremental.dart' show
-    INCREMENTAL_OPTIONS,
-    reuseCompiler;
-
-import 'package:dart2js_incremental/library_updater.dart' show
-    IncrementalCompilerContext,
-    LibraryUpdater;
-
-import 'package:compiler/src/source_file_provider.dart' show
-    FormattingDiagnosticHandler;
-
-import 'package:compiler/compiler.dart' as api;
-
-import 'package:compiler/src/compiler.dart' show
-    Compiler;
-
-import 'package:compiler/src/common/tasks.dart' show
-    CompilerTask;
-
-import 'package:compiler/src/common/work.dart' show
-    WorkItem;
-
-import 'package:compiler/src/elements/visitor.dart' show
-    BaseElementVisitor;
-
-import 'package:compiler/src/elements/elements.dart' show
-    AbstractFieldElement,
-    ClassElement,
-    CompilationUnitElement,
-    Element,
-    ElementCategory,
-    FunctionElement,
-    LibraryElement,
-    ScopeContainerElement;
-
-import 'package:compiler/src/elements/modelx.dart' as modelx;
-
-import 'package:compiler/src/elements/modelx.dart' show
-    DeclarationSite;
-
-import 'package:compiler/src/enqueue.dart' show
-    Enqueuer,
-    QueueFilter;
-
-import 'package:compiler/src/dart_types.dart' show
-    DartType;
-
-import 'package:compiler/src/parser/partial_elements.dart' show
-    PartialClassElement,
-    PartialElement;
-
-import 'package:compiler/src/tokens/token.dart' show
-    Token;
-
-import 'package:compiler/src/tokens/token_constants.dart' show
-    EOF_TOKEN,
-    IDENTIFIER_TOKEN,
-    KEYWORD_TOKEN;
-
-import 'package:compiler/src/js/js.dart' show
-    js;
-
-import 'scope_information_visitor.dart' show
-    ScopeInformationVisitor;
-
-/// Enabled by the option --enable-dart-mind.  Controls if this program should
-/// be querying Dart Mind.
-bool isDartMindEnabled = false;
-
-/// Iterator over lines from standard input (or the argument array).
-Iterator<String> stdin;
-
-/// Enabled by the option --simulate-mutation. When true, this program will
-/// only prompt for one file name, and subsequent runs will read
-/// FILENAME.N.dart, where N starts at 1, and is increased on each iteration.
-/// For example, if the program is invoked as:
-///
-///   dart poi.dart --simulate-mutation test.dart 11 22 33 44
-///
-/// The program will first read the file 'test.dart' and compute scope
-/// information about position 11, then position 22 in test.dart.1.dart, then
-/// position 33 in test.dart.2.dart, and finally position 44 in
-/// test.dart.3.dart.
-bool isSimulateMutationEnabled = false;
-
-/// Counts the number of times [runPoi] has been invoked.
-int poiCount;
-
-int globalCounter = 0;
-
-/// Enabled by the option --verbose (or -v). Prints more information than you
-/// really need.
-bool isVerbose = false;
-
-/// Enabled by the option --compile. Also compiles the program after analyzing
-/// the POI.
-bool isCompiler = false;
-
-/// Enabled by the option --minify. Passes the same option to the compiler to
-/// generate minified output.
-bool enableMinification = false;
-
-/// When true (the default value) print serialized scope information at the
-/// provided position.
-const bool PRINT_SCOPE_INFO =
-    const bool.fromEnvironment('PRINT_SCOPE_INFO', defaultValue: true);
-
-Stopwatch wallClock = new Stopwatch();
-
-PoiTask poiTask;
-
-Compiler cachedCompiler;
-
-/// Iterator for reading lines from [io.stdin].
-class StdinIterator implements Iterator<String> {
-  String current;
-
-  bool moveNext() {
-    current = io.stdin.readLineSync();
-    return true;
-  }
-}
-
-printFormattedTime(message, int us) {
-  String m = '$message${" " * 65}'.substring(0, 60);
-  String i = '${" " * 10}${(us/1000).toStringAsFixed(3)}';
-  i = i.substring(i.length - 10);
-  print('$m ${i}ms');
-}
-
-printWallClock(message) {
-  if (!isVerbose) return;
-  if (wallClock.isRunning) {
-    print('$message');
-    printFormattedTime('--->>>', wallClock.elapsedMicroseconds);
-    wallClock.reset();
-  } else {
-    print(message);
-  }
-}
-
-printVerbose(message) {
-  if (!isVerbose) return;
-  print(message);
-}
-
-main(List<String> arguments) {
-  poiCount = 0;
-  wallClock.start();
-  List<String> nonOptionArguments = [];
-  for (String argument in arguments) {
-    if (argument.startsWith('-')) {
-      switch (argument) {
-        case '--simulate-mutation':
-          isSimulateMutationEnabled = true;
-          break;
-        case '--enable-dart-mind':
-          isDartMindEnabled = true;
-          break;
-        case '-v':
-        case '--verbose':
-          isVerbose = true;
-          break;
-        case '--compile':
-          isCompiler = true;
-          break;
-        case '--minify':
-          enableMinification = true;
-          break;
-        default:
-          throw 'Unknown option: $argument.';
-      }
-    } else {
-      nonOptionArguments.add(argument);
-    }
-  }
-  if (nonOptionArguments.isEmpty) {
-    stdin = new StdinIterator();
-  } else {
-    stdin = nonOptionArguments.iterator;
-  }
-
-  FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler();
-  handler
-      ..verbose = false
-      ..enableColors = true;
-  api.CompilerInputProvider inputProvider = handler.provider;
-
-  return prompt('Dart file: ').then((String fileName) {
-    if (isSimulateMutationEnabled) {
-      inputProvider = simulateMutation(fileName, inputProvider);
-    }
-    return prompt('Position: ').then((String position) {
-      return parseUserInput(fileName, position, inputProvider, handler);
-    });
-  });
-}
-
-/// Create an input provider that implements the behavior documented at
-/// [simulateMutation].
-api.CompilerInputProvider simulateMutation(
-    String fileName,
-    api.CompilerInputProvider inputProvider) {
-  Uri script = Uri.base.resolveUri(new Uri.file(fileName));
-  int count = poiCount;
-  Future cache;
-  String cachedFileName = script.toFilePath();
-  int counter = ++globalCounter;
-  return (Uri uri) {
-    if (counter != globalCounter) throw 'Using old provider';
-    printVerbose('fake inputProvider#$counter($uri): $poiCount $count');
-    if (uri == script) {
-      if (poiCount == count) {
-        cachedFileName = uri.toFilePath();
-        if (count != 0) {
-          cachedFileName = '$cachedFileName.$count.dart';
-        }
-        printVerbose('Not using cached version of $cachedFileName');
-        cache = new io.File(cachedFileName).readAsBytes().then((data) {
-          printVerbose(
-              'Read file $cachedFileName: '
-              '${UTF8.decode(data.take(100).toList(), allowMalformed: true)}...');
-          return data;
-        });
-        count++;
-      } else {
-        printVerbose('Using cached version of $cachedFileName');
-      }
-      return cache;
-    } else {
-      printVerbose('Using original provider for $uri');
-      return inputProvider(uri);
-    }
-  };
-}
-
-Future<String> prompt(message) {
-  if (stdin is StdinIterator) {
-    io.stdout.write(message);
-  }
-  return io.stdout.flush().then((_) {
-    stdin.moveNext();
-    return stdin.current;
-  });
-}
-
-Future queryDartMind(String prefix, String info) {
-  // TODO(lukechurch): Use [info] for something.
-  String encodedArg0 = Uri.encodeComponent('"$prefix"');
-  String mindQuery =
-      'http://dart-mind.appspot.com/rpc'
-      '?action=GetExportingPubCompletions'
-      '&arg0=$encodedArg0';
-  Uri uri = Uri.parse(mindQuery);
-
-  io.HttpClient client = new io.HttpClient();
-  return client.getUrl(uri).then((io.HttpClientRequest request) {
-    return request.close();
-  }).then((io.HttpClientResponse response) {
-    Completer<String> completer = new Completer<String>();
-    response.transform(UTF8.decoder).listen((contents) {
-      completer.complete(contents);
-    });
-    return completer.future;
-  });
-}
-
-Future parseUserInput(
-    String fileName,
-    String positionString,
-    api.CompilerInputProvider inputProvider,
-    api.DiagnosticHandler handler) {
-  Future repeat() {
-    printFormattedTime('--->>>', wallClock.elapsedMicroseconds);
-    wallClock.reset();
-
-    return prompt('Position: ').then((String positionString) {
-      wallClock.reset();
-      return parseUserInput(fileName, positionString, inputProvider, handler);
-    });
-  }
-
-  printWallClock("\n\n\nparseUserInput('$fileName', '$positionString')");
-
-  Uri script = Uri.base.resolveUri(new Uri.file(fileName));
-  if (positionString == null) return null;
-  int position = int.parse(
-      positionString, onError: (_) { print('Please enter an integer.'); });
-  if (position == null) return repeat();
-
-  inputProvider(script);
-  if (isVerbose) {
-    handler(
-        script, position, position + 1,
-        'Point of interest. '
-        'Cursor is immediately before highlighted character.',
-        api.Diagnostic.HINT);
-  }
-
-  Stopwatch sw = new Stopwatch()..start();
-
-  Future future = runPoi(script, position, inputProvider, handler);
-  return future.then((Element element) {
-    if (isVerbose) {
-      printFormattedTime('Resolving took', sw.elapsedMicroseconds);
-    }
-    sw.reset();
-    String info = scopeInformation(element, position);
-    sw.stop();
-    if (PRINT_SCOPE_INFO) {
-      print(info);
-    }
-    printVerbose('Scope information took ${sw.elapsedMicroseconds}us.');
-    sw..reset()..start();
-    Token token = findToken(element, position);
-    String prefix;
-    if (token != null) {
-      if (token.charOffset + token.charCount <= position) {
-        // After the token; in whitespace, or in the beginning of another token.
-        prefix = "";
-      } else if (token.kind == IDENTIFIER_TOKEN ||
-                 token.kind == KEYWORD_TOKEN) {
-        prefix = token.value.substring(0, position - token.charOffset);
-      }
-    }
-    sw.stop();
-    printVerbose('Find token took ${sw.elapsedMicroseconds}us.');
-    if (isDartMindEnabled && prefix != null) {
-      sw..reset()..start();
-      return queryDartMind(prefix, info).then((String dartMindSuggestion) {
-        sw.stop();
-        print('Dart Mind ($prefix): $dartMindSuggestion.');
-        printVerbose('Dart Mind took ${sw.elapsedMicroseconds}us.');
-        return repeat();
-      });
-    } else {
-      if (isDartMindEnabled) {
-        print("Didn't talk to Dart Mind, no identifier at POI ($token).");
-      }
-      return repeat();
-    }
-  });
-}
-
-/// Find the token corresponding to [position] in [element].  The method only
-/// works for instances of [PartialElement] or [LibraryElement].  Support for
-/// [LibraryElement] is currently limited, and works only for named libraries.
-Token findToken(modelx.ElementX element, int position) {
-  Token beginToken;
-  DeclarationSite site = element.declarationSite;
-  if (site is PartialElement) {
-    beginToken = site.beginToken;
-  } else if (element.isLibrary) {
-    // TODO(ahe): Generalize support for library elements (and update above
-    // documentation).
-    modelx.LibraryElementX lib = element;
-    var tag = lib.libraryTag;
-    if (tag != null) {
-      beginToken = tag.libraryKeyword;
-    }
-  } else {
-    beginToken = element.position;
-  }
-  if (beginToken == null) return null;
-  for (Token token = beginToken; token.kind != EOF_TOKEN; token = token.next) {
-    if (token.charOffset < position && position <= token.next.charOffset) {
-      return token;
-    }
-  }
-  return null;
-}
-
-Future<Element> runPoi(
-    Uri script,
-    int position,
-    api.CompilerInputProvider inputProvider,
-    api.DiagnosticHandler handler) {
-  Stopwatch sw = new Stopwatch()..start();
-  Uri libraryRoot = Uri.base.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolve(io.Platform.packageRoot);
-
-  var options = [
-      '--analyze-main',
-      '--verbose',
-      '--categories=Client,Server',
-  ];
-  options.addAll(INCREMENTAL_OPTIONS);
-
-  if (!isCompiler) {
-    options.add('--analyze-only');
-  }
-
-  if (enableMinification) {
-    options.add('--minify');
-  }
-
-  LibraryUpdater updater;
-
-  Future<bool> reuseLibrary(LibraryElement library) {
-    return poiTask.measure(() => updater.reuseLibrary(library));
-  }
-
-  Future<Compiler> invokeReuseCompiler() {
-    var context = new IncrementalCompilerContext();
-    updater = new LibraryUpdater(
-        cachedCompiler, inputProvider, printWallClock, printVerbose, context);
-    context.registerUriWithUpdates([script]);
-    return reuseCompiler(
-        diagnosticHandler: handler,
-        inputProvider: inputProvider,
-        options: options,
-        cachedCompiler: cachedCompiler,
-        libraryRoot: libraryRoot,
-        packageRoot: packageRoot,
-        packagesAreImmutable: true,
-        reuseLibrary: reuseLibrary);
-  }
-
-  return invokeReuseCompiler().then((Compiler newCompiler) {
-    // TODO(ahe): Move this "then" block to [reuseCompiler].
-    if (updater.failed) {
-      cachedCompiler = null;
-      return invokeReuseCompiler();
-    } else {
-      return newCompiler;
-    }
-  }).then((Compiler newCompiler) {
-    if (!isCompiler) {
-      newCompiler.enqueuerFilter = new ScriptOnlyFilter(script);
-    }
-    return runPoiInternal(newCompiler, sw, updater, script, position);
-  });
-}
-
-Future<Element> runPoiInternal(
-    Compiler newCompiler,
-    Stopwatch sw,
-    LibraryUpdater updater,
-    Uri uri,
-    int position) {
-  bool isFullCompile = cachedCompiler != newCompiler;
-  cachedCompiler = newCompiler;
-  if (poiTask == null || poiTask.compiler != cachedCompiler) {
-    poiTask = new PoiTask(cachedCompiler);
-    cachedCompiler.tasks.add(poiTask);
-  }
-
-  if (!isFullCompile) {
-    printFormattedTime(
-        'Analyzing changes and updating elements took', sw.elapsedMicroseconds);
-  }
-  sw.reset();
-
-  Future<bool> compilation;
-
-  if (updater.hasPendingUpdates) {
-    compilation = new Future(() {
-      var node = js.statement(
-          r'var $dart_patch = #', js.escapedString(updater.computeUpdateJs()));
-      print(updater.prettyPrintJs(node));
-
-      return !cachedCompiler.compilationFailed;
-    });
-  } else {
-    compilation = cachedCompiler.run(uri);
-  }
-
-  return compilation.then((success) {
-    printVerbose('Compiler queue processed in ${sw.elapsedMicroseconds}us');
-    if (isVerbose) {
-      for (final task in cachedCompiler.tasks) {
-        int time = task.timingMicroseconds;
-        if (time != 0) {
-          printFormattedTime('${task.name} took', time);
-        }
-      }
-    }
-
-    if (poiCount != null) poiCount++;
-    if (success != true) {
-      throw 'Compilation failed';
-    }
-    return findPosition(position, cachedCompiler.mainApp);
-  });
-}
-
-Element findPosition(int position, Element element) {
-  FindPositionVisitor visitor = new FindPositionVisitor(position, element);
-  element.accept(visitor, null);
-  return visitor.element;
-}
-
-String scopeInformation(Element element, int position) {
-  ScopeInformationVisitor visitor =
-      new ScopeInformationVisitor(cachedCompiler, element, position);
-  element.accept(visitor, null);
-  return '${visitor.buffer}';
-}
-
-class FindPositionVisitor extends BaseElementVisitor {
-  final int position;
-  Element element;
-
-  FindPositionVisitor(this.position, this.element);
-
-  visitElement(modelx.ElementX e, _) {
-    DeclarationSite site = e.declarationSite;
-    if (site is PartialElement) {
-      if (site.beginToken.charOffset <= position &&
-          position < site.endToken.next.charOffset) {
-        element = e;
-      }
-    }
-  }
-
-  visitClassElement(ClassElement e, _) {
-    if (e is PartialClassElement) {
-      if (e.beginToken.charOffset <= position &&
-          position < e.endToken.next.charOffset) {
-        element = e;
-        visitScopeContainerElement(e, _);
-      }
-    }
-  }
-
-  visitScopeContainerElement(ScopeContainerElement e, _) {
-    e.forEachLocalMember((Element element) => element.accept(this, _));
-  }
-}
-
-class ScriptOnlyFilter implements QueueFilter {
-  final Uri script;
-
-  ScriptOnlyFilter(this.script);
-
-  bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) => true;
-
-  void processWorkItem(void f(WorkItem work), WorkItem work) {
-    if (work.element.library.canonicalUri != script) {
-      // TODO(ahe): Rather nasty hack to work around another nasty hack in
-      // backend.dart. Find better solution.
-      if (work.element.name != 'closureFromTearOff') {
-        printWallClock('Skipped ${work.element}.');
-        return;
-      }
-    }
-    f(work);
-    printWallClock('Processed ${work.element}.');
-  }
-}
-
-class PoiTask extends CompilerTask {
-  final Compiler compiler;
-  PoiTask(Compiler compiler) : compiler = compiler, super(compiler.measurer);
-
-  String get name => 'POI';
-}
diff --git a/site/try/poi/repeat_poi.dart b/site/try/poi/repeat_poi.dart
deleted file mode 100644
index 32a704f..0000000
--- a/site/try/poi/repeat_poi.dart
+++ /dev/null
@@ -1,17 +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 'poi.dart' as poi;
-
-int count = 0;
-
-int MAX_ITERATIONS =
-    const int.fromEnvironment('MAX_ITERATIONS', defaultValue: null);
-
-main(arguments) {
-  count++;
-  if (MAX_ITERATIONS != null && count > MAX_ITERATIONS) return;
-  print('\n\n\n\nIteration #$count.');
-  poi.main(arguments).then((_) => main(arguments));
-}
diff --git a/site/try/poi/scope_information_visitor.dart b/site/try/poi/scope_information_visitor.dart
deleted file mode 100644
index 5f1b5a1..0000000
--- a/site/try/poi/scope_information_visitor.dart
+++ /dev/null
@@ -1,305 +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 trydart.poi.scope_information_visitor;
-
-import 'package:compiler/src/elements/modelx.dart' as modelx;
-
-import 'package:compiler/src/elements/modelx.dart' show
-    CompilationUnitElementX,
-    FieldElementX;
-
-import 'package:compiler/src/elements/visitor.dart' show
-    BaseElementVisitor;
-
-import 'package:compiler/src/compiler.dart' show
-    Compiler;
-
-import 'package:compiler/src/elements/elements.dart' show
-    AbstractFieldElement,
-    ClassElement,
-    CompilationUnitElement,
-    Element,
-    ElementCategory,
-    FunctionElement,
-    LibraryElement,
-    ScopeContainerElement;
-
-import 'package:compiler/src/dart_types.dart' show
-    DartType;
-
-/**
- * Serializes scope information about an element. This is accomplished by
- * calling the [serialize] method on each element. Some elements need special
- * treatment, as their enclosing scope must also be serialized.
- */
-class ScopeInformationVisitor extends BaseElementVisitor/* <void> */ {
-  // TODO(ahe): Include function parameters and local variables.
-
-  final Compiler compiler;
-  final Element currentElement;
-  final int position;
-  final StringBuffer buffer = new StringBuffer();
-  int indentationLevel = 0;
-  ClassElement currentClass;
-
-  bool sortMembers = false;
-
-  bool ignoreImports = false;
-
-  ScopeInformationVisitor(this.compiler, this.currentElement, this.position);
-
-  String get indentation => '  ' * indentationLevel;
-
-  StringBuffer get indented => buffer..write(indentation);
-
-  void visitElement(Element e, _) {
-    serialize(e, omitEnclosing: false);
-  }
-
-  void visitLibraryElement(LibraryElement e, _) {
-    bool isFirst = true;
-    forEach(Element member) {
-      if (!isFirst) {
-        buffer.write(',');
-      }
-      buffer.write('\n');
-      indented;
-      serialize(member);
-      isFirst = false;
-    }
-    serialize(
-        e,
-        // TODO(ahe): We omit the import scope if there is no current
-        // class. That's wrong.
-        omitEnclosing: ignoreImports || currentClass == null,
-        name: e.libraryName,
-        serializeEnclosing: () {
-          // The enclosing scope of a library is a scope which contains all the
-          // imported names.
-          isFirst = true;
-          buffer.write('{\n');
-          indentationLevel++;
-          indented.write('"kind": "imports",\n');
-          indented.write('"members": [');
-          indentationLevel++;
-          sortElements(importScope(e).importScope.values).forEach(forEach);
-          indentationLevel--;
-          buffer.write('\n');
-          indented.write('],\n');
-          // The enclosing scope of the imported names scope is the superclass
-          // scope of the current class.
-          indented.write('"enclosing": ');
-          serializeClassSide(
-              currentClass.superclass, isStatic: false, includeSuper: true);
-          buffer.write('\n');
-          indentationLevel--;
-          indented.write('}');
-        },
-        serializeMembers: () {
-          isFirst = true;
-          sortElements(localScope(e).values).forEach(forEach);
-        });
-  }
-
-  void visitClassElement(ClassElement e, _) {
-    currentClass = e;
-    serializeClassSide(e, isStatic: true);
-  }
-
-  /// Serializes one of the "sides" a class. The sides of a class are "instance
-  /// side" and "class side". These terms are from Smalltalk. The instance side
-  /// is all the local instance members of the class (the members of the
-  /// mixin), and the class side is the equivalent for static members and
-  /// constructors.
-  /// The scope chain is ordered so that the "class side" is searched before
-  /// the "instance side".
-  void serializeClassSide(
-      ClassElement e,
-      {bool isStatic: false,
-       bool omitEnclosing: false,
-       bool includeSuper: false}) {
-    e.ensureResolved(compiler.resolution);
-    bool isFirst = true;
-    var serializeEnclosing;
-    String kind;
-    if (isStatic) {
-      kind = 'class side';
-      serializeEnclosing = () {
-        serializeClassSide(e, isStatic: false, omitEnclosing: omitEnclosing);
-      };
-    } else {
-      kind = 'instance side';
-    }
-    if (includeSuper) {
-      assert(!omitEnclosing && !isStatic);
-      if (e.superclass == null) {
-        omitEnclosing = true;
-      } else {
-        // Members of the superclass are represented as a separate scope.
-        serializeEnclosing = () {
-          serializeClassSide(
-              e.superclass, isStatic: false, omitEnclosing: false,
-              includeSuper: true);
-        };
-      }
-    }
-    serialize(
-        e, omitEnclosing: omitEnclosing, serializeEnclosing: serializeEnclosing,
-        kind: kind, serializeMembers: () {
-      localMembersSorted(e).forEach((Element member) {
-        // Filter out members that don't belong to this "side".
-        if (member.isConstructor) {
-          // In dart2js, some constructors aren't static, but that isn't
-          // convenient here.
-          if (!isStatic) return;
-        } else if (member.isStatic != isStatic) {
-          return;
-        }
-        if (!isFirst) {
-          buffer.write(',');
-        }
-        buffer.write('\n');
-        indented;
-        serialize(member);
-        isFirst = false;
-      });
-    });
-  }
-
-  void visitScopeContainerElement(ScopeContainerElement e, _) {
-    bool isFirst = true;
-    serialize(e, omitEnclosing: false, serializeMembers: () {
-      localMembersSorted(e).forEach((Element member) {
-        if (!isFirst) {
-          buffer.write(',');
-        }
-        buffer.write('\n');
-        indented;
-        serialize(member);
-        isFirst = false;
-      });
-    });
-  }
-
-  void visitCompilationUnitElement(CompilationUnitElement e, _) {
-    e.enclosingElement.accept(this, _);
-  }
-
-  void visitAbstractFieldElement(AbstractFieldElement e, _) {
-    throw new UnsupportedError('AbstractFieldElement cannot be serialized.');
-  }
-
-  void serialize(
-      Element element,
-      {bool omitEnclosing: true,
-       void serializeMembers(),
-       void serializeEnclosing(),
-       String kind,
-       String name}) {
-    if (element.isAbstractField) {
-      AbstractFieldElement field = element;
-      FunctionElement getter = field.getter;
-      FunctionElement setter = field.setter;
-      if (getter != null) {
-        serialize(
-            getter,
-            omitEnclosing: omitEnclosing,
-            serializeMembers: serializeMembers,
-            serializeEnclosing: serializeEnclosing,
-            kind: kind,
-            name: name);
-      }
-      if (setter != null) {
-        if (getter != null) {
-          buffer.write(',\n');
-          indented;
-        }
-        serialize(
-            getter,
-            omitEnclosing: omitEnclosing,
-            serializeMembers: serializeMembers,
-            serializeEnclosing: serializeEnclosing,
-            kind: kind,
-            name: name);
-      }
-      return;
-    }
-    DartType type;
-    int category = element.kind.category;
-    if (category == ElementCategory.FUNCTION ||
-        category == ElementCategory.VARIABLE ||
-        element.isConstructor) {
-      type = element.computeType(compiler.resolution);
-    }
-    if (name == null) {
-      name = element.name;
-    }
-    if (kind == null) {
-      kind = '${element.kind}';
-    }
-    buffer.write('{\n');
-    indentationLevel++;
-    if (name != '') {
-      indented
-          ..write('"name": "')
-          ..write(name)
-          ..write('",\n');
-    }
-    indented
-        ..write('"kind": "')
-        ..write(kind)
-        ..write('"');
-    if (type != null) {
-      buffer.write(',\n');
-      indented
-          ..write('"type": "')
-          ..write(type)
-          ..write('"');
-    }
-    if (serializeMembers != null) {
-      buffer.write(',\n');
-      indented.write('"members": [');
-      indentationLevel++;
-      serializeMembers();
-      indentationLevel--;
-      buffer.write('\n');
-      indented.write(']');
-    }
-    if (!omitEnclosing) {
-      buffer.write(',\n');
-      indented.write('"enclosing": ');
-      if (serializeEnclosing != null) {
-        serializeEnclosing();
-      } else {
-        element.enclosingElement.accept(this, null);
-      }
-    }
-    indentationLevel--;
-    buffer.write('\n');
-    indented.write('}');
-  }
-
-  List<Element> localMembersSorted(ScopeContainerElement element) {
-    List<Element> result = <Element>[];
-    element.forEachLocalMember((Element member) {
-      result.add(member);
-    });
-    return sortElements(result);
-  }
-
-  List<Element> sortElements(Iterable<Element> elements) {
-    List<Element> result = new List<Element>.from(elements);
-    if (sortMembers) {
-      result.sort((Element a, Element b) => a.name.compareTo(b.name));
-    }
-    return result;
-  }
-}
-
-modelx.ScopeX localScope(modelx.LibraryElementX element) => element.localScope;
-
-modelx.ImportScope importScope(modelx.LibraryElementX element) {
-  return element.importScope;
-}
diff --git a/site/try/project_server.dart b/site/try/project_server.dart
deleted file mode 100644
index 08c5d56..0000000
--- a/site/try/project_server.dart
+++ /dev/null
@@ -1,455 +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 trydart.projectServer;
-
-import 'dart:io';
-
-import 'dart:async' show
-    Future,
-    Stream;
-
-import 'dart:convert' show
-    HtmlEscape,
-    JSON,
-    UTF8;
-
-class WatchHandler {
-  final WebSocket socket;
-
-  final Set<String> watchedFiles;
-
-  static final Set<WatchHandler> handlers = new Set<WatchHandler>();
-
-  static const Map<int, String> fsEventNames = const <int, String>{
-    FileSystemEvent.CREATE: 'create',
-    FileSystemEvent.DELETE: 'delete',
-    FileSystemEvent.MODIFY: 'modify',
-    FileSystemEvent.MOVE: 'move',
-  };
-
-  WatchHandler(this.socket, Iterable<String> watchedFiles)
-      : this.watchedFiles = watchedFiles.toSet();
-
-  handleFileSystemEvent(FileSystemEvent event) {
-    if (event.isDirectory) return;
-    String type = fsEventNames[event.type];
-    if (type == null) type = 'unknown';
-    String path = new Uri.file(event.path).pathSegments.last;
-    shouldIgnore(type, path).then((bool ignored) {
-      if (ignored) return;
-      socket.add(JSON.encode({type: [path]}));
-    });
-  }
-
-  Future<bool> shouldIgnore(String type, String path) {
-    switch (type) {
-      case 'create':
-        return new Future<bool>.value(!watchedFiles.contains(path));
-      case 'delete':
-        return Conversation.listProjectFiles().then((List<String> files) {
-          watchedFiles
-              ..retainAll(files)
-              ..addAll(files);
-          return watchedFiles.contains(path);
-        });
-      case 'modify':
-        return new Future<bool>.value(false);
-      default:
-        print('Unhandled fs-event for $path ($type).');
-        return new Future<bool>.value(true);
-    }
-  }
-
-  onData(_) {
-    // TODO(ahe): Move POST code here?
-  }
-
-  onDone() {
-    handlers.remove(this);
-  }
-
-  static handleWebSocket(WebSocket socket) {
-    Conversation.ensureProjectWatcher();
-    Conversation.listProjectFiles().then((List<String> files) {
-      socket.add(JSON.encode({'create': files}));
-      WatchHandler handler = new WatchHandler(socket, files);
-      handlers.add(handler);
-      socket.listen(
-          handler.onData, cancelOnError: true, onDone: handler.onDone);
-    });
-  }
-
-  static onFileSystemEvent(FileSystemEvent event) {
-    for (WatchHandler handler in handlers) {
-      handler.handleFileSystemEvent(event);
-    }
-  }
-}
-
-/// Represents a "project" command. These commands are accessed from the URL
-/// "/project?name".
-class ProjectCommand {
-  final String name;
-
-  /// For each query parameter, this map describes rules for validating them.
-  final Map<String, String> rules;
-
-  final Function handle;
-
-  const ProjectCommand(this.name, this.rules, this.handle);
-}
-
-class Conversation {
-  HttpRequest request;
-  HttpResponse response;
-
-  static const String PROJECT_PATH = '/project';
-
-  static const String PACKAGES_PATH = '/packages';
-
-  static const String CONTENT_TYPE = HttpHeaders.CONTENT_TYPE;
-
-  static const String GIT_TAG = 'try_dart_backup';
-
-  static const String COMMIT_MESSAGE = """
-Automated backup.
-
-It is safe to delete tag '$GIT_TAG' if you don't need the backup.""";
-
-  static Uri documentRoot = Uri.base;
-
-  static Uri projectRoot = Uri.base.resolve('site/try/src/');
-
-  static Uri packageRoot = Uri.base.resolve('sdk/lib/_internal/');
-
-  static const List<ProjectCommand> COMMANDS = const <ProjectCommand>[
-      const ProjectCommand('list', const {'list': null}, handleProjectList),
-  ];
-
-  static Stream<FileSystemEvent> projectChanges;
-
-  static final Map<String, String> gitEnv = computeGitEnv();
-
-  Conversation(this.request, this.response);
-
-  onClosed(_) {
-    if (response.statusCode == HttpStatus.OK) return;
-    print('Request for ${request.uri} ${response.statusCode}');
-  }
-
-  notFound(path) {
-    response.statusCode = HttpStatus.NOT_FOUND;
-    response.write(htmlInfo('Not Found',
-                            'The file "$path" could not be found.'));
-    response.close();
-  }
-
-  badRequest(String problem) {
-    response.statusCode = HttpStatus.BAD_REQUEST;
-    response.write(htmlInfo("Bad request",
-                            "Bad request '${request.uri}': $problem"));
-    response.close();
-  }
-
-  internalError(error, stack) {
-    print(error);
-    if (stack != null) print(stack);
-    response.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
-    response.write(htmlInfo("Internal Server Error",
-                            "Internal Server Error: $error\n$stack"));
-    response.close();
-  }
-
-  bool validate(Map<String, String> parameters, Map<String, String> rules) {
-    Iterable<String> problems = rules.keys
-        .where((name) => !parameters.containsKey(name))
-        .map((name) => "Missing parameter: '$name'.");
-    if (!problems.isEmpty) {
-      badRequest(problems.first);
-      return false;
-    }
-    Set extra = new Set.from(parameters.keys)..removeAll(rules.keys);
-    if (extra.isEmpty) return true;
-    String extraString = (extra.toList()..sort()).join("', '");
-    badRequest("Extra parameters: '$extraString'.");
-    return false;
-  }
-
-  static Future<List<String>> listProjectFiles() {
-    String nativeDir = projectRoot.toFilePath();
-    Directory dir = new Directory(nativeDir);
-    var future = dir.list(recursive: true, followLinks: false).toList();
-    return future.then((List<FileSystemEntity> entries) {
-      return entries
-          .map((e) => e.path)
-          .where((p) => p.endsWith('.dart') && p.startsWith(nativeDir))
-          .map((p) => p.substring(nativeDir.length))
-          .map((p) => new Uri.file(p).path).toList();
-    });
-  }
-
-  static handleProjectList(Conversation self) {
-    listProjectFiles().then((List<String> files) {
-      self.response
-          ..write(JSON.encode(files))
-          ..close();
-    });
-  }
-
-  handleProjectRequest() {
-    Map<String, String> parameters = request.uri.queryParameters;
-    for (ProjectCommand command in COMMANDS) {
-      if (parameters.containsKey(command.name)) {
-        if (validate(parameters, command.rules)) {
-          (command.handle)(this);
-        }
-        return;
-      }
-    }
-    String commands = COMMANDS.map((c) => c.name).join("', '");
-    badRequest("Valid commands are: '$commands'");
-  }
-
-  handleSocket() {
-    if (request.uri.path == '/ws/watch') {
-      WebSocketTransformer.upgrade(request).then(WatchHandler.handleWebSocket);
-    } else {
-      response.done
-          .then(onClosed)
-          .catchError(onError);
-      notFound(request.uri.path);
-    }
-  }
-
-  handle() {
-    response.done
-      .then(onClosed)
-      .catchError(onError);
-
-    Uri uri = request.uri;
-    if (uri.path == PROJECT_PATH) {
-      return handleProjectRequest();
-    }
-    if (uri.path.endsWith('/')) {
-      uri = uri.resolve('index.html');
-    }
-    if (uri.path == '/css/fonts/fontawesome-webfont.woff') {
-      uri = uri.resolve('/fontawesome-webfont.woff');
-    }
-    if (uri.path.contains('..') || uri.path.contains('%')) {
-      return notFound(uri.path);
-    }
-    String path = uri.path;
-    Uri root = documentRoot;
-    String dartType = 'application/dart';
-    if (path.startsWith('/project/packages/')) {
-      root = packageRoot;
-      path = path.substring('/project/packages'.length);
-    } else if (path.startsWith('${PROJECT_PATH}/')) {
-      root = projectRoot;
-      path = path.substring(PROJECT_PATH.length);
-      dartType = 'text/plain';
-    } else if (path.startsWith('${PACKAGES_PATH}/')) {
-      root = packageRoot;
-      path = path.substring(PACKAGES_PATH.length);
-    }
-
-    String filePath = root.resolve('.$path').toFilePath();
-    switch (request.method) {
-      case 'GET':
-        return handleGet(filePath, dartType);
-      case 'POST':
-        return handlePost(filePath);
-      default:
-        String method = const HtmlEscape().convert(request.method);
-        return badRequest("Unsupported method: '$method'");
-    }
-  }
-
-  void handleGet(String path, String dartType) {
-    var f = new File(path);
-    f.exists().then((bool exists) {
-      if (!exists) return notFound(request.uri);
-      if (path.endsWith('.html')) {
-        response.headers.set(CONTENT_TYPE, 'text/html');
-      } else if (path.endsWith('.dart')) {
-        response.headers.set(CONTENT_TYPE, dartType);
-      } else if (path.endsWith('.js')) {
-        response.headers.set(CONTENT_TYPE, 'application/javascript');
-      } else if (path.endsWith('.ico')) {
-        response.headers.set(CONTENT_TYPE, 'image/x-icon');
-      } else if (path.endsWith('.appcache')) {
-        response.headers.set(CONTENT_TYPE, 'text/cache-manifest');
-      }
-      f.openRead().pipe(response).catchError(onError);
-    });
-  }
-
-  handlePost(String path) {
-    // The data is sent using a dart:html HttpRequest (aka XMLHttpRequest).
-    // According to http://xhr.spec.whatwg.org/, strings are always encoded as
-    // UTF-8.
-    request.transform(UTF8.decoder).join().then((String data) {
-      // The rest of this method is synchronous. This guarantees that we don't
-      // make conflicting git changes in response to multiple POST requests.
-      try {
-        backup(path);
-      } catch (e, stack) {
-        return internalError(e, stack);
-      }
-
-      new File(path).writeAsStringSync(data);
-
-      response
-          ..statusCode = HttpStatus.OK
-          ..close();
-    });
-  }
-
-  // Back up the file [path] using git.
-  static void backup(String path) {
-    // Reset the index.
-    git('read-tree', ['HEAD']);
-
-    // Save modifications in index.
-    git('update-index', ['--add', path]);
-
-    // If the file isn't modified, don't back it up.
-    if (checkGit('diff', ['--cached', '--quiet'])) return;
-
-    String localModifications = git('write-tree');
-
-    String tag = 'refs/tags/$GIT_TAG';
-    var arguments = ['-m', COMMIT_MESSAGE, localModifications];
-
-    if (checkGit('rev-parse',  ['-q', '--verify', tag])) {
-      // The tag already exists.
-
-      if (checkGit('diff-tree', ['--quiet', localModifications, tag])) {
-        // localModifications are identical to the last backup.
-        return;
-      }
-
-      // Use the tag as a parent.
-      arguments = ['-p', tag]..addAll(arguments);
-
-      String headCommit = git('rev-parse', ['HEAD']);
-      String mergeBase = git('merge-base', [tag, 'HEAD']);
-      if (headCommit != mergeBase) {
-        arguments = ['-p', 'HEAD']..addAll(arguments);
-      }
-    } else {
-      arguments = ['-p', 'HEAD']..addAll(arguments);
-    }
-
-    // Commit the local modifcations.
-    String commit = git('commit-tree', arguments);
-
-    // Create or update the tag.
-    git('tag', ['-f', GIT_TAG, commit]);
-  }
-
-  static String git(String command,
-                    [List<String> arguments = const <String> []]) {
-    ProcessResult result =
-        run('git', <String>[command]..addAll(arguments), gitEnv);
-    if (result.exitCode != 0) {
-      throw 'git error: ${result.stdout}\n${result.stderr}';
-    }
-    return result.stdout.trim();
-  }
-
-  static bool checkGit(String command,
-                       [List<String> arguments = const <String> []]) {
-    return
-        run('git', <String>[command]..addAll(arguments), gitEnv).exitCode == 0;
-  }
-
-  static Map<String, String> computeGitEnv() {
-    ProcessResult result = run('git', ['rev-parse', '--git-dir'], null);
-    if (result.exitCode != 0) {
-      throw 'git error: ${result.stdout}\n${result.stderr}';
-    }
-    String gitDir = result.stdout.trim();
-    return <String, String>{ 'GIT_INDEX_FILE': '$gitDir/try_dart_backup' };
-  }
-
-  static ProcessResult run(String executable,
-                           List<String> arguments,
-                           Map<String, String> environment) {
-    // print('Running $executable ${arguments.join(" ")}');
-    return Process.runSync(executable, arguments, environment: environment);
-  }
-
-  static onRequest(HttpRequest request) {
-    Conversation conversation = new Conversation(request, request.response);
-    if (WebSocketTransformer.isUpgradeRequest(request)) {
-      conversation.handleSocket();
-    } else {
-      conversation.handle();
-    }
-  }
-
-  static ensureProjectWatcher() {
-    if (projectChanges != null) return;
-    String nativeDir = projectRoot.toFilePath();
-    Directory dir = new Directory(nativeDir);
-    projectChanges = dir.watch();
-    projectChanges.listen(WatchHandler.onFileSystemEvent);
-  }
-
-  static onError(error) {
-    if (error is HttpException) {
-      print('Error: ${error.message}');
-    } else {
-      print('Error: ${error}');
-    }
-  }
-
-  String htmlInfo(String title, String text) {
-    // No script injection, please.
-    title = const HtmlEscape().convert(title);
-    text = const HtmlEscape().convert(text);
-    return """
-<!DOCTYPE html>
-<html lang='en'>
-<head>
-<title>$title</title>
-</head>
-<body>
-<h1>$title</h1>
-<p style='white-space:pre'>$text</p>
-</body>
-</html>
-""";
-  }
-}
-
-main(List<String> arguments) {
-  if (arguments.length > 0) {
-    Conversation.documentRoot = Uri.base.resolve(arguments[0]);
-  }
-  var host = '127.0.0.1';
-  if (arguments.length > 1) {
-    host = arguments[1];
-  }
-  int port = 0;
-  if (arguments.length > 2) {
-    port = int.parse(arguments[2]);
-  }
-  if (arguments.length > 3) {
-    Conversation.projectRoot = Uri.base.resolve(arguments[3]);
-  }
-  if (arguments.length > 4) {
-    Conversation.packageRoot = Uri.base.resolve(arguments[4]);
-  }
-  HttpServer.bind(host, port).then((HttpServer server) {
-    print('HTTP server started on http://$host:${server.port}/');
-    server.listen(Conversation.onRequest, onError: Conversation.onError);
-  }).catchError((e) {
-    print("HttpServer.bind error: $e");
-    exit(1);
-  });
-}
diff --git a/site/try/src/Makefile b/site/try/src/Makefile
deleted file mode 100644
index d114353..0000000
--- a/site/try/src/Makefile
+++ /dev/null
@@ -1,18 +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.
-
-SDK_DIR=../../../xcodebuild/ReleaseIA32/dart-sdk
-PACKAGE_ROOT=../../../xcodebuild/ReleaseIA32/packages/
-
-all:
-	$(SDK_DIR)/bin/dartanalyzer -p $(PACKAGE_ROOT) \
-	--package-warnings --machine leap.dart 2>&1 \
-	| grep -v DEPRECATED_MEMBER_USE \
-	| sed -e "s,$(PWD)/,," \
-	| awk -F'|' '{print $$4 ":" $$5 ":" $$6 ": [" $$3 "] " $$8 }'
-	$(SDK_DIR)/bin/dartanalyzer -p $(PACKAGE_ROOT) \
-	--package-warnings --machine compiler_isolate.dart 2>&1 \
-	| grep -v DEPRECATED_MEMBER_USE \
-	| sed -e "s,$(PWD)/,," \
-	| awk -F'|' '{print $$4 ":" $$5 ":" $$6 ": [" $$3 "] " $$8 }'
diff --git a/site/try/src/cache.dart b/site/try/src/cache.dart
deleted file mode 100644
index a61ec0a..0000000
--- a/site/try/src/cache.dart
+++ /dev/null
@@ -1,96 +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 trydart.cache;
-
-import 'dart:async' show
-    Timer;
-
-import 'dart:html' show
-    AnchorElement,
-    ApplicationCache,
-    Event,
-    MeterElement,
-    ProgressEvent,
-    window;
-
-import 'ui.dart' show
-    cacheStatusElement;
-
-/// Called when the window has finished loading.
-void onLoad(Event event) {
-  if (!ApplicationCache.supported) return;
-  window.applicationCache.onUpdateReady.listen(updateCacheStatus);
-  window.applicationCache.onCached.listen(updateCacheStatus);
-  window.applicationCache.onChecking.listen(updateCacheStatus);
-  window.applicationCache.onDownloading.listen(updateCacheStatus);
-  window.applicationCache.onError.listen(updateCacheStatus);
-  window.applicationCache.onNoUpdate.listen(updateCacheStatus);
-  window.applicationCache.onObsolete.listen(updateCacheStatus);
-  window.applicationCache.onProgress.listen(onCacheProgress);
-}
-
-void onCacheProgress(Event event) {
-  if (event is ProgressEvent) {
-    // Firefox doesn't fire a ProgressEvent on cache progress.  Just a plain
-    // Event with type == "progress".
-    if (event.lengthComputable) {
-      updateCacheStatusFromEvent(event);
-      return;
-    }
-  }
-  updateCacheStatus(null);
-}
-
-void updateCacheStatusFromEvent(ProgressEvent event) {
-  cacheStatusElement.nodes.clear();
-  cacheStatusElement.appendText('Downloading SDK ');
-  var progress = '${event.loaded} of ${event.total}';
-  if (MeterElement.supported) {
-    cacheStatusElement.append(
-        new MeterElement()
-            ..appendText(progress)
-            ..min = 0
-            ..max = event.total
-            ..value = event.loaded);
-  } else {
-    cacheStatusElement.appendText(progress);
-  }
-}
-
-String cacheStatus() {
-  if (!ApplicationCache.supported) return 'offline not supported';
-  int status = window.applicationCache.status;
-  if (status == ApplicationCache.CHECKING) return 'Checking for updates';
-  if (status == ApplicationCache.DOWNLOADING) return 'Downloading SDK';
-  if (status == ApplicationCache.IDLE) return 'Try Dart! works offline';
-  if (status == ApplicationCache.OBSOLETE) return 'OBSOLETE';
-  if (status == ApplicationCache.UNCACHED) return 'offline not available';
-  if (status == ApplicationCache.UPDATEREADY) return 'SDK downloaded';
-  return '?';
-}
-
-void updateCacheStatus(_) {
-  cacheStatusElement.nodes.clear();
-  int status = window.applicationCache.status;
-  if (status == ApplicationCache.UPDATEREADY) {
-    cacheStatusElement.appendText('New version of Try Dart! ready: ');
-    cacheStatusElement.append(
-        new AnchorElement(href: '#')
-            ..appendText('Load')
-            ..onClick.listen((event) {
-              event.preventDefault();
-              window.applicationCache.swapCache();
-              window.location.reload();
-            }));
-  } else if (status == ApplicationCache.IDLE) {
-    cacheStatusElement.appendText(cacheStatus());
-    cacheStatusElement.classes.add('offlineyay');
-    new Timer(const Duration(seconds: 10), () {
-      cacheStatusElement.style.display = 'none';
-    });
-  } else {
-    cacheStatusElement.appendText(cacheStatus());
-  }
-}
diff --git a/site/try/src/compilation.dart b/site/try/src/compilation.dart
deleted file mode 100644
index b234a2a..0000000
--- a/site/try/src/compilation.dart
+++ /dev/null
@@ -1,269 +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 trydart.compilation;
-
-import 'dart:html' show
-    Blob,
-    Element,
-    ErrorEvent,
-    IFrameElement,
-    MessageEvent,
-    Url,
-    Worker,
-    window;
-
-import 'dart:isolate' show
-    ReceivePort,
-    SendPort;
-
-import 'editor.dart' show
-    addDiagnostic,
-    isMalformedInput;
-
-import 'run.dart' show
-    makeOutputFrame;
-
-import 'ui.dart' show
-    buildButton,
-    interaction,
-    outputDiv,
-    outputFrame;
-
-import 'settings.dart' show
-    alwaysRunInWorker,
-    alwaysRunInIframe,
-    communicateViaBlobs,
-    incrementalCompilation,
-    minified,
-    onlyAnalyze,
-    verboseCompiler;
-
-import 'iframe_error_handler.dart' show
-    errorStream;
-
-/**
- * Scheme for recognizing files stored in memory.
- *
- * From http://tools.ietf.org/html/bcp35#section-2.8:
- *
- * Organizations that desire a private name space for URI scheme names
- * are encouraged to use a prefix based on their domain name, expressed
- * in reverse order.  For example, a URI scheme name of com-example-info
- * might be registered by the vendor that owns the example.com domain
- * name.
- */
-const String PRIVATE_SCHEME = 'org-trydart';
-
-SendPort compilerPort;
-
-// TODO(ahe): Remove this.
-String get currentSource => window.localStorage['currentSource'];
-
-void set currentSource(String text) {
-  window.localStorage['currentSource'] = text;
-}
-
-bool startCompilation() {
-  if (!CompilationProcess.shouldStartCompilation()) return false;
-  new CompilationProcess(currentSource, outputDiv).start();
-  return true;
-}
-
-class CompilationProcess {
-  final String source;
-  final Element console;
-  final ReceivePort receivePort = new ReceivePort();
-  final Set<String> seenMessages = new Set<String>();
-  bool isDone = false;
-  bool usesDartHtml = false;
-  Worker worker;
-  List<String> objectUrls = <String>[];
-  String firstError;
-
-  static CompilationProcess current;
-
-  CompilationProcess(this.source, this.console);
-
-  static bool shouldStartCompilation() {
-    if (compilerPort == null) return false;
-    if (isMalformedInput) return false;
-    if (current != null) return current.isDone;
-    return true;
-  }
-
-  void start() {
-    if (!shouldStartCompilation()) {
-      receivePort.close();
-      return;
-    }
-    if (current != null) current.dispose();
-    current = this;
-    var options = [
-        '--analyze-main',
-        '--no-source-maps',
-    ];
-    if (verboseCompiler) options.add('--verbose');
-    if (minified) options.add('--minify');
-    if (onlyAnalyze) options.add('--analyze-only');
-    if (incrementalCompilation.value) {
-      options.addAll(['--incremental-support', '--disable-type-inference']);
-    }
-    interaction.compilationStarting();
-    compilerPort.send([['options', options], receivePort.sendPort]);
-    compilerPort.send([['communicateViaBlobs', communicateViaBlobs.value],
-                       receivePort.sendPort]);
-    receivePort.listen(onMessage);
-    compilerPort.send([source, receivePort.sendPort]);
-  }
-
-  void dispose() {
-    if (worker != null) worker.terminate();
-    objectUrls.forEach(Url.revokeObjectUrl);
-  }
-
-  onMessage(message) {
-    String kind = message is String ? message : message[0];
-    var data = (message is List && message.length == 2) ? message[1] : null;
-    switch (kind) {
-      case 'done': return onDone(data);
-      case 'url': return onUrl(data);
-      case 'code': return onCode(data);
-      case 'diagnostic': return onDiagnostic(data);
-      case 'crash': return onCrash(data);
-      case 'failed': return onFail(data);
-      case 'dart:html': return onDartHtml(data);
-      default:
-        throw ['Unknown message kind', message];
-    }
-  }
-
-  onDartHtml(_) {
-    usesDartHtml = true;
-  }
-
-  onFail(_) {
-    interaction.onCompilationFailed(firstError);
-  }
-
-  onDone(_) {
-    interaction.onCompilationDone();
-    isDone = true;
-    receivePort.close();
-  }
-
-  // This is called in browsers that support creating Object URLs in a
-  // web worker.  For example, Chrome and Firefox 21.
-  onUrl(String url) {
-    objectUrls.add(url);
-    String wrapper = '''
-// Fool isolate_helper.dart so it does not think this is an isolate.
-var window = self;
-function dartPrint(msg) {
-  self.postMessage(msg);
-};
-self.importScripts("$url");
-''';
-    var wrapperUrl =
-        Url.createObjectUrl(new Blob([wrapper], 'application/javascript'));
-    objectUrls.add(wrapperUrl);
-
-    run(wrapperUrl, () => makeOutputFrame(url));
-  }
-
-  // This is called in browsers that do not support creating Object
-  // URLs in a web worker.  For example, Safari and Firefox < 21.
-  onCode(String code) {
-    IFrameElement makeIframe() {
-      // The obvious thing would be to call [makeOutputFrame], but
-      // Safari doesn't support access to Object URLs in an iframe.
-
-      IFrameElement frame = new IFrameElement()
-          ..src = 'iframe.html'
-          ..style.width = '100%'
-          ..style.height = '0px';
-      frame.onLoad.listen((_) {
-        frame.contentWindow.postMessage(['source', code], '*');
-      });
-      return frame;
-    }
-
-    String codeWithPrint =
-        '$code\n'
-        'function dartPrint(msg) { postMessage(msg); }\n';
-    var url =
-        Url.createObjectUrl(
-            new Blob([codeWithPrint], 'application/javascript'));
-    objectUrls.add(url);
-
-    run(url, makeIframe);
-  }
-
-  void run(String url, IFrameElement makeIframe()) {
-    void retryInIframe() {
-      interaction.aboutToRun();
-      var frame = makeIframe();
-      frame.style
-          ..visibility = 'hidden'
-          ..position = 'absolute';
-      outputFrame.parent.insertBefore(frame, outputFrame);
-      outputFrame = frame;
-      errorStream(frame).listen(interaction.onIframeError);
-    }
-    void onError(String errorMessage) {
-      interaction.consolePrintLine(errorMessage);
-      console
-          ..append(buildButton('Try in iframe', (_) => retryInIframe()))
-          ..appendText('\n');
-    }
-    interaction.aboutToRun();
-    if (alwaysRunInIframe.value ||
-        usesDartHtml && !alwaysRunInWorker) {
-      retryInIframe();
-    } else {
-      runInWorker(url, onError);
-    }
-  }
-
-  void runInWorker(String url, void onError(String errorMessage)) {
-    worker = new Worker(url)
-        ..onMessage.listen((MessageEvent event) {
-          interaction.consolePrintLine(event.data);
-        })
-        ..onError.listen((ErrorEvent event) {
-          worker.terminate();
-          worker = null;
-          onError(event.message);
-        });
-  }
-
-  onDiagnostic(Map<String, dynamic> diagnostic) {
-    if (currentSource != source) return;
-    String kind = diagnostic['kind'];
-    String message = diagnostic['message'];
-    if (kind == 'verbose info') {
-      interaction.verboseCompilerMessage(message);
-      return;
-    }
-    if (kind == 'error' && firstError == null) {
-      firstError = message;
-    }
-    String uri = diagnostic['uri'];
-    if (uri != '${PRIVATE_SCHEME}:/main.dart') {
-      interaction.consolePrintLine('$uri: [$kind] $message');
-      return;
-    }
-    int begin = diagnostic['begin'];
-    int end = diagnostic['end'];
-    if (begin == null) return;
-    if (seenMessages.add('$begin:$end: [$kind] $message')) {
-      // Guard against duplicated messages.
-      addDiagnostic(kind, message, begin, end);
-    }
-  }
-
-  onCrash(data) {
-    interaction.onCompilerCrash(data);
-  }
-}
diff --git a/site/try/src/compilation_unit.dart b/site/try/src/compilation_unit.dart
deleted file mode 100644
index 728db2f..0000000
--- a/site/try/src/compilation_unit.dart
+++ /dev/null
@@ -1,38 +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 trydart.compilationUnit;
-
-import 'dart:async' show
-    Stream,
-    StreamController;
-
-class CompilationUnitData {
-  final String name;
-  String content;
-
-  CompilationUnitData(this.name, this.content);
-}
-
-class CompilationUnit extends CompilationUnitData {
-  // Extending [CompilationUnitData] allows this class to hide the storage
-  // allocated for [content] without introducing new names. The conventional
-  // way of acheiving this is to introduce a library-private field, but library
-  // privacy isn't without problems.
-
-  static StreamController<CompilationUnit> controller =
-      new StreamController<CompilationUnit>(sync: false);
-
-  static Stream<CompilationUnit> get onChanged => controller.stream;
-
-  CompilationUnit(String name, String content)
-      : super(name, content);
-
-  void set content(String newContent) {
-    if (content != newContent) {
-      super.content = newContent;
-      controller.add(this);
-    }
-  }
-}
diff --git a/site/try/src/compiler_isolate.dart b/site/try/src/compiler_isolate.dart
deleted file mode 100644
index ea82650..0000000
--- a/site/try/src/compiler_isolate.dart
+++ /dev/null
@@ -1,180 +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 compiler_isolate;
-
-import 'dart:async';
-import 'dart:html';
-import 'dart:isolate';
-import 'dart:convert' show JSON;
-
-import 'compilation.dart' show PRIVATE_SCHEME;
-
-import 'package:compiler/compiler.dart' as compiler;
-
-import 'package:compiler/src/old_to_new_api.dart' show
-    LegacyCompilerDiagnostics, LegacyCompilerInput;
-
-import 'package:dart2js_incremental/dart2js_incremental.dart' show
-    reuseCompiler, OutputProvider;
-
-import 'package:compiler/src/compiler.dart' show
-    Compiler;
-
-const bool THROW_ON_ERROR = false;
-
-final cachedSources = new Map<Uri, Future<String>>();
-
-Uri sdkLocation;
-List options = [];
-
-var communicateViaBlobs;
-
-var cachedCompiler;
-
-void notifyDartHtml(SendPort port) {
-  // Notify the controlling isolate (Try Dart UI) that the program imports
-  // dart:html. This is used to determine how to run the program: in an iframe
-  // or in a worker.
-  port.send('dart:html');
-}
-
-compile(source, SendPort replyTo) {
-  if (sdkLocation == null) {
-    // The first message received gives us the URI of this web app.
-    if (source.endsWith('/sdk.json')) {
-      var request = new HttpRequest();
-      request.open('GET', source, async: false);
-      request.send(null);
-      if (request.status != 200) {
-        throw 'SDK not found at $source';
-      }
-      sdkLocation = Uri.parse('sdk:/sdk/');
-      JSON.decode(request.responseText).forEach((file, content) {
-        cachedSources[Uri.parse(file)] = new Future<String>.value(content);
-      });
-    } else {
-      sdkLocation = Uri.parse(source);
-    }
-    replyTo.send(null);
-    return;
-  }
-  if (source is List) {
-    String messageType = (source.length > 0) ? source[0] : null;
-    var data = (source.length > 1) ? source[1] : null;
-    if (messageType == 'options') {
-      options = data as List;
-    } if (messageType == 'communicateViaBlobs') {
-      communicateViaBlobs = data as bool;
-    }
-    return;
-  }
-  int charactersRead = 0;
-  Future<String> inputProvider(Uri uri) {
-    Future<String> future;
-    if (uri.scheme == 'sdk') {
-      if (uri.path.endsWith('/lib/html/dart2js/html_dart2js.dart')) {
-        notifyDartHtml(replyTo);
-      }
-      future = cachedSources[uri];
-    } else if (uri.scheme == 'http' || uri.scheme == 'https') {
-      future =
-          cachedSources.putIfAbsent(uri, () => HttpRequest.getString('$uri'));
-    } else if ('$uri' == '$PRIVATE_SCHEME:/main.dart') {
-      future = new Future<String>.value(source);
-    } else if (uri.scheme == PRIVATE_SCHEME) {
-      future = HttpRequest.getString('project${uri.path}');
-    }
-    if (future == null) {
-      future = new Future<String>.error('$uri: Not found');
-    }
-    return future.then((String value) {
-      charactersRead += value.length;
-      return value;
-    }).catchError((Event event) {
-      var target = event.target;
-      if (target is HttpRequest) {
-        throw '$uri: ${target.statusText}';
-      } else {
-        throw event;
-      }
-    }, test: (error) => error is Event);
-  }
-  void handler(Uri uri, int begin, int end,
-               String message, compiler.Diagnostic kind) {
-    replyTo.send(['diagnostic', { 'uri': '$uri',
-                                  'begin': begin,
-                                  'end': end,
-                                  'message': message,
-                                  'kind': kind.name }]);
-    if (THROW_ON_ERROR && kind == compiler.Diagnostic.ERROR) {
-      throw new Exception('Throw on error');
-    }
-  }
-  Stopwatch compilationTimer = new Stopwatch()..start();
-  OutputProvider outputProvider = new OutputProvider();
-  reuseCompiler(
-      diagnosticHandler: new LegacyCompilerDiagnostics(handler),
-      inputProvider: new LegacyCompilerInput(inputProvider),
-      outputProvider: outputProvider,
-      options: options,
-      cachedCompiler: cachedCompiler,
-      libraryRoot: sdkLocation,
-      packageRoot: Uri.base.resolve('/packages/'),
-      packagesAreImmutable: true).then((Compiler newCompiler) {
-    cachedCompiler = newCompiler;
-    return cachedCompiler.run(Uri.parse('$PRIVATE_SCHEME:/main.dart'));
-  }).then((success) {
-    compilationTimer.stop();
-    print('Compilation took ${compilationTimer.elapsed}');
-    if (cachedCompiler.libraryLoader
-            .lookupLibrary(Uri.parse('dart:html')) != null) {
-      notifyDartHtml(replyTo);
-    }
-    String js = outputProvider['.js'];
-    if (js == null) {
-      if (!options.contains('--analyze-only')) replyTo.send('failed');
-    } else {
-      var url;
-      handler(null, 0, 0,
-              'Compiled ${source.length}/${charactersRead} characters Dart'
-              ' -> ${js.length} characters.',
-              compiler.Diagnostic.VERBOSE_INFO);
-      if (communicateViaBlobs) {
-        try {
-          // At least Safari and Firefox do not support creating an
-          // object URL from a web worker.  MDN claims that it will be
-          // supported in Firefox 21.
-          url = Url.createObjectUrl(new Blob([js], 'application/javascript'));
-        } catch (_) {
-          // Ignored.
-        }
-      } else  {
-        url = null;
-      }
-      if (url != null) {
-        replyTo.send(['url', url]);
-      } else {
-        replyTo.send(['code', js]);
-      }
-    }
-  }).catchError((e, trace) {
-    replyTo.send(['crash', '$e, $trace']);
-  }).whenComplete(() {
-    replyTo.send('done');
-  });
-}
-
-void main(List<String> arguments, SendPort port) {
-  ReceivePort replyTo = new ReceivePort();
-  port.send(replyTo.sendPort);
-  replyTo.listen((message) {
-    try {
-      List list = message as List;
-      compile(list[0], list[1]);
-    } catch (exception, stack) {
-      port.send('$exception\n$stack');
-    }
-  });
-}
diff --git a/site/try/src/decoration.dart b/site/try/src/decoration.dart
deleted file mode 100644
index 994a3dd..0000000
--- a/site/try/src/decoration.dart
+++ /dev/null
@@ -1,120 +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 trydart.decoration;
-
-import 'dart:html';
-
-import 'shadow_root.dart' show
-    setShadowRoot;
-
-import 'editor.dart' show
-    diagnostic;
-
-class Decoration {
-  final String color;
-  final bool bold;
-  final bool italic;
-  final bool stress;
-  final bool important;
-
-  const Decoration({this.color: '#000000',
-                    this.bold: false,
-                    this.italic: false,
-                    this.stress: false,
-                    this.important: false});
-
-  Element applyTo(text) {
-    if (text is String) {
-      text = new Text(text);
-    }
-    if (bold) {
-      text = new Element.tag('b')..append(text);
-    }
-    if (italic) {
-      text = new Element.tag('i')..append(text);
-    }
-    if (stress) {
-      text = new Element.tag('em')..append(text);
-    }
-    if (important) {
-      text = new Element.tag('strong')..append(text);
-    }
-    return new SpanElement()..append(text)..style.color = color;
-  }
-}
-
-class DiagnosticDecoration extends Decoration {
-  final String kind;
-  final String message;
-
-  const DiagnosticDecoration(
-      this.kind,
-      this.message,
-      {String color: '#000000',
-       bool bold: false,
-       bool italic: false,
-       bool stress: false,
-       bool important: false})
-      : super(color: color, bold: bold, italic: italic, stress: stress,
-              important: important);
-
-  Element applyTo(text) {
-    var element = super.applyTo(text);
-    var nodes = new List.from(element.nodes);
-    element.nodes.clear();
-    var tip = new Text('');
-    if (kind == 'error') {
-      tip = error(message);
-    }
-    return element..append(diagnostic(nodes, tip));
-  }
-}
-
-createAlert(text, [String cls]) {
-  var classes = ['alert'];
-  if (cls != null) {
-    classes.add(cls);
-  }
-  SpanElement result = new SpanElement()
-      ..classes.addAll(classes)
-      ..style.fontWeight = 'normal';
-  setShadowRoot(result, text);
-  return result;
-}
-
-info(text) => createAlert(text, 'alert-info');
-
-error(text) => createAlert(text, 'alert-error');
-
-warning(text) => createAlert(text);
-
-class CodeCompletionDecoration extends Decoration {
-  const CodeCompletionDecoration(
-      {String color: '#000000',
-       bool bold: false,
-       bool italic: false,
-       bool stress: false,
-       bool important: false})
-      : super(color: color, bold: bold, italic: italic, stress: stress,
-              important: important);
-
-  static from(Decoration decoration) {
-    return new CodeCompletionDecoration(
-        color: decoration.color,
-        bold: decoration.bold,
-        italic: decoration.italic,
-        stress: decoration.stress,
-        important: decoration.important);
-  }
-
-  Element applyTo(text) {
-    var codeCompletion = new DivElement()
-        ..contentEditable = 'false'
-        ..classes.add('dart-code-completion');
-    return super.applyTo(text)
-        ..classes.add('dart-code-completion-holder')
-        ..nodes.add(codeCompletion);
-  }
-}
diff --git a/site/try/src/editor.dart b/site/try/src/editor.dart
deleted file mode 100644
index abe3f3c..0000000
--- a/site/try/src/editor.dart
+++ /dev/null
@@ -1,280 +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 trydart.editor;
-
-import 'dart:html';
-
-import 'package:compiler/src/scanner/string_scanner.dart' show
-    StringScanner;
-
-import 'package:compiler/src/tokens/token.dart' show
-    ErrorToken,
-    Token;
-
-import 'package:compiler/src/tokens/token_constants.dart' show
-    EOF_TOKEN;
-
-import 'ui.dart' show
-    currentTheme,
-    hackDiv,
-    interaction,
-    mainEditorPane,
-    observer,
-    outputDiv;
-
-import 'decoration.dart' show
-    CodeCompletionDecoration,
-    Decoration,
-    DiagnosticDecoration,
-    error,
-    info,
-    warning;
-
-import 'selection.dart' show
-    isCollapsed;
-
-import 'shadow_root.dart' show
-    getShadowRoot;
-
-import 'settings.dart' as settings;
-
-const String INDENT = '\u{a0}\u{a0}';
-
-Set<String> seenIdentifiers;
-
-Element moveActive(int distance, Node ui) {
-  var /* ShadowRoot or Element */ root = getShadowRoot(ui);
-  List<Element> entries = root.querySelectorAll('.dart-static>.dart-entry');
-  int activeIndex = -1;
-  for (var i = 0; i < entries.length; i++) {
-    if (entries[i].classes.contains('activeEntry')) {
-      activeIndex = i;
-      break;
-    }
-  }
-  int newIndex = activeIndex + distance;
-  Element currentEntry;
-  if (0 <= newIndex && newIndex < entries.length) {
-    currentEntry = entries[newIndex];
-  }
-  if (currentEntry == null) return null;
-  if (0 <= newIndex && activeIndex != -1) {
-    entries[activeIndex].classes.remove('activeEntry');
-  }
-  Element staticNode = root.querySelector('.dart-static');
-  String visibility = computeVisibility(currentEntry, staticNode);
-  print(visibility);
-  var serverResults = root.querySelectorAll('.dart-server>.dart-entry');
-  var serverResultCount = serverResults.length;
-  if (serverResultCount > 0) {
-    switch (visibility) {
-      case obscured:
-      case hidden: {
-        Rectangle cr = currentEntry.getBoundingClientRect();
-        Rectangle sr = staticNode.getBoundingClientRect();
-        Element entry = serverResults[0];
-        entry.remove();
-        currentEntry.parentNode.insertBefore(entry, currentEntry);
-        currentEntry = entry;
-        serverResultCount--;
-
-        staticNode.style.maxHeight = '${sr.boundingBox(cr).height}px';
-      }
-    }
-  } else {
-    currentEntry.scrollIntoView();
-  }
-  if (serverResultCount == 0) {
-    root.querySelector('.dart-server').style.display = 'none';
-  }
-  if (currentEntry != null) {
-    currentEntry.classes.add('activeEntry');
-  }
-  // Discard mutations.
-  observer.takeRecords();
-  return currentEntry;
-}
-
-const visible = 'visible';
-const obscured = 'obscured';
-const hidden = 'hidden';
-
-String computeVisibility(Element node, [Element parent]) {
-  Rectangle nr = node.getBoundingClientRect();
-  if (parent == null) parent = node.parentNode;
-  Rectangle pr = parent.getBoundingClientRect();
-
-  if (pr.containsRectangle(nr)) return visible;
-
-  if (pr.intersects(nr)) return obscured;
-
-  return hidden;
-}
-
-var activeCompletion;
-num minSuggestionWidth = 0;
-
-/// Returns the [Element] which encloses the current collapsed selection, if it
-/// exists.
-Element getElementAtSelection() {
-  Selection selection = window.getSelection();
-  if (!isCollapsed(selection)) return null;
-  var anchorNode = selection.anchorNode;
-  if (!mainEditorPane.contains(anchorNode)) return null;
-  if (mainEditorPane == anchorNode) return null;
-  int type = anchorNode.nodeType;
-  if (type != Node.TEXT_NODE) return null;
-  Text text = anchorNode;
-  var parent = text.parent;
-  if (parent is! Element) return null;
-  if (mainEditorPane == parent) return null;
-  return parent;
-}
-
-bool isMalformedInput = false;
-
-addDiagnostic(String kind, String message, int begin, int end) {
-  observer.disconnect();
-  Selection selection = window.getSelection();
-  int offset = 0;
-  int anchorOffset = 0;
-  bool hasSelection = false;
-  Node anchorNode = selection.anchorNode;
-  bool foundNode = false;
-  void walk4(Node node) {
-    // TODO(ahe): Use TreeWalker when that is exposed.
-    int type = node.nodeType;
-    if (type == Node.TEXT_NODE || type == Node.CDATA_SECTION_NODE) {
-      CharacterData cdata = node;
-      // print('walking: ${node.data}');
-      if (anchorNode == node) {
-        hasSelection = true;
-        anchorOffset = selection.anchorOffset + offset;
-      }
-      int newOffset = offset + cdata.length;
-      if (offset <= begin && begin < newOffset) {
-        hasSelection = node == anchorNode;
-        anchorOffset = selection.anchorOffset;
-        var alert;
-        if (kind == 'error') {
-          alert = error(message);
-        } else if (kind == 'warning') {
-          alert = warning(message);
-        } else {
-          alert = info(message);
-        }
-        Element parent = node.parentNode;
-        if (parent.classes.contains("diagnostic") &&
-            !interaction.oldDiagnostics.contains(parent)) {
-          Element other = parent.firstChild;
-          other.remove();
-          SpanElement wrapper = new SpanElement()
-            ..classes.add('diagnostic')
-            ..style.fontWeight = 'normal';
-
-          var root = getShadowRoot(wrapper);
-          if (root is ShadowRoot) {
-            // When https://code.google.com/p/chromium/issues/detail?id=313458
-            // is fixed:
-            // var link = new LinkElement()
-            //     ..rel = "stylesheet"
-            //     ..type = "text/css"
-            //     ..href = "dartlang-style.css";
-            // root.append(link);
-            root.append(
-                new StyleElement()..text = '@import url(dartlang-style.css)');
-          }
-          root
-              ..append(other)
-              ..append(alert);
-          other.style.display = 'block';
-          alert.style.display = 'block';
-          parent.append(wrapper);
-        } else {
-          if (interaction.oldDiagnostics.contains(parent)) {
-            node.remove();
-            parent.replaceWith(node);
-          }
-          Node marker = new Text("");
-          node.replaceWith(marker);
-          // TODO(ahe): Don't highlight everything in the node.  Find the
-          // relevant token (works for now as we create a node for each token,
-          // which is probably not great for performance).
-          marker.replaceWith(diagnostic(node, alert));
-          if (hasSelection) {
-            selection.collapse(node, anchorOffset);
-          }
-        }
-        foundNode = true;
-        return;
-      }
-      offset = newOffset;
-    } else if (type == Node.ELEMENT_NODE) {
-      Element element = node;
-      CssClassSet classes = element.classes;
-      if (classes.contains('alert') ||
-          classes.contains('dart-code-completion')) {
-        return;
-      }
-    }
-
-    var child = node.firstChild;
-    while(child != null && !foundNode) {
-      walk4(child);
-      child = child.nextNode;
-    }
-  }
-  walk4(mainEditorPane);
-
-  if (!foundNode) {
-    outputDiv.appendText('$message\n');
-  }
-
-  observer.takeRecords();
-  observer.observe(
-      mainEditorPane, childList: true, characterData: true, subtree: true);
-}
-
-Decoration getDecoration(Token token) {
-  if (token is ErrorToken) {
-    // TODO(ahe): Remove side effects from this method. It only leads to
-    // confusion.
-    isMalformedInput = true;
-    return new DiagnosticDecoration('error', token.assertionMessage);
-  }
-  String tokenValue = token.value;
-  String tokenInfo = token.info.value;
-  if (tokenInfo == 'string') return currentTheme.string;
-  if (tokenInfo == 'identifier') {
-    seenIdentifiers.add(tokenValue);
-    Decoration decoration = currentTheme.foreground;
-    if (settings.enableCodeCompletion.value) {
-      decoration = CodeCompletionDecoration.from(decoration);
-    }
-    return decoration;
-  }
-  if (tokenInfo == 'keyword') return currentTheme.keyword;
-  if (tokenInfo == 'comment') return currentTheme.singleLineComment;
-  if (tokenInfo == 'malformed input') {
-    // TODO(ahe): Remove side effects from this method. It only leads to
-    // confusion.
-    isMalformedInput = true;
-    return new DiagnosticDecoration('error', tokenValue);
-  }
-  return currentTheme.foreground;
-}
-
-diagnostic(content, tip) {
-  if (content is String) {
-    content = new Text(content);
-  }
-  if (content is! List) {
-    content = [content];
-  }
-  return new AnchorElement()
-      ..classes.add('diagnostic')
-      ..append(tip) // Should be first for better Firefox editing.
-      ..nodes.addAll(content);
-}
diff --git a/site/try/src/extract_theme.dart b/site/try/src/extract_theme.dart
deleted file mode 100644
index 1487c9b..0000000
--- a/site/try/src/extract_theme.dart
+++ /dev/null
@@ -1,83 +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:io';
-
-StringBuffer themes = new StringBuffer();
-
-void main(List<String> arguments) {
-  print('part of trydart.themes;\n');
-  arguments.forEach(extractTheme);
-  print('''
-/// List of known themes. The default is the first theme.
-const List<Theme> THEMES = const <Theme> [
-    const Theme(),
-$themes];''');
-}
-
-final DECORATION_PATTERN = new RegExp(r'^ *<([a-z][^ ]+)[ ]');
-
-String attr(String name, String line) {
-  var match = new RegExp('$name'r'="([^"]*)"').firstMatch(line);
-  if (match == null) return null;
-  return match[1];
-}
-
-void extractTheme(String filename) {
-  bool openedTheme = false;
-  for (String line in new File(filename).readAsLinesSync()) {
-    if (line.startsWith('<colorTheme')) {
-      openTheme(line, filename);
-      openedTheme = true;
-    } else if (line.startsWith('</colorTheme>')) {
-      if (!openedTheme) throw 'Theme not found in $filename';
-      closeTheme();
-      openedTheme = false;
-    } else if (DECORATION_PATTERN.hasMatch(line)) {
-      if (!openedTheme) throw 'Theme not found in $filename';
-      printDecoration(line);
-    }
-  }
-}
-
-openTheme(String line, String filename) {
-  var name = attr('name', line);
-  var author = attr('author', line);
-  if (name == null) name = 'Untitled';
-  if (name == 'Default') name = 'Dart Editor';
-  var declaration = name.replaceAll(new RegExp('[^a-zA-Z0-9_]'), '_');
-  themes.write('    const ${declaration}Theme(),\n');
-  print('/// $name theme extracted from');
-  print('/// $filename.');
-  if (author != null) {
-    print('/// Author: $author.');
-  }
-  print("""
-class ${declaration}Theme extends Theme {
-  const ${declaration}Theme();
-
-  String get name => '$name';
-""");
-}
-
-closeTheme() {
-  print('}\n');
-}
-
-printDecoration(String line) {
-  String name = DECORATION_PATTERN.firstMatch(line)[1];
-  if (name == 'class') name = 'className';
-  if (name == 'enum') name = 'enumName';
-  StringBuffer properties = new StringBuffer();
-  var color = attr('color', line);
-  if (color != null) {
-    properties.write("color: '$color'");
-  }
-  var bold = attr('bold', line) == 'true';
-  if (bold) {
-    if (!properties.isEmpty) properties.write(', ');
-    properties.write('bold: true');
-  }
-  print('  Decoration get $name => const Decoration($properties);');
-}
diff --git a/site/try/src/extracted_themes.dart b/site/try/src/extracted_themes.dart
deleted file mode 100644
index 43a37fc..0000000
--- a/site/try/src/extracted_themes.dart
+++ /dev/null
@@ -1,1479 +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.
-
-part of trydart.themes;
-
-/// Black Pastel theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/black-pastel.xml.
-/// Author: David.
-class Black_PastelTheme extends Theme {
-  const Black_PastelTheme();
-
-  String get name => 'Black Pastel';
-
-  Decoration get abstractMethod => const Decoration(color: '#E0E2E4');
-  Decoration get annotation => const Decoration(color: '#A082BD');
-  Decoration get background => const Decoration(color: '#000000');
-  Decoration get bracket => const Decoration(color: '#CCCCCC');
-  Decoration get className => const Decoration(color: '#82677E');
-  Decoration get commentTaskTag => const Decoration(color: '#a57b61');
-  Decoration get constant => const Decoration(color: '#A082BD');
-  Decoration get currentLine => const Decoration(color: '#2F393C');
-  Decoration get deletionIndication => const Decoration(color: '#E0E2E4');
-  Decoration get deprecatedMember => const Decoration(color: '#E0E2E4');
-  Decoration get dynamicType => const Decoration(color: '#E0E2E4');
-  Decoration get enumName => const Decoration(color: '#E0E2E4');
-  Decoration get field => const Decoration(color: '#678CB1');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#616161');
-  Decoration get findScope => const Decoration(color: '#E0E2E4');
-  Decoration get foreground => const Decoration(color: '#C0C0C0');
-  Decoration get inheritedMethod => const Decoration(color: '#E0E2E4');
-  Decoration get interface => const Decoration(color: '#82677E');
-  Decoration get javadoc => const Decoration(color: '#7D8C93');
-  Decoration get javadocKeyword => const Decoration(color: '#A082BD');
-  Decoration get javadocLink => const Decoration(color: '#678CB1');
-  Decoration get javadocTag => const Decoration(color: '#E0E2E4');
-  Decoration get keyword => const Decoration(color: '#82677E');
-  Decoration get lineNumber => const Decoration(color: '#81969A');
-  Decoration get localVariable => const Decoration(color: '#E0E2E4');
-  Decoration get localVariableDeclaration => const Decoration(color: '#E0E2E4');
-  Decoration get method => const Decoration(color: '#82677E');
-  Decoration get methodDeclaration => const Decoration(color: '#82677E');
-  Decoration get multiLineComment => const Decoration(color: '#7D8C93');
-  Decoration get number => const Decoration(color: '#c78d9b');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#E8E2B7');
-  Decoration get parameterVariable => const Decoration(color: '#E0E2E4');
-  Decoration get searchResultIndication => const Decoration(color: '#616161');
-  Decoration get selectionBackground => const Decoration(color: '#95bed8');
-  Decoration get selectionForeground => const Decoration(color: '#C0C0C0');
-  Decoration get singleLineComment => const Decoration(color: '#7D8C93');
-  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
-  Decoration get staticField => const Decoration(color: '#678CB1');
-  Decoration get staticFinalField => const Decoration(color: '#E0E2E4');
-  Decoration get staticMethod => const Decoration(color: '#E0E2E4');
-  Decoration get string => const Decoration(color: '#c78d9b');
-  Decoration get typeArgument => const Decoration(color: '#E0E2E4');
-  Decoration get typeParameter => const Decoration(color: '#E0E2E4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#616161');
-}
-
-/// Dartboard theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/dartboard.xml.
-/// Author: Dart.
-class DartboardTheme extends Theme {
-  const DartboardTheme();
-
-  String get name => 'Dartboard';
-
-  Decoration get abstractMethod => const Decoration(color: '#000000');
-  Decoration get annotation => const Decoration(color: '#000000');
-  Decoration get background => const Decoration(color: '#fafafa');
-  Decoration get bracket => const Decoration(color: '#606060');
-  Decoration get builtin => const Decoration(color: '#000000', bold: true);
-  Decoration get className => const Decoration(color: '#0646a7');
-  Decoration get commentTaskTag => const Decoration(color: '#606060');
-  Decoration get constant => const Decoration(color: '#55122a');
-  Decoration get currentLine => const Decoration(color: '#F0F0F0');
-  Decoration get deletionIndication => const Decoration(color: '#000000');
-  Decoration get deprecatedMember => const Decoration(color: '#000000');
-  Decoration get directive => const Decoration(color: '#014d64', bold: true);
-  Decoration get dynamicType => const Decoration(color: '#000000');
-  Decoration get enumName => const Decoration(color: '#000000');
-  Decoration get field => const Decoration(color: '#87312e');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#000000');
-  Decoration get findScope => const Decoration(color: '#000000');
-  Decoration get foreground => const Decoration(color: '#000000');
-  Decoration get getter => const Decoration(color: '#87312e');
-  Decoration get inheritedMethod => const Decoration(color: '#000000');
-  Decoration get interface => const Decoration(color: '#000000');
-  Decoration get javadoc => const Decoration(color: '#606060');
-  Decoration get javadocKeyword => const Decoration(color: '#606060');
-  Decoration get javadocLink => const Decoration(color: '#606060');
-  Decoration get javadocTag => const Decoration(color: '#606060');
-  Decoration get keyword => const Decoration(color: '#000000', bold: true);
-  Decoration get keywordReturn => const Decoration(color: '#000000', bold: true);
-  Decoration get lineNumber => const Decoration(color: '#000000');
-  Decoration get localVariable => const Decoration(color: '#000000');
-  Decoration get localVariableDeclaration => const Decoration(color: '#000000');
-  Decoration get method => const Decoration(color: '#000000');
-  Decoration get methodDeclaration => const Decoration(color: '#0b5bd2', bold: true);
-  Decoration get multiLineComment => const Decoration(color: '#606060');
-  Decoration get multiLineString => const Decoration(color: '#679b3b');
-  Decoration get number => const Decoration(color: '#000000');
-  Decoration get occurrenceIndication => const Decoration(color: '#e0e0e0');
-  Decoration get operator => const Decoration(color: '#000000');
-  Decoration get parameterVariable => const Decoration(color: '#87312e');
-  Decoration get searchResultIndication => const Decoration(color: '#D0D0D0');
-  Decoration get selectionBackground => const Decoration(color: '#b6d6fd');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get setter => const Decoration(color: '#87312e');
-  Decoration get singleLineComment => const Decoration(color: '#7a7a7a');
-  Decoration get sourceHoverBackground => const Decoration(color: '#fbfbc8');
-  Decoration get staticField => const Decoration(color: '#87312e');
-  Decoration get staticFinalField => const Decoration(color: '#55122a');
-  Decoration get staticMethod => const Decoration(color: '#000000');
-  Decoration get staticMethodDeclaration => const Decoration(color: '#0b5bd2', bold: true);
-  Decoration get string => const Decoration(color: '#679b3b');
-  Decoration get typeArgument => const Decoration(color: '#033178');
-  Decoration get typeParameter => const Decoration(color: '#033178');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#e0e0e0');
-}
-
-/// Debugging theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/debugging.xml.
-/// Author: Debug Tool.
-class DebuggingTheme extends Theme {
-  const DebuggingTheme();
-
-  String get name => 'Debugging';
-
-  Decoration get abstractMethod => const Decoration(color: '#F00000');
-  Decoration get annotation => const Decoration(color: '#F00000');
-  Decoration get background => const Decoration(color: '#FFF8FF');
-  Decoration get bracket => const Decoration(color: '#F00000');
-  Decoration get builtin => const Decoration(color: '#F00000');
-  Decoration get className => const Decoration(color: '#F00000');
-  Decoration get commentTaskTag => const Decoration(color: '#F00000');
-  Decoration get constant => const Decoration(color: '#F00000');
-  Decoration get currentLine => const Decoration(color: '#F0F0F0');
-  Decoration get deletionIndication => const Decoration(color: '#F00000');
-  Decoration get deprecatedMember => const Decoration(color: '#F00000');
-  Decoration get directive => const Decoration(color: '#F00000');
-  Decoration get dynamicType => const Decoration(color: '#F00000');
-  Decoration get enumName => const Decoration(color: '#F00000');
-  Decoration get field => const Decoration(color: '#F000000');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#F00000');
-  Decoration get findScope => const Decoration(color: '#F00000');
-  Decoration get foreground => const Decoration(color: '#F00000');
-  Decoration get getter => const Decoration(color: '#F00000');
-  Decoration get inheritedMethod => const Decoration(color: '#F00000');
-  Decoration get interface => const Decoration(color: '#F00000');
-  Decoration get javadoc => const Decoration(color: '#F00000');
-  Decoration get javadocKeyword => const Decoration(color: '#F00000');
-  Decoration get javadocLink => const Decoration(color: '#F00000');
-  Decoration get javadocTag => const Decoration(color: '#F00000');
-  Decoration get keyword => const Decoration(color: '#F00000', bold: true);
-  Decoration get keywordReturn => const Decoration(color: '#F00000', bold: true);
-  Decoration get lineNumber => const Decoration(color: '#F00000');
-  Decoration get localVariable => const Decoration(color: '#F00000');
-  Decoration get localVariableDeclaration => const Decoration(color: '#F00000');
-  Decoration get method => const Decoration(color: '#F00000');
-  Decoration get methodDeclaration => const Decoration(color: '#F00000');
-  Decoration get multiLineComment => const Decoration(color: '#F00000');
-  Decoration get multiLineString => const Decoration(color: '#F00000');
-  Decoration get number => const Decoration(color: '#F00000');
-  Decoration get occurrenceIndication => const Decoration(color: '#F00000');
-  Decoration get operator => const Decoration(color: '#F00000');
-  Decoration get parameterVariable => const Decoration(color: '#F00000');
-  Decoration get searchResultIndication => const Decoration(color: '#F00000');
-  Decoration get selectionBackground => const Decoration(color: '#F000F0');
-  Decoration get selectionForeground => const Decoration(color: '#F00000');
-  Decoration get setter => const Decoration(color: '#F00000');
-  Decoration get singleLineComment => const Decoration(color: '#F00000');
-  Decoration get sourceHoverBackground => const Decoration(color: '#F00000');
-  Decoration get staticField => const Decoration(color: '#F00000');
-  Decoration get staticFinalField => const Decoration(color: '#F00000');
-  Decoration get staticMethod => const Decoration(color: '#F00000');
-  Decoration get staticMethodDeclaration => const Decoration(color: '#F00000');
-  Decoration get string => const Decoration(color: '#F00000');
-  Decoration get typeArgument => const Decoration(color: '#F00000');
-  Decoration get typeParameter => const Decoration(color: '#F00000');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#F00000');
-}
-
-/// Dart Editor theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/default.xml.
-/// Author: Dart.
-class Dart_EditorTheme extends Theme {
-  const Dart_EditorTheme();
-
-  String get name => 'Dart Editor';
-
-  Decoration get abstractMethod => const Decoration(color: '#000000');
-  Decoration get annotation => const Decoration(color: '#000000');
-  Decoration get background => const Decoration(color: '#ffffff');
-  Decoration get bracket => const Decoration(color: '#000000');
-  Decoration get builtin => const Decoration(color: '#7e0854', bold: true);
-  Decoration get className => const Decoration(color: '#000000');
-  Decoration get commentTaskTag => const Decoration(color: '#606060');
-  Decoration get constant => const Decoration(color: '#000000');
-  Decoration get currentLine => const Decoration(color: '#F0F0F0');
-  Decoration get deletionIndication => const Decoration(color: '#000000');
-  Decoration get deprecatedMember => const Decoration(color: '#000000');
-  Decoration get directive => const Decoration(color: '#7e0854', bold: true);
-  Decoration get dynamicType => const Decoration(color: '#000000');
-  Decoration get enumName => const Decoration(color: '#000000');
-  Decoration get field => const Decoration(color: '#0618bd');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#000000');
-  Decoration get findScope => const Decoration(color: '#000000');
-  Decoration get foreground => const Decoration(color: '#000000');
-  Decoration get getter => const Decoration(color: '#0618bd');
-  Decoration get inheritedMethod => const Decoration(color: '#000000');
-  Decoration get interface => const Decoration(color: '#000000');
-  Decoration get javadoc => const Decoration(color: '#4162bc');
-  Decoration get javadocKeyword => const Decoration(color: '#4162bc');
-  Decoration get javadocLink => const Decoration(color: '#4162bc');
-  Decoration get javadocTag => const Decoration(color: '#7f809e');
-  Decoration get keyword => const Decoration(color: '#7e0854', bold: true);
-  Decoration get keywordReturn => const Decoration(color: '#7e0854', bold: true);
-  Decoration get lineNumber => const Decoration(color: '#000000');
-  Decoration get localVariable => const Decoration(color: '#7f1cc9');
-  Decoration get localVariableDeclaration => const Decoration(color: '#7f1cc9');
-  Decoration get method => const Decoration(color: '#000000');
-  Decoration get methodDeclaration => const Decoration(color: '#0b5bd2', bold: true);
-  Decoration get multiLineComment => const Decoration(color: '#4162bc');
-  Decoration get multiLineString => const Decoration(color: '#2d24fb');
-  Decoration get number => const Decoration(color: '#0c6f0e');
-  Decoration get occurrenceIndication => const Decoration(color: '#e0e0e0');
-  Decoration get operator => const Decoration(color: '#000000');
-  Decoration get parameterVariable => const Decoration(color: '#87312e');
-  Decoration get searchResultIndication => const Decoration(color: '#D0D0D0');
-  Decoration get selectionBackground => const Decoration(color: '#b6d6fd');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get setter => const Decoration(color: '#0618bd');
-  Decoration get singleLineComment => const Decoration(color: '#417e60');
-  Decoration get sourceHoverBackground => const Decoration(color: '#fbfbc8');
-  Decoration get staticField => const Decoration(color: '#0618bd');
-  Decoration get staticFinalField => const Decoration(color: '#0618bd');
-  Decoration get staticMethod => const Decoration(color: '#000000');
-  Decoration get staticMethodDeclaration => const Decoration(color: '#404040', bold: true);
-  Decoration get string => const Decoration(color: '#2d24fb');
-  Decoration get typeArgument => const Decoration(color: '#033178');
-  Decoration get typeParameter => const Decoration(color: '#033178');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#e0e0e0');
-}
-
-/// frontenddev theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/frontenddev.xml.
-/// Author: Plebe.
-class frontenddevTheme extends Theme {
-  const frontenddevTheme();
-
-  String get name => 'frontenddev';
-
-  Decoration get abstractMethod => const Decoration(color: '#F1C436');
-  Decoration get annotation => const Decoration(color: '#999999');
-  Decoration get background => const Decoration(color: '#000000');
-  Decoration get bracket => const Decoration(color: '#FFFFFF');
-  Decoration get className => const Decoration(color: '#9CF828');
-  Decoration get commentTaskTag => const Decoration(color: '#666666');
-  Decoration get currentLine => const Decoration(color: '#222220');
-  Decoration get deletionIndication => const Decoration(color: '#FF0000');
-  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
-  Decoration get dynamicType => const Decoration(color: '#F7C527');
-  Decoration get enumName => const Decoration(color: '#408000');
-  Decoration get field => const Decoration(color: '#c38705');
-  Decoration get findScope => const Decoration(color: '#191919');
-  Decoration get foreground => const Decoration(color: '#FFFFFF');
-  Decoration get inheritedMethod => const Decoration(color: '#E3B735');
-  Decoration get interface => const Decoration(color: '#87F025');
-  Decoration get javadoc => const Decoration(color: '#666666');
-  Decoration get javadocKeyword => const Decoration(color: '#800080');
-  Decoration get javadocLink => const Decoration(color: '#666666');
-  Decoration get javadocTag => const Decoration(color: '#800080');
-  Decoration get keyword => const Decoration(color: '#999999');
-  Decoration get lineNumber => const Decoration(color: '#999999');
-  Decoration get localVariable => const Decoration(color: '#F7C527');
-  Decoration get localVariableDeclaration => const Decoration(color: '#F7C527');
-  Decoration get method => const Decoration(color: '#F7C527');
-  Decoration get methodDeclaration => const Decoration(color: '#F1C438');
-  Decoration get multiLineComment => const Decoration(color: '#666666');
-  Decoration get number => const Decoration(color: '#FF0000');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#FFFFFF');
-  Decoration get parameterVariable => const Decoration(color: '#069609');
-  Decoration get selectionBackground => const Decoration(color: '#333333');
-  Decoration get selectionForeground => const Decoration(color: '#333333');
-  Decoration get singleLineComment => const Decoration(color: '#666666');
-  Decoration get staticField => const Decoration(color: '#FFFFFF');
-  Decoration get staticFinalField => const Decoration(color: '#80FF00');
-  Decoration get staticMethod => const Decoration(color: '#FFFFFF');
-  Decoration get string => const Decoration(color: '#00a40f');
-  Decoration get typeArgument => const Decoration(color: '#D9B0AC');
-  Decoration get typeParameter => const Decoration(color: '#CDB1AD');
-}
-
-/// Gedit Original Oblivion theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/gedit-original-oblivion.xml.
-/// Author: Sepehr Lajevardi.
-class Gedit_Original_OblivionTheme extends Theme {
-  const Gedit_Original_OblivionTheme();
-
-  String get name => 'Gedit Original Oblivion';
-
-  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
-  Decoration get annotation => const Decoration(color: '#FFFFFF');
-  Decoration get background => const Decoration(color: '#2e3436');
-  Decoration get bracket => const Decoration(color: '#D8D8D8');
-  Decoration get className => const Decoration(color: '#bbbbbb');
-  Decoration get commentTaskTag => const Decoration(color: '#CCDF32');
-  Decoration get constant => const Decoration(color: '#edd400');
-  Decoration get currentLine => const Decoration(color: '#555753');
-  Decoration get deletionIndication => const Decoration(color: '#D25252');
-  Decoration get dynamicType => const Decoration(color: '#729fcf');
-  Decoration get field => const Decoration(color: '#BED6FF');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
-  Decoration get findScope => const Decoration(color: '#000000');
-  Decoration get foreground => const Decoration(color: '#d3d7cf');
-  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
-  Decoration get interface => const Decoration(color: '#D197D9');
-  Decoration get javadoc => const Decoration(color: '#888a85');
-  Decoration get javadocKeyword => const Decoration(color: '#888a85');
-  Decoration get javadocLink => const Decoration(color: '#888a85');
-  Decoration get javadocTag => const Decoration(color: '#888a85');
-  Decoration get keyword => const Decoration(color: '#FFFFFF');
-  Decoration get lineNumber => const Decoration(color: '#555753');
-  Decoration get localVariable => const Decoration(color: '#729fcf');
-  Decoration get localVariableDeclaration => const Decoration(color: '#729fcf');
-  Decoration get method => const Decoration(color: '#FFFFFF');
-  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
-  Decoration get multiLineComment => const Decoration(color: '#888a85');
-  Decoration get number => const Decoration(color: '#ce5c00');
-  Decoration get occurrenceIndication => const Decoration(color: '#000000');
-  Decoration get operator => const Decoration(color: '#D8D8D8');
-  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
-  Decoration get searchResultIndication => const Decoration(color: '#eeeeec');
-  Decoration get selectionBackground => const Decoration(color: '#888a85');
-  Decoration get selectionForeground => const Decoration(color: '#eeeeec');
-  Decoration get singleLineComment => const Decoration(color: '#888a85');
-  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
-  Decoration get staticField => const Decoration(color: '#EFC090');
-  Decoration get staticFinalField => const Decoration(color: '#EFC090');
-  Decoration get staticMethod => const Decoration(color: '#BED6FF');
-  Decoration get string => const Decoration(color: '#edd400');
-  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
-  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
-}
-
-/// Havenjark theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/havenjark.xml.
-/// Author: Rodrigo Franco.
-class HavenjarkTheme extends Theme {
-  const HavenjarkTheme();
-
-  String get name => 'Havenjark';
-
-  Decoration get abstractMethod => const Decoration(color: '#C0B6A8');
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#2D3639');
-  Decoration get bracket => const Decoration(color: '#FFFFFF');
-  Decoration get className => const Decoration(color: '#B8ADA0');
-  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
-  Decoration get constant => const Decoration(color: '#93A2CC');
-  Decoration get currentLine => const Decoration(color: '#00001F');
-  Decoration get deprecatedMember => const Decoration(color: '#F3D651');
-  Decoration get dynamicType => const Decoration(color: '#A19A83');
-  Decoration get field => const Decoration(color: '#B3B784');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#3F3F6A');
-  Decoration get findScope => const Decoration(color: '#B9A185');
-  Decoration get foreground => const Decoration(color: '#C0B6A8');
-  Decoration get inheritedMethod => const Decoration(color: '#C0B6A8');
-  Decoration get interface => const Decoration(color: '#B8ADA0');
-  Decoration get javadoc => const Decoration(color: '#B3B5AF');
-  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
-  Decoration get javadocLink => const Decoration(color: '#A893CC');
-  Decoration get javadocTag => const Decoration(color: '#9393CC');
-  Decoration get keyword => const Decoration(color: '#A38474');
-  Decoration get lineNumber => const Decoration(color: '#C0C0C0');
-  Decoration get localVariable => const Decoration(color: '#A19A83');
-  Decoration get localVariableDeclaration => const Decoration(color: '#A19A83');
-  Decoration get method => const Decoration(color: '#DFBE95');
-  Decoration get methodDeclaration => const Decoration(color: '#DFBE95');
-  Decoration get multiLineComment => const Decoration(color: '#AEAEAE');
-  Decoration get multiLineString => const Decoration(color: '#808080');
-  Decoration get number => const Decoration(color: '#B9A185');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#F0EFD0');
-  Decoration get parameterVariable => const Decoration(color: '#A19A83');
-  Decoration get searchResultIndication => const Decoration(color: '#464467');
-  Decoration get selectionBackground => const Decoration(color: '#2A4750');
-  Decoration get selectionForeground => const Decoration(color: '#C0B6A8');
-  Decoration get singleLineComment => const Decoration(color: '#AEAEAE');
-  Decoration get sourceHoverBackground => const Decoration(color: '#A19879');
-  Decoration get staticField => const Decoration(color: '#93A2CC');
-  Decoration get staticFinalField => const Decoration(color: '#93A2CC');
-  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
-  Decoration get string => const Decoration(color: '#CC9393');
-  Decoration get typeArgument => const Decoration(color: '#C0B6A8');
-  Decoration get typeParameter => const Decoration(color: '#C0B6A8');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
-}
-
-/// Hot Pink theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/hotpink.xml.
-/// Author: KS.
-class Hot_PinkTheme extends Theme {
-  const Hot_PinkTheme();
-
-  String get name => 'Hot Pink';
-
-  Decoration get abstractMethod => const Decoration(color: '#000000');
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#FFFFFF');
-  Decoration get bracket => const Decoration(color: '#000f6a');
-  Decoration get builtin => const Decoration(color: '#7e0854');
-  Decoration get className => const Decoration(color: '#008000', bold: true);
-  Decoration get commentTaskTag => const Decoration(color: '#417e60');
-  Decoration get constant => const Decoration(color: '#ae25ab');
-  Decoration get currentLine => const Decoration(color: '#fff7cd');
-  Decoration get deletionIndication => const Decoration(color: '#9b5656');
-  Decoration get deprecatedMember => const Decoration(color: '#000000');
-  Decoration get directive => const Decoration(color: '#FF4040');
-  Decoration get dynamicType => const Decoration(color: '#FF4040');
-  Decoration get enumName => const Decoration(color: '#000000');
-  Decoration get field => const Decoration(color: '#0000C0');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#CC6633');
-  Decoration get findScope => const Decoration(color: '#BCADAD');
-  Decoration get foreground => const Decoration(color: '#000000');
-  Decoration get getter => const Decoration(color: '#0200C0');
-  Decoration get inheritedMethod => const Decoration(color: '#2c577c');
-  Decoration get interface => const Decoration(color: '#000000');
-  Decoration get javadoc => const Decoration(color: '#4162bc');
-  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
-  Decoration get javadocLink => const Decoration(color: '#4162bc');
-  Decoration get javadocTag => const Decoration(color: '#4162bc');
-  Decoration get keyword => const Decoration(color: '#7e0854', bold: true);
-  Decoration get keywordReturn => const Decoration(color: '#800390', bold: true);
-  Decoration get lineNumber => const Decoration(color: '#999999');
-  Decoration get localVariable => const Decoration(color: '#FF00FF');
-  Decoration get localVariableDeclaration => const Decoration(color: '#008080');
-  Decoration get method => const Decoration(color: '#2BA6E8');
-  Decoration get methodDeclaration => const Decoration(color: '#8000FF');
-  Decoration get multiLineComment => const Decoration(color: '#417e60');
-  Decoration get multiLineString => const Decoration(color: '#2000FF');
-  Decoration get number => const Decoration(color: '#008000');
-  Decoration get occurrenceIndication => const Decoration(color: '#CC6633');
-  Decoration get operator => const Decoration(color: '#5f97a9');
-  Decoration get parameterVariable => const Decoration(color: '#D7721E');
-  Decoration get searchResultIndication => const Decoration(color: '#CC6633');
-  Decoration get selectionBackground => const Decoration(color: '#c0c0c0');
-  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
-  Decoration get setter => const Decoration(color: '#0200C0');
-  Decoration get singleLineComment => const Decoration(color: '#417e60');
-  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
-  Decoration get staticField => const Decoration(color: '#0000C0');
-  Decoration get staticFinalField => const Decoration(color: '#464646');
-  Decoration get staticMethod => const Decoration(color: '#2BA6E8', bold: true);
-  Decoration get staticMethodDeclaration => const Decoration(color: '#8000FF', bold: true);
-  Decoration get string => const Decoration(color: '#2000FF');
-  Decoration get typeArgument => const Decoration(color: '#d07fcd');
-  Decoration get typeParameter => const Decoration(color: '#D00000', bold: true);
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#CC6633');
-}
-
-/// Inkpot theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/inkpot.xml.
-/// Author: Ciaran McCreesh.
-class InkpotTheme extends Theme {
-  const InkpotTheme();
-
-  String get name => 'Inkpot';
-
-  Decoration get background => const Decoration(color: '#1F1F27');
-  Decoration get bracket => const Decoration(color: '#CFBFAD');
-  Decoration get className => const Decoration(color: '#87CEFA');
-  Decoration get commentTaskTag => const Decoration(color: '#FF8BFF');
-  Decoration get currentLine => const Decoration(color: '#2D2D44');
-  Decoration get dynamicType => const Decoration(color: '#CFBFAD');
-  Decoration get enumName => const Decoration(color: '#CFBFAD');
-  Decoration get foreground => const Decoration(color: '#CFBFAD');
-  Decoration get interface => const Decoration(color: '#87FAC4');
-  Decoration get keyword => const Decoration(color: '#808BED');
-  Decoration get lineNumber => const Decoration(color: '#2B91AF');
-  Decoration get localVariable => const Decoration(color: '#CFBFAD');
-  Decoration get localVariableDeclaration => const Decoration(color: '#CFBFAD');
-  Decoration get method => const Decoration(color: '#87CEFA');
-  Decoration get methodDeclaration => const Decoration(color: '#CFBFAD');
-  Decoration get multiLineComment => const Decoration(color: '#CD8B00');
-  Decoration get number => const Decoration(color: '#FFCD8B');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#CFBFAD');
-  Decoration get selectionBackground => const Decoration(color: '#8B8BFF');
-  Decoration get selectionForeground => const Decoration(color: '#404040');
-  Decoration get singleLineComment => const Decoration(color: '#CD8B00');
-  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
-  Decoration get string => const Decoration(color: '#FFCD8B');
-}
-
-/// minimal theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/minimal.xml.
-/// Author: meers davy.
-class minimalTheme extends Theme {
-  const minimalTheme();
-
-  String get name => 'minimal';
-
-  Decoration get abstractMethod => const Decoration(color: '#5c8198');
-  Decoration get annotation => const Decoration(color: '#AAAAFF');
-  Decoration get background => const Decoration(color: '#ffffff');
-  Decoration get bracket => const Decoration(color: '#000066');
-  Decoration get className => const Decoration(color: '#000066');
-  Decoration get commentTaskTag => const Decoration(color: '#666666');
-  Decoration get currentLine => const Decoration(color: '#aaccff');
-  Decoration get deletionIndication => const Decoration(color: '#aaccff');
-  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
-  Decoration get enumName => const Decoration(color: '#000066');
-  Decoration get field => const Decoration(color: '#566874');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#EFEFEF');
-  Decoration get findScope => const Decoration(color: '#BCADff');
-  Decoration get foreground => const Decoration(color: '#000000');
-  Decoration get inheritedMethod => const Decoration(color: '#5c8198');
-  Decoration get interface => const Decoration(color: '#000066');
-  Decoration get javadoc => const Decoration(color: '#05314d');
-  Decoration get javadocKeyword => const Decoration(color: '#05314d');
-  Decoration get javadocLink => const Decoration(color: '#05314d');
-  Decoration get javadocTag => const Decoration(color: '#05314d');
-  Decoration get keyword => const Decoration(color: '#5c8198');
-  Decoration get lineNumber => const Decoration(color: '#666666');
-  Decoration get localVariable => const Decoration(color: '#5c8198');
-  Decoration get localVariableDeclaration => const Decoration(color: '#5c8198');
-  Decoration get method => const Decoration(color: '#5c8198');
-  Decoration get methodDeclaration => const Decoration(color: '#5c8198');
-  Decoration get multiLineComment => const Decoration(color: '#334466');
-  Decoration get number => const Decoration(color: '#333333');
-  Decoration get occurrenceIndication => const Decoration(color: '#EFEFEF');
-  Decoration get operator => const Decoration(color: '#333333');
-  Decoration get parameterVariable => const Decoration(color: '#5c8198');
-  Decoration get searchResultIndication => const Decoration(color: '#EFEFEF');
-  Decoration get selectionBackground => const Decoration(color: '#Efefff');
-  Decoration get selectionForeground => const Decoration(color: '#000066');
-  Decoration get singleLineComment => const Decoration(color: '#334466');
-  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
-  Decoration get staticField => const Decoration(color: '#05314d');
-  Decoration get staticFinalField => const Decoration(color: '#05314d');
-  Decoration get staticMethod => const Decoration(color: '#5c8198');
-  Decoration get string => const Decoration(color: '#333333');
-  Decoration get typeArgument => const Decoration(color: '#5c8198');
-  Decoration get typeParameter => const Decoration(color: '#5c8198');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#EFEFEF');
-}
-
-/// Monokai theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/monokai.xml.
-/// Author: Truong Xuan Tinh.
-class MonokaiTheme extends Theme {
-  const MonokaiTheme();
-
-  String get name => 'Monokai';
-
-  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
-  Decoration get annotation => const Decoration(color: '#FFFFFF');
-  Decoration get background => const Decoration(color: '#272822');
-  Decoration get bracket => const Decoration(color: '#D8D8D8');
-  Decoration get className => const Decoration(color: '#FFFFFF');
-  Decoration get commentTaskTag => const Decoration(color: '#CCDF32');
-  Decoration get constant => const Decoration(color: '#EFB571');
-  Decoration get currentLine => const Decoration(color: '#3E3D32');
-  Decoration get deletionIndication => const Decoration(color: '#D25252');
-  Decoration get deprecatedMember => const Decoration(color: '#F8F8F2');
-  Decoration get dynamicType => const Decoration(color: '#79ABFF');
-  Decoration get enumName => const Decoration(color: '#66D9EF');
-  Decoration get field => const Decoration(color: '#BED6FF');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
-  Decoration get findScope => const Decoration(color: '#000000');
-  Decoration get foreground => const Decoration(color: '#F8F8F2');
-  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
-  Decoration get interface => const Decoration(color: '#D197D9');
-  Decoration get javadoc => const Decoration(color: '#75715E');
-  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
-  Decoration get javadocLink => const Decoration(color: '#D9E577');
-  Decoration get javadocTag => const Decoration(color: '#D9E577');
-  Decoration get keyword => const Decoration(color: '#66CCB3');
-  Decoration get lineNumber => const Decoration(color: '#F8F8F2');
-  Decoration get localVariable => const Decoration(color: '#79ABFF');
-  Decoration get localVariableDeclaration => const Decoration(color: '#BED6FF');
-  Decoration get method => const Decoration(color: '#FFFFFF');
-  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
-  Decoration get multiLineComment => const Decoration(color: '#75715e');
-  Decoration get number => const Decoration(color: '#7FB347');
-  Decoration get occurrenceIndication => const Decoration(color: '#000000');
-  Decoration get operator => const Decoration(color: '#D8D8D8');
-  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
-  Decoration get searchResultIndication => const Decoration(color: '#D8D8D8');
-  Decoration get selectionBackground => const Decoration(color: '#757575');
-  Decoration get selectionForeground => const Decoration(color: '#D0D0D0');
-  Decoration get singleLineComment => const Decoration(color: '#75715E');
-  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
-  Decoration get staticField => const Decoration(color: '#EFC090');
-  Decoration get staticFinalField => const Decoration(color: '#EFC090');
-  Decoration get staticMethod => const Decoration(color: '#BED6FF');
-  Decoration get string => const Decoration(color: '#E6DB74');
-  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
-  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
-}
-
-/// Mr theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/mr.xml.
-/// Author: Jongosi.
-class MrTheme extends Theme {
-  const MrTheme();
-
-  String get name => 'Mr';
-
-  Decoration get abstractMethod => const Decoration(color: '#000099');
-  Decoration get annotation => const Decoration(color: '#990000');
-  Decoration get background => const Decoration(color: '#FFFFFF');
-  Decoration get bracket => const Decoration(color: '#000099');
-  Decoration get className => const Decoration(color: '#006600');
-  Decoration get commentTaskTag => const Decoration(color: '#FF3300');
-  Decoration get constant => const Decoration(color: '#552200');
-  Decoration get currentLine => const Decoration(color: '#D8D8D8');
-  Decoration get deprecatedMember => const Decoration(color: '#D8D8D8');
-  Decoration get enumName => const Decoration(color: '#FF0000');
-  Decoration get field => const Decoration(color: '#000099');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
-  Decoration get foreground => const Decoration(color: '#333333');
-  Decoration get inheritedMethod => const Decoration(color: '#000099');
-  Decoration get interface => const Decoration(color: '#666666');
-  Decoration get javadoc => const Decoration(color: '#FF3300');
-  Decoration get javadocKeyword => const Decoration(color: '#990099');
-  Decoration get javadocLink => const Decoration(color: '#990099');
-  Decoration get javadocTag => const Decoration(color: '#990099');
-  Decoration get keyword => const Decoration(color: '#0000FF');
-  Decoration get lineNumber => const Decoration(color: '#D8D8D8');
-  Decoration get localVariable => const Decoration(color: '#0066FF');
-  Decoration get localVariableDeclaration => const Decoration(color: '#000099');
-  Decoration get method => const Decoration(color: '#000099');
-  Decoration get methodDeclaration => const Decoration(color: '#000099');
-  Decoration get multiLineComment => const Decoration(color: '#FF9900');
-  Decoration get number => const Decoration(color: '#0000FF');
-  Decoration get occurrenceIndication => const Decoration(color: '#000000');
-  Decoration get operator => const Decoration(color: '#0000FF');
-  Decoration get parameterVariable => const Decoration(color: '#0000FF');
-  Decoration get searchResultIndication => const Decoration(color: '#D8D8D8');
-  Decoration get selectionBackground => const Decoration(color: '#D8D8D8');
-  Decoration get selectionForeground => const Decoration(color: '#333333');
-  Decoration get singleLineComment => const Decoration(color: '#FF9900');
-  Decoration get sourceHoverBackground => const Decoration(color: '#D8D8D8');
-  Decoration get staticField => const Decoration(color: '#552200');
-  Decoration get staticFinalField => const Decoration(color: '#552200');
-  Decoration get staticMethod => const Decoration(color: '#990000');
-  Decoration get string => const Decoration(color: '#CC0000');
-  Decoration get typeArgument => const Decoration(color: '#0000FF');
-  Decoration get typeParameter => const Decoration(color: '#006600');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
-}
-
-/// NightLion Aptana Theme theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/nightlion-aptana-theme.xml.
-/// Author: NightLion.
-class NightLion_Aptana_ThemeTheme extends Theme {
-  const NightLion_Aptana_ThemeTheme();
-
-  String get name => 'NightLion Aptana Theme';
-
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#1E1E1E');
-  Decoration get bracket => const Decoration(color: '#FFFFFF');
-  Decoration get className => const Decoration(color: '#CAE682');
-  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
-  Decoration get currentLine => const Decoration(color: '#505050');
-  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
-  Decoration get dynamicType => const Decoration(color: '#D4C4A9');
-  Decoration get field => const Decoration(color: '#B3B784');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#3F3F6A');
-  Decoration get findScope => const Decoration(color: '#BCADAD');
-  Decoration get foreground => const Decoration(color: '#E2E2E2');
-  Decoration get interface => const Decoration(color: '#CAE682');
-  Decoration get javadoc => const Decoration(color: '#B3B5AF');
-  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
-  Decoration get javadocLink => const Decoration(color: '#A893CC');
-  Decoration get javadocTag => const Decoration(color: '#9393CC');
-  Decoration get keyword => const Decoration(color: '#8DCBE2');
-  Decoration get lineNumber => const Decoration(color: '#C0C0C0');
-  Decoration get localVariable => const Decoration(color: '#D4C4A9');
-  Decoration get localVariableDeclaration => const Decoration(color: '#D4C4A9');
-  Decoration get method => const Decoration(color: '#DFBE95');
-  Decoration get methodDeclaration => const Decoration(color: '#DFBE95');
-  Decoration get multiLineComment => const Decoration(color: '#73879B');
-  Decoration get number => const Decoration(color: '#EAB882');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#F0EFD0');
-  Decoration get searchResultIndication => const Decoration(color: '#464467');
-  Decoration get selectionBackground => const Decoration(color: '#364656');
-  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
-  Decoration get singleLineComment => const Decoration(color: '#7F9F7F');
-  Decoration get sourceHoverBackground => const Decoration(color: '#A19879');
-  Decoration get staticField => const Decoration(color: '#93A2CC');
-  Decoration get staticFinalField => const Decoration(color: '#53DCCD');
-  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
-  Decoration get string => const Decoration(color: '#CC9393');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
-}
-
-/// Notepad++ Like theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/notepad++-like.xml.
-/// Author: Vokiel.
-class Notepad___LikeTheme extends Theme {
-  const Notepad___LikeTheme();
-
-  String get name => 'Notepad++ Like';
-
-  Decoration get abstractMethod => const Decoration(color: '#FF00FF');
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#FFFFFF');
-  Decoration get bracket => const Decoration(color: '#8000FF');
-  Decoration get className => const Decoration(color: '#000080');
-  Decoration get commentTaskTag => const Decoration(color: '#008000');
-  Decoration get currentLine => const Decoration(color: '#EEEEEE');
-  Decoration get deletionIndication => const Decoration(color: '#9b5656');
-  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
-  Decoration get enumName => const Decoration(color: '#800040');
-  Decoration get field => const Decoration(color: '#800080');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#EFEFEF');
-  Decoration get findScope => const Decoration(color: '#BCADAD');
-  Decoration get foreground => const Decoration(color: '#8000FF');
-  Decoration get inheritedMethod => const Decoration(color: '#FF00FF');
-  Decoration get interface => const Decoration(color: '#9b5656');
-  Decoration get javadoc => const Decoration(color: '#800080');
-  Decoration get javadocKeyword => const Decoration(color: '#0000FF');
-  Decoration get javadocLink => const Decoration(color: '#800080');
-  Decoration get javadocTag => const Decoration(color: '#801f91');
-  Decoration get keyword => const Decoration(color: '#0000FF');
-  Decoration get lineNumber => const Decoration(color: '#999999');
-  Decoration get localVariable => const Decoration(color: '#000080');
-  Decoration get localVariableDeclaration => const Decoration(color: '#000080');
-  Decoration get method => const Decoration(color: '#FF00FF');
-  Decoration get methodDeclaration => const Decoration(color: '#FF00FF');
-  Decoration get multiLineComment => const Decoration(color: '#008000');
-  Decoration get number => const Decoration(color: '#FF8000');
-  Decoration get occurrenceIndication => const Decoration(color: '#EFEFEF');
-  Decoration get operator => const Decoration(color: '#8000FF');
-  Decoration get parameterVariable => const Decoration(color: '#0000FF');
-  Decoration get searchResultIndication => const Decoration(color: '#EFEFEF');
-  Decoration get selectionBackground => const Decoration(color: '#EEEEEE');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get singleLineComment => const Decoration(color: '#008000');
-  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
-  Decoration get staticField => const Decoration(color: '#800040');
-  Decoration get staticFinalField => const Decoration(color: '#800040');
-  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
-  Decoration get string => const Decoration(color: '#808080');
-  Decoration get typeArgument => const Decoration(color: '#885d3b');
-  Decoration get typeParameter => const Decoration(color: '#885d3b');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#EFEFEF');
-}
-
-/// Oblivion theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/oblivion.xml.
-/// Author: Roger Dudler.
-class OblivionTheme extends Theme {
-  const OblivionTheme();
-
-  String get name => 'Oblivion';
-
-  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
-  Decoration get annotation => const Decoration(color: '#FFFFFF');
-  Decoration get background => const Decoration(color: '#1E1E1E');
-  Decoration get bracket => const Decoration(color: '#D8D8D8');
-  Decoration get className => const Decoration(color: '#D25252');
-  Decoration get commentTaskTag => const Decoration(color: '#CCDF32');
-  Decoration get constant => const Decoration(color: '#EFC090');
-  Decoration get currentLine => const Decoration(color: '#2A2A2A');
-  Decoration get deletionIndication => const Decoration(color: '#D25252');
-  Decoration get deprecatedMember => const Decoration(color: '#D25252');
-  Decoration get dynamicType => const Decoration(color: '#79ABFF');
-  Decoration get enumName => const Decoration(color: '#7FB347');
-  Decoration get field => const Decoration(color: '#BED6FF');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#000000');
-  Decoration get findScope => const Decoration(color: '#111111');
-  Decoration get foreground => const Decoration(color: '#D8D8D8');
-  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
-  Decoration get interface => const Decoration(color: '#D197D9');
-  Decoration get javadoc => const Decoration(color: '#CCDF32');
-  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
-  Decoration get javadocLink => const Decoration(color: '#D9E577');
-  Decoration get javadocTag => const Decoration(color: '#D9E577');
-  Decoration get keyword => const Decoration(color: '#FFFFFF');
-  Decoration get lineNumber => const Decoration(color: '#D0D0D0');
-  Decoration get localVariable => const Decoration(color: '#79ABFF');
-  Decoration get localVariableDeclaration => const Decoration(color: '#BED6FF');
-  Decoration get method => const Decoration(color: '#FFFFFF');
-  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
-  Decoration get multiLineComment => const Decoration(color: '#C7DD0C');
-  Decoration get number => const Decoration(color: '#7FB347');
-  Decoration get occurrenceIndication => const Decoration(color: '#000000');
-  Decoration get operator => const Decoration(color: '#D8D8D8');
-  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
-  Decoration get searchResultIndication => const Decoration(color: '#000000');
-  Decoration get selectionBackground => const Decoration(color: '#404040');
-  Decoration get selectionForeground => const Decoration(color: '#D0D0D0');
-  Decoration get singleLineComment => const Decoration(color: '#C7DD0C');
-  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
-  Decoration get staticField => const Decoration(color: '#EFC090');
-  Decoration get staticFinalField => const Decoration(color: '#EFC090');
-  Decoration get staticMethod => const Decoration(color: '#BED6FF');
-  Decoration get string => const Decoration(color: '#FFC600');
-  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
-  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
-}
-
-/// Obsidian theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/obsidian.xml.
-/// Author: Morinar.
-class ObsidianTheme extends Theme {
-  const ObsidianTheme();
-
-  String get name => 'Obsidian';
-
-  Decoration get abstractMethod => const Decoration(color: '#E0E2E4');
-  Decoration get annotation => const Decoration(color: '#A082BD');
-  Decoration get background => const Decoration(color: '#293134');
-  Decoration get bracket => const Decoration(color: '#E8E2B7');
-  Decoration get className => const Decoration(color: '#678CB1');
-  Decoration get commentTaskTag => const Decoration(color: '#FF8BFF');
-  Decoration get constant => const Decoration(color: '#A082BD');
-  Decoration get currentLine => const Decoration(color: '#2F393C');
-  Decoration get deletionIndication => const Decoration(color: '#E0E2E4');
-  Decoration get deprecatedMember => const Decoration(color: '#E0E2E4');
-  Decoration get dynamicType => const Decoration(color: '#E0E2E4');
-  Decoration get enumName => const Decoration(color: '#E0E2E4');
-  Decoration get field => const Decoration(color: '#678CB1');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#616161');
-  Decoration get findScope => const Decoration(color: '#E0E2E4');
-  Decoration get foreground => const Decoration(color: '#E0E2E4');
-  Decoration get inheritedMethod => const Decoration(color: '#E0E2E4');
-  Decoration get interface => const Decoration(color: '#678CB1');
-  Decoration get javadoc => const Decoration(color: '#7D8C93');
-  Decoration get javadocKeyword => const Decoration(color: '#A082BD');
-  Decoration get javadocLink => const Decoration(color: '#678CB1');
-  Decoration get javadocTag => const Decoration(color: '#E0E2E4');
-  Decoration get keyword => const Decoration(color: '#93C763');
-  Decoration get lineNumber => const Decoration(color: '#81969A');
-  Decoration get localVariable => const Decoration(color: '#E0E2E4');
-  Decoration get localVariableDeclaration => const Decoration(color: '#E0E2E4');
-  Decoration get method => const Decoration(color: '#678CB1');
-  Decoration get methodDeclaration => const Decoration(color: '#E8E2B7');
-  Decoration get multiLineComment => const Decoration(color: '#7D8C93');
-  Decoration get number => const Decoration(color: '#FFCD22');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#E8E2B7');
-  Decoration get parameterVariable => const Decoration(color: '#E0E2E4');
-  Decoration get searchResultIndication => const Decoration(color: '#616161');
-  Decoration get selectionBackground => const Decoration(color: '#804000');
-  Decoration get selectionForeground => const Decoration(color: '#E0E2E4');
-  Decoration get singleLineComment => const Decoration(color: '#7D8C93');
-  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
-  Decoration get staticField => const Decoration(color: '#678CB1');
-  Decoration get staticFinalField => const Decoration(color: '#E0E2E4');
-  Decoration get staticMethod => const Decoration(color: '#E0E2E4');
-  Decoration get string => const Decoration(color: '#EC7600');
-  Decoration get typeArgument => const Decoration(color: '#E0E2E4');
-  Decoration get typeParameter => const Decoration(color: '#E0E2E4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#616161');
-}
-
-/// Pastel theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/pastel.xml.
-/// Author: Ian Kabeary.
-class PastelTheme extends Theme {
-  const PastelTheme();
-
-  String get name => 'Pastel';
-
-  Decoration get abstractMethod => const Decoration(color: '#E0E2E4');
-  Decoration get annotation => const Decoration(color: '#A082BD');
-  Decoration get background => const Decoration(color: '#1f2223');
-  Decoration get bracket => const Decoration(color: '#95bed8');
-  Decoration get className => const Decoration(color: '#678CB1');
-  Decoration get commentTaskTag => const Decoration(color: '#a57b61');
-  Decoration get constant => const Decoration(color: '#A082BD');
-  Decoration get currentLine => const Decoration(color: '#2F393C');
-  Decoration get deletionIndication => const Decoration(color: '#E0E2E4');
-  Decoration get deprecatedMember => const Decoration(color: '#E0E2E4');
-  Decoration get dynamicType => const Decoration(color: '#E0E2E4');
-  Decoration get enumName => const Decoration(color: '#E0E2E4');
-  Decoration get field => const Decoration(color: '#678CB1');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#616161');
-  Decoration get findScope => const Decoration(color: '#E0E2E4');
-  Decoration get foreground => const Decoration(color: '#E0E2E4');
-  Decoration get inheritedMethod => const Decoration(color: '#E0E2E4');
-  Decoration get interface => const Decoration(color: '#678CB1');
-  Decoration get javadoc => const Decoration(color: '#7D8C93');
-  Decoration get javadocKeyword => const Decoration(color: '#A082BD');
-  Decoration get javadocLink => const Decoration(color: '#678CB1');
-  Decoration get javadocTag => const Decoration(color: '#E0E2E4');
-  Decoration get keyword => const Decoration(color: '#a57b61');
-  Decoration get lineNumber => const Decoration(color: '#81969A');
-  Decoration get localVariable => const Decoration(color: '#E0E2E4');
-  Decoration get localVariableDeclaration => const Decoration(color: '#E0E2E4');
-  Decoration get method => const Decoration(color: '#678CB1');
-  Decoration get methodDeclaration => const Decoration(color: '#95bed8');
-  Decoration get multiLineComment => const Decoration(color: '#7D8C93');
-  Decoration get number => const Decoration(color: '#c78d9b');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#E8E2B7');
-  Decoration get parameterVariable => const Decoration(color: '#E0E2E4');
-  Decoration get searchResultIndication => const Decoration(color: '#616161');
-  Decoration get selectionBackground => const Decoration(color: '#95bed8');
-  Decoration get selectionForeground => const Decoration(color: '#E0E2E4');
-  Decoration get singleLineComment => const Decoration(color: '#7D8C93');
-  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
-  Decoration get staticField => const Decoration(color: '#678CB1');
-  Decoration get staticFinalField => const Decoration(color: '#E0E2E4');
-  Decoration get staticMethod => const Decoration(color: '#E0E2E4');
-  Decoration get string => const Decoration(color: '#c78d9b');
-  Decoration get typeArgument => const Decoration(color: '#E0E2E4');
-  Decoration get typeParameter => const Decoration(color: '#E0E2E4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#616161');
-}
-
-/// RecognEyes theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/recogneyes.xml.
-/// Author: Dan.
-class RecognEyesTheme extends Theme {
-  const RecognEyesTheme();
-
-  String get name => 'RecognEyes';
-
-  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
-  Decoration get annotation => const Decoration(color: '#FFFFFF');
-  Decoration get background => const Decoration(color: '#101020');
-  Decoration get bracket => const Decoration(color: '#D0D0D0');
-  Decoration get className => const Decoration(color: '#FF8080');
-  Decoration get commentTaskTag => const Decoration(color: '#00FF00');
-  Decoration get constant => const Decoration(color: '#FFFF00');
-  Decoration get currentLine => const Decoration(color: '#202030');
-  Decoration get deletionIndication => const Decoration(color: '#FFFFFF');
-  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
-  Decoration get dynamicType => const Decoration(color: '#79ABFF');
-  Decoration get enumName => const Decoration(color: '#FFFFFF');
-  Decoration get field => const Decoration(color: '#BED6FF');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#606080');
-  Decoration get findScope => const Decoration(color: '#FFFFFF');
-  Decoration get foreground => const Decoration(color: '#D0D0D0');
-  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
-  Decoration get interface => const Decoration(color: '#D197D9');
-  Decoration get javadoc => const Decoration(color: '#CCDF32');
-  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
-  Decoration get javadocLink => const Decoration(color: '#D9E577');
-  Decoration get javadocTag => const Decoration(color: '#D9E577');
-  Decoration get keyword => const Decoration(color: '#00D0D0');
-  Decoration get lineNumber => const Decoration(color: '#2B91AF');
-  Decoration get localVariable => const Decoration(color: '#79ABFF');
-  Decoration get localVariableDeclaration => const Decoration(color: '#BED6FF');
-  Decoration get method => const Decoration(color: '#D0D0D0');
-  Decoration get methodDeclaration => const Decoration(color: '#BED6FF');
-  Decoration get multiLineComment => const Decoration(color: '#00E000');
-  Decoration get number => const Decoration(color: '#FFFF00');
-  Decoration get occurrenceIndication => const Decoration(color: '#000000');
-  Decoration get operator => const Decoration(color: '#D0D0D0');
-  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
-  Decoration get searchResultIndication => const Decoration(color: '#006080');
-  Decoration get selectionBackground => const Decoration(color: '#0000FF');
-  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
-  Decoration get singleLineComment => const Decoration(color: '#00E000');
-  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
-  Decoration get staticField => const Decoration(color: '#EFC090');
-  Decoration get staticFinalField => const Decoration(color: '#EFC090');
-  Decoration get staticMethod => const Decoration(color: '#BED6FF');
-  Decoration get string => const Decoration(color: '#DC78DC');
-  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
-  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
-}
-
-/// Retta theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/retta.xml.
-/// Author: Eric.
-class RettaTheme extends Theme {
-  const RettaTheme();
-
-  String get name => 'Retta';
-
-  Decoration get abstractMethod => const Decoration(color: '#A4B0C0');
-  Decoration get annotation => const Decoration(color: '#FFFFFF');
-  Decoration get background => const Decoration(color: '#000000');
-  Decoration get bracket => const Decoration(color: '#F8E1AA');
-  Decoration get className => const Decoration(color: '#DE6546', bold: true);
-  Decoration get commentTaskTag => const Decoration(color: '#83786E');
-  Decoration get constant => const Decoration(color: '#EFC090');
-  Decoration get currentLine => const Decoration(color: '#2A2A2A');
-  Decoration get deletionIndication => const Decoration(color: '#DE6546');
-  Decoration get deprecatedMember => const Decoration(color: '#DE6546');
-  Decoration get dynamicType => const Decoration(color: '#F8E1AA');
-  Decoration get enumName => const Decoration(color: '#527D5D', bold: true);
-  Decoration get field => const Decoration(color: '#DE6546');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#395EB1');
-  Decoration get findScope => const Decoration(color: '#FFFF00');
-  Decoration get foreground => const Decoration(color: '#F8E1AA');
-  Decoration get inheritedMethod => const Decoration(color: '#A4B0C0');
-  Decoration get interface => const Decoration(color: '#527D5D', bold: true);
-  Decoration get javadoc => const Decoration(color: '#83786E');
-  Decoration get javadocKeyword => const Decoration(color: '#83786E');
-  Decoration get javadocLink => const Decoration(color: '#83786E');
-  Decoration get javadocTag => const Decoration(color: '#A19387');
-  Decoration get keyword => const Decoration(color: '#E79E3C', bold: true);
-  Decoration get lineNumber => const Decoration(color: '#C97138');
-  Decoration get localVariable => const Decoration(color: '#F8E1AA');
-  Decoration get localVariableDeclaration => const Decoration(color: '#F8E1AA');
-  Decoration get method => const Decoration(color: '#A4B0C0');
-  Decoration get methodDeclaration => const Decoration(color: '#A4B0C0');
-  Decoration get multiLineComment => const Decoration(color: '#83786E');
-  Decoration get number => const Decoration(color: '#D6C248');
-  Decoration get occurrenceIndication => const Decoration(color: '#5E5C56');
-  Decoration get operator => const Decoration(color: '#D6C248');
-  Decoration get parameterVariable => const Decoration(color: '#A4B0C0');
-  Decoration get searchResultIndication => const Decoration(color: '#395EB1');
-  Decoration get selectionBackground => const Decoration(color: '#527D5D');
-  Decoration get selectionForeground => const Decoration(color: '#F8E1AA');
-  Decoration get singleLineComment => const Decoration(color: '#83786E');
-  Decoration get sourceHoverBackground => const Decoration(color: '#FF00FF');
-  Decoration get staticField => const Decoration(color: '#F8E1A3');
-  Decoration get staticFinalField => const Decoration(color: '#F8E1A3');
-  Decoration get staticMethod => const Decoration(color: '#A4B0C0');
-  Decoration get string => const Decoration(color: '#D6C248');
-  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
-  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#527D5D');
-}
-
-/// Roboticket theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/roboticket.xml.
-/// Author: Robopuff.
-class RoboticketTheme extends Theme {
-  const RoboticketTheme();
-
-  String get name => 'Roboticket';
-
-  Decoration get abstractMethod => const Decoration(color: '#2C577C');
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#F5F5F5');
-  Decoration get bracket => const Decoration(color: '#B05A65');
-  Decoration get className => const Decoration(color: '#AB2525');
-  Decoration get commentTaskTag => const Decoration(color: '#295F94');
-  Decoration get constant => const Decoration(color: '#0A0B0C');
-  Decoration get currentLine => const Decoration(color: '#E0E0FF');
-  Decoration get deletionIndication => const Decoration(color: '#9B5656');
-  Decoration get deprecatedMember => const Decoration(color: '#AB2525');
-  Decoration get enumName => const Decoration(color: '#885D3B');
-  Decoration get field => const Decoration(color: '#566874');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#FFDF99');
-  Decoration get findScope => const Decoration(color: '#BDD8F2');
-  Decoration get foreground => const Decoration(color: '#585858');
-  Decoration get inheritedMethod => const Decoration(color: '#2C577C');
-  Decoration get interface => const Decoration(color: '#9B5656');
-  Decoration get javadoc => const Decoration(color: '#AD95AF');
-  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
-  Decoration get javadocLink => const Decoration(color: '#AD95AF');
-  Decoration get javadocTag => const Decoration(color: '#566874');
-  Decoration get keyword => const Decoration(color: '#295F94');
-  Decoration get lineNumber => const Decoration(color: '#AFBFCF');
-  Decoration get localVariable => const Decoration(color: '#55aa55');
-  Decoration get localVariableDeclaration => const Decoration(color: '#B05A65');
-  Decoration get method => const Decoration(color: '#BC5A65', bold: true);
-  Decoration get methodDeclaration => const Decoration(color: '#B05A65');
-  Decoration get multiLineComment => const Decoration(color: '#AD95AF');
-  Decoration get number => const Decoration(color: '#AF0F91');
-  Decoration get occurrenceIndication => const Decoration(color: '#FFCFBB');
-  Decoration get operator => const Decoration(color: '#000000');
-  Decoration get parameterVariable => const Decoration(color: '#55aa55');
-  Decoration get searchResultIndication => const Decoration(color: '#FFDF99');
-  Decoration get selectionBackground => const Decoration(color: '#BDD8F2');
-  Decoration get selectionForeground => const Decoration(color: '#484848');
-  Decoration get singleLineComment => const Decoration(color: '#AD95AF');
-  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
-  Decoration get staticField => const Decoration(color: '#885D3B');
-  Decoration get staticFinalField => const Decoration(color: '#885D3B');
-  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
-  Decoration get string => const Decoration(color: '#317ECC');
-  Decoration get typeArgument => const Decoration(color: '#885D3B');
-  Decoration get typeParameter => const Decoration(color: '#885D3B');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#FFCFBB');
-}
-
-/// Schuss theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/schuss.xml.
-/// Author: Vasil Stoychev.
-class SchussTheme extends Theme {
-  const SchussTheme();
-
-  String get name => 'Schuss';
-
-  Decoration get abstractMethod => const Decoration(color: '#2c577c');
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#FFFFFF');
-  Decoration get bracket => const Decoration(color: '#000f6a');
-  Decoration get className => const Decoration(color: '#ca3349');
-  Decoration get commentTaskTag => const Decoration(color: '#d7d3cc');
-  Decoration get constant => const Decoration(color: '#ae25ab');
-  Decoration get currentLine => const Decoration(color: '#fff7cd');
-  Decoration get deletionIndication => const Decoration(color: '#9b5656');
-  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
-  Decoration get enumName => const Decoration(color: '#135a20');
-  Decoration get field => const Decoration(color: '#566874');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#CC6633');
-  Decoration get findScope => const Decoration(color: '#BCADAD');
-  Decoration get foreground => const Decoration(color: '#430400');
-  Decoration get inheritedMethod => const Decoration(color: '#2c577c');
-  Decoration get interface => const Decoration(color: '#ca3349');
-  Decoration get javadoc => const Decoration(color: '#05314d');
-  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
-  Decoration get javadocLink => const Decoration(color: '#05314d');
-  Decoration get javadocTag => const Decoration(color: '#05314d');
-  Decoration get keyword => const Decoration(color: '#606060');
-  Decoration get lineNumber => const Decoration(color: '#999999');
-  Decoration get localVariable => const Decoration(color: '#2b6488');
-  Decoration get localVariableDeclaration => const Decoration(color: '#ca3349');
-  Decoration get method => const Decoration(color: '#797a8a');
-  Decoration get methodDeclaration => const Decoration(color: '#4f6d8f');
-  Decoration get multiLineComment => const Decoration(color: '#d5d9e5');
-  Decoration get number => const Decoration(color: '#d0321f');
-  Decoration get occurrenceIndication => const Decoration(color: '#CC6633');
-  Decoration get operator => const Decoration(color: '#5f97a9');
-  Decoration get parameterVariable => const Decoration(color: '#5c8198');
-  Decoration get searchResultIndication => const Decoration(color: '#CC6633');
-  Decoration get selectionBackground => const Decoration(color: '#f4fdff');
-  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
-  Decoration get singleLineComment => const Decoration(color: '#d7d3cc');
-  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
-  Decoration get staticField => const Decoration(color: '#464646');
-  Decoration get staticFinalField => const Decoration(color: '#464646');
-  Decoration get staticMethod => const Decoration(color: '#797a8a');
-  Decoration get string => const Decoration(color: '#585545');
-  Decoration get typeArgument => const Decoration(color: '#d07fcd');
-  Decoration get typeParameter => const Decoration(color: '#d07fcd');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#CC6633');
-}
-
-/// Sublime Text 2 theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/sublime-text-2.xml.
-/// Author: Filip Minev.
-class Sublime_Text_2Theme extends Theme {
-  const Sublime_Text_2Theme();
-
-  String get name => 'Sublime Text 2';
-
-  Decoration get abstractMethod => const Decoration(color: '#BED6FF');
-  Decoration get annotation => const Decoration(color: '#FFFFFF');
-  Decoration get background => const Decoration(color: '#272822');
-  Decoration get bracket => const Decoration(color: '#F9FAF4');
-  Decoration get className => const Decoration(color: '#52E3F6');
-  Decoration get commentTaskTag => const Decoration(color: '#FFFFFF');
-  Decoration get currentLine => const Decoration(color: '#5B5A4E');
-  Decoration get deletionIndication => const Decoration(color: '#FF0000');
-  Decoration get deprecatedMember => const Decoration(color: '#FF0000');
-  Decoration get dynamicType => const Decoration(color: '#CFBFAD');
-  Decoration get field => const Decoration(color: '#CFBFAD');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#D8D8D8');
-  Decoration get findScope => const Decoration(color: '#000000');
-  Decoration get foreground => const Decoration(color: '#CFBFAD');
-  Decoration get inheritedMethod => const Decoration(color: '#BED6FF');
-  Decoration get interface => const Decoration(color: '#52E3F6');
-  Decoration get javadoc => const Decoration(color: '#FFFFFF');
-  Decoration get javadocKeyword => const Decoration(color: '#D9E577');
-  Decoration get javadocLink => const Decoration(color: '#CFBFAD');
-  Decoration get javadocTag => const Decoration(color: '#CFBFAD');
-  Decoration get keyword => const Decoration(color: '#FF007F');
-  Decoration get lineNumber => const Decoration(color: '#999999');
-  Decoration get localVariable => const Decoration(color: '#CFBFAD');
-  Decoration get localVariableDeclaration => const Decoration(color: '#CFBFAD');
-  Decoration get method => const Decoration(color: '#A7EC21');
-  Decoration get methodDeclaration => const Decoration(color: '#A7EC21');
-  Decoration get multiLineComment => const Decoration(color: '#FFFFFF');
-  Decoration get number => const Decoration(color: '#C48CFF');
-  Decoration get occurrenceIndication => const Decoration(color: '#000000');
-  Decoration get operator => const Decoration(color: '#FF007F');
-  Decoration get parameterVariable => const Decoration(color: '#79ABFF');
-  Decoration get searchResultIndication => const Decoration(color: '#D8D8D8');
-  Decoration get selectionBackground => const Decoration(color: '#CC9900');
-  Decoration get selectionForeground => const Decoration(color: '#404040');
-  Decoration get singleLineComment => const Decoration(color: '#FFFFFF');
-  Decoration get sourceHoverBackground => const Decoration(color: '#FFFFFF');
-  Decoration get staticField => const Decoration(color: '#CFBFAD');
-  Decoration get staticFinalField => const Decoration(color: '#CFBFAD');
-  Decoration get staticMethod => const Decoration(color: '#A7EC21');
-  Decoration get string => const Decoration(color: '#ECE47E');
-  Decoration get typeArgument => const Decoration(color: '#BFA4A4');
-  Decoration get typeParameter => const Decoration(color: '#BFA4A4');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#000000');
-}
-
-/// Sunburst theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/sunburst.xml.
-/// Author: Viorel Craescu.
-class SunburstTheme extends Theme {
-  const SunburstTheme();
-
-  String get name => 'Sunburst';
-
-  Decoration get abstractMethod => const Decoration(color: '#F9F9F9');
-  Decoration get annotation => const Decoration(color: '#A020F0');
-  Decoration get background => const Decoration(color: '#000000');
-  Decoration get bracket => const Decoration(color: '#F9F9F9');
-  Decoration get className => const Decoration(color: '#F9F9F9');
-  Decoration get commentTaskTag => const Decoration(color: '#A8A8A8');
-  Decoration get constant => const Decoration(color: '#3D9AD6');
-  Decoration get currentLine => const Decoration(color: '#2F2F2F');
-  Decoration get deletionIndication => const Decoration(color: '#D25252');
-  Decoration get deprecatedMember => const Decoration(color: '#F9F9F9');
-  Decoration get dynamicType => const Decoration(color: '#4B9CE9');
-  Decoration get enumName => const Decoration(color: '#7FB347');
-  Decoration get field => const Decoration(color: '#4B9CE9');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#5A5A5A');
-  Decoration get findScope => const Decoration(color: '#DDF0FF');
-  Decoration get foreground => const Decoration(color: '#F9F9F9');
-  Decoration get inheritedMethod => const Decoration(color: '#F9F9F9');
-  Decoration get interface => const Decoration(color: '#F9F9F9');
-  Decoration get javadoc => const Decoration(color: '#A8A8A8');
-  Decoration get javadocKeyword => const Decoration(color: '#EA9C77');
-  Decoration get javadocLink => const Decoration(color: '#548FA0');
-  Decoration get javadocTag => const Decoration(color: '#A8A8A8');
-  Decoration get keyword => const Decoration(color: '#EA9C77');
-  Decoration get lineNumber => const Decoration(color: '#F9F9F9');
-  Decoration get localVariable => const Decoration(color: '#4B9CE9');
-  Decoration get localVariableDeclaration => const Decoration(color: '#4B9CE9');
-  Decoration get method => const Decoration(color: '#F9F9F9');
-  Decoration get methodDeclaration => const Decoration(color: '#F9F9F9');
-  Decoration get multiLineComment => const Decoration(color: '#A8A8A8');
-  Decoration get number => const Decoration(color: '#F9F9F9');
-  Decoration get occurrenceIndication => const Decoration(color: '#5A5A5A');
-  Decoration get operator => const Decoration(color: '#F9F9F9');
-  Decoration get parameterVariable => const Decoration(color: '#4B9CE9');
-  Decoration get searchResultIndication => const Decoration(color: '#5A5A5A');
-  Decoration get selectionBackground => const Decoration(color: '#DDF0FF');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get singleLineComment => const Decoration(color: '#A8A8A8');
-  Decoration get sourceHoverBackground => const Decoration(color: '#000000');
-  Decoration get staticField => const Decoration(color: '#4B9CE9');
-  Decoration get staticFinalField => const Decoration(color: '#4B9CE9');
-  Decoration get staticMethod => const Decoration(color: '#F9F9F9');
-  Decoration get string => const Decoration(color: '#76BA53');
-  Decoration get typeArgument => const Decoration(color: '#4B9CE9');
-  Decoration get typeParameter => const Decoration(color: '#4B9CE9');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#5A5A5A');
-}
-
-/// Tango theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/tango.xml.
-/// Author: Roger Dudler.
-class TangoTheme extends Theme {
-  const TangoTheme();
-
-  String get name => 'Tango';
-
-  Decoration get abstractMethod => const Decoration(color: '#2c577c');
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#FFFFFF');
-  Decoration get bracket => const Decoration(color: '#444444');
-  Decoration get className => const Decoration(color: '#37550d');
-  Decoration get commentTaskTag => const Decoration(color: '#17608f');
-  Decoration get currentLine => const Decoration(color: '#EEEEEE');
-  Decoration get deletionIndication => const Decoration(color: '#9b5656');
-  Decoration get deprecatedMember => const Decoration(color: '#ab2525');
-  Decoration get dynamicType => const Decoration(color: '#5c8198');
-  Decoration get enumName => const Decoration(color: '#885d3b');
-  Decoration get field => const Decoration(color: '#566874');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#EFEFEF');
-  Decoration get findScope => const Decoration(color: '#BCADAD');
-  Decoration get foreground => const Decoration(color: '#000000');
-  Decoration get inheritedMethod => const Decoration(color: '#2c577c');
-  Decoration get interface => const Decoration(color: '#9b5656');
-  Decoration get javadoc => const Decoration(color: '#05314d');
-  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
-  Decoration get javadocLink => const Decoration(color: '#05314d');
-  Decoration get javadocTag => const Decoration(color: '#05314d');
-  Decoration get keyword => const Decoration(color: '#688046');
-  Decoration get lineNumber => const Decoration(color: '#999999');
-  Decoration get localVariable => const Decoration(color: '#5c8198');
-  Decoration get localVariableDeclaration => const Decoration(color: '#5c8198');
-  Decoration get method => const Decoration(color: '#444444');
-  Decoration get methodDeclaration => const Decoration(color: '#222222');
-  Decoration get multiLineComment => const Decoration(color: '#17608f');
-  Decoration get number => const Decoration(color: '#801f91');
-  Decoration get occurrenceIndication => const Decoration(color: '#EFEFEF');
-  Decoration get operator => const Decoration(color: '#000000');
-  Decoration get parameterVariable => const Decoration(color: '#5c8198');
-  Decoration get searchResultIndication => const Decoration(color: '#EFEFEF');
-  Decoration get selectionBackground => const Decoration(color: '#EEEEEE');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get singleLineComment => const Decoration(color: '#17608f');
-  Decoration get sourceHoverBackground => const Decoration(color: '#EEEEEE');
-  Decoration get staticField => const Decoration(color: '#885d3b');
-  Decoration get staticFinalField => const Decoration(color: '#885d3b');
-  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
-  Decoration get string => const Decoration(color: '#92679a');
-  Decoration get typeArgument => const Decoration(color: '#885d3b');
-  Decoration get typeParameter => const Decoration(color: '#885d3b');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#EFEFEF');
-}
-
-/// Vibrant Ink theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/vibrantink.xml.
-/// Author: indiehead.
-class Vibrant_InkTheme extends Theme {
-  const Vibrant_InkTheme();
-
-  String get name => 'Vibrant Ink';
-
-  Decoration get abstractMethod => const Decoration(color: '#F1C436');
-  Decoration get background => const Decoration(color: '#191919');
-  Decoration get bracket => const Decoration(color: '#FFFFFF');
-  Decoration get className => const Decoration(color: '#9CF828');
-  Decoration get commentTaskTag => const Decoration(color: '#800080');
-  Decoration get currentLine => const Decoration(color: '#222220');
-  Decoration get deletionIndication => const Decoration(color: '#FF0000');
-  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
-  Decoration get dynamicType => const Decoration(color: '#3C758D');
-  Decoration get enumName => const Decoration(color: '#408000');
-  Decoration get field => const Decoration(color: '#357A8F');
-  Decoration get findScope => const Decoration(color: '#191919');
-  Decoration get foreground => const Decoration(color: '#FFFFFF');
-  Decoration get inheritedMethod => const Decoration(color: '#E3B735');
-  Decoration get interface => const Decoration(color: '#87F025');
-  Decoration get javadoc => const Decoration(color: '#8C3FC8');
-  Decoration get javadocKeyword => const Decoration(color: '#800080');
-  Decoration get javadocLink => const Decoration(color: '#814582');
-  Decoration get javadocTag => const Decoration(color: '#800080');
-  Decoration get keyword => const Decoration(color: '#EC691E');
-  Decoration get lineNumber => const Decoration(color: '#666666');
-  Decoration get localVariable => const Decoration(color: '#3C758D');
-  Decoration get localVariableDeclaration => const Decoration(color: '#357A92');
-  Decoration get method => const Decoration(color: '#F7C527');
-  Decoration get methodDeclaration => const Decoration(color: '#F1C438');
-  Decoration get multiLineComment => const Decoration(color: '#8C3FC8');
-  Decoration get number => const Decoration(color: '#477488');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#FFFFFF');
-  Decoration get parameterVariable => const Decoration(color: '#408000');
-  Decoration get selectionBackground => const Decoration(color: '#414C3B');
-  Decoration get selectionForeground => const Decoration(color: '#FFFFFF');
-  Decoration get singleLineComment => const Decoration(color: '#8146A2');
-  Decoration get staticField => const Decoration(color: '#FFFFFF');
-  Decoration get staticFinalField => const Decoration(color: '#80FF00');
-  Decoration get staticMethod => const Decoration(color: '#FFFFFF');
-  Decoration get string => const Decoration(color: '#477488');
-  Decoration get typeArgument => const Decoration(color: '#D9B0AC');
-  Decoration get typeParameter => const Decoration(color: '#CDB1AD');
-}
-
-/// Wombat theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/wombat.xml.
-/// Author: Lars H. Nielsen.
-class WombatTheme extends Theme {
-  const WombatTheme();
-
-  String get name => 'Wombat';
-
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#242424');
-  Decoration get bracket => const Decoration(color: '#f3f6ee');
-  Decoration get className => const Decoration(color: '#cae682');
-  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
-  Decoration get currentLine => const Decoration(color: '#656565');
-  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
-  Decoration get dynamicType => const Decoration(color: '#D4C4A9');
-  Decoration get field => const Decoration(color: '#cae682');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#3f3f6a');
-  Decoration get findScope => const Decoration(color: '#BCADAD');
-  Decoration get foreground => const Decoration(color: '#f6f3e8');
-  Decoration get interface => const Decoration(color: '#CAE682');
-  Decoration get javadoc => const Decoration(color: '#b3b5af');
-  Decoration get javadocKeyword => const Decoration(color: '#f08080');
-  Decoration get javadocLink => const Decoration(color: '#a7a7d1');
-  Decoration get javadocTag => const Decoration(color: '#a7a7d1');
-  Decoration get keyword => const Decoration(color: '#8ac6f2');
-  Decoration get lineNumber => const Decoration(color: '#656565');
-  Decoration get localVariable => const Decoration(color: '#D4C4A9');
-  Decoration get localVariableDeclaration => const Decoration(color: '#D4C4A9');
-  Decoration get method => const Decoration(color: '#f3f6ee');
-  Decoration get methodDeclaration => const Decoration(color: '#f3f6ee');
-  Decoration get multiLineComment => const Decoration(color: '#99968b');
-  Decoration get number => const Decoration(color: '#f08080');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#f3f6ee');
-  Decoration get searchResultIndication => const Decoration(color: '#464467');
-  Decoration get selectionBackground => const Decoration(color: '#898941');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get singleLineComment => const Decoration(color: '#99968b');
-  Decoration get sourceHoverBackground => const Decoration(color: '#a19879');
-  Decoration get staticField => const Decoration(color: '#93A2CC');
-  Decoration get staticFinalField => const Decoration(color: '#53dccd');
-  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
-  Decoration get string => const Decoration(color: '#95e454');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
-}
-
-/// Zenburn theme extracted from
-/// ../editor/tools/plugins/com.google.dart.tools.deploy/themes/zenburn.xml.
-/// Author: Janni Nurminen.
-class ZenburnTheme extends Theme {
-  const ZenburnTheme();
-
-  String get name => 'Zenburn';
-
-  Decoration get annotation => const Decoration(color: '#808080');
-  Decoration get background => const Decoration(color: '#404040');
-  Decoration get bracket => const Decoration(color: '#FFFFFF');
-  Decoration get className => const Decoration(color: '#CAE682');
-  Decoration get commentTaskTag => const Decoration(color: '#ACC1AC');
-  Decoration get currentLine => const Decoration(color: '#505050');
-  Decoration get deprecatedMember => const Decoration(color: '#FFFFFF');
-  Decoration get dynamicType => const Decoration(color: '#D4C4A9');
-  Decoration get field => const Decoration(color: '#B3B784');
-  Decoration get filteredSearchResultIndication => const Decoration(color: '#3F3F6A');
-  Decoration get findScope => const Decoration(color: '#BCADAD');
-  Decoration get foreground => const Decoration(color: '#F6F3E8');
-  Decoration get interface => const Decoration(color: '#CAE682');
-  Decoration get javadoc => const Decoration(color: '#B3B5AF');
-  Decoration get javadocKeyword => const Decoration(color: '#CC9393');
-  Decoration get javadocLink => const Decoration(color: '#A893CC');
-  Decoration get javadocTag => const Decoration(color: '#9393CC');
-  Decoration get keyword => const Decoration(color: '#EFEFAF');
-  Decoration get lineNumber => const Decoration(color: '#C0C0C0');
-  Decoration get localVariable => const Decoration(color: '#D4C4A9');
-  Decoration get localVariableDeclaration => const Decoration(color: '#D4C4A9');
-  Decoration get method => const Decoration(color: '#DFBE95');
-  Decoration get methodDeclaration => const Decoration(color: '#DFBE95');
-  Decoration get multiLineComment => const Decoration(color: '#7F9F7F');
-  Decoration get number => const Decoration(color: '#8ACCCF');
-  Decoration get occurrenceIndication => const Decoration(color: '#616161');
-  Decoration get operator => const Decoration(color: '#F0EFD0');
-  Decoration get searchResultIndication => const Decoration(color: '#464467');
-  Decoration get selectionBackground => const Decoration(color: '#898941');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get singleLineComment => const Decoration(color: '#7F9F7F');
-  Decoration get sourceHoverBackground => const Decoration(color: '#A19879');
-  Decoration get staticField => const Decoration(color: '#93A2CC');
-  Decoration get staticFinalField => const Decoration(color: '#53DCCD');
-  Decoration get staticMethod => const Decoration(color: '#C4C4B7');
-  Decoration get string => const Decoration(color: '#CC9393');
-  Decoration get writeOccurrenceIndication => const Decoration(color: '#948567');
-}
-
-/// List of known themes. The default is the first theme.
-const List<Theme> THEMES = const <Theme> [
-    const Theme(),
-    const Black_PastelTheme(),
-    const DartboardTheme(),
-    const DebuggingTheme(),
-    const Dart_EditorTheme(),
-    const frontenddevTheme(),
-    const Gedit_Original_OblivionTheme(),
-    const HavenjarkTheme(),
-    const Hot_PinkTheme(),
-    const InkpotTheme(),
-    const minimalTheme(),
-    const MonokaiTheme(),
-    const MrTheme(),
-    const NightLion_Aptana_ThemeTheme(),
-    const Notepad___LikeTheme(),
-    const OblivionTheme(),
-    const ObsidianTheme(),
-    const PastelTheme(),
-    const RecognEyesTheme(),
-    const RettaTheme(),
-    const RoboticketTheme(),
-    const SchussTheme(),
-    const Sublime_Text_2Theme(),
-    const SunburstTheme(),
-    const TangoTheme(),
-    const Vibrant_InkTheme(),
-    const WombatTheme(),
-    const ZenburnTheme(),
-];
diff --git a/site/try/src/html_to_text.dart b/site/try/src/html_to_text.dart
deleted file mode 100644
index 532cad6..0000000
--- a/site/try/src/html_to_text.dart
+++ /dev/null
@@ -1,77 +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 trydart.htmlToText;
-
-import 'dart:math' show
-    max;
-
-import 'dart:html' show
-    CharacterData,
-    Element,
-    Node,
-    NodeFilter,
-    ShadowRoot,
-    TreeWalker;
-
-import 'selection.dart' show
-    TrySelection;
-
-import 'shadow_root.dart' show
-    WALKER_NEXT,
-    WALKER_SKIP_NODE,
-    walkNodes;
-
-/// Returns true if [node] is a block element, that is, not inline.
-bool isBlockElement(Node node) {
-  if (node is! Element) return false;
-  Element element = node;
-
-  // TODO(ahe): Remove this line by changing code completion to avoid using a
-  // div element.
-  if (element.classes.contains('dart-code-completion')) return false;
-
-  var display = element.getComputedStyle().display;
-  return display != 'inline' && display != 'none';
-}
-
-/// Writes the text of [root] to [buffer]. Keeps track of [selection] and
-/// returns the new anchorOffset from beginning of [buffer] or -1 if the
-/// selection isn't in [root].
-int htmlToText(Node root,
-               StringBuffer buffer,
-               TrySelection selection,
-               {bool treatRootAsInline: false}) {
-  int selectionOffset = -1;
-  walkNodes(root, (Node node) {
-    if (selection.anchorNode == node) {
-      selectionOffset = selection.anchorOffset + buffer.length;
-    }
-    switch (node.nodeType) {
-      case Node.CDATA_SECTION_NODE:
-      case Node.TEXT_NODE:
-        CharacterData text = node;
-        buffer.write(text.data.replaceAll('\xA0', ' '));
-        break;
-
-      default:
-        if (node.nodeName == 'BR') {
-          buffer.write('\n');
-        } else if (node != root && isBlockElement(node)) {
-          selectionOffset =
-              max(selectionOffset, htmlToText(node, buffer, selection));
-          return WALKER_SKIP_NODE;
-        }
-        break;
-    }
-
-    return WALKER_NEXT;
-  });
-
-  if (!treatRootAsInline && isBlockElement(root)) {
-    buffer.write('\n');
-  }
-
-  return selectionOffset;
-}
diff --git a/site/try/src/iframe_error_handler.dart b/site/try/src/iframe_error_handler.dart
deleted file mode 100644
index a1077be..0000000
--- a/site/try/src/iframe_error_handler.dart
+++ /dev/null
@@ -1,96 +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 trydart.iframe_error_handler;
-
-// TODO(ahe): Remove this import if issue 17936 is fixed.
-import 'dart:js' as hack;
-
-import 'dart:html' show
-    Event,
-    IFrameElement,
-    window;
-
-import 'dart:async' show
-    Stream,
-    StreamController;
-
-class ErrorMessage {
-  final String message;
-  final String filename;
-  final num lineno;
-  final num colno;
-  final String stack;
-
-  ErrorMessage(
-      this.message, this.filename, this.lineno, this.colno, this.stack);
-
-  String toString() {
-    String result = filename == null ? '' : filename;
-    if (lineno != null && lineno != 0 && !lineno.isNaN) {
-      result += ':$lineno';
-    }
-    if (colno != null && colno != 0 && !colno.isNaN) {
-      result += ':$colno';
-    }
-    if (message != null && !message.isEmpty) {
-      if (!result.isEmpty) {
-        result += ': ';
-      }
-      result += message;
-    }
-    if (stack != null && !stack.isEmpty) {
-      if (!result.isEmpty) {
-        result += '\n';
-      }
-      result += stack;
-    }
-    return result;
-  }
-}
-
-Stream<ErrorMessage> errorStream(IFrameElement iframe) {
-  StreamController<ErrorMessage> controller =
-      new StreamController<ErrorMessage>();
-  void onError(
-      String message,
-      String filename,
-      int lineno,
-      [int colno,
-       error]) {
-    // See:
-    // https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
-    String stack;
-    if (error != null) {
-      var jsStack = error['stack'];
-      if (jsStack != null) {
-        stack = hack.context.callMethod('String', [jsStack]);
-      }
-    }
-    controller.add(new ErrorMessage(message, filename, lineno, colno, stack));
-  }
-
-  void installErrorHandler() {
-    // This method uses dart:js to install an error event handler on the content
-    // window of [iframe]. This is a workaround for http://dartbug.com/17936.
-    var iframeProxy = new hack.JsObject.fromBrowserObject(iframe);
-    var contentWindowProxy = iframeProxy['contentWindow'];
-    if (contentWindowProxy == null) {
-      String message =
-          'No contentWindow, call this method *after* adding iframe to'
-          ' document.';
-      window.console.error(message);
-      throw message;
-    }
-
-    // Note: we have two options, use "iframe.contentWindow.onerror = ..." or
-    // "iframe.contentWindow.addEventListener('error', ...)".  The former seems
-    // to provide more details on both Chrome and Firefox (which provides no
-    // information at all in error events).
-    contentWindowProxy['onerror'] = onError;
-  }
-  iframe.onLoad.listen((Event event) => installErrorHandler());
-  installErrorHandler();
-  return controller.stream;
-}
diff --git a/site/try/src/interaction_manager.dart b/site/try/src/interaction_manager.dart
deleted file mode 100644
index 89ddf76..0000000
--- a/site/try/src/interaction_manager.dart
+++ /dev/null
@@ -1,1356 +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 trydart.interaction_manager;
-
-import 'dart:html';
-
-import 'dart:convert' show
-    JSON;
-
-import 'dart:math' show
-    max,
-    min;
-
-import 'dart:async' show
-    Completer,
-    Future,
-    Timer;
-
-import 'dart:collection' show
-    Queue;
-
-import 'package:compiler/src/scanner/string_scanner.dart' show
-    StringScanner;
-
-import 'package:compiler/src/tokens/token.dart' show
-    BeginGroupToken,
-    ErrorToken,
-    Token,
-    UnmatchedToken,
-    UnterminatedToken;
-
-import 'package:compiler/src/tokens/token_constants.dart' show
-    EOF_TOKEN,
-    STRING_INTERPOLATION_IDENTIFIER_TOKEN,
-    STRING_INTERPOLATION_TOKEN,
-    STRING_TOKEN;
-
-import 'package:compiler/src/io/source_file.dart' show
-    StringSourceFile;
-
-import 'package:compiler/src/string_validator.dart' show
-    StringValidator;
-
-import 'package:compiler/src/tree/tree.dart' show
-    StringQuoting;
-
-import 'compilation.dart' show
-    currentSource,
-    startCompilation;
-
-import 'ui.dart' show
-    currentTheme,
-    hackDiv,
-    mainEditorPane,
-    observer,
-    outputDiv,
-    outputFrame,
-    statusDiv;
-
-import 'decoration.dart' show
-    CodeCompletionDecoration,
-    Decoration,
-    DiagnosticDecoration,
-    error,
-    info,
-    warning;
-
-import 'html_to_text.dart' show
-    htmlToText;
-
-import 'compilation_unit.dart' show
-    CompilationUnit;
-
-import 'selection.dart' show
-    TrySelection,
-    isCollapsed;
-
-import 'editor.dart' as editor;
-
-import 'mock.dart' as mock;
-
-import 'settings.dart' as settings;
-
-import 'shadow_root.dart' show
-    getShadowRoot,
-    getText,
-    setShadowRoot,
-    containsNode;
-
-import 'iframe_error_handler.dart' show
-    ErrorMessage;
-
-const String TRY_DART_NEW_DEFECT =
-    'https://code.google.com/p/dart/issues/entry'
-    '?template=Try+Dart+Internal+Error';
-
-/// How frequently [InteractionManager.onHeartbeat] is called.
-const Duration HEARTBEAT_INTERVAL = const Duration(milliseconds: 50);
-
-/// Determines how frequently "project" files are saved.  The time is measured
-/// from the time of last modification.
-const Duration SAVE_INTERVAL = const Duration(seconds: 5);
-
-/// Determines how frequently the compiler is invoked.  The time is measured
-/// from the time of last modification.
-const Duration COMPILE_INTERVAL = const Duration(seconds: 1);
-
-/// Determines how frequently the compiler is invoked in "live" mode.  The time
-/// is measured from the time of last modification.
-const Duration LIVE_COMPILE_INTERVAL = const Duration(seconds: 0);
-
-/// Determines if a compilation is slow.  The time is measured from the last
-/// compilation started.  If a compilation is slow, progress information is
-/// displayed to the user, but the console is untouched if the compilation
-/// finished quickly.  The purpose is to reduce flicker in the UI.
-const Duration SLOW_COMPILE = const Duration(seconds: 1);
-
-const int TAB_WIDTH = 2;
-
-/**
- * UI interaction manager for the entire application.
- */
-abstract class InteractionManager {
-  // Design note: All UI interactions go through one instance of this
-  // class. This is by design.
-  //
-  // Simplicity in UI is in the eye of the beholder, not the implementor. Great
-  // 'natural UI' is usually achieved with substantial implementation
-  // complexity that doesn't modularize well and has nasty complicated state
-  // dependencies.
-  //
-  // In rare cases, some UI components can be independent of this state
-  // machine. For example, animation and auto-save loops.
-
-  // Implementation note: The state machine is actually implemented by
-  // [InteractionContext], this class represents public event handlers.
-
-  factory InteractionManager() => new InteractionContext();
-
-  InteractionManager.internal();
-
-  // TODO(ahe): Remove this.
-  Set<AnchorElement> get oldDiagnostics;
-
-  void onInput(Event event);
-
-  // TODO(ahe): Rename to onKeyDown (as it is called in response to keydown
-  // event).
-  void onKeyUp(KeyboardEvent event);
-
-  void onMutation(List<MutationRecord> mutations, MutationObserver observer);
-
-  void onSelectionChange(Event event);
-
-  /// Called when the content of a CompilationUnit changed.
-  void onCompilationUnitChanged(CompilationUnit unit);
-
-  Future<List<String>> projectFileNames();
-
-  /// Called when the user selected a new project file.
-  void onProjectFileSelected(String projectFile);
-
-  /// Called when notified about a project file changed (on the server).
-  void onProjectFileFsEvent(MessageEvent e);
-
-  /// Called every [HEARTBEAT_INTERVAL].
-  void onHeartbeat(Timer timer);
-
-  /// Called by [:window.onMessage.listen:].
-  void onWindowMessage(MessageEvent event);
-
-  void onCompilationFailed(String firstError);
-
-  void onCompilationDone();
-
-  /// Called when a compilation is starting, but just before sending the
-  /// initiating message to the compiler isolate.
-  void compilationStarting();
-
-  // TODO(ahe): Remove this from InteractionManager, but not from InitialState.
-  void consolePrintLine(line);
-
-  /// Called just before running a freshly compiled program.
-  void aboutToRun();
-
-  /// Called when an error occurs when running user code in an iframe.
-  void onIframeError(ErrorMessage message);
-
-  void verboseCompilerMessage(String message);
-
-  /// Called if the compiler crashes.
-  void onCompilerCrash(data);
-
-  /// Called if an internal error is detected.
-  void onInternalError(message);
-}
-
-/**
- * State machine for UI interactions.
- */
-class InteractionContext extends InteractionManager {
-  InteractionState state;
-
-  final Map<String, CompilationUnit> projectFiles = <String, CompilationUnit>{};
-
-  final Set<CompilationUnit> modifiedUnits = new Set<CompilationUnit>();
-
-  final Queue<CompilationUnit> unitsToSave = new Queue<CompilationUnit>();
-
-  /// Tracks time since last modification of a "project" file.
-  final Stopwatch saveTimer = new Stopwatch();
-
-  /// Tracks time since last modification.
-  final Stopwatch compileTimer = new Stopwatch();
-
-  /// Tracks elapsed time of current compilation.
-  final Stopwatch elapsedCompilationTime = new Stopwatch();
-
-  CompilationUnit currentCompilationUnit =
-      // TODO(ahe): Don't use a fake unit.
-      new CompilationUnit('fake', '');
-
-  Timer heartbeat;
-
-  Completer<String> completeSaveOperation;
-
-  bool shouldClearConsole = false;
-
-  Element compilerConsole;
-
-  bool isFirstCompile = true;
-
-  final Set<AnchorElement> oldDiagnostics = new Set<AnchorElement>();
-
-  final Duration compileInterval = settings.live.value
-      ? LIVE_COMPILE_INTERVAL
-      : COMPILE_INTERVAL;
-
-  InteractionContext()
-      : super.internal() {
-    state = new InitialState(this);
-    heartbeat = new Timer.periodic(HEARTBEAT_INTERVAL, onHeartbeat);
-  }
-
-  void onInput(Event event) => state.onInput(event);
-
-  void onKeyUp(KeyboardEvent event) => state.onKeyUp(event);
-
-  void onMutation(List<MutationRecord> mutations, MutationObserver observer) {
-    workAroundFirefoxBug();
-    try {
-      try {
-        return state.onMutation(mutations, observer);
-      } finally {
-        // Discard any mutations during the observer, as these can lead to
-        // infinite loop.
-        observer.takeRecords();
-      }
-    } catch (error, stackTrace) {
-      try {
-        editor.isMalformedInput = true;
-        state.onInternalError(
-            '\nError and stack trace:\n$error\n$stackTrace\n');
-      } catch (e) {
-        // Double faults ignored.
-      }
-      rethrow;
-    }
-  }
-
-  void onSelectionChange(Event event) => state.onSelectionChange(event);
-
-  void onCompilationUnitChanged(CompilationUnit unit) {
-    return state.onCompilationUnitChanged(unit);
-  }
-
-  Future<List<String>> projectFileNames() => state.projectFileNames();
-
-  void onProjectFileSelected(String projectFile) {
-    return state.onProjectFileSelected(projectFile);
-  }
-
-  void onProjectFileFsEvent(MessageEvent e) {
-    return state.onProjectFileFsEvent(e);
-  }
-
-  void onHeartbeat(Timer timer) => state.onHeartbeat(timer);
-
-  void onWindowMessage(MessageEvent event) => state.onWindowMessage(event);
-
-  void onCompilationFailed(String firstError) {
-    return state.onCompilationFailed(firstError);
-  }
-
-  void onCompilationDone() => state.onCompilationDone();
-
-  void compilationStarting() => state.compilationStarting();
-
-  void consolePrintLine(line) => state.consolePrintLine(line);
-
-  void aboutToRun() => state.aboutToRun();
-
-  void onIframeError(ErrorMessage message) => state.onIframeError(message);
-
-  void verboseCompilerMessage(String message) {
-    return state.verboseCompilerMessage(message);
-  }
-
-  void onCompilerCrash(data) => state.onCompilerCrash(data);
-
-  void onInternalError(message) => state.onInternalError(message);
-}
-
-abstract class InteractionState implements InteractionManager {
-  InteractionContext get context;
-
-  // TODO(ahe): Remove this.
-  Set<AnchorElement> get oldDiagnostics {
-    throw 'Use context.oldDiagnostics instead';
-  }
-
-  void set state(InteractionState newState);
-
-  void onStateChanged(InteractionState previous) {
-  }
-
-  void transitionToInitialState() {
-    state = new InitialState(context);
-  }
-}
-
-class InitialState extends InteractionState {
-  final InteractionContext context;
-  bool requestCodeCompletion = false;
-
-  InitialState(this.context);
-
-  void set state(InteractionState state) {
-    InteractionState previous = context.state;
-    if (previous != state) {
-      context.state = state;
-      state.onStateChanged(previous);
-    }
-  }
-
-  void onInput(Event event) {
-    state = new PendingInputState(context);
-  }
-
-  void onKeyUp(KeyboardEvent event) {
-    if (computeHasModifier(event)) {
-      onModifiedKeyUp(event);
-    } else {
-      onUnmodifiedKeyUp(event);
-    }
-  }
-
-  void onModifiedKeyUp(KeyboardEvent event) {
-    if (event.getModifierState("Shift")) return onShiftedKeyUp(event);
-    switch (event.keyCode) {
-      case KeyCode.S:
-        // Disable Ctrl-S, Cmd-S, etc. We have observed users hitting these
-        // keys often when using Try Dart and getting frustrated.
-        event.preventDefault();
-        // TODO(ahe): Consider starting a compilation.
-        break;
-    }
-  }
-
-  void onShiftedKeyUp(KeyboardEvent event) {
-    switch (event.keyCode) {
-      case KeyCode.TAB:
-        event.preventDefault();
-        break;
-    }
-  }
-
-  void onUnmodifiedKeyUp(KeyboardEvent event) {
-    switch (event.keyCode) {
-      case KeyCode.ENTER: {
-        Selection selection = window.getSelection();
-        if (isCollapsed(selection)) {
-          event.preventDefault();
-          Node node = selection.anchorNode;
-          if (node is Text) {
-            Text text = node;
-            int offset = selection.anchorOffset;
-            // If at end-of-file, insert an extra newline.  The the extra
-            // newline ensures that the next line isn't empty.  At least Chrome
-            // behaves as if "\n" is just a single line. "\nc" (where c is any
-            // character) is two lines, according to Chrome.
-            String newline = isAtEndOfFile(text, offset) ? '\n\n' : '\n';
-            text.insertData(offset, newline);
-            selection.collapse(text, offset + 1);
-          } else if (node is Element) {
-            node.appendText('\n\n');
-            selection.collapse(node.firstChild, 1);
-          } else {
-            window.console
-                ..error('Unexpected node')
-                ..dir(node);
-          }
-        }
-        break;
-      }
-      case KeyCode.TAB: {
-        Selection selection = window.getSelection();
-        if (isCollapsed(selection)) {
-          event.preventDefault();
-          Text text = new Text(' ' * TAB_WIDTH);
-          selection.getRangeAt(0).insertNode(text);
-          selection.collapse(text, TAB_WIDTH);
-        }
-        break;
-      }
-    }
-
-    // This is a hack to get Safari (iOS) to send mutation events on
-    // contenteditable.
-    // TODO(ahe): Move to onInput?
-    var newDiv = new DivElement();
-    hackDiv.replaceWith(newDiv);
-    hackDiv = newDiv;
-  }
-
-  void onMutation(List<MutationRecord> mutations, MutationObserver observer) {
-    removeCodeCompletion();
-
-    Selection selection = window.getSelection();
-    TrySelection trySelection = new TrySelection(mainEditorPane, selection);
-
-    Set<Node> normalizedNodes = new Set<Node>();
-    for (MutationRecord record in mutations) {
-      normalizeMutationRecord(record, trySelection, normalizedNodes);
-    }
-
-    if (normalizedNodes.length == 1) {
-      Node node = normalizedNodes.single;
-      if (node is Element && node.classes.contains('lineNumber')) {
-        print('Single line change: ${node.outerHtml}');
-
-        updateHighlighting(node, selection, trySelection, mainEditorPane);
-        return;
-      }
-    }
-
-    updateHighlighting(mainEditorPane, selection, trySelection);
-  }
-
-  void updateHighlighting(
-      Element node,
-      Selection selection,
-      TrySelection trySelection,
-      [Element root]) {
-    String state = '';
-    String currentText = getText(node);
-    if (root != null) {
-      // Single line change.
-      trySelection = trySelection.copyWithRoot(node);
-      Element previousLine = node.previousElementSibling;
-      if (previousLine != null) {
-        state = previousLine.getAttribute('dart-state');
-      }
-
-      node.parentNode.insertAllBefore(
-          createHighlightedNodes(trySelection, currentText, state),
-          node);
-      node.remove();
-    } else {
-      root = node;
-      editor.seenIdentifiers = new Set<String>.from(mock.identifiers);
-
-      // Fail safe: new [nodes] are computed before clearing old nodes.
-      List<Node> nodes =
-          createHighlightedNodes(trySelection, currentText, state);
-
-      node.nodes
-          ..clear()
-          ..addAll(nodes);
-    }
-
-    if (containsNode(mainEditorPane, trySelection.anchorNode)) {
-      // Sometimes the anchor node is removed by the above call. This has
-      // only been observed in Firefox, and is hard to reproduce.
-      trySelection.adjust(selection);
-    }
-
-    // TODO(ahe): We know almost exactly what has changed.  It could be
-    // more efficient to only communicate what changed.
-    context.currentCompilationUnit.content = getText(root);
-
-    // Discard highlighting mutations.
-    observer.takeRecords();
-  }
-
-  List<Node> createHighlightedNodes(
-      TrySelection trySelection,
-      String currentText,
-      String state) {
-    trySelection.updateText(currentText);
-
-    editor.isMalformedInput = false;
-    int offset = 0;
-    List<Node> nodes = <Node>[];
-
-    for (String line in splitLines(currentText)) {
-      List<Node> lineNodes = <Node>[];
-      state =
-          tokenizeAndHighlight(line, state, offset, trySelection, lineNodes);
-      offset += line.length;
-      nodes.add(makeLine(lineNodes, state));
-    }
-
-    return nodes;
-  }
-
-  void onSelectionChange(Event event) {
-  }
-
-  void onStateChanged(InteractionState previous) {
-    super.onStateChanged(previous);
-    context.compileTimer
-        ..start()
-        ..reset();
-  }
-
-  void onCompilationUnitChanged(CompilationUnit unit) {
-    if (unit == context.currentCompilationUnit) {
-      currentSource = unit.content;
-      if (context.projectFiles.containsKey(unit.name)) {
-        postProjectFileUpdate(unit);
-      }
-      context.compileTimer.start();
-    } else {
-      print("Unexpected change to compilation unit '${unit.name}'.");
-    }
-  }
-
-  void postProjectFileUpdate(CompilationUnit unit) {
-    context.modifiedUnits.add(unit);
-    context.saveTimer.start();
-  }
-
-  Future<List<String>> projectFileNames() {
-    return getString('project?list').then((String response) {
-      WebSocket socket = new WebSocket('ws://127.0.0.1:9090/ws/watch');
-      socket.onMessage.listen(context.onProjectFileFsEvent);
-      return new List<String>.from(JSON.decode(response));
-    });
-  }
-
-  void onProjectFileSelected(String projectFile) {
-    // Disable editing whilst fetching data.
-    mainEditorPane.contentEditable = 'false';
-
-    CompilationUnit unit = context.projectFiles[projectFile];
-    Future<CompilationUnit> future;
-    if (unit != null) {
-      // This project file had been fetched already.
-      future = new Future<CompilationUnit>.value(unit);
-
-      // TODO(ahe): Probably better to fetch the sources again.
-    } else {
-      // This project file has to be fetched.
-      future = getString('project/$projectFile').then((String text) {
-        CompilationUnit unit = context.projectFiles[projectFile];
-        if (unit == null) {
-          // Only create a new unit if the value hadn't arrived already.
-          unit = new CompilationUnit(projectFile, text);
-          context.projectFiles[projectFile] = unit;
-        } else {
-          // TODO(ahe): Probably better to overwrite sources. Create a new
-          // unit?
-          // The server should push updates to the client.
-        }
-        return unit;
-      });
-    }
-    future.then((CompilationUnit unit) {
-      mainEditorPane
-          ..contentEditable = 'true'
-          ..nodes.clear();
-      observer.takeRecords(); // Discard mutations.
-
-      transitionToInitialState();
-      context.currentCompilationUnit = unit;
-
-      // Install the code, which will trigger a call to onMutation.
-      mainEditorPane.appendText(unit.content);
-    });
-  }
-
-  void transitionToInitialState() {}
-
-  void onProjectFileFsEvent(MessageEvent e) {
-    Map map = JSON.decode(e.data);
-    List modified = map['modify'];
-    if (modified == null) return;
-    for (String name in modified) {
-      Completer completer = context.completeSaveOperation;
-      if (completer != null && !completer.isCompleted) {
-        completer.complete(name);
-      } else {
-        onUnexpectedServerModification(name);
-      }
-    }
-  }
-
-  void onUnexpectedServerModification(String name) {
-    if (context.currentCompilationUnit.name == name) {
-      mainEditorPane.contentEditable = 'false';
-      statusDiv.text = 'Modified on disk';
-    }
-  }
-
-  void onHeartbeat(Timer timer) {
-    if (context.unitsToSave.isEmpty &&
-        context.saveTimer.elapsed > SAVE_INTERVAL) {
-      context.saveTimer
-          ..stop()
-          ..reset();
-      context.unitsToSave.addAll(context.modifiedUnits);
-      context.modifiedUnits.clear();
-      saveUnits();
-    }
-    if (!settings.compilationPaused &&
-        context.compileTimer.elapsed > context.compileInterval) {
-      if (startCompilation()) {
-        context.compileTimer
-            ..stop()
-            ..reset();
-      }
-    }
-
-    if (context.elapsedCompilationTime.elapsed > SLOW_COMPILE) {
-      if (context.compilerConsole.parent == null) {
-        outputDiv.append(context.compilerConsole);
-      }
-    }
-  }
-
-  void saveUnits() {
-    if (context.unitsToSave.isEmpty) return;
-    CompilationUnit unit = context.unitsToSave.removeFirst();
-    onError(ProgressEvent event) {
-      HttpRequest request = event.target;
-      statusDiv.text = "Couldn't save '${unit.name}': ${request.responseText}";
-      context.completeSaveOperation.complete(unit.name);
-    }
-    new HttpRequest()
-        ..open("POST", "/project/${unit.name}")
-        ..onError.listen(onError)
-        ..send(unit.content);
-    void setupCompleter() {
-      context.completeSaveOperation = new Completer<String>.sync();
-      context.completeSaveOperation.future.then((String name) {
-        if (name == unit.name) {
-          print("Saved source of '$name'");
-          saveUnits();
-        } else {
-          setupCompleter();
-        }
-      });
-    }
-    setupCompleter();
-  }
-
-  void onWindowMessage(MessageEvent event) {
-    if (event.source is! WindowBase || event.source == window) {
-      return onBadMessage(event);
-    }
-    if (event.data is List) {
-      List message = event.data;
-      if (message.length > 0) {
-        switch (message[0]) {
-          case 'scrollHeight':
-            return onScrollHeightMessage(message[1]);
-        }
-      }
-      return onBadMessage(event);
-    } else {
-      return consolePrintLine(event.data);
-    }
-  }
-
-  /// Called when an iframe is modified.
-  void onScrollHeightMessage(int scrollHeight) {
-    window.console.log('scrollHeight = $scrollHeight');
-    if (scrollHeight > 8) {
-      outputFrame.style
-          ..height = '${scrollHeight}px'
-          ..visibility = ''
-          ..position = '';
-      while (outputFrame.nextNode is IFrameElement) {
-        outputFrame.nextNode.remove();
-      }
-    }
-  }
-
-  void onBadMessage(MessageEvent event) {
-    window.console
-        ..groupCollapsed('Bad message')
-        ..dir(event)
-        ..log(event.source.runtimeType)
-        ..groupEnd();
-  }
-
-  void consolePrintLine(line) {
-    if (context.shouldClearConsole) {
-      context.shouldClearConsole = false;
-      outputDiv.nodes.clear();
-    }
-    if (window.parent != window) {
-      // Test support.
-      // TODO(ahe): Use '/' instead of '*' when Firefox is upgraded to version
-      // 30 across build bots.  Support for '/' was added in version 29, and we
-      // support the two most recent versions.
-      window.parent.postMessage('$line\n', '*');
-    }
-    outputDiv.appendText('$line\n');
-  }
-
-  void onCompilationFailed(String firstError) {
-    if (firstError == null) {
-      consolePrintLine('Compilation failed.');
-    } else {
-      consolePrintLine('Compilation failed: $firstError');
-    }
-  }
-
-  void onCompilationDone() {
-    context.isFirstCompile = false;
-    context.elapsedCompilationTime.stop();
-    Duration compilationDuration = context.elapsedCompilationTime.elapsed;
-    context.elapsedCompilationTime.reset();
-    print('Compilation took $compilationDuration.');
-    if (context.compilerConsole.parent != null) {
-      context.compilerConsole.remove();
-    }
-    for (AnchorElement diagnostic in context.oldDiagnostics) {
-      if (diagnostic.parent != null) {
-        // Problem fixed, remove the diagnostic.
-        diagnostic.replaceWith(new Text(getText(diagnostic)));
-      }
-    }
-    context.oldDiagnostics.clear();
-    observer.takeRecords(); // Discard mutations.
-  }
-
-  void compilationStarting() {
-    var progress = new SpanElement()
-        ..appendHtml('<i class="icon-spinner icon-spin"></i>')
-        ..appendText(' Compiling Dart program.');
-    if (settings.verboseCompiler) {
-      progress.appendText('..');
-    }
-    context.compilerConsole = new SpanElement()
-        ..append(progress)
-        ..appendText('\n');
-    context.shouldClearConsole = true;
-    context.elapsedCompilationTime
-        ..start()
-        ..reset();
-    if (context.isFirstCompile) {
-      outputDiv.append(context.compilerConsole);
-    }
-    var diagnostics = mainEditorPane.querySelectorAll('a.diagnostic');
-    context.oldDiagnostics
-        ..clear()
-        ..addAll(diagnostics);
-  }
-
-  void aboutToRun() {
-    context.shouldClearConsole = true;
-  }
-
-  void onIframeError(ErrorMessage message) {
-    // TODO(ahe): Consider replacing object URLs with something like <a
-    // href='...'>out.js</a>.
-    // TODO(ahe): Use source maps to translate stack traces.
-    consolePrintLine(message);
-  }
-
-  void verboseCompilerMessage(String message) {
-    if (settings.verboseCompiler) {
-      context.compilerConsole.appendText('$message\n');
-    } else {
-      if (isCompilerStageMarker(message)) {
-        Element progress = context.compilerConsole.firstChild;
-        progress.appendText('.');
-      }
-    }
-  }
-
-  void onCompilerCrash(data) {
-    onInternalError('Error and stack trace:\n$data');
-  }
-
-  void onInternalError(message) {
-    outputDiv
-        ..nodes.clear()
-        ..append(new HeadingElement.h1()..appendText('Internal Error'))
-        ..appendText('We would appreciate if you take a moment to report '
-                     'this at ')
-        ..append(
-            new AnchorElement(href: TRY_DART_NEW_DEFECT)
-            ..target = '_blank'
-            ..appendText(TRY_DART_NEW_DEFECT))
-        ..appendText('$message');
-    if (window.parent != window) {
-      // Test support.
-      // TODO(ahe): Use '/' instead of '*' when Firefox is upgraded to version
-      // 30 across build bots.  Support for '/' was added in version 29, and we
-      // support the two most recent versions.
-      window.parent.postMessage('$message\n', '*');
-    }
-  }
-}
-
-Future<String> getString(uri) {
-  return new Future<String>.sync(() => HttpRequest.getString('$uri'));
-}
-
-class PendingInputState extends InitialState {
-  PendingInputState(InteractionContext context)
-      : super(context);
-
-  void onInput(Event event) {
-    // Do nothing.
-  }
-
-  void onMutation(List<MutationRecord> mutations, MutationObserver observer) {
-    super.onMutation(mutations, observer);
-
-    InteractionState nextState = new InitialState(context);
-    if (settings.enableCodeCompletion.value) {
-      Element parent = editor.getElementAtSelection();
-      Element ui;
-      if (parent != null) {
-        ui = parent.querySelector('.dart-code-completion');
-        if (ui != null) {
-          nextState = new CodeCompletionState(context, parent, ui);
-        }
-      }
-    }
-    state = nextState;
-  }
-}
-
-class CodeCompletionState extends InitialState {
-  final Element activeCompletion;
-  final Element ui;
-  int minWidth = 0;
-  DivElement staticResults;
-  SpanElement inline;
-  DivElement serverResults;
-  String inlineSuggestion;
-
-  CodeCompletionState(InteractionContext context,
-                      this.activeCompletion,
-                      this.ui)
-      : super(context);
-
-  void onInput(Event event) {
-    // Do nothing.
-  }
-
-  void onModifiedKeyUp(KeyboardEvent event) {
-    // TODO(ahe): Handle DOWN (jump to server results).
-  }
-
-  void onUnmodifiedKeyUp(KeyboardEvent event) {
-    switch (event.keyCode) {
-      case KeyCode.DOWN:
-        return moveDown(event);
-
-      case KeyCode.UP:
-        return moveUp(event);
-
-      case KeyCode.ESC:
-        event.preventDefault();
-        return endCompletion();
-
-      case KeyCode.TAB:
-      case KeyCode.RIGHT:
-      case KeyCode.ENTER:
-        event.preventDefault();
-        return endCompletion(acceptSuggestion: true);
-
-      case KeyCode.SPACE:
-        return endCompletion();
-    }
-  }
-
-  void moveDown(Event event) {
-    event.preventDefault();
-    move(1);
-  }
-
-  void moveUp(Event event) {
-    event.preventDefault();
-    move(-1);
-  }
-
-  void move(int direction) {
-    Element element = editor.moveActive(direction, ui);
-    if (element == null) return;
-    var text = activeCompletion.firstChild;
-    String prefix = "";
-    if (text is Text) prefix = text.data.trim();
-    updateInlineSuggestion(prefix, element.text);
-  }
-
-  void endCompletion({bool acceptSuggestion: false}) {
-    if (acceptSuggestion) {
-      suggestionAccepted();
-    }
-    activeCompletion.classes.remove('active');
-    mainEditorPane.querySelectorAll('.hazed-suggestion')
-        .forEach((e) => e.remove());
-    // The above changes create mutation records. This implicitly fire mutation
-    // events that result in saving the source code in local storage.
-    // TODO(ahe): Consider making this more explicit.
-    state = new InitialState(context);
-  }
-
-  void suggestionAccepted() {
-    if (inlineSuggestion != null) {
-      Text text = new Text(inlineSuggestion);
-      activeCompletion.replaceWith(text);
-      window.getSelection().collapse(text, inlineSuggestion.length);
-    }
-  }
-
-  void onMutation(List<MutationRecord> mutations, MutationObserver observer) {
-    for (MutationRecord record in mutations) {
-      if (!activeCompletion.contains(record.target)) {
-        endCompletion();
-        return super.onMutation(mutations, observer);
-      }
-    }
-
-    var text = activeCompletion.firstChild;
-    if (text is! Text) return endCompletion();
-    updateSuggestions(text.data.trim());
-  }
-
-  void onStateChanged(InteractionState previous) {
-    super.onStateChanged(previous);
-    displayCodeCompletion();
-  }
-
-  void displayCodeCompletion() {
-    Selection selection = window.getSelection();
-    if (selection.anchorNode is! Text) {
-      return endCompletion();
-    }
-    Text text = selection.anchorNode;
-    if (!activeCompletion.contains(text)) {
-      return endCompletion();
-    }
-
-    int anchorOffset = selection.anchorOffset;
-
-    String prefix = text.data.substring(0, anchorOffset).trim();
-    if (prefix.isEmpty) {
-      return endCompletion();
-    }
-
-    num height = activeCompletion.getBoundingClientRect().height;
-    activeCompletion.classes.add('active');
-    Node root = getShadowRoot(ui);
-
-    inline = new SpanElement()
-        ..classes.add('hazed-suggestion');
-    Text rest = text.splitText(anchorOffset);
-    text.parentNode.insertBefore(inline, text.nextNode);
-    activeCompletion.parentNode.insertBefore(
-        rest, activeCompletion.nextNode);
-
-    staticResults = new DivElement()
-        ..classes.addAll(['dart-static', 'dart-limited-height']);
-    serverResults = new DivElement()
-        ..style.display = 'none'
-        ..classes.add('dart-server');
-    root.nodes.addAll([staticResults, serverResults]);
-    ui.style.top = '${height}px';
-
-    staticResults.nodes.add(buildCompletionEntry(prefix));
-
-    updateSuggestions(prefix);
-  }
-
-  void updateInlineSuggestion(String prefix, String suggestion) {
-    inlineSuggestion = suggestion;
-
-    minWidth = max(minWidth, activeCompletion.getBoundingClientRect().width);
-
-    activeCompletion.style
-        ..display = 'inline-block'
-        ..minWidth = '${minWidth}px';
-
-    setShadowRoot(inline, suggestion.substring(prefix.length));
-    inline.style.display = '';
-
-    observer.takeRecords(); // Discard mutations.
-  }
-
-  void updateSuggestions(String prefix) {
-    if (prefix.isEmpty) {
-      return endCompletion();
-    }
-
-    Token first = tokenize(prefix);
-    for (Token token = first; token.kind != EOF_TOKEN; token = token.next) {
-      String tokenInfo = token.info.value;
-      if (token != first ||
-          tokenInfo != 'identifier' &&
-          tokenInfo != 'keyword') {
-        return endCompletion();
-      }
-    }
-
-    var borderHeight = 2; // 1 pixel border top & bottom.
-    num height = ui.getBoundingClientRect().height - borderHeight;
-    ui.style.minHeight = '${height}px';
-
-    minWidth =
-        max(minWidth, activeCompletion.getBoundingClientRect().width);
-
-    staticResults.nodes.clear();
-    serverResults.nodes.clear();
-
-    if (inlineSuggestion != null && inlineSuggestion.startsWith(prefix)) {
-      setShadowRoot(inline, inlineSuggestion.substring(prefix.length));
-    }
-
-    List<String> results = editor.seenIdentifiers.where(
-        (String identifier) {
-          return identifier != prefix && identifier.startsWith(prefix);
-        }).toList(growable: false);
-    results.sort();
-    if (results.isEmpty) results = <String>[prefix];
-
-    results.forEach((String completion) {
-      staticResults.nodes.add(buildCompletionEntry(completion));
-    });
-
-    if (settings.enableDartMind) {
-      // TODO(ahe): Move this code to its own function or class.
-      String encodedArg0 = Uri.encodeComponent('"$prefix"');
-      String mindQuery =
-          'http://dart-mind.appspot.com/rpc'
-          '?action=GetExportingPubCompletions'
-          '&arg0=$encodedArg0';
-      try {
-        var serverWatch = new Stopwatch()..start();
-        HttpRequest.getString(mindQuery).then((String responseText) {
-          serverWatch.stop();
-          List<String> serverSuggestions = JSON.decode(responseText);
-          if (!serverSuggestions.isEmpty) {
-            updateInlineSuggestion(prefix, serverSuggestions.first);
-          }
-          var root = getShadowRoot(ui);
-          for (int i = 1; i < serverSuggestions.length; i++) {
-            String completion = serverSuggestions[i];
-            DivElement where = staticResults;
-            int index = results.indexOf(completion);
-            if (index != -1) {
-              List<Element> entries = root.querySelectorAll(
-                  '.dart-static>.dart-entry');
-              entries[index].classes.add('doubleplusgood');
-            } else {
-              if (results.length > 3) {
-                serverResults.style.display = 'block';
-                where = serverResults;
-              }
-              Element entry = buildCompletionEntry(completion);
-              entry.classes.add('doubleplusgood');
-              where.nodes.add(entry);
-            }
-          }
-          serverResults.appendHtml(
-              '<div>${serverWatch.elapsedMilliseconds}ms</div>');
-          // Discard mutations.
-          observer.takeRecords();
-        }).catchError((error, stack) {
-          window.console.dir(error);
-          window.console.error('$stack');
-        });
-      } catch (error, stack) {
-        window.console.dir(error);
-        window.console.error('$stack');
-      }
-    }
-    // Discard mutations.
-    observer.takeRecords();
-  }
-
-  Element buildCompletionEntry(String completion) {
-    return new DivElement()
-        ..classes.add('dart-entry')
-        ..appendText(completion);
-  }
-
-  void transitionToInitialState() {
-    endCompletion();
-  }
-}
-
-Token tokenize(String text) {
-  var file = new StringSourceFile.fromName('', text);
-  return new StringScanner(file, includeComments: true).tokenize();
-}
-
-bool computeHasModifier(KeyboardEvent event) {
-  return
-      event.getModifierState("Alt") ||
-      event.getModifierState("AltGraph") ||
-      event.getModifierState("CapsLock") ||
-      event.getModifierState("Control") ||
-      event.getModifierState("Fn") ||
-      event.getModifierState("Meta") ||
-      event.getModifierState("NumLock") ||
-      event.getModifierState("ScrollLock") ||
-      event.getModifierState("Scroll") ||
-      event.getModifierState("Win") ||
-      event.getModifierState("Shift") ||
-      event.getModifierState("SymbolLock") ||
-      event.getModifierState("OS");
-}
-
-String tokenizeAndHighlight(String line,
-                            String state,
-                            int start,
-                            TrySelection trySelection,
-                            List<Node> nodes) {
-  String newState = '';
-  int offset = state.length;
-  int adjustedStart = start - state.length;
-
-  //   + offset  + charOffset  + globalOffset   + (charOffset + charCount)
-  //   v         v             v                v
-  // do          identifier_abcdefghijklmnopqrst
-  for (Token token = tokenize('$state$line');
-       token.kind != EOF_TOKEN;
-       token = token.next) {
-    int charOffset = token.charOffset;
-    int charCount = token.charCount;
-
-    Token tokenToDecorate = token;
-    if (token is UnterminatedToken && isUnterminatedMultiLineToken(token)) {
-      newState += '${token.start}';
-      continue; // This might not be an error.
-    } else {
-      Token follow = token.next;
-      if (token is BeginGroupToken && token.endGroup != null) {
-        follow = token.endGroup.next;
-      }
-      if (token.kind == STRING_TOKEN) {
-        follow = followString(follow);
-        if (follow is UnmatchedToken) {
-          if ('${follow.begin.value}' == r'${') {
-            newState += '${extractQuote(token.value)}';
-          }
-        }
-      }
-      if (follow is ErrorToken && follow.charOffset == token.charOffset) {
-        if (follow is UnmatchedToken) {
-          newState += '${follow.begin.value}';
-        } else {
-          tokenToDecorate = follow;
-        }
-      }
-    }
-
-    if (charOffset < offset) {
-      // Happens for scanner errors, or for the [state] prefix.
-      continue;
-    }
-
-    Decoration decoration;
-    if (charOffset - state.length == line.length - 1 && line.endsWith('\n')) {
-      // Don't add decorations to trailing newline.
-      decoration = null;
-    } else {
-      decoration = editor.getDecoration(tokenToDecorate);
-    }
-
-    if (decoration == null) continue;
-
-    // Add a node for text before current token.
-    trySelection.addNodeFromSubstring(
-        adjustedStart + offset, adjustedStart + charOffset, nodes);
-
-    // Add a node for current token.
-    trySelection.addNodeFromSubstring(
-        adjustedStart + charOffset,
-        adjustedStart + charOffset + charCount, nodes, decoration);
-
-    offset = charOffset + charCount;
-  }
-
-  // Add a node for anything after the last (decorated) token.
-  trySelection.addNodeFromSubstring(
-      adjustedStart + offset, start + line.length, nodes);
-
-  return newState;
-}
-
-bool isUnterminatedMultiLineToken(UnterminatedToken token) {
-  return
-      token.start == '/*' ||
-      token.start == "'''" ||
-      token.start == '"""' ||
-      token.start == "r'''" ||
-      token.start == 'r"""';
-}
-
-void normalizeMutationRecord(MutationRecord record,
-                             TrySelection selection,
-                             Set<Node> normalizedNodes) {
-  for (Node node in record.addedNodes) {
-    if (node.parentNode == null) continue;
-    normalizedNodes.add(findLine(node));
-    if (node is Text) continue;
-    StringBuffer buffer = new StringBuffer();
-    int selectionOffset = htmlToText(node, buffer, selection);
-    Text newNode = new Text('$buffer');
-    node.replaceWith(newNode);
-    if (selectionOffset != -1) {
-      selection.anchorNode = newNode;
-      selection.anchorOffset = selectionOffset;
-    }
-  }
-  if (!record.removedNodes.isEmpty) {
-    var first = record.removedNodes.first;
-    var line = findLine(record.target);
-
-    if (first is Text && line.nextNode != null) {
-      normalizedNodes.add(line.nextNode);
-    }
-    normalizedNodes.add(line);
-  }
-  if (record.type == "characterData" && record.target.parentNode != null) {
-    // At least Firefox sends a "characterData" record whose target is the
-    // deleted text node. It also sends a record where "removedNodes" isn't
-    // empty whose target is the parent (which we are interested in).
-    normalizedNodes.add(findLine(record.target));
-  }
-}
-
-// Finds the line of [node] (a parent node with CSS class 'lineNumber').
-// If no such parent exists, return mainEditorPane if it is a parent.
-// Otherwise return [node].
-Node findLine(Node node) {
-  for (Node n = node; n != null; n = n.parentNode) {
-    if (n is Element && n.classes.contains('lineNumber')) return n;
-    if (n == mainEditorPane) return n;
-  }
-  return node;
-}
-
-Element makeLine(List<Node> lineNodes, String state) {
-  return new SpanElement()
-      ..setAttribute('dart-state', state)
-      ..nodes.addAll(lineNodes)
-      ..classes.add('lineNumber');
-}
-
-bool isAtEndOfFile(Text text, int offset) {
-  Node line = findLine(text);
-  return
-      line.nextNode == null &&
-      text.parentNode.nextNode == null &&
-      offset == text.length;
-}
-
-List<String> splitLines(String text) {
-  return text.split(new RegExp('^', multiLine: true));
-}
-
-void removeCodeCompletion() {
-  List<Node> highlighting =
-      mainEditorPane.querySelectorAll('.dart-code-completion');
-  for (Element element in highlighting) {
-    element.remove();
-  }
-}
-
-bool isCompilerStageMarker(String message) {
-  return
-      message.startsWith('Package root is ') ||
-      message.startsWith('Compiling ') ||
-      message == "Resolving..." ||
-      message.startsWith('Resolved ') ||
-      message == "Inferring types..." ||
-      message == "Compiling..." ||
-      message.startsWith('Compiled ');
-}
-
-void workAroundFirefoxBug() {
-  Selection selection = window.getSelection();
-  if (!isCollapsed(selection)) return;
-  Node node = selection.anchorNode;
-  int offset = selection.anchorOffset;
-  if (node is Element && offset != 0) {
-    // In some cases, Firefox reports the wrong anchorOffset (always seems to
-    // be 6) when anchorNode is an Element. Moving the cursor back and forth
-    // adjusts the anchorOffset.
-    // Safari can also reach this code, but the offset isn't wrong, just
-    // inconsistent.  After moving the cursor back and forth, Safari will make
-    // the offset relative to a text node.
-    if (settings.hasSelectionModify.value) {
-      // IE doesn't support selection.modify, but it's okay since the code
-      // above is for Firefox, IE doesn't have problems with anchorOffset.
-      selection
-          ..modify('move', 'backward', 'character')
-          ..modify('move', 'forward', 'character');
-      print('Selection adjusted $node@$offset -> '
-            '${selection.anchorNode}@${selection.anchorOffset}.');
-    }
-  }
-}
-
-/// Compute the token following a string. Compare to parseSingleLiteralString
-/// in parser.dart.
-Token followString(Token token) {
-  // TODO(ahe): I should be able to get rid of this if I change the scanner to
-  // create BeginGroupToken for strings.
-  int kind = token.kind;
-  while (kind != EOF_TOKEN) {
-    if (kind == STRING_INTERPOLATION_TOKEN) {
-      // Looking at ${expression}.
-      BeginGroupToken begin = token;
-      token = begin.endGroup.next;
-    } else if (kind == STRING_INTERPOLATION_IDENTIFIER_TOKEN) {
-      // Looking at $identifier.
-      token = token.next.next;
-    } else {
-      return token;
-    }
-    kind = token.kind;
-    if (kind != STRING_TOKEN) return token;
-    token = token.next;
-    kind = token.kind;
-  }
-  return token;
-}
-
-String extractQuote(String string) {
-  StringQuoting q = StringValidator.quotingFromString(string);
-  return (q.raw ? 'r' : '') + (q.quoteChar * q.leftQuoteLength);
-}
diff --git a/site/try/src/leap.dart b/site/try/src/leap.dart
deleted file mode 100644
index 3688bed..0000000
--- a/site/try/src/leap.dart
+++ /dev/null
@@ -1,85 +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 trydart.main;
-
-import 'dart:html' show
-    HttpRequest,
-    LinkElement,
-    querySelector,
-    window;
-
-import 'dart:isolate' show
-    Isolate,
-    ReceivePort,
-    SendPort;
-
-import 'compilation.dart' show
-    compilerPort,
-    currentSource;
-
-import 'samples.dart' show
-    EXAMPLE_HELLO;
-
-import 'ui.dart' show
-    buildUI,
-    interaction,
-    observer;
-
-import 'user_option.dart' show
-    UserOption;
-
-import 'settings.dart' show
-    alwaysRunInIframe,
-    communicateViaBlobs;
-
-bool isBrowserIE() {
-  return window.navigator.userAgent.contains(' Trident/7.0;');
-}
-
-initHiddenSettings() {
-  alwaysRunInIframe.setIfNotInitialized(isBrowserIE);
-  communicateViaBlobs.setIfNotInitialized(() => !isBrowserIE());
-}
-
-int count = 0;
-
-main() {
-  UserOption.storage = window.localStorage;
-  if (currentSource == null) {
-    currentSource = EXAMPLE_HELLO;
-  }
-
-  initHiddenSettings();
-
-  buildUI();
-  ReceivePort port = new ReceivePort();
-  Isolate.spawnUri(
-      Uri.base.resolve('compiler_isolate.dart.js'),
-      const <String>[], port.sendPort).then((Isolate isolate) {
-    LinkElement link = querySelector('link[rel="dart-sdk"]');
-    String sdk = link.href;
-    print('Using Dart SDK: $sdk');
-    int messageCount = 0;
-    SendPort sendPort;
-    port.listen((message) {
-      messageCount++;
-      switch (messageCount) {
-        case 1:
-          sendPort = message as SendPort;
-          sendPort.send([sdk, port.sendPort]);
-          break;
-        case 2:
-          // Acknowledged Receiving the SDK URI.
-          compilerPort = sendPort;
-          interaction.onMutation([], observer);
-          break;
-        default:
-          // TODO(ahe): Close [port]?
-          print('Unexpected message received: $message');
-          break;
-      }
-    });
-  });
-}
diff --git a/site/try/src/messages.dart b/site/try/src/messages.dart
deleted file mode 100644
index cfa1f17..0000000
--- a/site/try/src/messages.dart
+++ /dev/null
@@ -1,47 +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 trydart.messages;
-
-const Map<String, dynamic> messages = const <String, dynamic> {
-  'alwaysRunInWorker':
-    'Always run in Worker thread.',
-
-  'alwaysRunInIframe':
-    'Always run in inline frame.',
-
-  'communicateViaBlobs':
-    'Use blobs to send source code between components.',
-
-  'verboseCompiler':
-    'Verbose compiler output.',
-
-  'minified':
-    'Generate compact (minified) JavaScript.',
-
-  'onlyAnalyze':
-    'Only analyze program.',
-
-  'enableDartMind':
-    'Talk to "Dart Mind" server.',
-
-  'compilationPaused':
-    'Pause compilation.',
-
-  'codeFont': const [
-      'Code font:',
-      'Enter a size and font, for example, 11pt monospace'],
-
-  'currentSample':
-    'N/A',
-
-  'theme':
-    'Theme:',
-
-  'incrementalCompilation':
-    'Enable incremental compilation (EXPERIMENTAL).',
-
-  'hasSelectionModify':
-    'Use Selection.modify.',
-};
diff --git a/site/try/src/mock.dart b/site/try/src/mock.dart
deleted file mode 100644
index 9c9533c..0000000
--- a/site/try/src/mock.dart
+++ /dev/null
@@ -1,733 +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 trydart.mock;
-
-const List<String> identifiers = const <String>[
-    "ATTRIBUTE_NODE",
-    "AnalyserNode",
-    "ApplicationCache",
-    "Array",
-    "ArrayBuffer",
-    "Attr",
-    "Audio",
-    "AudioBuffer",
-    "AudioBufferSourceNode",
-    "AudioDestinationNode",
-    "AudioListener",
-    "AudioNode",
-    "AudioParam",
-    "AudioProcessingEvent",
-    "AutocompleteErrorEvent",
-    "BarProp",
-    "BeforeUnloadEvent",
-    "BiquadFilterNode",
-    "Blob",
-    "Boolean",
-    "CDATASection",
-    "CDATA_SECTION_NODE",
-    "COMMENT_NODE",
-    "CSS",
-    "CSSCharsetRule",
-    "CSSFontFaceRule",
-    "CSSImportRule",
-    "CSSKeyframeRule",
-    "CSSKeyframesRule",
-    "CSSMediaRule",
-    "CSSPageRule",
-    "CSSPrimitiveValue",
-    "CSSRule",
-    "CSSRuleList",
-    "CSSStyleDeclaration",
-    "CSSStyleRule",
-    "CSSStyleSheet",
-    "CSSValue",
-    "CSSValueList",
-    "CSSViewportRule",
-    "CanvasGradient",
-    "CanvasPattern",
-    "CanvasRenderingContext2D",
-    "ChannelMergerNode",
-    "ChannelSplitterNode",
-    "CharacterData",
-    "ClientRect",
-    "ClientRectList",
-    "Clipboard",
-    "CloseEvent",
-    "Comment",
-    "CompositionEvent",
-    "ConvolverNode",
-    "Counter",
-    "CustomEvent",
-    "DOCUMENT_FRAGMENT_NODE",
-    "DOCUMENT_NODE",
-    "DOCUMENT_POSITION_CONTAINED_BY",
-    "DOCUMENT_POSITION_CONTAINS",
-    "DOCUMENT_POSITION_DISCONNECTED",
-    "DOCUMENT_POSITION_FOLLOWING",
-    "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
-    "DOCUMENT_POSITION_PRECEDING",
-    "DOCUMENT_TYPE_NODE",
-    "DOMException",
-    "DOMImplementation",
-    "DOMParser",
-    "DOMSettableTokenList",
-    "DOMStringList",
-    "DOMStringMap",
-    "DOMTokenList",
-    "DataTransferItemList",
-    "DataView",
-    "Date",
-    "DelayNode",
-    "DeviceMotionEvent",
-    "DeviceOrientationEvent",
-    "Document",
-    "DocumentFragment",
-    "DocumentType",
-    "DynamicsCompressorNode",
-    "ELEMENT_NODE",
-    "ENTITY_NODE",
-    "ENTITY_REFERENCE_NODE",
-    "Element",
-    "Error",
-    "ErrorEvent",
-    "EvalError",
-    "Event",
-    "EventSource",
-    "EventTarget",
-    "File",
-    "FileError",
-    "FileList",
-    "FileReader",
-    "Float32Array",
-    "Float64Array",
-    "FocusEvent",
-    "FormData",
-    "Function",
-    "GainNode",
-    "HTMLAllCollection",
-    "HTMLAnchorElement",
-    "HTMLAppletElement",
-    "HTMLAreaElement",
-    "HTMLAudioElement",
-    "HTMLBRElement",
-    "HTMLBaseElement",
-    "HTMLBodyElement",
-    "HTMLButtonElement",
-    "HTMLCanvasElement",
-    "HTMLCollection",
-    "HTMLContentElement",
-    "HTMLDListElement",
-    "HTMLDataListElement",
-    "HTMLDirectoryElement",
-    "HTMLDivElement",
-    "HTMLDocument",
-    "HTMLElement",
-    "HTMLEmbedElement",
-    "HTMLFieldSetElement",
-    "HTMLFontElement",
-    "HTMLFormControlsCollection",
-    "HTMLFormElement",
-    "HTMLFrameElement",
-    "HTMLFrameSetElement",
-    "HTMLHRElement",
-    "HTMLHeadElement",
-    "HTMLHeadingElement",
-    "HTMLHtmlElement",
-    "HTMLIFrameElement",
-    "HTMLImageElement",
-    "HTMLInputElement",
-    "HTMLKeygenElement",
-    "HTMLLIElement",
-    "HTMLLabelElement",
-    "HTMLLegendElement",
-    "HTMLLinkElement",
-    "HTMLMapElement",
-    "HTMLMarqueeElement",
-    "HTMLMediaElement",
-    "HTMLMenuElement",
-    "HTMLMetaElement",
-    "HTMLMeterElement",
-    "HTMLModElement",
-    "HTMLOListElement",
-    "HTMLObjectElement",
-    "HTMLOptGroupElement",
-    "HTMLOptionElement",
-    "HTMLOptionsCollection",
-    "HTMLOutputElement",
-    "HTMLParagraphElement",
-    "HTMLParamElement",
-    "HTMLPreElement",
-    "HTMLProgressElement",
-    "HTMLQuoteElement",
-    "HTMLScriptElement",
-    "HTMLSelectElement",
-    "HTMLShadowElement",
-    "HTMLSourceElement",
-    "HTMLSpanElement",
-    "HTMLStyleElement",
-    "HTMLTableCaptionElement",
-    "HTMLTableCellElement",
-    "HTMLTableColElement",
-    "HTMLTableElement",
-    "HTMLTableRowElement",
-    "HTMLTableSectionElement",
-    "HTMLTemplateElement",
-    "HTMLTextAreaElement",
-    "HTMLTitleElement",
-    "HTMLTrackElement",
-    "HTMLUListElement",
-    "HTMLUnknownElement",
-    "HTMLVideoElement",
-    "HashChangeEvent",
-    "History",
-    "IDBCursor",
-    "IDBCursorWithValue",
-    "IDBDatabase",
-    "IDBFactory",
-    "IDBIndex",
-    "IDBKeyRange",
-    "IDBObjectStore",
-    "IDBOpenDBRequest",
-    "IDBRequest",
-    "IDBTransaction",
-    "IDBVersionChangeEvent",
-    "Image",
-    "ImageBitmap",
-    "ImageData",
-    "Infinity",
-    "InputMethodContext",
-    "Int16Array",
-    "Int32Array",
-    "Int8Array",
-    "Intl",
-    "JSON",
-    "KeyboardEvent",
-    "Location",
-    "Math",
-    "MediaController",
-    "MediaElementAudioSourceNode",
-    "MediaError",
-    "MediaKeyError",
-    "MediaKeyEvent",
-    "MediaList",
-    "MediaSource",
-    "MediaStreamAudioDestinationNode",
-    "MediaStreamAudioSourceNode",
-    "MediaStreamEvent",
-    "MediaStreamTrack",
-    "MessageChannel",
-    "MessageEvent",
-    "MessagePort",
-    "MimeType",
-    "MimeTypeArray",
-    "MouseEvent",
-    "MutationEvent",
-    "MutationObserver",
-    "MutationRecord",
-    "NOTATION_NODE",
-    "NaN",
-    "NamedNodeMap",
-    "Navigator",
-    "Node",
-    "NodeFilter",
-    "NodeIterator",
-    "NodeList",
-    "Notation",
-    "Notification",
-    "Number",
-    "Object",
-    "OfflineAudioCompletionEvent",
-    "Option",
-    "OscillatorNode",
-    "OverflowEvent",
-    "PROCESSING_INSTRUCTION_NODE",
-    "PageTransitionEvent",
-    "Performance",
-    "PerformanceEntry",
-    "PerformanceMark",
-    "PerformanceMeasure",
-    "PerformanceNavigation",
-    "PerformanceResourceTiming",
-    "PerformanceTiming",
-    "PeriodicWave",
-    "Plugin",
-    "PluginArray",
-    "PopStateEvent",
-    "ProcessingInstruction",
-    "ProgressEvent",
-    "Promise",
-    "RGBColor",
-    "RTCIceCandidate",
-    "RTCSessionDescription",
-    "Range",
-    "RangeError",
-    "Rect",
-    "ReferenceError",
-    "RegExp",
-    "SVGAElement",
-    "SVGAltGlyphDefElement",
-    "SVGAltGlyphElement",
-    "SVGAltGlyphItemElement",
-    "SVGAngle",
-    "SVGAnimateElement",
-    "SVGAnimateMotionElement",
-    "SVGAnimateTransformElement",
-    "SVGAnimatedAngle",
-    "SVGAnimatedBoolean",
-    "SVGAnimatedEnumeration",
-    "SVGAnimatedInteger",
-    "SVGAnimatedLength",
-    "SVGAnimatedLengthList",
-    "SVGAnimatedNumber",
-    "SVGAnimatedNumberList",
-    "SVGAnimatedPreserveAspectRatio",
-    "SVGAnimatedRect",
-    "SVGAnimatedString",
-    "SVGAnimatedTransformList",
-    "SVGAnimationElement",
-    "SVGCircleElement",
-    "SVGClipPathElement",
-    "SVGComponentTransferFunctionElement",
-    "SVGCursorElement",
-    "SVGDefsElement",
-    "SVGDescElement",
-    "SVGDiscardElement",
-    "SVGElement",
-    "SVGElementInstance",
-    "SVGElementInstanceList",
-    "SVGEllipseElement",
-    "SVGFEBlendElement",
-    "SVGFEColorMatrixElement",
-    "SVGFEComponentTransferElement",
-    "SVGFECompositeElement",
-    "SVGFEConvolveMatrixElement",
-    "SVGFEDiffuseLightingElement",
-    "SVGFEDisplacementMapElement",
-    "SVGFEDistantLightElement",
-    "SVGFEDropShadowElement",
-    "SVGFEFloodElement",
-    "SVGFEFuncAElement",
-    "SVGFEFuncBElement",
-    "SVGFEFuncGElement",
-    "SVGFEFuncRElement",
-    "SVGFEGaussianBlurElement",
-    "SVGFEImageElement",
-    "SVGFEMergeElement",
-    "SVGFEMergeNodeElement",
-    "SVGFEMorphologyElement",
-    "SVGFEOffsetElement",
-    "SVGFEPointLightElement",
-    "SVGFESpecularLightingElement",
-    "SVGFESpotLightElement",
-    "SVGFETileElement",
-    "SVGFETurbulenceElement",
-    "SVGFilterElement",
-    "SVGFontElement",
-    "SVGFontFaceElement",
-    "SVGFontFaceFormatElement",
-    "SVGFontFaceNameElement",
-    "SVGFontFaceSrcElement",
-    "SVGFontFaceUriElement",
-    "SVGForeignObjectElement",
-    "SVGGElement",
-    "SVGGeometryElement",
-    "SVGGlyphElement",
-    "SVGGlyphRefElement",
-    "SVGGradientElement",
-    "SVGGraphicsElement",
-    "SVGHKernElement",
-    "SVGImageElement",
-    "SVGLength",
-    "SVGLengthList",
-    "SVGLineElement",
-    "SVGLinearGradientElement",
-    "SVGMPathElement",
-    "SVGMarkerElement",
-    "SVGMaskElement",
-    "SVGMatrix",
-    "SVGMetadataElement",
-    "SVGMissingGlyphElement",
-    "SVGNumber",
-    "SVGNumberList",
-    "SVGPathElement",
-    "SVGPathSeg",
-    "SVGPathSegArcAbs",
-    "SVGPathSegArcRel",
-    "SVGPathSegClosePath",
-    "SVGPathSegCurvetoCubicAbs",
-    "SVGPathSegCurvetoCubicRel",
-    "SVGPathSegCurvetoCubicSmoothAbs",
-    "SVGPathSegCurvetoCubicSmoothRel",
-    "SVGPathSegCurvetoQuadraticAbs",
-    "SVGPathSegCurvetoQuadraticRel",
-    "SVGPathSegCurvetoQuadraticSmoothAbs",
-    "SVGPathSegCurvetoQuadraticSmoothRel",
-    "SVGPathSegLinetoAbs",
-    "SVGPathSegLinetoHorizontalAbs",
-    "SVGPathSegLinetoHorizontalRel",
-    "SVGPathSegLinetoRel",
-    "SVGPathSegLinetoVerticalAbs",
-    "SVGPathSegLinetoVerticalRel",
-    "SVGPathSegList",
-    "SVGPathSegMovetoAbs",
-    "SVGPathSegMovetoRel",
-    "SVGPatternElement",
-    "SVGPoint",
-    "SVGPointList",
-    "SVGPolygonElement",
-    "SVGPolylineElement",
-    "SVGPreserveAspectRatio",
-    "SVGRadialGradientElement",
-    "SVGRect",
-    "SVGRectElement",
-    "SVGRenderingIntent",
-    "SVGSVGElement",
-    "SVGScriptElement",
-    "SVGSetElement",
-    "SVGStopElement",
-    "SVGStringList",
-    "SVGStyleElement",
-    "SVGSwitchElement",
-    "SVGSymbolElement",
-    "SVGTSpanElement",
-    "SVGTextContentElement",
-    "SVGTextElement",
-    "SVGTextPathElement",
-    "SVGTextPositioningElement",
-    "SVGTitleElement",
-    "SVGTransform",
-    "SVGTransformList",
-    "SVGUnitTypes",
-    "SVGUseElement",
-    "SVGVKernElement",
-    "SVGViewElement",
-    "SVGViewSpec",
-    "SVGZoomEvent",
-    "Screen",
-    "ScriptProcessorNode",
-    "Selection",
-    "SharedWorker",
-    "SpeechInputEvent",
-    "SpeechSynthesisEvent",
-    "SpeechSynthesisUtterance",
-    "Storage",
-    "StorageEvent",
-    "String",
-    "StyleSheet",
-    "StyleSheetList",
-    "SyntaxError",
-    "TEXT_NODE",
-    "Text",
-    "TextEvent",
-    "TextMetrics",
-    "TextTrack",
-    "TextTrackCue",
-    "TextTrackCueList",
-    "TextTrackList",
-    "TimeRanges",
-    "Touch",
-    "TouchEvent",
-    "TouchList",
-    "TrackEvent",
-    "TransitionEvent",
-    "TreeWalker",
-    "TypeError",
-    "UIEvent",
-    "URIError",
-    "URL",
-    "Uint16Array",
-    "Uint32Array",
-    "Uint8Array",
-    "Uint8ClampedArray",
-    "VTTCue",
-    "ValidityState",
-    "WaveShaperNode",
-    "WebGLActiveInfo",
-    "WebGLBuffer",
-    "WebGLContextEvent",
-    "WebGLFramebuffer",
-    "WebGLProgram",
-    "WebGLRenderbuffer",
-    "WebGLRenderingContext",
-    "WebGLShader",
-    "WebGLShaderPrecisionFormat",
-    "WebGLTexture",
-    "WebGLUniformLocation",
-    "WebSocket",
-    "WheelEvent",
-    "Window",
-    "Worker",
-    "XMLDocument",
-    "XMLHttpRequest",
-    "XMLHttpRequestProgressEvent",
-    "XMLHttpRequestUpload",
-    "XMLSerializer",
-    "XPathEvaluator",
-    "XPathExpression",
-    "XPathResult",
-    "XSLTProcessor",
-    "activeElement",
-    "addEventListener",
-    "adoptNode",
-    "alinkColor",
-    "all",
-    "anchors",
-    "appendChild",
-    "applets",
-    "applicationCache",
-    "baseURI",
-    "bgColor",
-    "body",
-    "captureEvents",
-    "caretRangeFromPoint",
-    "characterSet",
-    "charset",
-    "childElementCount",
-    "childNodes",
-    "children",
-    "chrome",
-    "clear",
-    "clientInformation",
-    "cloneNode",
-    "close",
-    "closed",
-    "compareDocumentPosition",
-    "compatMode",
-    "console",
-    "contains",
-    "cookie",
-    "cr",
-    "createAttribute",
-    "createCDATASection",
-    "createComment",
-    "createDocumentFragment",
-    "createElement",
-    "createElementNS",
-    "createEvent",
-    "createExpression",
-    "createNSResolver",
-    "createNodeIterator",
-    "createProcessingInstruction",
-    "createRange",
-    "createTextNode",
-    "createTreeWalker",
-    "crypto",
-    "currentScript",
-    "decodeURI",
-    "decodeURIComponent",
-    "defaultCharset",
-    "defaultStatus",
-    "defaultView",
-    "defaultstatus",
-    "designMode",
-    "devicePixelRatio",
-    "dir",
-    "dispatchEvent",
-    "doctype",
-    "document",
-    "documentElement",
-    "documentURI",
-    "domain",
-    "elementFromPoint",
-    "embeds",
-    "encodeURI",
-    "encodeURIComponent",
-    "escape",
-    "eval",
-    "evaluate",
-    "event",
-    "execCommand",
-    "external",
-    "fgColor",
-    "firstChild",
-    "firstElementChild",
-    "forms",
-    "frameElement",
-    "frames",
-    "getCSSCanvasContext",
-    "getElementById",
-    "getElementsByClassName",
-    "getElementsByName",
-    "getElementsByTagName",
-    "getElementsByTagNameNS",
-    "getOverrideStyle",
-    "getSelection",
-    "global",
-    "hasChildNodes",
-    "hasFocus",
-    "head",
-    "hidden",
-    "history",
-    "i18nTemplate",
-    "images",
-    "implementation",
-    "importNode",
-    "indexedDB",
-    "innerHeight",
-    "innerWidth",
-    "inputEncoding",
-    "insertBefore",
-    "isDefaultNamespace",
-    "isEqualNode",
-    "isFinite",
-    "isNaN",
-    "isSameNode",
-    "lastChild",
-    "lastElementChild",
-    "lastModified",
-    "length",
-    "linkColor",
-    "links",
-    "localName",
-    "localStorage",
-    "location",
-    "locationbar",
-    "lookupNamespaceURI",
-    "lookupPrefix",
-    "menubar",
-    "name",
-    "namespaceURI",
-    "navigator",
-    "nextSibling",
-    "nodeName",
-    "nodeType",
-    "nodeValue",
-    "normalize",
-    "ntp",
-    "offscreenBuffering",
-    "onabort",
-    "onbeforecopy",
-    "onbeforecut",
-    "onbeforepaste",
-    "onblur",
-    "oncancel",
-    "oncanplay",
-    "oncanplaythrough",
-    "onchange",
-    "onclick",
-    "onclose",
-    "oncontextmenu",
-    "oncopy",
-    "oncuechange",
-    "oncut",
-    "ondblclick",
-    "ondrag",
-    "ondragend",
-    "ondragenter",
-    "ondragleave",
-    "ondragover",
-    "ondragstart",
-    "ondrop",
-    "ondurationchange",
-    "onemptied",
-    "onended",
-    "onerror",
-    "onfocus",
-    "oninput",
-    "oninvalid",
-    "onkeydown",
-    "onkeypress",
-    "onkeyup",
-    "onload",
-    "onloadeddata",
-    "onloadedmetadata",
-    "onloadstart",
-    "onmousedown",
-    "onmouseenter",
-    "onmouseleave",
-    "onmousemove",
-    "onmouseout",
-    "onmouseover",
-    "onmouseup",
-    "onmousewheel",
-    "onpaste",
-    "onpause",
-    "onplay",
-    "onplaying",
-    "onprogress",
-    "onratechange",
-    "onreadystatechange",
-    "onreset",
-    "onresize",
-    "onscroll",
-    "onsearch",
-    "onseeked",
-    "onseeking",
-    "onselect",
-    "onselectionchange",
-    "onselectstart",
-    "onshow",
-    "onstalled",
-    "onsubmit",
-    "onsuspend",
-    "ontimeupdate",
-    "onvolumechange",
-    "onwaiting",
-    "onwheel",
-    "open",
-    "opener",
-    "outerHeight",
-    "outerWidth",
-    "ownerDocument",
-    "pageXOffset",
-    "pageYOffset",
-    "parent",
-    "parentElement",
-    "parentNode",
-    "parseFloat",
-    "parseInt",
-    "performance",
-    "personalbar",
-    "plugins",
-    "preferredStylesheetSet",
-    "previousSibling",
-    "queryCommandEnabled",
-    "queryCommandIndeterm",
-    "queryCommandState",
-    "queryCommandSupported",
-    "queryCommandValue",
-    "querySelector",
-    "querySelectorAll",
-    "readyState",
-    "referrer",
-    "registerElement",
-    "releaseEvents",
-    "removeChild",
-    "removeEventListener",
-    "replaceChild",
-    "rootElement",
-    "screen",
-    "screenLeft",
-    "screenTop",
-    "screenX",
-    "screenY",
-    "scripts",
-    "scrollX",
-    "scrollY",
-    "scrollbars",
-    "selectedStylesheetSet",
-    "self",
-    "sessionStorage",
-    "speechSynthesis",
-    "status",
-    "statusbar",
-    "styleMedia",
-    "styleSheets",
-    "templateData",
-    "textContent",
-    "title",
-    "toolbar",
-    "top",
-    "undefined",
-    "unescape",
-    "visibilityState",
-    "vlinkColor",
-    "window",
-    "write",
-    "writeln",
-    "xmlEncoding",
-    "xmlStandalone",
-    "xmlVersion",
-  ];
diff --git a/site/try/src/run.dart b/site/try/src/run.dart
deleted file mode 100644
index e453a70..0000000
--- a/site/try/src/run.dart
+++ /dev/null
@@ -1,71 +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 trydart.run;
-
-import 'dart:html' show
-    Blob,
-    IFrameElement,
-    Url;
-
-makeOutputFrame(String scriptUrl) {
-  final String outputHtml = '''
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>JavaScript output</title>
-<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
-</head>
-<body>
-<script type="application/javascript" src="$outputHelper"></script>
-<script type="application/javascript" src="$scriptUrl"></script>
-</body>
-</html>
-''';
-
-  return new IFrameElement()
-      ..src = Url.createObjectUrl(new Blob([outputHtml], "text/html"))
-      ..style.width = '100%'
-      ..style.height = '0px';
-}
-
-final String outputHelper =
-    Url.createObjectUrl(new Blob([OUTPUT_HELPER], 'application/javascript'));
-
-const String OUTPUT_HELPER = r'''
-function dartPrint(msg) {
-  // Send a message to the main Try Dart window.
-  window.parent.postMessage(String(msg), "*");
-}
-
-function dartMainRunner(main) {
-  // Store the current height (of an empty document).  This implies that the
-  // main Try Dart application is only notified if the document is actually
-  // changed.
-  var previousScrollHeight = document.documentElement.scrollHeight;
-
-  function postScrollHeight(mutations, observer) {
-    var scrollHeight = document.documentElement.scrollHeight;
-    if (scrollHeight !== previousScrollHeight) {
-      previousScrollHeight = scrollHeight;
-      window.parent.postMessage(["scrollHeight", scrollHeight], "*");
-    }
-  }
-
-  var MutationObserver =
-      window.MutationObserver ||
-      window.WebKitMutationObserver ||
-      window.MozMutationObserver;
-
-  // Listen to any changes to the DOM.
-  new MutationObserver(postScrollHeight).observe(
-      document.documentElement,
-      { attributes: true,
-        childList: true,
-        characterData: true,
-        subtree: true });
-
-  main();
-}
-''';
diff --git a/site/try/src/samples.dart b/site/try/src/samples.dart
deleted file mode 100644
index 8ccd8da0..0000000
--- a/site/try/src/samples.dart
+++ /dev/null
@@ -1,205 +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 trydart.samples;
-
-const String EXAMPLE_HELLO = r'''
-// Go ahead and modify this example.
-
-var greeting = "Hello, World!";
-
-// Prints a greeting.
-void main() {
-  // The [print] function displays a message in the "Console" box.
-  // Try modifying the greeting above and watch the "Console" box change.
-  print(greeting);
-}
-''';
-
-const String EXAMPLE_HELLO_HTML = r'''
-// Go ahead and modify this example.
-
-import "dart:html";
-
-var greeting = "Hello, World!";
-
-// Displays a greeting.
-void main() {
-  // This example uses HTML to display the greeting and it will appear
-  // in a nested HTML frame (an iframe).
-  document.body.append(new HeadingElement.h1()..appendText(greeting));
-}
-''';
-
-const String EXAMPLE_FIBONACCI = r'''
-// Go ahead and modify this example.
-
-// Computes the nth Fibonacci number.
-int fibonacci(int n) {
-  if (n < 2) return n;
-  return fibonacci(n - 1) + fibonacci(n - 2);
-}
-
-// Prints a Fibonacci number.
-void main() {
-  int i = 20;
-  String message = "fibonacci($i) = ${fibonacci(i)}";
-  // Print the result in the "Console" box.
-  print(message);
-}
-''';
-
-const String EXAMPLE_FIBONACCI_HTML = r'''
-// Go ahead and modify this example.
-
-import "dart:html";
-
-// Computes the nth Fibonacci number.
-int fibonacci(int n) {
-  if (n < 2) return n;
-  return fibonacci(n - 1) + fibonacci(n - 2);
-}
-
-// Displays a Fibonacci number.
-void main() {
-  int i = 20;
-  String message = "fibonacci($i) = ${fibonacci(i)}";
-
-  // This example uses HTML to display the result and it will appear
-  // in a nested HTML frame (an iframe).
-  document.body.append(new HeadingElement.h1()..appendText(message));
-}
-''';
-
-// Test that math.png is displayed correctly (centered without 3d border).
-// Test that slider works and changes size of sunflower.
-const String EXAMPLE_SUNFLOWER = '''
-// 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 sunflower;
-
-import "dart:html";
-import "dart:math";
-
-const String SEED_COLOR = "orange";
-const int SEED_RADIUS = 2;
-const int SCALE_FACTOR = 4;
-const num TAU = PI * 2;
-const int MAX_D = 300;
-const num centerX = MAX_D / 2;
-const num centerY = centerX;
-
-final InputElement slider = query("#slider");
-final Element notes = query("#notes");
-final num PHI = (sqrt(5) + 1) / 2;
-int seeds = 0;
-final CanvasRenderingContext2D context =
-  (query("#canvas") as CanvasElement).context2D;
-
-void main() {
-  document.head.append(new StyleElement()..appendText(STYLE));
-  document.body.innerHtml = BODY;
-  ImageElement img = document.querySelector("#math_png");
-  img.src = MATH_PNG;
-  slider.onChange.listen((e) => draw());
-  draw();
-}
-
-/// Draw the complete figure for the current number of seeds.
-void draw() {
-  seeds = int.parse(slider.value);
-  context.clearRect(0, 0, MAX_D, MAX_D);
-  for (var i = 0; i < seeds; i++) {
-    final num theta = i * TAU / PHI;
-    final num r = sqrt(i) * SCALE_FACTOR;
-    drawSeed(centerX + r * cos(theta), centerY - r * sin(theta));
-  }
-  notes.text = "\${seeds} seeds";
-}
-
-/// Draw a small circle representing a seed centered at (x,y).
-void drawSeed(num x, num y) {
-  context..beginPath()
-         ..lineWidth = 2
-         ..fillStyle = SEED_COLOR
-         ..strokeStyle = SEED_COLOR
-         ..arc(x, y, SEED_RADIUS, 0, TAU, false)
-         ..fill()
-         ..closePath()
-         ..stroke();
-}
-
-const String MATH_PNG =
-    "https://raw.githubusercontent.com/dart-lang/sample-sunflower/f808fcf68e523ea69631d2e61fd26be3296a1a8f/web/math.png";
-const String BODY = """
-    <h1>drfibonacci\'s Sunflower Spectacular</h1>
-
-    <p>A canvas 2D demo.</p>
-
-    <div id="container">
-      <canvas id="canvas" width="300" height="300" class="center"></canvas>
-      <form class="center">
-        <input id="slider" type="range" max="1000" value="500"/>
-      </form>
-      <br/>
-      <img id="math_png" width="350px" height="42px" class="center">
-    </div>
-
-    <footer>
-      <p id="summary"> </p>
-      <p id="notes"> </p>
-    </footer>
-""";
-
-const String STYLE = r"""
-body {
-  background-color: #F8F8F8;
-  font-family: \'Open Sans\', sans-serif;
-  font-size: 14px;
-  font-weight: normal;
-  line-height: 1.2em;
-  margin: 15px;
-}
-
-p {
-  color: #333;
-}
-
-#container {
-  width: 100%;
-  height: 400px;
-  position: relative;
-  border: 1px solid #ccc;
-  background-color: #fff;
-}
-
-#summary {
-  float: left;
-}
-
-#notes {
-  float: right;
-  width: 120px;
-  text-align: right;
-}
-
-.error {
-  font-style: italic;
-  color: red;
-}
-
-img {
-  border: 1px solid #ccc;
-  margin: auto;
-}
-
-.center {
-  display: block;
-  margin: 0px auto;
-  text-align: center;
-}
-""";
-''';
diff --git a/site/try/src/selection.dart b/site/try/src/selection.dart
deleted file mode 100644
index c0d606e..0000000
--- a/site/try/src/selection.dart
+++ /dev/null
@@ -1,103 +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 trydart.selection;
-
-import 'dart:html' show
-    CharacterData,
-    Element,
-    Node,
-    NodeFilter,
-    Selection,
-    Text,
-    TreeWalker;
-
-import 'shadow_root.dart' show
-    WALKER_NEXT,
-    WALKER_RETURN,
-    walkNodes;
-
-import 'decoration.dart';
-
-class TrySelection {
-  final Node root;
-  Node anchorNode;
-  int anchorOffset;
-
-  String text;
-  int globalOffset = -1;
-
-  TrySelection(this.root, Selection selection)
-      : anchorNode = isCollapsed(selection) ? selection.anchorNode : null,
-        anchorOffset = isCollapsed(selection) ? selection.anchorOffset : -1;
-
-  TrySelection.empty(this.root)
-      : anchorNode = null,
-        anchorOffset = -1;
-
-  Text addNodeFromSubstring(int start,
-                            int end,
-                            List<Node> nodes,
-                            [Decoration decoration]) {
-    if (start == end) return null;
-
-    Text textNode = new Text(text.substring(start, end));
-
-    if (start <= globalOffset && globalOffset <= end) {
-      anchorNode = textNode;
-      anchorOffset = globalOffset - start;
-    }
-
-    nodes.add(decoration == null ? textNode : decoration.applyTo(textNode));
-
-    return textNode;
-  }
-
-  void adjust(Selection selection) {
-    if (anchorOffset >= 0) {
-      selection.collapse(anchorNode, anchorOffset);
-    }
-  }
-
-  void updateText(String newText) {
-    text = newText;
-    globalOffset = computeGlobalOffset(root, anchorNode, anchorOffset);
-  }
-
-  TrySelection copyWithRoot(Node root) {
-    return new TrySelection.empty(root)
-        ..anchorNode = anchorNode
-        ..anchorOffset = anchorOffset;
-  }
-
-  /// Computes the global offset, that is, the offset from [root].
-  static int computeGlobalOffset(Node root, Node anchorNode, int anchorOffset) {
-    if (anchorOffset == -1) return -1;
-
-    int offset = 0;
-    bool found = false;
-    walkNodes(root, (Node node) {
-      if (anchorNode == node) {
-        offset += anchorOffset;
-        found = true;
-        return WALKER_RETURN;
-      }
-      switch (node.nodeType) {
-        case Node.CDATA_SECTION_NODE:
-        case Node.TEXT_NODE:
-          CharacterData text = node;
-          offset += text.data.length;
-          break;
-      }
-      return WALKER_NEXT;
-    });
-    return found ? offset : -1;
-  }
-}
-
-bool isCollapsed(Selection selection) {
-  // Firefox and Chrome don't agree on if the selection is collapsed if there
-  // is no node selected.
-  return selection.isCollapsed && selection.anchorNode != null;
-}
diff --git a/site/try/src/settings.dart b/site/try/src/settings.dart
deleted file mode 100644
index 82382e1..0000000
--- a/site/try/src/settings.dart
+++ /dev/null
@@ -1,123 +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 trydart.settings;
-
-import 'user_option.dart';
-
-const BooleanUserOption _alwaysRunInWorker =
-    const BooleanUserOption('alwaysRunInWorker');
-
-bool get alwaysRunInWorker => _alwaysRunInWorker.value;
-
-void set alwaysRunInWorker(bool b) {
-  _alwaysRunInWorker.value = b;
-}
-
-const BooleanUserOption _verboseCompiler =
-    const BooleanUserOption('verboseCompiler');
-
-bool get verboseCompiler => _verboseCompiler.value;
-
-void set verboseCompiler(bool b) {
-  _verboseCompiler.value = b;
-}
-
-const BooleanUserOption _minified =
-    const BooleanUserOption('minified');
-
-bool get minified => _minified.value;
-
-void set minified(bool b) {
-  _minified.value = b;
-}
-
-const BooleanUserOption _onlyAnalyze =
-    const BooleanUserOption('onlyAnalyze');
-
-bool get onlyAnalyze => _onlyAnalyze.value;
-
-void set onlyAnalyze(bool b) {
-  _onlyAnalyze.value = b;
-}
-
-const BooleanUserOption _enableDartMind =
-    const BooleanUserOption('enableDartMind', isHidden: true);
-
-bool get enableDartMind => _enableDartMind.value;
-
-void set enableDartMind(bool b) {
-  _enableDartMind.value = b;
-}
-
-const BooleanUserOption _compilationPaused =
-    const BooleanUserOption('compilationPaused');
-
-bool get compilationPaused => _compilationPaused.value;
-
-void set compilationPaused(bool b) {
-  _compilationPaused.value = b;
-}
-
-const StringUserOption _codeFont =
-    const StringUserOption('codeFont');
-
-String get codeFont => _codeFont.value;
-
-void set codeFont(String b) {
-  _codeFont.value = b;
-}
-
-const StringUserOption _currentSample =
-    const StringUserOption('currentSample', isHidden: true);
-
-String get currentSample => _currentSample.value;
-
-void set currentSample(String b) {
-  _currentSample.value = b;
-}
-
-const StringUserOption _theme =
-    const StringUserOption('theme');
-
-String get theme => _theme.value;
-
-void set theme(String b) {
-  _theme.value = b;
-}
-
-const BooleanUserOption enableCodeCompletion =
-    const BooleanUserOption('enableCodeCompletion', isHidden: true);
-
-const BooleanUserOption incrementalCompilation =
-    const BooleanUserOption('incrementalCompilation');
-
-const BooleanUserOption live = const BooleanUserOption('live', isHidden: true);
-
-const BooleanUserOption alwaysRunInIframe =
-    const BooleanUserOption('alwaysRunInIframe', isHidden: true);
-
-const BooleanUserOption communicateViaBlobs =
-    const BooleanUserOption('communicateViaBlobs', isHidden: true);
-
-const BooleanUserOption hasSelectionModify =
-    const BooleanUserOption('hasSelectionModify', isHidden: true);
-
-const List<UserOption> options = const <UserOption>[
-    _alwaysRunInWorker,
-    _verboseCompiler,
-    _minified,
-    _onlyAnalyze,
-    _enableDartMind,
-    _compilationPaused,
-    incrementalCompilation,
-    live,
-    enableCodeCompletion,
-    _codeFont,
-    _theme,
-    _currentSample,
-    alwaysRunInIframe,
-    communicateViaBlobs,
-    hasSelectionModify,
-  ];
diff --git a/site/try/src/shadow_root.dart b/site/try/src/shadow_root.dart
deleted file mode 100644
index 20ee0b2..0000000
--- a/site/try/src/shadow_root.dart
+++ /dev/null
@@ -1,105 +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 trydart.shadow_root;
-
-import 'dart:html';
-
-import 'selection.dart' show
-    TrySelection;
-
-import 'html_to_text.dart' show
-    htmlToText;
-
-const int WALKER_NEXT = 0;
-const int WALKER_RETURN = 1;
-const int WALKER_SKIP_NODE = 2;
-
-void setShadowRoot(Element node, text) {
-  if (text is String) {
-    text = new Text(text);
-  }
-  getShadowRoot(node)
-      ..nodes.clear()
-      ..append(text);
-}
-
-
-/* ShadowRoot or Element */ getShadowRoot(Element node) {
-  if (ShadowRoot.supported) {
-    ShadowRoot root = node.shadowRoot;
-    return root != null ? root : node.createShadowRoot();
-  } else {
-    Element root = node.querySelector('[try-dart-shadow-root]');
-    if (root == null) {
-      root = new SpanElement()
-          ..setAttribute('try-dart-shadow-root', '');
-      node.append(root);
-    }
-    return root;
-  }
-}
-
-String getText(Element node) {
-  if (ShadowRoot.supported) return node.text;
-  StringBuffer buffer = new StringBuffer();
-  htmlToText(
-      node, buffer, new TrySelection.empty(node), treatRootAsInline: true);
-  return '$buffer';
-}
-
-/// Element.contains(n) doesn't work when n is node(Text) in IE,
-/// so this is a brute-force implementation of contains.
-bool containsNode(parent, child) {
-  var p = child;
-  while (p != null && p != parent) {
-    p = p.parentNode;
-  }
-  return p != null;
-}
-
-/// Position [walker] at the last predecessor (that is, child of child of
-/// child...) of [node]. The next call to walker.nextNode will return the first
-/// node after [node].
-void skip(Node node, TreeWalker walker) {
-  if (walker.nextSibling() != null) {
-    walker.previousNode();
-    return;
-  }
-  for (Node current = walker.nextNode();
-       current != null;
-       current = walker.nextNode()) {
-    if (!containsNode(node, current)) {
-      walker.previousNode();
-      return;
-    }
-  }
-}
-
-/// Call [f] on each node in [root] in same order as [TreeWalker].  Skip any
-/// nodes used to implement shadow root polyfill.
-void walkNodes(Node root, int f(Node node)) {
-  TreeWalker walker = new TreeWalker(root, NodeFilter.SHOW_ALL);
-
-  for (Node node = root; node != null; node = walker.nextNode()) {
-    if (!ShadowRoot.supported &&
-        node is Element &&
-        node.getAttribute('try-dart-shadow-root') != null) {
-      skip(node, walker);
-    } else {
-      int action = f(node);
-      switch (action) {
-        case WALKER_RETURN:
-          return;
-        case WALKER_SKIP_NODE:
-          skip(node, walker);
-          break;
-        case WALKER_NEXT:
-          break;
-        default:
-          throw 'Unexpected action returned from [f]: $action';
-      }
-    }
-  }
-}
diff --git a/site/try/src/theme_default.dart b/site/try/src/theme_default.dart
deleted file mode 100644
index c761ef6..0000000
--- a/site/try/src/theme_default.dart
+++ /dev/null
@@ -1,79 +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 trydart.themes;
-
-/// Default theme extracted from
-/// editor/tools/plugins/com.google.dart.tools.deploy/themes/default.xml
-class Theme {
-  static named(String name) {
-    if (name == null) return THEMES[0];
-    return THEMES.firstWhere(
-        (theme) => name == theme.name,
-        orElse: () => THEMES[0]);
-  }
-
-  const Theme();
-
-  String get name => 'Default';
-
-  Decoration get abstractMethod => const Decoration(color: '#000000');
-  Decoration get annotation => const Decoration(color: '#000000');
-  Decoration get background => const Decoration(color: '#ffffff');
-  Decoration get bracket => const Decoration(color: '#000000');
-  Decoration get builtin => const Decoration(color: '#7e0854', bold: true);
-  Decoration get className => const Decoration(color: '#000000');
-  Decoration get commentTaskTag => const Decoration(color: '#606060');
-  Decoration get constant => const Decoration(color: '#000000');
-  Decoration get currentLine => const Decoration(color: '#F0F0F0');
-  Decoration get deletionIndication => const Decoration(color: '#000000');
-  Decoration get deprecatedMember => const Decoration(color: '#000000');
-  Decoration get directive => const Decoration(color: '#7e0854', bold: true);
-  Decoration get dynamicType => const Decoration(color: '#000000');
-  Decoration get enumName => const Decoration(color: '#000000');
-  Decoration get field => const Decoration(color: '#0618bd');
-  Decoration get filteredSearchResultIndication =>
-      const Decoration(color: '#000000');
-  Decoration get findScope => const Decoration(color: '#000000');
-  Decoration get foreground => const Decoration(color: '#000000');
-  Decoration get getter => const Decoration(color: '#0618bd');
-  Decoration get inheritedMethod => const Decoration(color: '#000000');
-  Decoration get interface => const Decoration(color: '#000000');
-  Decoration get javadoc => const Decoration(color: '#4162bc');
-  Decoration get javadocKeyword => const Decoration(color: '#4162bc');
-  Decoration get javadocLink => const Decoration(color: '#4162bc');
-  Decoration get javadocTag => const Decoration(color: '#7f809e');
-  Decoration get keyword => const Decoration(color: '#7e0854', bold: true);
-  Decoration get keywordReturn =>
-      const Decoration(color: '#7e0854', bold: true);
-  Decoration get lineNumber => const Decoration(color: '#000000');
-  Decoration get localVariable => const Decoration(color: '#7f1cc9');
-  Decoration get localVariableDeclaration =>
-      const Decoration(color: '#7f1cc9');
-  Decoration get method => const Decoration(color: '#000000');
-  Decoration get methodDeclaration =>
-      const Decoration(color: '#0b5bd2', bold: true);
-  Decoration get multiLineComment => const Decoration(color: '#4162bc');
-  Decoration get multiLineString => const Decoration(color: '#2d24fb');
-  Decoration get number => const Decoration(color: '#0c6f0e');
-  Decoration get occurrenceIndication => const Decoration(color: '#e0e0e0');
-  Decoration get operator => const Decoration(color: '#000000');
-  Decoration get parameterVariable => const Decoration(color: '#87312e');
-  Decoration get searchResultIndication => const Decoration(color: '#D0D0D0');
-  Decoration get selectionBackground => const Decoration(color: '#b6d6fd');
-  Decoration get selectionForeground => const Decoration(color: '#000000');
-  Decoration get setter => const Decoration(color: '#0618bd');
-  Decoration get singleLineComment => const Decoration(color: '#417e60');
-  Decoration get sourceHoverBackground => const Decoration(color: '#fbfbc8');
-  Decoration get staticField => const Decoration(color: '#0618bd');
-  Decoration get staticFinalField => const Decoration(color: '#0618bd');
-  Decoration get staticMethod => const Decoration(color: '#000000');
-  Decoration get staticMethodDeclaration =>
-      const Decoration(color: '#404040', bold: true);
-  Decoration get string => const Decoration(color: '#2d24fb');
-  Decoration get typeArgument => const Decoration(color: '#033178');
-  Decoration get typeParameter => const Decoration(color: '#033178');
-  Decoration get writeOccurrenceIndication =>
-      const Decoration(color: '#e0e0e0');
-}
diff --git a/site/try/src/themes.dart b/site/try/src/themes.dart
deleted file mode 100644
index 464f23c..0000000
--- a/site/try/src/themes.dart
+++ /dev/null
@@ -1,11 +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 trydart.themes;
-
-import 'decoration.dart';
-
-part 'theme_default.dart';
-
-part 'extracted_themes.dart';
diff --git a/site/try/src/ui.dart b/site/try/src/ui.dart
deleted file mode 100644
index e678f38..0000000
--- a/site/try/src/ui.dart
+++ /dev/null
@@ -1,476 +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 trydart.ui;
-
-import 'dart:html';
-
-import 'dart:async' show
-    Future,
-    Timer,
-    scheduleMicrotask;
-
-import 'cache.dart' show
-    onLoad,
-    updateCacheStatus;
-
-import 'interaction_manager.dart' show InteractionManager;
-
-import 'run.dart' show
-    makeOutputFrame;
-
-import 'themes.dart' show
-    THEMES,
-    Theme;
-
-import 'samples.dart' show
-    EXAMPLE_FIBONACCI,
-    EXAMPLE_FIBONACCI_HTML,
-    EXAMPLE_HELLO,
-    EXAMPLE_HELLO_HTML,
-    EXAMPLE_SUNFLOWER;
-
-import 'settings.dart';
-
-import 'user_option.dart';
-
-import 'messages.dart' show messages;
-
-import 'compilation_unit.dart' show
-    CompilationUnit;
-
-import 'compilation.dart' show
-    currentSource;
-
-// TODO(ahe): Make internal to buildUI once all interactions have been moved to
-// the manager.
-InteractionManager interaction;
-
-DivElement mainEditorPane;
-DivElement statusDiv;
-PreElement outputDiv;
-DivElement hackDiv;
-IFrameElement outputFrame;
-MutationObserver observer;
-SpanElement cacheStatusElement;
-Theme currentTheme = Theme.named(theme);
-
-buildButton(message, action) {
-  if (message is String) {
-    message = new Text(message);
-  }
-  return new ButtonElement()
-      ..onClick.listen(action)
-      ..append(message);
-}
-
-buildTab(message, id, action) {
-  if (message is String) {
-    message = new Text(message);
-  }
-
-  onClick(MouseEvent event) {
-    event.preventDefault();
-    Element e = event.target;
-    LIElement parent = e.parent;
-    parent.parent.querySelector('li[class="active"]').classes.remove('active');
-    parent.classes.add('active');
-    action(event);
-  }
-
-  codeCallbacks[id] = action;
-
-  return new OptionElement()..append(message)..id = id;
-}
-
-Map<String, Function> codeCallbacks = new Map<String, Function>();
-
-void onCodeChange(Event event) {
-  SelectElement select = event.target;
-  String id = select.querySelectorAll('option')[select.selectedIndex].id;
-  Function action = codeCallbacks[id];
-  if (action != null) action(event);
-  outputFrame.style.display = 'none';
-  outputDiv.nodes.clear();
-}
-
-buildUI() {
-  interaction = new InteractionManager();
-
-  CompilationUnit.onChanged.listen(interaction.onCompilationUnitChanged);
-
-  window.localStorage['currentSample'] = '$currentSample';
-
-  buildCode(interaction);
-
-  (mainEditorPane = new DivElement())
-      ..classes.addAll(['mainEditorPane'])
-      ..style.backgroundColor = currentTheme.background.color
-      ..style.color = currentTheme.foreground.color
-      ..style.font = codeFont
-      ..spellcheck = false;
-
-  mainEditorPane
-      ..contentEditable = 'true'
-      ..onKeyDown.listen(interaction.onKeyUp)
-      ..onInput.listen(interaction.onInput);
-
-  document.onSelectionChange.listen(interaction.onSelectionChange);
-
-  var inputWrapper = new DivElement()
-      ..append(mainEditorPane)
-      ..classes.add('well')
-      ..style.padding = '0px'
-      ..style.overflowX = 'hidden'
-      ..style.overflowY = 'scroll'
-      ..style.position = 'relative'
-      ..style.maxHeight = '80vh';
-
-  var inputHeader = new DivElement()..appendText('Code');
-
-  inputHeader.style
-      ..right = '3px'
-      ..top = '0px'
-      ..position = 'absolute';
-  inputWrapper.append(inputHeader);
-
-  statusDiv = new DivElement();
-  statusDiv.style
-      ..left = '0px'
-      ..top = '0px'
-      ..position = 'absolute';
-  inputWrapper.append(statusDiv);
-
-  outputFrame =
-      makeOutputFrame(
-          Url.createObjectUrl(new Blob([''], 'application/javascript')));
-
-  outputDiv = new PreElement();
-  outputDiv.style
-      ..backgroundColor = currentTheme.background.color
-      ..color = currentTheme.foreground.color
-      ..overflow = 'auto'
-      ..padding = '1em'
-      ..minHeight = '10em'
-      ..whiteSpace = 'pre-wrap';
-
-  var outputWrapper = new DivElement()
-      ..append(outputDiv)
-      ..style.position = 'relative';
-
-  var consoleHeader = new DivElement()..appendText('Console');
-
-  consoleHeader.style
-      ..right = '3px'
-      ..top = '0px'
-      ..position = 'absolute';
-  outputWrapper.append(consoleHeader);
-
-  hackDiv = new DivElement();
-
-  var saveButton = new ButtonElement()
-      ..onClick.listen((_) {
-        var blobUrl =
-            Url.createObjectUrl(new Blob([mainEditorPane.text], 'text/plain'));
-        var save = new AnchorElement(href: blobUrl);
-        save.target = '_blank';
-        save.download = 'untitled.dart';
-        save.dispatchEvent(new Event.eventType('Event', 'click'));
-      })
-      ..style.position = 'absolute'
-      ..style.right = '0px'
-      ..appendText('Save');
-
-  cacheStatusElement = document.getElementById('appcache-status');
-  updateCacheStatus(null);
-
-  var section = document.querySelector('article[class="homepage"]>section');
-
-  DivElement tryColumn = document.getElementById('try-dart-column');
-  DivElement runColumn = document.getElementById('run-dart-column');
-
-  tryColumn.append(inputWrapper);
-  outputFrame.style.display = 'none';
-  runColumn.append(outputFrame);
-  runColumn.append(outputWrapper);
-  runColumn.append(hackDiv);
-
-  var settingsElement = document.getElementById('settings');
-  settingsElement.onClick.listen(openSettings);
-
-  window.onMessage.listen(interaction.onWindowMessage);
-
-  observer = new MutationObserver(interaction.onMutation)
-      ..observe(
-          mainEditorPane, childList: true, characterData: true, subtree: true);
-
-  scheduleMicrotask(() {
-    mainEditorPane.appendText(currentSource);
-  });
-
-  // You cannot install event handlers on window.applicationCache
-  // until the window has loaded.  In dartium, that's later than this
-  // method is called.
-  window.onLoad.listen(onLoad);
-
-  // However, in dart2js, the window has already loaded, and onLoad is
-  // never called.
-  onLoad(null);
-}
-
-buildCode(InteractionManager interaction) {
-  var codePicker =
-      document.getElementById('code-picker')
-      ..style.visibility = 'hidden'
-      ..onChange.listen(onCodeChange);
-  var htmlGroup = new OptGroupElement()..label = 'HTML';
-  var benchmarkGroup = new OptGroupElement()..label = 'Benchmarks';
-
-  interaction.projectFileNames().then((List<String> names) {
-    OptionElement none = new OptionElement()
-        ..appendText('--')
-        ..disabled = true;
-    codePicker
-        ..append(none)
-        ..style.visibility = 'visible'
-        ..selectedIndex = 0;
-
-    for (String name in names) {
-      codePicker.append(buildTab(name, name, (event) {
-        interaction.onProjectFileSelected(name);
-      }));
-    }
-  }).catchError((error) {
-    codePicker.style.visibility = 'visible';
-    OptionElement none = new OptionElement()
-        ..appendText('Pick an example')
-        ..disabled = true;
-    codePicker.append(none);
-
-    // codePicker.classes.addAll(['nav', 'nav-tabs']);
-    codePicker.append(buildTab('Hello, World!', 'EXAMPLE_HELLO', (_) {
-      mainEditorPane
-          ..nodes.clear()
-          ..appendText(EXAMPLE_HELLO);
-    }));
-    codePicker.append(buildTab('Fibonacci', 'EXAMPLE_FIBONACCI', (_) {
-      mainEditorPane
-          ..nodes.clear()
-          ..appendText(EXAMPLE_FIBONACCI);
-    }));
-    codePicker.append(htmlGroup);
-    // TODO(ahe): Restore benchmarks.
-    // codePicker.append(benchmarkGroup);
-
-    htmlGroup.append(
-        buildTab('Hello, World!', 'EXAMPLE_HELLO_HTML', (_) {
-      mainEditorPane
-          ..nodes.clear()
-          ..appendText(EXAMPLE_HELLO_HTML);
-    }));
-    htmlGroup.append(
-        buildTab('Fibonacci', 'EXAMPLE_FIBONACCI_HTML', (_) {
-      mainEditorPane
-          ..nodes.clear()
-          ..appendText(EXAMPLE_FIBONACCI_HTML);
-    }));
-    htmlGroup.append(buildTab('Sunflower', 'EXAMPLE_SUNFLOWER', (_) {
-      mainEditorPane
-          ..nodes.clear()
-          ..appendText(EXAMPLE_SUNFLOWER);
-    }));
-
-    benchmarkGroup.append(buildTab('DeltaBlue', 'BENCHMARK_DELTA_BLUE', (_) {
-      mainEditorPane.contentEditable = 'false';
-      LinkElement link = querySelector('link[rel="benchmark-DeltaBlue"]');
-      String deltaBlueUri = link.href;
-      link = querySelector('link[rel="benchmark-base"]');
-      String benchmarkBaseUri = link.href;
-      HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
-        HttpRequest.getString(deltaBlueUri).then((String deltaBlue) {
-          benchmarkBase = benchmarkBase.replaceFirst(
-              'part of benchmark_harness;', '// part of benchmark_harness;');
-          deltaBlue = deltaBlue.replaceFirst(
-              "import 'package:benchmark_harness/benchmark_harness.dart';",
-              benchmarkBase);
-          mainEditorPane
-              ..nodes.clear()
-              ..appendText(deltaBlue)
-              ..contentEditable = 'true';
-        });
-      });
-    }));
-
-    benchmarkGroup.append(buildTab('Richards', 'BENCHMARK_RICHARDS', (_) {
-      mainEditorPane.contentEditable = 'false';
-      LinkElement link = querySelector('link[rel="benchmark-Richards"]');
-      String richardsUri = link.href;
-      link = querySelector('link[rel="benchmark-base"]');
-      String benchmarkBaseUri = link.href;
-      HttpRequest.getString(benchmarkBaseUri).then((String benchmarkBase) {
-        HttpRequest.getString(richardsUri).then((String richards) {
-          benchmarkBase = benchmarkBase.replaceFirst(
-              'part of benchmark_harness;', '// part of benchmark_harness;');
-          richards = richards.replaceFirst(
-              "import 'package:benchmark_harness/benchmark_harness.dart';",
-              benchmarkBase);
-          mainEditorPane
-              ..nodes.clear()
-              ..appendText(richards)
-              ..contentEditable = 'true';
-        });
-      });
-    }));
-
-    codePicker.selectedIndex = 0;
-  });
-}
-
-num settingsHeight = 0;
-
-void openSettings(MouseEvent event) {
-  event.preventDefault();
-
-  if (settingsHeight != 0) {
-    var dialog = document.getElementById('settings-dialog');
-    if (dialog.getBoundingClientRect().height > 0) {
-      dialog.style.height = '0px';
-    } else {
-      dialog.style.height = '${settingsHeight}px';
-    }
-    return;
-  }
-
-  void updateCodeFont(Event e) {
-    TextInputElement target = e.target;
-    codeFont = target.value;
-    mainEditorPane.style.font = codeFont;
-  }
-
-  void updateTheme(Event e) {
-    var select = e.target;
-    String theme = select.queryAll('option')[select.selectedIndex].text;
-    window.localStorage['theme'] = theme;
-    currentTheme = Theme.named(theme);
-
-    mainEditorPane.style
-        ..backgroundColor = currentTheme.background.color
-        ..color = currentTheme.foreground.color;
-
-    outputDiv.style
-        ..backgroundColor = currentTheme.background.color
-        ..color = currentTheme.foreground.color;
-
-    bool oldCompilationPaused = compilationPaused;
-    compilationPaused = true;
-    interaction.onMutation([], observer);
-    compilationPaused = false;
-  }
-
-  var body = document.getElementById('settings-body');
-
-  body.nodes.clear();
-
-  var form = new FormElement();
-  var fieldSet = new FieldSetElement();
-  body.append(form);
-  form.append(fieldSet);
-
-  bool isChecked(CheckboxInputElement checkBox) => checkBox.checked;
-
-  String messageFor(UserOption option) {
-    var message = messages[option.name];
-    if (message is List) message = message[0];
-    return (message == null) ? option.name : message;
-  }
-
-  String placeHolderFor(UserOption option) {
-    var message = messages[option.name];
-    if (message is! List) return '';
-    message = message[1];
-    return (message == null) ? '' : message;
-  }
-
-  void addBooleanOption(BooleanUserOption option) {
-    CheckboxInputElement checkBox = new CheckboxInputElement()
-        ..checked = option.value
-        ..onChange.listen((Event e) { option.value = isChecked(e.target); });
-
-    LabelElement label = new LabelElement()
-        ..classes.add('checkbox')
-        ..append(checkBox)
-        ..appendText(' ${messageFor(option)}');
-
-    fieldSet.append(label);
-  }
-
-  void addStringOption(StringUserOption option) {
-    fieldSet.append(new LabelElement()..appendText(messageFor(option)));
-    var textInput = new TextInputElement();
-    textInput.classes.add('input-block-level');
-    String value = option.value;
-    if (!value.isEmpty) {
-      textInput.value = value;
-    }
-    textInput.placeholder = placeHolderFor(option);;
-    textInput.onChange.listen(updateCodeFont);
-    fieldSet.append(textInput);
-  }
-
-  void addThemeOption(StringUserOption option) {
-    fieldSet.append(new LabelElement()..appendText('Theme:'));
-    var themeSelector = new SelectElement();
-    themeSelector.classes.add('input-block-level');
-    for (Theme theme in THEMES) {
-      OptionElement option = new OptionElement()..appendText(theme.name);
-      if (theme == currentTheme) option.selected = true;
-      themeSelector.append(option);
-    }
-    themeSelector.onChange.listen(updateTheme);
-    fieldSet.append(themeSelector);
-  }
-
-  for (UserOption option in options) {
-    if (option.isHidden) continue;
-    if (option.name == 'theme') {
-      addThemeOption(option);
-    } else if (option is BooleanUserOption) {
-      addBooleanOption(option);
-    } else if (option is StringUserOption) {
-      addStringOption(option);
-    }
-  }
-
-  var dialog = document.getElementById('settings-dialog');
-
-  if (settingsHeight == 0) {
-    settingsHeight = dialog.getBoundingClientRect().height;
-    dialog.classes
-        ..add('slider')
-        ..remove('myhidden');
-    Timer.run(() {
-      dialog.style.height = '${settingsHeight}px';
-    });
-  } else {
-    dialog.style.height = '${settingsHeight}px';
-  }
-
-  onSubmit(Event event) {
-    event.preventDefault();
-
-    window.localStorage['alwaysRunInWorker'] = '$alwaysRunInWorker';
-    window.localStorage['verboseCompiler'] = '$verboseCompiler';
-    window.localStorage['minified'] = '$minified';
-    window.localStorage['onlyAnalyze'] = '$onlyAnalyze';
-    window.localStorage['enableDartMind'] = '$enableDartMind';
-    window.localStorage['compilationPaused'] = '$compilationPaused';
-    window.localStorage['codeFont'] = '$codeFont';
-
-    dialog.style.height = '0px';
-  }
-  form.onSubmit.listen(onSubmit);
-
-  var doneButton = document.getElementById('settings-done');
-  doneButton.onClick.listen(onSubmit);
-}
diff --git a/site/try/src/user_option.dart b/site/try/src/user_option.dart
deleted file mode 100644
index 532c3f7..0000000
--- a/site/try/src/user_option.dart
+++ /dev/null
@@ -1,66 +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 trydart.userOption;
-
-/// Persistent user-configurable option.
-///
-/// Options included in [options] in settings.dart will automatically be
-/// included in the settings UI unless [isHidden] is true.
-///
-/// The value of an option is persisted in [storage] which is normally the
-/// browser's "localStorage", and [name] is a key in "localStorage".  This
-/// means that hidden options can be controlled by opening the JavaScript
-/// console and evaluate:
-///
-///   localStorage['name'] = value // or
-///   localStorage.name = value
-///
-/// An option can be reset to the default value using:
-///
-///   delete localStorage['name'] // or
-///   delete localStorage.name
-class UserOption {
-  final String name;
-
-  final bool isHidden;
-
-  static var storage;
-
-  const UserOption(this.name, {this.isHidden: false});
-
-  get value => storage[name];
-
-  void set value(newValue) {
-    storage[name] = newValue;
-  }
-
-  void setIfNotInitialized(newValueEvaluator()) {
-    if (storage[name] == null) {
-      value = newValueEvaluator();
-    }
-  }
-}
-
-class BooleanUserOption extends UserOption {
-  const BooleanUserOption(String name, {bool isHidden: false})
-      : super(name, isHidden: isHidden);
-
-  bool get value => super.value == 'true';
-
-  void set value(bool newValue) {
-    super.value = '$newValue';
-  }
-}
-
-class StringUserOption extends UserOption {
-  const StringUserOption(String name, {bool isHidden: false})
-      : super(name, isHidden: isHidden);
-
-  String get value => super.value == null ? '' : super.value;
-
-  void set value(String newValue) {
-    super.value = newValue;
-  }
-}
diff --git a/site/try/ssl.appcache b/site/try/ssl.appcache
deleted file mode 100644
index c8a117d..0000000
--- a/site/try/ssl.appcache
+++ /dev/null
@@ -1,26 +0,0 @@
-CACHE MANIFEST
-# 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.
-
-# @@TIMESTAMP@@
-
-CACHE:
-compiler_isolate.dart.js
-dartlang-style.css
-iframe.html
-iframe.js
-leap.dart.js
-line_numbers.css
-sdk.json
-
-dart-icon-196px.png
-dart-icon.png
-dart-iphone5.png
-favicon.ico
-try-dart-screenshot.png
-
-/css/fonts/fontawesome-webfont.woff?v=3.0.1
-
-NETWORK:
-*
diff --git a/site/try/testing.txt b/site/try/testing.txt
deleted file mode 100644
index 331148b..0000000
--- a/site/try/testing.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-Things to test manually:
-
-1. Each sample compiles and run as expected.
-
-2. Check that "add to home screen" works on iOS:
-
-   - Check that "add to home screen" creates a new icon in Safari (Dart logo on
-     white background with rounded corners). The suggested name should be "Try
-     Dart!".
-
-   - Check that the app launches as a full screen app which must be killed
-     separately from Safari.
-
-   - Check that the splash screen shows (Dart logo on white background).
-
-   - Check that the initial view port displays the full page, but that it can
-     be zoomed.
-
-3. Check that "add to home screen" works on Chrome Mobile (Android):
-
-   - Check the menu item "add to home screen" is enabled in Chrome.
-
-   - Check that an icon (Dart logo with transparent background) is added to the
-     Android home screen. The suggested name should be "Try Dart!".
-
-   - Check that the app launches full screen and is separate from Chrome in the
-     task viewer. For now, expect that the icon in task manager is Chrome and
-     the name is just "web app".
-
-4. Check that the site has a nice screen shot on Google+.
-
-   - Validate using http://www.google.com/webmasters/tools/richsnippets
-
-   - Try sharing on Google+. The screen shot should appear before you actually
-     share, so you don't need to actually share.
diff --git a/site/try/try-dart-screenshot.png b/site/try/try-dart-screenshot.png
deleted file mode 100644
index d1546de..0000000
--- a/site/try/try-dart-screenshot.png
+++ /dev/null
Binary files differ
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 1845277..12e0ed9 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -4,6 +4,15 @@
 
 [ $compiler == dart2analyzer ]
 
+# Trailing commas are now allowed by the language - issue #26644
+Language/Functions/Formal_Parameters/syntax_t12: MissingCompileTimeError
+Language/Functions/Formal_Parameters/syntax_t05: MissingCompileTimeError
+Language/Functions/Formal_Parameters/syntax_t04: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t10: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/syntax_t05: MissingCompileTimeError
+
 WebPlatformTest/html/semantics/forms/the-textarea-element/textarea-type_t01: fail
 LayoutTests/fast/events/event-creation_t01: Skip # Roll 45 OverflowEvent removed
 LayoutTests/fast/forms/checkValidity-001_t01: fail
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 80a6317..9d68884 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -76,7 +76,7 @@
 [ $runtime == dartium || $compiler == dart2js ]
 LibTest/async/Future/Future.delayed_A01_t02: Pass, Fail # Issue 15524
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == drt || $runtime == dartium || $runtime == dart_precompiled) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2appjit) && ($runtime == vm || $runtime == drt || $runtime == dartium || $runtime == dart_precompiled || $runtime == dart_app) ]
 # Optional trailing commas for argument and parameter lists added to language.
 # https://github.com/dart-lang/co19/issues/68
 Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: Fail, OK
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 2740bdf..a0dd69f 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,6 +3,15 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
+# Trailing commas are now allowed by the language - issue #26644
+Language/Functions/Formal_Parameters/syntax_t12: MissingCompileTimeError
+Language/Functions/Formal_Parameters/syntax_t05: MissingCompileTimeError
+Language/Functions/Formal_Parameters/syntax_t04: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/syntax_t05: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t05: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/syntax_t10: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/syntax_t05: MissingCompileTimeError
+
 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
@@ -876,6 +885,7 @@
 LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/csstext-of-content-string_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: RuntimeError # Please triage this failure
@@ -890,11 +900,13 @@
 LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-family-trailing-bracket-gunk_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/fontfaceset-download-error_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/font-family-fallback-reset_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/getPropertyValue-border_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/implicit-attach-marking_t01: Skip # Times out. Please triage this failure
@@ -1028,6 +1040,7 @@
 LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/css-shorthand-common-value_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/custom/element-names_t01: Pass, RuntimeError # Please triage this failure
@@ -1063,7 +1076,6 @@
 LayoutTests/fast/dom/shadow/shadowdom-for-input-type-change_t01: RuntimeError # Issue 26729
 LayoutTests/fast/dom/shadow/shadowroot-clonenode_t01: RuntimeError # Issue 26729
 LayoutTests/fast/dom/shadow/shadowroot-host_t01: RuntimeError # Issue 26729
-LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # Please triage this failure
@@ -1089,6 +1101,7 @@
 LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/events/div-focus_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/events/event-attributes-after-exception_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/event-creation_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/event-listener-html-non-html-confusion_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/event-trace_t01: RuntimeError # Please triage this failure
@@ -1482,8 +1495,10 @@
 WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out. Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out. Please triage this failure
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind_t01: RuntimeError # 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_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # Please triage this failure
@@ -1524,7 +1539,6 @@
 WebPlatformTest/html/semantics/selectors/pseudo-classes/enabled_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/selectors/pseudo-classes/focus_t01: Pass, RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/selectors/pseudo-classes/indeterminate_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/selectors/pseudo-classes/link_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/selectors/pseudo-classes/valid-invalid_t01: Pass, RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # Please triage this failure
@@ -1663,6 +1677,7 @@
 [ $compiler == dart2js && $runtime == chrome && $system == macos ]
 Language/Expressions/Function_Invocation/async_invokation_t04: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/canvas-test_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Times out flakily.
 LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Skip # Times out. Please triage this failure.
 LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
@@ -1828,10 +1843,7 @@
 LayoutTests/fast/canvas/canvas-currentColor_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented.
 LayoutTests/fast/canvas/canvas-drawImage-incomplete_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-ellipse-360-winding_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-ellipse-negative-radius_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-ellipse-zero-lineto_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-ellipse_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-fill-zeroSizeGradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-fillRect-zeroSizeGradient_t01: RuntimeError # Please triage this failure
@@ -1869,10 +1881,9 @@
 LayoutTests/fast/canvas/rgba-parsing_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Pass, RuntimeError # Issue 26898
+LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Pass, RuntimeError # Issue 26898
+LayoutTests/fast/canvas/webgl/context-lost_t01: Pass, RuntimeError # Issue 26898
 LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: Skip # Times out.
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
@@ -2044,7 +2055,6 @@
 LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/parsing-css-escapes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/parsing-css-nonascii_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/parsing-css-nth-child_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/parsing-unexpected-eof_t01: RuntimeError # Please triage this failure
@@ -2801,7 +2811,6 @@
 LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-invalid-values_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-invalid-xml_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: RuntimeError # Please triage this failure
@@ -2931,6 +2940,7 @@
 LibTest/html/Window/requestFileSystem_A02_t01: RuntimeError # Please triage this failure
 LibTest/html/Window/resizeBy_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Window/resizeTo_A01_t01: RuntimeError # Please triage this failure
+LibTest/math/log_A01_t01: Fail # Please triage this failure.
 LibTest/typed_data/Float32List/Float32List.view_A06_t01: RuntimeError # Please triage this failure
 LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: RuntimeError # Please triage this failure
 LibTest/typed_data/Float64List/Float64List.view_A06_t01: RuntimeError # Please triage this failure
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 941a1d8..bc8772c 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -158,11 +158,13 @@
 Language/Metadata/*: SkipByDesign # Uses dart:mirrors
 Language/Expressions/Null/instance_of_class_null_t01: Skip # Uses dart:mirrors
 
+[ $noopt || $compiler == precompiler || $compiler == dart2appjit || $mode == product ]
+Language/Libraries_and_Scripts/Imports/deferred_import_t02: Skip # Eager loading
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01: Skip # Eager loading
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: Skip # Eager loading
+
 [ $runtime == dart_precompiled || $runtime == dart_app ]
 LibTest/isolate/Isolate/spawnUri*: Skip # Isolate.spawnUri
-Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01: CompileTimeError # spawnUri
-Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: RuntimeError # spawnUri
-Language/Libraries_and_Scripts/Imports/deferred_import_t02: RuntimeError # Unsupported
 
 [ $noopt || $compiler == precompiler ]
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
@@ -191,22 +193,39 @@
 [ $compiler == precompiler && $runtime == dart_precompiled && $arch == simarm ]
 LibTest/typed_data/Float32x4/operator_division_A01_t02: RuntimeError # Issue #26675
 
-[ $hot_reload ]
-LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Pass, Crash
-LibTest/collection/HashSet/HashSet_class_A01_t01: Crash
-LibTest/collection/IterableBase/IterableBase_class_A01_t02: Crash
-LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Crash
-LibTest/collection/LinkedList/iterator_current_A01_t01: Crash
-LibTest/collection/ListBase/ListBase_class_A01_t01: Pass, Timeout, Crash
+[ $hot_reload || $hot_reload_rollback ]
+Language/Expressions/Assignment/prefix_object_t02: Crash # Requires deferred libraries
+Language/Expressions/Constants/constant_constructor_t03: Crash # Requires deferred libraries
+Language/Expressions/Constants/identifier_denotes_a_constant_t06: Crash # Requires deferred libraries
+Language/Expressions/Constants/identifier_denotes_a_constant_t07: Crash # Requires deferred libraries
+Language/Expressions/Constants/static_constant_t06: Crash # Requires deferred libraries
+Language/Expressions/Constants/static_constant_t07: Crash # Requires deferred libraries
+Language/Expressions/Constants/top_level_function_t04: Crash # Requires deferred libraries
+Language/Expressions/Constants/top_level_function_t05: Crash # Requires deferred libraries
+Language/Expressions/Instance_Creation/Const/deferred_type_t01: Crash # Requires deferred libraries
+Language/Expressions/Instance_Creation/Const/deferred_type_t02: Crash # Requires deferred libraries
+Language/Expressions/Instance_Creation/New/evaluation_t19: Crash # Requires deferred libraries
+Language/Expressions/Instance_Creation/New/evaluation_t20: Crash # Requires deferred libraries
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/deferred_type_t01: Crash # Requires deferred libraries
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: Crash # Requires deferred libraries
+Language/Expressions/Type_Cast/evaluation_t10: Crash # Requires deferred libraries
+Language/Expressions/Type_Test/evaluation_t10: Crash # Requires deferred libraries
+Language/Libraries_and_Scripts/Imports/deferred_import_t01: Crash # Requires deferred libraries
+Language/Libraries_and_Scripts/Imports/deferred_import_t02: Crash # Requires deferred libraries
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01: Crash # Requires deferred libraries
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: Crash # Requires deferred libraries
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t03: Crash # Requires deferred libraries
+Language/Libraries_and_Scripts/Imports/static_type_t01: Crash # Requires deferred libraries
+Language/Types/Dynamic_Type_System/deferred_type_error_t01: Crash # Requires deferred libraries
+Language/Types/Static_Types/deferred_type_t01: Crash # Requires deferred libraries
+LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Crash # Requires deferred libraries
+LibTest/collection/ListBase/ListBase_class_A01_t01: Pass, Timeout
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
-LibTest/collection/ListMixin/ListMixin_class_A01_t01: Pass, Timeout, Crash
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Pass, Timeout
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Pass, Timeout
-LibTest/collection/ListQueue/ListQueue_class_A01_t01: Pass, Crash
-LibTest/collection/Queue/Queue_class_A01_t01: Pass, Crash
-LibTest/core/List/List.from_A01_t01: Crash
-LibTest/core/List/List_class_A01_t01: Pass, Crash
-LibTest/core/List/List_class_A01_t02: Pass, Timeout, Crash
+LibTest/core/List/List_class_A01_t02: Pass, Timeout
 LibTest/core/Map/Map_class_A01_t04: Pass, Timeout
-LibTest/core/Set/IterableBase_A01_t01: Pass, Crash
 LibTest/core/Uri/Uri_A06_t03: Pass, Timeout
 LibTest/core/Uri/encodeQueryComponent_A01_t02: Pass, Timeout
+LibTest/isolate/Isolate/spawn_A01_t04: Pass, Timeout
+
diff --git a/tests/compiler/dart2js/analyze_test_test.dart b/tests/compiler/dart2js/analyze_test_test.dart
index ea2524d..43d490d 100644
--- a/tests/compiler/dart2js/analyze_test_test.dart
+++ b/tests/compiler/dart2js/analyze_test_test.dart
@@ -35,12 +35,9 @@
 const List<String> SKIP_LIST = const <String>[
   // Helper files:
   "/data/",
-  "http_launch_data/",
+  "quarantined/http_launch_data/",
   "mirrors_helper.dart",
   "path%20with%20spaces/",
-  "cps_ir/input/",
-  // No longer maintained:
-  "backend_dart/",
   // Broken tests:
   "quarantined/http_test.dart",
   // Package directory
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index 8106a06..292c2c9 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -23,9 +23,6 @@
       "The method 'asAssert' is never called.",
       "The method 'asLiteralBool' is never called."],
 
-  // Some things in dart_printer are not yet used
-  "lib/src/dart_backend/backend_ast_nodes.dart": const [" is never "],
-
   // Uncalled methods in SemanticSendVisitor and subclasses.
   "lib/src/resolution/semantic_visitor.dart": const [
       "The method 'error"],
@@ -43,29 +40,9 @@
   "lib/src/serialization/": const [
       "is never"],
 
-  // Nested functions are currently kept alive in the IR.
-  "lib/src/tree_ir/": const [
-    "accept", "FunctionExpression", "CreateFunction"
-  ],
-
   "lib/src/universe/universe.dart": const [
       "The method 'getterInvocationsByName' is never called.",
       "The method 'setterInvocationsByName' is never called."],
-
-  "lib/src/cps_ir/": const [
-    "accept", "CreateFunction",
-  ],
-
-  "lib/src/dart_backend/backend_ast_to_frontend_ast.dart": const [
-    " is never "
-  ],
-
-  // Useful utility functions that are not currently used.
-  "lib/src/cps_ir/cps_fragment.dart": const [
-    "The method 'beginLoop' is never called.",
-    "The method 'continueLoop' is never called.",
-    "The method 'invokeMethod' is never called.",
-  ],
 };
 
 void main() {
diff --git a/tests/compiler/dart2js/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await_js_transform_test.dart
index 40c9eb6..e934d28 100644
--- a/tests/compiler/dart2js/async_await_js_transform_test.dart
+++ b/tests/compiler/dart2js/async_await_js_transform_test.dart
@@ -73,8 +73,6 @@
           v1 = 0;
           if (v1 < 0 || v1 >= v0.length)
             H.ioore(v0, v1);
-          else
-            ;
           v2 = 4;
           v3 = 2;
           P.print(v0[v1].call$2(v2, v3));
diff --git a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
deleted file mode 100644
index 5db4160..0000000
--- a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
+++ /dev/null
@@ -1,1119 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package: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';
-import '../output_collector.dart';
-import 'package:compiler/compiler.dart';
-import 'package:compiler/src/common/names.dart' show Identifiers;
-import 'package:compiler/src/dart_backend/dart_backend.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/tree/tree.dart';
-
-const ioLib = r'''
-library io;
-class Platform {
-  static int operatingSystem;
-}
-''';
-
-const htmlLib = r'''
-library html;
-Window __window;
-Window get window => __window;
-abstract class Window {
-  Navigator get navigator;
-}
-abstract class Navigator {
-  String get userAgent;
-}
-''';
-
-/**
- * Library name is assumed to be 'mylib' in 'mylib.dart' file.
- */
-testDart2Dart(String mainSrc, {String librarySrc,
-                               String expectedResult,
-                               bool minify: false,
-                               bool stripTypes: false}) {
-
-  // If expectedResult is not provided, check that source string remains the
-  // same.
-  if (expectedResult == null) {
-    Expect.equals(null, librarySrc);
-    expectedResult = mainSrc;
-  }
-
-  fileUri(path) => new Uri(scheme: 'file', path: path);
-
-  final scriptUri = fileUri('script.dart');
-  final libUri = fileUri('mylib.dart');
-
-  provider(uri) {
-    if (uri == scriptUri) return new Future.value(mainSrc);
-    if (uri.toString() == libUri.toString()) {
-      return new Future.value(librarySrc);
-    }
-    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);
-    } else if (uri.path.endsWith('/io.dart')) {
-      return new Future.value(ioLib);
-    } else if (uri.path.endsWith('/js_helper.dart')) {
-      return new Future.value(buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY));
-    } else if (uri.path.endsWith('/html_dart2js.dart')) {
-      // TODO(smok): The file should change to html_dartium at some point.
-      return new Future.value(htmlLib);
-    } else if (uri.path.endsWith('/foreign_helper.dart')) {
-      return new Future.value(
-          buildLibrarySource(DEFAULT_FOREIGN_HELPER_LIBRARY));
-    } else if (uri.path.endsWith('/isolate_helper.dart')) {
-      return new Future.value(
-          buildLibrarySource(DEFAULT_ISOLATE_HELPER_LIBRARY));
-    }
-    return new Future.value('');
-  }
-
-  handler(uri, begin, end, message, kind) {
-    if (identical(kind, Diagnostic.ERROR) || identical(kind, Diagnostic.CRASH)) {
-      Expect.fail('$uri: $begin-$end: $message [$kind]');
-    }
-  }
-
-  final options = <String>['--output-type=dart'];
-  // Some tests below are using dart:io.
-  if (minify) options.add('--minify');
-  if (stripTypes) options.add('--force-strip=types');
-
-  asyncTest(() {
-    OutputCollector outputCollector = new OutputCollector();
-    return compile(
-        scriptUri,
-        Uri.base.resolve('sdk/'),
-        fileUri('packageRoot/'),
-        provider,
-        handler,
-        options,
-        outputCollector).then((_) {
-      String code = outputCollector.getOutput('', 'dart');
-      Expect.equals(expectedResult, code,
-          'expected:\n$expectedResult\nactual:\n$code');
-    });
-  });
-}
-
-testSimpleFileUnparse() {
-  final src = '''
-should_be_dropped() {
-}
-
-should_be_kept() {
-}
-
-main() {
-  should_be_kept();
-}
-''';
-  testDart2Dart(src, expectedResult: '''
-should_be_kept() {}
-main() {
-  should_be_kept();
-}
-''');
-}
-testTopLevelField() {
-  testDart2Dart('''
-final String x = "asd";
-main() {
-  x;
-}
-''');
-}
-
-testSimpleTopLevelClass() {
-  testDart2Dart('''
-main() {
-  new A();
-}
-class A {
-  A() {}
-}
-''');
-}
-
-testClassWithSynthesizedConstructor() {
-  testDart2Dart('''
-main() {
-  new A();
-}
-class A {}
-''');
-}
-
-testClassWithMethod() {
-  testDart2Dart(r'''
-main() {
-  var a = new A();
-  a.foo();
-}
-class A {
-  void foo() {}
-}
-''');
-}
-
-testExtendsImplements() {
-  testDart2Dart('''
-main() {
-  new B<Object>();
-}
-class A<T> {}
-class B<T> extends A<T> {}
-''');
-}
-
-testVariableDefinitions() {
-  testDart2Dart('''
-main() {
-  var x, y;
-  final String s = null;
-}
-''');
-  testDart2Dart('''
-main() {
-  final int x = 0, y = 0;
-  final String s = null;
-}
-''');
-  testDart2Dart('''
-foo(f, g) {}
-main() {
-  foo(1, 2);
-}
-''');
-  testDart2Dart('''
-foo(f(arg)) {}
-main() {
-  foo(main);
-}
-''');
-  // A couple of static/finals inside a class.
-  testDart2Dart('''
-main() {
-  A.a;
-  A.b;
-}
-class A {
-  static const String a = "5";
-  static const String b = "4";
-}
-''');
-  // Class member of typedef-ed function type.
-  // Maybe typedef should be included in the result too, but it
-  // works fine without it.
-  testDart2Dart('''
-typedef void foofunc(_0);
-main() {
-  new A((arg) {});
-}
-class A {
-  A(foofunc this.handler);
-  final foofunc handler;
-}
-''');
-}
-
-testGetSet() {
-  // Top-level get/set.
-  testDart2Dart('''
-set foo(arg) {}
-get foo {
-  return 5;
-}
-main() {
-  foo;
-  foo = 5;
-}
-''');
-  // Field get/set.
-  testDart2Dart('''
-main() {
-  var a = new A();
-  a.foo;
-  a.foo = 5;
-}
-class A {
-  set foo(a) {}
-  get foo {
-    return 5;
-  }
-}
-''');
-  // Typed get/set.
-  testDart2Dart('''
-String get foo {
-  return "a";
-}
-main() {
-  foo;
-}
-''');
-}
-
-testAbstractClass() {
-  testDart2Dart('''
-main() {
-  A.foo;
-}
-abstract class A {
-  static final num foo = 0;
-}
-''');
-}
-
-testConflictSendsRename() {
-  // Various Send-s to current library and external library. Verify that
-  // everything is renamed correctly in conflicting class names and global
-  // functions.
-  var librarySrc = '''
-library mylib;
-
-globalfoo() {}
-var globalVar;
-var globalVarInitialized = 6, globalVarInitialized2 = 7;
-
-class A {
-  A(){}
-  A.fromFoo(){}
-  static staticfoo(){}
-  foo(){}
-  static const field = 5;
-}
-''';
-  var mainSrc = '''
-import 'mylib.dart' as mylib;
-
-globalfoo() {}
-var globalVar;
-var globalVarInitialized = 6, globalVarInitialized2 = 7;
-
-class A {
-  A(){}
-  A.fromFoo(){}
-  static staticfoo(){}
-  foo(){}
-  static const field = 5;
-}
-
-main() {
-  globalVar;
-  globalVarInitialized;
-  globalVarInitialized2;
-  globalfoo();
-  A.field;
-  A.staticfoo();
-  new A();
-  new A.fromFoo();
-  new A().foo();
-
-  mylib.globalVar;
-  mylib.globalVarInitialized;
-  mylib.globalVarInitialized2;
-  mylib.globalfoo();
-  mylib.A.field;
-  mylib.A.staticfoo();
-  new mylib.A();
-  new mylib.A.fromFoo();
-  new mylib.A().foo();
-}
-''';
-  var expectedResult = '''
-globalfoo() {}
-var globalVar;
-var globalVarInitialized = 6;
-var globalVarInitialized2 = 7;
-class A {
-  A() {}
-  A.fromFoo() {}
-  static staticfoo() {}
-  foo() {}
-  static const field = 5;
-}
-globalfoo_A() {}
-var globalVar_A;
-var globalVarInitialized_A = 6;
-var globalVarInitialized2_A = 7;
-class A_A {
-  A_A() {}
-  A_A.fromFoo_A() {}
-  static staticfoo_A() {}
-  foo() {}
-  static const field_A = 5;
-}
-main() {
-  globalVar_A;
-  globalVarInitialized_A;
-  globalVarInitialized2_A;
-  globalfoo_A();
-  A_A.field_A;
-  A_A.staticfoo_A();
-  new A_A();
-  new A_A.fromFoo_A();
-  new A_A().foo();
-  globalVar;
-  globalVarInitialized;
-  globalVarInitialized2;
-  globalfoo();
-  A.field;
-  A.staticfoo();
-  new A();
-  new A.fromFoo();
-  new A().foo();
-}
-''';
-  testDart2Dart(mainSrc, librarySrc: librarySrc,
-      expectedResult: expectedResult);
-}
-
-testNoConflictSendsRename() {
-  // Various Send-s to current library and external library. Nothing should be
-  // renamed here, only library prefixes must be cut.
-  var librarySrc = '''
-library mylib;
-
-globalfoo() {}
-
-class A {
-  A(){}
-  A.fromFoo(){}
-  static staticfoo(){}
-  foo(){}
-  static const field = 5;
-}
-''';
-  var mainSrc = '''
-import 'mylib.dart' as mylib;
-
-myglobalfoo() {}
-
-class MyA {
-  MyA(){}
-  MyA.myfromFoo(){}
-  static mystaticfoo(){}
-  myfoo(){}
-  static const myfield = 5;
-}
-
-main() {
-  myglobalfoo();
-  MyA.myfield;
-  MyA.mystaticfoo();
-  new MyA();
-  new MyA.myfromFoo();
-  new MyA().myfoo();
-
-  mylib.globalfoo();
-  mylib.A.field;
-  mylib.A.staticfoo();
-  new mylib.A();
-  new mylib.A.fromFoo();
-  new mylib.A().foo();
-}
-''';
-  var expectedResult = '''
-globalfoo() {}
-class A {
-  A() {}
-  A.fromFoo() {}
-  static staticfoo() {}
-  foo() {}
-  static const field = 5;
-}
-myglobalfoo() {}
-class MyA {
-  MyA() {}
-  MyA.myfromFoo() {}
-  static mystaticfoo() {}
-  myfoo() {}
-  static const myfield = 5;
-}
-main() {
-  myglobalfoo();
-  MyA.myfield;
-  MyA.mystaticfoo();
-  new MyA();
-  new MyA.myfromFoo();
-  new MyA().myfoo();
-  globalfoo();
-  A.field;
-  A.staticfoo();
-  new A();
-  new A.fromFoo();
-  new A().foo();
-}
-''';
-  testDart2Dart(mainSrc, librarySrc: librarySrc,
-      expectedResult: expectedResult);
-}
-
-testConflictLibraryClassRename() {
-  var librarySrc = '''
-library mylib;
-
-topfoo() {}
-
-class A {
-  foo() {}
-}
-''';
-  var mainSrc = '''
-import 'mylib.dart' as mylib;
-topfoo() {
-  var x = 5;
-}
-class A {
-  num foo() {}
-  A.fromFoo() {}
-  mylib.A myliba;
-  List<A> mylist;
-}
-mylib.A getA() => null;
-main() {
-  var a = new mylib.A();
-  a.foo();
-  var b = new A.fromFoo();
-  b.foo();
-  var GREATVAR = b.myliba;
-  b.mylist;
-  a = getA();
-  topfoo();
-  mylib.topfoo();
-}
-''';
-  var expectedResult = '''
-topfoo() {}
-class A {
-  foo() {}
-}
-topfoo_A() {
-  var x = 5;
-}
-class A_A {
-  num foo() {}
-  A_A.fromFoo() {}
-  A myliba;
-  List<A_A> mylist;
-}
-A getA() => null;
-main() {
-  var a = new A();
-  a.foo();
-  var b = new A_A.fromFoo();
-  b.foo();
-  var GREATVAR = b.myliba;
-  b.mylist;
-  a = getA();
-  topfoo_A();
-  topfoo();
-}
-''';
-  testDart2Dart(mainSrc, librarySrc: librarySrc,
-      expectedResult: expectedResult);
-}
-
-testClassExtendsWithArgs() {
-  testDart2Dart('''
-main() {
-  new B<Object>();
-}
-class A<T extends Object> {}
-class B<T extends Object> extends A<T> {}
-''', expectedResult: '''
-main() {
-  new B<Object>();
-}
-class A<T> {}
-class B<T> extends A<T> {}
-''');
-}
-
-testStaticInvocation() {
-  testDart2Dart('''
-main() {
-  var x = double.parseDouble("1");
-}
-''');
-}
-
-testLibraryGetSet() {
-  var librarySrc = '''
-library mylib;
-
-get topgetset => 5;
-set topgetset(arg) {}
-''';
-  var mainSrc = '''
-import 'mylib.dart' as mylib;
-
-get topgetset => 6;
-set topgetset(arg) {}
-
-main() {
-  topgetset;
-  topgetset = 6;
-
-  mylib.topgetset;
-  mylib.topgetset = 5;
-}
-''';
-  var expectedResult = '''
-get topgetset => 5;
-set topgetset(arg) {}
-get topgetset_A => 6;
-set topgetset_A(arg) {}
-main() {
-  topgetset_A;
-  topgetset_A = 6;
-  topgetset;
-  topgetset = 5;
-}
-''';
-  testDart2Dart(mainSrc, librarySrc: librarySrc,
-      expectedResult: expectedResult);
-}
-
-testFieldTypeOutput() {
-  testDart2Dart('''
-main() {
-  new A().field;
-}
-class B {}
-class A {
-  B field;
-}
-''');
-}
-
-class DynoMap implements Map<Element, ElementAst> {
-  final compiler;
-  DynoMap(this.compiler);
-
-  ElementAst operator[](AstElement element) {
-    return new ElementAst(element.resolvedAst.node,
-                          element.resolvedAst.elements);
-  }
-
-  noSuchMethod(Invocation invocation) => throw 'unimplemented method';
-}
-
-PlaceholderCollector collectPlaceholders(compiler, element) {
-  DartBackend backend = compiler.backend;
-  return new PlaceholderCollector(
-      compiler.reporter,
-      backend.mirrorRenamer,
-      new Set<String>(),
-      new DynoMap(compiler),
-      compiler.mainFunction)
-    ..collect(element);
-}
-
-testLocalFunctionPlaceholder() {
-  var src = '''
-main() {
-  function localfoo() {}
-  localfoo();
-}
-''';
-  MockCompiler compiler = new MockCompiler.internal(emitJavaScript: false);
-  asyncTest(() => compiler.init().then((_) {
-    assert(compiler.backend is DartBackend);
-    compiler.parseScript(src);
-    FunctionElement mainElement = compiler.mainApp.find(Identifiers.main);
-    compiler.processQueue(compiler.enqueuer.resolution, mainElement);
-    PlaceholderCollector collector = collectPlaceholders(compiler, mainElement);
-    FunctionExpression mainNode = mainElement.node;
-    Block body = mainNode.body;
-    FunctionDeclaration functionDeclaration = body.statements.nodes.head;
-    FunctionExpression fooNode = functionDeclaration.function;
-    LocalPlaceholder fooPlaceholder =
-        collector.functionScopes[mainElement].localPlaceholders.first;
-    Expect.isTrue(fooPlaceholder.nodes.contains(fooNode.name));
-  }));
-}
-
-testTypeVariablesAreRenamed() {
-  // Somewhat a hack: we require all the references of the identifier
-  // to be renamed in the same way for the whole library. Hence
-  // if we have a class and type variable with the same name, they
-  // both should be renamed.
-  var librarySrc = '''
-library mylib;
-typedef void MyFunction<T extends num>(T arg);
-class T {}
-class B<T> {}
-class A<T> extends B<T> { T f; }
-''';
-  var mainSrc = '''
-import 'mylib.dart' as mylib;
-typedef void MyFunction<T extends num>(T arg);
-class T {}
-class B<T> {}
-class A<T> extends B<T> { T f; }
-
-main() {
-  MyFunction myf1;
-  mylib.MyFunction myf2;
-  new A<int>().f;
-  new T();
-
-  new mylib.A<int>().f;
-  new mylib.T();
-}
-''';
-  var expectedResult = '''
-typedef void MyFunction<T_B extends num>(T_B _0);
-class T {}
-class B<T_B> {}
-class A<T_B> extends B<T_B> {
-  T_B f;
-}
-typedef void MyFunction_A<T_B extends num>(T_B _0);
-class T_A {}
-class B_A<T_B> {}
-class A_A<T_B> extends B_A<T_B> {
-  T_B f;
-}
-main() {
-  MyFunction_A myf1;
-  MyFunction myf2;
-  new A_A<int>().f;
-  new T_A();
-  new A<int>().f;
-  new T();
-}
-''';
-  testDart2Dart(mainSrc, librarySrc: librarySrc,
-      expectedResult: expectedResult);
-}
-
-testClassTypeArgumentBound() {
-  var librarySrc = '''
-library mylib;
-
-class I {}
-class A<T extends I> {}
-
-''';
-  var mainSrc = '''
-import 'mylib.dart' as mylib;
-
-class I {}
-class A<T extends I> {}
-
-main() {
-  new A();
-  new mylib.A();
-}
-''';
-  var expectedResult = '''
-class I {}
-class A<T extends I> {}
-class I_A {}
-class A_A<T extends I_A> {}
-main() {
-  new A_A();
-  new A();
-}
-''';
-  testDart2Dart(mainSrc, librarySrc: librarySrc,
-      expectedResult: expectedResult);
-  }
-
-testDoubleMains() {
-  var librarySrc = '''
-library mylib;
-main() {}
-''';
-  var mainSrc = '''
-import 'mylib.dart' as mylib;
-main() {
-  mylib.main();
-}
-''';
-  var expectedResult = '''
-main_A() {}
-main() {
-  main_A();
-}
-''';
-  testDart2Dart(mainSrc, librarySrc: librarySrc,
-      expectedResult: expectedResult);
-}
-
-testStaticAccessIoLib() {
-  var src = '''
-import 'dart:io';
-
-main() {
-  Platform.operatingSystem;
-}
-''';
-  var expectedResult = '''
-import "dart:io";
-main() {
-  Platform.operatingSystem;
-}
-''';
-  testDart2Dart(src, expectedResult: expectedResult);
-}
-
-testMinification() {
-  var src = '''
-class ClassWithVeryVeryLongName {}
-main() {
-  new ClassWithVeryVeryLongName();
-}
-''';
-  var expectedResult =
-      'class A{}'
-      'main(){new A();}';
-  testDart2Dart(src, expectedResult: expectedResult, minify: true);
-}
-
-testClosureLocalsMinified() {
-  var src = '''
-main() {
-  var a = 7;
-  void foo1(a,b) {
-    void foo2(c,d) {
-       var E = a;
-    }
-    foo2(b, a);
-  }
-  foo1(a, 8);
-}
-''';
-  var expectedResult =
-      'main(){var A=7; B(A,C){ D(E,F){var G=A;}D(C,A);}B(A,8);}';
-  testDart2Dart(src, expectedResult: expectedResult, minify: true);
-}
-
-testParametersMinified() {
-  var src = '''
-class A {
-  var a;
-  static foo(arg1) {
-    // Should not rename arg1 to a.
-    arg1 = 5;
-  }
-}
-
-fooglobal(arg,{optionalarg: 7}) {
-  arg = 6;
-}
-
-main() {
-  new A().a;
-  A.foo(8);
-  fooglobal(8);
-}
-''';
-  var expectedResult =
-      'class B{var E;static C(A){A=5;}}D(A,{optionalarg: 7}){A=6;}'
-      'main(){new B().E;B.C(8);D(8);}';
-  testDart2Dart(src, expectedResult: expectedResult, minify: true);
-}
-
-testDeclarationTypePlaceholders() {
-  var src = '''
-String globalfield;
-const String globalconstfield;
-
-void foo(String arg) {}
-
-main() {
-  String localvar;
-  foo("5");
-}
-''';
-  var expectedResult = '''
-foo( arg) {}
-main() {
-  var localvar;
-  foo("5");
-}
-''';
-  testDart2Dart(src, expectedResult: expectedResult, stripTypes: true);
-}
-
-testPlatformLibraryMemberNamesAreFixed() {
-  var src = '''
-import 'dart:html';
-
-class A {
-  static String get userAgent => window.navigator.userAgent;
-}
-
-main() {
-  A.userAgent;
-}
-''';
-  var expectedResult = '''
-import "dart:html";
-class A {
-  static String get userAgent_A => window.navigator.userAgent;
-}
-main() {
-  A.userAgent_A;
-}
-''';
-  testDart2Dart(src, expectedResult: expectedResult);
-}
-
-testConflictsWithCoreLib() {
-  var src = '''
-import 'dart:core' as fisk;
-
-print(x) { throw 'fisk'; }
-
-main() {
-  fisk.print('corelib');
-  print('local');
-}
-''';
-  var expectedResult = """
-print_A(x) {
-  throw 'fisk';
-}
-main() {
-  print('corelib');
-  print_A('local');
-}
-""";
-  testDart2Dart(src, expectedResult: expectedResult);
-}
-
-testUnresolvedNamedConstructor1() {
-  var src = '''
-class A {
-}
-
-main() {
-  new A.named();
-}
-''';
-  var expectedResult = """
-main() {
-  new Unresolved();
-}
-""";
-  testDart2Dart(src, expectedResult: expectedResult);
-}
-
-testUnresolvedNamedConstructor2() {
-  var src = '''
-class A {
-  A() {}
-}
-
-main() {
-  new A();
-  new A.named();
-}
-''';
-  var expectedResult = """
-class A {
-  A() {}
-}
-main() {
-  new A();
-  new Unresolved();
-}
-""";
-  testDart2Dart(src, expectedResult: expectedResult);
-}
-
-testUnresolvedNamedConstructor3() {
-  var src = '''
-class A {
-  static method() {}
-}
-
-main() {
-  A.method();
-  new A.named();
-}
-''';
-  var expectedResult = """
-class A {
-  static method() {}
-}
-main() {
-  A.method();
-  new Unresolved();
-}
-""";
-  testDart2Dart(src, expectedResult: expectedResult);
-}
-
-testClassAndNamedMixinDeclarations() {
-  test(String declarations, {String expectedDeclarations}) {
-    const String mainSource = 'main() => new A();';
-    if (expectedDeclarations == null) {
-      expectedDeclarations = declarations;
-    }
-    testDart2Dart('$declarations\n$mainSource\n',
-                  expectedResult: '$expectedDeclarations\n$mainSource\n');
-  }
-
-  test('class A {}');
-  test('class A<T> {}');
-  test('class A<T extends num> {}');
-  test('class A<T extends Object> {}', expectedDeclarations: 'class A<T> {}');
-  test('class A extends Object {}', expectedDeclarations: 'class A {}');
-
-  test('''
-class S1 {}
-class A extends S1 {}''');
-
-  test('''
-class S1 {}
-class A implements S1 {}''');
-
-  test('''
-class S1 {}
-class S2 {}
-class A extends S1 implements S2 {}''');
-
-  test('''
-class S1 {}
-class S2 {}
-class S3 {}
-class A extends S1 implements S2, S3 {}''');
-
-  test('''
-class S1 {}
-class S2 {}
-class A implements S1, S2 {}''');
-
-  test('''
-class S1 {}
-class S2 {}
-class A extends Object implements S1, S2 {}''',
-       expectedDeclarations: '''
-class S1 {}
-class S2 {}
-class A implements S1, S2 {}''');
-
-  test('''
-class S1 {}
-class A extends Object with S1 {}''');
-
-  test('''
-class S1 {}
-class A = Object with S1;''');
-
-  test('''
-class S1 {}
-class S2 {}
-class A extends S1 with S2 {}''');
-
-  test('''
-class S1 {}
-class S2 {}
-class A = S1 with S2;''');
-
-  test('''
-class S1 {}
-class S2 {}
-class S3 {}
-class A extends S1 with S2, S3 {}''');
-
-  test('''
-class S1 {}
-class S2 {}
-class S3 {}
-class A = S1 with S2, S3;''');
-
-  test('''
-class S1 {}
-class S2 {}
-class S3 {}
-class S4 {}
-class S5 {}
-class A extends S1 with S2, S3 implements S4, S5 {}''');
-
-  test('''
-class S1 {}
-class S2 {}
-class S3 {}
-class S4 {}
-class S5 {}
-class A = S1 with S2, S3 implements S4, S5;''');
-
-  test('''
-class S1 {}
-class A extends Object with S1 implements S1 {}''',
-       expectedDeclarations: '''
-class S1 {}
-class A extends Object with S1 {}''');
-
-  test('''
-class S1 {}
-class A = Object with S1 implements S1;''',
-       expectedDeclarations: '''
-class S1 {}
-class A = Object with S1;''');
-
-  test('''
-class S1<T1> {}
-class S2<T2> {}
-class S3<T3> {}
-class S4<T4> {}
-class S5<T5, T6> {}
-class A<U1, U2, U3, U4, U5> extends S1<U1> with S2<U2>, S3<U3> '''
- '''implements S4<U4>, S5<U5, S5<U5, int>> {}''');
-}
-
-main() {
-  testSimpleFileUnparse();
-  testTopLevelField();
-  testSimpleTopLevelClass();
-  testClassWithSynthesizedConstructor();
-  testClassWithMethod();
-  testExtendsImplements();
-  testVariableDefinitions();
-  testGetSet();
-  testAbstractClass();
-  testConflictSendsRename();
-  testNoConflictSendsRename();
-  testConflictLibraryClassRename();
-  testClassExtendsWithArgs();
-  testStaticInvocation();
-  testLibraryGetSet();
-  testFieldTypeOutput();
-  testTypeVariablesAreRenamed();
-  testClassTypeArgumentBound();
-  testDoubleMains();
-  testStaticAccessIoLib();
-  testLocalFunctionPlaceholder();
-  testMinification();
-  testClosureLocalsMinified();
-  testParametersMinified();
-  testDeclarationTypePlaceholders();
-  testPlatformLibraryMemberNamesAreFixed();
-  testConflictsWithCoreLib();
-  testUnresolvedNamedConstructor1();
-  testUnresolvedNamedConstructor2();
-  testUnresolvedNamedConstructor3();
-  testClassAndNamedMixinDeclarations();
-}
-
diff --git a/tests/compiler/dart2js/backend_dart/dart_printer_test.dart b/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
deleted file mode 100644
index 4d331b3..0000000
--- a/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
+++ /dev/null
@@ -1,990 +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 dart_printer_test;
-
-import 'dart:mirrors';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/dart_backend/backend_ast_nodes.dart';
-import 'package:compiler/src/dart_backend/backend_ast_to_frontend_ast.dart'
-    show TreePrinter;
-import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
-import 'package:compiler/src/diagnostics/messages.dart';
-import 'package:compiler/src/diagnostics/spannable.dart' show Spannable;
-import 'package:compiler/src/parser/listener.dart';
-import 'package:compiler/src/parser/parser.dart';
-import 'package:compiler/src/scanner/scanner.dart';
-import 'package:compiler/src/tokens/token.dart';
-import 'package:compiler/src/tokens/token_constants.dart';
-import 'package:compiler/src/io/source_file.dart';
-import 'package:compiler/src/string_validator.dart';
-import 'package:compiler/src/tree/tree.dart' show DartString;
-import 'package:compiler/src/tree/tree.dart' as tree;
-import '../options_helper.dart';
-
-/// For debugging the [AstBuilder] stack. Prints information about [x].
-void show(x) {
-  StringBuffer buf = new StringBuffer();
-  Unparser unparser = new Unparser(buf);
-  void unparse(x) {
-    if (x is Expression)
-      unparser.writeExpression(x);
-    else if (x is TypeAnnotation)
-      unparser.writeType(x);
-    else if (x is Statement)
-      unparser.writeStatement(x);
-    else if (x is List) {
-      buf.write('[');
-      bool first = true;
-      for (var y in x) {
-        if (first)
-          first = false;
-        else
-          buf.write(', ');
-        unparse(y);
-      }
-      buf.write(']');
-    }
-  }
-  unparse(x);
-  print("${x.runtimeType}: ${buf.toString()}");
-}
-
-class PrintDiagnosticListener implements DiagnosticReporter {
-  void log(message) {
-    print(message);
-  }
-
-  void internalError(Spannable spannable, message) {
-    print(message);
-  }
-
-  SourceSpan spanFromSpannable(Spannable node) {
-    return new SourceSpan(null, 0, 0);
-  }
-
-  void reportFatalError(Spannable node, MessageKind errorCode,
-                        [Map arguments = const {}]) {
-    print(errorCode);
-    throw new Error();
-  }
-
-  void reportError(Spannable node, MessageKind errorCode,
-                   [Map arguments = const {}]) {
-    print(errorCode);
-  }
-
-  void reportWarning(Spannable node, MessageKind errorCode,
-                     [Map arguments = const {}]) {
-    print(errorCode);
-  }
-
-  void reportHint(Spannable node, MessageKind errorCode,
-                  [Map arguments = const {}]) {
-    print(errorCode);
-  }
-
-  void reportInfo(Spannable node, MessageKind errorCode,
-                  [Map arguments = const {}]) {
-    print(errorCode);
-  }
-
-  withCurrentElement(element, f()) {
-    f();
-  }
-}
-
-class AstBuilder extends Listener {
-  final List stack = [];
-  final StringValidator stringValidator
-         = new StringValidator(new PrintDiagnosticListener());
-
-  String asName(e) {
-    if (e is Identifier)
-      return e.name;
-    else if (e == null)
-      return null;
-    else
-      throw 'Expression is not a name: ${e.runtimeType}';
-  }
-
-  TypeAnnotation asType(x) {
-    if (x is TypeAnnotation)
-      return x;
-    if (x is Identifier)
-      return new TypeAnnotation(x.name);
-    if (x == null)
-      return null;
-    else
-      throw "Not a type: ${x.runtimeType}";
-  }
-
-  Parameter asParameter(x) {
-    if (x is Parameter)
-      return x;
-    if (x is Identifier)
-      return new Parameter(x.name);
-    else
-      throw "Not a parameter: ${x.runtimeType}";
-  }
-
-  void push(node) {
-    stack.add(node);
-  }
-  dynamic peek() {
-    return stack.last;
-  }
-  dynamic pop([coerce(x) = null]) {
-    var x = stack.removeLast();
-    if (coerce != null)
-      return coerce(x);
-    else
-      return x;
-  }
-  List popList(int count, [List result, coerce(x) = null]) {
-    if (result == null)
-      result = <Node>[];
-    for (int i=0; i<count; i++) {
-      var x = stack[stack.length-count+i];
-      if (coerce != null) {
-        x = coerce(x);
-      }
-      result.add(x);
-    }
-    stack.removeRange(stack.length-count, stack.length);
-    return result;
-  }
-  popTypeAnnotation() {
-    List<TypeAnnotation> args = pop();
-    if (args == null)
-      return null;
-    String name = pop(asName);
-    return new TypeAnnotation(name, args);
-  }
-
-  // EXPRESSIONS
-  endCascade() {
-    throw "Cascade not supported yet";
-  }
-  endIdentifierList(int count) {
-    push(popList(count, <Identifier>[]));
-  }
-  endTypeList(int count) {
-    push(popList(count, <TypeAnnotation>[], asType));
-  }
-  beginLiteralString(Token token) {
-    String source = token.value;
-    tree.StringQuoting quoting = StringValidator.quotingFromString(source);
-    push(quoting);
-    push(token); // collect token at the end
-  }
-  handleStringPart(Token token) {
-    push(token); // collect token at the end
-  }
-  endLiteralString(int interpCount) {
-    List parts = popList(2 * interpCount + 1, []);
-    tree.StringQuoting quoting = pop();
-    List<Expression> members = <Expression>[];
-    for (var i=0; i<parts.length; i++) {
-      var part = parts[i];
-      if (part is Expression) {
-        members.add(part);
-      } else {
-        assert(part is Token);
-        DartString str = stringValidator.validateInterpolationPart(
-            part as Token,
-            quoting,
-            isFirst: i == 0,
-            isLast: i == parts.length - 1);
-        members.add(new Literal(new StringConstantValue(str)));
-      }
-    }
-    push(new StringConcat(members));
-  }
-  handleStringJuxtaposition(int litCount) {
-    push(new StringConcat(popList(litCount, <Expression>[])));
-  }
-  endArguments(int count, begin, end) {
-    push(popList(count, <Argument>[]));
-  }
-  handleNoArguments(token) {
-    push(null);
-  }
-  handleNoTypeArguments(token) {
-    push(<TypeAnnotation>[]);
-  }
-  endTypeArguments(int count, t, y) {
-    List<TypeAnnotation> args = <TypeAnnotation>[];
-    for (var i=0; i<count; i++) {
-      args.add(popTypeAnnotation());
-    }
-    push(args.reversed.toList(growable:false));
-  }
-  handleVoidKeyword(token) {
-    push(new Identifier("void"));
-    push(<TypeAnnotation>[]); // prepare for popTypeAnnotation
-  }
-  handleQualified(Token period) {
-    String last = pop(asName);
-    String first = pop(asName);
-    push(new Identifier('$first.$last'));
-  }
-  endSend(t) {
-    List<Argument> arguments = pop();
-    pop(); // typeArguments
-    if (arguments == null)
-      return; // not a function call
-    Expression selector = pop();
-    push(new CallFunction(selector, arguments));
-  }
-  endThrowExpression(t, tt) {
-    push(new Throw(pop()));
-  }
-  handleAssignmentExpression(Token token) {
-    Expression right = pop();
-    Expression left = pop();
-    push(new Assignment(left, token.value, right));
-  }
-  handleBinaryExpression(Token token) {
-    Expression right = pop();
-    Receiver left = pop();
-    String tokenString = token.stringValue;
-    if (tokenString == '.') {
-      if (right is CallFunction) {
-        String name = (right.callee as Identifier).name;
-        push(new CallMethod(left, name, right.arguments));
-      } else {
-        push(new FieldExpression(left, (right as Identifier).name));
-      }
-    } else {
-      push(new BinaryOperator(left, tokenString, right));
-    }
-  }
-  handleConditionalExpression(question, colon) {
-    Expression elseExpression = pop();
-    Expression thenExpression = pop();
-    Expression condition = pop();
-    push(new Conditional(condition, thenExpression, elseExpression));
-  }
-  handleIdentifier(Token t) {
-    push(new Identifier(t.value));
-  }
-  handleOperator(t) {
-    push(new Identifier(t.value));
-  }
-  handleIndexedExpression(open, close) {
-    Expression index = pop();
-    Receiver object = pop();
-    push(new IndexExpression(object, index));
-  }
-  handleIsOperator(operathor, not, endToken) {
-    TypeAnnotation type = popTypeAnnotation();
-    Expression exp = pop();
-    TypeOperator r = new TypeOperator(exp, 'is', type);
-    if (not != null) {
-      push(new UnaryOperator('!', r));
-    } else {
-      push(r);
-    }
-  }
-  handleAsOperator(operathor, endToken) {
-    TypeAnnotation type = popTypeAnnotation();
-    Expression exp = pop();
-    push(new TypeOperator(exp, 'as', type));
-  }
-  handleLiteralBool(Token t) {
-    bool value = t.value == 'true';
-    push(new Literal(
-        value ? new TrueConstantValue() : new FalseConstantValue()));
-  }
-  handleLiteralDouble(t) {
-    push(new Literal(new DoubleConstantValue(double.parse(t.value))));
-  }
-  handleLiteralInt(Token t) {
-    push(new Literal(new IntConstantValue(int.parse(t.value))));
-  }
-  handleLiteralNull(t) {
-    push(new Literal(new NullConstantValue()));
-  }
-  endLiteralSymbol(Token hash, int idCount) {
-    List<Identifier> ids = popList(idCount, <Identifier>[]);
-    push(new LiteralSymbol(ids.map((id) => id.name).join('.')));
-  }
-  handleLiteralList(int count, begin, constKeyword, end) {
-    List<Expression> exps = popList(count, <Expression>[]);
-    List<TypeAnnotation> types = pop();
-    assert(types.length <= 1);
-    push(new LiteralList(exps,
-      isConst: constKeyword != null,
-      typeArgument: types.length == 0 ? null : types[0]
-    ));
-  }
-  handleLiteralMap(int count, begin, constKeyword, end) {
-    List<LiteralMapEntry> entries = popList(count, <LiteralMapEntry>[]);
-    List<TypeAnnotation> types = pop();
-    assert(types.length == 0 || types.length == 2);
-    push(new LiteralMap(entries,
-        isConst: constKeyword != null,
-        typeArguments: types
-    ));
-  }
-  endLiteralMapEntry(colon, endToken) {
-    Expression value = pop();
-    Expression key = pop();
-    push(new LiteralMapEntry(key,value));
-  }
-  handleNamedArgument(colon) {
-    Expression exp = pop();
-    Identifier name = pop();
-    push(new NamedArgument(name.name, exp));
-  }
-  endConstructorReference(Token start, Token period, Token end) {
-    if (period == null) {
-      push(null); // indicate missing constructor name
-    }
-  }
-  handleNewExpression(t) {
-    List<Argument> args = pop();
-    String constructorName = pop(asName);
-    TypeAnnotation type = popTypeAnnotation();
-    push(new CallNew(type, args, constructorName: constructorName));
-  }
-  handleConstExpression(t) {
-    List<Argument> args = pop();
-    String constructorName = pop(asName);
-    TypeAnnotation type = popTypeAnnotation();
-    push(new CallNew(type, args, constructorName: constructorName,
-                     isConst:true));
-  }
-  handleParenthesizedExpression(t) {
-    // do nothing, just leave expression on top of stack
-  }
-  handleSuperExpression(t) {
-    push(new SuperReceiver());
-  }
-  handleThisExpression(t) {
-    push(new This());
-  }
-  handleUnaryPostfixAssignmentExpression(Token t) {
-    push(new Increment.postfix(pop(), t.value));
-  }
-  handleUnaryPrefixAssignmentExpression(Token t) {
-    push(new Increment.prefix(pop(), t.value));
-  }
-  handleUnaryPrefixExpression(Token t) {
-    push(new UnaryOperator(t.value, pop()));
-  }
-
-  handleFunctionTypedFormalParameter(tok) {
-    // handled in endFormalParameter
-  }
-  endFormalParameter(thisKeyword) {
-    Expression defaultValue = null;
-    var x = pop();
-    if (x is DefaultValue) {
-      defaultValue = x.expression;
-      x = pop();
-    }
-    if (x is Parameters) {
-      String name = pop(asName);
-      TypeAnnotation returnType = popTypeAnnotation();
-      push(new Parameter.function(name, returnType, x, defaultValue));
-    } else {
-      String name = asName(x);
-      TypeAnnotation type = popTypeAnnotation();
-      push(new Parameter(name, type:type, defaultValue:defaultValue));
-    }
-  }
-  handleValuedFormalParameter(eq, tok) {
-    push(new DefaultValue(pop()));
-  }
-  endOptionalFormalParameters(int count, begin, end) {
-    bool isNamed = end.value == '}';
-    push(popList(count, <Parameter>[], asParameter));
-    push(isNamed); // Indicate optional parameters to endFormalParameters.
-  }
-  endFormalParameters(count, begin, end) {
-    if (count == 0) {
-      push(new Parameters([]));
-      return;
-    }
-    var last = pop();   // Detect if optional parameters are present.
-    if (last is bool) { // See endOptionalFormalParameters.
-      List<Parameter> optional = pop();
-      List<Parameter> required = popList(count-1, <Parameter>[], asParameter);
-      push(new Parameters(required, optional, last));
-    } else {
-      // No optional parameters.
-      List<Parameter> required = popList(count-1, <Parameter>[], asParameter);
-      required.add(last);
-      push(new Parameters(required));
-    }
-  }
-  handleNoFormalParameters(tok) {
-    push(new Parameters([]));
-  }
-
-  endUnnamedFunction(t) {
-    Statement body = pop();
-    Parameters parameters = pop();
-    push(new FunctionExpression(parameters, body));
-  }
-
-  handleNoType(Token token) {
-    push(null);
-  }
-
-  endReturnStatement(bool hasExpression, begin, end) {
-    // This is also called for functions whose body is "=> expression"
-    if (hasExpression) {
-      push(new Return(pop()));
-    } else {
-      push(new Return());
-    }
-  }
-
-  endExpressionStatement(Token token) {
-    push(new ExpressionStatement(pop()));
-  }
-
-  endDoWhileStatement(Token doKeyword, Token whileKeyword, Token end) {
-    Expression condition = pop();
-    Statement body = pop();
-    push(new DoWhile(body, condition));
-  }
-
-  endWhileStatement(Token whileKeyword, Token end) {
-    Statement body = pop();
-    Expression condition = pop();
-    push(new While(condition, body));
-  }
-
-  endBlock(int count, Token begin, Token end) {
-    push(new Block(popList(count, <Statement>[])));
-  }
-
-  endRethrowStatement(Token throwToken, Token endToken) {
-    push(new Rethrow());
-  }
-
-  endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
-    Statement finallyBlock = null;
-    if (finallyKeyword != null) {
-      finallyBlock = pop();
-    }
-    List<CatchBlock> catchBlocks = popList(catchCount, <CatchBlock>[]);
-    Statement tryBlock = pop();
-    push(new Try(tryBlock, catchBlocks, finallyBlock));
-  }
-
-  void handleCatchBlock(Token onKeyword, Token catchKeyword) {
-    Statement block = pop();
-    String exceptionVar = null;
-    String stackVar = null;
-    if (catchKeyword != null) {
-      Parameters params = pop();
-      exceptionVar = params.requiredParameters[0].name;
-      if (params.requiredParameters.length > 1) {
-        stackVar = params.requiredParameters[1].name;
-      }
-    }
-    TypeAnnotation type = onKeyword == null ? null : pop();
-    push(new CatchBlock(block,
-      onType: type,
-      exceptionVar: exceptionVar,
-      stackVar: stackVar
-    ));
-  }
-
-  endSwitchStatement(Token switchKeyword, Token end) {
-    List<SwitchCase> cases = pop();
-    Expression expression = pop();
-    push(new Switch(expression, cases));
-  }
-
-  endSwitchBlock(int caseCount, Token begin, Token end) {
-    push(popList(caseCount, <SwitchCase>[]));
-  }
-
-  handleSwitchCase(int labelCount, int caseCount, Token defaultKeyword,
-                   int statementCount, Token first, Token end) {
-    List<Statement> statements = popList(statementCount, <Statement>[]);
-    List<Expression> cases = popList(caseCount, <Expression>[]);
-    if (defaultKeyword != null) {
-      cases = null;
-    }
-    push(new SwitchCase(cases, statements));
-  }
-
-  handleCaseMatch(Token caseKeyword, Token colon) {
-    // do nothing, leave case expression on stack
-  }
-
-  handleBreakStatement(bool hasTarget, Token breakKeyword, Token end) {
-    String target = hasTarget ? pop(asName) : null;
-    push(new Break(target));
-  }
-
-  handleContinueStatement(bool hasTarget, Token continueKeyword, Token end) {
-    String target = hasTarget ? pop(asName) : null;
-    push(new Continue(target));
-  }
-
-  handleEmptyStatement(Token token) {
-    push(new EmptyStatement());
-  }
-
-
-  VariableDeclaration asVariableDeclaration(x) {
-    if (x is VariableDeclaration)
-      return x;
-    if (x is Identifier)
-      return new VariableDeclaration(x.name);
-    throw "Not a variable definition: ${x.runtimeType}";
-  }
-
-  endVariablesDeclaration(int count, Token end) {
-    List<VariableDeclaration> variables =
-        popList(count, <VariableDeclaration>[], asVariableDeclaration);
-    TypeAnnotation type = popTypeAnnotation();
-    push(new VariableDeclarations(variables,
-      type: type,
-      isFinal: false, // TODO(asgerf): Parse modifiers.
-      isConst: false
-    ));
-  }
-
-  endInitializer(Token assign) {
-    Expression init = pop();
-    String name = pop(asName);
-    push(new VariableDeclaration(name, init));
-  }
-
-  endIfStatement(Token ifToken, Token elseToken) {
-    Statement elsePart = (elseToken == null) ? null : pop();
-    Statement thenPart = pop();
-    Expression condition = pop();
-    push(new If(condition, thenPart, elsePart));
-  }
-
-  endForStatement(int updateCount, Token begin, Token end) {
-    Statement body = pop();
-    List<Expression> updates = popList(updateCount, <Expression>[]);
-    ExpressionStatement condition = pop(); // parsed as expression statement
-    Expression exp = condition == null ? null : condition.expression;
-    Node initializer = pop();
-    push(new For(initializer, exp, updates, body));
-  }
-
-  handleNoExpression(Token token) {
-    push(null);
-  }
-
-  endForIn(Token await, Token begin, Token inKeyword, Token end) {
-    Statement body = pop();
-    Expression exp = pop();
-    Node declaredIdentifier = pop();
-    push(new ForIn(declaredIdentifier, exp, body));
-  }
-
-  handleAssertStatement(Token assertKeyword,
-                        Token commaToken, Token semicolonToken) {
-    Expression message;
-    if (commaToken != null) message = pop();
-    Expression exp = pop();
-    var arguments = [exp];
-    if (message != null) arguments.add(message);
-    Expression call = new CallFunction(new Identifier("assert"), arguments);
-    push(new ExpressionStatement(call));
-  }
-
-  endLabeledStatement(int labelCount) {
-    Statement statement = pop();
-    for (int i=0; i<labelCount; i++) {
-      String label = pop(asName);
-      statement = new LabeledStatement(label, statement);
-    }
-    push(statement);
-  }
-
-  endFunctionDeclaration(Token end) {
-    Statement body = pop();
-    Parameters parameters = pop();
-    String name = pop(asName);
-    TypeAnnotation returnType = popTypeAnnotation();
-    push(new FunctionDeclaration(new FunctionExpression(parameters, body,
-        name: name,
-        returnType: returnType)));
-  }
-
-  endFunctionBody(int count, Token begin, Token end) {
-    push(new Block(popList(count, <Statement>[])));
-  }
-}
-
-class DefaultValue {
-  final Expression expression;
-  DefaultValue(this.expression);
-}
-
-/// Compares ASTs for structural equality.
-void checkDeepEqual(x, y) {
-  if (x is List && y is List) {
-    if (x.length != y.length)
-      return;
-    for (var i=0; i<x.length; i++) {
-      checkDeepEqual(x[i], y[i]);
-    }
-  }
-  else if (x is Node && y is Node) {
-    if (x.runtimeType != y.runtimeType)
-      throw new Error();
-    InstanceMirror xm = reflect(x);
-    InstanceMirror ym = reflect(y);
-    for (Symbol name in xm.type.instanceMembers.keys) {
-      if (reflectClass(Object).declarations.containsKey(name)) {
-        continue; // do not check things from Object, such as hashCode
-      }
-      MethodMirror mm = xm.type.instanceMembers[name];
-      if (mm.isGetter) {
-        var xv = xm.getField(name).reflectee;
-        var yv = ym.getField(name).reflectee;
-        checkDeepEqual(xv,yv);
-      }
-    }
-  }
-  else if (x is PrimitiveConstantValue && y is PrimitiveConstantValue) {
-    checkDeepEqual(x.primitiveValue, y.primitiveValue);
-  }
-  else if (x is DartString && y is DartString) {
-    if (x.slowToString() != y.slowToString()) {
-      throw new Error();
-    }
-  }
-  else {
-    if (x != y) {
-      throw new Error();
-    }
-  }
-}
-
-Expression parseExpression(String code) {
-  SourceFile file = new StringSourceFile.fromName('', code);
-  Scanner scan = new Scanner(file);
-  Token tok = scan.tokenize();
-  AstBuilder builder = new AstBuilder();
-  Parser parser = new Parser(builder, new MockParserOptions());
-  tok = parser.parseExpression(tok);
-  if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
-    throw "Parse error in $code";
-  }
-  return builder.pop();
-}
-Statement parseStatement(String code) {
-  SourceFile file = new StringSourceFile.fromName('', code);
-  Scanner scan = new Scanner(file);
-  Token tok = scan.tokenize();
-  AstBuilder builder = new AstBuilder();
-  Parser parser = new Parser(builder, new MockParserOptions());
-  tok = parser.parseStatement(tok);
-  if (builder.stack.length != 1 || tok.kind != EOF_TOKEN) {
-    throw "Parse error in $code";
-  }
-  return builder.pop();
-}
-
-String unparseExpression(Expression exp) {
-  StringBuffer buf = new StringBuffer();
-  new Unparser(buf).writeExpression(exp);
-  return buf.toString();
-}
-String unparseStatement(Statement stmt) {
-  StringBuffer buf = new StringBuffer();
-  new Unparser(buf).writeStatement(stmt);
-  return buf.toString();
-}
-
-/// Converts [exp] to an instance of the frontend AST and unparses that.
-String frontUnparseExpression(Expression exp) {
-  tree.Node node = new TreePrinter().makeExpression(exp);
-  return tree.unparse(node);
-}
-/// Converts [stmt] to an instance of the frontend AST and unparses that.
-String frontUnparseStatement(Statement stmt) {
-  tree.Node node = new TreePrinter().makeStatement(stmt);
-  return tree.unparse(node);
-}
-
-/// Parses [code], unparses the resulting AST, then parses the unparsed text.
-/// The ASTs from the first and second parse are then compared for structural
-/// equality. Alternatively, if [expected] is not an empty string, the second
-/// parse must match the AST of parsing [expected].
-void checkFn(String code, String expected, Function parse, Function unparse) {
-  var firstParse = parse(code);
-  String unparsed = unparse(firstParse);
-  try {
-    var secondParse = parse(unparsed);
-    var baseline = expected == "" ? firstParse : parse(expected);
-    checkDeepEqual(baseline, secondParse);
-  } catch (e, stack) {
-    Expect.fail('"$code" was unparsed as "$unparsed"');
-  }
-}
-
-void checkExpression(String code, [String expected="", String expected2=""]) {
-  checkFn(code, expected, parseExpression, unparseExpression);
-  checkFn(code, expected2, parseExpression, frontUnparseExpression);
-}
-void checkStatement(String code, [String expected="", String expected2=""]) {
-  checkFn(code, expected, parseStatement, unparseStatement);
-  checkFn(code, expected2, parseStatement, frontUnparseStatement);
-}
-
-void debugTokens(String code) {
-  SourceFile file = new StringSourceFile.fromName('', code);
-  Scanner scan = new Scanner(file);
-  Token tok = scan.tokenize();
-  while (tok.next != tok) {
-    print(tok.toString());
-    tok = tok.next;
-  }
-}
-
-void main() {
-  // To check if these tests are effective, one should manually alter
-  // something in [Unparser] and see if a test fails.
-
-  checkExpression(" a +  b  + c");
-  checkExpression("(a +  b) + c");
-  checkExpression(" a + (b  + c)");
-
-  checkExpression(" a +  b  - c");
-  checkExpression("(a +  b) - c");
-  checkExpression(" a + (b  - c)");
-
-  checkExpression(" a -  b  + c");
-  checkExpression("(a -  b) + c");
-  checkExpression(" a - (b  + c)");
-
-  checkExpression(" a *  b  + c");
-  checkExpression("(a *  b) + c");
-  checkExpression(" a * (b  + c)");
-
-  checkExpression(" a +  b  * c");
-  checkExpression("(a +  b) * c");
-  checkExpression(" a + (b  * c)");
-
-  checkExpression(" a *  b  * c");
-  checkExpression("(a *  b) * c");
-  checkExpression(" a * (b  * c)");
-
-  checkExpression("a is T");
-  checkExpression("a is! T");
-  checkExpression("!(a is T)");
-
-  checkExpression("a is T.x");
-  checkExpression("a is! T.x");
-  checkExpression("!(a is T.x)");
-  checkExpression("!(a is T).x");
-
-  checkExpression("a as T.x");
-  checkExpression("(a as T).x");
-
-  checkExpression("a == b");
-  checkExpression("a != b");
-  checkExpression("!(a == b)", "a != b");
-
-  checkExpression("a && b ? c : d");
-  checkExpression("(a && b) ? c : d");
-  checkExpression("a && (b ? c : d)");
-
-  checkExpression("a || b ? c : d");
-  checkExpression("(a || b) ? c : d");
-  checkExpression("a || (b ? c : d)");
-
-  checkExpression(" a ? b :  c && d");
-  checkExpression(" a ? b : (c && d)");
-  checkExpression("(a ? b :  c) && d");
-
-  checkExpression(" a ? b : c = d");
-  checkExpression(" a ? b : (c = d)");
-
-  checkExpression("(a == b) == c");
-  checkExpression("a == (b == c)");
-
-  checkExpression(" a <  b  == c");
-  checkExpression("(a <  b) == c");
-  checkExpression(" a < (b  == c)");
-
-  checkExpression(" a ==  b  < c");
-  checkExpression("(a ==  b) < c");
-  checkExpression(" a == (b  < c)");
-
-  checkExpression("x.f()");
-  checkExpression("(x.f)()");
-
-  checkExpression("x.f()()");
-  checkExpression("(x.f)()()");
-
-  checkExpression("x.f().g()");
-  checkExpression("(x.f)().g()");
-
-  checkExpression("x.f()");
-  checkExpression("x.f(1 + 2)");
-  checkExpression("x.f(1 + 2, 3 + 4)");
-  checkExpression("x.f(1 + 2, foo:3 + 4)");
-  checkExpression("x.f(1 + 2, foo:3 + 4, bar: 5)");
-  checkExpression("x.f(foo:3 + 4)");
-  checkExpression("x.f(foo:3 + 4, bar: 5)");
-
-  checkExpression("x.f.g.h");
-  checkExpression("(x.f).g.h");
-  checkExpression("(x.f.g).h");
-
-  checkExpression(" a =  b  + c");
-  checkExpression(" a = (b  + c)");
-  checkExpression("(a =  b) + c");
-
-  checkExpression("a + (b = c)");
-
-  checkExpression("dx * dx + dy * dy < r * r",
-                  "((dx * dx) + (dy * dy)) < (r * r)");
-  checkExpression("mid = left + right << 1",
-                  "mid = ((left + right) << 1)");
-  checkExpression("a + b % c * -d ^  e - f  ~/ x & ++y / z++ | w > a ? b : c");
-  checkExpression("a + b % c * -d ^ (e - f) ~/ x & ++y / z++ | w > a ? b : c");
-
-  checkExpression("'foo'");
-  checkExpression("'foo' 'bar'", "'foobar'");
-
-  checkExpression("{}.length");
-  checkExpression("{x: 1+2}.length");
-  checkExpression("<String,int>{}.length");
-  checkExpression("<String,int>{x: 1+2}.length");
-
-  checkExpression("[].length");
-  checkExpression("[1+2].length");
-  checkExpression("<num>[].length");
-  checkExpression("<num>[1+2].length");
-
-  checkExpression("x + -y");
-  checkExpression("x + --y");
-  checkExpression("x++ + y");
-  checkExpression("x + ++y");
-  checkExpression("x-- - y");
-  checkExpression("x-- - -y");
-  checkExpression("x - --y");
-
-  checkExpression("x && !y");
-  checkExpression("!x && y");
-  checkExpression("!(x && y)");
-
-  checkExpression(" super +  1  * 2");
-  checkExpression("(super +  1) * 2");
-  checkExpression(" super + (1  * 2)");
-  checkExpression("x + -super");
-  checkExpression("x-- - -super");
-  checkExpression("x - -super");
-  checkExpression("x && !super");
-
-  checkExpression("super.f(1, 2) + 3");
-  checkExpression("super.f + 3");
-
-  checkExpression(r"'foo\nbar'");
-  checkExpression(r"'foo\r\nbar'");
-  checkExpression(r"'foo\rbar'");
-  checkExpression(r"'foo\'bar'");
-  checkExpression(r"""'foo"bar'""");
-  checkExpression(r"r'foo\nbar'");
-  checkExpression("''");
-  checkExpression("r''");
-
-  var sq = "'";
-  var dq = '"';
-  checkExpression("'$dq$dq' \"$sq$sq\"");
-  checkExpression("'$dq$dq$dq$dq' \"$sq$sq$sq$sq\"");
-  checkExpression(r"'\$\$\$\$\$\$\$\$\$'");
-  checkExpression("'$dq$dq$dq' '\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n' \"$sq$sq$sq\"");
-  checkExpression("'$dq$dq$dq' '\\r\\r\\r\\r\\r\\r\\r\\r\\r\\r' \"$sq$sq$sq\"");
-  checkExpression("'$dq$dq$dq' '\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n' \"$sq$sq$sq\"");
-
-  checkExpression(r"'$foo'");
-  checkExpression(r"'${foo}x'");
-  checkExpression(r"'${foo}x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'");
-  checkExpression(r"'abc' '${foo}' r'\\\\\\\'");
-
-  checkExpression(r"'${$x}'");
-  checkExpression(r"'${$x}y'");
-  checkExpression("null + null");
-
-  checkExpression("(x) => x",
-                  '',
-                  '(x){return x;}');
-  checkStatement("fn(x) => x;",
-                  '',
-                  'fn(x){return x;}');
-
-  checkExpression("throw x");
-  checkStatement("throw x;");
-
-  checkStatement("var x, y, z;");
-  checkStatement("final x, y, z;");
-  checkStatement("dynamic x, y, z;");
-  checkStatement("String x, y, z;");
-  checkStatement("List<int> x, y, z;");
-  checkStatement("final dynamic x, y, z;");
-  checkStatement("final String x, y, z;");
-  checkStatement("final List<int> x, y, z;");
-
-  checkStatement("var x = y, z;");
-  checkStatement("var x, y = z;");
-  checkStatement("var x = y = z;");
-
-  // Note: We sometimes have to pass an expected string to account for
-  //       block flattening which does not preserve structural AST equality
-  checkStatement("if (x)   if (y) foo();   else bar();  ");
-  checkStatement("if (x) { if (y) foo(); } else bar();  ");
-  checkStatement("if (x) { if (y) foo();   else bar(); }",
-                 "if (x)   if (y) foo();   else bar();  ");
-
-  checkStatement("if (x) while (y)   if (z) foo();   else bar();  ");
-  checkStatement("if (x) while (y) { if (z) foo(); } else bar();  ");
-  checkStatement("if (x) while (y) { if (z) foo();   else bar(); }",
-                 "if (x) while (y)   if (z) foo();   else bar();  ");
-
-  checkStatement("{var x = 1; {var x = 2;} return x;}");
-  checkStatement("{var x = 1; {x = 2;} return x;}",
-                 "{var x = 1;  x = 2;  return x;}",
-                 "{var x = 1;  x = 2;  return x;}");
-
-  checkStatement("if (x) {var x = 1;}");
-
-  checkStatement("({'foo': 1}).bar();");
-  checkStatement("({'foo': 1}).length;");
-  checkStatement("({'foo': 1}).length + 1;");
-  checkStatement("({'foo': 1})['foo'].toString();");
-  checkStatement("({'foo': 1})['foo'] = 3;");
-  checkStatement("({'foo': 1}['foo']());");
-  checkStatement("({'foo': 1}['foo'])();");
-  checkStatement("({'foo': 1})['foo'].x++;");
-  checkStatement("({'foo': 1}) is Map;");
-  checkStatement("({'foo': 1}) as Map;");
-  checkStatement("({'foo': 1}) is util.Map;");
-  checkStatement("({'foo': 1}) + 1;");
-
-  checkStatement("[1].bar();");
-  checkStatement("1.bar();");
-  checkStatement("'foo'.bar();");
-
-  checkStatement("do while(x); while (y);");
-  checkStatement("{do; while(x); while (y);}");
-
-  checkStatement('switch(x) { case 1: case 2: return y; }');
-  checkStatement('switch(x) { default: return y; }');
-  checkStatement('switch(x) { case 1: x=y; default: return y; }');
-  checkStatement('switch(x) { case 1: x=y; y=z; break; default: return y; }');
-
-}
-
diff --git a/tests/compiler/dart2js/backend_dart/end2end_test.dart b/tests/compiler/dart2js/backend_dart/end2end_test.dart
deleted file mode 100644
index 60156c7..0000000
--- a/tests/compiler/dart2js/backend_dart/end2end_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.
-
-/// End-to-end test of the dart2dart compiler.
-library dart_backend.end2end_test;
-
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/dart_backend/dart_backend.dart';
-import 'package:expect/expect.dart';
-
-import '../../../../pkg/analyzer2dart/test/test_helper.dart' hide TestSpec;
-import '../../../../pkg/analyzer2dart/test/end2end_data.dart';
-
-import 'test_helper.dart';
-import '../output_collector.dart';
-
-main(List<String> args) {
-  performTests(TEST_DATA, asyncTester, runTest, args);
-}
-
-runTest(TestSpec result) {
-  OutputCollector outputCollector = new OutputCollector();
-  asyncTest(() => compilerFor(result.input, outputProvider: outputCollector)
-      .then((Compiler compiler) {
-    String expectedOutput = result.output.trim();
-    compiler.phase = Compiler.PHASE_COMPILING;
-    DartBackend backend = compiler.backend;
-    backend.assembleProgram();
-    String output = outputCollector.getOutput('', 'dart').trim();
-    Expect.equals(expectedOutput, output,
-        '\nInput:\n${result.input}\n'
-        'Expected:\n$expectedOutput\n'
-        'Actual:\n$output\n');
-  }));
-}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart b/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
deleted file mode 100644
index 2ee3890..0000000
--- a/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
+++ /dev/null
@@ -1,528 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import '../mock_compiler.dart';
-import 'sexpr_unstringifier.dart';
-import 'package:async_helper/async_helper.dart';
-import "package:expect/expect.dart";
-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
-import 'package:compiler/src/cps_ir/optimizers.dart';
-import 'package:compiler/src/constant_system_dart.dart';
-
-// The tests in this file that ensure that sparse constant propagation on the
-// CPS IR works as expected.
-
-// CP1 represents the following incoming dart code:
-//
-//  int main() {
-//    int i = 1;
-//    int j;
-//    if (i == 1) {
-//      j = 2;
-//    } else {
-//      j = 3;
-//    }
-//    return j;
-//  }
-
-String CP1_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 1)))
-      (LetCont
-        ((k0 (v2)
-           (LetCont
-             ((k1 ()
-                (LetPrim (v3 (Constant (Int 2)))
-                  (InvokeContinuation return (v3))))
-              (k2 ()
-                (LetPrim (v4 (Constant (Int 3)))
-                  (InvokeContinuation return (v4)))))
-             (Branch (IsTrue v2) k1 k2))))
-        (InvokeMethod v0 == (v1) k0)))))
-""";
-String CP1_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 1)))
-      (LetCont
-        ((k0 (v2)
-           (LetCont
-             ((k1 ()
-                (LetPrim (v3 (Constant (Int 2)))
-                  (InvokeContinuation return (v3))))
-              (k2 ()
-                (LetPrim (v4 (Constant (Int 3)))
-                  (InvokeContinuation return (v4)))))
-             (InvokeContinuation k1 ()))))
-        (LetPrim (v5 (Constant (Bool true)))
-          (InvokeContinuation k0 (v5)))))))
-""";
-
-// CP2 represents the following incoming dart code:
-//
-//  int main() {
-//    int i = 1;
-//    while (true) {
-//      if (false || false) {
-//        return i;
-//      }
-//      if (true && i == 1) {
-//        return i;
-//      }
-//    }
-//    return 42;
-//  }
-
-String CP2_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetCont
-        ((rec k0 ()
-           (LetCont
-               ((k1 ()
-                  (LetPrim (v1 (Constant (Int 42)))
-                    (InvokeContinuation return (v1))))
-                (k2 ()
-                  (LetPrim (v2 (Constant (Bool false)))
-                    (LetCont
-                        ((k3 (v3)
-                           (LetCont
-                               ((k4 ()
-                                  (InvokeContinuation return (v0)))
-                                (k5 ()
-                                  (LetPrim (v4 (Constant (Bool true)))
-                                    (LetCont
-                                        ((k6 (v5)
-                                           (LetCont
-                                               ((k7 ()
-                                                  (InvokeContinuation return (v0)))
-                                                (k8 ()
-                                                  (InvokeContinuation rec k0 ())))
-                                             (Branch (IsTrue v5) k7 k8))))
-                                      (LetCont
-                                          ((k9 ()
-                                             (LetPrim (v6 (Constant (Int 1)))
-                                               (LetCont
-                                                   ((k10 (v7)
-                                                      (LetCont
-                                                          ((k11 ()
-                                                             (LetPrim (v8 (Constant (Bool true)))
-                                                               (InvokeContinuation k6 (v8))))
-                                                           (k12 ()
-                                                             (LetPrim (v9 (Constant (Bool false)))
-                                                               (InvokeContinuation k6 (v9)))))
-                                                        (Branch (IsTrue v7) k11 k12))))
-                                                 (InvokeMethod v0 == (v6) k10))))
-                                           (k13 ()
-                                             (LetPrim (v10 (Constant (Bool false)))
-                                               (InvokeContinuation k6 (v10)))))
-                                        (Branch (IsTrue v4) k9 k13))))))
-                             (Branch (IsTrue v3) k4 k5))))
-                      (LetCont
-                          ((k14 ()
-                             (LetPrim (v11 (Constant (Bool true)))
-                               (InvokeContinuation k3 (v11))))
-                           (k15 ()
-                             (LetPrim (v12 (Constant (Bool false)))
-                               (LetCont
-                                   ((k16 ()
-                                      (LetPrim (v13 (Constant (Bool true)))
-                                        (InvokeContinuation k3 (v13))))
-                                    (k17 ()
-                                      (LetPrim (v14 (Constant (Bool false)))
-                                        (InvokeContinuation k3 (v14)))))
-                                 (Branch (IsTrue v12) k16 k17)))))
-                        (Branch (IsTrue v2) k14 k15))))))
-             (LetPrim (v15 (Constant (Bool true)))
-               (Branch (IsTrue v15) k2 k1)))))
-      (InvokeContinuation k0 ()))))
-""";
-String CP2_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetCont
-        ((rec k0 ()
-           (LetCont
-               ((k1 ()
-                  (LetPrim (v1 (Constant (Int 42)))
-                    (InvokeContinuation return (v1))))
-                (k2 ()
-                  (LetPrim (v2 (Constant (Bool false)))
-                    (LetCont
-                        ((k3 (v3)
-                           (LetCont
-                               ((k4 ()
-                                  (InvokeContinuation return (v0)))
-                                (k5 ()
-                                  (LetPrim (v4 (Constant (Bool true)))
-                                    (LetCont
-                                        ((k6 (v5)
-                                           (LetCont
-                                               ((k7 ()
-                                                  (InvokeContinuation return (v0)))
-                                                (k8 ()
-                                                  (InvokeContinuation rec k0 ())))
-                                             (InvokeContinuation k7 ()))))
-                                      (LetCont
-                                          ((k9 ()
-                                             (LetPrim (v6 (Constant (Int 1)))
-                                               (LetCont
-                                                   ((k10 (v7)
-                                                      (LetCont
-                                                          ((k11 ()
-                                                             (LetPrim (v8 (Constant (Bool true)))
-                                                               (InvokeContinuation k6 (v8))))
-                                                           (k12 ()
-                                                             (LetPrim (v9 (Constant (Bool false)))
-                                                               (InvokeContinuation k6 (v9)))))
-                                                        (InvokeContinuation k11 ()))))
-                                                 (LetPrim (v10 (Constant (Bool true)))
-                                                   (InvokeContinuation k10 (v10))))))
-                                           (k13 ()
-                                             (LetPrim (v11 (Constant (Bool false)))
-                                               (InvokeContinuation k6 (v11)))))
-                                        (InvokeContinuation k9 ()))))))
-                             (InvokeContinuation k5 ()))))
-                      (LetCont
-                          ((k14 ()
-                             (LetPrim (v12 (Constant (Bool true)))
-                               (InvokeContinuation k3 (v12))))
-                           (k15 ()
-                             (LetPrim (v13 (Constant (Bool false)))
-                               (LetCont
-                                   ((k16 ()
-                                      (LetPrim (v14 (Constant (Bool true)))
-                                        (InvokeContinuation k3 (v14))))
-                                    (k17 ()
-                                      (LetPrim (v15 (Constant (Bool false)))
-                                        (InvokeContinuation k3 (v15)))))
-                                 (InvokeContinuation k17 ())))))
-                        (InvokeContinuation k15 ()))))))
-             (LetPrim (v16 (Constant (Bool true)))
-               (InvokeContinuation k2 ())))))
-      (InvokeContinuation k0 ()))))
-""";
-
-// CP3 represents the following incoming dart code:
-//
-//  int main() {
-//    int i = 1;
-//    i = f();
-//    if (i == 1) {
-//      return 42;
-//    }
-//    return i;
-//  }
-
-String CP3_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetCont
-        ((k0 (v1)
-           (LetPrim (v2 (Constant (Int 1)))
-             (LetCont
-                 ((k1 (v3)
-                    (LetCont
-                        ((k2 ()
-                           (LetPrim (v4 (Constant (Int 42)))
-                             (InvokeContinuation return (v4))))
-                         (k3 ()
-                           (InvokeContinuation return (v1))))
-                      (Branch (IsTrue v3) k2 k3))))
-               (InvokeMethod v1 == (v2) k1)))))
-      (InvokeStatic f () k0))))
-""";
-String CP3_OUT = CP3_IN;
-
-// Addition.
-
-String CP4_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 2)))
-      (LetCont
-          ((k0 (v2)
-             (InvokeContinuation return (v2))))
-        (InvokeMethod v0 + (v1) k0)))))
-""";
-String CP4_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 2)))
-      (LetCont
-          ((k0 (v2)
-             (InvokeContinuation return (v2))))
-        (LetPrim (v3 (Constant (Int 3)))
-          (InvokeContinuation k0 (v3)))))))
-""";
-
-// Array access operator (no optimization).
-
-String CP5_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 2)))
-      (LetCont
-          ((k0 (v2)
-             (InvokeContinuation return (v2))))
-        (InvokeMethod v0 [] (v1) k0)))))
-""";
-String CP5_OUT = CP5_IN;
-
-// Division by 0.
-
-String CP6_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 0)))
-      (LetCont
-          ((k0 (v2)
-             (InvokeContinuation return (v2))))
-        (InvokeMethod v0 / (v1) k0)))))
-""";
-String CP6_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 0)))
-      (LetCont
-          ((k0 (v2)
-             (InvokeContinuation return (v2))))
-        (LetPrim (v3 (Constant (Double Infinity)))
-          (InvokeContinuation k0 (v3)))))))
-""";
-
-// Concatenate strings.
-
-String CP7_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (String "b")))
-    (LetPrim (v1 (Constant (String "d")))
-      (LetPrim (v2 (Constant (String "a")))
-        (LetPrim (v3 (Constant (String "c")))
-          (LetPrim (v4 (Constant (String "")))
-            (LetCont
-                ((k0 (v5)
-                   (LetCont
-                       ((k1 (v6)
-                          (InvokeContinuation return (v6))))
-                     (InvokeMethod v5 length () k1))))
-              (ConcatenateStrings (v2 v0 v3 v1 v4) k0))))))))
-""";
-String CP7_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (String "b")))
-    (LetPrim (v1 (Constant (String "d")))
-      (LetPrim (v2 (Constant (String "a")))
-        (LetPrim (v3 (Constant (String "c")))
-          (LetPrim (v4 (Constant (String "")))
-            (LetCont
-                ((k0 (v5)
-                   (LetCont
-                       ((k1 (v6)
-                          (InvokeContinuation return (v6))))
-                     (InvokeMethod v5 length () k1))))
-              (LetPrim (v7 (Constant (String "abcd")))
-                (InvokeContinuation k0 (v7))))))))))
-""";
-
-// TODO(jgruber): We can't test is-check optimization because the unstringifier
-// does not recreate accurate types for the TypeOperator node.
-
-// Simple branch removal.
-
-String CP8_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 1)))
-      (LetCont
-          ((k0 (v2)
-             (LetCont
-                 ((k1 ()
-                    (LetPrim (v3 (Constant (Int 42)))
-                      (InvokeContinuation return (v3))))
-                  (k2 ()
-                    (InvokeContinuation return (v0))))
-               (Branch (IsTrue v2) k1 k2))))
-        (InvokeMethod v0 == (v1) k0)))))
-""";
-String CP8_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetPrim (v1 (Constant (Int 1)))
-      (LetCont
-          ((k0 (v2)
-             (LetCont
-                 ((k1 ()
-                    (LetPrim (v3 (Constant (Int 42)))
-                      (InvokeContinuation return (v3))))
-                  (k2 ()
-                    (InvokeContinuation return (v0))))
-               (InvokeContinuation k1 ()))))
-        (LetPrim (v4 (Constant (Bool true)))
-          (InvokeContinuation k0 (v4)))))))
-""";
-
-// While loop.
-
-String CP9_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetCont
-        ((rec k0 (v1)
-           (LetCont
-               ((k1 ()
-                  (InvokeContinuation return (v1)))
-                (k2 ()
-                  (LetPrim (v2 (Constant (Int 1)))
-                    (LetCont
-                        ((k3 (v3)
-                           (LetCont
-                               ((k4 (v4)
-                                  (LetCont
-                                      ((k5 ()
-                                         (LetPrim (v5 (Constant (Int 42)))
-                                           (InvokeContinuation return (v5))))
-                                       (k6 ()
-                                         (LetPrim (v6 (Constant (Int 1)))
-                                           (LetCont
-                                               ((k7 (v7)
-                                                  (InvokeContinuation rec k0 (v7))))
-                                             (InvokeMethod v1 + (v6) k7)))))
-                                    (Branch (IsTrue v4) k5 k6))))
-                             (LetCont
-                                 ((k8 ()
-                                    (LetPrim (v8 (Constant (Bool false)))
-                                      (InvokeContinuation k4 (v8))))
-                                  (k9 ()
-                                    (LetPrim (v9 (Constant (Bool true)))
-                                      (InvokeContinuation k4 (v9)))))
-                               (Branch (IsTrue v3) k8 k9)))))
-                      (InvokeMethod v1 == (v2) k3)))))
-             (LetPrim (v10 (Constant (Bool true)))
-               (Branch (IsTrue v10) k2 k1)))))
-      (InvokeContinuation k0 (v0)))))
-""";
-String CP9_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 1)))
-    (LetCont
-        ((rec k0 (v1)
-           (LetCont
-               ((k1 ()
-                  (InvokeContinuation return (v1)))
-                (k2 ()
-                  (LetPrim (v2 (Constant (Int 1)))
-                    (LetCont
-                        ((k3 (v3)
-                           (LetCont
-                              ((k4 (v4)
-                                 (LetCont
-                                     ((k5 ()
-                                        (LetPrim (v5 (Constant (Int 42)))
-                                          (InvokeContinuation return (v5))))
-                                      (k6 ()
-                                        (LetPrim (v6 (Constant (Int 1)))
-                                          (LetCont
-                                              ((k7 (v7)
-                                                 (InvokeContinuation rec k0 (v7))))
-                                            (InvokeMethod v1 + (v6) k7)))))
-                                   (Branch (IsTrue v4) k5 k6))))
-                             (LetCont
-                                 ((k8 ()
-                                    (LetPrim (v8 (Constant (Bool false)))
-                                      (InvokeContinuation k4 (v8))))
-                                  (k9 ()
-                                    (LetPrim (v9 (Constant (Bool true)))
-                                      (InvokeContinuation k4 (v9)))))
-                               (Branch (IsTrue v3) k8 k9)))))
-                      (InvokeMethod v1 == (v2) k3)))))
-             (LetPrim (v10 (Constant (Bool true)))
-               (InvokeContinuation k2 ())))))
-      (InvokeContinuation k0 (v0)))))
-""";
-
-// While loop, from:
-//
-//  int main() {
-//    for (int i = 0; i < 2; i++) {
-//      print(42 + i);
-//    }
-//  }
-
-String CP10_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont
-        ((rec k0 (v1)
-           (LetCont
-               ((k1 ()
-                  (LetPrim (v2 (Constant (Null)))
-                    (InvokeContinuation return (v2))))
-                (k2 ()
-                  (LetPrim (v3 (Constant (Int 42)))
-                    (LetCont
-                        ((k3 (v4)
-                           (LetCont
-                               ((k4 (v5)
-                                  (LetPrim (v6 (Constant (Int 1)))
-                                    (LetCont
-                                        ((k5 (v7)
-                                           (InvokeContinuation rec k0 (v7))))
-                                      (InvokeMethod v1 + (v6) k5)))))
-                             (InvokeStatic print (v4) k4))))
-                      (InvokeMethod v3 + (v1) k3)))))
-             (LetPrim (v8 (Constant (Int 2)))
-               (LetCont
-                   ((k6 (v9)
-                      (Branch (IsTrue v9) k2 k1)))
-                 (InvokeMethod v1 < (v8) k6))))))
-      (InvokeContinuation k0 (v0)))))
-""";
-String CP10_OUT = CP10_IN;
-
-/// Normalizes whitespace by replacing all whitespace sequences by a single
-/// space and trimming leading and trailing whitespace.
-String normalizeSExpr(String input) {
-  return input.replaceAll(new RegExp(r'[ \n\t]+'), ' ').trim();
-}
-
-/// Parses the given input IR, runs an optimization pass over it, and compares
-/// the stringification of the result against the expected output.
-Future testConstantPropagator(String input, String expectedOutput) {
-  final compiler = new MockCompiler.internal(
-      emitJavaScript: false,
-      enableMinification: false);
-  return compiler.init().then((_) {
-    final unstringifier = new SExpressionUnstringifier();
-    final stringifier   = new SExpressionStringifier();
-    final optimizer     = new TypePropagator(
-        compiler.types,
-        DART_CONSTANT_SYSTEM,
-        new UnitTypeSystem(),
-        compiler.internalError);
-
-    final f = unstringifier.unstringify(input);
-    optimizer.rewrite(f);
-
-    String expected = normalizeSExpr(expectedOutput);
-    String actual   = normalizeSExpr(stringifier.visit(f));
-
-    Expect.equals(expected, actual);
-  });
-}
-
-void main() {
-  asyncTest(() => testConstantPropagator(CP1_IN, CP1_OUT));
-  asyncTest(() => testConstantPropagator(CP2_IN, CP2_OUT));
-  asyncTest(() => testConstantPropagator(CP3_IN, CP3_OUT));
-  asyncTest(() => testConstantPropagator(CP4_IN, CP4_OUT));
-  asyncTest(() => testConstantPropagator(CP5_IN, CP5_OUT));
-  asyncTest(() => testConstantPropagator(CP6_IN, CP6_OUT));
-  asyncTest(() => testConstantPropagator(CP7_IN, CP7_OUT));
-  asyncTest(() => testConstantPropagator(CP8_IN, CP8_OUT));
-  asyncTest(() => testConstantPropagator(CP9_IN, CP9_OUT));
-  asyncTest(() => testConstantPropagator(CP10_IN, CP10_OUT));
-}
diff --git a/tests/compiler/dart2js/backend_dart/opt_cyclic_redundant_phi_test.dart b/tests/compiler/dart2js/backend_dart/opt_cyclic_redundant_phi_test.dart
deleted file mode 100644
index 7132824..0000000
--- a/tests/compiler/dart2js/backend_dart/opt_cyclic_redundant_phi_test.dart
+++ /dev/null
@@ -1,97 +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 'opt_redundant_phi_test.dart';
-
-// The 'cyclic deps' IR tests removal of redundant phis with cyclic
-// dependencies.
-//
-//  void main() {
-//    var x = 0;
-//    var y = x;
-//    for (int i = 0; i < 10; i++) {
-//      if (i == -1) x = y;
-//      if (i == -1) y = x;
-//    }
-//    print(x);
-//    print(y);
-//  }
-
-String CYCLIC_DEPS_IN = """
-(FunctionDefinition main (return) (LetPrim v0 (Constant 0))
-  (LetPrim v1 (Constant 0))
-  (LetCont* (k0 v2 v3 v4)
-    (LetCont (k1)
-      (LetCont (k2 v5)
-        (LetCont (k3 v6) (LetPrim v7 (Constant null))
-          (InvokeContinuation return v7))
-        (InvokeStatic print v3 k3))
-      (InvokeStatic print v2 k2))
-    (LetCont (k4) (LetPrim v8 (Constant 1))
-      (LetCont (k5 v9)
-        (LetCont (k6 v10)
-          (LetCont (k7 v11) (LetPrim v12 (Constant 1))
-            (LetCont (k8 v13)
-              (LetCont (k9 v14)
-                (LetCont (k10 v15)
-                  (LetPrim v16 (Constant 1))
-                  (LetCont (k11 v17)
-                    (InvokeContinuation* k0 v11 v15 v17))
-                  (InvokeMethod v4 + v16 k11))
-                (LetCont (k12) (InvokeContinuation k10 v11))
-                (LetCont (k13) (InvokeContinuation k10 v3))
-                (Branch (IsTrue v14) k12 k13))
-              (InvokeMethod v4 == v13 k9))
-            (InvokeMethod v12 unary- k8))
-          (LetCont (k14) (InvokeContinuation k7 v3))
-          (LetCont (k15) (InvokeContinuation k7 v2))
-          (Branch (IsTrue v10) k14 k15))
-        (InvokeMethod v4 == v9 k6))
-      (InvokeMethod v8 unary- k5))
-    (LetPrim v18 (Constant 10))
-    (LetCont (k16 v19) (Branch (IsTrue v19) k4 k1))
-    (InvokeMethod v4 < v18 k16))
-  (InvokeContinuation k0 v0 v0 v1))
-""";
-
-String CYCLIC_DEPS_OUT = """
-(FunctionDefinition main (return) (LetPrim v0 (Constant 0))
-  (LetPrim v1 (Constant 0))
-  (LetCont* (k0 v2)
-    (LetCont (k1)
-      (LetCont (k2 v3)
-        (LetCont (k3 v4) (LetPrim v5 (Constant null))
-          (InvokeContinuation return v5))
-        (InvokeStatic print v0 k3))
-      (InvokeStatic print v0 k2))
-    (LetCont (k4) (LetPrim v6 (Constant 1))
-      (LetCont (k5 v7)
-        (LetCont (k6 v8)
-          (LetCont (k7) (LetPrim v9 (Constant 1))
-            (LetCont (k8 v10)
-              (LetCont (k9 v11)
-                (LetCont (k10)
-                  (LetPrim v12 (Constant 1))
-                  (LetCont (k11 v13)
-                    (InvokeContinuation* k0 v13))
-                  (InvokeMethod v2 + v12 k11))
-                (LetCont (k12) (InvokeContinuation k10))
-                (LetCont (k13) (InvokeContinuation k10))
-                (Branch (IsTrue v11) k12 k13))
-              (InvokeMethod v2 == v10 k9))
-            (InvokeMethod v9 unary- k8))
-          (LetCont (k14) (InvokeContinuation k7))
-          (LetCont (k15) (InvokeContinuation k7))
-          (Branch (IsTrue v8) k14 k15))
-        (InvokeMethod v2 == v7 k6))
-      (InvokeMethod v6 unary- k5))
-    (LetPrim v14 (Constant 10))
-    (LetCont (k16 v15) (Branch (IsTrue v15) k4 k1))
-    (InvokeMethod v2 < v14 k16))
-  (InvokeContinuation k0 v1))
-""";
-
-void main() {
-  testRedundantPhi(CYCLIC_DEPS_IN, CYCLIC_DEPS_OUT);
-}
diff --git a/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart b/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
deleted file mode 100644
index 50422e2..0000000
--- a/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
+++ /dev/null
@@ -1,309 +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 'sexpr_unstringifier.dart';
-import "package:expect/expect.dart";
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
-import 'package:compiler/src/cps_ir/optimizers.dart';
-
-// The 'read in loop' IR tests the most basic case of redundant phi removal
-// and represents the following source code:
-//
-// void main() {
-//   int j = 42;
-//   for (int i = 0; i < 2; i++) {
-//     print(j.toString());
-//   }
-// }
-
-String READ_IN_LOOP_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 42)))
-    (LetPrim (v1 (Constant (Int 0)))
-      (LetCont
-          ((rec k0 (v2 v3)
-             (LetCont
-                 ((k1 ()
-                    (LetPrim (v4 (Constant (Null)))
-                      (InvokeContinuation return (v4))))
-                  (k2 ()
-                    (LetCont
-                        ((k3 (v5)
-                           (LetCont
-                               ((k4 (v6)
-                                  (LetPrim (v7 (Constant (Int 1)))
-                                    (LetCont
-                                        ((k5 (v8)
-                                           (InvokeContinuation rec k0 (v2 v8))))
-                                      (InvokeMethod v3 + (v7) k5)))))
-                             (InvokeStatic print (v5) k4))))
-                      (InvokeMethod v2 toString () k3))))
-               (LetPrim (v9 (Constant (Int 2)))
-                 (LetCont
-                     ((k6 (v10)
-                        (Branch (IsTrue v10) k2 k1)))
-                   (InvokeMethod v3 < (v9) k6))))))
-        (InvokeContinuation k0 (v0 v1))))))
-""";
-
-String READ_IN_LOOP_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 42)))
-    (LetPrim (v1 (Constant (Int 0)))
-      (LetCont
-          ((rec k0 (v2)
-             (LetCont
-                 ((k1 ()
-                    (LetPrim (v3 (Constant (Null)))
-                      (InvokeContinuation return (v3))))
-                  (k2 ()
-                    (LetCont
-                        ((k3 (v4)
-                           (LetCont
-                               ((k4 (v5)
-                                  (LetPrim (v6 (Constant (Int 1)))
-                                    (LetCont
-                                        ((k5 (v7)
-                                           (InvokeContinuation rec k0 (v7))))
-                                      (InvokeMethod v2 + (v6) k5)))))
-                             (InvokeStatic print (v4) k4))))
-                      (InvokeMethod v0 toString () k3))))
-               (LetPrim (v8 (Constant (Int 2)))
-                 (LetCont
-                     ((k6 (v9)
-                        (Branch (IsTrue v9) k2 k1)))
-                   (InvokeMethod v2 < (v8) k6))))))
-        (InvokeContinuation k0 (v1))))))
-""";
-
-// The 'inner loop' IR represents the following source code:
-//
-// void main() {
-//   int j = 42;
-//   for (int i = 0; i < 2; i++) {
-//     for (int k = 0; k < 2; k++) {
-//       print(i.toString());
-//     }
-//   }
-//   print(j.toString());
-// }
-//
-// This test case ensures that iterative optimization works: first, v8 and v9
-// are removed from k5, and only then can k0 be optimized as well.
-
-const String INNER_LOOP_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 42)))
-    (LetPrim (v1 (Constant (Int 0)))
-      (LetCont
-          ((rec k0 (v2 v3)
-             (LetCont
-                 ((k1 ()
-                    (LetCont
-                        ((k2 (v4)
-                           (LetCont
-                               ((k3 (v5)
-                                  (LetPrim (v6 (Constant (Null)))
-                                    (InvokeContinuation return (v6)))))
-                             (InvokeStatic print (v4) k3))))
-                      (InvokeMethod v2 toString () k2)))
-                  (k4 ()
-                    (LetPrim (v7 (Constant (Int 0)))
-                      (LetCont
-                          ((rec k5 (v8 v9 v10)
-                             (LetCont
-                                 ((k6 ()
-                                    (LetPrim (v11 (Constant (Int 1)))
-                                      (LetCont
-                                          ((k7 (v12)
-                                             (InvokeContinuation rec k0 (v8 v12))))
-                                        (InvokeMethod v9 + (v11) k7))))
-                                  (k8 ()
-                                    (LetCont
-                                        ((k9 (v13)
-                                           (LetCont
-                                               ((k10 (v14)
-                                                  (LetPrim (v15 (Constant (Int 1)))
-                                                    (LetCont
-                                                        ((k11 (v16)
-                                                           (InvokeContinuation rec k5 (v8 v9 v16))))
-                                                      (InvokeMethod v10 + (v15) k11)))))
-                                             (InvokeStatic print (v13) k10))))
-                                      (InvokeMethod v9 toString () k9))))
-                               (LetPrim (v17 (Constant (Int 2)))
-                                 (LetCont
-                                     ((k12 (v18)
-                                        (Branch (IsTrue v18) k8 k6)))
-                                   (InvokeMethod v10 < (v17) k12))))))
-                        (InvokeContinuation k5 (v2 v3 v7))))))
-               (LetPrim (v19 (Constant (Int 2)))
-                 (LetCont
-                     ((k13 (v20)
-                        (Branch (IsTrue v20) k4 k1)))
-                   (InvokeMethod v3 < (v19) k13))))))
-        (InvokeContinuation k0 (v0 v1))))))
-""";
-
-const String INNER_LOOP_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 42)))
-    (LetPrim (v1 (Constant (Int 0)))
-      (LetCont
-          ((rec k0 (v2)
-             (LetCont
-                 ((k1 ()
-                    (LetCont
-                        ((k2 (v3)
-                           (LetCont
-                               ((k3 (v4)
-                                  (LetPrim (v5 (Constant (Null)))
-                                    (InvokeContinuation return (v5)))))
-                             (InvokeStatic print (v3) k3))))
-                      (InvokeMethod v0 toString () k2)))
-                  (k4 ()
-                    (LetPrim (v6 (Constant (Int 0)))
-                      (LetCont
-                          ((rec k5 (v7)
-                             (LetCont
-                                 ((k6 ()
-                                    (LetPrim (v8 (Constant (Int 1)))
-                                      (LetCont
-                                          ((k7 (v9)
-                                             (InvokeContinuation rec k0 (v9))))
-                                        (InvokeMethod v2 + (v8) k7))))
-                                  (k8 ()
-                                    (LetCont
-                                        ((k9 (v10)
-                                           (LetCont
-                                               ((k10 (v11)
-                                                  (LetPrim (v12 (Constant (Int 1)))
-                                                    (LetCont
-                                                        ((k11 (v13)
-                                                           (InvokeContinuation rec k5 (v13))))
-                                                      (InvokeMethod v7 + (v12) k11)))))
-                                             (InvokeStatic print (v10) k10))))
-                                      (InvokeMethod v2 toString () k9))))
-                               (LetPrim (v14 (Constant (Int 2)))
-                                 (LetCont
-                                     ((k12 (v15)
-                                        (Branch (IsTrue v15) k8 k6)))
-                                   (InvokeMethod v7 < (v14) k12))))))
-                        (InvokeContinuation k5 (v6))))))
-               (LetPrim (v16 (Constant (Int 2)))
-                 (LetCont
-                     ((k13 (v17)
-                        (Branch (IsTrue v17) k4 k1)))
-                   (InvokeMethod v2 < (v16) k13))))))
-        (InvokeContinuation k0 (v1))))))
-""";
-
-// There are no redundant phis in the 'basic loop' IR, and this test ensures
-// simply that the optimization does not alter the IR. It represents the
-// following program:
-//
-// void main() {
-//   for (int i = 0; i < 2; i++) {
-//     print(i.toString());
-//   }
-// }
-
-String BASIC_LOOP_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont
-       ((rec k0 (v1)
-          (LetCont
-              ((k1 ()
-                 (LetPrim (v2 (Constant (Null)))
-                   (InvokeContinuation return (v2))))
-               (k2 ()
-                 (LetCont
-                     ((k3 (v3)
-                        (LetCont
-                            ((k4 (v4)
-                               (LetPrim (v5 (Constant (Int 1)))
-                                 (LetCont
-                                     ((k5 (v6)
-                                        (InvokeContinuation rec k0 (v6))))
-                                   (InvokeMethod v1 + (v5) k5)))))
-                          (InvokeStatic print (v3) k4))))
-                   (InvokeMethod v1 toString () k3))))
-            (LetPrim (v7 (Constant (Int 2)))
-              (LetCont
-                  ((k6 (v8)
-                     (Branch (IsTrue v8) k2 k1)))
-                (InvokeMethod v1 < (v7) k6))))))
-      (InvokeContinuation k0 (v0)))))
-""";
-
-String BASIC_LOOP_OUT = BASIC_LOOP_IN;
-
-// Ensures that proper scoping is preserved, i.e. that the optimized
-// continuation body does reference out of scope primitives.
-// IR written by hand since this case is currently not being generated.
-
-String SCOPING_IN = """
-(FunctionDefinition main () () return
-  (LetCont
-      ((k0 (v1)
-         (InvokeStatic print (v1) return)))
-    (LetPrim (v0 (Constant (Int 0)))
-      (LetPrim (v2 (Constant (Null)))
-        (InvokeContinuation k0 (v0))))))
-""";
-
-String SCOPING_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont
-        ((k0 ()
-           (InvokeStatic print (v0) return)))
-      (LetPrim (v1 (Constant (Null)))
-        (InvokeContinuation k0 ())))))
-""";
-
-// Ensures that continuations which are never invoked are not optimized.
-// IR written by hand.
-
-String NEVER_INVOKED_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont
-        ((k0 (v1)
-           (InvokeStatic print (v1) return)))
-      (InvokeContinuation return (v0)))))
-""";
-
-String NEVER_INVOKED_OUT = NEVER_INVOKED_IN;
-
-/// Normalizes whitespace by replacing all whitespace sequences by a single
-/// space and trimming leading and trailing whitespace.
-String normalizeSExpr(String input) {
-  return input.replaceAll(new RegExp(r'[ \n\t]+'), ' ').trim();
-}
-
-/// Parses the given input IR, runs a redundant phi pass over it, and compares
-/// the stringification of the result against the expected output.
-void testRedundantPhi(String input, String expectedOutput) {
-  final unstringifier = new SExpressionUnstringifier();
-  final stringifier   = new SExpressionStringifier();
-  final optimizer     = new RedundantPhiEliminator();
-
-  FunctionDefinition f = unstringifier.unstringify(input);
-  optimizer.rewrite(f);
-
-  String expected = normalizeSExpr(expectedOutput);
-  String actual   = normalizeSExpr(stringifier.visit(f));
-
-  Expect.equals(expected, actual, "Actual:\n$actual");
-}
-
-void main() {
-  testRedundantPhi(READ_IN_LOOP_IN, READ_IN_LOOP_OUT);
-  testRedundantPhi(INNER_LOOP_IN, INNER_LOOP_OUT);
-  testRedundantPhi(BASIC_LOOP_IN, BASIC_LOOP_OUT);
-  testRedundantPhi(SCOPING_IN, SCOPING_OUT);
-  testRedundantPhi(NEVER_INVOKED_IN, NEVER_INVOKED_OUT);
-}
diff --git a/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart b/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
deleted file mode 100644
index 906a6cf..0000000
--- a/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
+++ /dev/null
@@ -1,331 +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 'sexpr_unstringifier.dart';
-import "package:expect/expect.dart";
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
-import 'package:compiler/src/cps_ir/optimizers.dart';
-
-// The tests in this file that ensure shrinking reductions work as expected.
-// Reductions and their corresponding names are taken from
-// 'Compiling with Continuations, Continued' by Andrew Kennedy.
-
-// Basic dead-val: letprim x = V in K -> K (x not free in K).
-//
-//  int main() {
-//    int i = 42;
-//    return 0;
-//  }
-
-String DEAD_VAL_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 42)))
-    (LetPrim (v1 (Constant (Int 0)))
-      (InvokeContinuation return (v1)))))
-""";
-String DEAD_VAL_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (InvokeContinuation return (v0))))
-""";
-
-// Iterative dead-val. No optimizations possible since the continuation to
-// InvokeMethod must have one argument, even if it is unused.
-//
-//  int main() {
-//    int i = 42;
-//    int j = i + 1;
-//    return 0;
-//  }
-
-String ITERATIVE_DEAD_VAL1_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 42)))
-    (LetPrim (v1 (Constant (Int 1)))
-      (LetCont ((k0 (v2)
-                  (LetPrim (v3 (Constant (Int 0)))
-                    (InvokeContinuation return (v3)))))
-        (InvokeMethod v0 + (v1) k0)))))
-""";
-String ITERATIVE_DEAD_VAL1_OUT = ITERATIVE_DEAD_VAL1_IN;
-
-// Iterative dead-val. IR written by hand.
-
-String ITERATIVE_DEAD_VAL2_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 42)))
-    (LetPrim (v1
-        (CreateFunction
-          (FunctionDefinition f () (i) return
-            (InvokeContinuation return (v0)))))
-      (LetPrim (v2 (Constant (Int 0)))
-        (InvokeContinuation return (v2))))))
-""";
-String ITERATIVE_DEAD_VAL2_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (InvokeContinuation return (v0))))
-""";
-
-// Basic dead-cont: letcont k x = L in K -> K (k not free in K).
-// IR written by hand.
-
-String DEAD_CONT_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v4 (Constant (Int 0)))
-    (LetCont ((k0 (v0)
-                (InvokeConstructor List () return)))
-      (LetCont ((k1 (v1)
-                  (LetCont ((k2 (v2)
-                              (LetPrim (v3 (Constant (Int 0)))
-                                (InvokeContinuation return (v3)))))
-                    (InvokeStatic print (v4) k2))))
-        (InvokeStatic print (v4) k1)))))
-""";
-String DEAD_CONT_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont ((k0 (v1)
-                (LetCont ((k1 (v2)
-                            (LetPrim (v3 (Constant (Int 0)))
-                              (InvokeContinuation return (v3)))))
-                  (InvokeStatic print (v0) k1))))
-      (InvokeStatic print (v0) k0))))
-""";
-
-// Iterative dead-cont. IR written by hand.
-
-String ITERATIVE_DEAD_CONT_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v4 (Constant (Int 0)))
-    (LetCont ((k0 (v0)
-                (InvokeConstructor List () return)))
-      (LetCont ((k3 (v5)
-                  (InvokeContinuation k0 (v5))))
-        (LetCont ((k1 (v1)
-                    (LetCont ((k2 (v2)
-                                (LetPrim (v3 (Constant (Int 0)))
-                                  (InvokeContinuation return (v3)))))
-                      (InvokeStatic print (v4) k2))))
-          (InvokeStatic print (v4) k1))))))
-""";
-String ITERATIVE_DEAD_CONT_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont ((k0 (v1)
-                (LetCont ((k1 (v2)
-                            (LetPrim (v3 (Constant (Int 0)))
-                              (InvokeContinuation return (v3)))))
-                  (InvokeStatic print (v0) k1))))
-      (InvokeStatic print (v0) k0))))
-""";
-
-// Beta-cont-lin: letcont k x = K in C[k y] -> C[K[y/x]] (k not free in C).
-// IR written by hand.
-
-String BETA_CONT_LIN_IN = """
-(FunctionDefinition main () () return
-  (LetCont ((k0 (v0)
-              (LetCont ((k1 (v1)
-                          (LetCont ((k2 (v2)
-                                      (LetPrim (v3 (Constant (Int 0)))
-                                        (InvokeContinuation return (v3)))))
-                            (InvokeStatic print (v0) k2))))
-                (InvokeStatic print (v0) k1))))
-    (LetPrim (v4 (Constant (Int 0)))
-      (InvokeContinuation k0 (v4)))))
-""";
-String BETA_CONT_LIN_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont ((k0 (v1)
-                (LetCont ((k1 (v2)
-                            (LetPrim (v3 (Constant (Int 0)))
-                              (InvokeContinuation return (v3)))))
-                  (InvokeStatic print (v0) k1))))
-      (InvokeStatic print (v0) k0))))
-""";
-
-// Beta-cont-lin with recursive continuation. IR written by hand.
-
-String RECURSIVE_BETA_CONT_LIN_IN = """
-(FunctionDefinition main () () return
-  (LetCont ((rec k0 (v0)
-              (InvokeContinuation rec k0 (v0))))
-    (LetPrim (v1 (Constant (Int 0)))
-      (InvokeContinuation k0 (v1)))))
-""";
-String RECURSIVE_BETA_CONT_LIN_OUT = RECURSIVE_BETA_CONT_LIN_IN;
-
-// Beta-cont-lin used inside body. IR written by hand.
-
-String USED_BETA_CONT_LIN_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont ((k0 (v1)
-                (LetCont ((k1 (v2)
-                            (LetCont ((k2 (v3)
-                                        (LetPrim (v4 (Constant (Int 0)))
-                                          (InvokeContinuation return (v4)))))
-                              (InvokeStatic print (v1) k2))))
-                  (InvokeStatic print (v1) k1))))
-      (LetPrim (v5
-                 (CreateFunction
-                   (FunctionDefinition f () () return
-                     (InvokeContinuation return (v1)))))
-        (InvokeContinuation k0 (v0))))))
-""";
-String USED_BETA_CONT_LIN_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont ((k0 (v1)
-                (LetCont ((k1 (v2)
-                            (LetPrim (v3 (Constant (Int 0)))
-                              (InvokeContinuation return (v3)))))
-                  (InvokeStatic print (v0) k1))))
-      (InvokeStatic print (v0) k0))))
-""";
-
-// Eta-cont: letcont k x = j x in K -> K[j/k].
-// IR written by hand.
-//
-// This test is incorrectly named: with the current implementation, there is no
-// eta reduction.  Instead, dead-parameter, beta-cont-lin, and dead-val
-// reductions are performed, which in turn creates a second beta-cont-lin
-// reduction.
-//
-// TODO(kmillikin): To test continuation eta reduction, use eta redexes that are
-// not overlapping beta redexes.
-String ETA_CONT_IN = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (LetCont ((rec k0 (v1)
-                (InvokeContinuation return (v0))))
-      (LetCont ((k1 (v2)
-                  (InvokeContinuation k0 (v2))))
-        (LetPrim (v3
-                   (CreateFunction
-                     (FunctionDefinition f () () return
-                       (InvokeContinuation k0 (v0)))))
-          (InvokeContinuation k1 (v0)))))))
-""";
-String ETA_CONT_OUT = """
-(FunctionDefinition main () () return
-  (LetPrim (v0 (Constant (Int 0)))
-    (InvokeContinuation return (v0))))
-""";
-
-// Dead-parameter:
-// letcont k x = E0 in E1 -> letcont k () = E0 in E1,
-//    if x does not occur free in E0.
-
-// Parameter v1 is unused in k0.
-String DEAD_PARAMETER_IN = """
-(FunctionDefinition main () (x) return
-  (LetCont ((k0 (v0 v1 v2)
-              (InvokeStatic foo (v0 v2) return)))
-    (LetCont ((k1 ()
-                (LetPrim (v3 (Constant (Int 0)))
-                  (LetPrim (v4 (Constant (Int 1)))
-                    (LetPrim (v5 (Constant (Int 2)))
-                      (InvokeContinuation k0 (v3 v4 v5))))))
-              (k2 ()
-                (LetPrim (v6 (Constant (Int 3)))
-                  (LetPrim (v7 (Constant (Int 4)))
-                    (LetPrim (v8 (Constant (Int 5)))
-                      (InvokeContinuation k0 (v6 v7 v8)))))))
-      (Branch (IsTrue x) k1 k2))))
-""";
-String DEAD_PARAMETER_OUT = """
-(FunctionDefinition main () (x) return
-  (LetCont ((k0 (v0 v1)
-              (InvokeStatic foo (v0 v1) return)))
-    (LetCont ((k1 ()
-                (LetPrim (v2 (Constant (Int 0)))
-                  (LetPrim (v3 (Constant (Int 2)))
-                    (InvokeContinuation k0 (v2 v3)))))
-              (k2 ()
-                (LetPrim (v4 (Constant (Int 3)))
-                  (LetPrim (v5 (Constant (Int 5)))
-                    (InvokeContinuation k0 (v4 v5))))))
-      (Branch (IsTrue x) k1 k2))))
-""";
-
-// Create an eta-cont redex:
-// Dead parameter reductions can create an eta-cont redex by removing unused
-// continuation parameters and thus creating the eta redex.
-String CREATE_ETA_CONT_IN = """
-(FunctionDefinition main () (x) return
-  (LetCont ((rec loop (v0)
-              (InvokeContinuation rec loop (v0))))
-    (LetCont ((created (v1 v2 v3)
-                (InvokeContinuation loop (v2))))
-      (LetCont ((then ()
-                  (LetPrim (v4 (Constant (Int 0)))
-                    (LetPrim (v5 (Constant (Int 1)))
-                      (LetPrim (v6 (Constant (Int 2)))
-                        (InvokeContinuation created (v4 v5 v6))))))
-                (else ()
-                  (LetPrim (v6 (Constant (Int 3)))
-                    (LetPrim (v7 (Constant (Int 4)))
-                      (LetPrim (v8 (Constant (Int 5)))
-                        (InvokeContinuation created (v6 v7 v8)))))))
-        (Branch (IsTrue x) then else)))))
-""";
-String CREATE_ETA_CONT_OUT = """
-(FunctionDefinition main () (x) return
-  (LetCont ((rec k0 (v0)
-              (InvokeContinuation rec k0 (v0))))
-    (LetCont ((k1 ()
-                (LetPrim (v1 (Constant (Int 1)))
-                  (InvokeContinuation k0 (v1))))
-              (k2 ()
-                (LetPrim (v2 (Constant (Int 4)))
-                  (InvokeContinuation k0 (v2)))))
-      (Branch (IsTrue x) k1 k2))))
-""";
-
-
-
-// Beta-fun-lin and eta-fun might not apply to us, since
-// a. in (InvokeMethod v0 call k0), v0 might carry state, and
-// b. there is no way to generate static nested functions that we could
-//    use InvokeStatic on.
-
-/// Normalizes whitespace by replacing all whitespace sequences by a single
-/// space and trimming leading and trailing whitespace.
-String normalizeSExpr(String input) {
-  return input.replaceAll(new RegExp(r'[ \n\t]+'), ' ').trim();
-}
-
-/// Parses the given input IR, runs an optimization pass over it, and compares
-/// the stringification of the result against the expected output.
-void testShrinkingReducer(String input, String expectedOutput) {
-  final unstringifier = new SExpressionUnstringifier();
-  final stringifier   = new SExpressionStringifier();
-  final optimizer     = new ShrinkingReducer();
-
-  FunctionDefinition f = unstringifier.unstringify(input);
-  optimizer.rewrite(f);
-
-  String expected = normalizeSExpr(expectedOutput);
-  String actual = normalizeSExpr(stringifier.visit(f));
-
-  Expect.equals(expected, actual);
-}
-
-void main() {
-  testShrinkingReducer(DEAD_VAL_IN, DEAD_VAL_OUT);
-  testShrinkingReducer(ITERATIVE_DEAD_VAL1_IN, ITERATIVE_DEAD_VAL1_OUT);
-  testShrinkingReducer(ITERATIVE_DEAD_VAL2_IN, ITERATIVE_DEAD_VAL2_OUT);
-  testShrinkingReducer(DEAD_CONT_IN, DEAD_CONT_OUT);
-  testShrinkingReducer(ITERATIVE_DEAD_CONT_IN, ITERATIVE_DEAD_CONT_OUT);
-  testShrinkingReducer(BETA_CONT_LIN_IN, BETA_CONT_LIN_OUT);
-  testShrinkingReducer(RECURSIVE_BETA_CONT_LIN_IN, RECURSIVE_BETA_CONT_LIN_OUT);
-  testShrinkingReducer(USED_BETA_CONT_LIN_IN, USED_BETA_CONT_LIN_OUT);
-  testShrinkingReducer(ETA_CONT_IN, ETA_CONT_OUT);
-  testShrinkingReducer(DEAD_PARAMETER_IN, DEAD_PARAMETER_OUT);
-  testShrinkingReducer(CREATE_ETA_CONT_IN, CREATE_ETA_CONT_OUT);
-}
diff --git a/tests/compiler/dart2js/backend_dart/sexpr2_test.dart b/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
deleted file mode 100644
index 03803bd..0000000
--- a/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
+++ /dev/null
@@ -1,62 +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.
-
-/// Unittest test of the CPS ir generated by the dart2dart compiler.
-library dart_backend.sexpr2_test;
-
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:expect/expect.dart';
-
-import '../../../../pkg/analyzer2dart/test/test_helper.dart';
-import '../../../../pkg/analyzer2dart/test/sexpr_data.dart';
-
-import 'test_helper.dart';
-
-main(List<String> args) {
-  performTests(TEST_DATA, asyncTester, runTest, args);
-}
-
-runTest(TestSpec result) {
-  return compilerFor(result.input).then((Compiler compiler) {
-    void checkOutput(String elementName,
-                     Element element,
-                     String expectedOutput) {
-      FunctionDefinition ir = compiler.irBuilder.getIr(element);
-      if (expectedOutput == null) {
-        Expect.isNull(ir, "\nInput:\n${result.input}\n"
-                          "No CPS IR expected for $element");
-      } else {
-        Expect.isNotNull(ir, "\nInput:\n${result.input}\n"
-                             "No CPS IR for $element");
-        expectedOutput = expectedOutput.trim();
-        String output = ir.accept(new SExpressionStringifier()).trim();
-        Expect.equals(expectedOutput, output,
-            "\nInput:\n${result.input}\n"
-            "Expected for '$elementName':\n$expectedOutput\n"
-            "Actual for '$elementName':\n$output\n");
-      }
-    }
-
-    if (result.output is String) {
-      checkOutput('main', compiler.mainFunction, result.output);
-    } else {
-      assert(result.output is Map<String, String>);
-      result.output.forEach((String elementName, String output) {
-        Element element;
-        if (elementName.contains('.')) {
-          ClassElement cls = compiler.mainApp.localLookup(
-              elementName.substring(0, elementName.indexOf('.')));
-          element = cls.localLookup(
-              elementName.substring(elementName.indexOf('.') + 1));
-        } else {
-          element = compiler.mainApp.localLookup(elementName);
-        }
-        checkOutput(elementName, element, output);
-      });
-    }
-  });
-}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_test.dart b/tests/compiler/dart2js/backend_dart/sexpr_test.dart
deleted file mode 100644
index 2293cdb..0000000
--- a/tests/compiler/dart2js/backend_dart/sexpr_test.dart
+++ /dev/null
@@ -1,177 +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 dart_backend.sexpr_test;
-
-import 'dart:async';
-
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
-import 'package:expect/expect.dart';
-
-import '../compiler_helper.dart' hide compilerFor;
-import 'sexpr_unstringifier.dart';
-import 'test_helper.dart';
-
-const String CODE = """
-class Foo {
-  static int x = 1;
-  foo() => 42;
-}
-
-class Bar extends Foo {
-  int y = 2;
-  Bar() {
-    Foo.x = 2;
-  }
-  foo() =>  this.y + super.foo();
-}
-
-class FooBar<T> {
-  bool foobar() => T is int;
-}
-
-main() {
-  Foo foo;
-  if (foo is Foo) {
-    print("Surprise");
-  }
-
-  String inner() => "Inner function";
-  print(inner());
-
-  int j = 42;
-  for (int i = 0; i < 2; i++) {
-    print(i.toString());
-  }
-
-  print(Foo.x);
-
-  String recursive(int h) {
-    if (h < 1) {
-      return j.toString();
-    }
-    j++;
-    return "h\$\{recursive(h - 1)\}";
-  }
-  print(recursive(5));
-
-  Bar bar = new Bar();
-  print(bar.foo().toString());
-
-  bar = foo as Bar;
-  if (bar == null) {
-    var list = [1, 2, 3, 4];
-    var map  = { 1: "one"
-               , 2: "two"
-               , 3: "three"
-               };
-    var double = 3.14;
-    list.forEach((i) => print(i.toString()));
-    print("\$list \$map \$double");
-  }
-
-  print(new FooBar<int>().foobar());
-}
-
-""";
-
-bool shouldOutput(Element element) {
-  return (!element.library.isPlatformLibrary &&
-          !element.isSynthesized &&
-          element.kind == ElementKind.FUNCTION);
-}
-
-/// Compiles the given dart code (which must include a 'main' function) and
-/// returns a list of all generated CPS IR definitions.
-Future<List<FunctionDefinition>> compile(String code) {
-  return compilerFor(code).then((Compiler compiler) {
-    return compiler.enqueuer.resolution.resolvedElements
-              .where(shouldOutput)
-              .map(compiler.irBuilder.getIr)
-              .toList();
-  });
-}
-
-/// Returns an S-expression string for each compiled function.
-List<String> stringifyAll(Iterable<FunctionDefinition> functions) {
-  final stringifier = new SExpressionStringifier();
-  return functions.map((f) => stringifier.visitFunctionDefinition(f)).toList();
-}
-
-Future<List<String>> testStringifier(String code,
-                                     Iterable<String> expectedTokens) {
-  return compile(code)
-      .then((List<FunctionDefinition> functions) {
-        List<String> sexprs = stringifyAll(functions);
-        String combined = sexprs.join();
-        String withoutNullConstants = combined.replaceAll("Constant null", "");
-        Expect.isFalse(withoutNullConstants.contains("null"));
-        for (String token in expectedTokens) {
-          Expect.isTrue(combined.contains(token),
-              "'$combined' doesn't contain '$token' in test:\n$code");
-        }
-
-        return sexprs;
-      });
-}
-
-/// Checks if the generated S-expressions can be processed by the unstringifier,
-/// returns the resulting definitions.
-List<FunctionDefinition> testUnstringifier(List<String> sexprs) {
-  return sexprs.map((String sexpr) {
-    try {
-      final function = new SExpressionUnstringifier().unstringify(sexpr);
-      Expect.isNotNull(function, "Unstringification failed:\n\n$sexpr");
-      return function;
-    } catch (e, s) {
-      print('$e\n$s');
-      Expect.fail('Error unstringifying "$sexpr": $e');
-    }
-  }).toList();
-}
-
-void main() {
-  final tokens =
-          [ "FunctionDefinition"
-          , "IsTrue"
-
-          // Expressions
-          , "Branch"
-          , "ConcatenateStrings"
-          , "DeclareFunction"
-          , "InvokeConstructor"
-          , "InvokeContinuation"
-          , "InvokeMethod"
-          , "InvokeStatic"
-          , "InvokeMethodDirectly"
-          , "LetCont"
-          , "LetPrim"
-          , "SetMutableVariable"
-          , "TypeOperator"
-
-          // Primitives
-          , "Constant"
-          , "CreateFunction"
-          , "GetMutableVariable"
-          , "LiteralList"
-          , "LiteralMap"
-          // Parameters are encoded by name only and hence are not in this list.
-          , "ReifyTypeVar"
-
-          , "(this)"   // 'this' Parameter declarations
-          , "this"     // 'this' Parameter uses
-
-          ];
-
-  asyncTest(() => testStringifier(CODE, tokens).then((List<String> sexprs) {
-    final functions = testUnstringifier(sexprs);
-
-    // Ensure that
-    // stringified(CODE) == stringified(unstringified(stringified(CODE)))
-    Expect.listEquals(sexprs, stringifyAll(functions));
-  }));
-}
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
deleted file mode 100644
index e0252e7..0000000
--- a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
+++ /dev/null
@@ -1,885 +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.
-
-// SExpressionUnstringifier implements the inverse operation to
-// [SExpressionStringifier].
-
-library sexpr_unstringifier;
-
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/dart_types.dart' as dart_types
-    show DartType;
-import 'package:compiler/src/diagnostics/messages.dart'
-    show MessageKind;
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/modelx.dart'
-    show ErroneousElementX, TypeVariableElementX;
-import 'package:compiler/src/tree/tree.dart' show LiteralDartString;
-import 'package:compiler/src/universe/call_structure.dart'
-    show CallStructure;
-import 'package:compiler/src/universe/selector.dart'
-    show Selector, SelectorKind;
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
-
-/// Used whenever a node constructed by [SExpressionUnstringifier] needs a
-/// named entity.
-class DummyEntity extends Entity {
-  final String name;
-  DummyEntity(this.name);
-}
-
-/// Used whenever a node constructed by [SExpressionUnstringifier] needs a
-/// local.
-class DummyLocal extends DummyEntity implements Local {
-  DummyLocal(String name) : super(name);
-
-  ExecutableElement get executableContext => null;
-}
-
-// TODO(karlklose): we should remove all references to [ErroneousElement] from
-// the CPS IR.  Instead, the builder must construct appropriate terms for ASTs
-// that could not be resolved correctly.  Perhaps the IR should not rely on
-// elements at all for naming.
-/// Used whenever a node constructed by [SExpressionUnstringifier] requires
-/// an [Element] or [FunctionElement]. Extends [ErroneousElementX] since there
-/// is currently a large amount of overhead when extending the base abstract
-/// classes, and erroneous elements conveniently also skip several assertion
-/// checks in CPS IR nodes that are irrelevant to us.
-class DummyElement extends ErroneousElementX
-    implements TypeVariableElement, FieldElement {
-  DummyElement(String name)
-      : super(MessageKind.GENERIC, {}, name, null);
-
-  final dart_types.DartType bound = null;
-  final TypeDeclarationElement typeDeclaration = null;
-
-  noSuchMethod(inv) => super.noSuchMethod(inv);
-}
-
-/// Used whenever a node constructed by [SExpressionUnstringifier] requires
-/// a named type.
-class DummyNamedType extends dart_types.DartType {
-  final String name;
-
-  final kind = null;
-  final element = null;
-
-  DummyNamedType(this.name);
-
-  subst(arguments, parameters) => null;
-  unalias(compiler) => null;
-  accept(visitor, argument) => null;
-
-  String toString() => name;
-}
-
-/// Represents a list of tokens, but is basically a partial view into a list
-/// with appropriate convenience methods.
-class Tokens {
-  final List<String> _list;
-  int _index; // Current index into the list.
-
-  Tokens(List<String> this._list) : _index = 0;
-
-  String get current => _list[_index];
-  String get next    => _list[_index + 1];
-
-  String read([String expected]) {
-    if (expected != null) {
-      if (current != expected) {
-        print('expected "$expected", found "$current"');
-        int start = _index - 15;
-        String dotdotdot = '... ';
-        if (start < 0) {
-          start = 0;
-          dotdotdot = '';
-        }
-        print('${dotdotdot}${_list.sublist(start, _index + 1).join(' ')}');
-        assert(current == expected);
-      }
-    }
-    return _list[_index++];
-  }
-
-  /// Consumes the preamble to a new node, consisting of an opening parenthesis
-  /// and a tag.
-  void consumeStart([String tag]) {
-    read("(");
-    if (tag != null) {
-      read(tag);
-    }
-  }
-
-  void consumeEnd() {
-    read(")");
-  }
-
-  bool get hasNext  => _index < _list.length;
-  String toString() => _list.sublist(_index).toString();
-}
-
-/// Constructs a minimal in-memory representation of the IR represented
-/// by the given string. Many fields are currently simply set to null.
-class SExpressionUnstringifier {
-
-  // Expressions
-  static const String BRANCH = "Branch";
-  static const String CONCATENATE_STRINGS = "ConcatenateStrings";
-  static const String DECLARE_FUNCTION = "DeclareFunction";
-  static const String INVOKE_CONSTRUCTOR = "InvokeConstructor";
-  static const String INVOKE_CONTINUATION = "InvokeContinuation";
-  static const String INVOKE_STATIC = "InvokeStatic";
-  static const String INVOKE_METHOD_DIRECTLY = "InvokeMethodDirectly";
-  static const String INVOKE_METHOD = "InvokeMethod";
-  static const String LET_PRIM = "LetPrim";
-  static const String LET_CONT = "LetCont";
-  static const String LET_MUTABLE = "LetMutable";
-  static const String TYPE_CAST = "TypeCast";
-  static const String GET_LAZY_STATIC = "GetLazyStatic";
-  static const String UNREACHABLE = "Unreachable";
-
-  // Primitives
-  static const String CONSTANT = "Constant";
-  static const String CREATE_FUNCTION = "CreateFunction";
-  static const String GET_MUTABLE = "GetMutable";
-  static const String SET_MUTABLE = "SetMutable";
-  static const String LITERAL_LIST = "LiteralList";
-  static const String LITERAL_MAP = "LiteralMap";
-  static const String REIFY_TYPE_VAR = "ReifyTypeVar";
-  static const String GET_STATIC = "GetStatic";
-  static const String SET_STATIC = "SetStatic";
-  static const String TYPE_TEST = "TypeTest";
-  static const String APPLY_BUILTIN_OPERATOR = "ApplyBuiltinOperator";
-  static const String GET_LENGTH = "GetLength";
-  static const String GET_INDEX = "GetIndex";
-  static const String SET_INDEX = "SetIndex";
-  static const String GET_FIELD = "GetField";
-  static const String SET_FIELD = "SetField";
-
-  // Other
-  static const String FUNCTION_DEFINITION = "FunctionDefinition";
-  static const String IS_TRUE = "IsTrue";
-
-  // Constants
-  static const String BOOL = "Bool";
-  static const String DOUBLE = "Double";
-  static const String INT = "Int";
-  static const String NULL = "Null";
-  static const String STRING = "String";
-
-  final Map<String, Definition> name2variable =
-      <String, Definition>{ "return": new Continuation.retrn() };
-
-  // Operator names used for canonicalization. In theory, we could simply use
-  // Elements.isOperatorName() on the parsed tokens; however, comparisons are
-  // done using identical() for performance reasons, which are reliable only for
-  // compile-time literal strings.
-  static Set<String> OPERATORS = new Set<String>.from(
-      [ '~', '==', '[]', '*', '/', '%', '~/', '+', '<<', 'unary-'
-      , '>>', '>=', '>', '<=', '<', '&', '^', '|', '[]=', '-'
-      ]);
-
-  // The tokens currently being parsed.
-  Tokens tokens;
-
-  FunctionDefinition unstringify(String s) {
-    tokens = tokenize(s);
-    FunctionDefinition def = parseFunctionDefinition();
-    assert(!tokens.hasNext);
-    return def;
-  }
-
-  /// Returns a new named dummy selector with a roughly appropriate kind.
-  Selector dummySelector(String name, int argumentCount) {
-    SelectorKind kind;
-    if (name == "[]") {
-      kind = SelectorKind.INDEX;
-    } else if (Elements.isOperatorName(name)) {
-      kind = SelectorKind.OPERATOR;
-    } else {
-      kind = SelectorKind.CALL;
-    }
-    return new Selector(kind, new PublicName(name),
-        new CallStructure.unnamed(argumentCount));
-  }
-
-  /// Returns the tokens in s. Note that string literals are not necessarily
-  /// preserved; for instance, "(literalString)" is transformed to
-  /// " ( literalString ) ".
-  Tokens tokenize(String s) =>
-      new Tokens(
-          s.replaceAll("(", " ( ")
-           .replaceAll(")", " ) ")
-           .replaceAll("{", " { ")
-           .replaceAll("}", " } ")
-           .replaceAll(new RegExp(r"[ \t\n]+"), " ")
-           .trim()
-           .split(" ")
-           .map(canonicalizeOperators)
-           .toList());
-
-  /// Canonicalizes strings containing operator names.
-  String canonicalizeOperators(String token) {
-    String opname = OPERATORS.lookup(token);
-    if (opname != null) {
-      return opname;
-    }
-    return token;
-  }
-
-  Expression parseExpression() {
-    assert(tokens.current == "(");
-
-    switch (tokens.next) {
-      case BRANCH:
-        return parseBranch();
-      case CONCATENATE_STRINGS:
-        return parseConcatenateStrings();
-      case DECLARE_FUNCTION:
-        return parseDeclareFunction();
-      case INVOKE_CONSTRUCTOR:
-        return parseInvokeConstructor();
-      case INVOKE_CONTINUATION:
-        return parseInvokeContinuation();
-      case INVOKE_METHOD:
-        return parseInvokeMethod();
-      case INVOKE_STATIC:
-        return parseInvokeStatic();
-      case INVOKE_METHOD_DIRECTLY:
-        return parseInvokeMethodDirectly();
-      case LET_PRIM:
-        return parseLetPrim();
-      case LET_CONT:
-        return parseLetCont();
-      case LET_MUTABLE:
-        return parseLetMutable();
-      case TYPE_CAST:
-        return parseTypeCast();
-      case GET_LAZY_STATIC:
-        return parseGetLazyStatic();
-      case UNREACHABLE:
-        return parseUnreachable();
-      default:
-        assert(false);
-    }
-
-    return null;
-  }
-
-  /// (prim1 prim2 ... primn)
-  List<Primitive> parsePrimitiveList() {
-    tokens.consumeStart();
-    List<Primitive> prims = <Primitive>[];
-    while (tokens.current != ")") {
-      Primitive prim = name2variable[tokens.read()];
-      assert(prim != null);
-      prims.add(prim);
-    }
-    tokens.consumeEnd();
-    return prims;
-  }
-
-  /// (FunctionDefinition name (parameters) continuation body)
-  FunctionDefinition parseFunctionDefinition() {
-    tokens.consumeStart(FUNCTION_DEFINITION);
-
-    // name
-    Element element = new DummyElement("");
-    if (tokens.current != '(') {
-      // This is a named function.
-      element = new DummyElement(tokens.read());
-    }
-
-    // (this) or ()
-    Definition thisParameter = null;
-    tokens.consumeStart();
-    if (tokens.current != ')') {
-      String thisName = tokens.read();
-      if (name2variable.containsKey(thisName)) {
-        thisParameter = name2variable[thisName];
-      } else {
-        thisParameter = new Parameter(new DummyElement(thisName));
-        name2variable[thisName] = thisParameter;
-      }
-    }
-    tokens.consumeEnd();
-
-    // (parameters)
-    List<Definition> parameters = <Definition>[];
-    tokens.consumeStart();
-    while (tokens.current != ")") {
-      String paramName = tokens.read();
-      if (name2variable.containsKey(paramName)) {
-        parameters.add(name2variable[paramName]);
-      } else {
-        Parameter param = new Parameter(new DummyElement(paramName));
-        name2variable[paramName] = param;
-        parameters.add(param);
-      }
-    }
-    tokens.consumeEnd();
-
-    // continuation
-    String contName = tokens.read("return");
-    Continuation cont = name2variable[contName];
-    assert(cont != null);
-
-    // body
-    Expression body = parseExpression();
-
-    tokens.consumeEnd();
-    return new FunctionDefinition(element, thisParameter, parameters,
-        new Body(body, cont), null, null);
-  }
-
-  /// (IsTrue arg)
-  Condition parseCondition() {
-    // Handles IsTrue only for now.
-    tokens.consumeStart(IS_TRUE);
-
-    Definition value = name2variable[tokens.read()];
-    assert(value != null);
-
-    tokens.consumeEnd();
-    return new IsTrue(value);
-  }
-
-  /// (Branch condition cont cont)
-  Branch parseBranch() {
-    tokens.consumeStart(BRANCH);
-
-    Condition cond = parseCondition();
-    Continuation trueCont = name2variable[tokens.read()];
-    Continuation falseCont = name2variable[tokens.read()];
-    assert(trueCont != null && falseCont != null);
-
-    tokens.consumeEnd();
-    return new Branch(cond, trueCont, falseCont);
-  }
-
-  /// (ConcatenateStrings (args) cont)
-  ConcatenateStrings parseConcatenateStrings() {
-    tokens.consumeStart(CONCATENATE_STRINGS);
-
-    List<Primitive> args = parsePrimitiveList();
-
-    Continuation cont = name2variable[tokens.read()];
-    assert(cont != null);
-
-    tokens.consumeEnd();
-    return new ConcatenateStrings(args, cont);
-  }
-
-  /// (DeclareFunction name = function in body)
-  DeclareFunction parseDeclareFunction() {
-    tokens.consumeStart(DECLARE_FUNCTION);
-
-    // name =
-    MutableVariable local = addMutableVariable(tokens.read());
-    tokens.read("=");
-
-    // function in
-    FunctionDefinition def = parseFunctionDefinition();
-    tokens.read("in");
-
-    // body
-    Expression body = parseExpression();
-
-    tokens.consumeEnd();
-    return new DeclareFunction(local, def)..plug(body);
-  }
-
-  /// (InvokeConstructor name (args) cont)
-  InvokeConstructor parseInvokeConstructor() {
-    tokens.consumeStart(INVOKE_CONSTRUCTOR);
-
-    String constructorName = tokens.read();
-    List<String> split = constructorName.split(".");
-    assert(split.length < 3);
-
-    dart_types.DartType type = new DummyNamedType(split[0]);
-    Element element = new DummyElement((split.length == 1) ? "" : split[1]);
-
-    List<Primitive> args = parsePrimitiveList();
-
-    Continuation cont = name2variable[tokens.read()];
-    assert(cont != null);
-
-    tokens.consumeEnd();
-    Selector selector = dummySelector(constructorName, args.length);
-    return new InvokeConstructor(type, element, selector, args, cont);
-  }
-
-  /// (InvokeContinuation rec? name (args))
-  InvokeContinuation parseInvokeContinuation() {
-    tokens.consumeStart(INVOKE_CONTINUATION);
-    String name = tokens.read();
-    bool isRecursive = name == "rec";
-    if (isRecursive) name = tokens.read();
-
-    Continuation cont = name2variable[name];
-    assert(cont != null);
-
-    List<Primitive> args = parsePrimitiveList();
-
-    tokens.consumeEnd();
-    return new InvokeContinuation(cont, args, isRecursive: isRecursive);
-  }
-
-  /// (InvokeMethod receiver method (args) cont)
-  InvokeMethod parseInvokeMethod() {
-    tokens.consumeStart(INVOKE_METHOD);
-
-    Definition receiver = name2variable[tokens.read()];
-    assert(receiver != null);
-
-    String methodName = tokens.read();
-
-    List<Primitive> args = parsePrimitiveList();
-
-    Continuation cont = name2variable[tokens.read()];
-    assert(cont != null);
-
-    tokens.consumeEnd();
-    Selector selector = dummySelector(methodName, args.length);
-    return new InvokeMethod(receiver, selector, args, cont);
-  }
-
-  /// (InvokeStatic method (args) cont)
-  InvokeStatic parseInvokeStatic() {
-    tokens.consumeStart(INVOKE_STATIC);
-
-    String methodName = tokens.read();
-
-    List<Primitive> args = parsePrimitiveList();
-
-    Continuation cont = name2variable[tokens.read()];
-    assert(cont != null);
-
-    Entity entity = new DummyEntity(methodName);
-    Selector selector = dummySelector(methodName, args.length);
-
-    tokens.consumeEnd();
-    return new InvokeStatic(entity, selector, args, cont, null);
-  }
-
-  /// (InvokeMethodDirectly receiver method (args) cont)
-  InvokeMethodDirectly parseInvokeMethodDirectly() {
-    tokens.consumeStart(INVOKE_METHOD_DIRECTLY);
-
-    Definition receiver = name2variable[tokens.read()];
-    assert(receiver != null);
-
-    String methodName = tokens.read();
-
-    List<Primitive> args = parsePrimitiveList();
-
-    Continuation cont = name2variable[tokens.read()];
-    assert(cont != null);
-
-    tokens.consumeEnd();
-    Element element = new DummyElement(methodName);
-    Selector selector = dummySelector(methodName, args.length);
-    return new InvokeMethodDirectly(receiver, element, selector, args, cont);
-  }
-
-  // (rec? name (args) body)
-  Continuation parseContinuation() {
-    // (rec? name
-    tokens.consumeStart();
-    String name = tokens.read();
-    bool isRecursive = name == "rec";
-    if (isRecursive) name = tokens.read();
-
-    // (args)
-    tokens.consumeStart();
-    List<Parameter> params = <Parameter>[];
-    while (tokens.current != ")") {
-      String paramName = tokens.read();
-      Parameter param = new Parameter(new DummyElement(paramName));
-      name2variable[paramName] = param;
-      params.add(param);
-    }
-    tokens.consumeEnd();
-
-    Continuation cont = new Continuation(params);
-    name2variable[name] = cont;
-
-    cont.isRecursive = isRecursive;
-    // cont_body
-    cont.body = parseExpression();
-    tokens.consumeEnd();
-    return cont;
-  }
-
-  /// (LetCont (continuations) body)
-  LetCont parseLetCont() {
-    tokens.consumeStart(LET_CONT);
-    tokens.consumeStart();
-    List<Continuation> continuations = <Continuation>[];
-    while (tokens.current != ")") {
-      continuations.add(parseContinuation());
-    }
-    tokens.consumeEnd();
-
-    // body)
-    Expression body = parseExpression();
-    tokens.consumeEnd();
-
-    return new LetCont.many(continuations, body);
-  }
-
-  /// (LetMutable (name value) body)
-  LetMutable parseLetMutable() {
-    tokens.consumeStart(LET_MUTABLE);
-
-    tokens.consumeStart();
-    String name = tokens.read();
-    MutableVariable local = addMutableVariable(name);
-    Primitive value = name2variable[tokens.read()];
-    tokens.consumeEnd();
-
-    Expression body = parseExpression();
-    tokens.consumeEnd();
-    return new LetMutable(local, value)..plug(body);
-  }
-
-  /// (SetMutable name value)
-  SetMutable parseSetMutable() {
-    tokens.consumeStart(SET_MUTABLE);
-
-    MutableVariable local = name2variable[tokens.read()];
-    Primitive value = name2variable[tokens.read()];
-    assert(value != null);
-
-    tokens.consumeEnd();
-    return new SetMutable(local, value);
-  }
-
-  /// (TypeCast value type args cont)
-  TypeCast parseTypeCast() {
-    tokens.consumeStart(TYPE_CAST);
-
-    Primitive value = name2variable[tokens.read()];
-    assert(value != null);
-
-    dart_types.DartType type = new DummyNamedType(tokens.read());
-
-    List<ir.Primitive> typeArguments = parsePrimitiveList();
-
-    Continuation cont = name2variable[tokens.read()];
-    assert(cont != null);
-
-    tokens.consumeEnd();
-    return new TypeCast(value, type, typeArguments, cont);
-  }
-
-  /// (TypeTest value type args)
-  TypeTest parseTypeTest() {
-    tokens.consumeStart(TYPE_TEST);
-
-    Primitive value = name2variable[tokens.read()];
-    assert(value != null);
-
-    dart_types.DartType type = new DummyNamedType(tokens.read());
-
-    List<ir.Primitive> typeArguments = parsePrimitiveList();
-
-    tokens.consumeEnd();
-    return new TypeTest(value, type, typeArguments);
-  }
-
-  /// (ApplyBuiltinOperator operator args)
-  ApplyBuiltinOperator parseApplyBuiltinOperator() {
-    tokens.consumeStart(APPLY_BUILTIN_OPERATOR);
-
-    String operatorName = tokens.read();
-    BuiltinOperator operator;
-    for (BuiltinOperator op in BuiltinOperator.values) {
-      if (op.toString() == operatorName) {
-        operator = op;
-        break;
-      }
-    }
-    assert(operator != null);
-    List<ir.Primitive> arguments = parsePrimitiveList();
-
-    tokens.consumeEnd();
-    return new ApplyBuiltinOperator(operator, arguments);
-  }
-
-  /// (GetLength object)
-  GetLength parseGetLength() {
-    tokens.consumeStart(GET_LENGTH);
-    Primitive object = name2variable[tokens.read()];
-    tokens.consumeEnd();
-    return new GetLength(object);
-  }
-
-  /// (GetIndex object index)
-  GetIndex parseGetIndex() {
-    tokens.consumeStart(GET_INDEX);
-    Primitive object = name2variable[tokens.read()];
-    Primitive index = name2variable[tokens.read()];
-    tokens.consumeEnd();
-    return new GetIndex(object, index);
-  }
-
-  /// (SetIndex object index value)
-  SetIndex parseSetIndex() {
-    tokens.consumeStart(SET_INDEX);
-    Primitive object = name2variable[tokens.read()];
-    Primitive index = name2variable[tokens.read()];
-    Primitive value = name2variable[tokens.read()];
-    tokens.consumeEnd();
-    return new SetIndex(object, index, value);
-  }
-
-  /// (SetStatic field value)
-  SetStatic parseSetStatic() {
-    tokens.consumeStart(SET_STATIC);
-
-    Element fieldElement = new DummyElement(tokens.read());
-    Primitive value = name2variable[tokens.read()];
-    assert(value != null);
-
-    tokens.consumeEnd();
-    return new SetStatic(fieldElement, value, null);
-  }
-
-  /// (GetLazyStatic field cont)
-  GetLazyStatic parseGetLazyStatic() {
-    tokens.consumeStart(GET_LAZY_STATIC);
-
-    Element fieldElement = new DummyElement(tokens.read());
-    Continuation cont = name2variable[tokens.read()];
-    assert(cont != null);
-
-    tokens.consumeEnd();
-    return new GetLazyStatic(fieldElement, cont, null);
-  }
-
-  /// (Unreachable)
-  Unreachable parseUnreachable() {
-    tokens.consumeStart(UNREACHABLE);
-    tokens.consumeEnd();
-    return new Unreachable();
-  }
-
-  /// (LetPrim (name primitive) body)
-  LetPrim parseLetPrim() {
-    tokens.consumeStart(LET_PRIM);
-
-    // (name
-    tokens.consumeStart();
-    String name = tokens.read();
-
-    // primitive)
-    Primitive primitive = parsePrimitive();
-    name2variable[name] = primitive;
-    tokens.consumeEnd();
-
-    // body)
-    Expression body = parseExpression();
-    tokens.consumeEnd();
-
-    return new LetPrim(primitive)..plug(body);
-  }
-
-  Primitive parsePrimitive() {
-    assert(tokens.current == "(");
-
-    switch (tokens.next) {
-      case CONSTANT:
-        return parseConstant();
-      case CREATE_FUNCTION:
-        return parseCreateFunction();
-      case GET_MUTABLE:
-        return parseGetMutable();
-      case SET_MUTABLE:
-        return parseSetMutable();
-      case LITERAL_LIST:
-        return parseLiteralList();
-      case LITERAL_MAP:
-        return parseLiteralMap();
-      case REIFY_TYPE_VAR:
-        return parseReifyTypeVar();
-      case GET_STATIC:
-        return parseGetStatic();
-      case SET_STATIC:
-        return parseSetStatic();
-      case TYPE_TEST:
-        return parseTypeTest();
-      case APPLY_BUILTIN_OPERATOR:
-        return parseApplyBuiltinOperator();
-      case GET_LENGTH:
-        return parseGetLength();
-      case GET_INDEX:
-        return parseGetIndex();
-      case SET_INDEX:
-        return parseSetIndex();
-      case GET_FIELD:
-        return parseGetField();
-      case SET_FIELD:
-        return parseSetField();
-      default:
-        assert(false);
-    }
-
-    return null;
-  }
-
-  /// (Constant (constant))
-  Constant parseConstant() {
-    tokens.consumeStart(CONSTANT);
-    tokens.consumeStart();
-    Constant result;
-    String tag = tokens.read();
-    switch (tag) {
-      case NULL:
-        result = new Constant(
-            new NullConstantExpression(new NullConstantValue()));
-        break;
-      case BOOL:
-        String value = tokens.read();
-        if (value == "true") {
-          result = new Constant(
-              new BoolConstantExpression(true, new TrueConstantValue()));
-        } else if (value == "false") {
-          result = new Constant(
-              new BoolConstantExpression(false, new FalseConstantValue()));
-        } else {
-          throw "Invalid Boolean value '$value'.";
-        }
-        break;
-      case STRING:
-        List<String> strings = <String>[];
-        do {
-          strings.add(tokens.read());
-        } while (tokens.current != ")");
-        String string = strings.join(" ");
-        assert(string.startsWith('"') && string.endsWith('"'));
-        String text = string.substring(1, string.length - 1);
-        StringConstantValue value = new StringConstantValue(
-            new LiteralDartString(text));
-        result = new Constant(new StringConstantExpression(text, value));
-        break;
-      case INT:
-        String value = tokens.read();
-        int intValue = int.parse(value, onError: (_) => null);
-        if (intValue == null) {
-          throw "Invalid int value 'value'.";
-        }
-        result = new Constant(new IntConstantExpression(
-            intValue, new IntConstantValue(intValue)));
-        break;
-      case DOUBLE:
-        String value = tokens.read();
-        double doubleValue = double.parse(value, (_) => null);
-        if (doubleValue == null) {
-          throw "Invalid double value '$value'.";
-        }
-        result = new Constant(new DoubleConstantExpression(
-            doubleValue, new DoubleConstantValue(doubleValue)));
-        break;
-      default:
-        throw "Unexpected constant tag '$tag'.";
-    }
-    tokens.consumeEnd();
-    tokens.consumeEnd();
-    return result;
-  }
-
-  /// (CreateFunction (definition))
-  CreateFunction parseCreateFunction() {
-    tokens.consumeStart(CREATE_FUNCTION);
-    FunctionDefinition def = parseFunctionDefinition();
-    tokens.consumeEnd();
-    return new CreateFunction(def);
-  }
-
-  MutableVariable addMutableVariable(String name) {
-    assert(!name2variable.containsKey(name));
-    MutableVariable variable = new MutableVariable(new DummyElement(name));
-    name2variable[name] = variable;
-    return variable;
-  }
-
-  /// (GetMutable name)
-  GetMutable parseGetMutable() {
-    tokens.consumeStart(GET_MUTABLE);
-    MutableVariable local = name2variable[tokens.read()];
-    tokens.consumeEnd();
-
-    return new GetMutable(local);
-  }
-
-  /// (LiteralList (values))
-  LiteralList parseLiteralList() {
-    tokens.consumeStart(LITERAL_LIST);
-    List<Primitive> values = parsePrimitiveList();
-    tokens.consumeEnd();
-    return new LiteralList(null, values);
-  }
-
-  /// (LiteralMap (keys) (values))
-  LiteralMap parseLiteralMap() {
-    tokens.consumeStart(LITERAL_MAP);
-
-    List<Primitive> keys   = parsePrimitiveList();
-    List<Primitive> values = parsePrimitiveList();
-
-    List<LiteralMapEntry> entries = <LiteralMapEntry>[];
-    for (int i = 0; i < keys.length; i++) {
-      entries.add(new LiteralMapEntry(keys[i], values[i]));
-    }
-
-    tokens.consumeEnd();
-    return new LiteralMap(null, entries);
-  }
-
-  /// (ReifyTypeVar type)
-  ReifyTypeVar parseReifyTypeVar() {
-    tokens.consumeStart(REIFY_TYPE_VAR);
-
-    TypeVariableElement type = new DummyElement(tokens.read());
-
-    tokens.consumeEnd();
-    return new ReifyTypeVar(type);
-  }
-
-  /// (GetStatic field)
-  GetStatic parseGetStatic() {
-    tokens.consumeStart(GET_STATIC);
-
-    Element field = new DummyElement(tokens.read());
-
-    tokens.consumeEnd();
-    return new GetStatic(field, null);
-  }
-
-  /// (GetField object field)
-  GetField parseGetField() {
-    tokens.consumeStart(GET_FIELD);
-
-    Primitive object = name2variable[tokens.read()];
-    Element field = new DummyElement(tokens.read());
-
-    tokens.consumeEnd();
-    return new GetField(object, field);
-  }
-
-  /// (SetField object field value)
-  SetField parseSetField() {
-    tokens.consumeStart(SET_FIELD);
-
-    Primitive object = name2variable[tokens.read()];
-    Element field = new DummyElement(tokens.read());
-    Primitive value = name2variable[tokens.read()];
-
-    tokens.consumeEnd();
-    return new SetField(object, field, value);
-  }
-}
diff --git a/tests/compiler/dart2js/backend_dart/test_helper.dart b/tests/compiler/dart2js/backend_dart/test_helper.dart
deleted file mode 100644
index 0eeb656..0000000
--- a/tests/compiler/dart2js/backend_dart/test_helper.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart_backend.test_helper;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/compiler.dart' as api;
-import 'package:compiler/src/compiler.dart';
-import '../../../../pkg/analyzer2dart/test/test_helper.dart';
-import '../compiler_helper.dart';
-
-/// Compiles the given dart code (which must include a 'main' function) and
-/// returns the compiler.
-Future<Compiler> compilerFor(String code,
-                             {api.CompilerOutputProvider outputProvider}) {
-  MockCompiler compiler = new MockCompiler.internal(
-      emitJavaScript: false,
-      enableMinification: false,
-      outputProvider: outputProvider);
-  compiler.diagnosticHandler = createHandler(compiler, code);
-  return compiler.init().then((_) {
-    compiler.parseScript(code);
-
-    Element element = compiler.mainApp.find('main');
-    if (element == null) return null;
-
-    compiler.mainFunction = element;
-    compiler.phase = Compiler.PHASE_RESOLVING;
-    compiler.backend.enqueueHelpers(compiler.enqueuer.resolution,
-                                    compiler.globalDependencies);
-    compiler.processQueue(compiler.enqueuer.resolution, element);
-    compiler.world.populate();
-    compiler.backend.onResolutionComplete();
-
-    compiler.irBuilder.buildNodes();
-
-    return compiler;
-  });
-}
-
-/// Test group using async_helper.
-asyncTester(Group group, RunTest runTest) {
-  asyncTest(() => Future.forEach(group.results, runTest));
-}
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index e365f3b..2c1684e 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -179,7 +179,7 @@
 
 Future compileSources(Map<String, String> sources,
                check(MockCompiler compiler)) {
-  Uri base = new Uri(scheme: 'source');
+  Uri base = new Uri(scheme: 'source', path: '/');
   Uri mainUri = base.resolve('main.dart');
   String mainCode = sources['main.dart'];
   Expect.isNotNull(mainCode, 'No source code found for "main.dart"');
diff --git a/tests/compiler/dart2js/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
index 49f3b51..3dd05ac 100644
--- a/tests/compiler/dart2js/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
@@ -61,6 +61,8 @@
     const ConstantData('identical(0, 1)',
                        const { const {} : 'BoolConstant(false)' }),
     const ConstantData('"a" "b"', const { const {} : 'StringConstant("ab")' }),
+    const ConstantData(r'"${null}"',
+        const { const {} : 'StringConstant("null")' }),
     const ConstantData('identical',
         const { const {} : 'FunctionConstant(identical)' }),
     const ConstantData('true ? 0 : 1', const { const {} : 'IntConstant(0)' }),
@@ -79,6 +81,9 @@
         const { const {} :
           'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
                                  'IntConstant(2): IntConstant(3)})' }),
+    const ConstantData('const <int, int>{0: 1, 0: 2}',
+        const { const {} :
+        'MapConstant(<int, int>{IntConstant(0): IntConstant(2)})' }),
     const ConstantData(
         'const bool.fromEnvironment("foo", defaultValue: false)',
         const { const {} : 'BoolConstant(false)',
diff --git a/tests/compiler/dart2js/cps_ir/README.md b/tests/compiler/dart2js/cps_ir/README.md
deleted file mode 100644
index 1106a72..0000000
--- a/tests/compiler/dart2js/cps_ir/README.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# 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
deleted file mode 100644
index 7e6129f..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_10_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 90e4293..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_11_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index a170a0a..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_12_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 262f833..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_13_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 5e081e0..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_14_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 32a89c7..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_15_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 7ec112f..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_16_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 41533c9..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_17_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index abda443..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_18_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 03d2e0d..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_19_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index cbd95ce..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 8421f29..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_20_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index d65f1d2..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_21_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index b6fff18..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_22_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 71083d4..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_23_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index ed56ade..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_24_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index d3aa3a8..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_25_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 348162f..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_26_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 545ed60..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_27_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 4777d3d..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_28_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 82dfbed..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 3fa5714..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index f254f71..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index d90713c..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 1a35cbe..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 6069711..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 082bb9b..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 49c5202..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_9_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 4b2600c..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_10_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index e8f6b2c..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_11_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 5a5810c..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_12_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index a72d96b..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_13_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9453955..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_14_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 3fcdc5d..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_15_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 6c55492..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_16_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 59f9881..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_17_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 89d6903..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9aaee58..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 1f2613c..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 5248eae..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index ae259b3..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 315b8ba..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index b3b060d..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 803d019..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 86963e3..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_9
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index f6cbe34..0000000
--- a/tests/compiler/dart2js/cps_ir/argument_refinement_num_9_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 3d6ab6f..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_10_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index eed3081..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_11_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index cbdbd19..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_12_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index e867b76..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_13_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 814bf20..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_14_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 72c06fe..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_15_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 559ad5c..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_16_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 711cb33..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index f5eb5b3..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 5476c1f..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9cd8d85..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index e38ea0b..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 0a79e84..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index b411ab8..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 03bc57c..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index dd02afb..0000000
--- a/tests/compiler/dart2js/cps_ir/basic_9_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index e5d99a8..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_10_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 6012079..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_11_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 4bf040d..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_12_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index f4c83b9..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_13_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index c5198e2..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_14_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index f78f7a9..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_15_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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_16_test.dart b/tests/compiler/dart2js/cps_ir/closures_16_test.dart
deleted file mode 100644
index 6b359ec..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_16_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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_16.dart;
-
-import 'runner.dart';
-
-main(args) {
-  runTest("closures_16.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
deleted file mode 100644
index 9eb7749..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index ff5b698..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index cb19e78..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 66142a4..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 5910347..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9616d62..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index a95b1b2..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 03b05f1..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 3cf10ca..0000000
--- a/tests/compiler/dart2js/cps_ir/closures_9_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index e765c1d..0000000
--- a/tests/compiler/dart2js/cps_ir/codeUnitAt_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9838b61..0000000
--- a/tests/compiler/dart2js/cps_ir/codeUnitAt_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index ee3d425..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_10_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 0b3002d..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_11_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 16442e3..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_12_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 084f2ef..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_13_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 41903ef..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_14_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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_15_test.dart b/tests/compiler/dart2js/cps_ir/constructor_15_test.dart
deleted file mode 100644
index d745e08..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_15_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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_15.dart;
-
-import 'runner.dart';
-
-main(args) {
-  runTest("constructor_15.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
deleted file mode 100644
index 1acf661..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 11fd0f8..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 46c02be..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 11a392b..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index f95c26b..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index c37314b..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 0aeca1c..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index b22a96d..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9fe1d90..0000000
--- a/tests/compiler/dart2js/cps_ir/constructor_9_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 3efea51..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 04ab770..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index c3cd858..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index b355d84..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 37ab62c..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 341be8e..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 3b9f94c..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9a64a8c..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 7328a45..0000000
--- a/tests/compiler/dart2js/cps_ir/control_flow_9_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index be268f4..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_1.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$sub$n(x, y);
-  P.print(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
deleted file mode 100644
index 9c4c3f3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_10.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$gt$n(x, y);
-  P.print(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
deleted file mode 100644
index 23f5fca..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_11.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$lt$n(x, y);
-  P.print(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
deleted file mode 100644
index 0fd94d2..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_12.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$ge$n(x, y);
-  P.print(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
deleted file mode 100644
index 481395c..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_13.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$le$n(x, y);
-  P.print(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
deleted file mode 100644
index 642f48b..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_14.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index aa6f727..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_15.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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
deleted file mode 100644
index 0ba4b75..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_16.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 1fb2867..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_17.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 0e73f85..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_18.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 5125dcb..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_19.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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);
-  if (typeof x !== "number")
-    return x.$div();
-  P.print(x / 2);
-  P.print(true);
-  P.print(typeof y === "number");
-  if (typeof y !== "number")
-    return H.iae(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
deleted file mode 100644
index 0de632e..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_2.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$div$n(x, y);
-  P.print(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
deleted file mode 100644
index 13b3053..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_20.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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);
-  if (typeof x !== "number")
-    return x.$div();
-  P.print(x / 2);
-  P.print(true);
-  P.print(typeof y === "number");
-  if (typeof y !== "number")
-    return H.iae(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
deleted file mode 100644
index 26cfc95..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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;
-  if (typeof x !== "number")
-    return x.$div();
-  P.print(x / 2);
-  P.print(true);
-  v0 = typeof y === "number";
-  P.print(v0);
-  if (!v0)
-    throw H.wrapException(H.argumentErrorValue(y));
-  P.print(x < y ? -1 : x > y ? 1 : x === y ? x === 0 ? 1 / x < 0 === (y === 0 ? 1 / y < 0 : y < 0) ? 0 : 1 / x < 0 ? -1 : 1 : 0 : isNaN(x) ? isNaN(y) ? 0 : 1 : -1);
-  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
deleted file mode 100644
index 3948378..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_22.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index e2e290d..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_23.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index f251917..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_24.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 9ebb55a..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_25.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 9294a75..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_26.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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
deleted file mode 100644
index 484f6a1..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_27.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index b5ab697..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_28.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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
deleted file mode 100644
index 5d7d8a8..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_3.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 43dfc17..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_4.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 049ef54..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_5.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 953fc10..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_6.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index cb58cd3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_7.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$and$n(x, y);
-  P.print((x & y) >>> 0);
-  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
deleted file mode 100644
index 7c0109d..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_8.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$or$n(x, y);
-  P.print((x | y) >>> 0);
-  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
deleted file mode 100644
index c1c6bec..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_9.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$xor$n(x, y);
-  P.print((x ^ y) >>> 0);
-  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
deleted file mode 100644
index be268f4..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_1.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$sub$n(x, y);
-  P.print(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
deleted file mode 100644
index 23f5fca..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_10.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$lt$n(x, y);
-  P.print(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
deleted file mode 100644
index 9c4c3f3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_11.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$gt$n(x, y);
-  P.print(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
deleted file mode 100644
index 481395c..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_12.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$le$n(x, y);
-  P.print(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
deleted file mode 100644
index 0fd94d2..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_13.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$ge$n(x, y);
-  P.print(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
deleted file mode 100644
index 642f48b..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_14.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 3ce06f4..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_15.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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
deleted file mode 100644
index 10c7792..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_16.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 4fa1574..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_17.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 0de632e..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_2.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$div$n(x, y);
-  P.print(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
deleted file mode 100644
index 5d7d8a8..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_3.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 43dfc17..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_4.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 049ef54..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_5.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 953fc10..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_6.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index cb58cd3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_7.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$and$n(x, y);
-  P.print((x & y) >>> 0);
-  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
deleted file mode 100644
index 7c0109d..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_8.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$or$n(x, y);
-  P.print((x | y) >>> 0);
-  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
deleted file mode 100644
index c1c6bec..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_num_9.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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");
-  if (typeof x !== "number" || typeof y !== "number")
-    return J.$xor$n(x, y);
-  P.print((x ^ y) >>> 0);
-  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
deleted file mode 100644
index f8384d4..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_1.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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__makeLiteral(["s", 1]);
-  P.print("()");
-  P.print("(true)");
-  P.print("(1)");
-  P.print("(" + H.S([1, 2, 3]) + ")");
-  P.print("(" + P.Maps_mapToString(P.LinkedHashMap__makeLiteral(["s", 1])) + ")");
-  P.print("(1)");
-  P.print("(" + H.S(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
deleted file mode 100644
index 745bc50..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_10.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Expectation for test: 
-// main() {
-//   print(new DateTime.now().isBefore(new DateTime.now()));
-// }
-
-function() {
-  var line = H.S(Date.now() < Date.now());
-  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
deleted file mode 100644
index 68995ca..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_11.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Expectation for test: 
-// foo() { print(42); }
-// main() { foo(); }
-
-function() {
-  if (typeof dartPrint == "function")
-    dartPrint("42");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("42");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("42");
-    print("42");
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_12.js b/tests/compiler/dart2js/cps_ir/expected/basic_12.js
deleted file mode 100644
index ac9e1d3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_12.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Expectation for test: 
-// var foo = 42;
-// main() { print(foo); }
-
-function() {
-  var line = H.S($.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/basic_13.js b/tests/compiler/dart2js/cps_ir/expected/basic_13.js
deleted file mode 100644
index e8db598..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_13.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Expectation for test: 
-// get foo { print(42); }
-// main() { foo; }
-
-function() {
-  if (typeof dartPrint == "function")
-    dartPrint("42");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("42");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("42");
-    print("42");
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_14.js b/tests/compiler/dart2js/cps_ir/expected/basic_14.js
deleted file mode 100644
index 068816d..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_14.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Expectation for test: 
-// var foo = 0;
-// main() { print(foo = 42); }
-
-function() {
-  $.foo = 42;
-  if (typeof dartPrint == "function")
-    dartPrint("42");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("42");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("42");
-    print("42");
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_15.js b/tests/compiler/dart2js/cps_ir/expected/basic_15.js
deleted file mode 100644
index 92ba7b0..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_15.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Expectation for test: 
-// set foo(x) { print(x); }
-// main() { foo = 42; }
-
-function() {
-  if (typeof dartPrint == "function")
-    dartPrint("42");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("42");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("42");
-    print("42");
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_16.js b/tests/compiler/dart2js/cps_ir/expected/basic_16.js
deleted file mode 100644
index 0442443..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_16.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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
deleted file mode 100644
index 3f579fc..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_2.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
deleted file mode 100644
index 3d8269f..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_3.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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
deleted file mode 100644
index 8ce632a..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_4.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Expectation for test: 
-// foo() { print(42); return 42; }
-// main() { return foo(); }
-
-function() {
-  if (typeof dartPrint == "function")
-    dartPrint("42");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("42");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("42");
-    print("42");
-  }
-  return 42;
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_5.js b/tests/compiler/dart2js/cps_ir/expected/basic_5.js
deleted file mode 100644
index 9027244..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_5.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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
deleted file mode 100644
index a6a2296..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_6.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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
deleted file mode 100644
index cd112ad..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_7.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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
deleted file mode 100644
index 1d8cccd..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_8.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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
deleted file mode 100644
index c23788a..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/basic_9.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Expectation for test: 
-// class C {}
-// main() {
-//   print(new C());
-// }
-
-function() {
-  var line = "Instance of '" + H.Primitives_objectTypeName(V.C$()) + "'";
-  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_1.js b/tests/compiler/dart2js/cps_ir/expected/closures_1.js
deleted file mode 100644
index e8cc7ab..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_1.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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
deleted file mode 100644
index 64e5e31..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_10.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Expectation for test: 
-// class A {
-//   a() => 1;
-//   b() => () => a();
-// }
-// main() {
-//   print(new A().b()());
-// }
-
-function() {
-  var line = H.S(V.A$().a$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
deleted file mode 100644
index e547d06..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_11.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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
deleted file mode 100644
index 5078169..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_12.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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
deleted file mode 100644
index 5a61827..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_13.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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
deleted file mode 100644
index 5c27c7b..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_14.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
deleted file mode 100644
index cf37dd2..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_15.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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(123);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_16.js b/tests/compiler/dart2js/cps_ir/expected/closures_16.js
deleted file mode 100644
index e589971..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_16.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Expectation for test: 
-// class Foo {
-//   get getter {
-//     print('getter');
-//     return (x) { try { return x; } finally { } };  // Inhibit inlining.
-//   }
-// }
-// main(x) {
-//   // Getter may or may not be inlined.
-//   var notTearOff = new Foo().getter;
-//   // Closure is not inlined.
-//   print(notTearOff(123));
-// }
-
-function(x) {
-  P.print(V.Foo$().get$getter().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
deleted file mode 100644
index b5ffeebd..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_2.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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
deleted file mode 100644
index 69425f1..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_3.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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
deleted file mode 100644
index 02027fe..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_4.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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
deleted file mode 100644
index 3c61ff5..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_5.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Expectation for test: 
-// main() {
-//   var x = 122;
-//   var a = () => x;
-//   x = x + 1;
-//   print(a());
-// }
-
-function() {
-  var line = H.S(122 + 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/closures_6.js b/tests/compiler/dart2js/cps_ir/expected/closures_6.js
deleted file mode 100644
index 3ff087a..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_6.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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
deleted file mode 100644
index 62f16ad..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_7.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Expectation for test: 
-// main() {
-//   var x = 122;
-//   var a = () {
-//     var y = x;
-//     return () => y;
-//   };
-//   x = x + 1;
-//   print(a()());
-// }
-
-function() {
-  var line = H.S(122 + 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/closures_8.js b/tests/compiler/dart2js/cps_ir/expected/closures_8.js
deleted file mode 100644
index 35d033f..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_8.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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
deleted file mode 100644
index c11aa2d..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/closures_9.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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
deleted file mode 100644
index 9043a3f..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_1.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Expectation for test: 
-// // Constant folding
-// main() {
-//   print('A'.codeUnitAt(0));
-// }
-
-function() {
-  if (typeof dartPrint == "function")
-    dartPrint("65");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("65");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("65");
-    print("65");
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
deleted file mode 100644
index 4fdd8a2..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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 sum = 0, i = 0;
-  for (; i < 3; sum += "ABC".charCodeAt(i), ++i)
-    ;
-  P.print(sum);
-  sum = 0;
-  for (i = 0; i < 5; 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
deleted file mode 100644
index 6afa3a3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_1.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 = H.S(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
deleted file mode 100644
index c2148d0..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_10.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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
deleted file mode 100644
index 3221867..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_11.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Expectation for test: 
-// class A {
-//   var x;
-//   A() : this.b(1);
-//   A.b(this.x);
-// }
-// main() {
-//   print(new A().x);
-// }
-
-function() {
-  var line = H.S(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
deleted file mode 100644
index d892327..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_12.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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
deleted file mode 100644
index a95670c..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_13.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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 line = "Instance of '" + H.Primitives_objectTypeName(new V.Foo(5)) + "'";
-  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_14.js b/tests/compiler/dart2js/cps_ir/expected/constructor_14.js
deleted file mode 100644
index fe479f9..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_14.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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_15.js b/tests/compiler/dart2js/cps_ir/expected/constructor_15.js
deleted file mode 100644
index 22c0973..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_15.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Expectation for test: 
-// // Method to test: generative_constructor(A#)
-// class A {
-//   var x, y, z;
-//   A(x, y) {
-//     this.x = x;
-//     this.y = y;
-//     this.z = this.x / 2;
-//   }
-// }
-// 
-// main() {
-//   print(new A(123, 'sdf').y);
-//   try {} finally {} // Do not inline into main.
-// }
-
-function(x, y) {
-  return new V.A(x, y, x / 2);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/constructor_2.js b/tests/compiler/dart2js/cps_ir/expected/constructor_2.js
deleted file mode 100644
index 94d3b4e..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_2.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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
deleted file mode 100644
index 0f14d28..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_3.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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
deleted file mode 100644
index 7253134..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_4.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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
deleted file mode 100644
index ed704e1..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_5.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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
deleted file mode 100644
index 66d5ae5..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_6.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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
deleted file mode 100644
index 8474ee4..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_7.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
deleted file mode 100644
index e4a2ea6..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_8.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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
deleted file mode 100644
index 6240573..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/constructor_9.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 line = H.S(H.createRuntimeType(H.runtimeTypeToString($T)));
-  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 H.setRuntimeTypeInfo(new V.C(), [$T]);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
deleted file mode 100644
index 7fd9aff..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Expectation for test: 
-// main() {
-//   while (true);
-// }
-
-function() {
-  for (;;)
-    ;
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
deleted file mode 100644
index 3cb9718..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Expectation for test: 
-// foo(a) { try { print(a); } finally { return a; } }
-// 
-// main() {
-//   while (true) {
-//     l: while (true) {
-//       while (foo(true)) {
-//         if (foo(false)) break l;
-//       }
-//       print(1);
-//     }
-//     print(2);
-//   }
-// }
-
-function() {
-  L0:
-    for (;;)
-      for (;;) {
-        while (V.foo(true))
-          if (V.foo(false)) {
-            P.print(2);
-            continue L0;
-          }
-        P.print(1);
-      }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
deleted file mode 100644
index f7c0900..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Expectation for test: 
-// foo(a) { try { print(a); } finally { 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);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
deleted file mode 100644
index dae4cc7..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Expectation for test: 
-// foo(a) { try { print(a); } finally { 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);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
deleted file mode 100644
index 0f28201..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Expectation for test: 
-// foo(a) { try { print(a); } finally { 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);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js
deleted file mode 100644
index 4530b7e..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_6.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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
deleted file mode 100644
index e4f20e1..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_7.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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
deleted file mode 100644
index bcb67d3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_8.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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
deleted file mode 100644
index 637d654..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_9.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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
deleted file mode 100644
index 5e14c5c..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/gvn_1.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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 = H.S(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
deleted file mode 100644
index a8df9d1..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/interceptors_1.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Expectation for test: 
-// main() {
-//   var g = 1;
-// 
-//   var x = g + 3;
-//   print(x);
-// }
-
-function() {
-  if (typeof dartPrint == "function")
-    dartPrint("4");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("4");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("4");
-    print("4");
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js b/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js
deleted file mode 100644
index fdb0701..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/interceptors_2.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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
deleted file mode 100644
index d70ebf8..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/literals_1.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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__makeEmpty());
-  P.print(P.LinkedHashMap__makeLiteral([1, 2]));
-  P.print(P.LinkedHashMap__makeLiteral([[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
deleted file mode 100644
index 71a1da5..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Expectation for test: 
-// // Method to test: function(foo)
-// foo(a, b) => ((a & 0xff0000) >> 1) & b;
-// main() {
-//   print(foo.toString());
-//   print(foo(123, 234));
-//   print(foo(0, 2));
-// }
-
-function(a, b) {
-  return (a & 16711680) >>> 1 & b;
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_2.js b/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
deleted file mode 100644
index 7858649..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Expectation for test: 
-// // Method to test: function(foo)
-// foo(a) => ~a;
-// main() {
-//   print(foo.toString());
-//   print(foo(1));
-//   print(foo(10));
-// }
-
-function(a) {
-  return ~a >>> 0;
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_3.js b/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
deleted file mode 100644
index 0ec8440..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Expectation for test: 
-// // Method to test: function(foo)
-// import 'package:expect/expect.dart';
-// 
-// @NoInline() foo(a) => a % 13;
-// 
-// main() {
-//   print(foo(5));
-//   print(foo(-100));
-// }
-
-function(a) {
-  return C.JSInt_methods.$mod(a, 13);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_4.js b/tests/compiler/dart2js/cps_ir/expected/operators2_4.js
deleted file mode 100644
index 4f5c0f0..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_4.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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
deleted file mode 100644
index a07d368..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_5.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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
deleted file mode 100644
index d9cfe87..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_6.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Expectation for test: 
-// // Method to test: function(foo)
-// import 'package:expect/expect.dart';
-// 
-// @NoInline() foo(a) => a ~/ 13;
-// 
-// main() {
-//   print(foo(5));
-//   print(foo(-100));
-// }
-
-function(a) {
-  return C.JSInt_methods.$tdiv(a, 13);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_7.js b/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
deleted file mode 100644
index 403b831..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Expectation for test: 
-// // Method to test: function(foo)
-// import 'package:expect/expect.dart';
-// 
-// @NoInline() foo(a) => a ~/ 13;
-// 
-// main() {
-//   print(foo.toString());
-//   print(foo(5));
-//   print(foo(100));
-// }
-
-function(a) {
-  return a / 13 | 0;
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_8.js b/tests/compiler/dart2js/cps_ir/expected/operators2_8.js
deleted file mode 100644
index b322ba0..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_8.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Expectation for test: 
-// // Method to test: function(foo)
-// import 'package:expect/expect.dart';
-// 
-// @NoInline() foo(a) => a ~/ 13;
-// 
-// main() {
-//   print(foo(5));
-//   print(foo(8000000000));
-// }
-
-function(a) {
-  return C.JSInt_methods.$tdiv(a, 13);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_1.js b/tests/compiler/dart2js/cps_ir/expected/operators_1.js
deleted file mode 100644
index dd0ddca..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_1.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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
deleted file mode 100644
index 4b6236b..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_2.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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
deleted file mode 100644
index 525b95f..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_3.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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
deleted file mode 100644
index 65acae6..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_4.js
+++ /dev/null
@@ -1,24 +0,0 @@
-// Expectation for test: 
-// var x = 1;
-// get foo => ++x > 10;
-// main() { print(foo && foo); }
-
-function() {
-  var v0 = $.x + 1, line;
-  $.x = v0;
-  if (v0 > 10) {
-    $.x = v0 = $.x + 1;
-    v0 = v0 > 10;
-  } else
-    v0 = false;
-  line = H.S(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
deleted file mode 100644
index df02418..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_5.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// Expectation for test: 
-// var x = 1;
-// get foo => ++x > 10;
-// main() { print(foo || foo); }
-
-function() {
-  var v0 = $.x + 1, line;
-  $.x = v0;
-  if (v0 > 10)
-    v0 = true;
-  else {
-    $.x = v0 = $.x + 1;
-    v0 = v0 > 10;
-  }
-  line = H.S(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_6.js b/tests/compiler/dart2js/cps_ir/expected/operators_6.js
deleted file mode 100644
index 10e71da..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_6.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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
deleted file mode 100644
index 9b278bf..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_7.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Expectation for test: 
-// class Foo {
-//   operator[]=(index, value) {
-//     print(value);
-//   }
-// }
-// main() {
-//   var foo = new Foo();
-//   foo[5] = 6;
-// }
-
-function() {
-  V.Foo$();
-  if (typeof dartPrint == "function")
-    dartPrint("6");
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log("6");
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String("6");
-    print("6");
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_8.js b/tests/compiler/dart2js/cps_ir/expected/operators_8.js
deleted file mode 100644
index 908c5f3..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/operators_8.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Expectation for test: 
-// main() {
-//   var list = [1, 2, 3];
-//   list[1] = 6;
-//   print(list);
-// }
-
-function() {
-  var list = [1, 2, 3], line;
-  list[1] = 6;
-  line = H.S(list);
-  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/optimize_indexers.js b/tests/compiler/dart2js/cps_ir/expected/optimize_indexers.js
deleted file mode 100644
index 1b8c351..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/optimize_indexers.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// Expectation for test: 
-// // Method to test: function(test)
-// import 'package:expect/expect.dart';
-// 
-// // This example illustrates a case we wish to do better in terms of inlining and
-// // code generation.
-// //
-// // Naively this function would be compiled without inlining Wrapper.[],
-// // JSArray.[] and Wrapper.[]= because:
-// // JSArray.[] is too big (14 nodes)
-// // Wrapper.[] is too big if we force inlining of JSArray (15 nodes)
-// // Wrapper.[]= is even bigger (46 nodes)
-// //
-// // We now do specialization of [] and []= by adding guards and injecting builtin
-// // operators. This made it possible to inline []. We still don't see []= inlined
-// // yet, that might require that we improve the inlining counting heuristics a
-// // bit.
-// @NoInline()
-// test(data, x) {
-//   data[x + 1] = data[x];
-// }
-// 
-// main() {
-//   var wrapper = new Wrapper();
-//   wrapper[33] = wrapper[1]; // make Wrapper.[]= and [] used more than once.
-//   print(test(new Wrapper(), int.parse('2')));
-// }
-// 
-// class Wrapper {
-//   final List arr = <bool>[true, false, false, true];
-//   operator[](int i) => this.arr[i];
-//   operator[]=(int i, v) {
-//     if (i > arr.length - 1) arr.length = i + 1;
-//     return arr[i] = v;
-//   }
-// }
-
-function(data, x) {
-  var v0 = J.$add$ns(x, 1), v1 = data.arr;
-  if (x >>> 0 !== x || x >= v1.length)
-    return H.ioore(v1, x);
-  data.$indexSet(0, v0, v1[x]);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/redundant_condition.js b/tests/compiler/dart2js/cps_ir/expected/redundant_condition.js
deleted file mode 100644
index 211aec6..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/redundant_condition.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Expectation for test: 
-// // This test illustrates an opportunity to remove redundant code by
-// // propagating inforamtion after inlining.
-// //
-// // The code below inlines `foo` twice, but we don't propagate that we already
-// // know from the first `foo` that `a` is an int, so the second check can be
-// // removed entirely.
-// 
-// import 'package:expect/expect.dart';
-// 
-// main() {
-//   var a = nextNumber();
-//   action(foo(a));
-//   action(foo(a));
-// }
-// 
-// foo(x) {
-//   if (x is! int) throw "error 1";
-//   return x + 5 % 100;
-// }
-// 
-// @NoInline() @AssumeDynamic()
-// nextNumber() => int.parse('33');
-// 
-// @NoInline()
-// action(v) => print(v);
-
-function() {
-  var a = V.nextNumber();
-  if (typeof a !== "number" || Math.floor(a) !== a)
-    throw H.wrapException("error 1");
-  a += 5;
-  V.action(a);
-  V.action(a);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js b/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js
deleted file mode 100644
index 914008d..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/runtime_types_1.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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
deleted file mode 100644
index d22895f..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/runtime_types_2.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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
deleted file mode 100644
index 435bb62..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/runtime_types_3.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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
deleted file mode 100644
index 823dbe9..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/runtime_types_4.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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
deleted file mode 100644
index cc601dd..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Expectation for test: 
-// class Base {
-//   m(x) {
-//     try { print(x+1); } finally { }
-//   }
-// }
-// class Sub extends Base {
-//   m(x) => super.m(x+10);
-// }
-// main() {
-//   new Sub().m(100);
-// }
-
-function() {
-  var v0 = V.Sub$();
-  V.Base.prototype.m$1.call(v0, 110);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_2.js b/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
deleted file mode 100644
index 27f6c2b..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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, 10001);
-}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_3.js b/tests/compiler/dart2js/cps_ir/expected/supercall_3.js
deleted file mode 100644
index f45afaf..0000000
--- a/tests/compiler/dart2js/cps_ir/expected/supercall_3.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 = H.S(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
deleted file mode 100644
index e341e5d..0000000
--- a/tests/compiler/dart2js/cps_ir/gvn_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index e807927..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_1.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 85143eb..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_10.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index eca7811..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_11.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 7ad1e67..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_12.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 6083767..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_13.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 09c8e76..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_14.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 5724188..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_15.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index f7655f4..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_16.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 20dd689..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_17.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index aae68b8..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_18.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index a61936e..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_19.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 2021ca9..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_2.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index d8a5b4d..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_20.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index ae28a0e..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_21.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 988edd7..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_22.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c727aa8..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_23.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 1b2aef6..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_24.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 740bb92..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_25.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index dfdd56b..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_26.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index b53d2df..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_27.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index cbea9617..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_28.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-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
deleted file mode 100644
index 8353ddf..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_3.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 958363a..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_4.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c46235b..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_5.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 461da84..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_6.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c5f7d72..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_7.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 9aef9e2..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_8.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 22266c7..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_9.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index e807927..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_1.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index eca7811..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_10.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 85143eb..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_11.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 6083767..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_12.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 7ad1e67..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_13.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 09c8e76..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_14.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 227e62e..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_15.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index c757d08..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_16.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 9dd57c3..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_17.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 2021ca9..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_2.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 8353ddf..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_3.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 958363a..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_4.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c46235b..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_5.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 461da84..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_6.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c5f7d72..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_7.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 9aef9e2..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_8.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 22266c7..0000000
--- a/tests/compiler/dart2js/cps_ir/input/argument_refinement_num_9.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index ee77081..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_1.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-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
deleted file mode 100644
index e5a56a0..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_10.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 34c8802..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_11.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index d48fb05..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_12.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 3582183..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_13.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index f39e531..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_14.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 5ecc7ac..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_15.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 749ce68..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_16.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 6305610..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_2.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 95ffd22..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_3.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-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
deleted file mode 100644
index 1e74c32..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_4.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index bae895a..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_5.dart
+++ /dev/null
@@ -1 +0,0 @@
-main() {}
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_6.dart b/tests/compiler/dart2js/cps_ir/input/basic_6.dart
deleted file mode 100644
index f55f628..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_6.dart
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 98b304d..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_7.dart
+++ /dev/null
@@ -1 +0,0 @@
-main() { return; }
diff --git a/tests/compiler/dart2js/cps_ir/input/basic_8.dart b/tests/compiler/dart2js/cps_ir/input/basic_8.dart
deleted file mode 100644
index e6ebb66..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_8.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 15a7643..0000000
--- a/tests/compiler/dart2js/cps_ir/input/basic_9.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index f47a0a0..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_1.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 542d012..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_10.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index cd8e049..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_11.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 9e787fa..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_12.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 9994ca3..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_13.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 5ef8e6c..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_14.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index 55e1263..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_15.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-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_16.dart b/tests/compiler/dart2js/cps_ir/input/closures_16.dart
deleted file mode 100644
index 0d57270..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_16.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-class Foo {
-  get getter {
-    print('getter');
-    return (x) { try { return x; } finally { } };  // Inhibit inlining.
-  }
-}
-main(x) {
-  // Getter may or may not be inlined.
-  var notTearOff = new Foo().getter;
-  // Closure is not inlined.
-  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
deleted file mode 100644
index 7c8ad36..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_2.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 6e4f5d9..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_3.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index e6be22c..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_4.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 3e35ec0..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_5.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index e9ff65b..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_6.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 05087ca..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_7.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index 2b6e8c5..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_8.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 185576a..0000000
--- a/tests/compiler/dart2js/cps_ir/input/closures_9.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index c39bc74..0000000
--- a/tests/compiler/dart2js/cps_ir/input/codeUnitAt_1.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-// 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
deleted file mode 100644
index a26c359..0000000
--- a/tests/compiler/dart2js/cps_ir/input/codeUnitAt_2.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// 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
deleted file mode 100644
index 1cc265a..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_1.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 1e3dddc..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_10.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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
deleted file mode 100644
index c4ee04c..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_11.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index efafb99..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_12.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index dcba070..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_13.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index b22bbcb..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_14.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-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_15.dart b/tests/compiler/dart2js/cps_ir/input/constructor_15.dart
deleted file mode 100644
index 898b04f..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_15.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Method to test: generative_constructor(A#)
-class A {
-  var x, y, z;
-  A(x, y) {
-    this.x = x;
-    this.y = y;
-    this.z = this.x / 2;
-  }
-}
-
-main() {
-  print(new A(123, 'sdf').y);
-  try {} finally {} // Do not inline into main.
-}
diff --git a/tests/compiler/dart2js/cps_ir/input/constructor_2.dart b/tests/compiler/dart2js/cps_ir/input/constructor_2.dart
deleted file mode 100644
index 23ac512..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_2.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index 7a532a3..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_3.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-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
deleted file mode 100644
index 5f14854..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_4.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-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
deleted file mode 100644
index f615668..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_5.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-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
deleted file mode 100644
index f1c6b51..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_6.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-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
deleted file mode 100644
index 32af53c..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_7.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 3e72ab1..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_8.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index fe8dfbf..0000000
--- a/tests/compiler/dart2js/cps_ir/input/constructor_9.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// 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
deleted file mode 100644
index 72e7e7c..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_1.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index a7baf52..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-foo(a) { try { print(a); } finally { 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
deleted file mode 100644
index 8335da4..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-foo(a) { try { print(a); } finally { 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
deleted file mode 100644
index dd9fa9c..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-foo(a) { try { print(a); } finally { 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
deleted file mode 100644
index ee75818..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-foo(a) { try { print(a); } finally { 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
deleted file mode 100644
index 58550fe..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_6.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 66709ff..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_7.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 62c6fed..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_8.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 7e59e5a..0000000
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_9.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 4953cb9..0000000
--- a/tests/compiler/dart2js/cps_ir/input/gvn_1.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-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
deleted file mode 100644
index 6363521..0000000
--- a/tests/compiler/dart2js/cps_ir/input/interceptors_1.dart
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 7853486..0000000
--- a/tests/compiler/dart2js/cps_ir/input/interceptors_2.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index a5d7294..0000000
--- a/tests/compiler/dart2js/cps_ir/input/literals_1.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index 38b8f4f..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Method to test: function(foo)
-foo(a, b) => ((a & 0xff0000) >> 1) & b;
-main() {
-  print(foo.toString());
-  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
deleted file mode 100644
index f38e967..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Method to test: function(foo)
-foo(a) => ~a;
-main() {
-  print(foo.toString());
-  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
deleted file mode 100644
index 2cd9a53..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_3.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Method to test: function(foo)
-import 'package:expect/expect.dart';
-
-@NoInline() 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
deleted file mode 100644
index b9f5be2..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_4.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 3ece837..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_5.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 88bd137..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_6.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Method to test: function(foo)
-import 'package:expect/expect.dart';
-
-@NoInline() 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
deleted file mode 100644
index f8fe827..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Method to test: function(foo)
-import 'package:expect/expect.dart';
-
-@NoInline() foo(a) => a ~/ 13;
-
-main() {
-  print(foo.toString());
-  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
deleted file mode 100644
index ec9b8b3..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators2_8.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Method to test: function(foo)
-import 'package:expect/expect.dart';
-
-@NoInline() 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
deleted file mode 100644
index 52e587e..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_1.dart
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c9049ed..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_2.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 42ceb0e..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_3.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 3f07752..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_4.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 98756b6..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_5.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 36e7d9f..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_6.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-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
deleted file mode 100644
index 8838126..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_7.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c5b66d3..0000000
--- a/tests/compiler/dart2js/cps_ir/input/operators_8.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-main() {
-  var list = [1, 2, 3];
-  list[1] = 6;
-  print(list);
-}
diff --git a/tests/compiler/dart2js/cps_ir/input/optimize_indexers.dart b/tests/compiler/dart2js/cps_ir/input/optimize_indexers.dart
deleted file mode 100644
index 8150653..0000000
--- a/tests/compiler/dart2js/cps_ir/input/optimize_indexers.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Method to test: function(test)
-import 'package:expect/expect.dart';
-
-// This example illustrates a case we wish to do better in terms of inlining and
-// code generation.
-//
-// Naively this function would be compiled without inlining Wrapper.[],
-// JSArray.[] and Wrapper.[]= because:
-// JSArray.[] is too big (14 nodes)
-// Wrapper.[] is too big if we force inlining of JSArray (15 nodes)
-// Wrapper.[]= is even bigger (46 nodes)
-//
-// We now do specialization of [] and []= by adding guards and injecting builtin
-// operators. This made it possible to inline []. We still don't see []= inlined
-// yet, that might require that we improve the inlining counting heuristics a
-// bit.
-@NoInline()
-test(data, x) {
-  data[x + 1] = data[x];
-}
-
-main() {
-  var wrapper = new Wrapper();
-  wrapper[33] = wrapper[1]; // make Wrapper.[]= and [] used more than once.
-  print(test(new Wrapper(), int.parse('2')));
-}
-
-class Wrapper {
-  final List arr = <bool>[true, false, false, true];
-  operator[](int i) => this.arr[i];
-  operator[]=(int i, v) {
-    if (i > arr.length - 1) arr.length = i + 1;
-    return arr[i] = v;
-  }
-}
diff --git a/tests/compiler/dart2js/cps_ir/input/redundant_condition.dart b/tests/compiler/dart2js/cps_ir/input/redundant_condition.dart
deleted file mode 100644
index 913dfc5..0000000
--- a/tests/compiler/dart2js/cps_ir/input/redundant_condition.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// This test illustrates an opportunity to remove redundant code by
-// propagating inforamtion after inlining.
-//
-// The code below inlines `foo` twice, but we don't propagate that we already
-// know from the first `foo` that `a` is an int, so the second check can be
-// removed entirely.
-
-import 'package:expect/expect.dart';
-
-main() {
-  var a = nextNumber();
-  action(foo(a));
-  action(foo(a));
-}
-
-foo(x) {
-  if (x is! int) throw "error 1";
-  return x + 5 % 100;
-}
-
-@NoInline() @AssumeDynamic()
-nextNumber() => int.parse('33');
-
-@NoInline()
-action(v) => print(v);
diff --git a/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart b/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart
deleted file mode 100644
index f67e4d3a..0000000
--- a/tests/compiler/dart2js/cps_ir/input/runtime_types_1.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index a225509..0000000
--- a/tests/compiler/dart2js/cps_ir/input/runtime_types_2.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index c9253bb..0000000
--- a/tests/compiler/dart2js/cps_ir/input/runtime_types_3.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index f45e59c..0000000
--- a/tests/compiler/dart2js/cps_ir/input/runtime_types_4.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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
deleted file mode 100644
index 0ac95c8d..0000000
--- a/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-class Base {
-  m(x) {
-    try { print(x+1); } finally { }
-  }
-}
-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
deleted file mode 100644
index 1a2f726..0000000
--- a/tests/compiler/dart2js/cps_ir/input/supercall_2.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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
deleted file mode 100644
index dd2edfc..0000000
--- a/tests/compiler/dart2js/cps_ir/input/supercall_3.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 98d813a..0000000
--- a/tests/compiler/dart2js/cps_ir/interceptors_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 2562d63..0000000
--- a/tests/compiler/dart2js/cps_ir/interceptors_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 86e1f1d5..0000000
--- a/tests/compiler/dart2js/cps_ir/literals_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index acf42c2..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 75f6bb7..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 7fc2f50..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9315168..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 03544c1..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index e11bd8a..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 13480a4..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index d39aa5f..0000000
--- a/tests/compiler/dart2js/cps_ir/operators2_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9e457ac..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 99dd439..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 57ebc5a..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index c7fed55..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index c412522..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_5_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 01246e2..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_6_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 2864e6f..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_7_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 6c2d67c..0000000
--- a/tests/compiler/dart2js/cps_ir/operators_8_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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/optimize_indexers_test.dart b/tests/compiler/dart2js/cps_ir/optimize_indexers_test.dart
deleted file mode 100644
index eaf0b4a..0000000
--- a/tests/compiler/dart2js/cps_ir/optimize_indexers_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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.optimize_indexers.dart;
-
-import 'runner.dart';
-
-main(args) {
-  runTest("optimize_indexers.dart", update: args.length > 0 && args[0] == "update");
-}
diff --git a/tests/compiler/dart2js/cps_ir/redundant_condition_test.dart b/tests/compiler/dart2js/cps_ir/redundant_condition_test.dart
deleted file mode 100644
index e97e0ac..0000000
--- a/tests/compiler/dart2js/cps_ir/redundant_condition_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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.redundant_condition.dart;
-
-import 'runner.dart';
-
-main(args) {
-  runTest("redundant_condition.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
deleted file mode 100644
index 9f76482..0000000
--- a/tests/compiler/dart2js/cps_ir/runner.dart
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// 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 = '';
-  if (expectedFile.existsSync()) {
-    expected = expectedFile.readAsStringSync()
-      .replaceAll(new RegExp('^//.*\n', multiLine: true), '')
-      .trim();
-  }
-
-  var match = elementNameRegExp.firstMatch(source);
-  var elementName = match?.group(1);
-
-  Map files = {
-      TEST_MAIN_FILE: source,
-      'package:expect/expect.dart': '''
-          class NoInline {
-            const NoInline();
-          }
-          class TrustTypeAnnotations {
-            const TrustTypeAnnotations();
-          }
-          class AssumeDynamic {
-            const AssumeDynamic();
-          }
-       ''',
-   };
-  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) {
-        found = elementName == null
-            ? _getCodeForMain(compiler)
-            : _getCodeForMethod(compiler, elementName);
-      }
-    } 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) {
-        // 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.
-        String comment = source.trim().replaceAll('\n', '\n// ');
-        expectedFile.writeAsStringSync('// Expectation for test: \n'
-            '// ${comment}\n\n${found}\n');
-        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\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);
-}
-
-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);
-}
diff --git a/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart b/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart
deleted file mode 100644
index f5336f1..0000000
--- a/tests/compiler/dart2js/cps_ir/runtime_types_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 978f612..0000000
--- a/tests/compiler/dart2js/cps_ir/runtime_types_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 43a3349..0000000
--- a/tests/compiler/dart2js/cps_ir/runtime_types_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index eaf7937..0000000
--- a/tests/compiler/dart2js/cps_ir/runtime_types_4_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index caf3030..0000000
--- a/tests/compiler/dart2js/cps_ir/supercall_1_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 6f40662..0000000
--- a/tests/compiler/dart2js/cps_ir/supercall_2_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index 9b96977..0000000
--- a/tests/compiler/dart2js/cps_ir/supercall_3_test.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// ---- 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
deleted file mode 100644
index a9508a4..0000000
--- a/tests/compiler/dart2js/cps_ir/up_to_date_test.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// 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
deleted file mode 100644
index 59c0bc3..0000000
--- a/tests/compiler/dart2js/cps_ir/update_all.dart
+++ /dev/null
@@ -1,146 +0,0 @@
-// ---- 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_16.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_15.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('optimize_indexers.dart', update: true);
-  runTest('redundant_condition.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 d4ef503..4f4da85 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -37,20 +37,8 @@
 patch_test/bug: RuntimeError # Issue 21132
 
 quarantined/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,
-# but for now they are disabled.
-backend_dart/end2end_test: Skip
-backend_dart/sexpr2_test: Skip
-backend_dart/sexpr_test: Skip
-backend_dart/opt_constprop_test: Skip
-backend_dart/opt_shrinking_test: Skip
-backend_dart/opt_redundant_phi_test: Skip
 
 # Source information is not correct due to inlining.
-js_backend_cps_ir_source_information_test: Fail
 sourcemaps/source_mapping_operators_test: Pass, Slow
 sourcemaps/source_mapping_invokes_test: Pass, Slow
 
@@ -60,6 +48,7 @@
 
 [ $unchecked ]
 exit_code_test: Skip # This tests requires checked mode.
+serialization*: Slow, Pass
 
 [ $checked ]
 analyze_dart2js_helpers_test: Pass, Slow
@@ -75,6 +64,7 @@
 serialization*: Slow, Pass
 uri_retention_test: Pass, Slow
 value_range_test: Pass, Slow
+jsinterop/world_test: Pass, Slow
 
 [ $mode == debug ]
 check_elements_invariants_test: Skip # Slow and only needs to be run in one
diff --git a/tests/compiler/dart2js/dart2js_batch_test.dart b/tests/compiler/dart2js/dart2js_batch_test.dart
index 04b3ad6..55f8ca7 100644
--- a/tests/compiler/dart2js/dart2js_batch_test.dart
+++ b/tests/compiler/dart2js/dart2js_batch_test.dart
@@ -10,6 +10,8 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 
+import 'launch_helper.dart' show dart2JsCommand;
+
 var tmpDir;
 
 copyDirectory(Directory sourceDir, Directory destinationDir) {
@@ -51,12 +53,11 @@
 }
 
 Future launchDart2Js(_) {
-  String ext = Platform.isWindows ? '.bat' : '';
-  String command =
-      path.normalize(path.join(path.fromUri(Platform.script),
-                    '../../../../sdk/bin/dart2js${ext}'));
-  print("Running '$command --batch' from '${tmpDir}'.");
-  return Process.start(command, ['--batch'], workingDirectory: tmpDir.path);
+  return Process.start(
+      // Use an absolute path because we are changing the cwd below.
+      path.fromUri(Uri.base.resolve(Platform.executable)),
+      dart2JsCommand(['--batch']),
+      workingDirectory: tmpDir.path);
 }
 
 Future runTests(Process process) {
diff --git a/tests/compiler/dart2js/elide_callthrough_stub_test.dart b/tests/compiler/dart2js/elide_callthrough_stub_test.dart
new file mode 100644
index 0000000..bdb9667
--- /dev/null
+++ b/tests/compiler/dart2js/elide_callthrough_stub_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.
+
+// Check that calls through fields elide the call-through stub.  This
+// optimization is done by the simplifier, so inlining does not need to be
+// enabled.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'compiler_helper.dart';
+
+const String TEST1 = r'''
+class W {
+  final Function _fun;
+  W(this._fun);
+  foo(zzz) => _fun(zzz);   // this._fun$1(zzz) -->  this._fun.call$1(zzz)
+}
+add1(x) => x + 1;
+main() {
+  var w = new W(add1);
+  var x = w.foo(42);
+}
+''';
+
+const String TEST2 = r'''
+class W {
+  final Function __fun;
+  Function get _fun => __fun;
+  W(this.__fun);
+  foo(zzz) => _fun(zzz);   // this._fun$1(zzz) stays same.
+}
+add1(x) => x + 1;
+main() {
+  var w = new W(add1);
+  var x = w.foo(42);
+}
+''';
+
+main() {
+  asyncTest(() => compileAll(TEST1).then((generated) {
+    // Direct call through field.
+    Expect.isTrue(generated.contains(r'this._fun.call$1(zzz)'));
+    // No stub.
+    Expect.isFalse(generated.contains(r'_fun$1:'));
+    // No call to stub.
+    Expect.isFalse(generated.contains(r'_fun$1('));
+  }));
+
+  asyncTest(() => compileAll(TEST2).then((generated) {
+    // No call through field.
+    Expect.isFalse(generated.contains(r'this._fun.call$1(zzz)'));
+    // Call through stub.
+    Expect.isTrue(generated.contains(r'this._fun$1(zzz)'));
+    // Stub is generated.
+    Expect.isTrue(generated.contains(r'_fun$1:'));
+    // Call through getter (inside stub).
+    Expect.isTrue(generated.contains(r'get$_fun().call$1'));
+  }));
+}
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index ff419c7..bf3cdeb 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -150,10 +150,15 @@
 }
 
 class TestResolver extends ResolverTask {
-  TestResolver(TestCompiler compiler, ConstantCompiler constantCompiler)
-      : super(compiler, constantCompiler);
+  final TestCompiler compiler;
 
-  TestCompiler get compiler => super.compiler;
+  TestResolver(TestCompiler compiler, ConstantCompiler constantCompiler)
+      : this.compiler = compiler,
+        super(
+            compiler.resolution,
+            constantCompiler,
+            compiler.world,
+            compiler.measurer);
 
   void computeClassMembers(ClassElement element) {
     compiler.test('ResolverTask.computeClassMembers');
diff --git a/tests/compiler/dart2js/generate_code_with_compile_time_errors_test.dart b/tests/compiler/dart2js/generate_code_with_compile_time_errors_test.dart
index d2b29b0..a1814d7 100644
--- a/tests/compiler/dart2js/generate_code_with_compile_time_errors_test.dart
+++ b/tests/compiler/dart2js/generate_code_with_compile_time_errors_test.dart
@@ -10,7 +10,6 @@
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/dart_backend/dart_backend.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
 import 'memory_compiler.dart';
 import 'output_collector.dart';
@@ -53,14 +52,8 @@
       collector.hints.isNotEmpty,
       "Unexpected hints: ${collector.warnings}");
 
-  bool isCodeGenerated;
-  if (options.contains('--output-type=dart')) {
-    DartBackend backend = compiler.backend;
-    isCodeGenerated = backend.outputter.libraryInfo != null;
-  } else {
-    JavaScriptBackend backend = compiler.backend;
-    isCodeGenerated = backend.generatedCode.isNotEmpty;
-  }
+  JavaScriptBackend backend = compiler.backend;
+  bool isCodeGenerated = backend.generatedCode.isNotEmpty;
   Expect.equals(
       expectedCodeGenerated,
       isCodeGenerated,
@@ -93,47 +86,5 @@
        ['--generate-code-with-compile-time-errors', '--test-mode'],
        expectedCodeGenerated: true,
        expectedOutput: false);
-
-    await test(
-       ['--use-cps-ir'],
-       expectedCodeGenerated: false,
-       expectedOutput: false);
-    await test(
-       ['--use-cps-ir', '--test-mode'],
-       expectedCodeGenerated: false,
-       expectedOutput: false);
-    await test(
-       ['--use-cps-ir', '--generate-code-with-compile-time-errors'],
-       expectedCodeGenerated: false,
-       expectedOutput: false,
-       expectHint: true);
-    await test(
-       ['--use-cps-ir',
-        '--generate-code-with-compile-time-errors',
-        '--test-mode'],
-       expectedCodeGenerated: false,
-       expectedOutput: false,
-       expectHint: true);
-
-    await test(
-       ['--output-type=dart'],
-       expectedCodeGenerated: false,
-       expectedOutput: false);
-    await test(
-       ['--output-type=dart', '--test-mode'],
-       expectedCodeGenerated: false,
-       expectedOutput: false);
-    await test(
-       ['--output-type=dart', '--generate-code-with-compile-time-errors'],
-       expectedCodeGenerated: false,
-       expectedOutput: false,
-       expectHint: true);
-    await test(
-       ['--output-type=dart',
-        '--generate-code-with-compile-time-errors',
-        '--test-mode'],
-       expectedCodeGenerated: false,
-       expectedOutput: false,
-       expectHint: true);
   });
 }
diff --git a/tests/compiler/dart2js/inference_stats_test.dart b/tests/compiler/dart2js/inference_stats_test.dart
deleted file mode 100644
index a85ca39..0000000
--- a/tests/compiler/dart2js/inference_stats_test.dart
+++ /dev/null
@@ -1,340 +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.
-// SharedOptions=-Dsend_stats=true
-
-/// Tests that we compute send metrics correctly in many simple scenarios.
-library dart2js.test.send_measurements_test;
-
-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';
-
-main() {
-  test('nothing is reachable, nothing to count', () {
-    return _check('''
-      main() {}
-      test() { int x = 3; }
-      ''');
-  });
-
-  test('local variable read', () {
-    return _check('''
-      main() => test();
-      test() { int x = 3; int y = x; }
-      ''',
-      localSend: 1); // from `int y = x`;
-  });
-
-  test('generative constructor call', () {
-    return _check('''
-      class A {
-        get f => 1;
-      }
-      main() => test();
-      test() { new A(); }
-      ''',
-      constructorSend: 1);  // from new A()
-  });
-
-  group('instance call', () {
-    test('monomorphic only one implementor', () {
-      return _check('''
-        class A {
-          get f => 1;
-        }
-        main() => test();
-        test() { new A().f; }
-        ''',
-        constructorSend: 1, // new A()
-        instanceSend: 1);   // f resolved to A.f
-    });
-
-    test('monomorphic only one type possible from types', () {
-      return _check('''
-        class A {
-          get f => 1;
-        }
-        class B extends A {
-          get f => 1;
-        }
-        main() => test();
-        test() { new B().f; }
-        ''',
-        constructorSend: 1,
-        instanceSend: 1); // f resolved to B.f
-    });
-
-    test('monomorphic only one type possible from liveness', () {
-      return _check('''
-        class A {
-          get f => 1;
-        }
-        class B extends A {
-          get f => 1;
-        }
-        main() => test();
-        test() { A x = new B(); x.f; }
-        ''',
-        constructorSend: 1, // new B()
-        localSend: 1,       // x in x.f
-        instanceSend: 1);  // x.f known to resolve to B.f
-    });
-
-    test('monomorphic one possible, more than one live', () {
-      return _check('''
-        class A {
-          get f => 1;
-        }
-        class B extends A {
-          get f => 1;
-        }
-        main() { new A(); test(); }
-        test() { B x = new B(); x.f; }
-        ''',
-        constructorSend: 1, // new B()
-        localSend: 1,       // x in x.f
-        instanceSend: 1);   // x.f resolves to B.f
-    });
-
-    test('polymorphic-virtual couple possible types from liveness', () {
-        // Note: this would be an instanceSend if we used the inferrer.
-      return _check('''
-        class A {
-          get f => 1;
-        }
-        class B extends A {
-          get f => 1;
-        }
-        main() { new A(); test(); }
-        test() { A x = new B(); x.f; }
-        ''',
-        constructorSend: 1, // new B()
-        localSend: 1,       // x in x.f
-        virtualSend: 1);    // x.f may be A.f or B.f (types alone is not enough)
-    });
-
-    test("polymorphic-dynamic: type annotations don't help", () {
-      return _check('''
-        class A {
-          get f => 1;
-        }
-        class B extends A {
-          get f => 1;
-        }
-        main() { new A(); test(); }
-        test() { var x = new B(); x.f; }
-        ''',
-        constructorSend: 1, // new B()
-        localSend: 1,       // x in x.f
-        dynamicSend: 1);    // x.f could be any `f` or no `f`
-    });
-  });
-
-  group('instance this call', () {
-    test('monomorphic only one implementor', () {
-      return _check('''
-        class A {
-          get f => 1;
-          test() => this.f;
-        }
-        main() => new A().test();
-        ''',
-        instanceSend: 1);   // this.f resolved to A.f
-    });
-
-    test('monomorphic only one type possible from types & liveness', () {
-      return _check('''
-        class A {
-          get f => 1;
-          test() => this.f;
-        }
-        class B extends A {
-          get f => 1;
-        }
-        main() => new B().test();
-        ''',
-        instanceSend: 1); // this.f resolved to B.f
-    });
-
-    test('polymorphic-virtual couple possible types from liveness', () {
-        // Note: this would be an instanceSend if we used the inferrer.
-      return _check('''
-        class A {
-          get f => 1;
-          test() => this.f;
-        }
-        class B extends A {
-          get f => 1;
-        }
-        main() { new A(); new B().test(); }
-        ''',
-        virtualSend: 1);    // this.f may be A.f or B.f
-    });
-  });
-
-  group('noSuchMethod', () {
-    test('error will be thrown', () {
-      return _check('''
-        class A {
-        }
-        main() { test(); }
-        test() { new A().f; }
-        ''',
-        constructorSend: 1, // new B()
-        nsmErrorSend: 1);   // f not there, A has no nSM
-    });
-
-    test('nSM will be called - one option', () {
-      return _check('''
-        class A {
-          noSuchMethod(i) => null;
-        }
-        main() { test(); }
-        test() { new A().f; }
-        ''',
-        constructorSend: 1,    // new B()
-        singleNsmCallSend: 1); // f not there, A has nSM
-    });
-
-    // TODO(sigmund): is it worth splitting multiNSMvirtual?
-    test('nSM will be called - multiple options', () {
-      return _check('''
-        class A {
-          noSuchMethod(i) => null;
-        }
-        class B extends A {
-          noSuchMethod(i) => null;
-        }
-        main() { new A(); test(); }
-        test() { A x = new B(); x.f; }
-        ''',
-        constructorSend: 1,   // new B()
-        localSend: 1,         // x in x.f
-        multiNsmCallSend: 1); // f not there, A has nSM
-    });
-
-    // TODO(sigmund): is it worth splitting multiNSMvirtual?
-    test('nSM will be called - multiple options', () {
-      return _check('''
-        class A {
-          noSuchMethod(i) => null;
-        }
-        class B extends A {
-          // don't count A's nsm as distinct
-        }
-        main() { new A(); test(); }
-        test() { A x = new B(); x.f; }
-        ''',
-        constructorSend: 1,    // new B()
-        localSend: 1,          // x in x.f
-        singleNsmCallSend: 1); // f not there, A has nSM
-    });
-
-    test('nSM will be called - multiple options', () {
-      return _check('''
-        class A {
-          noSuchMethod(i) => null;
-        }
-        class B extends A {
-          get f => null;
-        }
-        main() { new A(); test(); }
-        test() { A x = new B(); x.f; }
-        ''',
-        constructorSend: 1,   // new B()
-        localSend: 1,         // x in x.f
-        dynamicSend: 1);      // f not known to be there there, A has nSM
-    });
-
-    test('nSM in super', () {
-      return _check('''
-        class A {
-          noSuchMethod(i) => null;
-        }
-        class B extends A {
-          get f => super.f;
-        }
-        main() { new A(); test(); }
-        test() { A x = new B(); x.f; }
-        ''',
-        singleNsmCallSend: 1, //   super.f
-        testMethod: 'f');
-    });
-  });
-}
-
-
-/// Checks that the `test` function in [code] produces the given distribution of
-/// sends.
-_check(String code, {int staticSend: 0, int superSend: 0, int localSend: 0,
-    int constructorSend: 0, int typeVariableSend: 0, int nsmErrorSend: 0,
-    int singleNsmCallSend: 0, int instanceSend: 0, int interceptorSend: 0,
-    int multiNsmCallSend: 0, int virtualSend: 0, int multiInterceptorSend: 0,
-    int dynamicSend: 0, String testMethod: 'test'}) async {
-
-  // Set up the expectation.
-  var expected = new Measurements();
-  int monomorphic = staticSend + superSend + localSend + constructorSend +
-    typeVariableSend + nsmErrorSend + singleNsmCallSend + instanceSend +
-    interceptorSend;
-  int polymorphic = multiNsmCallSend + virtualSend + multiInterceptorSend +
-    dynamicSend;
-
-  expected.counters[Metric.monomorphicSend] = monomorphic;
-  expected.counters[Metric.staticSend] = staticSend;
-  expected.counters[Metric.superSend] = superSend;
-  expected.counters[Metric.localSend] = localSend;
-  expected.counters[Metric.constructorSend] = constructorSend;
-  expected.counters[Metric.typeVariableSend] = typeVariableSend;
-  expected.counters[Metric.nsmErrorSend] = nsmErrorSend;
-  expected.counters[Metric.singleNsmCallSend] = singleNsmCallSend;
-  expected.counters[Metric.instanceSend] = instanceSend;
-  expected.counters[Metric.interceptorSend] = interceptorSend;
-
-  expected.counters[Metric.polymorphicSend] = polymorphic;
-  expected.counters[Metric.multiNsmCallSend] = multiNsmCallSend;
-  expected.counters[Metric.virtualSend] = virtualSend;
-  expected.counters[Metric.multiInterceptorSend] = multiInterceptorSend;
-  expected.counters[Metric.dynamicSend] = dynamicSend;
-
-  expected.counters[Metric.send] = monomorphic + polymorphic;
-
-  // Run the compiler to get the results.
-  var all = await _compileAndGetStats(code);
-  var function = all.functions.firstWhere((f) => f.name == testMethod,
-      orElse: () => null);
-  var result = function?.measurements;
-  if (function == null) {
-    expect(expected.counters[Metric.send], 0);
-    return;
-  }
-
-  expect(result, isNotNull);
-
-  _compareMetric(Metric key) {
-    var expectedValue = expected.counters[key];
-    var value = result.counters[key];
-    if (value == null) value = 0;
-    if (value == expectedValue) return;
-    expect(expectedValue, value,
-        reason: "count for `$key` didn't match:\n"
-        "expected measurements:\n${recursiveDiagnosticString(expected, key)}\n"
-        "actual measurements:\n${recursiveDiagnosticString(result, key)}");
-  }
-
-  _compareMetric(Metric.send);
-  expected.counters.keys.forEach(_compareMetric);
-}
-
-/// Helper that runs the compiler and returns the [GlobalResult] computed for
-/// it.
-Future<AllInfo> _compileAndGetStats(String program) async {
-  var result = await runCompiler(
-      memorySourceFiles: {'main.dart': program}, options: ['--dump-info']);
-  expect(result.compiler.compilationFailed, isFalse);
-  return result.compiler.dumpInfoTask.infoCollector.result;
-}
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
deleted file mode 100644
index 781ef91..0000000
--- a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
+++ /dev/null
@@ -1,152 +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.
-
-// Test that the CPS IR code generator generates source information.
-
-library source_information_tests;
-
-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/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';
-
-class TestEntry {
-  final String source;
-  final List<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];
-}
-
-js.Node getCodeForMain(CompilerImpl compiler) {
-  Element mainFunction = compiler.mainFunction;
-  return compiler.enqueuer.codegen.generatedCode[mainFunction];
-}
-
-js.Node getJsNodeForElement(CompilerImpl compiler, Element element) {
-  return compiler.enqueuer.codegen.generatedCode[element];
-}
-
-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);
-}
-
-runTests(List<TestEntry> tests) {
-  for (TestEntry test in tests) {
-    Map files = {TEST_MAIN_FILE: test.source};
-    asyncTest(() {
-      CompilerImpl compiler = compilerFor(
-          memorySourceFiles: files, options: <String>['--use-cps-ir']);
-      ir.FunctionDefinition irNodeForMain;
-
-      void cacheIrNodeForMain(Element function, ir.FunctionDefinition irNode) {
-        if (function == compiler.mainFunction) {
-          assert(irNodeForMain == null);
-          irNodeForMain = irNode;
-        }
-      }
-
-      Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
-      JavaScriptBackend backend = compiler.backend;
-      var functionCompiler = backend.functionCompiler;
-      functionCompiler.cpsBuilderTask.builderCallback = cacheIrNodeForMain;
-
-      return compiler.run(uri).then((bool success) {
-        Expect.isTrue(success);
-
-        IrSourceInformationVisitor irVisitor = new IrSourceInformationVisitor();
-        irNodeForMain.accept(irVisitor);
-
-        js.Node jsNode = getJsNodeForElement(compiler, compiler.mainFunction);
-        JsSourceInformationVisitor jsVisitor = new JsSourceInformationVisitor();
-        jsNode.accept(jsVisitor);
-
-        List<String> expectation = test.expectation;
-        // Visiting of CPS is in structural order so we check for set equality.
-        Expect.setEquals(expectation, irVisitor.sourceInformation,
-              'Unexpected IR source information. '
-              'Expected:\n$expectation\n'
-              'but found\n${irVisitor.sourceInformation}\n'
-              'in\n${test.source}'
-              'CPS:\n${irNodeForMain.accept(new ir.SExpressionStringifier())}');
-        Expect.listEquals(expectation, jsVisitor.sourceInformation,
-              'Unexpected JS source information. '
-              'Expected:\n$expectation\n'
-              'but found\n${jsVisitor.sourceInformation}\n'
-              'in\n${test.source}');
-      }).catchError((e) {
-        print(e);
-        Expect.fail('The following test failed to compile:\n'
-                    '${formatTest(files)}');
-      });
-    });
-  }
-}
-
-class JsSourceInformationVisitor extends js.BaseVisitor {
-  List<String> sourceInformation = <String>[];
-
-  @override
-  visitCall(js.Call node) {
-    sourceInformation.add('${node.sourceInformation}');
-    super.visitCall(node);
-  }
-}
-
-class IrSourceInformationVisitor extends ir.TrampolineRecursiveVisitor {
-  List<String> sourceInformation = <String>[];
-
-  @override
-  processInvokeStatic(ir.InvokeStatic node) {
-    sourceInformation.add('${node.sourceInformation}');
-  }
-}
-
-const List<TestEntry> tests = const [
-  const TestEntry("""
-main() { print('Hello World'); }
-""", const ['memory:test.dart:[1,10]']),
-const TestEntry("""
-main() {
-  print('Hello');
-  print('World');
-}
-""", const ['memory:test.dart:[2,3]',
-            'memory:test.dart:[3,3]']),
-];
-
-void main() {
-  runTests(tests);
-}
diff --git a/tests/compiler/dart2js/jsinterop/world_test.dart b/tests/compiler/dart2js/jsinterop/world_test.dart
new file mode 100644
index 0000000..f196b8e
--- /dev/null
+++ b/tests/compiler/dart2js/jsinterop/world_test.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsinterop.world_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common.dart';
+import 'package:compiler/src/elements/elements.dart'
+    show Element, ClassElement;
+import 'package:compiler/src/js_backend/js_backend.dart';
+import 'package:compiler/src/world.dart';
+import '../type_test_helper.dart';
+
+void main() {
+  asyncTest(() async {
+    await testClasses();
+  });
+}
+
+testClasses() async {
+  test(String mainSource,
+      {List<String> directlyInstantiated: const <String>[],
+       List<String> indirectlyInstantiated: const <String>[]}) async {
+    TypeEnvironment env = await TypeEnvironment.create(r"""
+@JS()
+class A {
+  get foo;
+
+  external A(var foo);
+}
+
+@JS()
+class B {
+  get foo;
+
+  external B(var foo);
+}
+
+@JS()
+@anonymous
+class C {
+  final foo;
+
+  external factory C({foo});
+}
+
+@JS()
+@anonymous
+class D {
+  final foo;
+
+  external factory D({foo});
+}
+
+class E {
+  final foo;
+
+  E(this.foo);
+}
+
+class F {
+  final foo;
+
+  F(this.foo);
+}
+
+newA() => new A(0);
+newB() => new B(1);
+newC() => new C(foo: 2);
+newD() => new D(foo: 3);
+newE() => new E(4);
+newF() => new F(5);
+""", mainSource: """
+import 'package:js/js.dart';
+
+$mainSource
+""", useMockCompiler: false);
+    Map<String, ClassElement> classEnvironment = <String, ClassElement>{};
+
+    ClassElement registerClass(ClassElement cls) {
+      classEnvironment[cls.name] = cls;
+      return cls;
+    }
+
+    ClassWorld world = env.compiler.world;
+    JavaScriptBackend backend = env.compiler.backend;
+    ClassElement Object_ = registerClass(env.compiler.coreClasses.objectClass);
+    ClassElement Interceptor =
+        registerClass(backend.helpers.jsInterceptorClass);
+    ClassElement JavaScriptObject =
+        registerClass(backend.helpers.jsJavaScriptObjectClass);
+    ClassElement A = registerClass(env.getElement('A'));
+    ClassElement B = registerClass(env.getElement('B'));
+    ClassElement C = registerClass(env.getElement('C'));
+    ClassElement D = registerClass(env.getElement('D'));
+    ClassElement E = registerClass(env.getElement('E'));
+    ClassElement F = registerClass(env.getElement('F'));
+
+    Expect.equals(Interceptor.superclass, Object_);
+    Expect.equals(JavaScriptObject.superclass, Interceptor);
+
+    Expect.equals(A.superclass, JavaScriptObject);
+    Expect.equals(B.superclass, JavaScriptObject);
+    Expect.equals(C.superclass, JavaScriptObject);
+    Expect.equals(D.superclass, JavaScriptObject);
+    Expect.equals(E.superclass, Object_);
+    Expect.equals(F.superclass, Object_);
+
+    for (String name in classEnvironment.keys) {
+      ClassElement cls = classEnvironment[name];
+      bool isInstantiated = false;
+      if (directlyInstantiated.contains(name)) {
+        isInstantiated = true;
+        Expect.isTrue(world.isDirectlyInstantiated(cls),
+            "Expected $name to be directly instantiated in `${mainSource}`:"
+                "\n${world.dump(cls)}");
+      }
+      if (indirectlyInstantiated.contains(name)) {
+        isInstantiated = true;
+        Expect.isTrue(world.isIndirectlyInstantiated(cls),
+            "Expected $name to be indirectly instantiated in `${mainSource}`:"
+                "\n${world.dump(cls)}");
+      }
+      if (!isInstantiated && (name != 'Object' && name != 'Interceptor')) {
+        Expect.isFalse(world.isInstantiated(cls),
+            "Expected $name to be uninstantiated in `${mainSource}`:"
+                "\n${world.dump(cls)}");
+      }
+    }
+  }
+
+  await test('main() {}');
+
+  await test('main() => newA();',
+      directlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newB();',
+      directlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newC();',
+      directlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newD();',
+      directlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newE();',
+      directlyInstantiated: ['E']);
+
+  await test('main() => newF();',
+      directlyInstantiated: ['F']);
+
+  await test('main() => [newD(), newE()];',
+      directlyInstantiated: ['A', 'B', 'C', 'D', 'E'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+}
diff --git a/tests/compiler/dart2js/launch_helper.dart b/tests/compiler/dart2js/launch_helper.dart
new file mode 100644
index 0000000..671d412
--- /dev/null
+++ b/tests/compiler/dart2js/launch_helper.dart
@@ -0,0 +1,30 @@
+import 'dart:async';
+import 'dart:io';
+import 'package:path/path.dart' as path;
+
+List<String> dart2JsCommand(List<String> args) {
+  String basePath = path.fromUri(Platform.script);
+  while (path.basename(basePath) != 'sdk') {
+    basePath = path.dirname(basePath);
+  }
+  String dart2jsPath =
+      path.normalize(path.join(basePath, 'pkg/compiler/lib/src/dart2js.dart'));
+  List command = <String>[];
+  if (Platform.packageRoot != null) {
+    command.add('--package-root=${Platform.packageRoot}');
+  } else if (Platform.packageConfig != null) {
+    command.add('--packages=${Platform.packageConfig}');
+  }
+  command.add(dart2jsPath);
+  command.addAll(args);
+  return command;
+}
+
+Future launchDart2Js(args, {bool noStdoutEncoding: false}) {
+  if (noStdoutEncoding) {
+    return Process.run(Platform.executable, dart2JsCommand(args),
+        stdoutEncoding: null);
+  } else {
+    return Process.run(Platform.executable, dart2JsCommand(args));
+  }
+}
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 2efa806..c6b3b3c 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -33,7 +33,8 @@
     }
     String source = memorySourceFiles[resourceUri.path];
     if (source == null) {
-      return new Future.error(new Exception('No such file $resourceUri'));
+      return new Future.error(new Exception(
+          'No such memory file $resourceUri in ${memorySourceFiles.keys}'));
     }
     this.sourceFiles[resourceUri] =
         new StringSourceFile.fromUri(resourceUri, source);
@@ -48,7 +49,8 @@
     }
     String source = memorySourceFiles[resourceUri.path];
     if (source == null) {
-      throw new Exception('No such file $resourceUri');
+      throw new Exception(
+          'No such memory file $resourceUri in ${memorySourceFiles.keys}');
     }
     return new StringSourceFile.fromUri(resourceUri, source);
   }
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index 34e7efe..31094e4 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -10,8 +10,6 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart' show
     Compiler;
-import 'package:compiler/src/dart_backend/dart_backend.dart' show
-    DartBackend;
 import 'package:compiler/src/diagnostics/messages.dart' show
     MessageKind,
     MessageTemplate;
@@ -71,21 +69,12 @@
     }
     DiagnosticCollector collector = new DiagnosticCollector();
 
-    bool oldBackendIsDart;
-    if (cachedCompiler != null) {
-      oldBackendIsDart = cachedCompiler.backend is DartBackend;
-    }
-    bool newBackendIsDart = template.options.contains('--output-type=dart');
-
     Compiler compiler = compilerFor(
         memorySourceFiles: example,
         diagnosticHandler: collector,
         options: [Flags.analyzeOnly,
                   Flags.enableExperimentalMirrors]..addAll(template.options),
-        cachedCompiler:
-             // TODO(johnniwinther): Remove this restriction when constant
-             // values can be computed directly from the expressions.
-             oldBackendIsDart == newBackendIsDart ? cachedCompiler : null);
+        cachedCompiler: cachedCompiler);
 
     return compiler.run(Uri.parse('memory:main.dart')).then((_) {
       Iterable<CollectedMessage> messages = collector.filterMessagesByKinds(
diff --git a/tests/compiler/dart2js/minimal_resolution_test.dart b/tests/compiler/dart2js/minimal_resolution_test.dart
index 7de35a3..ddc1eaf 100644
--- a/tests/compiler/dart2js/minimal_resolution_test.dart
+++ b/tests/compiler/dart2js/minimal_resolution_test.dart
@@ -29,19 +29,17 @@
   bool isProcessed = enqueuer.isClassProcessed(cls);
   Expect.equals(expected, isInstantiated,
       'Unexpected instantiation state of class $cls.');
-  Expect.equals(expected, isProcessed,
-      'Unexpected processing state of class $cls.');
+  Expect.equals(
+      expected, isProcessed, 'Unexpected processing state of class $cls.');
 }
 
 analyze(String code,
-        {bool proxyConstant: false,
-         bool deprecatedClass: false}) async {
+    {bool proxyConstant: false, bool deprecatedClass: false}) async {
   CompilationResult result = await runCompiler(
-      memorySourceFiles: {'main.dart': code},
-      options: ['--analyze-only']);
+      memorySourceFiles: {'main.dart': code}, options: ['--analyze-only']);
   Expect.isTrue(result.isSuccess);
   Compiler compiler = result.compiler;
-  Expect.equals(proxyConstant, compiler.proxyConstant != null,
+  Expect.equals(proxyConstant, compiler.resolution.proxyConstant != null,
       "Unexpected computation of proxy constant.");
 
   checkInstantiated(
diff --git a/tests/compiler/dart2js/mirror_helper_rename_test.dart b/tests/compiler/dart2js/mirror_helper_rename_test.dart
deleted file mode 100644
index 80edc15..0000000
--- a/tests/compiler/dart2js/mirror_helper_rename_test.dart
+++ /dev/null
@@ -1,108 +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 "package:expect/expect.dart";
-import 'dart:async';
-import "package:async_helper/async_helper.dart";
-import 'memory_compiler.dart' show runCompiler, OutputCollector;
-import 'package:compiler/src/apiimpl.dart' show
-    CompilerImpl;
-import 'package:compiler/src/tree/tree.dart' show
-    Node;
-import 'package:compiler/src/dart_backend/dart_backend.dart';
-import 'package:compiler/src/mirror_renamer/mirror_renamer.dart';
-
-main() {
-  asyncTest(() async {
-    await testWithMirrorHelperLibrary(minify: true);
-    await testWithMirrorHelperLibrary(minify: false);
-    await testWithoutMirrorHelperLibrary(minify: true);
-    await testWithoutMirrorHelperLibrary(minify: false);
-  });
-}
-
-Future<CompilerImpl> run({OutputCollector outputCollector,
-                      bool useMirrorHelperLibrary: false,
-                      bool minify: false}) async {
-  List<String> options = ['--output-type=dart'];
-  if (minify) {
-    options.add('--minify');
-  }
-  var result = await runCompiler(
-      memorySourceFiles: MEMORY_SOURCE_FILES,
-      outputProvider: outputCollector,
-      options: options,
-      beforeRun: (CompilerImpl compiler) {
-        DartBackend backend = compiler.backend;
-        backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
-      });
-  return result.compiler;
-}
-
-Future testWithMirrorHelperLibrary({bool minify}) async {
-  OutputCollector outputCollector = new OutputCollector();
-  CompilerImpl compiler = await run(
-      outputCollector: outputCollector,
-      useMirrorHelperLibrary: true,
-      minify: minify);
-  DartBackend backend = compiler.backend;
-  MirrorRenamerImpl mirrorRenamer = backend.mirrorRenamer;
-  Map<Node, String> renames = backend.placeholderRenamer.renames;
-  Map<String, String> symbols = mirrorRenamer.symbols;
-
-  Expect.isFalse(null == mirrorRenamer.helperLibrary);
-  Expect.isFalse(null == mirrorRenamer.getNameFunction);
-
-  for (Node n in renames.keys) {
-    if (symbols.containsKey(renames[n])) {
-      if(n.toString() == 'getName') {
-        Expect.equals(
-            MirrorRenamerImpl.MIRROR_HELPER_GET_NAME_FUNCTION,
-            symbols[renames[n]]);
-      } else {
-        Expect.equals(n.toString(), symbols[renames[n]]);
-      }
-    }
-  }
-
-  String output = outputCollector.getOutput('', 'dart');
-  String getNameMatch = MirrorRenamerImpl.MIRROR_HELPER_GET_NAME_FUNCTION;
-  Iterable i = getNameMatch.allMatches(output);
-  print(output);
-  if (minify) {
-    Expect.equals(0, i.length);
-  } else {
-    // Appears twice in code (defined & called).
-    Expect.equals(2, i.length);
-  }
-
-  RegExp mapMatch = new RegExp('const<String,( )?String>');
-  i = mapMatch.allMatches(output);
-  Expect.equals(1, i.length);
-}
-
-Future testWithoutMirrorHelperLibrary({bool minify}) async {
-  CompilerImpl compiler =
-      await run(useMirrorHelperLibrary: false, minify: minify);
-  DartBackend backend = compiler.backend;
-  MirrorRenamer mirrorRenamer = backend.mirrorRenamer;
-
-  Expect.equals(null, mirrorRenamer.helperLibrary);
-  Expect.equals(null, mirrorRenamer.getNameFunction);
-}
-
-const MEMORY_SOURCE_FILES = const <String, String> {
-  'main.dart': """
-import 'dart:mirrors';
-
-class Foo {
-  noSuchMethod(Invocation invocation) {
-    MirrorSystem.getName(invocation.memberName);
-  }
-}
-
-void main() {
-  new Foo().fisk();
-}
-"""};
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirror_helper_test.dart b/tests/compiler/dart2js/mirror_helper_test.dart
deleted file mode 100644
index ce257c7..0000000
--- a/tests/compiler/dart2js/mirror_helper_test.dart
+++ /dev/null
@@ -1,94 +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 "package:expect/expect.dart";
-import 'dart:async';
-import "package:async_helper/async_helper.dart";
-import 'memory_compiler.dart' show runCompiler;
-import 'package:compiler/src/apiimpl.dart' show
-    CompilerImpl;
-import 'package:compiler/src/elements/elements.dart' show
-    Element, LibraryElement, ClassElement;
-import 'package:compiler/src/tree/tree.dart' show
-    Block, ExpressionStatement, FunctionExpression, Node, Send;
-import 'package:compiler/src/dart_backend/dart_backend.dart' show
-    DartBackend, ElementAst;
-import 'package:compiler/src/mirror_renamer/mirror_renamer.dart' show
-    MirrorRenamerImpl;
-
-main() {
-  asyncTest(() async {
-    await testWithMirrorRenaming(minify: true);
-    await testWithMirrorRenaming(minify: false);
-    await testWithoutMirrorRenaming(minify: true);
-    await testWithoutMirrorRenaming(minify: false);
-  });
-}
-
-Future<CompilerImpl> run({useMirrorHelperLibrary: false, minify: false}) async {
-  List<String> options = ['--output-type=dart'];
-  if (minify) {
-    options.add('--minify');
-  }
-  var result = await runCompiler(
-      memorySourceFiles: MEMORY_SOURCE_FILES,
-      options: options,
-      beforeRun: (CompilerImpl compiler) {
-        DartBackend backend = compiler.backend;
-        backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
-      });
-  return result.compiler;
-}
-
-Future testWithMirrorRenaming({bool minify}) async {
-  CompilerImpl compiler =
-      await run(useMirrorHelperLibrary: true, minify: minify);
-  DartBackend backend = compiler.backend;
-  MirrorRenamerImpl mirrorRenamer = backend.mirrorRenamer;
-  Map<Node, String> renames = backend.placeholderRenamer.renames;
-  Iterable<LibraryElement> imports =
-      backend.placeholderRenamer.platformImports.keys;
-
-  FunctionExpression node = backend.memberNodes.values.first.first;
-  Block block = node.body;
-  ExpressionStatement getNameFunctionNode = block.statements.nodes.head;
-  Send send = getNameFunctionNode.expression;
-
-  Expect.equals(renames[mirrorRenamer.getNameFunctionNode.name],
-                renames[send.selector]);
-  Expect.equals("",
-                renames[send.receiver]);
-  Expect.equals(1, imports.length);
-}
-
-Future testWithoutMirrorRenaming({bool minify}) async {
-  CompilerImpl compiler =
-      await run(useMirrorHelperLibrary: false, minify: minify);
-  DartBackend backend = compiler.backend;
-  Map<Node, String> renames = backend.placeholderRenamer.renames;
-  Iterable<LibraryElement> imports =
-      backend.placeholderRenamer.platformImports.keys;
-  FunctionExpression node = backend.memberNodes.values.first.first;
-  Block block = node.body;
-  ExpressionStatement getNameFunctionNode = block.statements.nodes.head;
-  Send send = getNameFunctionNode.expression;
-
-  Expect.isFalse(renames.containsKey(send.selector));
-  Expect.equals(1, imports.length);
-}
-
-const MEMORY_SOURCE_FILES = const <String, String> {
-  'main.dart': """
-import 'dart:mirrors';
-
-class Foo {
-  noSuchMethod(Invocation invocation) {
-    MirrorSystem.getName(invocation.memberName);
-  }
-}
-
-void main() {
-  new Foo().fisk();
-}
-"""};
diff --git a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
deleted file mode 100644
index bec8f9f..0000000
--- a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
+++ /dev/null
@@ -1,89 +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 "package:expect/expect.dart";
-import 'dart:async';
-import "package:async_helper/async_helper.dart";
-import 'memory_compiler.dart' show runCompiler;
-import 'package:compiler/src/apiimpl.dart' show
-    CompilerImpl;
-import 'package:compiler/src/dart_backend/dart_backend.dart' show
-    DartBackend;
-import 'package:compiler/src/tree/tree.dart' show
-    Identifier, Node, Send;
-import 'package:compiler/src/mirror_renamer/mirror_renamer.dart' show
-    MirrorRenamerImpl;
-
-main() {
-  asyncTest(() async {
-    await testUniqueMinification();
-    await testNoUniqueMinification();
-  });
-}
-
-Future<CompilerImpl> run({useMirrorHelperLibrary: false, minify: false}) async {
-  List<String> options = ['--output-type=dart'];
-  if (minify) {
-    options.add('--minify');
-  }
-  var result = await runCompiler(
-      memorySourceFiles: MEMORY_SOURCE_FILES,
-      options: options,
-      beforeRun: (CompilerImpl compiler) {
-        DartBackend backend = compiler.backend;
-        backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
-      });
-  return result.compiler;
-}
-
-Future testUniqueMinification() async {
-  CompilerImpl compiler = await run(useMirrorHelperLibrary: true, minify: true);
-  DartBackend backend = compiler.backend;
-  MirrorRenamerImpl mirrorRenamer = backend.mirrorRenamer;
-  Map<Node, String> renames = backend.placeholderRenamer.renames;
-  Map<String, String> symbols = mirrorRenamer.symbols;
-
-  // Check that no two different source code names get the same mangled name,
-  // with the exception of MirrorSystem.getName that gets renamed to the same
-  // mangled name as the getNameHelper from _mirror_helper.dart.
-  for (Node node in renames.keys) {
-    Identifier identifier = node.asIdentifier();
-    if (identifier != null) {
-      String source = identifier.source;
-      Send send = mirrorRenamer.mirrorSystemGetNameNodes.first;
-      if (send.selector == node)
-        continue;
-      if (symbols.containsKey(renames[node])) {
-        print(node);
-        Expect.equals(source, symbols[renames[node]]);
-      }
-    }
-  }
-}
-
-Future testNoUniqueMinification() async {
-  CompilerImpl compiler =
-      await run(useMirrorHelperLibrary: false, minify: true);
-  DartBackend backend = compiler.backend;
-  Map<Node, String> renames = backend.placeholderRenamer.renames;
-
-  // 'Foo' appears twice and 'invocation' and 'hest' get the same mangled
-  // name.
-  Expect.equals(renames.values.toSet().length, renames.values.length - 2);
-}
-
-const MEMORY_SOURCE_FILES = const <String, String> {
-  'main.dart': """
-import 'dart:mirrors';
-
-class Foo {
-  noSuchMethod(invocation) {
-    MirrorSystem.getName(null);
-  }
-}
-
-main(hest) {
-  new Foo().fisk();
-}
-"""};
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index fc08b6b..4b9c31a 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -69,7 +69,7 @@
     // 2. Some code was refactored, and there are more methods.
     // Either situation could be problematic, but in situation 2, it is often
     // acceptable to increase [expectedMethodCount] a little.
-    int expectedMethodCount = 432;
+    int expectedMethodCount = 466;
     Expect.isTrue(
         generatedCode.length <= expectedMethodCount,
         'Too many compiled methods: '
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 9c5b770..5d83c5d 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -80,7 +80,6 @@
        bool disableTypeInference: false,
        bool analyzeAll: false,
        bool analyzeOnly: false,
-       bool emitJavaScript: true,
        bool preserveComments: false,
        // Our unit tests check code generation output that is
        // affected by inlining support.
@@ -106,7 +105,6 @@
               disableTypeInference: disableTypeInference,
               analyzeAll: analyzeAll,
               analyzeOnly: analyzeOnly,
-              emitJavaScript: emitJavaScript,
               preserveComments: preserveComments,
               trustTypeAnnotations: trustTypeAnnotations,
               trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
@@ -228,9 +226,9 @@
                                           ExecutableElement element) {
     ResolverVisitor visitor =
         new ResolverVisitor(
-            this,
+            this.resolution,
             element,
-            new ResolutionRegistry(this,
+            new ResolutionRegistry(this.backend,
                 new CollectingTreeElements(element)),
             scope: new MockTypeVariablesScope(
                 element.enclosingElement.buildScope()));
@@ -247,10 +245,10 @@
     Element mockElement = new MockElement(mainApp.entryCompilationUnit);
     ResolverVisitor visitor =
         new ResolverVisitor(
-            this,
+            this.resolution,
             mockElement,
             new ResolutionRegistry(
-                this, new CollectingTreeElements(mockElement)),
+                this.backend, new CollectingTreeElements(mockElement)),
             scope: mockElement.enclosingElement.buildScope());
     visitor.scope = new MethodScope(visitor.scope, mockElement);
     return visitor;
diff --git a/tests/compiler/dart2js/octagon_test.dart b/tests/compiler/dart2js/octagon_test.dart
deleted file mode 100644
index 59ea0c0..0000000
--- a/tests/compiler/dart2js/octagon_test.dart
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:compiler/src/cps_ir/octagon.dart';
-import 'package:expect/expect.dart';
-
-Octagon octagon;
-SignedVariable v1, v2, v3, v4;
-
-setup() {
-  octagon = new Octagon();
-  v1 = octagon.makeVariable();
-  v2 = octagon.makeVariable();
-  v3 = octagon.makeVariable();
-  v4 = octagon.makeVariable();
-}
-
-Constraint pushConstraint(SignedVariable w1, SignedVariable w2, int k) {
-  Constraint c = new Constraint(w1, w2, k);
-  octagon.pushConstraint(c);
-  return c;
-}
-
-void popConstraint(Constraint c) {
-  octagon.popConstraint(c);
-}
-
-negative_loop1() {
-  setup();
-  // Create the contradictory constraint:
-  //  v1 <= v2 <= v1 - 1 (loop weight = -1)
-  //
-  // As difference bounds:
-  //  v1 - v2 <= 0
-  //  v2 - v1 <= -1
-  pushConstraint(v1, v2.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'v1 <= v2: should be solvable');
-  var c = pushConstraint(v2, v1.negated, -1);
-  Expect.isTrue(octagon.isUnsolvable, 'v2 <= v1 - 1: should become unsolvable');
-
-  // Check that pop restores solvability.
-  popConstraint(c);
-  Expect.isTrue(octagon.isSolvable, 'Should be solvable without v2 <= v1 - 1');
-}
-
-negative_loop2() {
-  setup();
-  // Create a longer contradiction, and add the middle constraint last:
-  //  v1 <= v2 <= v3 <= v1 - 1
-  pushConstraint(v1, v2.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'v1 <= v2: should be solvable');
-  pushConstraint(v3, v1.negated, -1);
-  Expect.isTrue(octagon.isSolvable, 'v3 <= v1 - 1: should be solvable');
-  var c = pushConstraint(v2, v3.negated, 0);
-  Expect.isTrue(octagon.isUnsolvable, 'v2 <= v3: should become unsolvable');
-
-  // Check that pop restores solvability.
-  popConstraint(c);
-  Expect.isTrue(octagon.isSolvable, 'Should be solvable without v2 <= v3');
-}
-
-negative_loop3() {
-  setup();
-  // Add a circular constraint with offsets and negative weight:
-  //   v1 <= v2 - 1 <= v3 + 2 <= v1 - 1
-  // As difference bounds:
-  //   v1 - v2 <= -1
-  //   v2 - v3 <=  3
-  //   v3 - v1 <= -3
-  pushConstraint(v1, v2.negated, -1);
-  Expect.isTrue(octagon.isSolvable, 'v1 <= v2 - 1: should be solvable');
-  pushConstraint(v2, v3.negated, 3);
-  Expect.isTrue(octagon.isSolvable, 'v2 - 1 <= v3 + 2: should be solvable');
-  var c = pushConstraint(v3, v1.negated, -3);
-  Expect.isTrue(octagon.isUnsolvable, 'v3 + 2 <= v1 - 1: should become unsolvable');
-
-  // Check that pop restores solvability.
-  popConstraint(c);
-  Expect.isTrue(octagon.isSolvable, 'Should be solvable without v3 + 2 <= v1 - 1');
-}
-
-zero_loop1() {
-  setup();
-  // Add the circular constraint with zero weight:
-  //   v1 <= v2 <= v3 <= v1
-  pushConstraint(v1, v2.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'v1 <= v2: should be solvable');
-  pushConstraint(v2, v3.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'v2 <= v3: should be solvable');
-  pushConstraint(v3, v1.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'v3 <= v1: should be solvable');
-}
-
-zero_loop2() {
-  setup();
-  // Add a circular constraint with offsets:
-  //   v1 <= v2 - 1 <= v3 + 2 <= v1
-  // As difference bounds:
-  //   v1 - v2 <= -1
-  //   v2 - v3 <=  3
-  //   v3 - v1 <= -2
-  pushConstraint(v1, v2.negated, -1);
-  Expect.isTrue(octagon.isSolvable, 'v1 <= v2 - 1: should be solvable');
-  pushConstraint(v2, v3.negated, 3);
-  Expect.isTrue(octagon.isSolvable, 'v2 - 1 <= v3 + 2: should be solvable');
-  pushConstraint(v3, v1.negated, -2);
-  Expect.isTrue(octagon.isSolvable, 'v3 + 2 <= v1: should be solvable');
-}
-
-positive_loop1() {
-  setup();
-  // Add constraints with some slack (positive-weight loop):
-  //   v1 <= v2 <= v3 <= v1 + 1
-  pushConstraint(v1, v2.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'v1 <= v2: should be solvable');
-  pushConstraint(v2, v3.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'v2 <= v3: should be solvable');
-  pushConstraint(v3, v1.negated, 1);
-  Expect.isTrue(octagon.isSolvable, 'v3 <= v1 + 1: should be solvable');
-}
-
-positive_loop2() {
-  setup();
-  // Add constraints with offsets and slack at the end:
-  //   v1 <= v2 - 1 <= v3 + 2 <= v1 + 1
-  // As difference bounds:
-  //   v1 - v2 <= -1
-  //   v2 - v3 <=  3
-  //   v3 - v1 <= -1
-  pushConstraint(v1, v2.negated, -1);
-  Expect.isTrue(octagon.isSolvable, 'v1 <= v2 - 1: should be solvable');
-  pushConstraint(v2, v3.negated, 3);
-  Expect.isTrue(octagon.isSolvable, 'v2 - 1 <= v3 + 2: should be solvable');
-  pushConstraint(v3, v1.negated, -1);
-  Expect.isTrue(octagon.isSolvable, 'v3 + 2 <= v1: should be solvable');
-}
-
-positive_and_negative_loops1() {
-  setup();
-  //  v1 <= v2 <= v3 <= v1 + 1
-  //  v2 <= v3 - 2  (unsolvable: v3 - 2 <= (v1 + 1) - 2 = v1 - 1)
-  pushConstraint(v1, v2.negated, 0);
-  pushConstraint(v2, v3.negated, 0);
-  pushConstraint(v3, v1.negated, 1);
-  Expect.isTrue(octagon.isSolvable, 'should be solvable');
-  pushConstraint(v2, v3.negated, -2);
-  Expect.isTrue(octagon.isUnsolvable, 'v2 <= v3 - 2: should become unsolvable');
-}
-
-positive_and_negative_loops2() {
-  setup();
-  // Same as above, but constraints are added in a different order.
-  pushConstraint(v2, v3.negated, -2);
-  pushConstraint(v2, v3.negated, 0);
-  pushConstraint(v3, v1.negated, 1);
-  Expect.isTrue(octagon.isSolvable, 'should be solvable');
-  pushConstraint(v1, v2.negated, 0);
-  Expect.isTrue(octagon.isUnsolvable, 'v1 <= v2: should become unsolvable');
-}
-
-positive_and_negative_loops3() {
-  setup();
-  // Same as above, but constraints are added in a different order.
-  pushConstraint(v2, v3.negated, 0);
-  pushConstraint(v2, v3.negated, -2);
-  pushConstraint(v3, v1.negated, 1);
-  Expect.isTrue(octagon.isSolvable, 'should be solvable');
-  pushConstraint(v1, v2.negated, 0);
-  Expect.isTrue(octagon.isUnsolvable, 'v1 <= v2: should become unsolvable');
-}
-
-plus_minus1() {
-  setup();
-  // Given:
-  //   v1 = v2 + 1    (modeled as: v1 <= v2 + 1 <= v1)
-  //   v3 = v4 + 1
-  //   v1 <= v3
-  // prove:
-  //   v2 <= v4
-  pushConstraint(v1, v2.negated,  1); // v1 <= v2 + 1
-  pushConstraint(v2, v1.negated, -1); // v2 <= v1 - 1
-  pushConstraint(v3, v4.negated,  1); // v3 <= v4 + 1
-  pushConstraint(v4, v3.negated, -1); // v4 <= v3 - 1
-  pushConstraint(v1, v3.negated,  0); // v1 <= v3
-  Expect.isTrue(octagon.isSolvable, 'should be solvable');
-  // Push the negated constraint: v2 > v4 <=> v4 - v2 <= -1
-  pushConstraint(v4, v2.negated, -1);
-  Expect.isTrue(octagon.isUnsolvable, 'should be unsolvable');
-}
-
-constant1() {
-  setup();
-  // Given:
-  //   v1 = 10
-  //   v2 <= v3
-  //   v3 + v1 <= 3   (i.e. v2 <= v3 <= -v1 + 3 = 7)
-  // prove:
-  //   v2 <= 7  (modeled as: v2 + v2 <= 14)
-  pushConstraint(v1, v1, 20); // v1 + v1 <= 20
-  pushConstraint(v1.negated, v1.negated, -20); // -v1 - v1 <= -20
-  pushConstraint(v2, v3.negated, 0); // v2 <= v3
-  pushConstraint(v3, v1,  3); // v3 + v1 <= 3
-  Expect.isTrue(octagon.isSolvable, 'should be solvable');
-  // Push the negated constraint: v2 + v2 > 14 <=> -v2 - v2 <= -15
-  var c = pushConstraint(v2.negated, v2.negated, -15);
-  Expect.isTrue(octagon.isUnsolvable, 'should be unsolvable');
-  popConstraint(c);
-  // Push the thing we are trying to prove.
-  pushConstraint(v2, v2, 14);
-  Expect.isTrue(octagon.isSolvable, 'v2 + v2 <= 14: should be solvable');
-}
-
-contradict1() {
-  setup();
-  // v1 < v1  (v1 - v1 <= -1)
-  pushConstraint(v1, v1.negated, -1);
-  Expect.isTrue(octagon.isUnsolvable, 'v1 < v1: should be unsolvable');
-}
-
-contradict2() {
-  setup();
-  // v1 = 2
-  // v2 = 0
-  // v1 <= v2
-  pushConstraint(v1, v1, 2);
-  pushConstraint(v1.negated, v1.negated, -2);
-  pushConstraint(v2, v2, 0);
-  pushConstraint(v2.negated, v2.negated, 0);
-  Expect.isTrue(octagon.isSolvable, 'should be solvable');
-  pushConstraint(v1, v2.negated, 0);
-  Expect.isTrue(octagon.isUnsolvable, 'v1 <= v2: should be unsolvable');
-}
-
-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();
-  negative_loop3();
-  zero_loop1();
-  zero_loop2();
-  positive_loop1();
-  positive_loop2();
-  positive_and_negative_loops1();
-  positive_and_negative_loops2();
-  positive_and_negative_loops3();
-  plus_minus1();
-  constant1();
-  contradict1();
-  contradict2();
-  lower_bounds_check();
-  upper_bounds_check();
-  diamond_graph();
-}
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 2130f06..607fae9 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -1023,13 +1023,17 @@
     class A {
       A() : super();
       factory A.forward() = B.patchTarget;
+      factory A.forwardOne() = B.patchFactory;
       factory A.forwardTwo() = B.reflectBack;
+      factory A.forwardThree() = B.patchInjected;
     }
     class B extends A {
       B() : super();
       external B.patchTarget();
+      external factory B.patchFactory();
       external factory B.reflectBack();
       B.originTarget() : super();
+      external factory B.patchInjected();
     }
     """;
   String patch = """
@@ -1037,7 +1041,14 @@
       @patch
       B.patchTarget() : super();
       @patch
+      factory B.patchFactory() => new B.patchTarget();
+      @patch
       factory B.reflectBack() = B.originTarget;
+      @patch
+      factory B.patchInjected() = _C.injected;
+    }
+    class _C extends B {
+      _C.injected() : super.patchTarget();
     }
     """;
 
@@ -1048,14 +1059,28 @@
 
   ConstructorElement forward = clsA.lookupConstructor("forward");
   ConstructorElement target = forward.effectiveTarget;
-  Expect.isTrue(target.isPatch);
+  Expect.isTrue(target.isPatched, "Unexpected target $target for $forward");
+  Expect.isFalse(target.isPatch, "Unexpected target $target for $forward");
   Expect.equals("patchTarget", target.name);
 
+  ConstructorElement forwardOne = clsA.lookupConstructor("forwardOne");
+  target = forwardOne.effectiveTarget;
+  Expect.isFalse(forwardOne.isMalformed);
+  Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardOne");
+  Expect.equals("patchFactory", target.name);
+
   ConstructorElement forwardTwo = clsA.lookupConstructor("forwardTwo");
   target = forwardTwo.effectiveTarget;
   Expect.isFalse(forwardTwo.isMalformed);
-  Expect.isFalse(target.isPatch);
+  Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardTwo");
   Expect.equals("originTarget", target.name);
+
+  ConstructorElement forwardThree = clsA.lookupConstructor("forwardThree");
+  target = forwardThree.effectiveTarget;
+  Expect.isFalse(forwardThree.isMalformed);
+  Expect.isTrue(target.isInjected,
+      "Unexpected target $target for $forwardThree");
+  Expect.equals("injected", target.name);
 }
 
 Future testTypecheckPatchedMembers() async {
diff --git a/tests/compiler/dart2js/platform_consistency_test.dart b/tests/compiler/dart2js/platform_consistency_test.dart
index e946c16..fa50b29 100644
--- a/tests/compiler/dart2js/platform_consistency_test.dart
+++ b/tests/compiler/dart2js/platform_consistency_test.dart
@@ -20,12 +20,8 @@
   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) {
@@ -36,6 +32,5 @@
     }
     test(client);
     test(server);
-    test(dart2dart);
   }
  }
diff --git a/tests/compiler/dart2js/http_launch_data/http_launch_main.dart b/tests/compiler/dart2js/quarantined/http_launch_data/http_launch_main.dart
similarity index 100%
rename from tests/compiler/dart2js/http_launch_data/http_launch_main.dart
rename to tests/compiler/dart2js/quarantined/http_launch_data/http_launch_main.dart
diff --git a/tests/compiler/dart2js/http_launch_data/http_launch_main_package.dart b/tests/compiler/dart2js/quarantined/http_launch_data/http_launch_main_package.dart
similarity index 100%
rename from tests/compiler/dart2js/http_launch_data/http_launch_main_package.dart
rename to tests/compiler/dart2js/quarantined/http_launch_data/http_launch_main_package.dart
diff --git a/tests/compiler/dart2js/http_launch_data/lib1.dart b/tests/compiler/dart2js/quarantined/http_launch_data/lib1.dart
similarity index 100%
rename from tests/compiler/dart2js/http_launch_data/lib1.dart
rename to tests/compiler/dart2js/quarantined/http_launch_data/lib1.dart
diff --git a/tests/compiler/dart2js/http_launch_data/packages/simple/simple.dart b/tests/compiler/dart2js/quarantined/http_launch_data/packages/simple/simple.dart
similarity index 100%
rename from tests/compiler/dart2js/http_launch_data/packages/simple/simple.dart
rename to tests/compiler/dart2js/quarantined/http_launch_data/packages/simple/simple.dart
diff --git a/tests/compiler/dart2js/http_launch_data/pkcert/README b/tests/compiler/dart2js/quarantined/http_launch_data/pkcert/README
similarity index 100%
rename from tests/compiler/dart2js/http_launch_data/pkcert/README
rename to tests/compiler/dart2js/quarantined/http_launch_data/pkcert/README
diff --git a/tests/compiler/dart2js/http_launch_data/pkcert/cert9.db b/tests/compiler/dart2js/quarantined/http_launch_data/pkcert/cert9.db
similarity index 100%
rename from tests/compiler/dart2js/http_launch_data/pkcert/cert9.db
rename to tests/compiler/dart2js/quarantined/http_launch_data/pkcert/cert9.db
Binary files differ
diff --git a/tests/compiler/dart2js/http_launch_data/pkcert/key4.db b/tests/compiler/dart2js/quarantined/http_launch_data/pkcert/key4.db
similarity index 100%
rename from tests/compiler/dart2js/http_launch_data/pkcert/key4.db
rename to tests/compiler/dart2js/quarantined/http_launch_data/pkcert/key4.db
Binary files differ
diff --git a/tests/compiler/dart2js/quarantined/http_test.dart b/tests/compiler/dart2js/quarantined/http_test.dart
index cdb1348..328cea3 100644
--- a/tests/compiler/dart2js/quarantined/http_test.dart
+++ b/tests/compiler/dart2js/quarantined/http_test.dart
@@ -15,7 +15,9 @@
 import 'package:expect/expect.dart';
 import 'package:path/path.dart' as path;
 
-Uri pathOfData = Platform.script.resolve('../http_launch_data/');
+import '../launch_helper.dart' show launchDart2Js;
+
+Uri pathOfData = Platform.script.resolve('http_launch_data/');
 Directory tempDir;
 String outFilePath;
 
@@ -39,14 +41,6 @@
   });
 }
 
-Future launchDart2Js(args) {
-  String ext = Platform.isWindows ? '.bat' : '';
-  String command =
-      path.normalize(path.join(path.fromUri(Platform.script),
-                    '../../../../../sdk/bin/dart2js${ext}'));
-  return Process.run(command, args);
-}
-
 void check(ProcessResult result) {
   Expect.equals(0, result.exitCode);
   File outFile = new File(outFilePath);
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 2e1868a..5ddf37c 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -223,9 +223,11 @@
     FunctionElement fooA = classA.lookupLocalMember("foo");
 
     ResolverVisitor visitor = new ResolverVisitor(
-        compiler,
+        compiler.resolution,
         fooB,
-        new ResolutionRegistry(compiler, new CollectingTreeElements(fooB)),
+        new ResolutionRegistry(
+            compiler.backend,
+            new CollectingTreeElements(fooB)),
         scope: new MockTypeVariablesScope(classB.buildScope()));
     FunctionExpression node =
         (fooB as FunctionElementX).parseNode(compiler.parsingContext);
@@ -268,10 +270,10 @@
       ClassElement fooElement = compiler.mainApp.find("Foo");
       FunctionElement funElement = fooElement.lookupLocalMember("foo");
       ResolverVisitor visitor = new ResolverVisitor(
-          compiler,
+          compiler.resolution,
           funElement,
           new ResolutionRegistry(
-              compiler, new CollectingTreeElements(funElement)),
+              compiler.backend, new CollectingTreeElements(funElement)),
           scope: new MockTypeVariablesScope(fooElement.buildScope()));
       FunctionExpression function =
           (funElement as FunctionElementX).parseNode(compiler.parsingContext);
@@ -296,10 +298,10 @@
       ClassElement fooElement = compiler.mainApp.find("Foo");
       FunctionElement funElement = fooElement.lookupLocalMember("foo");
       ResolverVisitor visitor = new ResolverVisitor(
-          compiler,
+          compiler.resolution,
           funElement,
           new ResolutionRegistry(
-              compiler, new CollectingTreeElements(funElement)),
+              compiler.backend, new CollectingTreeElements(funElement)),
           scope: new MockTypeVariablesScope(fooElement.buildScope()));
       FunctionExpression function =
           (funElement as FunctionElementX).parseNode(compiler.parsingContext);
@@ -588,9 +590,11 @@
     compiler.parseScript("abstract class Bar {}");
 
     ResolverVisitor visitor = new ResolverVisitor(
-        compiler,
+        compiler.resolution,
         null,
-        new ResolutionRegistry(compiler, new CollectingTreeElements(null)));
+        new ResolutionRegistry(
+            compiler.backend,
+            new CollectingTreeElements(null)));
     compiler.resolveStatement("Foo bar;");
 
     ClassElement fooElement = compiler.mainApp.find('Foo');
@@ -707,9 +711,11 @@
     element = classElement.lookupConstructor(constructor);
     FunctionExpression tree = (element as FunctionElement).node;
     ResolverVisitor visitor = new ResolverVisitor(
-        compiler,
+        compiler.resolution,
         element,
-        new ResolutionRegistry(compiler, new CollectingTreeElements(element)),
+        new ResolutionRegistry(
+            compiler.backend,
+            new CollectingTreeElements(element)),
         scope: classElement.buildScope());
     new InitializerResolver(visitor, element, tree).resolveInitializers();
     visitor.visit(tree.body);
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
index 1019d8c..3004a61 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
@@ -661,6 +661,8 @@
         const [
           const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
               element: 'field(C#m)'),
+          const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+              element: 'field(C#n)'),
         ]),
     const Test.clazz(
         '''
@@ -787,7 +789,9 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
-                element: 'field(C#m)'),
+              element: 'field(C#m)'),
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+              element: 'field(C#n)'),
         ]),
     const Test.clazz(
         '''
@@ -797,7 +801,13 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
-                element: 'field(C#m)'),
+              element: 'field(C#k)'),
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+              element: 'field(C#l)'),
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+              element: 'field(C#m)'),
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+              element: 'field(C#n)'),
         ]),
     const Test.clazz(
         '''
@@ -820,6 +830,9 @@
           const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
                 element: 'field(C#m)',
                 rhs: 42),
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+              element: 'field(C#n)',
+              rhs: true),
         ]),
     const Test.clazz(
         '''
@@ -846,7 +859,9 @@
         ''',
         const [
           const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
-                element: 'field(m)'),
+              element: 'field(m)'),
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+              element: 'field(n)'),
         ]),
     const Test(
         '''
diff --git a/tests/compiler/dart2js/serialization/analysis1_test.dart b/tests/compiler/dart2js/serialization/analysis1_test.dart
index 1b8532e..e78f634 100644
--- a/tests/compiler/dart2js/serialization/analysis1_test.dart
+++ b/tests/compiler/dart2js/serialization/analysis1_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.analysis1_test;
 
 import 'analysis_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['0', '${TESTS.length ~/ 2}']);
+  test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/analysis2_test.dart b/tests/compiler/dart2js/serialization/analysis2_test.dart
index b13a6a3..05c3339 100644
--- a/tests/compiler/dart2js/serialization/analysis2_test.dart
+++ b/tests/compiler/dart2js/serialization/analysis2_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.analysis2_test;
 
 import 'analysis_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['${TESTS.length ~/ 2}']);
+  test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/analysis3_test.dart b/tests/compiler/dart2js/serialization/analysis3_test.dart
new file mode 100644
index 0000000..84da9d9
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/analysis3_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.analysis3_test;
+
+import 'analysis_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/analysis4_test.dart b/tests/compiler/dart2js/serialization/analysis4_test.dart
new file mode 100644
index 0000000..ff5c1ac
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/analysis4_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.analysis4_test;
+
+import 'analysis_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/analysis5_test.dart b/tests/compiler/dart2js/serialization/analysis5_test.dart
new file mode 100644
index 0000000..4e44643
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/analysis5_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.analysis5_test;
+
+import 'analysis_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/analysis_test_helper.dart b/tests/compiler/dart2js/serialization/analysis_test_helper.dart
index 152972b..82be8ee 100644
--- a/tests/compiler/dart2js/serialization/analysis_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/analysis_test_helper.dart
@@ -14,6 +14,12 @@
 import 'helper.dart';
 import 'test_data.dart';
 
+/// Number of tests that are not part of the automatic test grouping.
+int SKIP_COUNT = 0;
+
+/// Number of groups that the [TESTS] are split into.
+int SPLIT_COUNT = 5;
+
 main(List<String> args) {
   asyncTest(() async {
     Arguments arguments = new Arguments.from(args);
@@ -27,6 +33,7 @@
     } else {
       await arguments.forEachTest(serializedData, TESTS, analyze);
     }
+    printMeasurementResults();
   });
 }
 
@@ -39,27 +46,27 @@
      bool verbose: false}) async {
   String testDescription = test != null ? test.name : '${entryPoint}';
   String id = index != null ? '$index: ' : '';
-  print('------------------------------------------------------------------');
-  print('analyze ${id}${testDescription}');
-  print('------------------------------------------------------------------');
-  DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
-  await runCompiler(
-      entryPoint: entryPoint,
-      resolutionInputs: resolutionInputs,
-      memorySourceFiles: sourceFiles,
-      options: [Flags.analyzeOnly],
-      diagnosticHandler: diagnosticCollector);
-  if (test != null) {
-    Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length,
-        "Unexpected error count.");
-    Expect.equals(
-        test.expectedWarningCount,
-        diagnosticCollector.warnings.length,
-        "Unexpected warning count.");
-    Expect.equals(test.expectedHintCount, diagnosticCollector.hints.length,
-        "Unexpected hint count.");
-    Expect.equals(test.expectedInfoCount, diagnosticCollector.infos.length,
-        "Unexpected info count.");
-  }
+  String title = '${id}${testDescription}';
+  await measure(title, 'analyze', () async {
+    DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
+    await runCompiler(
+        entryPoint: entryPoint,
+        resolutionInputs: resolutionInputs,
+        memorySourceFiles: sourceFiles,
+        options: [Flags.analyzeOnly],
+        diagnosticHandler: diagnosticCollector);
+    if (test != null) {
+      Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length,
+          "Unexpected error count.");
+      Expect.equals(
+          test.expectedWarningCount,
+          diagnosticCollector.warnings.length,
+          "Unexpected warning count.");
+      Expect.equals(test.expectedHintCount, diagnosticCollector.hints.length,
+          "Unexpected hint count.");
+      Expect.equals(test.expectedInfoCount, diagnosticCollector.infos.length,
+          "Unexpected info count.");
+    }
+  });
 }
 
diff --git a/tests/compiler/dart2js/serialization/compilation0_test.dart b/tests/compiler/dart2js/serialization/compilation0_test.dart
index 9df7f53..3e68dd2 100644
--- a/tests/compiler/dart2js/serialization/compilation0_test.dart
+++ b/tests/compiler/dart2js/serialization/compilation0_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.compilation0_test;
 
 import 'compilation_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['0', '0']);
+  test.main(testSkipped(0, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/compilation1_test.dart b/tests/compiler/dart2js/serialization/compilation1_test.dart
index e3f6176..f59e0a0 100644
--- a/tests/compiler/dart2js/serialization/compilation1_test.dart
+++ b/tests/compiler/dart2js/serialization/compilation1_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.compilation1_test;
 
 import 'compilation_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['1', '${TESTS.length ~/ 4}']);
+  test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/compilation2_test.dart b/tests/compiler/dart2js/serialization/compilation2_test.dart
index 6141cbb..1947010 100644
--- a/tests/compiler/dart2js/serialization/compilation2_test.dart
+++ b/tests/compiler/dart2js/serialization/compilation2_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.compilation2_test;
 
 import 'compilation_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['${TESTS.length ~/ 4}', '${2 * TESTS.length ~/ 4}']);
+  test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/compilation3_test.dart b/tests/compiler/dart2js/serialization/compilation3_test.dart
index c168f22..90bc6ff 100644
--- a/tests/compiler/dart2js/serialization/compilation3_test.dart
+++ b/tests/compiler/dart2js/serialization/compilation3_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.compilation3_test;
 
 import 'compilation_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['${2 * TESTS.length ~/ 4}', '${3 * TESTS.length ~/ 4}']);
+  test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/compilation4_test.dart b/tests/compiler/dart2js/serialization/compilation4_test.dart
index 7e2dc7c..809f62b 100644
--- a/tests/compiler/dart2js/serialization/compilation4_test.dart
+++ b/tests/compiler/dart2js/serialization/compilation4_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.compilation4_test;
 
 import 'compilation_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['${3 * TESTS.length ~/ 4}']);
+  test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/compilation5_test.dart b/tests/compiler/dart2js/serialization/compilation5_test.dart
new file mode 100644
index 0000000..10ce5eb
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/compilation5_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.compilation5_test;
+
+import 'compilation_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/compilation_1_test.dart b/tests/compiler/dart2js/serialization/compilation_1_test.dart
new file mode 100644
index 0000000..355cddc
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/compilation_1_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.compilation_1_test;
+
+import 'compilation_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSkipped(1, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/compilation_test_helper.dart b/tests/compiler/dart2js/serialization/compilation_test_helper.dart
index 9889bf4..0a44ce2e 100644
--- a/tests/compiler/dart2js/serialization/compilation_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/compilation_test_helper.dart
@@ -6,13 +6,19 @@
 
 import 'dart:async';
 import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/filenames.dart';
 import '../memory_compiler.dart';
 import 'helper.dart';
 import 'test_data.dart';
 import '../output_collector.dart';
 
+/// Number of tests that are not part of the automatic test grouping.
+int SKIP_COUNT = 2;
+
+/// Number of groups that the [TESTS] are split into.
+int SPLIT_COUNT = 5;
+
 main(List<String> args) {
   asyncTest(() async {
     Arguments arguments = new Arguments.from(args);
@@ -28,6 +34,7 @@
       Uri entryPoint = Uri.parse('memory:main.dart');
       await arguments.forEachTest(serializedData, TESTS, compile);
     }
+    printMeasurementResults();
   });
 }
 
@@ -40,16 +47,20 @@
      bool verbose: false}) async {
   String testDescription = test != null ? test.name : '${entryPoint}';
   String id = index != null ? '$index: ' : '';
-  print('------------------------------------------------------------------');
-  print('compile ${id}${testDescription}');
-  print('------------------------------------------------------------------');
+  String title = '${id}${testDescription}';
   OutputCollector outputCollector = new OutputCollector();
-  await runCompiler(
-      entryPoint: entryPoint,
-      memorySourceFiles: sourceFiles,
-      resolutionInputs: resolutionInputs,
-      options: [],
-      outputProvider: outputCollector);
+  await measure(title, 'compile', () async {
+    List<String> options = [];
+    if (test.checkedMode) {
+      options.add(Flags.enableCheckedMode);
+    }
+    await runCompiler(
+        entryPoint: entryPoint,
+        memorySourceFiles: sourceFiles,
+        resolutionInputs: resolutionInputs,
+        options: options,
+        outputProvider: outputCollector);
+  });
   if (verbose) {
     print(outputCollector.getOutput('', 'js'));
   }
diff --git a/tests/compiler/dart2js/serialization/equivalence_test.dart b/tests/compiler/dart2js/serialization/equivalence_test.dart
index 4e3d6e2..ee110f6 100644
--- a/tests/compiler/dart2js/serialization/equivalence_test.dart
+++ b/tests/compiler/dart2js/serialization/equivalence_test.dart
@@ -27,9 +27,34 @@
 
 const TEST_SOURCES = const <String, String>{
   'main.dart': '''
-import 'a.dart' deferred as a;
+import 'library.dart';
+import 'deferred_library.dart' deferred as prefix;
+
+asyncMethod() async {}
+asyncStarMethod() async* {}
+syncStarMethod() sync* {}
+get asyncGetter async {}
+get asyncStarGetter async* {}
+get syncStarGetter sync* {}
+
+genericMethod<T>() {}
+
+class Class1 {
+  factory Class1.deferred() = prefix.DeferredClass;
+  factory Class1.unresolved() = Unresolved;
+}
 ''',
-  'a.dart': '''
+  'deferred_library.dart': '''
+class DeferredClass {
+}
+
+get getter => 0;
+set setter(_) {}
+get property => 0;
+set property(_) {}
+''',
+  'library.dart': '''
+class Type {}
 ''',
 };
 
@@ -65,7 +90,7 @@
     CompilationResult result = await runCompiler(
         memorySourceFiles: sourceFiles,
         entryPoint: entryPoint,
-        options: [Flags.analyzeAll]);
+        options: [Flags.analyzeAll, Flags.genericMethodSyntax]);
     Compiler compiler = result.compiler;
     testSerialization(
         compiler.libraryLoader.libraries,
@@ -277,6 +302,9 @@
 
   void visit(Element element1, Element element2) {
     if (element1 == null && element2 == null) return;
+    if (element1 == null || element2 == null) {
+      throw currentCheck;
+    }
     element1 = element1.declaration;
     element2 = element2.declaration;
     if (element1 == element2) return;
@@ -333,22 +361,35 @@
         LibrarySerializer.getCompilationUnits(element1),
         LibrarySerializer.getCompilationUnits(element2));
 
-    checkElementListIdentities(
+    checkElementLists(
         element1, element2, 'imports',
         LibrarySerializer.getImports(element1),
         LibrarySerializer.getImports(element2));
-    checkElementListIdentities(
+    checkElementLists(
         element1, element2, 'exports', element1.exports, element2.exports);
 
+    List<Element> imported1 = LibrarySerializer.getImportedElements(element1);
+    List<Element> imported2 = LibrarySerializer.getImportedElements(element2);
     checkElementListIdentities(
-        element1, element2, 'importScope',
-        LibrarySerializer.getImportedElements(element1),
-        LibrarySerializer.getImportedElements(element2));
+        element1, element2, 'importScope', imported1, imported2);
 
     checkElementListIdentities(
         element1, element2, 'exportScope',
         LibrarySerializer.getExportedElements(element1),
         LibrarySerializer.getExportedElements(element2));
+
+    for (int index = 0; index < imported1.length; index++) {
+      checkImportsFor(element1, element2, imported1[index], imported2[index]);
+    }
+  }
+
+  void checkImportsFor(Element element1, Element element2,
+      Element import1, Element import2) {
+    List<ImportElement> imports1 = element1.library.getImportsFor(import1);
+    List<ImportElement> imports2 = element2.library.getImportsFor(import2);
+    checkElementListIdentities(
+        element1, element2, 'importsFor($import1/$import2)',
+        imports1, imports2);
   }
 
   @override
@@ -639,6 +680,8 @@
         element1, element2, 'functionSignature.orderedOptionalParameters',
         element1.functionSignature.orderedOptionalParameters,
         element2.functionSignature.orderedOptionalParameters);
+    checkTypeLists(element1, element2, 'typeVariables',
+        element1.typeVariables, element2.typeVariables);
   }
 
   @override
@@ -678,6 +721,17 @@
         element1.isRedirectingFactory, element2.isRedirectingFactory);
     checkElementIdentities(element1, element2, 'effectiveTarget',
         element1.effectiveTarget, element2.effectiveTarget);
+    if (element1.isRedirectingFactory) {
+      checkElementIdentities(element1, element2, 'immediateRedirectionTarget',
+          element1.immediateRedirectionTarget,
+          element2.immediateRedirectionTarget);
+      checkElementIdentities(element1, element2, 'redirectionDeferredPrefix',
+          element1.redirectionDeferredPrefix,
+          element2.redirectionDeferredPrefix);
+      check(element1, element2, 'isEffectiveTargetMalformed',
+          element1.isEffectiveTargetMalformed,
+          element2.isEffectiveTargetMalformed);
+    }
     checkElementIdentities(element1, element2, 'definingConstructor',
         element1.definingConstructor, element2.definingConstructor);
     check(
@@ -817,6 +871,19 @@
       checkElementProperties(element1, element2,
           'loadLibrary', element1.loadLibrary, element2.loadLibrary);
     }
-    // TODO(johnniwinther): Check members.
+    element1.forEachLocalMember((Element member1) {
+      String name = member1.name;
+      Element member2 = element2.lookupLocalMember(name);
+      checkElementIdentities(element1, element2, 'lookupLocalMember:$name',
+          member1, member2);
+      checkImportsFor(element1, element2, member1, member2);
+    });
+  }
+
+  @override
+  void visitErroneousElement(
+      ErroneousElement element1, ErroneousElement element2) {
+    check(element1, element2, 'messageKind',
+        element1.messageKind, element2.messageKind);
   }
 }
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
index e5fab48..0c986a1 100644
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -77,9 +77,9 @@
       TestFunction testFunction) async {
     Uri entryPoint = Uri.parse('memory:main.dart');
     int first = start ?? 0;
-    int last = end ?? tests.length - 1;
+    int last = end ?? tests.length;
 
-    for (int index = first; index <= last; index++) {
+    for (int index = first; index < last; index++) {
       Test test = TESTS[index];
       List<SerializedData> dataList =
           await preserializeData(serializedData, test);
@@ -115,28 +115,28 @@
      bool verbose});
 
 Future<SerializedData> serializeDartCore(
-    {Arguments arguments: const Arguments()}) async {
-  Uri uri = Uri.parse('memory:${arguments.serializedDataFileName}');
-  print('------------------------------------------------------------------');
-  print('serialize dart:core');
-  print('------------------------------------------------------------------');
-  SerializedData serializedData;
-  if (arguments.loadSerializedData) {
-    File file = new File(arguments.serializedDataFileName);
-    if (file.existsSync()) {
-      print('Loading data from $file');
-      serializedData = new SerializedData(uri, file.readAsStringSync());
+    {Arguments arguments: const Arguments()}) {
+  return measure('dart:core', 'serialize', () async {
+    Uri uri = Uri.parse('memory:${arguments.serializedDataFileName}');
+    SerializedData serializedData;
+    if (arguments.loadSerializedData) {
+      File file = new File(arguments.serializedDataFileName);
+      if (file.existsSync()) {
+        print('Loading data from $file');
+        serializedData = new SerializedData(uri, file.readAsStringSync());
+      }
+    } else {
+      SerializationResult result =
+          await serialize(Uris.dart_core, dataUri: uri);
+      serializedData = result.serializedData;
     }
-  } else {
-    SerializationResult result = await serialize(Uris.dart_core, dataUri: uri);
-    serializedData = result.serializedData;
-  }
-  if (arguments.saveSerializedData) {
-    File file = new File(arguments.serializedDataFileName);
-    print('Saving data to $file');
-    file.writeAsStringSync(serializedData.data);
-  }
-  return serializedData;
+    if (arguments.saveSerializedData) {
+      File file = new File(arguments.serializedDataFileName);
+      print('Saving data to $file');
+      file.writeAsStringSync(serializedData.data);
+    }
+    return serializedData;
+  });
 }
 
 class SerializationResult {
@@ -149,20 +149,22 @@
 Future<SerializationResult> serialize(Uri entryPoint,
     {Map<String, String> memorySourceFiles: const <String, String>{},
      List<Uri> resolutionInputs: const <Uri>[],
-     Uri dataUri}) async {
+     Uri dataUri,
+     bool deserializeCompilationDataForTesting: false}) async {
   if (dataUri == null) {
     dataUri = Uri.parse('memory:${DEFAULT_DATA_FILE_NAME}');
   }
+  OutputCollector outputCollector = new OutputCollector();
   Compiler compiler = compilerFor(
-      options: [Flags.analyzeAll],
+      options: [Flags.resolveOnly],
       memorySourceFiles: memorySourceFiles,
-      resolutionInputs: resolutionInputs);
-  compiler.serialization.supportSerialization = true;
+      resolutionInputs: resolutionInputs,
+      outputProvider: outputCollector);
+  compiler.serialization.deserializeCompilationDataForTesting =
+      deserializeCompilationDataForTesting;
   await compiler.run(entryPoint);
-  BufferedEventSink sink = new BufferedEventSink();
-  compiler.serialization.serializeToSink(
-      sink, compiler.libraryLoader.libraries);
-  SerializedData serializedData = new SerializedData(dataUri, sink.text);
+  SerializedData serializedData = new SerializedData(
+      dataUri, outputCollector.getOutput('', 'data'));
   return new SerializationResult(compiler, serializedData);
 }
 
@@ -170,7 +172,10 @@
   final Uri uri;
   final String data;
 
-  SerializedData(this.uri, this.data);
+  SerializedData(this.uri, this.data) {
+    assert(uri != null);
+    assert(data != null);
+  }
 
   Map<String, String> toMemorySourceFiles([Map<String, String> input]) {
     Map<String, String> sourceFiles = <String, String>{};
@@ -201,13 +206,6 @@
   }
 }
 
-String extractSerializedData(
-    Compiler compiler, Iterable<LibraryElement> libraries) {
-  BufferedEventSink sink = new BufferedEventSink();
-  compiler.serialization.serializeToSink(sink, libraries);
-  return sink.text;
-}
-
 Future<List<SerializedData>> preserializeData(
     SerializedData serializedData, Test test) async {
   if (test == null ||
@@ -224,19 +222,76 @@
   if (test.unserializedSourceFiles != null) {
     sourceFiles.addAll(test.unserializedSourceFiles);
   }
+  OutputCollector outputCollector = new OutputCollector();
   Compiler compiler = compilerFor(
       memorySourceFiles: sourceFiles,
       resolutionInputs: serializedData.toUris(),
-      options: [Flags.analyzeOnly, Flags.analyzeMain]);
+      options: [Flags.resolveOnly],
+      outputProvider: outputCollector);
   compiler.librariesToAnalyzeWhenRun = uriList;
-  compiler.serialization.supportSerialization = true;
   await compiler.run(null);
   List<LibraryElement> libraries = <LibraryElement>[];
   for (Uri uri in uriList) {
     libraries.add(compiler.libraryLoader.lookupLibrary(uri));
   }
-  SerializedData additionalSerializedData =
-      new SerializedData(Uri.parse('memory:additional.data'),
-      extractSerializedData(compiler, libraries));
+  SerializedData additionalSerializedData = new SerializedData(
+      Uri.parse('memory:additional.data'),
+      outputCollector.getOutput('', 'data'));
   return <SerializedData>[serializedData, additionalSerializedData];
 }
+
+class MeasurementResult {
+  final String title;
+  final String taskTitle;
+  final int elapsedMilliseconds;
+
+  MeasurementResult(this.title, this.taskTitle, this.elapsedMilliseconds);
+}
+
+final List<MeasurementResult> measurementResults = <MeasurementResult>[];
+
+/// Print all store [measurementResults] grouped by title and sorted by
+/// decreasing execution time.
+void printMeasurementResults() {
+  Map<String, int> totals = <String, int>{};
+
+  for (MeasurementResult result in measurementResults) {
+    totals.putIfAbsent(result.title, () => 0);
+    totals[result.title] += result.elapsedMilliseconds;
+  }
+
+  List<String> sorted = totals.keys.toList();
+  sorted.sort((a, b) => -totals[a].compareTo(totals[b]));
+
+  int paddingLength = '${totals[sorted.first]}'.length;
+
+  String pad(int value) {
+    String text = '$value';
+    return '${' ' * (paddingLength - text.length)}$text';
+  }
+
+  print('================================================================');
+  print('Summary:');
+  for (String task in sorted) {
+    int time = totals[task];
+    print('${pad(time)}ms $task');
+  }
+
+  measurementResults.clear();
+}
+
+/// Measure execution of [task], print the result and store it in
+/// [measurementResults] for a summary.
+Future measure(String title, String taskTitle, Future task()) async {
+  Stopwatch stopwatch = new Stopwatch()..start();
+  print('================================================================');
+  print('$taskTitle: $title');
+  print('----------------------------------------------------------------');
+  var result = await task();
+  stopwatch.stop();
+  int elapsedMilliseconds = stopwatch.elapsedMilliseconds;
+  print('$taskTitle: $title: ${elapsedMilliseconds}ms');
+  measurementResults.add(
+      new MeasurementResult(title, taskTitle, elapsedMilliseconds));
+  return result;
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/serialization/model0_test.dart b/tests/compiler/dart2js/serialization/model0_test.dart
new file mode 100644
index 0000000..c4ef537
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/model0_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.model0_test;
+
+import 'model_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSkipped(0, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/model1_test.dart b/tests/compiler/dart2js/serialization/model1_test.dart
index 9582274..aec8489 100644
--- a/tests/compiler/dart2js/serialization/model1_test.dart
+++ b/tests/compiler/dart2js/serialization/model1_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.model1_test;
 
 import 'model_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['0', '${TESTS.length ~/ 2}']);
+  test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/model2_test.dart b/tests/compiler/dart2js/serialization/model2_test.dart
index 369e4a1..8f02334 100644
--- a/tests/compiler/dart2js/serialization/model2_test.dart
+++ b/tests/compiler/dart2js/serialization/model2_test.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization.model2_test;
 
 import 'model_test_helper.dart' as test;
-import 'test_data.dart';
+import 'test_helper.dart';
 
 main() {
-  test.main(['${TESTS.length ~/ 2}']);
+  test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
 }
diff --git a/tests/compiler/dart2js/serialization/model3_test.dart b/tests/compiler/dart2js/serialization/model3_test.dart
new file mode 100644
index 0000000..d3a2ff1
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/model3_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.model3_test;
+
+import 'model_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/model4_test.dart b/tests/compiler/dart2js/serialization/model4_test.dart
new file mode 100644
index 0000000..5871fc2
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/model4_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.model4_test;
+
+import 'model_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/model5_test.dart b/tests/compiler/dart2js/serialization/model5_test.dart
new file mode 100644
index 0000000..9cf0596
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/model5_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.model5_test;
+
+import 'model_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/model_1_test.dart b/tests/compiler/dart2js/serialization/model_1_test.dart
new file mode 100644
index 0000000..e74bd17
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/model_1_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.model_1_test;
+
+import 'model_test_helper.dart' as test;
+import 'test_helper.dart';
+
+main() {
+  test.main(testSkipped(1, test.SKIP_COUNT));
+}
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
index 2c6d861..ef92303 100644
--- a/tests/compiler/dart2js/serialization/model_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/model_test_helper.dart
@@ -10,7 +10,10 @@
 import 'package:expect/expect.dart';
 import 'package:compiler/src/closure.dart';
 import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common.dart';
+import 'package:compiler/src/constants/values.dart';
 import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/deferred_load.dart';
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/filenames.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
@@ -22,6 +25,12 @@
 import 'test_data.dart';
 import 'test_helper.dart';
 
+/// Number of tests that are not part of the automatic test grouping.
+int SKIP_COUNT = 2;
+
+/// Number of groups that the [TESTS] are split into.
+int SPLIT_COUNT = 5;
+
 main(List<String> args) {
   asyncTest(() async {
     Arguments arguments = new Arguments.from(args);
@@ -29,13 +38,24 @@
         await serializeDartCore(arguments: arguments);
     if (arguments.filename != null) {
       Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
+      SerializationResult result = await measure(
+          '${entryPoint}', 'serialize', () {
+        return serialize(
+            entryPoint,
+            memorySourceFiles: serializedData.toMemorySourceFiles(),
+            resolutionInputs: serializedData.toUris(),
+            dataUri: Uri.parse('memory:test.data'));
+      });
       await checkModels(entryPoint,
-          sourceFiles: serializedData.toMemorySourceFiles(),
-          resolutionInputs: serializedData.toUris());
+          sourceFiles: serializedData.toMemorySourceFiles(
+              result.serializedData.toMemorySourceFiles()),
+          resolutionInputs: serializedData.toUris(
+              result.serializedData.toUris()));
     } else {
       Uri entryPoint = Uri.parse('memory:main.dart');
       await arguments.forEachTest(serializedData, TESTS, checkModels);
     }
+    printMeasurementResults();
   });
 }
 
@@ -48,88 +68,133 @@
      bool verbose: false}) async {
   String testDescription = test != null ? test.name : '${entryPoint}';
   String id = index != null ? '$index: ' : '';
-  print('------------------------------------------------------------------');
-  print('compile normal ${id}${testDescription}');
-  print('------------------------------------------------------------------');
-  Compiler compilerNormal = compilerFor(
-      memorySourceFiles: sourceFiles,
-      options: [Flags.analyzeOnly]);
-  compilerNormal.resolution.retainCachesForTesting = true;
-  await compilerNormal.run(entryPoint);
-  compilerNormal.phase = Compiler.PHASE_DONE_RESOLVING;
-  compilerNormal.world.populate();
-  compilerNormal.backend.onResolutionComplete();
+  String title = '${id}${testDescription}';
+  Compiler compilerNormal = await measure(
+      title, 'compile normal', () async {
+    Compiler compilerNormal = compilerFor(
+        memorySourceFiles: sourceFiles,
+        options: [Flags.analyzeOnly]);
+    compilerNormal.resolution.retainCachesForTesting = true;
+    await compilerNormal.run(entryPoint);
+    compilerNormal.phase = Compiler.PHASE_DONE_RESOLVING;
+    compilerNormal.world.populate();
+    compilerNormal.backend.onResolutionComplete();
+    compilerNormal.deferredLoadTask.onResolutionComplete(
+        compilerNormal.mainFunction);
+    return compilerNormal;
+  });
 
-  print('------------------------------------------------------------------');
-  print('compile deserialized ${id}${testDescription}');
-  print('------------------------------------------------------------------');
-  Compiler compilerDeserialized = compilerFor(
-      memorySourceFiles: sourceFiles,
-      resolutionInputs: resolutionInputs,
-      options: [Flags.analyzeOnly]);
-  compilerDeserialized.resolution.retainCachesForTesting = true;
-  await compilerDeserialized.run(entryPoint);
-  compilerDeserialized.phase = Compiler.PHASE_DONE_RESOLVING;
-  compilerDeserialized.world.populate();
-  compilerDeserialized.backend.onResolutionComplete();
+  Compiler compilerDeserialized = await measure(
+      title, 'compile deserialized', () async {
+    Compiler compilerDeserialized = compilerFor(
+        memorySourceFiles: sourceFiles,
+        resolutionInputs: resolutionInputs,
+        options: [Flags.analyzeOnly]);
+    compilerDeserialized.resolution.retainCachesForTesting = true;
+    await compilerDeserialized.run(entryPoint);
+    compilerDeserialized.phase = Compiler.PHASE_DONE_RESOLVING;
+    compilerDeserialized.world.populate();
+    compilerDeserialized.backend.onResolutionComplete();
+    compilerDeserialized.deferredLoadTask.onResolutionComplete(
+        compilerDeserialized.mainFunction);
+    return compilerDeserialized;
+  });
 
-  checkAllImpacts(
-      compilerNormal, compilerDeserialized,
-      verbose: verbose);
+  return measure(title, 'check models', () async {
+    checkAllImpacts(
+        compilerNormal, compilerDeserialized,
+        verbose: verbose);
 
-  checkSets(
-      compilerNormal.resolverWorld.directlyInstantiatedClasses,
-      compilerDeserialized.resolverWorld.directlyInstantiatedClasses,
-      "Directly instantiated classes mismatch",
-      areElementsEquivalent,
-      verbose: verbose);
+    checkSets(
+        compilerNormal.resolverWorld.directlyInstantiatedClasses,
+        compilerDeserialized.resolverWorld.directlyInstantiatedClasses,
+        "Directly instantiated classes mismatch",
+        areElementsEquivalent,
+        verbose: verbose);
 
-  checkSets(
-      compilerNormal.resolverWorld.instantiatedTypes,
-      compilerDeserialized.resolverWorld.instantiatedTypes,
-      "Instantiated types mismatch",
-      areTypesEquivalent,
-      verbose: verbose);
+    checkSets(
+        compilerNormal.resolverWorld.instantiatedTypes,
+        compilerDeserialized.resolverWorld.instantiatedTypes,
+        "Instantiated types mismatch",
+        areTypesEquivalent,
+        verbose: verbose);
 
-  checkSets(
-      compilerNormal.resolverWorld.isChecks,
-      compilerDeserialized.resolverWorld.isChecks,
-      "Is-check mismatch",
-      areTypesEquivalent,
-      verbose: verbose);
+    checkSets(
+        compilerNormal.resolverWorld.isChecks,
+        compilerDeserialized.resolverWorld.isChecks,
+        "Is-check mismatch",
+        areTypesEquivalent,
+        verbose: verbose);
 
-  checkSets(
-      compilerNormal.enqueuer.resolution.processedElements,
-      compilerDeserialized.enqueuer.resolution.processedElements,
-      "Processed element mismatch",
-      areElementsEquivalent,
-      onSameElement: (a, b) {
-        checkElements(
-            compilerNormal, compilerDeserialized, a, b, verbose: verbose);
-      },
-      verbose: verbose);
+    checkSets(
+        compilerNormal.enqueuer.resolution.processedElements,
+        compilerDeserialized.enqueuer.resolution.processedElements,
+        "Processed element mismatch",
+        areElementsEquivalent,
+        onSameElement: (a, b) {
+          checkElements(
+              compilerNormal, compilerDeserialized, a, b, verbose: verbose);
+        },
+        verbose: verbose);
 
-  checkClassHierarchyNodes(
-      compilerNormal,
-      compilerDeserialized,
-      compilerNormal.world.getClassHierarchyNode(
-          compilerNormal.coreClasses.objectClass),
-      compilerDeserialized.world.getClassHierarchyNode(
-          compilerDeserialized.coreClasses.objectClass),
-      verbose: verbose);
+    checkClassHierarchyNodes(
+        compilerNormal,
+        compilerDeserialized,
+        compilerNormal.world.getClassHierarchyNode(
+            compilerNormal.coreClasses.objectClass),
+        compilerDeserialized.world.getClassHierarchyNode(
+            compilerDeserialized.coreClasses.objectClass),
+        verbose: verbose);
 
-  Expect.equals(compilerNormal.enabledInvokeOn,
-      compilerDeserialized.enabledInvokeOn,
-      "Compiler.enabledInvokeOn mismatch");
-  Expect.equals(compilerNormal.enabledFunctionApply,
-      compilerDeserialized.enabledFunctionApply,
-      "Compiler.enabledFunctionApply mismatch");
-  Expect.equals(compilerNormal.enabledRuntimeType,
-      compilerDeserialized.enabledRuntimeType,
-      "Compiler.enabledRuntimeType mismatch");
-  Expect.equals(compilerNormal.hasIsolateSupport,
-      compilerDeserialized.hasIsolateSupport,
-      "Compiler.hasIsolateSupport mismatch");
+    Expect.equals(compilerNormal.enabledInvokeOn,
+        compilerDeserialized.enabledInvokeOn,
+        "Compiler.enabledInvokeOn mismatch");
+    Expect.equals(compilerNormal.enabledFunctionApply,
+        compilerDeserialized.enabledFunctionApply,
+        "Compiler.enabledFunctionApply mismatch");
+    Expect.equals(compilerNormal.enabledRuntimeType,
+        compilerDeserialized.enabledRuntimeType,
+        "Compiler.enabledRuntimeType mismatch");
+    Expect.equals(compilerNormal.hasIsolateSupport,
+        compilerDeserialized.hasIsolateSupport,
+        "Compiler.hasIsolateSupport mismatch");
+    Expect.equals(
+        compilerNormal.deferredLoadTask.isProgramSplit,
+        compilerDeserialized.deferredLoadTask.isProgramSplit,
+        "isProgramSplit mismatch");
+
+    Map<ConstantValue, OutputUnit> constants1 =
+        compilerNormal.deferredLoadTask.outputUnitForConstantsForTesting;
+    Map<ConstantValue, OutputUnit> constants2 =
+        compilerDeserialized.deferredLoadTask.outputUnitForConstantsForTesting;
+    checkSets(
+        constants1.keys,
+        constants2.keys,
+        'deferredLoadTask._outputUnitForConstants.keys',
+        areConstantValuesEquivalent,
+        failOnUnfound: false,
+        failOnExtra: false,
+        onSameElement: (ConstantValue value1, ConstantValue value2) {
+          OutputUnit outputUnit1 = constants1[value1];
+          OutputUnit outputUnit2 = constants2[value2];
+          checkOutputUnits(outputUnit1, outputUnit2,
+              'for ${value1.toStructuredText()} '
+                  'vs ${value2.toStructuredText()}');
+        },
+        onUnfoundElement: (ConstantValue value1) {
+          OutputUnit outputUnit1 = constants1[value1];
+          Expect.isTrue(outputUnit1.isMainOutput,
+              "Missing deferred constant: ${value1.toStructuredText()}");
+        },
+        onExtraElement: (ConstantValue value2) {
+          OutputUnit outputUnit2 = constants2[value2];
+          Expect.isTrue(outputUnit2.isMainOutput,
+              "Extra deferred constant: ${value2.toStructuredText()}");
+        },
+        elementToString: (a) {
+          return '${a.toStructuredText()} -> ${constants1[a]}/${constants2[a]}';
+        });
+  });
 }
 
 void checkElements(
@@ -182,6 +247,28 @@
         "$element1.variablesUsedInTryOrGenerator",
         areLocalsEquivalent,
         verbose: verbose);
+    if (element1 is MemberElement && element2 is MemberElement) {
+      MemberElement member1 = element1.implementation;
+      MemberElement member2 = element2.implementation;
+      checkSets(
+          member1.nestedClosures,
+          member2.nestedClosures,
+          "$member1.nestedClosures",
+          areElementsEquivalent,
+          verbose: verbose,
+          onSameElement: (a, b) {
+            LocalFunctionElement localFunction1 = a.expression;
+            LocalFunctionElement localFunction2 = b.expression;
+            checkElementIdentities(
+                localFunction1, localFunction2,
+                'enclosingClass',
+                localFunction1.enclosingClass, localFunction2.enclosingClass);
+            testResolvedAstEquivalence(
+                localFunction1.resolvedAst,
+                localFunction2.resolvedAst,
+                const CheckStrategy());
+          });
+    }
   }
   JavaScriptBackend backend1 = compiler1.backend;
   JavaScriptBackend backend2 = compiler2.backend;
@@ -189,6 +276,8 @@
       backend1.inlineCache.getCurrentCacheDecisionForTesting(element1),
       backend2.inlineCache.getCurrentCacheDecisionForTesting(element2),
       "Inline cache decision mismatch for $element1 vs $element2");
+
+  checkElementOutputUnits(compiler1, compiler2, element1, element2);
 }
 
 void checkMixinUses(
@@ -302,4 +391,26 @@
     return '(${node.runtimeType}) ${text.substring(0, 37)}...';
   }
   return '(${node.runtimeType}) $text';
-}
\ No newline at end of file
+}
+
+void checkElementOutputUnits(
+    Compiler compiler1, Compiler compiler2,
+    Element element1, Element element2) {
+  OutputUnit outputUnit1 =
+      compiler1.deferredLoadTask.getOutputUnitForElementForTesting(element1);
+  OutputUnit outputUnit2 =
+      compiler2.deferredLoadTask.getOutputUnitForElementForTesting(element2);
+  checkOutputUnits(outputUnit1, outputUnit2, 'for $element1 vs $element2');
+}
+
+void checkOutputUnits(
+    OutputUnit outputUnit1, OutputUnit outputUnit2, String message) {
+  if (outputUnit1 == null && outputUnit2 == null) return;
+  check(outputUnit1, outputUnit2,
+      'OutputUnit.isMainOutput $message',
+      outputUnit1.isMainOutput, outputUnit2.isMainOutput);
+  checkSetEquivalence(outputUnit1, outputUnit2,
+      'OutputUnit.imports $message',
+      outputUnit1.imports, outputUnit2.imports,
+      (a, b) => areElementsEquivalent(a.declaration, b.declaration));
+}
diff --git a/tests/compiler/dart2js/serialization/reserialization_test.dart b/tests/compiler/dart2js/serialization/reserialization_test.dart
index 691bdab..2f56e2e 100644
--- a/tests/compiler/dart2js/serialization/reserialization_test.dart
+++ b/tests/compiler/dart2js/serialization/reserialization_test.dart
@@ -38,14 +38,16 @@
 
   SerializationResult result2 = await serialize(entryPoint,
       memorySourceFiles: serializedData1.toMemorySourceFiles(),
-      resolutionInputs: serializedData1.toUris());
+      resolutionInputs: serializedData1.toUris(),
+      deserializeCompilationDataForTesting: true);
   Compiler compiler2 = result2.compiler;
   SerializedData serializedData2 = result2.serializedData;
   Iterable<LibraryElement> libraries2 = compiler2.libraryLoader.libraries;
 
   SerializationResult result3 = await serialize(entryPoint,
       memorySourceFiles: serializedData2.toMemorySourceFiles(),
-      resolutionInputs: serializedData2.toUris());
+      resolutionInputs: serializedData2.toUris(),
+      deserializeCompilationDataForTesting: true);
   Compiler compiler3 = result3.compiler;
   Iterable<LibraryElement> libraries3 = compiler3.libraryLoader.libraries;
 
diff --git a/tests/compiler/dart2js/serialization/test_data.dart b/tests/compiler/dart2js/serialization/test_data.dart
index 83cf2da..065bf66 100644
--- a/tests/compiler/dart2js/serialization/test_data.dart
+++ b/tests/compiler/dart2js/serialization/test_data.dart
@@ -5,8 +5,8 @@
 library dart2js.serialization_test_data;
 
 const List<Test> TESTS = const <Test>[
-  // This test is very long-running and put here first to compile it on its own
-  // in compilation0_test.dart
+  // These tests are very long-running and put here first to compile them on
+  // their own tests.
   const Test('Disable tree shaking through reflection', const {
     'main.dart': '''
 import 'dart:mirrors';
@@ -17,6 +17,19 @@
 ''',
   }, expectedWarningCount: 1),
 
+  const Test('Use of dart:indexed_db', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() {}
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+import 'dart:indexed_db';
+''',
+  }),
+
+  // These tests
   const Test('Empty program', const {
     'main.dart': 'main() {}'
   }),
@@ -122,7 +135,7 @@
   },
   expectedWarningCount: 1),
 
-  const Test('Impliment Comparable with incompatible parameter types', const {
+  const Test('Implement Comparable with incompatible parameter types', const {
     'main.dart': r'''
 class Class implements Comparable<Class> {
   int compareTo(String other) => 0;
@@ -134,7 +147,7 @@
   expectedWarningCount: 1,
   expectedInfoCount: 1),
 
-  const Test('Impliment Comparable with incompatible parameter count', const {
+  const Test('Implement Comparable with incompatible parameter count', const {
     'main.dart': r'''
 class Class implements Comparable {
   bool compareTo(a, b) => true;
@@ -457,6 +470,18 @@
 ''',
   }),
 
+  const Test('Index set if null', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() => m(null, null, null);
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+m(a, b, c) => a[b] ??= c;
+''',
+  }),
+
   const Test('If-null expression in constant constructor', const {
     'main.dart': '''
 import 'a.dart';
@@ -546,6 +571,128 @@
     'c.dart': '''
 ''',
   }, expectedErrorCount: 1),
+
+  const Test('Closure in operator function', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() {
+  test();
+}
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+class C {
+  operator ==(other) => () {};
+}
+
+test() => new C() == null;
+''',
+  }),
+
+  const Test('Checked setter', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() {
+  test();
+}
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+class C {
+  set foo(int i) {}
+}
+
+test() => new C().foo = 0;
+''',
+  }, checkedMode: true),
+
+  const Test('Deferred access', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() {
+  test();
+}
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+import 'b.dart' deferred as b;
+
+test() => b.loadLibrary().then((_) => b.test2());
+''',
+    'b.dart': '''
+test2() {}
+''',
+  }),
+
+  const Test('Deferred access of dart:core', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() {
+  test();
+}
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+import "dart:core" deferred as core;
+
+test() {
+  core.loadLibrary().then((_) => null);
+}
+''',
+  }),
+
+  const Test('Use of dart:indexed_db', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() {}
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+import 'dart:indexed_db';
+''',
+  }),
+
+  const Test('Deferred static access', const {},
+      preserializedSourceFiles: const {
+    'main.dart': '''
+import 'b.dart' deferred as prefix;
+
+main() => prefix.loadLibrary().then((_) => prefix.test2());
+''',
+    'b.dart': '''
+test2() => x;
+var x = const ConstClass(const ConstClass(1));
+class ConstClass {
+  final x;
+  const ConstClass(this.x);
+}
+''',
+  }),
+
+  const Test('Multi variable declaration', const {
+    'main.dart': '''
+import 'a.dart';
+
+main() => y;
+''',
+  }, preserializedSourceFiles: const {
+    'a.dart': '''
+var x, y = 2;
+''',
+  }),
+
+  const Test('Double values', const {},
+      preserializedSourceFiles: const {
+  'main.dart': '''
+const a = 1e+400;
+main() => a;
+''',
+  }),
 ];
 
 class Test {
@@ -557,6 +704,7 @@
   final int expectedWarningCount;
   final int expectedHintCount;
   final int expectedInfoCount;
+  final bool checkedMode;
 
   const Test(
       this.name,
@@ -566,5 +714,6 @@
       this.expectedErrorCount: 0,
       this.expectedWarningCount: 0,
       this.expectedHintCount: 0,
-      this.expectedInfoCount: 0});
+      this.expectedInfoCount: 0,
+      this.checkedMode: false});
 }
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
index 9d3115f..f5d986d 100644
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ b/tests/compiler/dart2js/serialization/test_helper.dart
@@ -7,12 +7,14 @@
 import 'dart:collection';
 import 'package:compiler/src/common/resolution.dart';
 import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/constants/values.dart';
 import 'package:compiler/src/dart_types.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/tree/nodes.dart';
 import 'package:expect/expect.dart';
+import 'test_data.dart';
 
 Check currentCheck;
 
@@ -87,6 +89,15 @@
   }
 
   @override
+  bool testMaps(
+      var object1, var object2, String property, Map map1, Map map2,
+      [bool keyEquivalence(a, b) = equality,
+      bool valueEquivalence(a, b) = equality]) {
+    return checkMapEquivalence(object1, object2, property,
+        map1, map2, keyEquivalence, valueEquivalence);
+  }
+
+  @override
   bool testElements(
       Object object1, Object object2, String property,
       Element element1, Element element2) {
@@ -109,6 +120,12 @@
   }
 
   @override
+  bool testConstantValues(Object object1, Object object2, String property,
+      ConstantValue value1, ConstantValue value2) {
+    return areConstantValuesEquivalent(value1, value2);
+  }
+
+  @override
   bool testTypeLists(
       Object object1, Object object2, String property,
       List<DartType> list1, List<DartType> list2) {
@@ -124,6 +141,12 @@
   }
 
   @override
+  bool testConstantValueLists(Object object1, Object object2, String property,
+      List<ConstantValue> list1, List<ConstantValue> list2) {
+    return checkConstantValueLists(object1, object2, property, list1, list2);
+  }
+
+  @override
   bool testNodes(Object object1, Object object2, String property,
       Node node1, Node node2) {
     return new NodeEquivalenceVisitor(this).testNodes(
@@ -246,6 +269,38 @@
   return true;
 }
 
+/// Check equivalence of the two iterables, [set1] and [set1], as sets using
+/// [elementEquivalence] to compute the pair-wise equivalence.
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkMapEquivalence(
+    var object1,
+    var object2,
+    String property,
+    Map map1,
+    Map map2,
+    bool sameKey(a, b),
+    bool sameValue(a, b)) {
+  List<List> common = <List>[];
+  List unfound = [];
+  Set remaining =
+      computeSetDifference(map1.keys, map2.keys, common, unfound,
+          sameElement: sameKey);
+  if (unfound.isNotEmpty || remaining.isNotEmpty) {
+    String message =
+        "Map key mismatch for `$property` on $object1 vs $object2: \n"
+        "Common:\n ${common.join('\n ')}\n"
+        "Unfound:\n ${unfound.join('\n ')}\n"
+        "Extra: \n ${remaining.join('\n ')}";
+    throw message;
+  }
+  for (List pair in common) {
+    check(object1, object2, 'Map value for `$property`',
+        map1[pair[0]], map2[pair[1]], sameValue);
+  }
+  return true;
+}
+
 /// Checks the equivalence of the identity (but not properties) of [element1]
 /// and [element2].
 ///
@@ -310,7 +365,23 @@
   }
 }
 
-/// Checks the pair-wise equivalence of the contants in [list1] and [list2].
+/// Checks the equivalence of [value1] and [value2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkConstantValues(
+    Object object1, Object object2, String property,
+    ConstantValue value1, ConstantValue value2) {
+  if (identical(value1, value2)) return true;
+  if (value1 == null || value2 == null) {
+    return check(object1, object2, property, value1, value2);
+  } else {
+    return check(object1, object2, property, value1, value2,
+        (a, b) => const ConstantValueEquivalence(
+            const CheckStrategy()).visit(a, b));
+  }
+}
+
+/// Checks the pair-wise equivalence of the constants in [list1] and [list2].
 ///
 /// Uses [object1], [object2] and [property] to provide context for failures.
 bool checkConstantLists(
@@ -322,6 +393,18 @@
       list1, list2, checkConstants);
 }
 
+/// Checks the pair-wise equivalence of the constants values in [list1] and
+/// [list2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkConstantValueLists(
+    Object object1, Object object2, String property,
+    List<ConstantValue> list1,
+    List<ConstantValue> list2) {
+  return checkListEquivalence(
+      object1, object2, property,
+      list1, list2, checkConstantValues);
+}
 
 /// Check member property equivalence between all members common to [compiler1]
 /// and [compiler2].
@@ -438,27 +521,41 @@
     {bool failOnUnfound: true,
     bool failOnExtra: true,
     bool verbose: false,
-    void onSameElement(a, b)}) {
+    void onSameElement(a, b),
+    void onUnfoundElement(a),
+    void onExtraElement(b),
+    String elementToString(key): defaultToString}) {
   List<List> common = <List>[];
   List unfound = [];
   Set remaining = computeSetDifference(
       set1, set2, common, unfound,
       sameElement: sameElement,
       checkElements: onSameElement);
+  if (onUnfoundElement != null) {
+    unfound.forEach(onUnfoundElement);
+  }
+  if (onExtraElement != null) {
+    remaining.forEach(onExtraElement);
+  }
   StringBuffer sb = new StringBuffer();
   sb.write("$messagePrefix:");
   if (verbose) {
-    sb.write("\n Common:\n  ${common.join('\n  ')}");
+    sb.write("\n Common: \n");
+    for (List pair in common) {
+      var element1 = pair[0];
+      var element2 = pair[1];
+      sb.write("  [${elementToString(element1)},"
+          "${elementToString(element2)}]\n");
+    }
   }
   if (unfound.isNotEmpty || verbose) {
-    sb.write("\n Unfound:\n  ${unfound.join('\n  ')}");
+    sb.write("\n Unfound:\n  ${unfound.map(elementToString).join('\n  ')}");
   }
   if (remaining.isNotEmpty || verbose) {
-    sb.write("\n Extra: \n  ${remaining.join('\n  ')}");
+    sb.write("\n Extra: \n  ${remaining.map(elementToString).join('\n  ')}");
   }
   String message = sb.toString();
   if (unfound.isNotEmpty || remaining.isNotEmpty) {
-
     if ((failOnUnfound && unfound.isNotEmpty) ||
         (failOnExtra && remaining.isNotEmpty)) {
       Expect.fail(message);
@@ -589,3 +686,33 @@
   testResolvedAstEquivalence(
       resolvedAst1, resolvedAst2, const CheckStrategy());
 }
+
+/// Returns the test arguments for testing the [index]th skipped test. The
+/// [skip] count is used to check that [index] is a valid index.
+List<String> testSkipped(int index, int skip) {
+  if (index < 0 || index >= skip) {
+    throw new ArgumentError('Invalid skip index $index');
+  }
+  return ['${index}', '${index + 1}'];
+}
+
+/// Return the test arguments for testing the [index]th segment (1-based) of
+/// the [TESTS] split into [count] groups. The first [skip] tests are excluded
+/// from the automatic grouping.
+List<String> testSegment(int index, int count, int skip) {
+  if (index < 0 || index > count) {
+    throw new ArgumentError('Invalid segment index $index');
+  }
+
+  String segmentNumber(int i) {
+    return '${skip + i * (TESTS.length - skip) ~/ count}';
+  }
+
+  if (index == 1 && skip != 0) {
+    return ['${skip}', segmentNumber(index)];
+  } else if (index  == count) {
+    return [segmentNumber(index - 1)];
+  } else {
+    return [segmentNumber(index - 1), segmentNumber(index)];
+  }
+}
diff --git a/tests/compiler/dart2js/sourcemaps/diff_view.dart b/tests/compiler/dart2js/sourcemaps/diff_view.dart
index 1c1090a..adeb641 100644
--- a/tests/compiler/dart2js/sourcemaps/diff_view.dart
+++ b/tests/compiler/dart2js/sourcemaps/diff_view.dart
@@ -65,11 +65,13 @@
   List<String> commonArguments = optionSegments[0];
   List<List<String>> options = <List<String>>[];
   if (optionSegments.length == 1) {
+    // TODO(sigmund, johnniwinther): change default options now that CPS is
+    // deleted.
     // Use default options; comparing SSA and CPS output using the new
     // source information strategy.
     options.add([Flags.useNewSourceInfo]..addAll(commonArguments));
-    options.add(
-        [Flags.useNewSourceInfo, Flags.useCpsIr]..addAll(commonArguments));
+    options.add([Flags.useNewSourceInfo]..addAll(commonArguments));
+    throw "missing options: please specify options for the second column";
   } else if (optionSegments.length == 2) {
     // Use alternative options for the second output column.
     options.add(commonArguments);
diff --git a/tests/compiler/dart2js/sourcemaps/source_mapping_tester.dart b/tests/compiler/dart2js/sourcemaps/source_mapping_tester.dart
index 6134d20..713814a 100644
--- a/tests/compiler/dart2js/sourcemaps/source_mapping_tester.dart
+++ b/tests/compiler/dart2js/sourcemaps/source_mapping_tester.dart
@@ -98,7 +98,6 @@
 
 const Map<String, List<String>> TEST_CONFIGURATIONS = const {
   'ssa': const ['--use-new-source-info', ],
-  'cps': const ['--use-new-source-info', '--use-cps-ir'],
   'old': const [],
 };
 
diff --git a/tests/compiler/dart2js/zero_termination_test.dart b/tests/compiler/dart2js/zero_termination_test.dart
index fbfeab7..7599bc5 100644
--- a/tests/compiler/dart2js/zero_termination_test.dart
+++ b/tests/compiler/dart2js/zero_termination_test.dart
@@ -15,6 +15,8 @@
 import 'package:expect/expect.dart';
 import 'package:path/path.dart' as path;
 
+import 'launch_helper.dart' show launchDart2Js;
+
 Uri pathOfData = Platform.script;
 Directory tempDir;
 String outFilePath;
@@ -46,14 +48,6 @@
   }
 }
 
-Future launchDart2Js(args) {
-  String ext = Platform.isWindows ? '.bat' : '';
-  String command =
-      path.normalize(path.join(path.fromUri(Platform.script),
-                    '../../../../sdk/bin/dart2js${ext}'));
-  return Process.run(command, args, stdoutEncoding: null);
-}
-
 void check(ProcessResult result) {
   Expect.notEquals(0, result.exitCode);
   List<int> stdout = result.stdout;
@@ -72,7 +66,7 @@
   List<String> args = [inFilePath, "--out=" + outFilePath];
 
   await cleanup();
-  check(await launchDart2Js(args));
+  check(await launchDart2Js(args, noStdoutEncoding: true));
   await cleanup();
 }
 
@@ -84,7 +78,7 @@
   server.listen(handleRequest);
   try {
     await cleanup();
-    check(await launchDart2Js(args));
+    check(await launchDart2Js(args, noStdoutEncoding: true));
   } finally {
     await server.close();
     await cleanup();
diff --git a/tests/compiler/dart2js_extra/invalid_annotation2_test.dart b/tests/compiler/dart2js_extra/invalid_annotation2_test.dart
index d8dafd5..5b1f41a 100644
--- a/tests/compiler/dart2js_extra/invalid_annotation2_test.dart
+++ b/tests/compiler/dart2js_extra/invalid_annotation2_test.dart
@@ -14,7 +14,7 @@
 import 'dart:mirrors';
 
 @Deprecated("m"
-,                                /// 01: compile-time error
+,,                                /// 01: compile-time error
 )
 class A {
 }
diff --git a/tests/compiler/dart2js_extra/invalid_annotation_test.dart b/tests/compiler/dart2js_extra/invalid_annotation_test.dart
index 5e0285a8..50e8e6f 100644
--- a/tests/compiler/dart2js_extra/invalid_annotation_test.dart
+++ b/tests/compiler/dart2js_extra/invalid_annotation_test.dart
@@ -8,7 +8,7 @@
 // annotation had a syntax error.
 
 @Deprecated("m"
-,                                /// 01: compile-time error
+,,                                /// 01: compile-time error
 )
 class A {}
 
diff --git a/tests/compiler/dart2js_extra/truncation_errors_test.dart b/tests/compiler/dart2js_extra/truncation_errors_test.dart
new file mode 100644
index 0000000..1e3767c
--- /dev/null
+++ b/tests/compiler/dart2js_extra/truncation_errors_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.
+
+// Check that exception messages for truncating operations contains the
+// operands.
+
+import 'package:expect/expect.dart';
+
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
+
+void find1(expected, thunk) {
+  if (thunk == null) return;
+  var returned, exceptionText;
+  try {
+    returned = thunk();
+  } catch (e) {
+    exceptionText = '$e';
+  }
+  if (exceptionText == null) {
+    Expect.fail(
+        'Expected exception containing "$expected", returned: $returned');
+  }
+  Expect.isTrue(
+      exceptionText.contains(expected),
+      'Expected "$expected" in "$exceptionText"');
+}
+
+void find(expected, [thunk1, thunk2, thunk3, thunk4]) {
+  find1(expected, thunk1);
+  find1(expected, thunk2);
+  find1(expected, thunk3);
+  find1(expected, thunk4);
+}
+
+main() {
+
+  var NaN = double.NAN;
+  var Infinity = double.INFINITY;
+
+  find(' Infinity: 123 ~/ 0',
+       () => confuse(123) ~/ confuse(0),
+       () => confuse(123) ~/ 0,
+       () => 123 ~/ confuse(0),
+       () => 123 ~/ 0);
+
+  find('-Infinity: 123 ~/ -0.0',
+       () => confuse(123) ~/ confuse(-0.0),
+       () => confuse(123) ~/ -0.0,
+       () => 123 ~/ confuse(-0.0),
+       () => 123 ~/ -0.0);
+
+  find(' NaN: NaN ~/ 123',
+       () => confuse(NaN) ~/ confuse(123),
+       () => confuse(NaN) ~/ 123,
+       () => NaN ~/ confuse(123),
+       () => NaN ~/ 123);
+
+  find(' Infinity: 1e+200 ~/ 1e-200',
+       () => confuse(1e200) ~/ confuse(1e-200),
+       () => confuse(1e200) ~/ 1e-200,
+       () => 1e200 ~/ confuse(1e-200),
+       () => 1e200 ~/ 1e-200);
+
+  find('NaN.toInt()',
+       () => confuse(NaN).toInt(),
+       () => NaN.toInt());
+  find(' Infinity.toInt()',
+       () => confuse(Infinity).toInt(),
+       () => Infinity.toInt());
+  find('-Infinity.toInt()',
+       () => confuse(-Infinity).toInt(),
+       () => (-Infinity).toInt());
+
+  find('NaN.ceil()',
+       () => confuse(NaN).ceil(),
+       () => NaN.ceil());
+  find(' Infinity.ceil()',
+       () => confuse(Infinity).ceil(),
+       () => Infinity.ceil());
+  find('-Infinity.ceil()',
+       () => confuse(-Infinity).ceil(),
+       () => (-Infinity).ceil());
+
+  find('NaN.floor()',
+       () => confuse(NaN).floor(),
+       () => NaN.floor());
+  find(' Infinity.floor()',
+       () => confuse(Infinity).floor(),
+       () => Infinity.floor());
+  find('-Infinity.floor()',
+       () => confuse(-Infinity).floor(),
+       () => (-Infinity).floor());
+
+  find('NaN.round()',
+       () => confuse(NaN).round(),
+       () => NaN.round());
+  find(' Infinity.round()',
+       () => confuse(Infinity).round(),
+       () => Infinity.round());
+  find('-Infinity.round()',
+       () => confuse(-Infinity).round(),
+       () => (-Infinity).round());
+
+  // `truncate()` is the same as `toInt()`.
+  // We could change the runtime so that `truncate` is reported.
+  find('NaN.toInt()',
+       () => confuse(NaN).truncate(),
+       () => NaN.truncate());
+  find(' Infinity.toInt()',
+       () => confuse(Infinity).truncate(),
+       () => Infinity.truncate());
+  find('-Infinity.toInt()',
+       () => confuse(-Infinity).truncate(),
+       () => (-Infinity).truncate());
+
+}
+
diff --git a/tests/compiler/dart2js_native/call_on_native_class_test.dart b/tests/compiler/dart2js_native/call_on_native_class_test.dart
deleted file mode 100644
index 5142982..0000000
--- a/tests/compiler/dart2js_native/call_on_native_class_test.dart
+++ /dev/null
@@ -1,17 +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:_js_helper';
-
-@Native('*A')
-class A {
-}
-
-class B extends A {
-  call() => 42;
-}
-
-main() {
-  new B()();
-}
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index 28abf25..cae6550 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -6,7 +6,6 @@
 *: Skip
 
 [ $compiler == dart2js ]
-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
 
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 53ec300..78010e9 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -41,6 +41,7 @@
 symbol_reserved_word_test/10: MissingCompileTimeError # bug 11669, 19972
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
+package_resource_test: RuntimeError # Issue 26842
 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
 symbol_reserved_word_test/04: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
@@ -138,8 +139,6 @@
 
 [ $compiler == dart2analyzer ]
 int_parse_radix_bad_handler_test: fail
-list_insert_test: fail
-list_removeat_test: fail
 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.
@@ -162,8 +161,8 @@
 file_resource_test: Skip, OK # VM specific test, uses dart:io.
 http_resource_test: Skip, OK # VM specific test, uses dart:io.
 
-[ $runtime != vm && $runtime != dart_precompiled && $compiler != dart2analyzer && $cps_ir == false ]
-package_resource_test: RuntimeError # Issue 23825 (not implemented yet).
+[ $compiler == dart2js && $browser == false ]
+package_resource_test: RuntimeError # Issue 26842
 
 [ $mode == debug ]
 regexp/pcre_test: Pass, Slow # Timeout. Issue 22008
@@ -173,7 +172,6 @@
 big_integer_parsed_mul_div_vm_test: Pass, Slow
 
 [ $compiler == dart2js && $cps_ir ]
-package_resource_test: Crash # Surprisingly null object in type propagation.
 regexp/pcre_test: Crash # Stack Overflow in LoopHierarchy.
 core_runtime_types_test: Pass, RuntimeError # Issue 25795.
 
@@ -184,9 +182,6 @@
 regexp/pcre_test: Crash # Stack Overflow
 collection_removes_test: Crash # Issue 25911
 
-[ $compiler == dart2js && $host_checked ]
-package_resource_test: Crash # Issue 25911
-
 [ $noopt || $compiler == precompiler ]
 # Stacktraces in precompilation omit inlined frames.
 stacktrace_current_test: Pass, RuntimeError
@@ -209,15 +204,3 @@
 
 [ $arch == simdbc || $arch == simdbc64 ]
 regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
-
-[ $hot_reload ]
-big_integer_huge_mul_vm_test: Pass, Timeout
-big_integer_parsed_mul_div_vm_test: Pass, Timeout
-collection_length_test: Fail, Crash
-hash_map2_test: Pass, Crash
-queue_test: Pass, Crash
-regexp/regexp_test: Pass, Fail, Crash
-uri_parse_test: Pass, Timeout
-uri_test: Pass, RuntimeError
-data_uri_test: Pass, RuntimeError
-int_parse_radix_test: Pass, Timeout
diff --git a/tests/corelib/data_uri_test.dart b/tests/corelib/data_uri_test.dart
index 1a21be1..41f2290 100644
--- a/tests/corelib/data_uri_test.dart
+++ b/tests/corelib/data_uri_test.dart
@@ -18,6 +18,13 @@
   testRoundTrip("blåbærgrød", UTF8);
   testRoundTrip("blåbærgrød", LATIN1);
 
+  testUriEquals("data:,abc?d#e");
+  testUriEquals("DATA:,ABC?D#E");
+  testUriEquals("data:,a%20bc?d#e");
+  testUriEquals("DATA:,A%20BC?D#E");
+  testUriEquals("data:,a%62c?d#e");
+  testUriEquals("DATA:,A%42C?D#E");
+
   testUtf8Encoding("\u1000\uffff");
   testBytes();
   testInvalidCharacters();
@@ -250,3 +257,11 @@
   Expect.equals(expect.hasFragment, actual.hasFragment, "hasFragment");
   Expect.equals(expect.fragment, actual.fragment, "fragment");
 }
+
+void testUriEquals(String uriText) {
+  var data = UriData.parse(uriText);
+  var uri = Uri.parse(uriText);
+  Expect.equals(data.uri, uri);
+  Expect.equals(data.toString(), uri.data.toString());
+  Expect.equals(data.toString(), uri.toString());
+}
diff --git a/tests/corelib/double_floor_test.dart b/tests/corelib/double_floor_test.dart
index c59f411..7407561 100644
--- a/tests/corelib/double_floor_test.dart
+++ b/tests/corelib/double_floor_test.dart
@@ -79,4 +79,4 @@
   Expect.isTrue((-9007199254740991.0).floor() is int);
   Expect.isTrue((-9007199254740992.0).floor() is int);
   Expect.isTrue((-double.MAX_FINITE).floor() is int);
-}
\ No newline at end of file
+}
diff --git a/tests/corelib/hash_map2_test.dart b/tests/corelib/hash_map2_test.dart
index 848f449..cc4ed3e 100644
--- a/tests/corelib/hash_map2_test.dart
+++ b/tests/corelib/hash_map2_test.dart
@@ -1,9 +1,6 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-//
-// VMOptions=
-// VMOptions=--use_internal_hash_map
 
 // Tests of hash map behavior, with focus in iteration and concurrent
 // modification errors.
diff --git a/tests/corelib/hash_map_test.dart b/tests/corelib/hash_map_test.dart
index 8f9ce30..52848e1 100644
--- a/tests/corelib/hash_map_test.dart
+++ b/tests/corelib/hash_map_test.dart
@@ -1,9 +1,6 @@
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-//
-// VMOptions=
-// VMOptions=--use_internal_hash_map
 
 import "package:expect/expect.dart";
 
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index ef7a9a3..5c8c1d1 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -10,6 +10,12 @@
 testUri(String uriText, bool isAbsolute) {
   var uri = Uri.parse(uriText);
 
+  // Test that parsing a substring works the same as parsing the string.
+  String wrapper = "://@[]:/%?#";
+  var embeddedUri = Uri.parse(
+       "$wrapper$uri$wrapper", wrapper.length, uriText.length + wrapper.length);
+
+  Expect.equals(uri, embeddedUri);
   Expect.equals(isAbsolute, uri.isAbsolute);
   Expect.stringEquals(uriText, uri.toString());
 
@@ -82,7 +88,8 @@
   final urisSample = "http://a/b/c/d;p?q";
   Uri base = Uri.parse(urisSample);
   testResolve(expect, relative) {
-    Expect.stringEquals(expect, base.resolve(relative).toString());
+    String name = "$base << $relative";
+    Expect.stringEquals(expect, base.resolve(relative).toString(), name);
   }
 
   // From RFC 3986.
@@ -132,19 +139,232 @@
   // Additional tests (not from RFC 3986).
   testResolve("http://a/b/g;p/h;s",    "../g;p/h;s");
 
+  base = Uri.parse("s:a/b");
+  testResolve("s:a/c", "c");
+  testResolve("s:/c", "../c");
+
+  base = Uri.parse("S:a/b");
+  testResolve("s:a/c", "c");
+  testResolve("s:/c", "../c");
+
+  base = Uri.parse("s:foo");
+  testResolve("s:bar", "bar");
+  testResolve("s:bar", "../bar");
+
+  base = Uri.parse("S:foo");
+  testResolve("s:bar", "bar");
+  testResolve("s:bar", "../bar");
+
+  // Special-case (deliberate non-RFC behavior).
+  base = Uri.parse("foo/bar");
+  testResolve("foo/baz", "baz");
+  testResolve("baz", "../baz");
+
+  base = Uri.parse("s:/foo");
+  testResolve("s:/bar", "bar");
+  testResolve("s:/bar", "../bar");
+
+  base = Uri.parse("S:/foo");
+  testResolve("s:/bar", "bar");
+  testResolve("s:/bar", "../bar");
+
   // Test non-URI base (no scheme, no authority, relative path).
   base = Uri.parse("a/b/c?_#_");
   testResolve("a/b/g?q#f", "g?q#f");
   testResolve("./", "../..");
   testResolve("../", "../../..");
   testResolve("a/b/", ".");
-  testResolve("c", "../../c");
+  testResolve("c", "../../c");  // Deliberate non-RFC behavior.
   base = Uri.parse("../../a/b/c?_#_");  // Initial ".." in base url.
   testResolve("../../a/d", "../d");
   testResolve("../../../d", "../../../d");
 
-  base = Uri.parse("s:a/b");
-  testResolve("s:/c", "../c");
+  base = Uri.parse("s://h/p?q#f");  // A simple base.
+  // Simple references:
+  testResolve("s2://h2/P?Q#F", "s2://h2/P?Q#F");
+  testResolve("s://h2/P?Q#F", "//h2/P?Q#F");
+  testResolve("s://h/P?Q#F", "/P?Q#F");
+  testResolve("s://h/p?Q#F", "?Q#F");
+  testResolve("s://h/p?q#F", "#F");
+  testResolve("s://h/p?q", "");
+  // Non-simple references:
+  testResolve("s2://I@h2/P?Q#F%20", "s2://I@h2/P?Q#F%20");
+  testResolve("s://I@h2/P?Q#F%20", "//I@h2/P?Q#F%20");
+  testResolve("s://h2/P?Q#F%20", "//h2/P?Q#F%20");
+  testResolve("s://h/P?Q#F%20", "/P?Q#F%20");
+  testResolve("s://h/p?Q#F%20", "?Q#F%20");
+  testResolve("s://h/p?q#F%20", "#F%20");
+
+  base = Uri.parse("s://h/p1/p2/p3");  // A simple base with a path.
+  testResolve("s://h/p1/p2/", ".");
+  testResolve("s://h/p1/p2/", "./");
+  testResolve("s://h/p1/", "..");
+  testResolve("s://h/p1/", "../");
+  testResolve("s://h/", "../..");
+  testResolve("s://h/", "../../");
+  testResolve("s://h/p1/%20", "../%20");
+  testResolve("s://h/", "../../../..");
+  testResolve("s://h/", "../../../../");
+
+  base = Uri.parse("s://h/p?q#f%20");  // A non-simpe base.
+  // Simple references:
+  testResolve("s2://h2/P?Q#F", "s2://h2/P?Q#F");
+  testResolve("s://h2/P?Q#F", "//h2/P?Q#F");
+  testResolve("s://h/P?Q#F", "/P?Q#F");
+  testResolve("s://h/p?Q#F", "?Q#F");
+  testResolve("s://h/p?q#F", "#F");
+  testResolve("s://h/p?q", "");
+  // Non-simple references:
+  testResolve("s2://I@h2/P?Q#F%20", "s2://I@h2/P?Q#F%20");
+  testResolve("s://I@h2/P?Q#F%20", "//I@h2/P?Q#F%20");
+  testResolve("s://h2/P?Q#F%20", "//h2/P?Q#F%20");
+  testResolve("s://h/P?Q#F%20", "/P?Q#F%20");
+  testResolve("s://h/p?Q#F%20", "?Q#F%20");
+  testResolve("s://h/p?q#F%20", "#F%20");
+
+  base = Uri.parse("S://h/p1/p2/p3");  // A non-simple base with a path.
+  testResolve("s://h/p1/p2/", ".");
+  testResolve("s://h/p1/p2/", "./");
+  testResolve("s://h/p1/", "..");
+  testResolve("s://h/p1/", "../");
+  testResolve("s://h/", "../..");
+  testResolve("s://h/", "../../");
+  testResolve("s://h/p1/%20", "../%20");
+  testResolve("s://h/", "../../../..");
+  testResolve("s://h/", "../../../../");
+
+  base = Uri.parse("../../../");  // A simple relative path.
+  testResolve("../../../a", "a");
+  testResolve("../../../../a", "../a");
+  testResolve("../../../a%20", "a%20");
+  testResolve("../../../../a%20", "../a%20");
+
+  // Tests covering the branches of the merge algorithm in RFC 3986
+  // with both simple and complex base URIs.
+  for (var b in ["s://a/pa/pb?q#f", "s://a/pa/pb?q#f%20"]) {
+    var origBase = Uri.parse(b);
+    base = origBase;
+
+    // if defined(R.scheme) then ...
+    testResolve("s2://a2/p2?q2#f2", "s2://a2/p2?q2#f2");
+    // else, if defined(R.authority) then ...
+    testResolve("s://a2/p2?q2#f2", "//a2/p2?q2#f2");
+    testResolve("s://a2/?q2#f2", "//a2/../?q2#f2");
+    testResolve("s://a2?q2#f2", "//a2?q2#f2");
+    testResolve("s://a2#f2", "//a2#f2");
+    testResolve("s://a2", "//a2");
+    // else, if (R.path == "") then ...
+    //   if defined(R.query) then
+    testResolve("s://a/pa/pb?q2#f2", "?q2#f2");
+    testResolve("s://a/pa/pb?q2", "?q2");
+    //   else
+    testResolve("s://a/pa/pb?q#f2", "#f2");
+    testResolve("s://a/pa/pb?q", "");
+    // else, if (R.path starts-with "/") then ...
+    testResolve("s://a/p2?q2#f2", "/p2?q2#f2");
+    testResolve("s://a/?q2#f2", "/?q2#f2");
+    testResolve("s://a/#f2", "/#f2");
+    testResolve("s://a/", "/");
+    testResolve("s://a/", "/../");
+    // else ... T.path = merge(Base.path, R.path)
+    // ... remove-dot-fragments(T.path) ...
+    // (Cover the merge function and the remove-dot-fragments functions too).
+
+    // If base has authority and empty path ...
+    var emptyPathBase = Uri.parse(b.replaceFirst("/pa/pb", ""));
+    base = emptyPathBase;
+    testResolve("s://a/p2?q2#f2", "p2?q2#f2");
+    testResolve("s://a/p2#f2", "p2#f2");
+    testResolve("s://a/p2", "p2");
+
+    base = origBase;
+    // otherwise
+    // (Cover both no authority and non-empty path and both).
+    var noAuthEmptyPathBase = Uri.parse(b.replaceFirst("//a/pa/pb", ""));
+    var noAuthAbsPathBase = Uri.parse(b.replaceFirst("//a", ""));
+    var noAuthRelPathBase = Uri.parse(b.replaceFirst("//a/", ""));
+    var noAuthRelSinglePathBase = Uri.parse(b.replaceFirst("//a/pa/", ""));
+
+    testResolve("s://a/pa/p2?q2#f2", "p2?q2#f2");
+    testResolve("s://a/pa/p2#f2", "p2#f2");
+    testResolve("s://a/pa/p2", "p2");
+
+    base = noAuthEmptyPathBase;
+    testResolve("s:p2?q2#f2", "p2?q2#f2");
+    testResolve("s:p2#f2", "p2#f2");
+    testResolve("s:p2", "p2");
+
+    base = noAuthAbsPathBase;
+    testResolve("s:/pa/p2?q2#f2", "p2?q2#f2");
+    testResolve("s:/pa/p2#f2", "p2#f2");
+    testResolve("s:/pa/p2", "p2");
+
+    base = noAuthRelPathBase;
+    testResolve("s:pa/p2?q2#f2", "p2?q2#f2");
+    testResolve("s:pa/p2#f2", "p2#f2");
+    testResolve("s:pa/p2", "p2");
+
+    base = noAuthRelSinglePathBase;
+    testResolve("s:p2?q2#f2", "p2?q2#f2");
+    testResolve("s:p2#f2", "p2#f2");
+    testResolve("s:p2", "p2");
+
+    // Then remove dot segments.
+
+    // A. if input buffer starts with "../" or "./".
+    // This only happens if base has only a single (may be empty) segment and
+    // no slash.
+    base = emptyPathBase;
+    testResolve("s://a/p2", "../p2");
+    testResolve("s://a/", "../");
+    testResolve("s://a/", "..");
+    testResolve("s://a/p2", "./p2");
+    testResolve("s://a/", "./");
+    testResolve("s://a/", ".");
+    testResolve("s://a/p2", "../../p2");
+    testResolve("s://a/p2", "../../././p2");
+
+    base = noAuthRelSinglePathBase;
+    testResolve("s:p2", "../p2");
+    testResolve("s:", "../");
+    testResolve("s:", "..");
+    testResolve("s:p2", "./p2");
+    testResolve("s:", "./");
+    testResolve("s:", ".");
+    testResolve("s:p2", "../../p2");
+    testResolve("s:p2", "../../././p2");
+
+    // B. if input buffer starts with "/./" or is "/.". replace with "/".
+    // (The URI implementation removes the "." path segments when parsing,
+    // so this case isn't handled by merge).
+    base = origBase;
+    testResolve("s://a/pa/p2", "./p2");
+
+    // C. if input buffer starts with "/../" or is "/..", replace with "/"
+    // and remove preceeding segment.
+    testResolve("s://a/p2", "../p2");
+    var longPathBase = Uri.parse(b.replaceFirst("/pb", "/pb/pc/pd"));
+    base = longPathBase;
+    testResolve("s://a/pa/pb/p2", "../p2");
+    testResolve("s://a/pa/p2", "../../p2");
+    testResolve("s://a/p2", "../../../p2");
+    testResolve("s://a/p2", "../../../../p2");
+    var noAuthRelLongPathBase =
+        Uri.parse(b.replaceFirst("//a/pa/pb", "pa/pb/pc/pd"));
+    base = noAuthRelLongPathBase;
+    testResolve("s:pa/pb/p2", "../p2");
+    testResolve("s:pa/p2", "../../p2");
+    testResolve("s:/p2", "../../../p2");
+    testResolve("s:/p2", "../../../../p2");
+
+    // D. if the input buffer contains only ".." or ".", remove it.
+    base = noAuthEmptyPathBase;
+    testResolve("s:", "..");
+    testResolve("s:", ".");
+    base = noAuthRelSinglePathBase;
+    testResolve("s:", "..");
+    testResolve("s:", ".");
+  }
 }
 
 void testResolvePath(String expected, String path) {
@@ -334,6 +554,13 @@
     Expect.equals("/zZ${char}zZ", uri.path);
     Expect.equals("vV${char}vV", uri.query);
     Expect.equals("wW${char}wW", uri.fragment);
+
+    uri = Uri.parse("s://yY${escape}yY/zZ${escape}zZ"
+                    "?vV${escape}vV#wW${escape}wW");
+    Expect.equals("yY${char}yY".toLowerCase(), uri.host);
+    Expect.equals("/zZ${char}zZ", uri.path);
+    Expect.equals("vV${char}vV", uri.query);
+    Expect.equals("wW${char}wW", uri.fragment);
   }
 
   // Escapes of reserved characters are kept, but upper-cased.
@@ -400,7 +627,11 @@
   var uris = [
     Uri.parse(""),
     Uri.parse("a://@:/?#"),
+    Uri.parse("a://:/?#"),  // Parsed as simple URI.
     Uri.parse("a://b@c:4/e/f?g#h"),
+    Uri.parse("a://c:4/e/f?g#h"),  // Parsed as simple URI.
+    Uri.parse("$SCHEMECHAR://$REGNAMECHAR:$DIGIT/$PCHAR/$PCHAR"
+              "?$QUERYCHAR#$QUERYCHAR"),  // Parsed as simple URI.
     Uri.parse("$SCHEMECHAR://$USERINFOCHAR@$REGNAMECHAR:$DIGIT/$PCHAR/$PCHAR"
               "?$QUERYCHAR#$QUERYCHAR"),
   ];
@@ -470,6 +701,13 @@
   Expect.equals(2, params.length);
   Expect.listEquals(["42", "37"], params["x"]);
   Expect.listEquals(["43", "38"], params["y"]);
+
+  // Test replacing with empty strings.
+  uri = Uri.parse("s://a:1/b/c?d#e");
+  Expect.equals("s://a:1/b/c?d#", uri.replace(fragment: "").toString());
+  Expect.equals("s://a:1/b/c?#e", uri.replace(query: "").toString());
+  Expect.equals("s://a:1?d#e", uri.replace(path: "").toString());
+  Expect.equals("s://:1/b/c?d#e", uri.replace(host: "").toString());
 }
 
 main() {
@@ -498,6 +736,11 @@
                           query: null,
                           fragment: null).toString());
   Expect.stringEquals("file:///", Uri.parse("file:").toString());
+  Expect.stringEquals("file:///", Uri.parse("file:/").toString());
+  Expect.stringEquals("file:///", Uri.parse("file:").toString());
+  Expect.stringEquals("file:///foo", Uri.parse("file:foo").toString());
+  Expect.stringEquals("file:///foo", Uri.parse("file:/foo").toString());
+  Expect.stringEquals("file://foo/", Uri.parse("file://foo").toString());
 
   testResolvePath("/a/g", "/a/b/c/./../../g");
   testResolvePath("/a/g", "/a/b/c/./../../g");
diff --git a/tests/html/gamepad_test.dart b/tests/html/gamepad_test.dart
new file mode 100644
index 0000000..6bbef59
--- /dev/null
+++ b/tests/html/gamepad_test.dart
@@ -0,0 +1,32 @@
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+main() {
+  var isGamepadList =
+      predicate((x) => x is List<Gamepad>, 'is a List<Gamepad>');
+
+  insertTestDiv() {
+    var element = new Element.tag('div');
+    element.innerHtml = r'''
+    A large block of text should go here. Click this
+    block of text multiple times to see each line
+    highlight with every click of the mouse button.
+    ''';
+    document.body.append(element);
+    return element;
+  }
+
+  useHtmlConfiguration();
+
+  test("getGamepads", () {
+    insertTestDiv();
+    var gamepads = window.navigator.getGamepads();
+    expect(gamepads, isGamepadList);
+    for (var gamepad in gamepads) {
+      if (gamepad != null) {
+        expect(gamepad.id, isNotNull);
+      }
+    }
+  });
+}
diff --git a/tests/html/html.status b/tests/html/html.status
index 4d57f42..36c0e8a 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -26,6 +26,9 @@
 wrapping_collections_test: SkipByDesign # Testing an issue that is only relevant to Dartium
 js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue #25759
 mirrors_js_typed_interop_test: Pass, Slow
+js_type_test/dynamic-null-not-Foo: Fail  # Issue 26838
+js_type_test/dynamic-String-not-Foo: Fail  # Issue 26838
+js_type_test/dynamic-String-not-dynamic-Foo: Fail  # Issue 26838
 
 
 [ $compiler == dart2js && $checked ]
@@ -47,7 +50,6 @@
 custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
 fontface_test: Fail # Fontface not supported on these.
 custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Polyfill does not support
-element_animate_test: Fail # Element.animate not supported on these browsers.
 
 [ $compiler == none && $runtime == dartium && $system == macos]
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Pass,Fail # Issue 11834
@@ -112,6 +114,9 @@
 transition_event_test/functional: Skip # Times out. Issue 22167
 request_animation_frame_test: Skip # Times out. Issue 22167
 custom/*: Pass, Timeout # Issue 26789
+custom_elements_test: Pass, Timeout # Issue 26789
+custom_element_method_clash_test: Pass, Timeout # Issue 26789
+custom_element_name_clash_test: Pass, Timeout # Issue 26789
 
 [$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid ]
 webgl_1_test: Pass, Fail # Issue 8219
@@ -144,6 +149,9 @@
 text_event_test: RuntimeError # Issue 23437
 transition_event_test/functional: Skip # Times out. Issue 22167
 request_animation_frame_test: Skip # Times out. Issue 22167
+js_util_test/callConstructor: RuntimeError # Issue 26978
+element_animate_test: Fail # Element.animate not supported on these browsers.
+gamepad_test: Fail # IE does not support Navigator.getGamepads()
 
 [$runtime == ie10 ]
 # IE10 Feature support statuses-
@@ -167,6 +175,8 @@
 input_element_test/supported_month: Fail
 input_element_test/supported_time: Fail
 input_element_test/supported_week: Fail
+js_util_test/hasProperty: RuntimeError # Issue 26978
+js_util_test/getProperty: RuntimeError # Issue 26978
 media_stream_test/supported_MediaStreamEvent: Fail
 media_stream_test/supported_MediaStreamTrackEvent: Fail
 media_stream_test/supported_media: Fail
@@ -260,6 +270,8 @@
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # Safari does not support drawImage w/ video element
 element_test: Pass, Fail # Issue 21434
 mediasource_test: Pass, Fail # MediaSource only available on Safari 8 desktop, we can't express that.
+element_animate_test: Fail # Element.animate not supported on these browsers.
+gamepad_test: Fail # Safari does not support Navigator.getGamepads()
 
 # Safari Feature support statuses-
 # All changes should be accompanied by platform support annotation changes.
@@ -309,6 +321,7 @@
 dart_object_local_storage_test: Skip  # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
 webgl_1_test: Pass, Fail   # Issue 8219
 text_event_test: Fail # Issue 17893
+element_animate_test/timing_dict: RuntimeError # Issue 26730
 
 # Firefox Feature support statuses-
 # All changes should be accompanied by platform support annotation changes.
@@ -338,14 +351,29 @@
 [ $compiler == dart2js && ($runtime == drt || $runtime == ff) ]
 request_animation_frame_test: Skip # Async test hangs.
 
+[ $runtime == drt ]
+webgl_extensions_test: Skip # webgl does not work properly on DRT, which is 'headless'.
+
+[ $runtime == dartium && ($system == windows || $system == linux) ]
+webgl_extensions_test: Fail # WebGL extension tests fail on Dartium without graphics. This is dependent on our bot configuration.
+
+[ $runtime == chrome && ($system == windows || $system == linux) ]
+webgl_extensions_test: Fail # WebGL extension tests fail without graphics. This is dependent on our bot configuration.
+
 [ $compiler == dart2js && $csp && ($runtime == drt || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == chromeOnAndroid) ]
 # Note: these tests are all injecting scripts by design.  This is not allowed under CSP.
+# TODO(sra): Change these tests to use a same-origin JavaScript script file.
 event_customevent_test: SkipByDesign
 js_interop_1_test: SkipByDesign
 js_test: SkipByDesign
 js_array_test: SkipByDesign
+js_util_test: SkipByDesign
+js_typed_interop_bind_this_test: SkipByDesign
+js_typed_interop_callable_object_test: SkipByDesign
 js_typed_interop_test: SkipByDesign
 js_typed_interop_default_arg_test: SkipByDesign
+js_typed_interop_type_test: SkipByDesign
+js_typed_interop_window_property_test: SkipByDesign
 js_function_getter_test: SkipByDesign
 js_function_getter_trust_types_test: SkipByDesign
 js_dart_to_string_test: SkipByDesign
diff --git a/tests/html/js_type_test.dart b/tests/html/js_type_test.dart
new file mode 100644
index 0000000..90df68f
--- /dev/null
+++ b/tests/html/js_type_test.dart
@@ -0,0 +1,146 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsTest;
+
+import 'dart:html';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+
+import 'js_type_test_lib.dart';
+
+class Bar {}
+
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
+
+class Is<T> {
+  const Is();
+  check(o) => o is T;
+}
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  new Is<Foo>().check(new Bar());  // Bar is instantiated by this code.
+  new Is<Foo>().check([]);
+  new Is<List>().check([]);
+
+  group('static', () {
+    test('not-String', () {
+      Foo e = new Foo();
+      expect(e is String, isFalse);
+    });
+
+    test('not-int', () {
+      Foo e = new Foo();
+      expect(e is int, isFalse);
+    });
+
+    test('not-Null', () {
+      Foo e = new Foo();
+      expect(e is Null, isFalse);
+    });
+
+    test('not-Bar', () {
+      Foo e = new Foo();
+      expect(e is Bar, isFalse);
+    });
+
+    test('is-Foo', () {
+      Foo e = new Foo();
+      expect(e is Foo, isTrue);
+    });
+
+    test('String-not-Foo', () {
+      String e = 'hello';
+      expect(e is Foo, isFalse);
+    });
+  });
+
+  group('dynamic', () {
+    test('not-String', () {
+      var e = confuse(new Foo());
+      expect(e is String, isFalse);
+    });
+
+    test('not-int', () {
+      var e = confuse(new Foo());
+      expect(e is int, isFalse);
+    });
+
+    test('not-Null', () {
+      var e = confuse(new Foo());
+      expect(e is Null, isFalse);
+    });
+
+    test('not-Bar', () {
+      var e = confuse(new Foo());
+      expect(e is Bar, isFalse);
+    });
+
+    test('is-Foo', () {
+      var e = confuse(new Foo());
+      expect(e is Foo, isTrue);
+    });
+  });
+
+  group('dynamic-String-not-Foo', () {
+    test('test', () {
+      var e = confuse('hello');
+      expect(e is Foo, isFalse);
+    });
+  });
+
+  group('dynamic-null-not-Foo', () {
+    test('test', () {
+      var e = confuse(null);
+      expect(e is Foo, isFalse);
+    });
+  });
+
+  group('dynamic-type', () {
+    test('not-String', () {
+      var e = confuse(new Foo());
+      expect(const Is<String>().check(e), isFalse);
+    });
+
+    test('not-int', () {
+      var e = confuse(new Foo());
+      expect(const Is<int>().check(e), isFalse);
+    });
+
+    test('not-Null', () {
+      var e = confuse(new Foo());
+      expect(const Is<Null>().check(e), isFalse);
+    });
+
+    test('not-Bar', () {
+      var e = confuse(new Foo());
+      expect(const Is<Bar>().check(e), isFalse);
+    });
+
+    test('is-Foo', () {
+      var e = confuse(new Foo());
+      expect(const Is<Foo>().check(e), isTrue);
+    });
+  });
+
+  group('dynamic-String-not-dynamic-Foo', () {
+    test('test', () {
+      var e = confuse('hello');
+      expect(const Is<Foo>().check(e), isFalse);
+    });
+  });
+
+  group('dynamic-null-not-dynamic-Foo', () {
+    test('test', () {
+      var e = confuse(null);
+      expect(const Is<Foo>().check(e), isFalse);
+    });
+  });
+
+}
diff --git a/tests/html/js_type_test.html b/tests/html/js_type_test.html
new file mode 100644
index 0000000..69628ed
--- /dev/null
+++ b/tests/html/js_type_test.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<--
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+-->
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <title> js_type_test </title>
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+</head>
+<body>
+  <h1> Running js_type_test </h1>
+  <script type="text/javascript"
+      src="/root_dart/tests/html/js_type_test_js.js"></script>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/html/js_type_test_js.js b/tests/html/js_type_test_js.js
new file mode 100644
index 0000000..1f12f38
--- /dev/null
+++ b/tests/html/js_type_test_js.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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 Foo() {}
diff --git a/tests/html/js_type_test_lib.dart b/tests/html/js_type_test_lib.dart
new file mode 100644
index 0000000..6b7113c
--- /dev/null
+++ b/tests/html/js_type_test_lib.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_type_test_lib;
+
+import 'package:js/js.dart';
+
+@JS()
+class Foo {
+  external factory Foo();
+}
diff --git a/tests/html/js_typed_interop_bind_this_test.dart b/tests/html/js_typed_interop_bind_this_test.dart
new file mode 100644
index 0000000..d241cb9
--- /dev/null
+++ b/tests/html/js_typed_interop_bind_this_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_typed_interop_bind_this_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:unittest/html_individual_config.dart';
+
+// This is a regression test for https://github.com/dart-lang/sdk/issues/25658
+
+_injectJs() {
+  document.body.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  "use strict";
+
+  function JsTest() {
+  }
+
+  JsTest.returnThis = function(name, value) {
+    return this;
+  };
+""");
+}
+
+@JS('JsTest.returnThis')
+external returnThis([name, value]);
+
+@JS('JsTest')
+external get jsTestObject;
+
+@JS('window')
+external get jsWindow;
+
+main() {
+  _injectJs();
+
+  useHtmlIndividualConfiguration();
+
+  group('bind this', () {
+    test('simple', () {
+      expect(identical(returnThis(), jsWindow), isFalse);
+      expect(identical(returnThis(), null), isFalse);
+      expect(identical(returnThis(), jsTestObject), isTrue);
+    });
+  });
+}
diff --git a/tests/html/js_typed_interop_callable_object_test.dart b/tests/html/js_typed_interop_callable_object_test.dart
new file mode 100644
index 0000000..4456459
--- /dev/null
+++ b/tests/html/js_typed_interop_callable_object_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_typed_interop_callable_object_test;
+
+import 'dart:html';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+import 'package:js/js.dart';
+import 'package:unittest/html_config.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+
+// This is a regression test for https://github.com/dart-lang/sdk/issues/25658
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+_injectJs() {
+  document.body.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  "use strict";
+
+  window.callableObject = function (a, b) { return a + b; };
+  window.callableObject.foo = function() { return "bar"; };
+  window.callableObject.bar = 42;
+
+""");
+}
+
+@JS()
+@anonymous
+class CallableObject {
+  /// If a @JS class implements `call`, the underlying representation must be
+  /// a JavaScript callable (i.e. function).
+  external num call(num a, num b);
+  external int get bar;
+  external String foo();
+}
+
+@JS()
+external CallableObject get callableObject;
+
+main() {
+  _injectJs();
+
+  useHtmlIndividualConfiguration();
+
+  group('callable object', () {
+    test('simple', () {
+      var obj = callableObject;
+      expect(obj(4, 5), equals(9));
+      expect(obj.bar, equals(42));
+      expect(obj.foo(), equals("bar"));
+
+      expect(callableObject(4, 5), equals(9));
+      expect(callableObject.bar, equals(42));
+      expect(callableObject.foo(), equals("bar"));
+    });
+
+    test('dynamic', () {
+      var obj = confuse(callableObject);
+      expect(obj(4, 5), equals(9));
+      expect(obj.bar, equals(42));
+      expect(obj.foo(), equals("bar"));
+    });
+  });
+}
diff --git a/tests/html/js_typed_interop_test.dart b/tests/html/js_typed_interop_test.dart
index 431d533..960c0cc 100644
--- a/tests/html/js_typed_interop_test.dart
+++ b/tests/html/js_typed_interop_test.dart
@@ -71,6 +71,15 @@
     getA: function() { return this.a;}
   };
 
+  function _PrivateClass(a, b) {
+    this._a = a;
+    this._b = b;
+  };
+
+  _PrivateClass.prototype = {
+    _getA: function() { return this._a;}
+  };
+
   var selection = ["a", "b", "c", foo, bar];  
 
   function returnNumArgs() { return arguments.length; };
@@ -78,6 +87,23 @@
 
   function confuse(obj) { return obj; }
 
+  window['class'] = function() { return 42; };
+  window['delete'] = 100;
+  window['JS$hasJsInName'] = 'unicorn';
+  window['JS$hasJsInNameMethod'] = function(x) { return x*5; };
+
+  function JS$ClassWithJSInName(x) {
+    this.x = x;
+    this.JS$hasJsInName = 73;
+    this.$JS$doesNotNeedEscape = 103;
+  };
+
+  JS$ClassWithJSInName.prototype = {
+    JS$getXwithJsInName: function() { return this.x;}
+  };
+
+  JS$ClassWithJSInName.JS$staticMethod = function(x) { return x * 3; };
+
   function StringWrapper(str) {
     this.str = str;
   }
@@ -110,6 +136,49 @@
   external get b;
 }
 
+@JS('ClassWithConstructor')
+class _ClassWithConstructor {
+  external _ClassWithConstructor(aParam, bParam);
+  external getA();
+  external get a;
+  external get b;
+}
+
+@JS()
+class JS$_PrivateClass {
+  external JS$_PrivateClass(aParam, bParam);
+  external JS$_getA();
+  external get JS$_a;
+  external get JS$_b;
+  // Equivalent to JS$_a but only visible within
+  // the class.
+  external get _a;
+}
+
+@JS()
+external String get JS$JS$hasJsInName;
+
+@JS()
+external int JS$JS$hasJsInNameMethod(int x);
+
+// This is the prefered way to handle static or top level members that start
+// with JS$. We verify that JS$JS$ works purely to prevent bugs.
+@JS(r'JS$hasJsInName')
+external String get JS$hasJsInName;
+
+@JS(r'JS$hasJsInNameMethod')
+external int JS$hasJsInNameMethod(int x);
+
+@JS()
+class JS$JS$ClassWithJSInName {
+  external JS$JS$ClassWithJSInName(x);
+  external int get x;
+  external int get JS$JS$hasJsInName;
+  external int get $JS$doesNotNeedEscape;
+  external int JS$JS$getXwithJsInName();
+  external static int JS$JS$staticMethod(x);
+}
+
 typedef num MultiplyWithDefault(num a, [num b]);
 
 @JS()
@@ -118,6 +187,7 @@
   external set x(int v);
   external num multiplyByX(num y);
   external num multiplyBy2(num y);
+  external num JS$multiplyBy2(num y);
   external MultiplyWithDefault get multiplyDefault2Function;
 
   external callClosureWithArgAndThis(Function closure, arg);
@@ -126,14 +196,17 @@
   external Bar getBar();
 
   external static num multiplyDefault2(num a, [num b]);
+  // Should desugar to multiplyDefault2.
+  external static num JS$multiplyDefault2(num a, [num b]);
 }
 
 @anonymous
 @JS()
 class ExampleLiteral {
-  external factory ExampleLiteral({int x, String y, num z});
+  external factory ExampleLiteral({int x, String y, num z, JS$class});
 
   external int get x;
+  external int get JS$class;
   external String get y;
   external num get z;
 }
@@ -182,6 +255,13 @@
 @JS()
 external confuse(obj);
 
+/// Desugars to calling the js method named class.
+@JS()
+external JS$class();
+
+@JS()
+external get JS$delete;
+
 @JS()
 external CanvasRenderingContext2D getCanvasContext();
 
@@ -191,6 +271,16 @@
 @JS('window.self.window.window.windowProperty')
 external num get propertyOnWindow;
 
+@JS()
+@anonymous
+class Simple
+{
+    external List<int> get numbers;
+    external set numbers(List<int> numbers);
+
+    external factory Simple({ List<int> numbers });
+}
+
 main() {
   _injectJs();
 
@@ -210,6 +300,17 @@
       expect(stringify(l), equals('{"z":100}'));
     });
 
+    test('with array', () {
+      // Repro for https://github.com/dart-lang/sdk/issues/26768
+       var simple = new Simple(numbers: [ 1, 2, 3 ]);
+       expect(stringify(simple), equals('{"numbers":[1,2,3]}'));
+    });
+
+    test(r'JS$ escaped name', () {
+      var l = new ExampleLiteral(JS$class: 3, y: "foo");
+      expect(l.JS$class, equals(3));
+    });
+
     test('empty', () {
       var l = new EmptyLiteral();
       expect(stringify(l), equals('{}'));
@@ -225,6 +326,25 @@
     });
   });
 
+  group('private class', () {
+    test('simple', () {
+      var o = new _ClassWithConstructor("foo", "bar");
+      expect(o.a, equals("foo"));
+      expect(o.b, equals("bar"));
+      expect(o.getA(), equals("foo"));
+    });
+  });
+
+  group('private class', () {
+    test('simple', () {
+      var o = new JS$_PrivateClass("foo", "bar");
+      expect(o.JS$_a, equals("foo"));
+      expect(o.JS$_b, equals("bar"));
+      expect(o._a, equals("foo"));
+      expect(o.JS$_getA(), equals("foo"));
+    });
+  });
+
   group('property', () {
     test('get', () {
       expect(foo.x, equals(3));
@@ -276,6 +396,22 @@
       expect(untypedFunction(), isNaN);
 
     });
+
+    test(r'JS$ escaped name', () {
+      foo.x = 10;
+      expect(foo.JS$multiplyBy2(5), equals(10));
+
+      Function multiplyBy2 = foo.JS$multiplyBy2;
+      expect(multiplyBy2(5), equals(10));
+    });
+
+    test(r'JS$ double escaped name', () {
+      var obj = new JS$JS$ClassWithJSInName(42);
+      expect(obj.x, equals(42));
+      expect(obj.JS$JS$getXwithJsInName(), equals(42));
+      expect(obj.JS$JS$hasJsInName, equals(73));
+      expect(obj.$JS$doesNotNeedEscape, equals(103));
+    });
   });
 
   group('static_method_call', () {
@@ -283,6 +419,15 @@
       expect(Foo.multiplyDefault2(6, 7), equals(42));
       expect(Foo.multiplyDefault2(6), equals(12));
     });
+
+    test(r'JS$ escaped name', () {
+      expect(Foo.JS$multiplyDefault2(6, 7), equals(42));
+      expect(Foo.JS$multiplyDefault2(6), equals(12));
+    });
+
+    test(r'JS$ double escaped name', () {
+      expect(JS$JS$ClassWithJSInName.JS$JS$staticMethod(4), equals(12));
+    });
   });
 
   // Note: these extra groups are added to be able to mark each test
@@ -384,6 +529,17 @@
     });
   });
 
+  group(r'JS$ escaped', () {
+    test('top level', () {
+      expect(JS$class(), equals(42));
+      expect(JS$delete, equals(100));
+    });
+    test('top level double escaped', () {
+      expect(JS$JS$hasJsInName, equals('unicorn'));
+      expect(JS$JS$hasJsInNameMethod(4), equals(20));
+    });
+  });
+
   group('type check', () {
     test('js interfaces', () {
       // Is checks return true for all  JavaScript interfaces.
diff --git a/tests/html/js_typed_interop_type_test.dart b/tests/html/js_typed_interop_type_test.dart
new file mode 100644
index 0000000..59266dc
--- /dev/null
+++ b/tests/html/js_typed_interop_type_test.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@JS()
+library js_typed_interop_type_test;
+
+import 'dart:html';
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+class A {
+  var foo;
+
+  external A(var foo);
+}
+
+@JS()
+class B {
+  var foo;
+
+  external B(var foo);
+}
+
+@JS()
+@anonymous
+class C {
+  final foo;
+
+  external factory C({foo});
+}
+
+@JS()
+@anonymous
+class D {
+  final foo;
+
+  external factory D({foo});
+}
+
+class E {
+  final foo;
+
+  E(this.foo);
+}
+
+class F {
+  final foo;
+
+  F(this.foo);
+}
+
+@NoInline()
+testA(A o) {
+  return o.foo;
+}
+
+
+@NoInline()
+testB(B o) {
+  return o.foo;
+}
+
+
+@NoInline()
+testC(C o) {
+  return o.foo;
+}
+
+
+@NoInline()
+testD(D o) {
+  return o.foo;
+}
+
+@NoInline()
+testE(E o) {
+  return o.foo;
+}
+
+@NoInline()
+testF(F o) {
+  return o.foo;
+}
+
+
+_injectJs() {
+  document.body.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+function A(foo) {
+  this.foo = foo;
+}
+
+function B(foo) {
+  this.foo = foo;
+}
+""");
+}
+
+void expectValueOrTypeError(f(), value) {
+  try {
+    var i = 0;
+    String s = i; // Test for checked mode.
+    Expect.equals(f(), value);
+  } on TypeError catch (error) {
+    Expect.throws(f, (ex) => ex is TypeError);
+  }
+}
+
+main() {
+  _injectJs();
+
+  var a = new A(1);
+  var b = new B(2);
+  var c = new C(foo: 3);
+  var d = new D(foo: 4);
+  var e = new E(5);
+  var f = new F(6);
+
+  Expect.equals(testA(a), 1);
+  Expect.equals(testA(b), 2);
+  Expect.equals(testA(c), 3);
+  Expect.equals(testA(d), 4);
+  expectValueOrTypeError(() => testA(e), 5);
+  expectValueOrTypeError(() => testA(f), 6);
+
+  Expect.equals(testB(a), 1);
+  Expect.equals(testB(b), 2);
+  Expect.equals(testB(c), 3);
+  Expect.equals(testB(d), 4);
+  expectValueOrTypeError(() => testB(e), 5);
+  expectValueOrTypeError(() => testB(f), 6);
+
+  Expect.equals(testC(a), 1);
+  Expect.equals(testC(b), 2);
+  Expect.equals(testC(c), 3);
+  Expect.equals(testC(d), 4);
+  expectValueOrTypeError(() => testC(e), 5);
+  expectValueOrTypeError(() => testC(f), 6);
+
+  Expect.equals(testD(a), 1);
+  Expect.equals(testD(b), 2);
+  Expect.equals(testD(c), 3);
+  Expect.equals(testD(d), 4);
+  expectValueOrTypeError(() => testD(e), 5);
+  expectValueOrTypeError(() => testD(f), 6);
+
+  expectValueOrTypeError(() => testE(a), 1);
+  expectValueOrTypeError(() => testE(b), 2);
+  expectValueOrTypeError(() => testE(c), 3);
+  expectValueOrTypeError(() => testE(d), 4);
+  Expect.equals(testE(e), 5);
+  expectValueOrTypeError(() => testE(f), 6);
+
+  expectValueOrTypeError(() => testF(a), 1);
+  expectValueOrTypeError(() => testF(b), 2);
+  expectValueOrTypeError(() => testF(c), 3);
+  expectValueOrTypeError(() => testF(d), 4);
+  expectValueOrTypeError(() => testF(e), 5);
+  Expect.equals(testF(f), 6);
+}
+
+
diff --git a/tests/html/js_typed_interop_window_property_test.dart b/tests/html/js_typed_interop_window_property_test.dart
new file mode 100644
index 0000000..0f2bdc6
--- /dev/null
+++ b/tests/html/js_typed_interop_window_property_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_typed_interop_window_property_test;
+
+import 'dart:html';
+
+import 'package:js/js.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:unittest/html_individual_config.dart';
+
+// This is a regression test for https://github.com/dart-lang/sdk/issues/24817
+
+_injectJs() {
+  document.body.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  "use strict";
+
+  window.foo = [function() { return 42; }];
+""");
+}
+
+@JS("window.foo")
+external List<Function> get foo;
+
+main() {
+  _injectJs();
+
+  useHtmlIndividualConfiguration();
+
+  group('bind this', () {
+    test('simple', () {
+      expect(foo[0](), equals(42));
+    });
+  });
+}
diff --git a/tests/html/js_util_test.dart b/tests/html/js_util_test.dart
new file mode 100644
index 0000000..b0130b2
--- /dev/null
+++ b/tests/html/js_util_test.dart
@@ -0,0 +1,347 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_native_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:typed_data' show ByteBuffer, Int32List;
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+
+_injectJs() {
+  final script = new ScriptElement();
+  script.type = 'text/javascript';
+  script.innerHtml = r"""
+var x = 42;
+
+var _x = 123;
+
+var myArray = ["value1"];
+
+function returnThis() {
+  return this;
+}
+
+function getTypeOf(o) {
+  return typeof(o);
+}
+
+function Foo(a) {
+  this.a = a;
+}
+
+Foo.b = 38;
+
+Foo.prototype.bar = function() {
+  return this.a;
+}
+Foo.prototype.toString = function() {
+  return "I'm a Foo a=" + this.a;
+}
+
+var container = new Object();
+container.Foo = Foo;
+
+function checkMap(m, key, value) {
+  if (m.hasOwnProperty(key))
+    return m[key] == value;
+  else
+    return false;
+}
+
+""";
+  document.body.append(script);
+}
+
+@JS()
+external bool checkMap(m, String, value);
+
+@JS('JSON.stringify')
+external String stringify(o);
+
+@JS('Node')
+external get JSNodeType;
+
+@JS('Element')
+external get JSElementType;
+
+@JS('Text')
+external get JSTextType;
+
+@JS('HTMLCanvasElement')
+external get JSHtmlCanvasElementType;
+
+@JS()
+class Foo {
+  external Foo(num a);
+
+  external num get a;
+  external num bar();
+}
+
+@JS('Foo')
+external get JSFooType;
+
+@JS()
+@anonymous
+class ExampleTypedLiteral {
+  external factory ExampleTypedLiteral({a, b, JS$_c, JS$class});
+
+  external get a;
+  external get b;
+  external get JS$_c;
+  external set JS$_c(v);
+  // Identical to JS$_c but only accessible within the library.
+  external get _c;
+  external get JS$class;
+  external set JS$class(v);
+}
+
+@JS("Object.prototype.hasOwnProperty")
+external get _hasOwnProperty;
+
+bool hasOwnProperty(o, String name) {
+  return js_util.callMethod(_hasOwnProperty, 'call', [o, name]);
+}
+
+main() {
+  _injectJs();
+  useHtmlIndividualConfiguration();
+
+  group('js_util.jsify()', () {
+    test('convert a List', () {
+      final list = [1, 2, 3, 4, 5, 6, 7, 8];
+      var array = js_util.jsify(list);
+      expect(array is List, isTrue);
+      expect(identical(array, list), isFalse);
+      expect(array.length, equals(list.length));
+      for (var i = 0; i < list.length; i++) {
+        expect(array[i], equals(list[i]));
+      }
+    });
+
+    test('convert an Iterable', () {
+      final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]);
+      var array = js_util.jsify(set);
+      expect(array is List, isTrue);
+      expect(array.length, equals(set.length));
+      for (var i = 0; i < array.length; i++) {
+        expect(set.contains(array[i]), isTrue);
+      }
+    });
+
+    test('convert a Map', () {
+      var map = {'a': 1, 'b': 2, 'c': 3};
+      var jsMap = js_util.jsify(map);
+      expect(jsMap is! List, isTrue);
+      for (var key in map.keys) {
+        expect(checkMap(jsMap, key, map[key]), isTrue);
+      }
+    });
+
+    test('deep convert a complex object', () {
+      final object = {
+        'a': [
+          1,
+          [2, 3]
+        ],
+        'b': {'c': 3, 'd': new Foo(42)},
+        'e': null
+      };
+      var jsObject = js_util.jsify(object);
+      expect(js_util.getProperty(jsObject, 'a')[0], equals(object['a'][0]));
+      expect(
+          js_util.getProperty(jsObject, 'a')[1][0], equals(object['a'][1][0]));
+      expect(
+          js_util.getProperty(jsObject, 'a')[1][1], equals(object['a'][1][1]));
+      expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'c'),
+          equals(object['b']['c']));
+      expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'),
+          equals(object['b']['d']));
+      expect(
+          js_util.callMethod(
+              js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'),
+              'bar', []),
+          equals(42));
+      expect(js_util.getProperty(jsObject, 'e'), isNull);
+    });
+
+    test('throws if object is not a Map or Iterable', () {
+      expect(() => js_util.jsify('a'),
+          throwsA(new isInstanceOf<ArgumentError>()));
+    });
+  });
+
+  group('js_util.newObject', () {
+    test('create', () {
+      expect(identical(js_util.newObject(), js_util.newObject()), isFalse);
+    });
+
+    test('callMethod', () {
+      var o = js_util.newObject();
+      expect(js_util.callMethod(o, 'toString', []), equals('[object Object]'));
+      expect(stringify(o), equals('{}'));
+    });
+
+    test('properties', () {
+      var o = js_util.newObject();
+      expect(js_util.hasProperty(o, 'foo bar'), isFalse);
+      expect(js_util.hasProperty(o, 'toString'), isTrue);
+      expect(hasOwnProperty(o, 'toString'), isFalse);
+      expect(hasOwnProperty(o, 'foo bar'), isFalse);
+      js_util.setProperty(o, 'foo bar', 42);
+      expect(hasOwnProperty(o, 'foo bar'), isTrue);
+      expect(js_util.getProperty(o, 'foo bar'), equals(42));
+      expect(js_util.hasProperty(o, 'foo bar'), isTrue);
+      expect(stringify(o), equals('{"foo bar":42}'));
+    });
+  });
+
+  group('hasProperty', () {
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.hasProperty(f, 'a'), isTrue);
+      expect(js_util.hasProperty(f, 'toString'), isTrue);
+      js_util.setProperty(f, '__proto__', null);
+      expect(js_util.hasProperty(f, 'toString'), isFalse);
+    });
+    test('typed literal', () {
+      var l =
+          new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: null, JS$class: true);
+      expect(js_util.hasProperty(l, 'a'), isTrue);
+      expect(js_util.hasProperty(l, 'b'), isTrue);
+      expect(js_util.hasProperty(l, '_c'), isTrue);
+      expect(l.JS$_c, isNull);
+      expect(js_util.hasProperty(l, 'class'), isTrue);
+      // JS$_c escapes to _c so the property JS$_c will not exist on the object.
+      expect(js_util.hasProperty(l, r'JS$_c'), isFalse);
+      expect(js_util.hasProperty(l, r'JS$class'), isFalse);
+      expect(l.JS$class, isTrue);
+
+      l = new ExampleTypedLiteral(a: null);
+      expect(js_util.hasProperty(l, 'a'), isTrue);
+      expect(js_util.hasProperty(l, 'b'), isFalse);
+      expect(js_util.hasProperty(l, '_c'), isFalse);
+      expect(js_util.hasProperty(l, 'class'), isFalse);
+
+      l = new ExampleTypedLiteral(JS$_c: 74);
+      expect(js_util.hasProperty(l, '_c'), isTrue);
+      expect(l.JS$_c, equals(74));
+    });
+  });
+
+  group('getProperty', () {
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.getProperty(f, 'a'), equals(42));
+      expect(js_util.getProperty(f, 'toString') is Function, isTrue);
+      js_util.setProperty(f, '__proto__', null);
+      expect(js_util.getProperty(f, 'toString'), isNull);
+    });
+
+    test('typed literal', () {
+      var l = new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: 7, JS$class: true);
+      expect(js_util.getProperty(l, 'a'), equals('x'));
+      expect(js_util.getProperty(l, 'b'), equals(42));
+      expect(js_util.getProperty(l, '_c'), equals(7));
+      expect(l.JS$_c, equals(7));
+      expect(js_util.getProperty(l, 'class'), isTrue);
+      expect(js_util.getProperty(l, r'JS$_c'), isNull);
+      expect(js_util.getProperty(l, r'JS$class'), isNull);
+    });
+  });
+
+  group('setProperty', () {
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.getProperty(f, 'a'), equals(42));
+      js_util.setProperty(f, 'a', 100);
+      expect(f.a, equals(100));
+      expect(js_util.getProperty(f, 'a'), equals(100));
+    });
+
+    test('typed literal', () {
+      var l = new ExampleTypedLiteral();
+      js_util.setProperty(l, 'a', 'foo');
+      expect(js_util.getProperty(l, 'a'), equals('foo'));
+      expect(l.a, equals('foo'));
+      js_util.setProperty(l, 'a', l);
+      expect(identical(l.a, l), isTrue);
+      var list = ['arr'];
+      js_util.setProperty(l, 'a', list);
+      expect(identical(l.a, list), isTrue);
+      l.JS$class = 42;
+      expect(l.JS$class, equals(42));
+      js_util.setProperty(l, 'class', 100);
+      expect(l.JS$class, equals(100));
+    });
+  });
+
+  group('callMethod', () {
+    test('html object', () {
+      var canvas = new Element.tag('canvas');
+      expect(
+          identical(canvas.getContext('2d'),
+              js_util.callMethod(canvas, 'getContext', ['2d'])),
+          isTrue);
+    });
+
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.callMethod(f, 'bar', []), equals(42));
+    });
+  });
+
+  group('instanceof', () {
+    test('html object', () {
+      var canvas = new Element.tag('canvas');
+      expect(js_util.instanceof(canvas, JSNodeType), isTrue);
+      expect(js_util.instanceof(canvas, JSTextType), isFalse);
+      expect(js_util.instanceof(canvas, JSElementType), isTrue);
+      expect(js_util.instanceof(canvas, JSHtmlCanvasElementType), isTrue);
+      var div = new Element.tag('div');
+      expect(js_util.instanceof(div, JSNodeType), isTrue);
+      expect(js_util.instanceof(div, JSTextType), isFalse);
+      expect(js_util.instanceof(div, JSElementType), isTrue);
+      expect(js_util.instanceof(div, JSHtmlCanvasElementType), isFalse);
+
+      var text = new Text('foo');
+      expect(js_util.instanceof(text, JSNodeType), isTrue);
+      expect(js_util.instanceof(text, JSTextType), isTrue);
+      expect(js_util.instanceof(text, JSElementType), isFalse);
+    });
+
+    test('typed object', () {
+      var f = new Foo(42);
+      expect(js_util.instanceof(f, JSFooType), isTrue);
+      expect(js_util.instanceof(f, JSNodeType), isFalse);
+    });
+
+    test('typed literal', () {
+      var l = new ExampleTypedLiteral();
+      expect(js_util.instanceof(l, JSFooType), isFalse);
+    });
+  });
+
+  group('callConstructor', () {
+    test('html object', () {
+      var textNode = js_util.callConstructor(JSTextType, ['foo']);
+      expect(js_util.instanceof(textNode, JSTextType), isTrue);
+      expect(textNode is Text, isTrue);
+      expect(textNode.text, equals('foo'));
+    });
+
+    test('typed object', () {
+      Foo f = js_util.callConstructor(JSFooType, [42]);
+      expect(f.a, equals(42));
+    });
+  });
+}
diff --git a/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart b/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
index 4d7d338..6859e87 100644
--- a/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
+++ b/tests/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
@@ -116,6 +116,14 @@
         validator,
         '<span>![CDATA[ some text ]]></span>');
 
+    testHtml('backquotes not removed',
+             validator,
+             '<img src="dice.png" alt="``onload=xss()" />');
+
+    testHtml('0x3000 not removed',
+             validator,
+             '<a href="&#x3000;javascript:alert(1)">CLICKME</a>');
+
     test('sanitizes template contents', () {
       if (!TemplateElement.supported) return;
 
diff --git a/tests/html/webgl_extensions_test.dart b/tests/html/webgl_extensions_test.dart
new file mode 100644
index 0000000..07232f0
--- /dev/null
+++ b/tests/html/webgl_extensions_test.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 web_gl_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+import 'dart:typed_data';
+import 'dart:web_gl';
+import 'dart:web_gl' as gl;
+
+// Test that various webgl extensions are available. Only test advertised
+// supported extensions. If the extension has methods, we just test the presence
+// of some methods - we don't test if functionality works.
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  if (!RenderingContext.supported) return;
+
+
+  const allExtensions = const [
+    'ANGLE_instanced_arrays',
+    'EXT_blend_minmax',
+    'EXT_color_buffer_float',
+    'EXT_color_buffer_half_float',
+    'EXT_disjoint_timer_query',
+    'EXT_frag_depth',
+    'EXT_sRGB',
+    'EXT_shader_texture_lod',
+    'EXT_texture_filter_anisotropic',
+    'OES_element_index_uint',
+    'OES_standard_derivatives',
+    'OES_texture_float',
+    'OES_texture_float_linear',
+    'OES_texture_half_float',
+    'OES_texture_half_float_linear',
+    'OES_vertex_array_object',
+    'WEBGL_color_buffer_float',
+    'WEBGL_compressed_texture_atc',
+    'WEBGL_compressed_texture_es3',
+    'WEBGL_compressed_texture_etc1',
+    'WEBGL_compressed_texture_pvrtc',
+    'WEBGL_compressed_texture_s3tc',
+    'WEBGL_debug_renderer_info',
+    'WEBGL_debug_shaders',
+    'WEBGL_depth_texture',
+    'WEBGL_draw_buffers',
+    'WEBGL_lose_context',
+  ];
+
+  getExtension(String name) {
+    expect(name, isIn(allExtensions), reason: 'unknown extension');
+    var canvas = new CanvasElement();
+    var context = canvas.getContext3d();
+    var supportedExtensions = context.getSupportedExtensions();
+    if (supportedExtensions.contains(name)) {
+      var extension = context.getExtension(name);
+      expect(extension, isNotNull);
+      return extension;
+    }
+    return null;
+  }
+
+  testType(name, typeMatcher) {
+    test('type', () {
+      var extension = getExtension(name);
+      if (extension == null) return;
+      expect(extension, typeMatcher);
+      // Ensure that isInstanceOf<X> is not instantiated for an erroneous type
+      // X.  If X is erroneous, there is only a warning at compile time and X is
+      // treated as dynamic, which would make the above line pass.
+      expect(1, isNot(typeMatcher), reason: 'invalid typeMatcher');
+    });
+  }
+
+  group('ANGLE_instanced_arrays', () {
+    const name = 'ANGLE_instanced_arrays';
+    testType(name, const isInstanceOf<AngleInstancedArrays>());
+    test('vertexAttribDivisorAngle', () {
+      var extension = getExtension(name);
+      if (extension == null) return;
+      expect(extension.vertexAttribDivisorAngle, isFunction);
+    });
+  });
+
+  group('EXT_blend_minmax', () {
+    testType('EXT_blend_minmax', const isInstanceOf<ExtBlendMinMax>());
+  });
+
+  group('EXT_frag_depth', () {
+    testType('EXT_frag_depth', const isInstanceOf<ExtFragDepth>());
+  });
+
+  group('EXT_sRGB', () {
+    testType('EXT_sRGB', const isInstanceOf<EXTsRgb>());
+  });
+
+  group('EXT_shader_texture_lod', () {
+    testType(
+        'EXT_shader_texture_lod', const isInstanceOf<ExtShaderTextureLod>());
+  });
+
+  group('EXT_texture_filter_anisotropic', () {
+    testType('EXT_texture_filter_anisotropic',
+        const isInstanceOf<ExtTextureFilterAnisotropic>());
+  });
+
+  group('OES_element_index_uint', () {
+    testType(
+        'OES_element_index_uint', const isInstanceOf<OesElementIndexUint>());
+  });
+
+  group('OES_standard_derivatives', () {
+    testType('OES_standard_derivatives',
+        const isInstanceOf<OesStandardDerivatives>());
+  });
+
+  group('OES_texture_float', () {
+    testType('OES_texture_float', const isInstanceOf<OesTextureFloat>());
+  });
+
+  group('OES_texture_float_linear', () {
+    testType('OES_texture_float_linear',
+        const isInstanceOf<OesTextureFloatLinear>());
+  });
+
+  group('OES_texture_half_float', () {
+    testType(
+        'OES_texture_half_float', const isInstanceOf<OesTextureHalfFloat>());
+  });
+
+  group('OES_texture_half_float_linear', () {
+    testType('OES_texture_half_float_linear',
+        const isInstanceOf<OesTextureHalfFloatLinear>());
+  });
+
+  group('OES_vertex_array_object', () {
+    testType(
+        'OES_vertex_array_object', const isInstanceOf<OesVertexArrayObject>());
+  });
+
+  group('WEBGL_compressed_texture_atc', () {
+    testType('WEBGL_compressed_texture_atc',
+        const isInstanceOf<CompressedTextureAtc>());
+  });
+
+  group('WEBGL_compressed_texture_etc1', () {
+    testType('WEBGL_compressed_texture_etc1',
+        const isInstanceOf<CompressedTextureETC1>());
+  });
+
+  group('WEBGL_compressed_texture_pvrtc', () {
+    testType('WEBGL_compressed_texture_pvrtc',
+        const isInstanceOf<CompressedTexturePvrtc>());
+  });
+
+  group('WEBGL_compressed_texture_s3tc', () {
+    testType('WEBGL_compressed_texture_s3tc',
+        const isInstanceOf<CompressedTextureS3TC>());
+  });
+
+  group('WEBGL_debug_renderer_info', () {
+    testType(
+        'WEBGL_debug_renderer_info', const isInstanceOf<DebugRendererInfo>());
+  });
+
+  group('WEBGL_debug_shaders', () {
+    testType('WEBGL_debug_shaders', const isInstanceOf<DebugShaders>());
+  });
+
+  group('WEBGL_depth_texture', () {
+    testType('WEBGL_depth_texture', const isInstanceOf<DepthTexture>());
+  });
+
+  group('WEBGL_draw_buffers', () {
+    const name = 'WEBGL_draw_buffers';
+    testType(name, const isInstanceOf<DrawBuffers>());
+    test('drawBuffersWebgl', () {
+      var extension = getExtension(name);
+      if (extension == null) return;
+      expect(extension.drawBuffersWebgl, isFunction);
+    });
+  });
+
+  group('WEBGL_lose_context', () {
+    const name = 'WEBGL_lose_context';
+    testType(name, const isInstanceOf<LoseContext>());
+    test('loseContext', () {
+      var extension = getExtension(name);
+      if (extension == null) return;
+      expect(extension.loseContext, isFunction);
+    });
+  });
+}
+
+Matcher isFunction = const isInstanceOf<Function>();
diff --git a/tests/isolate/enum_const_test.dart b/tests/isolate/enum_const_test.dart
index 54ba24f..4654cdc 100644
--- a/tests/isolate/enum_const_test.dart
+++ b/tests/isolate/enum_const_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 import "dart:isolate";
 import "package:expect/expect.dart";
 
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 67d2941..ab8dec3 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -207,3 +207,10 @@
 
 [ $compiler == precompiler && $runtime == dart_precompiled && $system == android ]
 *: Skip # Issue #26373
+
+[ $hot_reload || $hot_reload_rollback ]
+function_send_test: Pass, Fail # Closure identity
+message3_test/fun: Pass, Fail # Closure identity
+deferred_in_isolate_test: Crash # Requires deferred libraries
+deferred_in_isolate2_test: Crash # Requires deferred libraries
+issue_21398_parent_isolate2_test: Crash # Requires deferred libraries
diff --git a/tests/isolate/message_enum_test.dart b/tests/isolate/message_enum_test.dart
index b06dfc3..aa11fb2 100644
--- a/tests/isolate/message_enum_test.dart
+++ b/tests/isolate/message_enum_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import "dart:isolate";
diff --git a/tests/isolate/package_config_test.dart b/tests/isolate/package_config_test.dart
index 1b55194..58792d9 100644
--- a/tests/isolate/package_config_test.dart
+++ b/tests/isolate/package_config_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=--trace_shutdown
 import 'dart:io';
 import 'dart:isolate';
 
diff --git a/tests/language/arg_param_trailing_comma_test.dart b/tests/language/arg_param_trailing_comma_test.dart
index 4b87b1a..cd0d3a4 100644
--- a/tests/language/arg_param_trailing_comma_test.dart
+++ b/tests/language/arg_param_trailing_comma_test.dart
@@ -41,7 +41,7 @@
 void afterFunsigY([void f(),]) {}                     /// none: continued
 void afterFunsigZ({void f(),}) {}                     /// none: continued
 void afterFunsigDefaultValueY([void f() = topy,]) {}  /// none: continued
-void afterFunsigDefaultValueZ({void f() : topt,}) {}  /// none: continued
+void afterFunsigDefaultValueZ({void f() : topz,}) {}  /// none: continued
 
 class C {
   C();
@@ -77,8 +77,8 @@
 
 main() {
   testCalls();                                        /// none: continued
-  // Make sure the Bad class is checked.
-  new Bad().method();
+  // Make sure the cases are checked.
+  testBadCalls();
 }
 
 void testCalls() {
@@ -124,7 +124,7 @@
   c + x;                                              /// none: continued
   c[x] = y;                                           /// none: continued
 
-  // Call with ekstra comma (not possible for setters and operators).
+  // Call with extra comma (not possible for setters and operators).
   topx(x, );                                          /// none: continued
   topy(y, );                                          /// none: continued
   topxy(x, y, );                                      /// none: continued
@@ -169,7 +169,6 @@
   argfxz(topxz);                                      /// none: continued
 }
 
-
 // Invalid syntax. This was invalid syntax before the addition of trailing
 // commas too, and should stay that way.
 void topBadEmpty(,) {}                           /// 1: compile-time error
@@ -199,6 +198,7 @@
 void set topSetBadEnd(a,,) {}                    /// 25: compile-time error
 void set topSetBadMiddle(a,, b) {}               /// 26: compile-time error
 class Bad {
+  Bad() {}
   Bad.empty(,) {}                                /// 27: compile-time error
   Bad.start(, a) {}                              /// 28: compile-time error
   Bad.end(a,,) {}                                /// 29: compile-time error
@@ -399,3 +399,164 @@
 typedef void BadNamEnd({a,,});                   /// 208: compile-time error
 typedef void BadNamStart({a},);                  /// 209: compile-time error
 typedef void BadNamMiddle({a,, b});              /// 210: compile-time error
+
+void testBadCalls() {
+  topBadEmpty();                                 /// 1: continued
+  topBadStart();                                 /// 2: continued
+  topBadEnd();                                   /// 3: continued
+  topBadMiddle();                                /// 4: continued
+  topBadPosEmpty();                              /// 5: continued
+  topBadPosEmpty();                              /// 6: continued
+  topBadPosEmpty();                              /// 7: continued
+  topBadPosEmpty();                              /// 8: continued
+  topBadPosStart();                              /// 9: continued
+  topBadPosStart();                              /// 10: continued
+  topBadPosEnd();                                /// 11: continued
+  topBadPosStart();                              /// 12: continued
+  topBadPosMiddle();                             /// 13: continued
+  topBadNamEmpty();                              /// 14: continued
+  topBadNamEmpty();                              /// 15: continued
+  topBadNamEmpty();                              /// 16: continued
+  topBadNamEmpty();                              /// 17: continued
+  topBadNamStart();                              /// 18: continued
+  topBadNamStart();                              /// 19: continued
+  topBadNamEnd();                                /// 20: continued
+  topBadNamStart();                              /// 21: continued
+  topBadNamMiddle();                             /// 22: continued
+  topSetBadEmpty = 1;                            /// 23: continued
+  topSetBadStart = 1;                            /// 24: continued
+  topSetBadEnd = 1;                              /// 25: continued
+  topSetBadMiddle = 1;                           /// 26: continued
+  new Bad.empty();                               /// 27: continued
+  new Bad.start();                               /// 28: continued
+  new Bad.end();                                 /// 29: continued
+  new Bad.middle();                              /// 30: continued
+  new Bad.posEmpty();                            /// 31: continued
+  new Bad.posEmpty();                            /// 32: continued
+  new Bad.posEmpty();                            /// 33: continued
+  new Bad.posEmpty();                            /// 34: continued
+  new Bad.posStart();                            /// 35: continued
+  new Bad.posStart();                            /// 36: continued
+  new Bad.posEnd();                              /// 37: continued
+  new Bad.posStart();                            /// 38: continued
+  new Bad.PosMiddle();                           /// 39: continued
+  new Bad.namEmpty();                            /// 40: continued
+  new Bad.namEmpty();                            /// 41: continued
+  new Bad.namEmpty();                            /// 42: continued
+  new Bad.namEmpty();                            /// 43: continued
+  new Bad.namStart();                            /// 44: continued
+  new Bad.namStart();                            /// 45: continued
+  new Bad.namEnd();                              /// 46: continued
+  new Bad.namStart();                            /// 47: continued
+  new Bad.namMiddle();                           /// 48: continued
+  Bad.staticBadEmpty();                          /// 49: continued
+  Bad.staticBadStart();                          /// 50: continued
+  Bad.staticBadEnd();                            /// 51: continued
+  Bad.staticBadMiddle();                         /// 52: continued
+  Bad.staticBadPosEmpty();                       /// 53: continued
+  Bad.staticBadPosEmpty();                       /// 54: continued
+  Bad.staticBadPosEmpty();                       /// 55: continued
+  Bad.staticBadPosEmpty();                       /// 56: continued
+  Bad.staticBadPosStart();                       /// 57: continued
+  Bad.staticBadPosStart();                       /// 58: continued
+  Bad.staticBadPosEnd();                         /// 59: continued
+  Bad.staticBadPosStart();                       /// 60: continued
+  Bad.staticBadPosMiddle();                      /// 61: continued
+  Bad.staticBadNamEmpty();                       /// 62: continued
+  Bad.staticBadNamEmpty();                       /// 63: continued
+  Bad.staticBadNamEmpty();                       /// 64: continued
+  Bad.staticBadNamEmpty();                       /// 65: continued
+  Bad.staticBadNamStart();                       /// 66: continued
+  Bad.staticBadNamStart();                       /// 67: continued
+  Bad.staticBadNamEnd();                         /// 68: continued
+  Bad.staticBadNamStart();                       /// 69: continued
+  Bad.staticBadNamMiddle();                      /// 70: continued
+  Bad.staticSetBadEmpty = 1;                     /// 71: continued
+  Bad.staticSetBadStart = 1;                     /// 72: continued
+  Bad.staticSetBadEnd = 1;                       /// 73: continued
+  Bad.staticSetBadMiddle = 1;                    /// 74: continued
+
+  var bad = new Bad();
+  bad.instanceBadEmpty();                        /// 75: continued
+  bad.instanceBadStart();                        /// 76: continued
+  bad.instanceBadEnd();                          /// 77: continued
+  bad.instanceBadMiddle();                       /// 78: continued
+  bad.instanceBadPosEmpty();                     /// 79: continued
+  bad.instanceBadPosEmpty();                     /// 80: continued
+  bad.instanceBadPosEmpty();                     /// 81: continued
+  bad.instanceBadPosEmpty();                     /// 82: continued
+  bad.instanceBadPosStart();                     /// 83: continued
+  bad.instanceBadPosStart();                     /// 84: continued
+  bad.instanceBadPosEnd();                       /// 85: continued
+  bad.instanceBadPosStart();                     /// 86: continued
+  bad.instanceBadPosMiddle();                    /// 87: continued
+  bad.instanceBadNamEmpty();                     /// 88: continued
+  bad.instanceBadNamEmpty();                     /// 89: continued
+  bad.instanceBadNamEmpty();                     /// 90: continued
+  bad.instanceBadNamEmpty();                     /// 91: continued
+  bad.instanceBadNamStart();                     /// 92: continued
+  bad.instanceBadNamStart();                     /// 93: continued
+  bad.instanceBadNamEnd();                       /// 94: continued
+  bad.instanceBadNamStart();                     /// 95: continued
+  bad.instanceBadNamMiddle();                    /// 96: continued
+  bad.instanceSetBadEmpty = 1;                   /// 97: continued
+  bad.instanceSetBadStart = 1;                   /// 98: continued
+  bad.instanceSetBadEnd = 1;                     /// 99: continued
+  bad.instanceSetBadMiddle = 1;                  /// 100: continued
+  bad * bad;                                     /// 101: continued
+  bad * bad;                                     /// 102: continued
+  bad * bad;                                     /// 103: continued
+  bad[1] = 1;                                    /// 104: continued
+  bad[1] = 1;                                    /// 105: continued
+  bad[1] = 1;                                    /// 106: continued
+  bad[1] = 1;                                    /// 107: continued
+
+  // This covers tests 108-166
+  bad.method();
+
+  bad.f(() {});                                  /// 167: compile-time error
+  bad.f(() {});                                  /// 168: compile-time error
+  bad.f(() {});                                  /// 169: compile-time error
+  bad.f(() {});                                  /// 170: compile-time error
+  bad.f(() {});                                  /// 171: compile-time error
+  bad.f(() {});                                  /// 172: compile-time error
+  bad.f(() {});                                  /// 173: compile-time error
+  bad.f(() {});                                  /// 174: compile-time error
+  bad.f(() {});                                  /// 175: compile-time error
+  bad.f(() {});                                  /// 176: compile-time error
+  bad.f(() {});                                  /// 177: compile-time error
+  bad.f(() {});                                  /// 178: compile-time error
+  bad.f(() {});                                  /// 179: compile-time error
+  bad.f(() {});                                  /// 180: compile-time error
+  bad.f(() {});                                  /// 181: compile-time error
+  bad.f(() {});                                  /// 182: compile-time error
+  bad.f(() {});                                  /// 183: compile-time error
+  bad.f(() {});                                  /// 184: compile-time error
+  bad.f(() {});                                  /// 185: compile-time error
+  bad.f(() {});                                  /// 186: compile-time error
+  bad.f(() {});                                  /// 187: compile-time error
+  bad.f(() {});                                  /// 188: compile-time error
+
+  BadEmpty x;                                    /// 189: compile-time error
+  BadStart x;                                    /// 190: compile-time error
+  BadEnd x;                                      /// 191: compile-time error
+  BadMiddle x;                                   /// 192: compile-time error
+  BadPosEmpty x;                                 /// 193: compile-time error
+  BadPosEmpty x;                                 /// 194: compile-time error
+  BadPosEmpty x;                                 /// 195: compile-time error
+  BadPosEmpty x;                                 /// 196: compile-time error
+  BadPosStart x;                                 /// 197: compile-time error
+  BadPosStart x;                                 /// 198: compile-time error
+  BadPosEnd x;                                   /// 199: compile-time error
+  BadPosStart x;                                 /// 200: compile-time error
+  BadPosMiddle x;                                /// 201: compile-time error
+  BadNamEmpty x;                                 /// 202: compile-time error
+  BadNamEmpty x;                                 /// 203: compile-time error
+  BadNamEmpty x;                                 /// 204: compile-time error
+  BadNamEmpty x;                                 /// 205: compile-time error
+  BadNamStart x;                                 /// 206: compile-time error
+  BadNamStart x;                                 /// 207: compile-time error
+  BadNamEnd x;                                   /// 208: compile-time error
+  BadNamStart x;                                 /// 209: compile-time error
+  BadNamMiddle x;                                /// 210: compile-time error
+}
diff --git a/tests/language/await_test.dart b/tests/language/await_test.dart
index 257d840..d91c2a8 100644
--- a/tests/language/await_test.dart
+++ b/tests/language/await_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.
 
-// VMOptions=---optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
 
 import 'package:expect/expect.dart';
 
diff --git a/tests/language/compile_time_constant_e_test.dart b/tests/language/compile_time_constant_e_test.dart
index 7ab0ea2..77b20e9 100644
--- a/tests/language/compile_time_constant_e_test.dart
+++ b/tests/language/compile_time_constant_e_test.dart
@@ -19,7 +19,6 @@
 }
 
 const a1 = const A(99, 100);
-const a1n = const A.n(99, 100);
 const a2 = const A.named(z: 99, t: 100);
 const a3 = const A.named2(t: 1, z: 2, y: 3, x: 4);
 const a4 = const A();
diff --git a/tests/language/dangling_else_test.dart b/tests/language/dangling_else_test.dart
index 84bdec8..cad2fc7 100644
--- a/tests/language/dangling_else_test.dart
+++ b/tests/language/dangling_else_test.dart
@@ -1,8 +1,8 @@
 // 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.
-// Tests dangling else. The VM should not have any problems, but dart2js or
-// dart2dart could get this wrong.
+// Tests dangling else. The VM should not have any problems, but dart2js could
+// get this wrong.
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/disassemble_test.dart b/tests/language/disassemble_test.dart
index 8e53224..bdee5fff 100644
--- a/tests/language/disassemble_test.dart
+++ b/tests/language/disassemble_test.dart
@@ -4,6 +4,7 @@
 // Dart test program for testing isolate communication with
 // typed objects.
 // VMOptions=--disassemble
+// VMOptions=--disassemble --print-variable-descriptors --no-background-compilation
 
 // Tests proper object recognition in disassembler.
 
diff --git a/tests/language/enum_duplicate_test.dart b/tests/language/enum_duplicate_test.dart
index 9222a6f..ad0665a 100644
--- a/tests/language/enum_duplicate_test.dart
+++ b/tests/language/enum_duplicate_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 // Test for duplicate enums.
 
 library enum_duplicate_test;
diff --git a/tests/language/enum_index_test.dart b/tests/language/enum_index_test.dart
index 21a8e0e..5f922b3 100644
--- a/tests/language/enum_index_test.dart
+++ b/tests/language/enum_index_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 // Test index access for enums.
 
 library enum_index_test;
diff --git a/tests/language/enum_mirror_test.dart b/tests/language/enum_mirror_test.dart
index e85f121..00de84b 100644
--- a/tests/language/enum_mirror_test.dart
+++ b/tests/language/enum_mirror_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 import 'dart:mirrors';
 
 import 'package:expect/expect.dart';
diff --git a/tests/language/enum_private_test.dart b/tests/language/enum_private_test.dart
index e55b0c2..bf99f4f 100644
--- a/tests/language/enum_private_test.dart
+++ b/tests/language/enum_private_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 // Test privacy issue for enums.
 
 library enum_private_test;
diff --git a/tests/language/enum_syntax_test.dart b/tests/language/enum_syntax_test.dart
index 2ceef46..6d76db1 100644
--- a/tests/language/enum_syntax_test.dart
+++ b/tests/language/enum_syntax_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 // Basic syntax test for enumeration types
 
 import 'package:expect/expect.dart';
diff --git a/tests/language/enum_test.dart b/tests/language/enum_test.dart
index 0e41965..a3b4586 100644
--- a/tests/language/enum_test.dart
+++ b/tests/language/enum_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// SharedOptions=--enable-enum
-
 import 'package:expect/expect.dart';
 
 enum Enum1 { _ }
@@ -112,4 +110,4 @@
       break;
   }
   Expect.equals(e.index, index);
-}
\ No newline at end of file
+}
diff --git a/tests/language/factory5_test.dart b/tests/language/factory5_test.dart
index ff2013b..6155625 100644
--- a/tests/language/factory5_test.dart
+++ b/tests/language/factory5_test.dart
@@ -6,9 +6,8 @@
   factory Link.create() = LinkFactory<T>.create;
 }
 
-class LinkFactory<T> {
+class LinkFactory<T> implements Link<T> {
   factory LinkFactory.create() { return null; }
-  factory LinkFactory.Foo() = Foo<T>;  /// 00: static type warning
 }
 
 main() {
diff --git a/tests/language/factory6_test.dart b/tests/language/factory6_test.dart
new file mode 100644
index 0000000..0f998ff
--- /dev/null
+++ b/tests/language/factory6_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+abstract class Link<T> {
+  factory Link.Foo() = LinkFactory<T>.Foo;  /// 00: static type warning
+}
+
+class LinkFactory<T> {
+  factory LinkFactory.Foo() = Foo<T>;  /// 00: continued
+}
+
+main() {
+  Expect.throws(() => new Link<int>.Foo()); /// 00: continued
+}
diff --git a/tests/language/final_initializer_instance_reference_test.dart b/tests/language/final_initializer_instance_reference_test.dart
new file mode 100644
index 0000000..65580e7
--- /dev/null
+++ b/tests/language/final_initializer_instance_reference_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart2js regression test. Error in initializer might be report with the wrong
+// current element.
+
+class C {
+  const C();
+
+  final x = 1;
+  final y = x; /// 01: compile-time error
+}
+
+main() {
+  const C().y; /// 01: continued
+}
diff --git a/tests/language/function_field_test.dart b/tests/language/function_field_test.dart
index 7b0966e..f34b760 100644
--- a/tests/language/function_field_test.dart
+++ b/tests/language/function_field_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--fatal-type-errors --enable_type_checks
+// VMOptions=--enable_type_checks
 //
 // Test of calling Function, which is field of some class.
 
diff --git a/tests/language/generic_local_functions_test.dart b/tests/language/generic_local_functions_test.dart
index 1ec1227..47496a6 100644
--- a/tests/language/generic_local_functions_test.dart
+++ b/tests/language/generic_local_functions_test.dart
@@ -12,13 +12,13 @@
 import "package:expect/expect.dart";
 
 // Declare a generic function parameter.
-String f(int g<X, Y>(Map<X, Y> arg)) => null;
+int f(Y g<X, Y>(Map<X, Y> arg, X x)) => g<int, int>(<int, int>{1: 42}, 1);
 
 main() {
   // Declare a generic local function
-  int h<X extends Y, Y>(Map<X, Y> arg) => null;
+  Y h<X, Y>(Map<X, Y> m, X x) => m[x];
   // Pass a generic local function as an argument.
-  f(h);
+  Expect.equals(f(h), 42);
   // Pass a function expression as an argument.
-  f(<X, Y super X>(Map<X, Y> arg) => 42);
+  Expect.equals(f(<X, Y>(Map<X, Y> m, X x) => m[x]), 42);
 }
diff --git a/tests/language/initializing_formal_access_test.dart b/tests/language/initializing_formal_access_test.dart
index 3d3ceed..71f445e 100644
--- a/tests/language/initializing_formal_access_test.dart
+++ b/tests/language/initializing_formal_access_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // DartOptions=--initializing-formal-access
+// VMOptions=--initializing-formal-access
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/initializing_formal_capture_test.dart b/tests/language/initializing_formal_capture_test.dart
index 7ad3f08..8257d4f 100644
--- a/tests/language/initializing_formal_capture_test.dart
+++ b/tests/language/initializing_formal_capture_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // DartOptions=--initializing-formal-access
+// VMOptions=--initializing-formal-access
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/initializing_formal_final_test.dart b/tests/language/initializing_formal_final_test.dart
index 0832ce0..3df4ba5 100644
--- a/tests/language/initializing_formal_final_test.dart
+++ b/tests/language/initializing_formal_final_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // DartOptions=--initializing-formal-access
+// VMOptions=--initializing-formal-access
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/initializing_formal_promotion_test.dart b/tests/language/initializing_formal_promotion_test.dart
index b0314e8..5f0a3b6 100644
--- a/tests/language/initializing_formal_promotion_test.dart
+++ b/tests/language/initializing_formal_promotion_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // DartOptions=--initializing-formal-access
+// VMOptions=--initializing-formal-access
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/initializing_formal_scope_test.dart b/tests/language/initializing_formal_scope_test.dart
index dd85fad..5544a8e 100644
--- a/tests/language/initializing_formal_scope_test.dart
+++ b/tests/language/initializing_formal_scope_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // DartOptions=--initializing-formal-access
+// VMOptions=--initializing-formal-access
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/initializing_formal_type_test.dart b/tests/language/initializing_formal_type_test.dart
index 352eecf..7544f9d 100644
--- a/tests/language/initializing_formal_type_test.dart
+++ b/tests/language/initializing_formal_type_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // DartOptions=--initializing-formal-access
+// VMOptions=--initializing-formal-access
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/language.status b/tests/language/language.status
index 03fd476..bd95b58 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,12 +5,6 @@
 # This directory contains tests that are intended to show the
 # current state of the language.
 
-# Trailing commas are so far supported by:
-# - The VM (vm, dartium, drt, precompiler+dart_precompiled)
-# Remaining targets still fail on arg_param_trailing_comma_test/none.
-[($compiler != none && $compiler != precompiler) || ($runtime != vm && $runtime != dartium && $runtime != drt && $runtime != dart_precompiled)]
-arg_param_trailing_comma_test/none: Fail # Issue 26644
-
 [ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) ]
 tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating
 
@@ -59,12 +53,6 @@
 generic_methods_function_type_test: CompiletimeError # Issue 25869
 generic_methods_type_expression_test: CompiletimeError # Issue 25869
 
-# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_access_test: CompiletimeError # Issue 26656
-initializing_formal_capture_test: CompiletimeError # Issue 26656
-initializing_formal_final_test: CompiletimeError # Issue 26656
-initializing_formal_type_test: CompiletimeError # Issue 26656
-
 [ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
 
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
@@ -105,6 +93,12 @@
 mirror_in_static_init_test: Fail # Issue 22071
 vm/debug_break_enabled_vm_test/*: Skip # Issue 14651.
 
+# These tests need the flag --initializing-formal-access to pass:
+initializing_formal_access_test: Skip
+initializing_formal_capture_test: Skip
+initializing_formal_final_test: Skip
+initializing_formal_type_test: Skip
+
 # Experimental feature: Syntactic support for generic methods.
 generic_methods_test: RuntimeError # Issue 25869
 generic_functions_test: RuntimeError # Issue 25869
@@ -114,12 +108,6 @@
 generic_methods_function_type_test: RuntimeError # Issue 25869
 generic_methods_type_expression_test: RuntimeError # Issue 25869
 
-# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_access_test: RuntimeError # Issue 26656
-initializing_formal_capture_test: RuntimeError # Issue 26656
-initializing_formal_final_test: RuntimeError # Issue 26656
-initializing_formal_type_test: RuntimeError # Issue 26656
-
 config_import_test: Skip  # Issue 26250
 
 [ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
@@ -158,6 +146,7 @@
 stacktrace_rethrow_error_test: Pass, RuntimeError
 stacktrace_rethrow_nonerror_test: Pass, RuntimeError
 stacktrace_test: Pass, RuntimeError
+regress_26948_test: Skip # Crashes, regis investigating
 
 [ $noopt || $compiler == precompiler || $mode == product ]
 # Imports dart:mirrors
@@ -197,6 +186,9 @@
 ct_const2_test: Skip # Incompatible flag: --compile_all
 hello_dart_test: Skip # Incompatible flag: --compile_all
 
+[ $runtime == dart_app ]
+number_identity_test: RuntimeError # Issue 26873
+
 [ $compiler == precompiler ]
 implicit_closure_test: Skip # Incompatible flag: --use_slow_path
 deopt_inlined_function_lazy_test: Skip # Incompatible flag: --deoptimize-alot
@@ -240,9 +232,6 @@
 library_env_test/has_mirror_support: RuntimeError, OK
 
 [ $arch == simdbc || $arch == simdbc64 ]
-# TODO(vegorov) StopInstr is unimplemented.
-vm/debug_break_enabled_vm_test/none: Skip
-
 # TODO(vegorov) Encoding limitation: StoreField bytecode only supports 256
 # fields in an object.
 large_class_declaration_test: Skip
@@ -251,7 +240,37 @@
 vm/optimized_guarded_field_isolates_test: Skip # Issue #26373
 issue23244_test: Skip # Issue #26373
 
-[ $hot_reload ]
-deferred_load_inval_code_test: RuntimeError
-regress_26453_test: Pass, Fail, Crash
-vm/regress_16873_test: Pass, Crash
+[ $hot_reload || $hot_reload_rollback ]
+static_closure_identical_test: Pass, Fail # Closure identity
+cha_deopt1_test: Crash # Requires deferred libraries
+cha_deopt2_test: Crash # Requires deferred libraries
+cha_deopt3_test: Crash # Requires deferred libraries
+deferred_call_empty_before_load_test: Crash # Requires deferred libraries
+deferred_closurize_load_library_test: Crash # Requires deferred libraries
+deferred_constant_list_test: Crash # Requires deferred libraries
+deferred_constraints_constants_test: Crash # Requires deferred libraries
+deferred_constraints_type_annotation_test: Crash # Requires deferred libraries
+deferred_function_type_test: Crash # Requires deferred libraries
+deferred_global_test: Crash # Requires deferred libraries
+deferred_import_core_test: Crash # Requires deferred libraries
+deferred_inlined_test: Crash # Requires deferred libraries
+deferred_inheritance_constraints_test: Crash # Requires deferred libraries
+deferred_load_constants_test: Crash # Requires deferred libraries
+deferred_load_inval_code_test: Crash # Requires deferred libraries
+deferred_load_library_wrong_args_test: Crash # Requires deferred libraries
+deferred_mixin_test: Crash # Requires deferred libraries
+deferred_no_such_method_test: Crash # Requires deferred libraries
+deferred_not_loaded_check_test: Crash # Requires deferred libraries
+deferred_only_constant_test: Crash # Requires deferred libraries
+deferred_optimized_test: Crash # Requires deferred libraries
+deferred_redirecting_factory_test: Crash # Requires deferred libraries
+deferred_regression_22995_test: Crash # Requires deferred libraries
+deferred_shadow_load_library_test: Crash # Requires deferred libraries
+deferred_shared_and_unshared_classes_test: Crash # Requires deferred libraries
+deferred_static_seperate_test: Crash # Requires deferred libraries
+deferred_super_dependency_test: Pass, Crash # Requires deferred libraries
+deferred_type_dependency_test: Crash # Requires deferred libraries
+issue_1751477_test: Crash # Requires deferred libraries
+regress_23408_test: Crash # Requires deferred libraries
+regress_22443_test: Crash # Requires deferred libraries
+tearoff_basic_test: Crash # Requires deferred libraries
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 63ac9b5..492e396 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -85,9 +85,6 @@
 # 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
@@ -126,9 +123,6 @@
 # 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
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index aec3d55..8001ee7 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -5,6 +5,7 @@
 [ $compiler == dart2js ]
 getter_setter_in_lib_test: Fail # Issue 23288
 method_name_test: Fail # issue 25574
+setter4_test: CompileTimeError # issue 13639
 
 async_star_cancel_while_paused_test: RuntimeError # Issue 22853
 tearoff_basic_test: Skip # Tear-off not supported
@@ -102,8 +103,7 @@
 ref_before_declaration_test/05: MissingCompileTimeError
 ref_before_declaration_test/06: MissingCompileTimeError
 
-regress_22976_test/01: CompileTimeError # Issue 23132
-regress_22976_test/02: CompileTimeError # Issue 23132
+regress_22976_test: CompileTimeError # Issue 23132
 
 if_null_assignment_behavior_test/13: Crash # Issue 23491
 if_null_assignment_behavior_test/14: Crash # Issue 23491
@@ -243,14 +243,6 @@
 stack_trace_test: Fail, OK # Stack trace not preserved in minified code.
 regress_21795_test: RuntimeError # Issue 12605
 
-[ $compiler == dart2js && $runtime == d8 && $system == windows ]
-# Detection of d8 runtime does not work on Windows so the runtime result is
-# unreliable; at the time of writing, 32 passed, 31 failed with runtime error.
-# Marked with Pass,RuntimeError to avoid undetected compile-time failures.
-*deferred*: Pass,RuntimeError # Issue 17458
-cha_deopt*: Pass,RuntimeError # Issue 17458
-regress_22443_test: Pass,RuntimeError # Issue 17458
-
 [ $compiler == dart2js && $cps_ir == false ]
 accessor_conflict_export2_test: Crash # Issue 25626
 accessor_conflict_export_test: Crash # Issue 25626
@@ -337,3 +329,9 @@
 
 [ $compiler == dart2js && $cps_ir && $checked ]
 *: Skip # `assert` not implemented
+
+[ $compiler == dart2js && $host_checked ]
+regress_26855_test/1: Crash # Issue 26867
+regress_26855_test/2: Crash # Issue 26867
+regress_26855_test/3: Crash # Issue 26867
+regress_26855_test/4: Crash # Issue 26867
diff --git a/tests/language/regress_22976_test.dart b/tests/language/regress_22976_test.dart
index 67d6957..ea29319 100644
--- a/tests/language/regress_22976_test.dart
+++ b/tests/language/regress_22976_test.dart
@@ -9,6 +9,8 @@
 class C<S, T> implements B<S>, A<T> {}
 
 main() {
-  A<int> a0 = new C<int, String>(); /// 01: ok
-  A<int> a1 = new C<String, int>(); /// 02: ok
+  C<int, String> c1 = new C<int, String>();
+  C<String, int> c2 = new C<String, int>();
+  A<int> a0 = c1; /// 01: ok
+  A<int> a1 = c2; /// 02: ok
 }
diff --git a/tests/language/regress_26855_test.dart b/tests/language/regress_26855_test.dart
new file mode 100644
index 0000000..3d6c963
--- /dev/null
+++ b/tests/language/regress_26855_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void f0(this.x) {}  /// 0: compile-time error
+
+void f1(int g(this.x)) {}  /// 1: compile-time error
+
+void f2(int g(int this.x)) {}  /// 2: compile-time error
+
+class C {
+  C();
+  var x;
+  void f3(int g(this.x)) {}  /// 3: compile-time error
+  C.f4(int g(this.x));  /// 4: compile-time error
+}
+
+main() {
+  f0(null);  /// 0: continued
+  f1(null);  /// 1: continued
+  f2(null);  /// 2: continued
+  C c = new C();
+  c.f3(null);  /// 3: continued
+  new C.f4(null);  /// 4: continued
+}
+
diff --git a/tests/language/setter4_test.dart b/tests/language/setter4_test.dart
index 8428a7a..0fea7fe 100644
--- a/tests/language/setter4_test.dart
+++ b/tests/language/setter4_test.dart
@@ -4,14 +4,23 @@
 // Dart test to catch error reporting bugs in class fields declarations.
 // Should be an error because we have a setter overriding a function name.
 
+import 'package:expect/expect.dart';
+
 class A {
+  int i;
   int a() {
     return 1;
   }
   void set a(var val) {
-    int i = val;
+    i = val;
   }
 }
 
 main() {
+  var a = new A();
+  Expect.isNull(a.i);
+  Expect.equals(a.a(), 1);
+  a.a = 2;
+  Expect.equals(a.a(), 1);
+  Expect.equals(a.i, 2);
 }
diff --git a/tests/language/string_interpolation1_negative_test.dart b/tests/language/string_interpolation1_negative_test.dart
deleted file mode 100644
index 15ccfe4..0000000
--- a/tests/language/string_interpolation1_negative_test.dart
+++ /dev/null
@@ -1,21 +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.
-
-// A dollar must be followed by a "{" or an identifier.
-
-class A {
-  final String str;
-  const A(this.str);
-}
-
-class StringInterpolation1NegativeTest {
-  // Dollar not followed by "{" or identifier.
-  static const DOLLAR = const A("$");
-  testMain() {
-  }
-}
-
-main() {
-  StringInterpolation1NegativeTest.testMain();
-}
diff --git a/tests/language/string_interpolation1_test.dart b/tests/language/string_interpolation1_test.dart
new file mode 100644
index 0000000..4555dd0
--- /dev/null
+++ b/tests/language/string_interpolation1_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A dollar must be followed by a "{" or an identifier.
+
+class A {
+  final String str;
+  const A(this.str);
+}
+
+class StringInterpolation1NegativeTest {
+  // Dollar not followed by "{" or identifier.
+  static const DOLLAR = const A("$"); /// 01: compile-time error
+  static testMain() {
+    print(DOLLAR); /// 01: continued
+  }
+}
+
+main() {
+  StringInterpolation1NegativeTest.testMain();
+}
diff --git a/tests/language/string_interpolation2_negative_test.dart b/tests/language/string_interpolation2_negative_test.dart
deleted file mode 100644
index ca5e269..0000000
--- a/tests/language/string_interpolation2_negative_test.dart
+++ /dev/null
@@ -1,15 +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.
-
-// A dollar must be followed by a "{" or an identifier.
-
-class StringInterpolation2NegativeTest {
-  testMain() {
-    print('C;Y1;X4;K"$/Month"');  // Dollar followed by "/".
-  }
-}
-
-main() {
-  StringInterpolation2NegativeTest.testMain();
-}
diff --git a/tests/language/string_interpolation2_test.dart b/tests/language/string_interpolation2_test.dart
new file mode 100644
index 0000000..55aa734
--- /dev/null
+++ b/tests/language/string_interpolation2_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A dollar must be followed by a "{" or an identifier.
+
+class StringInterpolation2NegativeTest {
+  static testMain() {
+    // Dollar followed by "/".
+    print('C;Y1;X4;K"$/Month"'); /// 01: compile-time error
+  }
+}
+
+main() {
+  StringInterpolation2NegativeTest.testMain();
+}
diff --git a/tests/language/string_interpolation3_negative_test.dart b/tests/language/string_interpolation3_negative_test.dart
deleted file mode 100644
index 14e2525..0000000
--- a/tests/language/string_interpolation3_negative_test.dart
+++ /dev/null
@@ -1,15 +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.
-
-// A dollar must be followed by a "{" or an identifier.
-
-class StringInterpolation3NegativeTest {
-  static testMain() {
-    print('F;P4;F$2R');  // Dollar followed by a number.
-  }
-}
-
-main() {
-  StringInterpolation3NegativeTest.testMain();
-}
diff --git a/tests/language/string_interpolation3_test.dart b/tests/language/string_interpolation3_test.dart
new file mode 100644
index 0000000..4ccf8d5
--- /dev/null
+++ b/tests/language/string_interpolation3_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A dollar must be followed by a "{" or an identifier.
+
+class StringInterpolation3NegativeTest {
+  static testMain() {
+    // Dollar followed by a number.
+    print('F;P4;F$2R'); /// 01: compile-time error
+  }
+}
+
+main() {
+  StringInterpolation3NegativeTest.testMain();
+}
diff --git a/tests/language/string_interpolation4_negative_test.dart b/tests/language/string_interpolation4_negative_test.dart
deleted file mode 100644
index bc7db6f..0000000
--- a/tests/language/string_interpolation4_negative_test.dart
+++ /dev/null
@@ -1,16 +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.
-
-// A dollar must be followed by a "{" or an identifier.
-
-class StringInterpolation4NegativeTest {
-  testMain() {
-    // Dollar not followed by "{" or identifier.
-    print("-" + "$" + "foo");
-  }
-}
-
-main() {
-  StringInterpolation4NegativeTest.testMain();
-}
diff --git a/tests/language/string_interpolation4_test.dart b/tests/language/string_interpolation4_test.dart
new file mode 100644
index 0000000..ab26160
--- /dev/null
+++ b/tests/language/string_interpolation4_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A dollar must be followed by a "{" or an identifier.
+
+class StringInterpolation4NegativeTest {
+  static testMain() {
+    // Dollar not followed by "{" or identifier.
+    print("-" + "$" + "foo"); /// 01: compile-time error
+  }
+}
+
+main() {
+  StringInterpolation4NegativeTest.testMain();
+}
diff --git a/tests/language/string_interpolation5_negative_test.dart b/tests/language/string_interpolation5_negative_test.dart
deleted file mode 100644
index 9d6197d..0000000
--- a/tests/language/string_interpolation5_negative_test.dart
+++ /dev/null
@@ -1,15 +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.
-
-// A dollar must be followed by a "{" or an identifier.
-
-class StringInterpolation5NegativeTest {
-  testMain() {
-    print("$1,000");  // Dollar followed by a number.
-  }
-}
-
-main() {
-  StringInterpolation5NegativeTest.testMain();
-}
diff --git a/tests/language/string_interpolation5_test.dart b/tests/language/string_interpolation5_test.dart
new file mode 100644
index 0000000..13cf3d3
--- /dev/null
+++ b/tests/language/string_interpolation5_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A dollar must be followed by a "{" or an identifier.
+
+class StringInterpolation5NegativeTest {
+  static testMain() {
+    // Dollar followed by a number.
+    print("$1,000"); /// 01: compile-time error
+  }
+}
+
+main() {
+  StringInterpolation5NegativeTest.testMain();
+}
diff --git a/tests/language/string_interpolation6_negative_test.dart b/tests/language/string_interpolation6_negative_test.dart
deleted file mode 100644
index e90545f..0000000
--- a/tests/language/string_interpolation6_negative_test.dart
+++ /dev/null
@@ -1,17 +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.
-
-// A dollar must be followed by a "{" or an identifier.
-
-class StringInterpolation6NegativeTest {
-  testMain() {
-    // Dollar not followed by "{" or identifier.
-    String regexp = "^(\\d\\d?)[-/](\\d\\d?)$";
-    print(regexp);
-  }
-}
-
-main() {
-  StringInterpolation6NegativeTest.testMain();
-}
diff --git a/tests/language/string_interpolation6_test.dart b/tests/language/string_interpolation6_test.dart
new file mode 100644
index 0000000..155f9fb
--- /dev/null
+++ b/tests/language/string_interpolation6_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A dollar must be followed by a "{" or an identifier.
+
+class StringInterpolation6NegativeTest {
+  static testMain() {
+    // Dollar not followed by "{" or identifier.
+    String regexp;
+    regexp = "^(\\d\\d?)[-/](\\d\\d?)$"; /// 01: compile-time error
+    print(regexp);
+  }
+}
+
+main() {
+  StringInterpolation6NegativeTest.testMain();
+}
diff --git a/tests/language/syntax_test.dart b/tests/language/syntax_test.dart
index 11aee70..7f7b21b 100644
--- a/tests/language/syntax_test.dart
+++ b/tests/language/syntax_test.dart
@@ -238,6 +238,7 @@
     new SyntaxTest() = 1; /// 64: compile-time error
     futureOf(null) = 1; /// 65: compile-time error
 
+    new C();
   } catch (ex) {
     // Swallowing exceptions. Any error should be a compile-time error
     // which kills the current isolate.
@@ -247,3 +248,9 @@
 class Bad {
   factory Bad<Bad(String type) { return null; } /// 63: compile-time error
 }
+
+class C {
+  void f;  /// 66: compile-time error
+  static void g;  /// 67: compile-time error
+}
+
diff --git a/tests/language/typecheck_multifield_declaration_test.dart b/tests/language/typecheck_multifield_declaration_test.dart
new file mode 100644
index 0000000..bbd0cba
--- /dev/null
+++ b/tests/language/typecheck_multifield_declaration_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Checks that we can correctly typecheck multi-variable declarations on fields 
+/// and top-levels. This is also a regression test for Issue 27401.
+
+class A {}
+
+A a = new A(), b = new A();
+
+class B {
+  A a = new A(), b = new A();  
+}
+
+main() => [a, b, new B().a, new B().b];
\ No newline at end of file
diff --git a/tests/language/vm/regress_16873_test.dart b/tests/language/vm/regress_16873_test.dart
index 4080f5c..06a0348 100644
--- a/tests/language/vm/regress_16873_test.dart
+++ b/tests/language/vm/regress_16873_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--new_gen_heap_size=1 --no_inline_alloc
+// VMOptions=--new_gen_semi_max_size=1 --no_inline_alloc
 
 // Regression test for slow-path allocation in the allocation stub.
 
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index b86abdc..98b521c 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -9,6 +9,7 @@
 lib/html/html_common/html_common_dart2js: CompileTimeError # Issue 16522
 lib/indexed_db/dart2js/indexed_db_dart2js: CompileTimeError # Issue 16522
 lib/js/dart2js/js_dart2js: CompileTimeError # Issue 16522
+lib/js_util/dart2js/js_util_dart2js: CompileTimeError # Issue 16522
 lib/svg/dart2js/svg_dart2js: CompileTimeError # Issue 16522
 lib/typed_data/dart2js/native_typed_data_dart2js: CompileTimeError # Issue 16522
 lib/typed_data/dart2js/typed_data_dart2js: CompileTimeError # Issue 16522
@@ -25,4 +26,5 @@
 lib/web_audio/dartium/web_audio_dartium: StaticWarning # Issue 21647
 lib/svg/dartium/svg_dartium: StaticWarning # Issue 21647
 lib/_blink/dartium/_blink_dartium: StaticWarning # Undefined Creates and Returns classes
-lib/js/dartium/js_dartium: StaticWarning # Undefined Creates and Returns classes
\ No newline at end of file
+lib/js/dartium/js_dartium: StaticWarning # Undefined Creates and Returns classes
+lib/js_util/dartium/js_util_dartium: StaticWarning # Issue 21647
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 8d3dcee..b280b4f 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -374,7 +374,23 @@
 # version.
 mirrors/accessor_cache_overflow_test: Skip
 
+[ $hot_reload || $hot_reload_rollback ]
+async/multiple_timer_test: Pass, Fail # Timing related
+async/stream_transformer_test: Pass, Fail # Closure identity
+mirrors/closurization_equivalence_test: SkipByDesign # Method equality
+mirrors/fake_function_with_call_test: SkipByDesign # Method equality
+
+mirrors/library_enumeration_deferred_loading_test: Crash # Deferred loading
+mirrors/library_imports_deferred_test: Crash # Deferred loading
+mirrors/library_import_deferred_loading_test: Crash # Deferred loading
+mirrors/typedef_deferred_library_test: Crash # Deferred loading
+mirrors/deferred_mirrors_update_test: Crash # Deferred loading
+mirrors/deferred_mirrors_metadata_test: Crash # Deferred loading
+mirrors/deferred_mirrors_metatarget_test: Crash # Deferred loading
+mirrors/load_library_test: Crash # Deferred loading
+
 [ $hot_reload ]
-convert/chunked_conversion_utf88_test: Pass, Timeout
-convert/streamed_conversion_json_utf8_decode_test: Fail, Crash
-convert/utf85_test: Fail, Crash
+mirrors/metadata_scope_test/none: Fail # Constant equality - Issue 26868
+mirrors/generic_bounded_test/02: Fail # Type equality - Issue 26869
+mirrors/typedef_reflected_type_test/01: Fail # Type equality - Issue 26869
+mirrors/generic_bounded_by_type_parameter_test/02: Fail # Type equality - Issue 26869
diff --git a/tests/lib/math/double_pow_test.dart b/tests/lib/math/double_pow_test.dart
index 83a8ece..f1071c4 100644
--- a/tests/lib/math/double_pow_test.dart
+++ b/tests/lib/math/double_pow_test.dart
@@ -117,6 +117,13 @@
     }
     // if `x` is -Infinity or -0.0 and `y` is not an odd integer, then the
     // result is the same as `pow(-x , y)`.
+    if (d.isNaN) {
+      Expect.isTrue(pow(Infinity, d).isNaN);
+      Expect.isTrue(pow(-Infinity, d).isNaN);
+      Expect.isTrue(pow(0.0, d).isNaN);
+      Expect.isTrue(pow(-0.0, d).isNaN);
+      continue;
+    }
     Expect.identical(pow(Infinity, d), pow(-Infinity, d));
     Expect.identical(pow(0.0, d), pow(-0.0, d));
   }
@@ -136,7 +143,12 @@
       Expect.identical(1.0, pow(d, Infinity));
     }
     // if `y` is -Infinity, the result is `1/pow(x, Infinity)`.
-    Expect.identical(1/pow(d, Infinity), pow(d, -Infinity));
+    if (d.isNaN) {
+      Expect.isTrue((1/pow(d, Infinity)).isNaN);
+      Expect.isTrue(pow(d, -Infinity).isNaN);
+    } else {
+      Expect.identical(1/pow(d, Infinity), pow(d, -Infinity));
+    }
   }
 
   // Some non-exceptional values.
@@ -159,4 +171,4 @@
 
 main() {
   for (int i = 0; i < 10; i++) test();
-}
\ No newline at end of file
+}
diff --git a/tests/lib/typed_data/float32x4_list_test.dart b/tests/lib/typed_data/float32x4_list_test.dart
index 901f712..d294763 100644
--- a/tests/lib/typed_data/float32x4_list_test.dart
+++ b/tests/lib/typed_data/float32x4_list_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background_compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background_compilation
 
 // Library tag to be able to run in html test framework.
 library float32x4_list_test;
diff --git a/tests/lib/typed_data/float32x4_test.dart b/tests/lib/typed_data/float32x4_test.dart
index 0e5eeb2..a048cc9 100644
--- a/tests/lib/typed_data/float32x4_test.dart
+++ b/tests/lib/typed_data/float32x4_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library float32x4_test;
diff --git a/tests/lib/typed_data/float32x4_unbox_phi_test.dart b/tests/lib/typed_data/float32x4_unbox_phi_test.dart
index c44ae5e..d96b2cf 100644
--- a/tests/lib/typed_data/float32x4_unbox_phi_test.dart
+++ b/tests/lib/typed_data/float32x4_unbox_phi_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library float32x4_unbox_regress_test;
diff --git a/tests/lib/typed_data/float32x4_unbox_regress_test.dart b/tests/lib/typed_data/float32x4_unbox_regress_test.dart
index abb00d6..230141a 100644
--- a/tests/lib/typed_data/float32x4_unbox_regress_test.dart
+++ b/tests/lib/typed_data/float32x4_unbox_regress_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library float32x4_unbox_regress_test;
diff --git a/tests/lib/typed_data/float64x2_functional_test.dart b/tests/lib/typed_data/float64x2_functional_test.dart
index 67359e1..c9d81ce 100644
--- a/tests/lib/typed_data/float64x2_functional_test.dart
+++ b/tests/lib/typed_data/float64x2_functional_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 library float64x2_functional_test;
 
diff --git a/tests/lib/typed_data/float64x2_typed_list_test.dart b/tests/lib/typed_data/float64x2_typed_list_test.dart
index 95db6c6..7c43da8 100644
--- a/tests/lib/typed_data/float64x2_typed_list_test.dart
+++ b/tests/lib/typed_data/float64x2_typed_list_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 library float64x2_typed_list_test;
 
diff --git a/tests/lib/typed_data/int32x4_arithmetic_test.dart b/tests/lib/typed_data/int32x4_arithmetic_test.dart
index f558840..0b118da 100644
--- a/tests/lib/typed_data/int32x4_arithmetic_test.dart
+++ b/tests/lib/typed_data/int32x4_arithmetic_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library uint32x4_arithmetic_test;
diff --git a/tests/lib/typed_data/int32x4_bigint_test.dart b/tests/lib/typed_data/int32x4_bigint_test.dart
index 282a7fb..c0daba9 100644
--- a/tests/lib/typed_data/int32x4_bigint_test.dart
+++ b/tests/lib/typed_data/int32x4_bigint_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library int32x4_bigint_test;
diff --git a/tests/lib/typed_data/int32x4_list_test.dart b/tests/lib/typed_data/int32x4_list_test.dart
index 70480bd..1b03ce6 100644
--- a/tests/lib/typed_data/int32x4_list_test.dart
+++ b/tests/lib/typed_data/int32x4_list_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library int32x4_list_test;
diff --git a/tests/lib/typed_data/int32x4_test.dart b/tests/lib/typed_data/int32x4_test.dart
index 06fd62b..a15a5fb 100644
--- a/tests/lib/typed_data/int32x4_test.dart
+++ b/tests/lib/typed_data/int32x4_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 library int32x4_test;
 
diff --git a/tests/lib/typed_data/simd_store_to_load_forward_test.dart b/tests/lib/typed_data/simd_store_to_load_forward_test.dart
index d7757b7..6fd4c35 100644
--- a/tests/lib/typed_data/simd_store_to_load_forward_test.dart
+++ b/tests/lib/typed_data/simd_store_to_load_forward_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library simd_store_to_load_forward_test;
diff --git a/tests/lib/typed_data/simd_type_check_removal.dart b/tests/lib/typed_data/simd_type_check_removal.dart
index bffb456..eeb6792 100644
--- a/tests/lib/typed_data/simd_type_check_removal.dart
+++ b/tests/lib/typed_data/simd_type_check_removal.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
+// VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation
 
 // Library tag to be able to run in html test framework.
 library simd_store_to_load_forward_test;
diff --git a/tests/standalone/fixed_precision_double_test.dart b/tests/standalone/fixed_precision_double_test.dart
new file mode 100644
index 0000000..350bbc3
--- /dev/null
+++ b/tests/standalone/fixed_precision_double_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+bool testAssociativity(Function f) {
+  // Example from https://en.wikipedia.org/wiki/Floating_point
+  // Test that (a + b) + c == a + (b + c).
+  double a = f(1234.567);  // Chop literals.
+  double b = f(45.67834);
+  double c = f(0.0004);
+  double x = (a + b) + c;  // Chop result of multiplication or division only.
+  double y = a + (b + c);
+  print("x: $x");
+  print("y: $y");
+  return x == y;
+}
+
+bool testDistributivity(Function f) {
+  // Example from https://en.wikipedia.org/wiki/Floating_point
+  // Test that (a + b)*c == a*c + b*c.
+  double a = f(1234.567);  // Chop literals.
+  double b = f(1.234567);
+  double c = f(3.333333);
+  double x = f((a + b)*c);  // Chop result of multiplication.
+  double y = f(a*c) + f(b*c);
+  print("x: $x");
+  print("y: $y");
+  return x == y;
+}
+
+// Simulate precision checking with assert.
+assertP(double d) {
+  assert(d == d.p);
+}
+
+bool assertionsEnabled() {
+  try {
+    assert(false);
+    return false;
+  } on AssertionError catch (e) {
+    return true;
+  }
+  return false;
+}
+
+main() {
+  // The getter p keeps only 20 (by default) bits after the decimal point.
+  Expect.equals(0.0, 0.0.p);  // 0.0 has no 1-bit after the decimal point.
+  Expect.equals(1.5, 1.5.p);  // 1.5 has a single 1-bit after the decimal point.
+  Expect.notEquals(1.1, 1.1.p);  // 1.1 has many 1-bits after the decimal point.
+  Expect.notEquals(1/3, (1/3).p);  // 0.33333333... ditto.
+
+  Expect.equals(1.1 + 1/3, 1/3 + 1.1);  // Test addition commutativity.
+  Expect.equals(1.1.p + (1/3).p, (1/3).p + 1.1.p);
+  Expect.equals(1.1 * 1/3, 1/3 * 1.1);  // Test multiplication commutativity.
+  Expect.equals(1.1.p * (1/3).p, (1/3).p * 1.1.p);
+
+  print("Without chopping fractional bits:");
+  Expect.isFalse(testAssociativity((x) => x));
+  Expect.isFalse(testDistributivity((x) => x));
+  print("With chopping fractional bits:");
+  Expect.isTrue(testAssociativity((x) => x.p));
+  Expect.isTrue(testDistributivity((x) => x.p));
+
+  // Check that p works with NaN and Infinity.
+  Expect.isTrue(double.NAN.p.isNaN);
+  Expect.isTrue(double.INFINITY.p.isInfinite);
+  Expect.isFalse(double.INFINITY.p.isNegative);
+  Expect.isTrue(double.NEGATIVE_INFINITY.p.isInfinite);
+  Expect.isTrue(double.NEGATIVE_INFINITY.p.isNegative);
+
+  // Check use of assert to verify precision.
+  if (assertionsEnabled()) {
+    assertP(1.5);
+    assertP(1.1.p);
+    Expect.throws(() => assertP(1.1), (e) => e is AssertionError);
+    assertP(1.23456789.p);
+    Expect.throws(() => assertP(1.23456789), (e) => e is AssertionError);
+  }
+}
diff --git a/tests/standalone/io/http_basic_test.dart b/tests/standalone/io/http_basic_test.dart
index f30a32b..266dd8f 100644
--- a/tests/standalone/io/http_basic_test.dart
+++ b/tests/standalone/io/http_basic_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.
 //
-// VMOptions=
-// VMOptions=--short_socket_read
-// VMOptions=--short_socket_write
-// VMOptions=--short_socket_read --short_socket_write
+// VMOptions=--trace_shutdown
+// VMOptions=--trace_shutdown --short_socket_read
+// VMOptions=--trace_shutdown --short_socket_write
+// VMOptions=--trace_shutdown --short_socket_read --short_socket_write
 
 import "package:expect/expect.dart";
 import "dart:isolate";
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 1c84cd5..26edb5f 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -380,6 +380,11 @@
       "  text/html  ;  charset  =  utf-8  ;  xxx=yyy  ");
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
 
+  contentType = ContentType.parse("text/html; charset=;");
+  check(contentType, "text", "html", {"charset": null});
+  contentType = ContentType.parse("text/html; charset;");
+  check(contentType, "text", "html", {"charset": null});
+
   // Test builtin content types.
   check(ContentType.TEXT, "text", "plain", {"charset": "utf-8"});
   check(ContentType.HTML, "text", "html", {"charset": "utf-8"});
@@ -387,6 +392,20 @@
   check(ContentType.BINARY, "application", "octet-stream");
 }
 
+void testKnownContentTypes() {
+  // Well known content types used by the VM service.
+  ContentType.parse('text/html; charset=UTF-8');
+  ContentType.parse('application/dart; charset=UTF-8');
+  ContentType.parse('application/javascript; charset=UTF-8');
+  ContentType.parse('text/css; charset=UTF-8');
+  ContentType.parse('image/gif');
+  ContentType.parse('image/png');
+  ContentType.parse('image/jpeg');
+  ContentType.parse('image/jpeg');
+  ContentType.parse('image/svg+xml');
+  ContentType.parse('text/plain');
+}
+
 void testContentTypeCache() {
   _HttpHeaders headers = new _HttpHeaders("1.1");
   headers.set(HttpHeaders.CONTENT_TYPE, "text/html");
@@ -570,6 +589,7 @@
   testEnumeration();
   testHeaderValue();
   testContentType();
+  testKnownContentTypes();
   testContentTypeCache();
   testCookie();
   testInvalidCookie();
diff --git a/tests/standalone/io/issue_26954_test.dart b/tests/standalone/io/issue_26954_test.dart
new file mode 100644
index 0000000..5e8738b
--- /dev/null
+++ b/tests/standalone/io/issue_26954_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+final List<int> _UTF8_PLS_CERTIFICATE = UTF8.encode('''
+-----BEGIN CERTIFICATE-----
+MIIDZDCCAkygAwIBAgIBATANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVpbnRl
+cm1lZGlhdGVhdXRob3JpdHkwHhcNMTUxMDI3MTAyNjM1WhcNMjUxMDI0MTAyNjM1
+WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCkg/Qr8RQeLTOSgCkyiEX2ztgkgscX8hKGHEHdvlkmVK3JVEIIwkvu
+/Y9LtHZUia3nPAgqEEbexzTENZjSCcC0V6I2XW/e5tIE3rO0KLZyhtZhN/2SfJ6p
+KbOh0HLr1VtkKJGp1tzUmHW/aZI32pK60ZJ/N917NLPCJpCaL8+wHo3+w3oNqln6
+oJsfgxy9SUM8Bsc9WMYKMUdqLO1QKs1A5YwqZuO7Mwj+4LY2QDixC7Ua7V9YAPo2
+1SBeLvMCHbYxSPCuxcZ/kDkgax/DF9u7aZnGhMImkwBka0OQFvpfjKtTIuoobTpe
+PAG7MQYXk4RjnjdyEX/9XAQzvNo1CDObAgMBAAGjgbQwgbEwPAYDVR0RBDUwM4IJ
+bG9jYWxob3N0ggkxMjcuMC4wLjGCAzo6MYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAA
+ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSvhJo6taTggJQBukEvMo/PDk8tKTAf
+BgNVHSMEGDAWgBS98L4T5RaIToE3DkBRsoeWPil0eDAOBgNVHQ8BAf8EBAMCA6gw
+EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAHLOt0mL2S4A
+B7vN7KsfQeGlVgZUVlEjem6kqBh4fIzl4CsQuOO8oJ0FlO1z5JAIo98hZinymJx1
+phBVpyGIKakT/etMH0op5evLe9dD36VA3IM/FEv5ibk35iGnPokiJXIAcdHd1zam
+YaTHRAnZET5S03+7BgRTKoRuszhbvuFz/vKXaIAnVNOF4Gf2NUJ/Ax7ssJtRkN+5
+UVxe8TZVxzgiRv1uF6NTr+J8PDepkHCbJ6zEQNudcFKAuC56DN1vUe06gRDrNbVq
+2JHEh4pRfMpdsPCrS5YHBjVq/XHtFHgwDR6g0WTwSUJvDeM4OPQY5f61FB0JbFza
+PkLkXmoIod8=
+-----END CERTIFICATE-----''');
+
+main() {
+  // create context for establishing socket later
+  final _context = SecurityContext.defaultContext;
+  _context.useCertificateChainBytes(_UTF8_PLS_CERTIFICATE);
+}
diff --git a/tests/standalone/io/raw_datagram_socket_test.dart b/tests/standalone/io/raw_datagram_socket_test.dart
index 20d841e..f3168fb 100644
--- a/tests/standalone/io/raw_datagram_socket_test.dart
+++ b/tests/standalone/io/raw_datagram_socket_test.dart
@@ -195,6 +195,25 @@
   }
 }
 
+testLoopbackMulticastError() {
+  var bindAddress = InternetAddress.ANY_IP_V4;
+  var multicastAddress = new InternetAddress("228.0.0.4");
+  asyncStart();
+  Future.wait([
+      RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false),
+      RawDatagramSocket.bind(bindAddress, 0, reuseAddress: false)])
+    .then((values) {
+      var sender = values[0];
+      var receiver = values[1];
+      Expect.throws(
+          () { sender.joinMulticast(new InternetAddress("127.0.0.1")); },
+          (e) => e is! TypeError);
+      sender.close();
+      receiver.close();
+      asyncEnd();
+    });
+}
+
 testSendReceive(InternetAddress bindAddress, int dataSize) {
   asyncStart();
 
@@ -320,6 +339,7 @@
   }
   testBroadcast();
   testLoopbackMulticast();
+  testLoopbackMulticastError();
   testSendReceive(InternetAddress.LOOPBACK_IP_V4, 1000);
   testSendReceive(InternetAddress.LOOPBACK_IP_V6, 1000);
   if (!Platform.isMacOS) {
diff --git a/tests/standalone/io/socket_source_address_test.dart b/tests/standalone/io/socket_source_address_test.dart
index 4b95433..64dc490 100644
--- a/tests/standalone/io/socket_source_address_test.dart
+++ b/tests/standalone/io/socket_source_address_test.dart
@@ -43,7 +43,8 @@
     await throws(() => connectFunction('127.0.0.1',
                                        server.port,
                                        sourceAddress: sourceAddress),
-                 (e) => e is SocketException);
+                 (e) => e is SocketException &&
+                     e.address == new InternetAddress('8.8.8.8'));
   }
   // Address family mismatch.
   for (sourceAddress in ['::1', InternetAddress.LOOPBACK_IP_V6]) {
diff --git a/tests/standalone/io/stdio_implicit_close_script.dart b/tests/standalone/io/stdio_implicit_close_script.dart
new file mode 100644
index 0000000..4be58a88
--- /dev/null
+++ b/tests/standalone/io/stdio_implicit_close_script.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:io";
+
+void main(List<String> arguments) {
+  // Access stdout and stderr so that the system grabs a handle to it. This
+  // initializes some internal structures.
+  if (stdout.hashCode == -1234 && stderr.hashCode == (stderr.hashCode + 1)) {
+    throw "we have other problems.";
+  }
+
+  if (arguments.contains("stdout")) {
+    stdout.close();
+  }
+  if (arguments.contains("stderr")) {
+    stderr.close();
+  }
+}
diff --git a/tests/standalone/io/stdio_implicit_close_test.dart b/tests/standalone/io/stdio_implicit_close_test.dart
new file mode 100644
index 0000000..dc67f0e
--- /dev/null
+++ b/tests/standalone/io/stdio_implicit_close_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "dart:convert";
+import "dart:io";
+
+void test({bool closeStdout, bool closeStderr}) {
+  var scriptFile = "stdio_implicit_close_script.dart";
+  var script = Platform.script.resolve(scriptFile).toFilePath();
+
+  // Relying on these flags to print something specific on stdout and stderr
+  // is brittle, but otherwise we would need to add our own flag.
+  var arguments = [
+      "--print-metrics",  // Prints on stderr.
+      "--timing",         // Prints on stdout.
+      script,
+  ];
+  if (closeStdout) arguments.add("stdout");
+  if (closeStderr) arguments.add("stderr");
+
+  asyncStart();
+  Process.run(Platform.executable,
+              arguments,
+              stdoutEncoding: ASCII,
+              stderrEncoding: ASCII).then((result) {
+                  print(result.stdout);
+                  print(result.stderr);
+    Expect.equals(0, result.exitCode);
+
+    if (closeStdout) {
+      Expect.equals("", result.stdout);
+    } else {
+      Expect.isTrue(result.stdout.contains("Timing for"));
+    }
+
+    if (closeStderr) {
+      Expect.equals("", result.stderr);
+    } else {
+      Expect.isTrue(result.stderr.contains("Printing metrics"));
+    }
+
+    asyncEnd();
+  });
+}
+
+void main() {
+  asyncStart();
+  test(closeStdout: false, closeStderr: false);
+  test(closeStdout: false, closeStderr: true);
+  test(closeStdout: true, closeStderr: false);
+  test(closeStdout: true, closeStderr: true);
+  asyncEnd();
+}
diff --git a/tests/standalone/no_support_coverage_test.dart b/tests/standalone/no_support_coverage_test.dart
deleted file mode 100644
index 7bbf602..0000000
--- a/tests/standalone/no_support_coverage_test.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions=--no-support_coverage
-
-main() {
-  print("Okay");
-}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index bcad73f..8163f89 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -78,6 +78,7 @@
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 issue14236_test: Skip # Analyzer can't handle Script snapshots.
+fixed_precision_double_test: Skip # double p getter only implemented in VM.
 
 # test issue https://code.google.com/p/dart/issues/detail?id=11518
 io/file_constructor_test: fail
@@ -114,6 +115,7 @@
 pair_location_remapping_test: Skip
 regress_25335_test: Skip # Int64List not supported.
 deferred_transitive_import_error_test: Skip # Contains intentional errors.
+fixed_precision_double_test: Skip # double p getter only implemented in VM.
 
 [ $compiler == dart2js && $cps_ir && $checked ]
 *: Skip # `assert` not implemented
@@ -252,6 +254,7 @@
 io/http_client_stays_alive_test: Skip # Platform.executable
 io/print_sync_test: Skip # Platform.executable
 io/signals_test: Skip # Platform.executable
+io/stdio_implicit_close_test: Skip # Platform.executable
 io/stdio_nonblocking_test: Skip # Platform.executable
 io/regress_7191_test: Skip # Platform.executable
 io/secure_unauthorized_test: Skip # Platform.executable
@@ -287,6 +290,7 @@
 no_support_il_printer_test: SkipByDesign
 no_support_service_test: SkipByDesign
 no_support_timeline_test: SkipByDesign
+io/stdio_implicit_close_test: Skip # SkipByDesign
 
 # Following tests are skipped on dart_app as package mapping is not supported.
 [ $runtime == dart_precompiled || $runtime == dart_app ]
@@ -319,13 +323,18 @@
 oom_error_stacktrace_test: Skip # Issue #26377
 out_of_memory_test: Skip # Issue #26377
 
-[ $runtime == dart_precompiled ]
+[ $runtime == vm || $runtime == dart_app || $runtime == dart_precompiled ]
 deferred_transitive_import_error_test: Skip # Contains intentional errors.
 
-[ $hot_reload ]
-io/bytes_builder_test: RuntimeError
-io/file_input_stream_test: Crash
-io/file_test: Pass, Crash
-io/web_socket_protocol_processor_test: Pass, Crash
-map_insert_remove_oom_test: Crash
-priority_queue_stress_test: Crash
+[ $hot_reload || $hot_reload_rollback ]
+deferred_transitive_import_error_test: Crash # Uses deferred imports.
+package/*: SkipByDesign # Launches VMs in interesting ways.
+
+[ $builder_tag == no_ipv6 ]
+io/http_bind_test: Skip
+io/raw_datagram_socket_test: Skip
+io/socket_source_address_test: Skip
+io/socket_bind_test: Skip
+io/http_proxy_advanced_test: Skip
+io/http_ipv6_test: Skip
+io/socket_ipv6_test: Skip
diff --git a/tests/try/firefox-linemerges.applescript b/tests/try/firefox-linemerges.applescript
deleted file mode 100644
index c62c9c6..0000000
--- a/tests/try/firefox-linemerges.applescript
+++ /dev/null
@@ -1,98 +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.
-
--- This: 'tell application "Firefox" to activate' doesn't seem to bring
--- application in focus if it's not already open.
-do shell script "open -a Firefox"
-
-delay 3.0
-
-tell application "System Events"
-	--- Open Incognito window to avoid effect of caching of pages.
-	keystroke "p" using {command down, shift down}
-	
-	delay 1.0
-	
-	keystroke "l" using command down
-	
-	keystroke "http://localhost:8080/"
-	-- Simulate Enter key.
-	key code 36
-	
-	delay 10.0
-	
-	-- Refresh the page to reload the scripts
-	keystroke "r" using command down
-	
-	keystroke "l" using command down
-	
-	delay 1.0
-	
-	-- Simulate Tab key to get to 'Pick an example' dropdown
-	repeat 8 times
-		key code 48
-	end repeat
-	
-	-- Simulate Down then Enter to select Hello, World
-	key code 125
-	key code 36
-	
-	delay 1.0
-	
-	keystroke "l" using command down
-	
-	delay 1.0
-	
-	-- Simulate Tab key to get to Code editor.
-	repeat 9 times
-		key code 48
-	end repeat
-	
-	-- Simulate sequence of Down keys to get to "print(greeting);" line
-	repeat 8 times
-		key code 125
-	end repeat
-	
-	-- Simulate Cmd-Right.
-	key code 124 using command down
-	
-	keystroke "print('c');"
-	
-	-- Simulate Left*11 to get to the beginning of "print('c');"
-	repeat 11 times
-		key code 123
-	end repeat
-	
-	-- Simulate Enter to split lines
-	key code 36
-	
-	-- Simulate Delete to join lines
-	key code 51
-	
-	-- Simulate Enter to split lines
-	key code 36
-	
-	-- Simulate Right*8 to get to right after the c in "print('c');"
-	repeat 8 times
-		key code 124
-	end repeat
-	
-	keystroke "d"
-	
-	delay 0.1
-	keystroke "a" using command down
-	delay 0.2
-	keystroke "c" using command down
-	
-	delay 1
-	set clipboardData to (the clipboard as text)
-	
-	if ("print('cd')" is not in (clipboardData as string)) then
-		error "print('cd')  is not in clipboardData: "
-	end if
-end tell
-
-tell application "Firefox" to quit
-
-display notification "Test passed" with title "Firefox test" sound name "Glass"
\ No newline at end of file
diff --git a/tests/try/firefox.applescript b/tests/try/firefox.applescript
deleted file mode 100644
index d5a4c51..0000000
--- a/tests/try/firefox.applescript
+++ /dev/null
@@ -1,126 +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.
-
-tell application "Firefox 29" to activate
-
-delay 3.0
-
-tell application "System Events"
-        keystroke "n" using command down
-
-        delay 1.0
-
-        keystroke "l" using command down
-
-        keystroke "http://localhost:8080/"
-        -- Simulate Enter key.
-        key code 36
-
-        delay 10.0
-
-        keystroke "l" using command down
-        -- Simulate Tab key.
-        key code 48
-        key code 48
-        key code 48
-        key code 48
-
-        -- Simulate End key.
-        key code 119
-
-        -- Simulate Home key.
-        key code 115
-
-        -- Simulate Tab key.
-        key code 48
-
-        -- Simulate Cmd-Up.
-        key code 126 using command down
-
-        -- Simulate Down.
-        key code 125
-        key code 125
-        key code 125
-        key code 125
-        key code 125
-
-        -- Simulate Cmd-Right.
-        key code 124 using command down
-
-        -- Simulate Delete
-        key code 51
-
-        delay 0.1
-        keystroke "a" using command down
-        delay 0.2
-        keystroke "c" using command down
-
-        delay 0.2
-        set clipboardData to (the clipboard as text)
-
-        if ("main() {" is in (clipboardData as string)) then
-                error "main() { in clipboardData"
-        end if
-
-        if ("main() " is not in (clipboardData as string)) then
-                error "main() is not in clipboardData"
-        end if
-
-        keystroke "l" using command down
-        delay 0.2
-
-        keystroke "http://localhost:8080/"
-        -- Simulate Enter key.
-        key code 36
-
-        delay 5.0
-
-        keystroke "l" using command down
-        -- Simulate Tab key.
-        key code 48
-        key code 48
-        key code 48
-        key code 48
-
-        -- Simulate End key.
-        key code 119
-
-        -- Simulate Home key.
-        key code 115
-
-        -- Simulate Tab key.
-        key code 48
-
-        -- Simulate Cmd-Down.
-        key code 125 using command down
-
-        repeat 204 times
-                -- Simulate Delete
-               key code 51
-        end repeat
-
-        delay 5.0
-        repeat 64 times
-                -- Simulate Delete
-               key code 51
-        end repeat
-
-
-        delay 0.1
-        keystroke "a" using command down
-        delay 0.5
-        keystroke "c" using command down
-
-        delay 0.5
-        set clipboardData to (the clipboard as text)
-
-        if ("/" is not (clipboardData as string)) then
-                error "/ is not clipboardData"
-        end if
-
-end tell
-
-tell application "Firefox" to quit
-
-display notification "Test passed" with title "Firefox test" sound name "Glass"
diff --git a/tests/try/poi/apply_updates_test.dart b/tests/try/poi/apply_updates_test.dart
deleted file mode 100644
index 6c7c6cd..0000000
--- a/tests/try/poi/apply_updates_test.dart
+++ /dev/null
@@ -1,107 +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 of FunctionUpdate by pretty printing the updated element before and
-// after.
-library trydart.library_updater_test;
-
-import 'package:dart2js_incremental/library_updater.dart' show
-    IncrementalCompilerContext,
-    LibraryUpdater,
-    Update;
-
-import 'package:compiler/src/parser/partial_elements.dart' show
-    PartialFunctionElement;
-
-import 'package:compiler/src/script.dart' show
-    Script;
-
-import 'package:compiler/src/io/source_file.dart' show
-    StringSourceFile;
-
-import 'compiler_test_case.dart';
-
-import 'library_updater_test.dart' show
-    LibraryUpdaterTestCase,
-    newScriptFrom,
-    nolog;
-
-class ApplyUpdateTestCase extends LibraryUpdaterTestCase {
-  final String expectedUpdate;
-
-  ApplyUpdateTestCase(
-      {String before,
-      String after,
-      String update})
-      : this.expectedUpdate = update,
-        super(before: before, after: after, canReuse: true);
-
-  Future run() => loadMainApp().then((LibraryElement library) {
-    // Capture the current version of [before] before invoking the [updater].
-    PartialFunctionElement before = library.localLookup(expectedUpdate);
-    var beforeNode = before.parseNode(compiler.parsingContext);
-
-    var context = new IncrementalCompilerContext();
-    LibraryUpdater updater =
-        new LibraryUpdater(this.compiler, null, nolog, nolog, context);
-    context.registerUriWithUpdates([scriptUri]);
-
-    bool actualCanReuse =
-        updater.canReuseLibrary(
-            library, <Script>[newScriptFrom(library, newSource)]);
-    Expect.equals(expectedCanReuse, actualCanReuse);
-
-    Update update = updater.updates.single;
-
-    // Check that the [updater] didn't modify the changed element.
-    Expect.identical(before, update.before);
-    Expect.identical(beforeNode, before.parseNode(compiler.parsingContext));
-
-    PartialFunctionElement after = update.after;
-    var afterNode = after.parseNode(compiler.parsingContext);
-
-    // Check that pretty-printing the elements match [source] (before), and
-    // [newSource] (after).
-    Expect.stringEquals(source, '$beforeNode');
-    Expect.stringEquals(newSource, '$afterNode');
-    Expect.notEquals(source, newSource);
-
-    // Apply the update.
-    update.apply();
-
-    // Check that the update was applied by pretty-printing [before]. Make no
-    // assumptions about [after], as the update may destroy that element.
-    beforeNode = before.parseNode(compiler.parsingContext);
-    Expect.notEquals(source, '$beforeNode');
-    Expect.stringEquals(newSource, '$beforeNode');
-  });
-}
-
-void main() {
-  runTests(
-      [
-          new ApplyUpdateTestCase(
-              before: 'main(){print("Hello, World!");}',
-              after: 'main(){print("Hello, Brave New World!");}',
-              update: 'main'),
-
-          new ApplyUpdateTestCase(
-              before: 'main(){foo(){return 1;}return foo();}',
-              after: 'main(){bar(){return "1";}return bar();}',
-              update: 'main'),
-
-          new ApplyUpdateTestCase(
-              before: 'main()=>null;',
-              after: 'main(){}',
-              update: 'main'),
-
-          new ApplyUpdateTestCase(
-              before: 'main(){}',
-              after: 'main()=>null;',
-              update: 'main'),
-
-          // TODO(ahe): When supporting class members, test abstract methods.
-      ]
-  );
-}
diff --git a/tests/try/poi/compiler_test_case.dart b/tests/try/poi/compiler_test_case.dart
deleted file mode 100644
index 711e47e..0000000
--- a/tests/try/poi/compiler_test_case.dart
+++ /dev/null
@@ -1,86 +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.
-
-// Helper class for writing compiler tests.
-library trydart.compiler_test_case;
-
-import 'dart:async' show
-    Future;
-
-export 'dart:async' show
-    Future;
-
-import 'package:async_helper/async_helper.dart' show
-    asyncTest;
-
-import '../../compiler/dart2js/mock_compiler.dart' show
-    MockCompiler,
-    compilerFor;
-
-export 'package:expect/expect.dart' show
-    Expect;
-
-import 'package:compiler/src/elements/elements.dart' show
-    LibraryElement;
-
-export 'package:compiler/src/elements/elements.dart' show
-    LibraryElement;
-
-const String CONSTANT_CLASS = 'class Constant { const Constant(); }';
-
-const String SCHEME = 'org.trydart.compiler-test-case';
-
-Uri customUri(String path) => Uri.parse('$SCHEME:/$path');
-
-Future runTests(List<CompilerTestCase> tests) {
-  asyncTest(() => Future.forEach(tests, runTest));
-}
-
-Future runTest(CompilerTestCase test) {
-  print('\n{{{\n$test\n\n=== Test Output:\n');
-  return test.run().then((_) {
-  print('}}}');
-  });
-}
-
-abstract class CompilerTestCase {
-  final String source;
-
-  final Uri scriptUri;
-
-  final MockCompiler compiler;
-
-  CompilerTestCase.init(this.source, this.scriptUri, this.compiler);
-
-  CompilerTestCase.intermediate(String source, Uri scriptUri)
-      : this.init(source, scriptUri, compilerFor(source, scriptUri));
-
-  CompilerTestCase(String source, [String path])
-      : this.intermediate(source, customUri(path == null ? 'main.dart' : path));
-
-  Future<LibraryElement> loadMainApp() {
-    return compiler.libraryLoader.loadLibrary(scriptUri)
-        .then((LibraryElement library) {
-          if (compiler.mainApp == null) {
-            compiler.mainApp = library;
-          } else if (compiler.mainApp != library) {
-            throw
-                "Inconsistent use of compiler"
-                " (${compiler.mainApp} != $library).";
-          }
-          return library;
-        });
-  }
-
-  Future run();
-
-  /// Returns a future for the mainApp after running the compiler.
-  Future<LibraryElement> compile() {
-    return loadMainApp().then((LibraryElement library) {
-      return compiler.run(scriptUri).then((_) => library);
-    });
-  }
-
-  String toString() => source;
-}
diff --git a/tests/try/poi/data/abstract_field.dart b/tests/try/poi/data/abstract_field.dart
deleted file mode 100644
index cc793b9..0000000
--- a/tests/try/poi/data/abstract_field.dart
+++ /dev/null
@@ -1,20 +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 abstract_field;
-
-class A {
-  String get foo => null;
-
-  set foo(String v) => null;
-
-  method() {
-  }
-}
-
-String get bar => null;
-
-set bar(String v) => null;
-
-main() {}
diff --git a/tests/try/poi/data/empty_main.dart b/tests/try/poi/data/empty_main.dart
deleted file mode 100644
index ba1bc74..0000000
--- a/tests/try/poi/data/empty_main.dart
+++ /dev/null
@@ -1,5 +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.
-
-void main() {}
diff --git a/tests/try/poi/data/interesting.dart b/tests/try/poi/data/interesting.dart
deleted file mode 100644
index 9f39d9d..0000000
--- a/tests/try/poi/data/interesting.dart
+++ /dev/null
@@ -1,14 +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 interesting;
-
-class Foo {
-  fisk() {
-  }
-  hest() {
-  }
-}
-
-main() {}
diff --git a/tests/try/poi/data/private.dart b/tests/try/poi/data/private.dart
deleted file mode 100644
index 23f2c4c..0000000
--- a/tests/try/poi/data/private.dart
+++ /dev/null
@@ -1,31 +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 private;
-
-class P {
-  pMethod1() {
-  }
-
-  pMethod2() {
-  }
-
-  _pMethod1() {
-  }
-
-  _pMethod2() {
-  }
-
-  static staticPMethod1() {
-  }
-
-  static staticPMethod2() {
-  }
-
-  static _staticPMethod1() {
-  }
-
-  static _staticPMethod2() {
-  }
-}
diff --git a/tests/try/poi/data/subclass.dart b/tests/try/poi/data/subclass.dart
deleted file mode 100644
index 80ea9a8..0000000
--- a/tests/try/poi/data/subclass.dart
+++ /dev/null
@@ -1,33 +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 subclass;
-
-import 'interesting.dart';
-
-import 'private.dart' as p;
-
-class S extends p.P {
-  superMethod1() {
-  }
-  superMethod2() {
-  }
-  static staticSuperMethod1() {
-  }
-  static staticSuperMethod2() {
-  }
-}
-
-class C extends S {
-  instanceMethod1() {
-  }
-  instanceMethod2() {
-  }
-  static staticMethod1() {
-  }
-  static staticMethod2() {
-  }
-}
-
-main() {}
diff --git a/tests/try/poi/diff_test.dart b/tests/try/poi/diff_test.dart
deleted file mode 100644
index c6de2fd..0000000
--- a/tests/try/poi/diff_test.dart
+++ /dev/null
@@ -1,126 +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 of element diff.
-library trydart.diff_test;
-
-import 'dart:async' show
-    Future;
-
-import 'package:expect/expect.dart' show
-    Expect;
-
-import 'package:async_helper/async_helper.dart' show
-    asyncTest;
-
-import 'package:compiler/src/compiler.dart' show
-    Compiler;
-
-import 'package:compiler/src/io/source_file.dart' show
-    StringSourceFile;
-
-import 'package:compiler/src/elements/elements.dart' show
-    Element,
-    LibraryElement;
-
-import 'package:compiler/src/script.dart' show
-    Script;
-
-import 'package:dart2js_incremental/diff.dart' show
-    Difference,
-    computeDifference;
-
-import '../../compiler/dart2js/mock_compiler.dart' show
-    MockCompiler,
-    compilerFor;
-
-final TEST_DATA = [
-    {
-      'beforeSource': 'main() {}',
-      'afterSource': 'main() { var x; }',
-      'expectations': [['main', 'main']],
-    },
-    {
-      'beforeSource': 'main() {}',
-      'afterSource': 'main() { /* ignored */ }',
-      'expectations': [],
-    },
-    {
-      'beforeSource': 'main() {}',
-      'afterSource': 'main() { }',
-      'expectations': [],
-    },
-    {
-      'beforeSource': 'var i; main() {}',
-      'afterSource': 'main() { } var i;',
-      'expectations': [],
-    },
-    {
-      'beforeSource': 'main() {}',
-      'afterSource': '',
-      'expectations': [['main', null]],
-    },
-    {
-      'beforeSource': '',
-      'afterSource': 'main() {}',
-      'expectations': [[null, 'main']],
-    },
-];
-
-const String SCHEME = 'org.trydart.diff-test';
-
-Uri customUri(String path) => Uri.parse('$SCHEME://$path');
-
-Future<List<Difference>> testDifference(
-    String beforeSource,
-    String afterSource) {
-  Uri scriptUri = customUri('main.dart');
-  MockCompiler compiler = compilerFor(beforeSource, scriptUri);
-
-  Future<LibraryElement> future = compiler.libraryLoader.loadLibrary(scriptUri);
-  return future.then((LibraryElement library) {
-    Script sourceScript = new Script(
-        scriptUri, scriptUri,
-        new StringSourceFile.fromUri(scriptUri, afterSource));
-    var dartPrivacyIsBroken = compiler.libraryLoader;
-    LibraryElement newLibrary = dartPrivacyIsBroken.createLibrarySync(
-        null, sourceScript, scriptUri);
-    return computeDifference(library, newLibrary);
-  });
-}
-
-Future testData(Map data) {
-  String beforeSource = data['beforeSource'];
-  String afterSource = data['afterSource'];
-  List expectations = data['expectations'];
-
-  validate(List<Difference> differences) {
-    return checkExpectations(expectations, differences);
-  }
-
-  return testDifference(beforeSource, afterSource).then(validate);
-}
-
-String elementNameOrNull(Element element) {
-  return element == null ? null : element.name;
-}
-
-checkExpectations(List expectations, List<Difference> differences) {
-  Iterator iterator = expectations.iterator;
-  for (Difference difference in differences) {
-    Expect.isTrue(iterator.moveNext());
-    List expectation = iterator.current;
-    String expectedBeforeName = expectation[0];
-    String expectedAfterName = expectation[1];
-    Expect.stringEquals(
-        expectedBeforeName, elementNameOrNull(difference.before));
-    Expect.stringEquals(expectedAfterName, elementNameOrNull(difference.after));
-    print(difference);
-  }
-  Expect.isFalse(iterator.moveNext());
-}
-
-void main() {
-  asyncTest(() => Future.forEach(TEST_DATA, testData));
-}
diff --git a/tests/try/poi/forget_element_assertion.dart b/tests/try/poi/forget_element_assertion.dart
deleted file mode 100644
index a825532..0000000
--- a/tests/try/poi/forget_element_assertion.dart
+++ /dev/null
@@ -1,64 +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 that dart2js doesn't support metadata on local elements.
-// Remove this file when dart2js support such features.
-library trydart.forget_element_assertion;
-
-import '../../compiler/dart2js/mock_compiler.dart' show
-    compilerFor;
-
-import 'compiler_test_case.dart';
-
-class FailingTestCase extends CompilerTestCase {
-  FailingTestCase.intermediate(String source, int errorCount, Uri scriptUri)
-      : super.init(
-          source, scriptUri,
-          compilerFor(source, scriptUri, expectedErrors: errorCount));
-
-  FailingTestCase(String source, int errorCount)
-      : this.intermediate(source, errorCount, customUri('main.dart'));
-
-  Future run() {
-    return compile().then((_) {
-      print("Failed as expected.");
-    }).catchError((error, stackTrace) {
-      print(
-          "\n\n\n***\n\n\n"
-          "The compiler didn't fail when compiling:\n $source\n\n"
-          "Please adjust assumptions in "
-          "tests/try/poi/forget_element_assertion.dart\n\n"
-        );
-      print("$error\n$stackTrace");
-      throw "Please update assumptions in this file.";
-    });
-  }
-}
-
-List<FailingTestCase> assertUnimplementedLocalMetadata() {
-  return <FailingTestCase>[
-
-      // This tests that the compiler doesn't accept metadata on local
-      // functions. If this feature is implemented, please convert this test to
-      // a positive test in forget_element_test.dart. For example:
-      //
-      //    new ForgetElementTestCase(
-      //       'main() { @Constant() foo() {}; return foo(); } $CONSTANT_CLASS',
-      //       metadataCount: 1),
-      new FailingTestCase(
-          'main() { @Constant() foo() {}; return foo(); } $CONSTANT_CLASS',
-          1),
-
-      // This tests that the compiler doesn't accept metadata on local
-      // variables. If this feature is implemented, please convert this test to
-      // a positive test in forget_element_test.dart. For example:
-      //
-      //    new ForgetElementTestCase(
-      //       'main() { @Constant() var x; return x; } $CONSTANT_CLASS',
-      //       metadataCount: 1),
-      new FailingTestCase(
-          'main() { @Constant() var x; return x; } $CONSTANT_CLASS',
-          1),
-    ];
-}
diff --git a/tests/try/poi/forget_element_test.dart b/tests/try/poi/forget_element_test.dart
deleted file mode 100644
index 095b52c..0000000
--- a/tests/try/poi/forget_element_test.dart
+++ /dev/null
@@ -1,404 +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 of Compiler.forgetElement.
-library trydart.forget_element_test;
-
-import 'package:compiler/src/elements/elements.dart' show
-    AstElement,
-    ClassElement,
-    Element,
-    FunctionElement,
-    LocalFunctionElement,
-    MetadataAnnotation,
-    ScopeContainerElement,
-    VariableElement;
-
-import 'package:compiler/src/js_backend/js_backend.dart' show
-    JavaScriptBackend;
-
-import 'package:compiler/src/tree/tree.dart' as tree;
-
-import 'package:compiler/src/parser/partial_elements.dart' show
-    PartialMetadataAnnotation;
-
-import 'package:compiler/src/elements/visitor.dart' show
-    ElementVisitor;
-
-import 'package:compiler/src/compile_time_constants.dart' show
-    DartConstantCompiler;
-
-import 'package:compiler/src/universe/universe.dart' show
-    Universe;
-
-import 'package:compiler/src/dart_types.dart' show
-    DartType;
-
-import 'compiler_test_case.dart';
-
-import 'forget_element_assertion.dart' show
-    assertUnimplementedLocalMetadata;
-
-class ForgetElementTestCase extends CompilerTestCase {
-  final int expectedClosureCount;
-
-  final int expectedMetadataCount;
-
-  final int expectedConstantCount;
-
-  final int expectedInitialValueCount;
-
-  final int expectedInitialDartValueCount;
-
-  final int additionalClosureClassMaps;
-
-  JavaScriptBackend get backend => compiler.backend;
-
-  DartConstantCompiler get dartConstants =>
-      backend.constantCompilerTask.dartConstantCompiler;
-
-  Universe get codegenUniverse => compiler.enqueuer.codegen.universe;
-
-  Universe get resolutionUniverse => compiler.enqueuer.resolution.universe;
-
-  ForgetElementTestCase(
-      String source,
-      {int closureCount: 0,
-       int metadataCount: 0,
-       int constantCount: 0,
-       int initialValueCount: 0,
-       int initialDartValueCount: null,
-       this.additionalClosureClassMaps: 0})
-      : this.expectedClosureCount = closureCount,
-        this.expectedMetadataCount = metadataCount,
-        this.expectedConstantCount = constantCount,
-        this.expectedInitialValueCount = initialValueCount,
-        // Sometimes these numbers aren't the same. Appears to happen with
-        // non-const fields, because those aren't compile-time constants in the
-        // strict language specification sense.
-        this.expectedInitialDartValueCount = (initialDartValueCount == null)
-            ? initialValueCount : initialDartValueCount,
-        super(source);
-
-  Future run() => compile().then((LibraryElement library) {
-
-    // Check that the compiler has recorded the expected number of closures.
-    Expect.equals(
-        expectedClosureCount, closuresInLibrary(library).length,
-        'closure count');
-
-    // Check that the compiler has recorded the expected number of metadata
-    // annotations.
-    Expect.equals(
-        expectedMetadataCount, metadataInLibrary(library).length,
-        'metadata count');
-
-    // Check that the compiler has recorded the expected number of
-    // constants. Since metadata is also constants, those must also be counted.
-    Expect.equals(
-        expectedConstantCount + expectedMetadataCount,
-        constantsIn(library).length,
-        'constant count');
-
-    // Check that the compiler has recorded the expected number of initial
-    // values.
-    Expect.equals(
-        expectedInitialValueCount,
-        elementsWithJsInitialValuesIn(library).length,
-        'number of fields with initial values (JS)');
-    Expect.equals(
-        expectedInitialDartValueCount,
-        elementsWithDartInitialValuesIn(library).length,
-        'number of fields with initial values (Dart)');
-
-    // Check that the compiler has recorded the expected number of closure
-    // class maps. There's always at least one, from main. Each top-level
-    // element also seems to induce one.
-    Expect.equals(
-        expectedClosureCount + additionalClosureClassMaps,
-        closureClassMapsIn(library).length - 1,
-        'closure class map count ${closureClassMapsIn(library)}');
-
-
-    // Forget about all elements.
-    library.forEachLocalMember(compiler.forgetElement);
-
-    // Check that all the closures were forgotten.
-    Expect.isTrue(closuresInLibrary(library).isEmpty, 'closures');
-
-    // Check that the metadata annotations were forgotten.
-    Expect.isTrue(metadataInLibrary(library).isEmpty, 'metadata');
-
-    // Check that the constants were forgotten.
-    Expect.isTrue(constantsIn(library).isEmpty, 'constants');
-
-    // Check that initial values were forgotten.
-    Expect.isTrue(
-        elementsWithJsInitialValuesIn(library).isEmpty,
-        'fields with initial values (JS)');
-    Expect.isTrue(
-        elementsWithDartInitialValuesIn(library).isEmpty,
-        'fields with initial values (Dart)');
-
-    // Check that closure class maps were forgotten.
-    Expect.isTrue(closureClassMapsIn(library).isEmpty, 'closure class maps');
-
-    // Check that istantiated types and classes were forgotten.
-    Expect.isTrue(
-        resolutionTypesIn(library).isEmpty, 'resolution instantiatedTypes');
-    Expect.isTrue(
-        resolutionClassesIn(library).isEmpty, 'resolution instantiatedClasses');
-    Expect.isTrue(
-        codegenTypesIn(library).isEmpty, 'codegen instantiatedTypes');
-    Expect.isTrue(
-        codegenClassesIn(library).isEmpty, 'codegen instantiatedClasses');
-
-    // Check that other members remembered by [Universe] were forgotten.
-    Expect.isTrue(
-        resolutionMembersIn(library).isEmpty, 'resolution misc members');
-    Expect.isTrue(
-        codegenMembersIn(library).isEmpty, 'codegen misc members');
-
-    // Check that classes remembered by the enqueuer have been forgotten.
-    Expect.isTrue(
-        codegenSeenClassesIn(library).isEmpty, 'codegen seen classes');
-    Expect.isTrue(
-        resolutionSeenClassesIn(library).isEmpty, 'resolution seen classes');
-  });
-
-  Iterable closuresInLibrary(LibraryElement library) {
-    return compiler.enqueuer.resolution.universe.allClosures.where(
-        (LocalFunctionElement closure) => closure.library == library);
-  }
-
-  Iterable metadataInLibrary(LibraryElement library) {
-    return backend.constants.metadataConstantMap.keys.where(
-        (MetadataAnnotation metadata) {
-          return metadata.annotatedElement.library == library;
-        });
-  }
-
-  Iterable<tree.Node> nodesIn(LibraryElement library) {
-    NodeCollector collector = new NodeCollector();
-    library.forEachLocalMember((e) {
-      if (e is AstElement && e.hasNode) {
-        e.node.accept(collector);
-      }
-
-      // Due to quirks of history, only parameter metadata is recorded in AST
-      // nodes, so they must be extracted from the elements.
-      for (MetadataAnnotation metadata in e.metadata) {
-        if (metadata is PartialMetadataAnnotation) {
-          if (metadata.cachedNode != null) {
-            metadata.cachedNode.accept(collector);
-          }
-        }
-      }
-    });
-
-    List<MetadataAnnotation> metadata =
-        (new MetadataCollector()..visit(library, null)).metadata;
-    return collector.nodes;
-  }
-
-  Iterable constantsIn(LibraryElement library) {
-    return nodesIn(library)
-        .map((node) => backend.constants.nodeConstantMap[node])
-        .where((constant) => constant != null);
-  }
-
-  Iterable elementsWithJsInitialValuesIn(LibraryElement library) {
-    return backend.constants.initialVariableValues.keys.where(
-        (VariableElement element) => element.library == library);
-  }
-
-  Iterable elementsWithDartInitialValuesIn(LibraryElement library) {
-    return dartConstants.initialVariableValues.keys.where(
-        (VariableElement element) => element.library == library);
-  }
-
-  Iterable closureClassMapsIn(LibraryElement library) {
-    Map cache = compiler.closureToClassMapper.closureMappingCache;
-    return nodesIn(library).where((node) => cache[node] != null);
-  }
-
-  Iterable codegenTypesIn(LibraryElement library) {
-    return codegenUniverse.instantiatedTypes.where(
-        (DartType type) => type.element.library == library);
-  }
-
-  Iterable codegenClassesIn(LibraryElement library) {
-    return codegenUniverse.directlyInstantiatedClasses.where(
-        (ClassElement cls) => cls.library == library);
-  }
-
-  Iterable codegenMembersIn(LibraryElement library) {
-    sameLibrary(e) => e.library == library;
-    return new Set()
-        ..addAll(codegenUniverse.closurizedMembers.where(sameLibrary))
-        ..addAll(codegenUniverse.fieldSetters.where(sameLibrary))
-        ..addAll(codegenUniverse.fieldGetters.where(sameLibrary));
-  }
-
-  Iterable resolutionTypesIn(LibraryElement library) {
-    return resolutionUniverse.instantiatedTypes.where(
-        (DartType type) => type.element.library == library);
-  }
-
-  Iterable resolutionClassesIn(LibraryElement library) {
-    return resolutionUniverse.directlyInstantiatedClasses.where(
-        (ClassElement cls) => cls.library == library);
-  }
-
-  Iterable resolutionMembersIn(LibraryElement library) {
-    sameLibrary(e) => e.library == library;
-    return new Set()
-        ..addAll(resolutionUniverse.closurizedMembers.where(sameLibrary))
-        ..addAll(resolutionUniverse.fieldSetters.where(sameLibrary))
-        ..addAll(resolutionUniverse.fieldGetters.where(sameLibrary));
-  }
-
-  Iterable codegenSeenClassesIn(LibraryElement library) {
-    return compiler.enqueuer.codegen.processedClasses.where(
-        (e) => e.library == library);
-  }
-
-  Iterable resolutionSeenClassesIn(LibraryElement library) {
-    return compiler.enqueuer.resolution.processedClasses.where(
-        (e) => e.library == library);
-  }
-}
-
-class NodeCollector extends tree.Visitor {
-  final List<tree.Node> nodes = <tree.Node>[];
-
-  void visitNode(tree.Node node) {
-    nodes.add(node);
-    node.visitChildren(this);
-  }
-}
-
-class MetadataCollector extends ElementVisitor {
-  final List<MetadataAnnotation> metadata = <MetadataAnnotation>[];
-
-  void visitElement(Element e, _) {
-    metadata.addAll(e.metadata.toList());
-  }
-
-  void visitScopeContainerElement(ScopeContainerElement e, _) {
-    super.visitScopeContainerElement(e);
-    e.forEachLocalMember(this.visit);
-  }
-
-  void visitFunctionElement(FunctionElement e, _) {
-    super.visitFunctionElement(e);
-    if (e.hasFunctionSignature) {
-      e.functionSignature.forEachParameter(this.visit);
-    }
-  }
-}
-
-void main() {
-  runTests(tests);
-}
-
-List<CompilerTestCase> get tests => <CompilerTestCase>[
-
-    // Edge case: empty body.
-    new ForgetElementTestCase(
-        'main() {}'),
-
-    // Edge case: simple arrow function.
-    new ForgetElementTestCase(
-        'main() => null;'),
-
-    // Test that a local closure is discarded correctly.
-    new ForgetElementTestCase(
-        'main() => (() => null)();',
-        closureCount: 1),
-
-    // Test that nested closures are discarded correctly.
-    new ForgetElementTestCase(
-        'main() => (() => (() => null)())();',
-        closureCount: 2),
-
-    // Test that nested closures are discarded correctly.
-    new ForgetElementTestCase(
-        'main() => (() => (() => (() => null)())())();',
-        closureCount: 3),
-
-    // Test that metadata on top-level function is discarded correctly.
-    new ForgetElementTestCase(
-        '@Constant() main() => null; $CONSTANT_CLASS',
-        metadataCount: 1),
-
-    // Test that metadata on top-level variable is discarded correctly.
-    new ForgetElementTestCase(
-        '@Constant() var x; main() => x; $CONSTANT_CLASS',
-        metadataCount: 1,
-        initialValueCount: 1,
-        initialDartValueCount: 0),
-
-    // Test that metadata on parameter on a local function is discarded
-    // correctly.
-    new ForgetElementTestCase(
-        'main() => ((@Constant() x) => x)(null); $CONSTANT_CLASS',
-        closureCount: 1,
-        metadataCount: 1),
-
-    // Test that a constant in a top-level method body is discarded
-    // correctly.
-    new ForgetElementTestCase(
-        'main() => const Constant(); $CONSTANT_CLASS',
-        constantCount: 1),
-
-    // Test that a constant in a nested function body is discarded
-    // correctly.
-    new ForgetElementTestCase(
-        'main() => (() => const Constant())(); $CONSTANT_CLASS',
-        constantCount: 1,
-        closureCount: 1),
-
-    // Test that a constant in a nested function body is discarded
-    // correctly.
-    new ForgetElementTestCase(
-        'main() => (() => (() => const Constant())())(); $CONSTANT_CLASS',
-        constantCount: 1,
-        closureCount: 2),
-
-    // Test that a constant in a top-level variable initializer is
-    // discarded correctly.
-    new ForgetElementTestCase(
-        'main() => x; var x = const Constant(); $CONSTANT_CLASS',
-        constantCount: 1,
-        initialValueCount: 1,
-        initialDartValueCount: 0,
-        additionalClosureClassMaps: 1),
-
-    // Test that a constant in a parameter initializer is discarded
-    // correctly.
-    new ForgetElementTestCase(
-        'main([x = const Constant()]) => x; $CONSTANT_CLASS',
-        constantCount: 1,
-        initialValueCount: 1),
-
-    // Test that a constant in a parameter initializer is discarded
-    // correctly (nested function).
-    new ForgetElementTestCase(
-        'main() => (([x = const Constant()]) => x)(); $CONSTANT_CLASS',
-        closureCount: 1,
-        constantCount: 1,
-        initialValueCount: 1),
-
-    // Test that a constant in a parameter initializer is discarded
-    // correctly (deeply nested function).
-    new ForgetElementTestCase(
-        'main() => (() => (([x = const Constant()]) => x)())();'
-        ' $CONSTANT_CLASS',
-        closureCount: 2,
-        constantCount: 1,
-        initialValueCount: 1),
-
-    // TODO(ahe): Add test for super sends [backend.aliasedSuperMembers].
-]..addAll(assertUnimplementedLocalMetadata());
diff --git a/tests/try/poi/library_updater_test.dart b/tests/try/poi/library_updater_test.dart
deleted file mode 100644
index b37fac5..0000000
--- a/tests/try/poi/library_updater_test.dart
+++ /dev/null
@@ -1,140 +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 of LibraryUpdater (one compilation unit per library).
-library trydart.library_updater_test;
-
-import 'package:dart2js_incremental/library_updater.dart' show
-    IncrementalCompilerContext,
-    LibraryUpdater,
-    Update;
-
-import 'package:compiler/src/script.dart' show
-    Script;
-
-import 'package:compiler/src/io/source_file.dart' show
-    StringSourceFile;
-
-import 'compiler_test_case.dart';
-
-void nolog(_) {}
-
-Script newScriptFrom(LibraryElement library, String newSource) {
-  Script script = library.entryCompilationUnit.script;
-  return script.copyWithFile(
-      new StringSourceFile.fromUri(script.file.uri, newSource));
-}
-
-class LibraryUpdaterTestCase extends CompilerTestCase {
-  final String newSource;
-
-  final bool expectedCanReuse;
-
-  final List<String> expectedUpdates;
-
-  LibraryUpdaterTestCase(
-      {String before,
-       String after,
-       bool canReuse,
-       List<String> updates})
-      : this.newSource = after,
-        this.expectedCanReuse = canReuse,
-        this.expectedUpdates = updates,
-        super(before);
-
-  Future run() => loadMainApp().then((LibraryElement library) {
-    var context = new IncrementalCompilerContext();
-    LibraryUpdater updater =
-        new LibraryUpdater(this.compiler, null, nolog, nolog, context);
-    context.registerUriWithUpdates([scriptUri]);
-    bool actualCanReuse =
-        updater.canReuseLibrary(
-            library, <Script>[newScriptFrom(library, newSource)]);
-    Expect.equals(expectedCanReuse, actualCanReuse);
-
-    Expect.setEquals(
-        expectedUpdates.toSet(),
-        updater.updates.map(nameOfUpdate).toSet());
-  });
-
-  String toString() => 'Before:\n$source\n\n\nAfter:\n$newSource';
-}
-
-String nameOfUpdate(Update update) {
-  var element = update.before;
-  if (element == null) element = update.after;
-  return element.name;
-}
-
-void main() {
-  runTests(
-      [
-          // Only method body changed. Can be reused if 'main' is
-          // updated/patched.
-          new LibraryUpdaterTestCase(
-              before: 'main() { print("Hello, World!"); }',
-              after: 'main() { print("Hello, Brave New World!"); }',
-              canReuse: true,
-              updates: ['main']),
-
-          // Signature changed. Can't be reused.
-          new LibraryUpdaterTestCase(
-              before: 'main() { print("Hello, World!"); }',
-              after: 'void main() { print("Hello, World!"); }',
-              canReuse: true,
-              updates: ['main']),
-
-          // Only whitespace changes. Can be reused; no updates/patches needed.
-          new LibraryUpdaterTestCase(
-              before: 'main(){print("Hello, World!");}',
-              after: 'main() { print ( "Hello, World!" ) ; }',
-              canReuse: true,
-              updates: []),
-
-          // Only whitespace/comment changes (in signature). Can be reused; no
-          // updates/patches needed.
-          new LibraryUpdaterTestCase(
-              before:
-                  '/* Implicitly dynamic. */ main ( /* No parameters. */ ) '
-                  '{print("Hello, World!");}',
-              after: 'main() {print("Hello, World!");}',
-              canReuse: true,
-              updates: []),
-
-          // Arrow function changed to method body. Can be reused if 'main' is
-          // updated/patched.
-          new LibraryUpdaterTestCase(
-              before: 'main() => null',
-              after: 'main() { return null; }',
-              canReuse: true,
-              updates: ['main']),
-
-          // Empty body changed to contain a statement. Can be reused if 'main'
-          // is updated/patched.
-          new LibraryUpdaterTestCase(
-              before: 'main() {}',
-              after: 'main() { return null; }',
-              canReuse: true,
-              updates: ['main']),
-
-          // Empty body changed to arrow. Can be reused if 'main'
-          // is updated/patched.
-          new LibraryUpdaterTestCase(
-              before: 'main() {}',
-              after: 'main() => null;',
-              canReuse: true,
-              updates: ['main']),
-
-          // Arrow changed to empty body. Can be reused if 'main'
-          // is updated/patched.
-          new LibraryUpdaterTestCase(
-              before: 'main() => null;',
-              after: 'main() {}',
-              canReuse: true,
-              updates: ['main']),
-
-          // TODO(ahe): When supporting class members, test abstract methods.
-      ]
-  );
-}
diff --git a/tests/try/poi/poi_find_test.dart b/tests/try/poi/poi_find_test.dart
deleted file mode 100644
index af4bec7..0000000
--- a/tests/try/poi/poi_find_test.dart
+++ /dev/null
@@ -1,76 +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 poi.dart finds the right element.
-
-library trydart.poi_find_test;
-
-import 'dart:io' show
-    Platform;
-
-import 'dart:async' show
-    Future;
-
-import 'package:try/poi/poi.dart' as poi;
-
-import 'package:async_helper/async_helper.dart';
-
-import 'package:expect/expect.dart';
-
-import 'package:compiler/src/elements/elements.dart' show
-    Element;
-
-import 'package:compiler/src/source_file_provider.dart' show
-    FormattingDiagnosticHandler;
-
-Future testPoi() {
-  Uri script = Platform.script.resolve('data/empty_main.dart');
-  FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler();
-  handler.verbose = false;
-
-  Future future = poi.runPoi(script, 225, handler.provider, handler);
-  return future.then((Element element) {
-    Uri foundScript = element.compilationUnit.script.resourceUri;
-    Expect.stringEquals('$script', '$foundScript');
-    Expect.stringEquals('main', element.name);
-
-    String source = handler.provider.sourceFiles[script].slowText();
-    final int position = source.indexOf('main()');
-    Expect.isTrue(position > 0, '$position > 0');
-
-    var token;
-
-    // When the cursor is at the same character offset as "main()", it
-    // corresponds to having the cursor just before "main()". So we find the
-    // "void" token.
-    token = poi.findToken(element, position);
-    Expect.isNotNull(token, 'token');
-    Expect.stringEquals('void', token.value);
-
-    // Cursor at position + 1 corresponds to having the cursor just after "m"
-    // in "main()". So we find the "main" token.
-    token = poi.findToken(element, position + 1);
-    Expect.isNotNull(token, 'token');
-    Expect.equals(position, token.charOffset);
-    Expect.stringEquals('main', token.value);
-
-    // This corresponds to the cursor after "main", but before "()" in
-    // "main()". So we find the "main" token.
-    token = poi.findToken(element, position + 4);
-    Expect.isNotNull(token, 'token');
-    Expect.equals(position, token.charOffset);
-    Expect.stringEquals('main', token.value);
-
-    // This corresponds to the cursor after "(" in "main()". So we find the "("
-    // token.
-    token = poi.findToken(element, position + 5);
-    Expect.isNotNull(token, 'token');
-    Expect.equals(position + 4, token.charOffset, '$token');
-    Expect.stringEquals('(', token.value);
-  });
-}
-
-void main() {
-  asyncTest(testPoi);
-}
diff --git a/tests/try/poi/poi_test.dart b/tests/try/poi/poi_test.dart
deleted file mode 100644
index 9e79274..0000000
--- a/tests/try/poi/poi_test.dart
+++ /dev/null
@@ -1,41 +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 of the main method in poi.dart. This test only ensures that poi.dart
-/// doesn't crash.
-
-library trydart.poi_test;
-
-import 'dart:io' show
-    Platform;
-
-import 'dart:async' show
-    Future;
-
-import 'package:try/poi/poi.dart' as poi;
-
-import 'package:async_helper/async_helper.dart';
-
-class PoiTest {
-  final Uri script;
-  final int offset;
-
-  PoiTest(this.script, this.offset);
-
-  Future run() => poi.main(<String>[script.toFilePath(), '$offset']);
-}
-
-void main() {
-  int position = 695;
-  List tests = [
-      // The file empty_main.dart is a regression test for crash in
-      // resolveMetadataAnnotation in dart2js.
-      new PoiTest(Platform.script.resolve('data/empty_main.dart'), 225),
-      new PoiTest(Platform.script, position),
-  ];
-
-  poi.isDartMindEnabled = false;
-
-  asyncTest(() => Future.forEach(tests, (PoiTest test) => test.run()));
-}
diff --git a/tests/try/poi/qualified_names_test.dart b/tests/try/poi/qualified_names_test.dart
deleted file mode 100644
index 0d512f3..0000000
--- a/tests/try/poi/qualified_names_test.dart
+++ /dev/null
@@ -1,64 +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 of [qualifiedNamesIn] and [canNamesResolveStaticallyTo].
-library trydart.qualified_names_test;
-
-import 'package:dart2js_incremental/library_updater.dart' show
-    canNamesResolveStaticallyTo,
-    qualifiedNamesIn;
-
-import 'compiler_test_case.dart';
-
-typedef Checker(LibraryElement script);
-
-class NameTestCase extends CompilerTestCase {
-  final Checker check;
-
-  NameTestCase(String source, this.check)
-      : super(source);
-
-  Future run() => loadMainApp().then(check);
-}
-
-main() {
-  runTests(tests.map((l) => new NameTestCase(l.first, l.last)).toList());
-}
-
-final List tests = [
-    ["main() { x; }",
-     (LibraryElement script) {
-       var names = qualifiedNamesIn(script.findLocal("main"));
-       Expect.setEquals(["main", "x"].toSet(), names);
-     }],
-
-    ["main() { x; x.y; }",
-     (LibraryElement script) {
-       var names = qualifiedNamesIn(script.findLocal("main"));
-       Expect.setEquals(["main", "x", "x.y"].toSet(), names);
-     }],
-
-    ["main() { x; x.y; x.y.z; x.y.z.w;}",
-     (LibraryElement script) {
-       var names = qualifiedNamesIn(script.findLocal("main"));
-       // ".w" is skipped.
-       Expect.setEquals(["main", "x", "x.y", "x.y.z"].toSet(), names);
-     }],
-
-
-    ["x() {} y() {} z() {} w() {} main() { x; x.y; x.y.z; x.y.z.w;}",
-     (LibraryElement script) {
-       var main = script.findLocal("main");
-       var names = qualifiedNamesIn(main);
-       var x = script.findLocal("x");
-       var y = script.findLocal("y");
-       var z = script.findLocal("z");
-       var w = script.findLocal("w");
-       Expect.isTrue(canNamesResolveStaticallyTo(names, main, script));
-       Expect.isTrue(canNamesResolveStaticallyTo(names, x, script));
-       Expect.isFalse(canNamesResolveStaticallyTo(names, y, script));
-       Expect.isFalse(canNamesResolveStaticallyTo(names, z, script));
-       Expect.isFalse(canNamesResolveStaticallyTo(names, w, script));
-     }],
-];
diff --git a/tests/try/poi/serialize_test.dart b/tests/try/poi/serialize_test.dart
deleted file mode 100644
index c890b8b..0000000
--- a/tests/try/poi/serialize_test.dart
+++ /dev/null
@@ -1,620 +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 poi.dart can serialize a scope.
-
-library trydart.serialize_test;
-
-import 'dart:io' show
-    Platform;
-
-import 'dart:async' show
-    Future;
-
-import 'dart:convert' show
-    JSON;
-
-import 'package:try/poi/poi.dart' as poi;
-
-import 'package:async_helper/async_helper.dart';
-
-import 'package:expect/expect.dart';
-
-import 'package:compiler/src/elements/elements.dart' show
-    Element;
-
-import 'package:compiler/src/source_file_provider.dart' show
-    FormattingDiagnosticHandler;
-
-Future testInteresting() {
-  poi.cachedCompiler = null;
-  Uri script = Platform.script.resolve('data/interesting.dart');
-  FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler();
-
-  int position = 263;
-
-  Future future = poi.runPoi(script, position, handler.provider, handler);
-  return future.then((Element element) {
-    Uri foundScript = element.compilationUnit.script.resourceUri;
-    Expect.stringEquals('$script', '$foundScript');
-    Expect.stringEquals('fisk', element.name);
-
-    String scope = poi.scopeInformation(element, position);
-    Expect.stringEquals(
-        JSON.encode(expectedInteresting), JSON.encode(JSON.decode(scope)),
-        scope);
-    return testSubclass(handler);
-  });
-}
-
-Future testSubclass(FormattingDiagnosticHandler handler) {
-  poi.cachedCompiler = null;
-  int position = 506;
-
-  Uri script = Platform.script.resolve('data/subclass.dart');
-
-  Future future = poi.runPoi(script, position, handler.provider, handler);
-  return future.then((Element element) {
-    Uri foundScript = element.compilationUnit.script.resourceUri;
-    Expect.stringEquals('$script', '$foundScript');
-    Expect.stringEquals('instanceMethod2', element.name);
-
-    String scope = poi.scopeInformation(element, position);
-    Expect.stringEquals(
-        JSON.encode(expectedSubclass), JSON.encode(JSON.decode(scope)), scope);
-
-    return testAbstractField(handler);
-  });
-}
-
-Future testAbstractField(FormattingDiagnosticHandler handler) {
-  poi.cachedCompiler = null;
-  int position = 321;
-
-  Uri script = Platform.script.resolve('data/abstract_field.dart');
-
-  Future future = poi.runPoi(script, position, handler.provider, handler);
-  return future.then((Element element) {
-    Uri foundScript = element.compilationUnit.script.resourceUri;
-    Expect.stringEquals('$script', '$foundScript');
-    Expect.stringEquals('method', element.name);
-
-    String scope = poi.scopeInformation(element, position);
-    Expect.stringEquals(
-        JSON.encode(expectedAbstractField), JSON.encode(JSON.decode(scope)),
-        scope);
-  });
-}
-
-void main() {
-  asyncTest(testInteresting);
-}
-
-final expectedInteresting = {
-  "name": "fisk",
-  "kind": "function",
-  "type": "() -> dynamic",
-  "enclosing": {
-    "name": "Foo",
-    "kind": "class side",
-    "members": [
-      {
-        "kind": "generative_constructor",
-        "type": "() -> Foo"
-      }
-    ],
-    "enclosing": {
-      "name": "Foo",
-      "kind": "instance side",
-      "members": [
-        {
-          "name": "fisk",
-          "kind": "function",
-          "type": "() -> dynamic"
-        },
-        {
-          "name": "hest",
-          "kind": "function",
-          "type": "() -> dynamic"
-        },
-      ],
-      "enclosing": {
-        "name": "interesting",
-        "kind": "library",
-        "members": [
-          {
-            "name": "Foo",
-            "kind": "class"
-          },
-          {
-            "name": "main",
-            "kind": "function",
-            "type": "() -> dynamic"
-          }
-        ],
-        "enclosing": {
-          "kind": "imports",
-          "members": coreImports,
-          "enclosing": object,
-        }
-      }
-    }
-  }
-};
-
-final expectedSubclass = {
-  "name": "instanceMethod2",
-  "kind": "function",
-  "type": "() -> dynamic",
-  "enclosing": {
-    "name": "C",
-    "kind": "class side",
-    "members": [
-      {
-        "name": "staticMethod1",
-        "kind": "function",
-        "type": "() -> dynamic"
-      },
-      {
-        "name": "staticMethod2",
-        "kind": "function",
-        "type": "() -> dynamic"
-      },
-      {
-        "kind": "generative_constructor",
-        "type": "() -> C"
-      }
-    ],
-    "enclosing": {
-      "name": "C",
-      "kind": "instance side",
-      "members": [
-        {
-          "name": "instanceMethod1",
-          "kind": "function",
-          "type": "() -> dynamic"
-        },
-        {
-          "name": "instanceMethod2",
-          "kind": "function",
-          "type": "() -> dynamic"
-        }
-      ],
-      "enclosing": {
-        "name": "subclass",
-        "kind": "library",
-        "members": [
-          {
-            "name": "S",
-            "kind": "class"
-          },
-          {
-            "name": "C",
-            "kind": "class"
-          },
-          {
-            "name": "main",
-            "kind": "function",
-            "type": "() -> dynamic"
-          },
-          {
-            "name": "p",
-            "kind": "prefix"
-          }
-        ],
-        "enclosing": {
-          "kind": "imports",
-          "members": [
-            {
-              "name": "Foo",
-              "kind": "class"
-            },
-            {
-              "name": "main",
-              "kind": "function",
-              "type": "() -> dynamic"
-            },
-          ]..addAll(coreImports),
-          "enclosing": {
-            "name": "S",
-            "kind": "instance side",
-            "members": [
-              {
-                "name": "superMethod1",
-                "kind": "function",
-                "type": "() -> dynamic"
-              },
-              {
-                "name": "superMethod2",
-                "kind": "function",
-                "type": "() -> dynamic"
-              },
-            ],
-            "enclosing": {
-              "name": "P",
-              "kind": "instance side",
-              "members": [
-                {
-                  "name": "pMethod1",
-                  "kind": "function",
-                  "type": "() -> dynamic"
-                },
-                {
-                  "name": "pMethod2",
-                  "kind": "function",
-                  "type": "() -> dynamic"
-                },
-                {
-                  "name": "_pMethod1",
-                  "kind": "function",
-                  "type": "() -> dynamic"
-                },
-                {
-                  "name": "_pMethod2",
-                  "kind": "function",
-                  "type": "() -> dynamic"
-                },
-              ],
-              "enclosing": object,
-            }
-          }
-        }
-      }
-    }
-  }
-};
-
-final expectedAbstractField = {
-  "name": "method",
-  "kind": "function",
-  "type": "() -> dynamic",
-  "enclosing": {
-    "name": "A",
-    "kind": "class side",
-    "members": [
-      {
-        "kind": "generative_constructor",
-        "type": "() -> A"
-      }
-    ],
-    "enclosing": {
-      "name": "A",
-      "kind": "instance side",
-      "members": [
-        {
-          "name": "foo",
-          "kind": "getter"
-        },
-        {
-          "name": "foo",
-          "kind": "setter"
-        },
-        {
-          "name": "method",
-          "kind": "function",
-          "type": "() -> dynamic"
-        }
-      ],
-      "enclosing": {
-        "name": "abstract_field",
-        "kind": "library",
-        "members": [
-          {
-            "name": "A",
-            "kind": "class"
-          },
-          {
-            "name": "bar",
-            "kind": "getter"
-          },
-          {
-            "name": "bar",
-            "kind": "getter"
-          },
-          {
-            "name": "main",
-            "kind": "function",
-            "type": "() -> dynamic"
-          }
-        ],
-        "enclosing": {
-          "kind": "imports",
-          "members": coreImports,
-          "enclosing": object
-        },
-      },
-    },
-  },
-};
-
-final coreImports = [
-  {
-    "name": "Deprecated",
-    "kind": "class"
-  },
-  {
-    "name": "deprecated",
-    "kind": "field",
-    "type": "Deprecated"
-  },
-  {
-    "name": "override",
-    "kind": "field",
-    "type": "Object"
-  },
-  {
-    "name": "proxy",
-    "kind": "field",
-    "type": "Object"
-  },
-  {
-    "name": "bool",
-    "kind": "class"
-  },
-  {
-    "name": "Comparator",
-    "kind": "typedef"
-  },
-  {
-    "name": "Comparable",
-    "kind": "class"
-  },
-  {
-    "name": "DateTime",
-    "kind": "class"
-  },
-  {
-    "name": "double",
-    "kind": "class"
-  },
-  {
-    "name": "Duration",
-    "kind": "class"
-  },
-  {
-    "name": "Error",
-    "kind": "class"
-  },
-  {
-    "name": "AssertionError",
-    "kind": "class"
-  },
-  {
-    "name": "TypeError",
-    "kind": "class"
-  },
-  {
-    "name": "CastError",
-    "kind": "class"
-  },
-  {
-    "name": "NullThrownError",
-    "kind": "class"
-  },
-  {
-    "name": "ArgumentError",
-    "kind": "class"
-  },
-  {
-    "name": "RangeError",
-    "kind": "class"
-  },
-  {
-    "name": "IndexError",
-    "kind": "class"
-  },
-  {
-    "name": "FallThroughError",
-    "kind": "class"
-  },
-  {
-    "name": "AbstractClassInstantiationError",
-    "kind": "class"
-  },
-  {
-    "name": "NoSuchMethodError",
-    "kind": "class"
-  },
-  {
-    "name": "UnsupportedError",
-    "kind": "class"
-  },
-  {
-    "name": "UnimplementedError",
-    "kind": "class"
-  },
-  {
-    "name": "StateError",
-    "kind": "class"
-  },
-  {
-    "name": "ConcurrentModificationError",
-    "kind": "class"
-  },
-  {
-    "name": "OutOfMemoryError",
-    "kind": "class"
-  },
-  {
-    "name": "StackOverflowError",
-    "kind": "class"
-  },
-  {
-    "name": "CyclicInitializationError",
-    "kind": "class"
-  },
-  {
-    "name": "Exception",
-    "kind": "class"
-  },
-  {
-    "name": "FormatException",
-    "kind": "class"
-  },
-  {
-    "name": "IntegerDivisionByZeroException",
-    "kind": "class"
-  },
-  {
-    "name": "Expando",
-    "kind": "class"
-  },
-  {
-    "name": "Function",
-    "kind": "class"
-  },
-  {
-    "name": "identical",
-    "kind": "function",
-    "type": "(Object, Object) -> bool"
-  },
-  {
-    "name": "identityHashCode",
-    "kind": "function",
-    "type": "(Object) -> int"
-  },
-  {
-    "name": "int",
-    "kind": "class"
-  },
-  {
-    "name": "Invocation",
-    "kind": "class"
-  },
-  {
-    "name": "Iterable",
-    "kind": "class"
-  },
-  {
-    "name": "BidirectionalIterator",
-    "kind": "class"
-  },
-  {
-    "name": "Iterator",
-    "kind": "class"
-  },
-  {
-    "name": "List",
-    "kind": "class"
-  },
-  {
-    "name": "Map",
-    "kind": "class"
-  },
-  {
-    "name": "Null",
-    "kind": "class"
-  },
-  {
-    "name": "num",
-    "kind": "class"
-  },
-  {
-    "name": "Object",
-    "kind": "class"
-  },
-  {
-    "name": "Pattern",
-    "kind": "class"
-  },
-  {
-    "name": "Match",
-    "kind": "class"
-  },
-  {
-    "name": "print",
-    "kind": "function",
-    "type": "(Object) -> void"
-  },
-  {
-    "name": "RegExp",
-    "kind": "class"
-  },
-  {
-    "name": "Resource",
-    "kind": "class"
-  },
-  {
-    "name": "Set",
-    "kind": "class"
-  },
-  {
-    "name": "Sink",
-    "kind": "class"
-  },
-  {
-    "name": "StackTrace",
-    "kind": "class"
-  },
-  {
-    "name": "Stopwatch",
-    "kind": "class"
-  },
-  {
-    "name": "String",
-    "kind": "class"
-  },
-  {
-    "name": "Runes",
-    "kind": "class"
-  },
-  {
-    "name": "RuneIterator",
-    "kind": "class"
-  },
-  {
-    "name": "StringBuffer",
-    "kind": "class"
-  },
-  {
-    "name": "StringSink",
-    "kind": "class"
-  },
-  {
-    "name": "Symbol",
-    "kind": "class"
-  },
-  {
-    "name": "Type",
-    "kind": "class"
-  },
-  {
-    "name": "Uri",
-    "kind": "class"
-  },
-  {
-    "name": "UriData",
-    "kind": "class"
-  }
-];
-
-final object = {
-  "name": "Object",
-  "kind": "instance side",
-  "members": [
-    {
-      "name": "==",
-      "kind": "function",
-      "type": "(dynamic) -> bool"
-    },
-    {
-      "name": "hashCode",
-      "kind": "getter"
-    },
-    {
-      "name": "toString",
-      "kind": "function",
-      "type": "() -> String"
-    },
-    {
-      "name": "noSuchMethod",
-      "kind": "function",
-      "type": "(Invocation) -> dynamic"
-    },
-    {
-      "name": "runtimeType",
-      "kind": "getter"
-    }
-  ]
-};
diff --git a/tests/try/poi/source_update.dart b/tests/try/poi/source_update.dart
deleted file mode 100644
index 95ea1d1..0000000
--- a/tests/try/poi/source_update.dart
+++ /dev/null
@@ -1,154 +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 trydart.source_update;
-
-/// Returns [updates] expanded to full compilation units/source files.
-///
-/// [updates] is a convenient way to write updates/patches to a single source
-/// file without repeating common parts.
-///
-/// For example:
-///   ["head ", ["v1", "v2"], " tail"]
-/// expands to:
-///   ["head v1 tail", "head v2 tail"]
-List<String> expandUpdates(List updates) {
-  int outputCount = updates.firstWhere((e) => e is Iterable).length;
-  List<StringBuffer> result = new List<StringBuffer>(outputCount);
-  for (int i = 0; i < outputCount; i++) {
-    result[i] = new StringBuffer();
-  }
-  for (var chunk in updates) {
-    if (chunk is Iterable) {
-      int segmentCount = 0;
-      for (var segment in chunk) {
-        result[segmentCount++].write(segment);
-      }
-      if (segmentCount != outputCount) {
-        throw new ArgumentError(
-            "Expected ${outputCount} segments, "
-            "but found ${segmentCount} in $chunk");
-      }
-    } else {
-      for (StringBuffer buffer in result) {
-        buffer.write(chunk);
-      }
-    }
-  }
-
-  return result.map((e) => '$e').toList();
-}
-
-/// Returns [files] split into multiple named files. The keys in the returned
-/// map are filenames, the values are the files' content.
-///
-/// Names are indicated by a line on the form "==> filename <==". Spaces are
-/// significant. For example, given this input:
-///
-///     ==> file1.dart <==
-///     First line of file 1.
-///     Second line of file 1.
-///     Third line of file 1.
-///     ==> empty.dart <==
-///     ==> file2.dart <==
-///     First line of file 2.
-///     Second line of file 2.
-///     Third line of file 2.
-///
-/// This function would return:
-///
-///     {
-///       "file1.dart": """
-///     First line of file 1.
-///     Second line of file 1.
-///     Third line of file 1.
-///     """,
-///
-///       "empty.dart":"",
-///
-///       "file2.dart":"""
-///     First line of file 2.
-///     Second line of file 2.
-///     Third line of file 2.
-///     """
-///     }
-Map<String, String> splitFiles(String files) {
-  Map<String, String> result = <String, String>{};
-  String currentName;
-  List<String> content;
-  void finishFile() {
-    if (currentName != null) {
-      if (result.containsKey(currentName)) {
-        throw new ArgumentError("Duplicated filename $currentName in $files");
-      }
-      result[currentName] = content.join('');
-    }
-    content = null;
-  }
-  void processDirective(String line) {
-    finishFile();
-    if (line.length < 8 || !line.endsWith(" <==\n")) {
-      throw new ArgumentError(
-          "Malformed line: expected '==> ... <==', but got: '$line'");
-    }
-    currentName = line.substring(4, line.length - 5);
-    content = <String>[];
-  }
-  for (String line in splitLines(files)) {
-    if (line.startsWith("==>")) {
-      processDirective(line);
-    } else {
-      content.add(line);
-    }
-  }
-  finishFile();
-  return result;
-}
-
-/// Split [text] into lines preserving trailing newlines (unlike
-/// String.split("\n"). Also, if [text] is empty, return an empty list (unlike
-/// String.split("\n")).
-List<String> splitLines(String text) {
-  return text.split(new RegExp('^', multiLine: true));
-}
-
-/// Expand a file with diffs in common merge conflict format into a [List] that
-/// can be passed to [expandUpdates].
-///
-/// For example:
-///     first
-///     <<<<<<<
-///     v1
-///     =======
-///     v2
-///     =======
-///     v3
-///     >>>>>>>
-///     last
-///
-/// Would be expanded to something equivalent to:
-///
-///     ["first\n", ["v1\n", "v2\n", "v3\n"], "last\n"]
-List expandDiff(String text) {
-  List result = [new StringBuffer()];
-  bool inDiff = false;
-  for (String line in splitLines(text)) {
-    if (inDiff) {
-      if (line.startsWith("=======")) {
-        result.last.add(new StringBuffer());
-      } else if (line.startsWith(">>>>>>>")) {
-        inDiff = false;
-        result.add(new StringBuffer());
-      } else {
-        result.last.last.write(line);
-      }
-    } else if (line.startsWith("<<<<<<<")) {
-      inDiff = true;
-      result.add(<StringBuffer>[new StringBuffer()]);
-    } else {
-      result.last.write(line);
-    }
-  }
-  return result;
-}
diff --git a/tests/try/poi/source_update_test.dart b/tests/try/poi/source_update_test.dart
deleted file mode 100644
index 1b279bd..0000000
--- a/tests/try/poi/source_update_test.dart
+++ /dev/null
@@ -1,120 +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 [source_update.dart].
-library trydart.source_update_test;
-
-import 'dart:convert' show
-    JSON;
-
-import 'package:expect/expect.dart' show
-    Expect;
-
-import 'source_update.dart' show
-    expandDiff,
-    expandUpdates,
-    splitFiles,
-    splitLines;
-
-main() {
-  Expect.listEquals(
-      ["head v1 tail", "head v2 tail"],
-      expandUpdates(["head ", ["v1", "v2"], " tail"]));
-
-  Expect.listEquals(
-      ["head v1 tail v2", "head v2 tail v1"],
-      expandUpdates(["head ", ["v1", "v2"], " tail ", ["v2", "v1"]]));
-
-  Expect.throws(() {
-    expandUpdates(["head ", ["v1", "v2"], " tail ", ["v1"]]);
-  });
-
-  Expect.throws(() {
-    expandUpdates(["head ", ["v1", "v2"], " tail ", ["v1", "v2", "v3"]]);
-  });
-
-  Expect.stringEquals(
-      JSON.encode({
-          "file1.dart": """
-First line of file 1.
-Second line of file 1.
-Third line of file 1.
-""",
-          "empty.dart":"",
-          "file2.dart":"""
-First line of file 2.
-Second line of file 2.
-Third line of file 2.
-"""}),
-
-      JSON.encode(splitFiles(r"""
-==> file1.dart <==
-First line of file 1.
-Second line of file 1.
-Third line of file 1.
-==> empty.dart <==
-==> file2.dart <==
-First line of file 2.
-Second line of file 2.
-Third line of file 2.
-""")));
-
-  Expect.stringEquals("{}", JSON.encode(splitFiles("")));
-
-  Expect.stringEquals("[]", JSON.encode(splitLines("")));
-
-  Expect.stringEquals('["1"]', JSON.encode(splitLines("1")));
-
-  Expect.stringEquals('["\\n"]', JSON.encode(splitLines("\n")));
-
-  Expect.stringEquals('["\\n","1"]', JSON.encode(splitLines("\n1")));
-
-  Expect.stringEquals(
-      '["","",""]',
-      JSON.encode(expandUpdates(expandDiff(r"""
-<<<<<<<
-=======
-=======
->>>>>>>
-"""))));
-
-  Expect.stringEquals(
-      r'["first\nv1\nlast\n","first\nv2\nlast\n","first\nv3\nlast\n"]',
-      JSON.encode(expandUpdates(expandDiff(r"""
-first
-<<<<<<<
-v1
-=======
-v2
-=======
-v3
->>>>>>>
-last
-"""))));
-
-  Expect.stringEquals(
-      r'["v1\nlast\n","v2\nlast\n","v3\nlast\n"]',
-      JSON.encode(expandUpdates(expandDiff(r"""
-<<<<<<<
-v1
-=======
-v2
-=======
-v3
->>>>>>>
-last
-"""))));
-
-  Expect.stringEquals(
-      r'["v1\n","v2\n","v3\n"]',
-      JSON.encode(expandUpdates(expandDiff(r"""
-<<<<<<<
-v1
-=======
-v2
-=======
-v3
->>>>>>>
-"""))));
-}
diff --git a/tests/try/safari.applescript b/tests/try/safari.applescript
deleted file mode 100644
index 299bcbc..0000000
--- a/tests/try/safari.applescript
+++ /dev/null
@@ -1,144 +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.
-
-tell application "Safari" to activate
-
-delay 3.0
-
-tell application "System Events"
-
-        keystroke "n" using command down
-
-        delay 1.0
-
-        keystroke "l" using command down
-
-        keystroke "http://localhost:8080/"
-        -- Simulate Enter key.
-        key code 36
-
-        delay 5.0
-
-        keystroke "l" using command down
-        -- Simulate Tab key.
-        key code 48
-        key code 48
-
-        delay 0.2
-
-        -- Simulate Down.
-        key code 125
-
-        delay 0.2
-
-        -- Simulate Down.
-        key code 125
-
-        delay 0.2
-
-        -- Simulate Enter key.
-        key code 36
-
-        delay 0.2
-
-        -- Simulate Tab key.
-        key code 48
-
-        -- Simulate Cmd-Up.
-        key code 126 using command down
-
-        -- Simulate Down.
-        key code 125
-        key code 125
-        key code 125
-        key code 125
-        key code 125
-
-        -- Simulate Cmd-Right.
-        key code 124 using command down
-
-        -- Simulate Delete
-        key code 51
-
-        delay 0.1
-        keystroke "a" using command down
-        delay 0.2
-        keystroke "c" using command down
-
-        delay 0.2
-        set clipboardData to (the clipboard as text)
-
-        if ("main() {" is in (clipboardData as string)) then
-                error "main() { in clipboardData"
-        end if
-
-        if ("main() " is not in (clipboardData as string)) then
-                error "main() is not in clipboardData"
-        end if
-
-        keystroke "l" using command down
-        delay 0.2
-
-        keystroke "http://localhost:8080/"
-        -- Simulate Enter key.
-        key code 36
-
-        delay 5.0
-
-        keystroke "l" using command down
-        -- Simulate Tab key.
-        key code 48
-        key code 48
-
-        delay 0.2
-
-        -- Simulate Down.
-        key code 125
-
-        delay 0.2
-
-        -- Simulate Down.
-        key code 125
-
-        delay 0.2
-
-        -- Simulate Enter key.
-        key code 36
-
-        delay 0.2
-
-        -- Simulate Tab key.
-        key code 48
-
-        -- Simulate Cmd-Down.
-        key code 125 using command down
-
-        repeat 203 times
-                -- Simulate Delete
-               key code 51
-        end repeat
-        delay 5.0
-        repeat 64 times
-                -- Simulate Delete
-               key code 51
-        end repeat
-
-
-        delay 0.1
-        keystroke "a" using command down
-        delay 0.5
-        keystroke "c" using command down
-
-        delay 0.5
-        set clipboardData to (the clipboard as text)
-
-        if ("/" is not (clipboardData as string)) then
-                error "/ is not clipboardData"
-        end if
-
-end tell
-
-tell application "Safari" to quit
-
-display notification "Test passed" with title "Safari test" sound name "Glass"
diff --git a/tests/try/try.status b/tests/try/try.status
deleted file mode 100644
index f84f339..0000000
--- a/tests/try/try.status
+++ /dev/null
@@ -1,47 +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.
-
-web/incremental_compilation_update_test: Slow, RuntimeError # issue 23197
-
-[ $runtime == ie10 || $runtime == ie9 || $runtime == vm || $jscl ]
-web/*: Skip
-
-[ $compiler == dart2js && $runtime == drt ]
-web/end_to_end_test: Fail, Pass # https://code.google.com/p/v8/issues/detail?id=3347
-
-[ $compiler == none && $runtime == drt ]
-web/end_to_end_test: Fail # Issue 24568
-
-[ $csp ]
-web/end_to_end_test: Fail, OK # Issue 17935
-web/incremental_compilation_update_test: SkipByDesign # Test uses eval, not supported in CSP mode.
-
-[ $runtime == safari || $runtime == safarimobilesim ]
-web/incremental_compilation_update_test: Skip # Safari may crash on this test.
-
-[ $runtime == safarimobilesim ]
-web/cursor_position_test: Fail # Issue 19836
-
-[ $runtime == safari && $checked ]
-# The following tests flake with this error:
-#   type '*Theme' is not a subtype of type 'Theme'
-# Suspect this is a bad optimization.
-web/source_update_test: Fail, Pass
-web/paste_content_rewriting_test: Fail, Pass
-
-[ $runtime == safarimobilesim ]
-web/end_to_end_test: Skip # Issue 21608
-
-[ $browser ]
-poi/poi_test: SkipByDesign # Uses dart:io.
-poi/poi_find_test: SkipByDesign # Uses dart:io.
-poi/serialize_test: SkipByDesign # Uses dart:io.
-
-[ $compiler == dart2js ]
-poi/*: Skip # Issue 20031
-
-[ $compiler == dart2js ]
-# Compilation is slow, test fails at runtime due to time out, but
-# unpredictably.
-web/incremental_compilation_update_test: Skip
diff --git a/tests/try/web/cursor_position_test.dart b/tests/try/web/cursor_position_test.dart
deleted file mode 100644
index 52ccb03..0000000
--- a/tests/try/web/cursor_position_test.dart
+++ /dev/null
@@ -1,114 +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 cursor positions are correctly updated after adding new content.
-
-import 'test_try.dart';
-
-void main() {
-  InteractionManager interaction = mockTryDartInteraction();
-
-  TestCase twoLines =
-      new TestCase('Test adding two lines programmatically.', () {
-        clearEditorPaneWithoutNotifications();
-        mainEditorPane.appendText('\n\n');
-        Text text = mainEditorPane.firstChild;
-        window.getSelection().collapse(text, 1);
-        checkSelectionIsCollapsed(text, 1);
-      }, checkAtBeginningOfSecondLine);
-
-  runTests(<TestCase>[
-    twoLines,
-
-    new TestCase('Test adding a new text node.', () {
-      // This test relies on the previous test leaving two lines.
-      Text text = new Text('fisk');
-      window.getSelection().getRangeAt(0).insertNode(text);
-      window.getSelection().collapse(text, text.length);
-      checkSelectionIsCollapsed(text, text.length);
-    }, checkAtEndOfSecondLineWithFisk),
-
-    twoLines,
-
-    new TestCase('Test adding a new wrapped text node.', () {
-      // This test relies on the previous test leaving two lines.
-      Text text = new Text('fisk');
-      Node node = new SpanElement()..append(text);
-      window.getSelection().getRangeAt(0).insertNode(node);
-      window.getSelection().collapse(text, text.length);
-      checkSelectionIsCollapsed(text, text.length);
-    }, checkAtEndOfSecondLineWithFisk),
-
-    new TestCase('Test adding a new line with mock key event.', () {
-      clearEditorPaneWithoutNotifications();
-      checkSelectionIsCollapsed(mainEditorPane, 0);
-      simulateEnterKeyDown(interaction);
-    }, checkAtBeginningOfSecondLine),
-
-    new TestCase('Clear and presetup the test', () {
-      clearEditorPaneWithoutNotifications();
-      mainEditorPane.text = 'var greeting = "Hello, World!\n";';
-    }, () {
-      checkLineCount(2);
-    }),
-
-    new TestCase('Test removing a split line', () {
-      mainEditorPane.nodes.first.nodes.last.remove();
-    }, () {
-      checkLineCount(1);
-    }),
-  ]);
-}
-
-void simulateEnterKeyDown(InteractionManager interaction) {
-  interaction.onKeyUp(
-      new MockKeyboardEvent('keydown', keyCode: KeyCode.ENTER));
-}
-
-void checkSelectionIsCollapsed(Node node, int offset) {
-  var selection = window.getSelection();
-  Expect.isTrue(selection.isCollapsed, 'selection.isCollapsed');
-  Expect.equals(node, selection.anchorNode, 'selection.anchorNode');
-  Expect.equals(offset, selection.anchorOffset, 'selection.anchorOffset');
-}
-
-void checkLineCount(int expectedLineCount) {
-  Expect.equals(
-      expectedLineCount, mainEditorPane.nodes.length,
-      'mainEditorPane.nodes.length');
-}
-
-void checkAtBeginningOfSecondLine() {
-  checkLineCount(2);
-  checkSelectionIsCollapsed(mainEditorPane.nodes[1].firstChild, 0);
-}
-
-void checkAtEndOfSecondLineWithFisk() {
-  checkLineCount(2);
-  SpanElement secondLine = mainEditorPane.nodes[1];
-  Text text = secondLine.firstChild.firstChild;
-  Expect.stringEquals('fisk', text.text);
-  Expect.equals(4, text.length);
-  Text newline = secondLine.firstChild.nextNode;
-  Expect.equals(newline, secondLine.lastChild);
-  /// Chrome and Firefox cannot agree on where to put the cursor.  At the end
-  /// of [text] or at the beginning of [newline].  It's the same position.
-  if (window.getSelection().anchorOffset == 0) {
-    // Firefox.
-    checkSelectionIsCollapsed(newline, 0);
-  } else {
-    // Chrome.
-    checkSelectionIsCollapsed(text, 4);
-  }
-}
-
-class MockKeyboardEvent extends KeyEvent {
-  final int keyCode;
-
-  MockKeyboardEvent(String type, {int keyCode})
-      : this.keyCode = keyCode,
-        super.wrap(new KeyEvent(type, keyCode: keyCode));
-
-  bool getModifierState(String keyArgument) => false;
-}
diff --git a/tests/try/web/end_to_end_test.dart b/tests/try/web/end_to_end_test.dart
deleted file mode 100644
index 8352270..0000000
--- a/tests/try/web/end_to_end_test.dart
+++ /dev/null
@@ -1,45 +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.
-
-/// Whitebox integration/end-to-end test of Try Dart! site.
-///
-/// This test opens Try Dart! in an iframe.  When opened the first time, Try
-/// Dart! will display a simple hello-world example, color tokens, compile the
-/// example, and run the result.  We've instrumented Try Dart! to use
-/// window.parent.postMessage when the running program prints anything. So this
-/// test just waits for a "Hello, World!" message.
-library trydart.end_to_end_test;
-
-import 'dart:html';
-
-import 'package:async_helper/async_helper.dart' show
-    asyncTest;
-
-import 'sandbox.dart' show
-    appendIFrame,
-    listener;
-
-void main() => asyncTest(() {
-  listener.start();
-
-  // Disable analytics for testing.
-  document.cookie = 'org-trydart-AutomatedTest=true;path=/';
-
-  // Clearing localStorage makes Try Dart! think it is opening for the first
-  // time.
-  window.localStorage.clear();
-
-  IFrameElement iframe =
-      appendIFrame('/root_build/try_dartlang_org/index.html', document.body)
-          ..style.width = '90vw'
-          ..style.height = '90vh';
-
-  return listener.expect('Hello, World!\n').then((_) {
-    // Remove the iframe to work around a bug in test.dart.
-    iframe.remove();
-
-    // Clean up after ourselves.
-    window.localStorage.clear();
-  });
-});
diff --git a/tests/try/web/incremental_compilation_update.html b/tests/try/web/incremental_compilation_update.html
deleted file mode 100644
index 61734d4..0000000
--- a/tests/try/web/incremental_compilation_update.html
+++ /dev/null
@@ -1,63 +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>
-    <title>incremental_compilation_update_test.html</title>
-    <meta charset="UTF-8">
-  </head>
-  <body>
-    <h1>incremental_compilation_update_test.html</h1>
-    <pre id="console"></pre>
-<script type="application/javascript" src="print.js"></script>
-<script type="application/javascript">
-(function() {
-  var dartMainClosure;
-
-  /// Invoked by JavaScript code generated by dart2js when the program is ready
-  /// to invoke main.
-  self.dartMainRunner = function dartMainRunner(main) {
-    dartMainClosure = main;
-
-    // Invoke the "main" method of the Dart program.
-    main();
-
-    // Let the sandbox embedder know that main is done running.
-    window.parent.postMessage('iframe-dart-main-done', '*');
-  }
-
-  /// Invoked when a 'message' event is received. Message events are generated
-  /// with Window.postMessage and used to communicate between this iframe and
-  /// its embedding parent page.
-  function onMessage(e) {
-    if (e.data[0] === 'add-script') {
-      // Received a message on the form ['add-script', uri].
-      // Install a new script tag with the uri.
-      var script = document.createElement('script');
-      script.src = e.data[1];
-      script.type = 'application/javascript';
-      document.body.appendChild(script);
-    } else if (e.data[0] === 'apply-update') {
-      self.$dart_unsafe_incremental_support.patch(e.data[1]);
-
-      dartMainClosure();
-
-      // Let the sandbox embedder know that main is done running.
-      window.parent.postMessage('iframe-dart-updated-main-done', '*');
-    } else {
-      // Other messages are just logged.
-      console.log(e);
-    }
-  }
-  window.addEventListener('message', onMessage, false);
-
-  // Let the sandbox embedder know that this iframe is ready, that is,
-  // listening for messages.
-  window.parent.postMessage('iframe-ready', '*');
-
-})();
-</script>
-  </body>
-</html>
diff --git a/tests/try/web/incremental_compilation_update_test.dart b/tests/try/web/incremental_compilation_update_test.dart
deleted file mode 100644
index d434b47..0000000
--- a/tests/try/web/incremental_compilation_update_test.dart
+++ /dev/null
@@ -1,2062 +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 trydart.incremental_compilation_update_test;
-
-import 'dart:html' hide
-    Element;
-
-import 'dart:async' show
-    Future;
-
-import 'package:async_helper/async_helper.dart' show
-    asyncTest;
-
-import 'package:expect/expect.dart' show
-    Expect;
-
-import 'package:try/src/interaction_manager.dart' show
-    splitLines;
-
-import 'package:try/poi/scope_information_visitor.dart' show
-    ScopeInformationVisitor;
-
-import 'sandbox.dart' show
-    appendIFrame,
-    listener;
-
-import 'web_compiler_test_case.dart' show
-    WebCompilerTestCase,
-    WebInputProvider;
-
-import '../poi/compiler_test_case.dart' show
-    CompilerTestCase;
-
-import 'package:compiler/src/elements/elements.dart' show
-    Element,
-    LibraryElement;
-
-import 'package:compiler/src/compiler.dart' show
-    Compiler;
-
-import 'package:dart2js_incremental/dart2js_incremental.dart' show
-    IncrementalCompilationFailed;
-
-import 'program_result.dart';
-
-const int TIMEOUT = 100;
-
-const List<EncodedResult> tests = const <EncodedResult>[
-    // Basic hello-world test.
-    const EncodedResult(
-        const [
-            "main() { print('Hello, ",
-            const ["", "Brave New "],
-            "World!'); }",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['Hello, World!']),
-            const ProgramExpectation(
-                const <String>['Hello, Brave New World!']),
-        ]),
-
-    // Test that the test framework handles more than one update.
-    const EncodedResult(
-        const [
-            "main() { print('",
-            const [
-                "Hello darkness, my old friend",
-                "I\\'ve come to talk with you again",
-                "Because a vision softly creeping",
-            ],
-            "'); }",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['Hello darkness, my old friend']),
-            const ProgramExpectation(
-                const <String>['I\'ve come to talk with you again']),
-            const ProgramExpectation(
-                const <String>['Because a vision softly creeping']),
-        ]),
-
-    // Test that that isolate support works.
-    const EncodedResult(
-        const [
-            "main(arguments) { print(",
-            const [
-                "'Hello, Isolated World!'",
-                "arguments"
-            ],
-            "); }",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['Hello, Isolated World!']),
-            const ProgramExpectation(
-                const <String>['[]']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that a stored closure changes behavior when updated.
-
-var closure;
-
-foo(a, [b = 'b']) {
-""",
-            const [
-                r"""
-  print('$a $b');
-""",
-                r"""
-  print('$b $a');
-""",
-            ],
-            r"""
-}
-
-main() {
-  if (closure == null) {
-    print('[closure] is null.');
-    closure = foo;
-  }
-  closure('a');
-  closure('a', 'c');
-}
-"""],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['[closure] is null.', 'a b', 'a c']),
-            const ProgramExpectation(
-                const <String>['b a', 'c a']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test modifying a static method works.
-
-class C {
-  static m() {
-""",
-            const [
-                r"""
-  print('v1');
-""",
-                r"""
-  print('v2');
-""",
-            ],
-            """
-  }
-}
-main() {
-  C.m();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test modifying an instance method works.
-
-class C {
-  m() {
-""",
-            const [
-                r"""
-  print('v1');
-""",
-                r"""
-  print('v2');
-""",
-            ],
-            """
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test that a stored instance tearoff changes behavior when updated.
-
-class C {
-  m() {
-""",
-            const [
-                r"""
-  print('v1');
-""",
-                r"""
-  print('v2');
-""",
-            ],
-                """
-  }
-}
-var closure;
-main() {
-  if (closure == null) {
-    print('closure is null');
-    closure = new C().m;
-  }
-  closure();
-}
-""",
-
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['closure is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test that deleting an instance method works.
-
-class C {
-""",
-            const [
-                """
-  m() {
-    print('v1');
-  }
-""",
-                """
-""",
-            ],
-            """
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  try {
-    instance.m();
-  } catch (e) {
-    print('threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['threw']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test that deleting an instance method works, even when accessed through
-// super.
-
-class A {
-  m() {
-    print('v2');
-  }
-}
-class B extends A {
-""",
-            const [
-                """
-  m() {
-    print('v1');
-  }
-""",
-                """
-""",
-            ],
-            """
-}
-class C extends B {
-  m() {
-    super.m();
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test that deleting a top-level method works.
-
-""",
-            const [
-                """
-toplevel() {
-  print('v1');
-}
-""",
-                """
-""",
-            ],
-            """
-class C {
-  m() {
-    try {
-      toplevel();
-    } catch (e) {
-      print('threw');
-    }
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['threw']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test that deleting a static method works.
-
-class B {
-""",
-            const [
-                """
-  static staticMethod() {
-    print('v1');
-  }
-""",
-                """
-""",
-            ],
-                """
-}
-class C {
-  m() {
-    try {
-      B.staticMethod();
-    } catch (e) {
-      print('threw');
-    }
-    try {
-      // Ensure that noSuchMethod support is compiled. This test is not about
-      // adding new classes.
-      B.missingMethod();
-      print('bad');
-    } catch (e) {
-    }
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['threw']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test that a newly instantiated class is handled.
-
-class A {
-  m() {
-    print('Called A.m');
-  }
-}
-
-class B {
-  m() {
-    print('Called B.m');
-  }
-}
-
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
-""",
-            const [
-                """
-""",
-                """
-  } else {
-    instance = new B();
-""",
-            ],
-            """
-  }
-  instance.m();
-}
-""",
-
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'Called A.m']),
-            const ProgramExpectation(
-                const <String>['Called B.m']),
-        ]),
-
-    const EncodedResult(
-        const [
-            """
-// Test that source maps don't throw exceptions.
-
-main() {
-  print('a');
-""",
-            const [
-                """
-""",
-                """
-  print('b');
-  print('c');
-""",
-            ],
-            """
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['a']),
-            const ProgramExpectation(
-                const <String>['a', 'b', 'c']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that a newly instantiated class is handled.
-
-class A {
-  get name => 'A.m';
-
-  m() {
-    print('Called $name');
-  }
-}
-
-class B extends A {
-  get name => 'B.m';
-}
-
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
-""",
-            const [
-                r"""
-""",
-                r"""
-  } else {
-    instance = new B();
-""",
-            ],
-            r"""
-  }
-  instance.m();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'Called A.m']),
-            const ProgramExpectation(
-                const <String>['Called B.m']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that fields of a newly instantiated class are handled.
-
-class A {
-  var x;
-  A(this.x);
-}
-var instance;
-foo() {
-  if (instance != null) {
-    print(instance.x);
-  } else {
-    print('v1');
-  }
-}
-main() {
-""",
-            const [
-                r"""
-""",
-                r"""
-  instance = new A('v2');
-""",
-            ],
-            r"""
-  foo();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that top-level functions can be added.
-
-""",
-            const [
-                "",
-                r"""
-foo() {
-  print('v2');
-}
-""",
-            ],
-            r"""
-main() {
-  try {
-    foo();
-  } catch(e) {
-    print('threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['threw']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that static methods can be added.
-
-class C {
-""",
-            const [
-                "",
-                r"""
-  static foo() {
-    print('v2');
-  }
-""",
-            ],
-            r"""
-}
-
-main() {
-  try {
-    C.foo();
-  } catch(e) {
-    print('threw');
-  }
-}
-""",
-
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['threw']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that instance methods can be added.
-
-class C {
-""",
-            const [
-                "",
-                r"""
-  foo() {
-    print('v2');
-  }
-""",
-            ],
-            r"""
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-
-  try {
-    instance.foo();
-  } catch(e) {
-    print('threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'threw']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that top-level functions can have signature changed.
-
-""",
-            const [
-                r"""
-foo() {
-  print('v1');
-""",
-                r"""
-void foo() {
-  print('v2');
-""",
-            ],
-            r"""
-}
-
-main() {
-  foo();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that static methods can have signature changed.
-
-class C {
-""",
-            const [
-                r"""
-  static foo() {
-    print('v1');
-""",
-                r"""
-  static void foo() {
-    print('v2');
-""",
-            ],
-            r"""
-  }
-}
-
-main() {
-  C.foo();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that instance methods can have signature changed.
-
-class C {
-""",
-            const [
-                r"""
-  foo() {
-    print('v1');
-""",
-                r"""
-  void foo() {
-    print('v2');
-""",
-            ],
-            r"""
-  }
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-
-  instance.foo();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that adding a class is supported.
-
-""",
-            const [
-                "",
-                r"""
-class C {
-  void foo() {
-    print('v2');
-  }
-}
-""",
-            ],
-            r"""
-main() {
-""",
-            const [
-                r"""
-  print('v1');
-""",
-                r"""
-  new C().foo();
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that removing a class is supported, using constructor.
-
-""",
-            const [
-                r"""
-class C {
-}
-""",
-                ""
-            ],
-            r"""
-main() {
-  try {
-    new C();
-    print('v1');
-  } catch (e) {
-    print('v2');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that removing a class is supported, using a static method.
-
-""",
-            const [
-                r"""
-class C {
-  static m() {
-    print('v1');
-  }
-}
-""",
-                "",
-            ],
-            r"""
-main() {
-  try {
-    C.m();
-  } catch (e) {
-    print('v2');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that changing the supertype of a class.
-
-class A {
-  m() {
-    print('v2');
-  }
-}
-class B extends A {
-  m() {
-    print('v1');
-  }
-}
-""",
-            const [
-                r"""
-class C extends B {
-""",
-                r"""
-class C extends A {
-""",
-            ],
-            r"""
-  m() {
-    super.m();
-  }
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test adding a field to a class works.
-
-class A {
-""",
-            const [
-                "",
-                r"""
-  var x;
-""",
-            ],
-            r"""
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
-  }
-  try {
-    instance.x = 'v2';
-  } catch(e) {
-    print('setter threw');
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('getter threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'setter threw', 'getter threw']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test removing a field from a class works.
-
-class A {
-""",
-            const [
-                r"""
-  var x;
-""",
-                "",
-            ],
-            r"""
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
-  }
-  try {
-    instance.x = 'v1';
-  } catch(e) {
-    print('setter threw');
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('getter threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['setter threw', 'getter threw']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that named arguments can be called.
-
-class C {
-  foo({a, named: 'v1', x}) {
-    print(named);
-  }
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-""",
-            const [
-                r"""
-  instance.foo();
-""",
-                r"""
-  instance.foo(named: 'v2');
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test than named arguments can be called.
-
-class C {
-  foo({a, named: 'v2', x}) {
-    print(named);
-  }
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-""",
-            const [
-                r"""
-  instance.foo(named: 'v1');
-""",
-                r"""
-  instance.foo();
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['instance is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that an instance tear-off with named parameters can be called.
-
-class C {
-  foo({a, named: 'v1', x}) {
-    print(named);
-  }
-}
-
-var closure;
-
-main() {
-  if (closure == null) {
-    print('closure is null');
-    closure = new C().foo;
-  }
-""",
-            const [
-                r"""
-  closure();
-""",
-                r"""
-  closure(named: 'v2');
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['closure is null', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that a lazy static is supported.
-
-var normal;
-
-""",
-            const [
-                r"""
-foo() {
-  print(normal);
-}
-""",
-                r"""
-var lazy = bar();
-
-foo() {
-  print(lazy);
-}
-
-bar() {
-  print('v2');
-  return 'lazy';
-}
-
-""",
-            ],
-            r"""
-main() {
-  if (normal == null) {
-    normal = 'v1';
-  } else {
-    normal = '';
-  }
-  foo();
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2', 'lazy']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that superclasses of directly instantiated classes are also emitted.
-class A {
-}
-
-class B extends A {
-}
-
-main() {
-""",
-            const [
-                r"""
-  print('v1');
-""",
-                r"""
-  new B();
-  print('v2');
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that interceptor classes are handled correctly.
-
-main() {
-""",
-            const [
-                r"""
-  print('v1');
-""",
-                r"""
-  ['v2'].forEach(print);
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that newly instantiated superclasses are handled correctly when there
-// is more than one change.
-
-class A {
-  foo() {
-    print('Called foo');
-  }
-
-  bar() {
-    print('Called bar');
-  }
-}
-
-class B extends A {
-}
-
-main() {
-""",
-            const [
-                r"""
-  new B().foo();
-""",
-                r"""
-  new B().foo();
-""",
-            r"""
-  new A().bar();
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['Called foo']),
-            const ProgramExpectation(
-                const <String>['Called foo']),
-            const ProgramExpectation(
-                const <String>['Called bar']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that newly instantiated subclasses are handled correctly when there is
-// more than one change.
-
-class A {
-  foo() {
-    print('Called foo');
-  }
-
-  bar() {
-    print('Called bar');
-  }
-}
-
-class B extends A {
-}
-
-main() {
-""",
-            const [
-                r"""
-  new A().foo();
-""",
-                r"""
-  new A().foo();
-""",
-            r"""
-  new B().bar();
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['Called foo']),
-            const ProgramExpectation(
-                const <String>['Called foo']),
-            const ProgramExpectation(
-                const <String>['Called bar']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that constants are handled correctly.
-
-class C {
-  final String value;
-  const C(this.value);
-}
-
-main() {
-""",
-            const [
-                r"""
-  print(const C('v1').value);
-""",
-                r"""
-  print(const C('v2').value);
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['v1']),
-            const ProgramExpectation(
-                const <String>['v2']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that an instance field can be added to a compound declaration.
-
-class C {
-""",
-            const [
-                r"""
-  int x;
-""",
-                r"""
-  int x, y;
-""",
-            ],
-                r"""
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('[instance] is null');
-    instance = new C();
-    instance.x = 'v1';
-  } else {
-    instance.y = 'v2';
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('[instance.x] threw');
-  }
-  try {
-    print(instance.y);
-  } catch (e) {
-    print('[instance.y] threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>[
-                    '[instance] is null', 'v1', '[instance.y] threw']),
-            const ProgramExpectation(
-                const <String>['v1', 'v2'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that an instance field can be removed from a compound declaration.
-
-class C {
-""",
-            const [
-                r"""
-  int x, y;
-""",
-                r"""
-  int x;
-""",
-            ],
-                r"""
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('[instance] is null');
-    instance = new C();
-    instance.x = 'v1';
-    instance.y = 'v2';
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('[instance.x] threw');
-  }
-  try {
-    print(instance.y);
-  } catch (e) {
-    print('[instance.y] threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['[instance] is null', 'v1', 'v2']),
-            const ProgramExpectation(
-                const <String>['v1', '[instance.y] threw'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that a static field can be made an instance field.
-
-class C {
-""",
-
-            const [
-                r"""
-  static int x;
-""",
-                r"""
-  int x;
-""",
-            ],
-                r"""
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('[instance] is null');
-    instance = new C();
-    C.x = 'v1';
-  } else {
-    instance.x = 'v2';
-  }
-  try {
-    print(C.x);
-  } catch (e) {
-    print('[C.x] threw');
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('[instance.x] threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['[instance] is null', 'v1', '[instance.x] threw']),
-            const ProgramExpectation(
-                const <String>['[C.x] threw', 'v2'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test that instance field can be made static.
-
-class C {
-""",
-            const [
-                r"""
-  int x;
-""",
-                r"""
-  static int x;
-""",
-            ],
-            r"""
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('[instance] is null');
-    instance = new C();
-    instance.x = 'v1';
-  } else {
-    C.x = 'v2';
-  }
-  try {
-    print(C.x);
-  } catch (e) {
-    print('[C.x] threw');
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('[instance.x] threw');
-  }
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['[instance] is null', '[C.x] threw', 'v1']),
-            const ProgramExpectation(
-                const <String>['v2', '[instance.x] threw'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test compound constants.
-
-class A {
-  final value;
-  const A(this.value);
-
-  toString() => 'A($value)';
-}
-
-class B {
-  final value;
-  const B(this.value);
-
-  toString() => 'B($value)';
-}
-
-main() {
-""",
-            const [
-                r"""
-  print(const A('v1'));
-  print(const B('v1'));
-""",
-                r"""
-  print(const B(const A('v2')));
-  print(const A(const B('v2')));
-""",
-            ],
-            r"""
-}
-""",
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['A(v1)', 'B(v1)']),
-            const ProgramExpectation(
-                const <String>['B(A(v2))', 'A(B(v2))']),
-        ]),
-
-    const EncodedResult(
-        const [
-            r"""
-// Test constants of new classes.
-
-class A {
-  final value;
-  const A(this.value);
-
-  toString() => 'A($value)';
-}
-""",
-            const [
-                "",
-                r"""
-class B {
-  final value;
-  const B(this.value);
-
-  toString() => 'B($value)';
-}
-
-""",
-            ],
-            r"""
-main() {
-""",
-
-            const [
-                r"""
-  print(const A('v1'));
-""",
-                r"""
-  print(const A('v2'));
-  print(const B('v2'));
-  print(const B(const A('v2')));
-  print(const A(const B('v2')));
-""",
-            ],
-            r"""
-}
-""",
-
-        ],
-        const <ProgramExpectation>[
-            const ProgramExpectation(
-                const <String>['A(v1)']),
-            const ProgramExpectation(
-                const <String>['A(v2)', 'B(v2)', 'B(A(v2))', 'A(B(v2))']),
-        ]),
-
-    const EncodedResult(
-        r"""
-==> main.dart <==
-// Test that a change in a part is handled.
-library test.main;
-
-part 'part.dart';
-
-
-==> part.dart.patch <==
-part of test.main;
-
-main() {
-<<<<<<<
-  print('Hello, World!');
-=======
-  print('Hello, Brave New World!');
->>>>>>>
-}
-""",
-        const [
-            'Hello, World!',
-            'Hello, Brave New World!',
-        ]),
-
-    const EncodedResult(
-        r"""
-==> main.dart.patch <==
-// Test that a change in library name is handled.
-<<<<<<<
-library test.main1;
-=======
-library test.main2;
->>>>>>>
-
-main() {
-  print('Hello, World!');
-}
-""",
-        const [
-            'Hello, World!',
-            const ProgramExpectation(
-                const <String>['Hello, World!'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        r"""
-==> main.dart.patch <==
-// Test that adding an import is handled.
-<<<<<<<
-=======
-import 'dart:core';
->>>>>>>
-
-main() {
-  print('Hello, World!');
-}
-""",
-        const [
-            'Hello, World!',
-            const ProgramExpectation(
-                const <String>['Hello, World!'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        r"""
-==> main.dart.patch <==
-// Test that adding an export is handled.
-<<<<<<<
-=======
-export 'dart:core';
->>>>>>>
-
-main() {
-  print('Hello, World!');
-}
-""",
-        const [
-            'Hello, World!',
-            const ProgramExpectation(
-                const <String>['Hello, World!'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        r"""
-==> main.dart.patch <==
-// Test that adding a part is handled.
-library test.main;
-
-<<<<<<<
-=======
-part 'part.dart';
->>>>>>>
-
-main() {
-  print('Hello, World!');
-}
-
-
-==> part.dart <==
-part of test.main
-""",
-        const [
-            'Hello, World!',
-            const ProgramExpectation(
-                const <String>['Hello, World!'],
-                // TODO(ahe): Shouldn't throw.
-                compileUpdatesShouldThrow: true),
-        ]),
-
-    const EncodedResult(
-        r"""
-==> main.dart <==
-// Test that changes in multiple libraries is handled.
-import 'library1.dart' as lib1;
-import 'library2.dart' as lib2;
-
-main() {
-  lib1.method();
-  lib2.method();
-}
-
-
-==> library1.dart.patch <==
-library test.library1;
-
-method() {
-<<<<<<<
-  print('lib1.v1');
-=======
-  print('lib1.v2');
-=======
-  print('lib1.v3');
->>>>>>>
-}
-
-
-==> library2.dart.patch <==
-library test.library2;
-
-method() {
-<<<<<<<
-  print('lib2.v1');
-=======
-  print('lib2.v2');
-=======
-  print('lib2.v3');
->>>>>>>
-}
-""",
-        const [
-            const <String>['lib1.v1', 'lib2.v1'],
-            const <String>['lib1.v2', 'lib2.v2'],
-            const <String>['lib1.v3', 'lib2.v3'],
-        ]),
-];
-
-void main() {
-  listener.start();
-
-  document.head.append(lineNumberStyle());
-
-  summary = new SpanElement();
-  document.body.append(new HeadingElement.h1()
-      ..appendText("Incremental compiler tests")
-      ..append(summary));
-
-  String query = window.location.search;
-  int skip = 0;
-  if (query != null && query.length > 1) {
-    query = query.substring(1);
-    String skipParameter = Uri.splitQueryString(window.location.search)['skip'];
-    if (skipParameter != null) {
-      skip = int.parse(skipParameter);
-    }
-    String verboseParameter =
-        Uri.splitQueryString(window.location.search)['verbose'];
-    verboseStatus = verboseParameter != null;
-  }
-  testCount += skip;
-
-  return asyncTest(() => Future.forEach(tests.skip(skip), compileAndRun)
-      .then(updateSummary));
-}
-
-SpanElement summary;
-
-int testCount = 1;
-
-bool verboseStatus = false;
-
-void updateSummary(_) {
-  summary.text = " (${testCount - 1}/${tests.length})";
-}
-
-Future compileAndRun(EncodedResult encodedResult) {
-  updateSummary(null);
-  List<ProgramResult> programs = encodedResult.decode();
-  var status = new DivElement();
-  document.body.append(status);
-
-  IFrameElement iframe =
-      appendIFrame(
-          '/root_dart/tests/try/web/incremental_compilation_update.html',
-          document.body)
-          ..style.width = '100%'
-          ..style.height = '600px';
-
-  return listener.expect('iframe-ready').then((_) {
-    ProgramResult program = programs.first;
-
-    status.append(
-        new HeadingElement.h2()
-            ..appendText("Full program #${testCount++}:"));
-    status.append(numberedLines(program.code));
-
-    status.style.color = 'orange';
-    WebCompilerTestCase test = new WebCompilerTestCase(program.code);
-    return test.run().then((String jsCode) {
-      status.style.color = 'red';
-      var objectUrl =
-          Url.createObjectUrl(new Blob([jsCode], 'application/javascript'));
-
-      iframe.contentWindow.postMessage(['add-script', objectUrl], '*');
-      Future future =
-          listener.expect(program.messagesWith('iframe-dart-main-done'));
-      return future.then((_) {
-        int version = 2;
-        return Future.forEach(programs.skip(1), (ProgramResult program) {
-
-          status.append(new HeadingElement.h2()..appendText("Update:"));
-          status.append(numberedLines(program.code));
-
-          WebInputProvider inputProvider =
-              test.incrementalCompiler.inputProvider;
-          Uri base = test.scriptUri;
-          Map<String, String> code = program.code is String
-              ? { 'main.dart': program.code }
-              : program.code;
-          Map<Uri, Uri> uriMap = <Uri, Uri>{};
-          for (String name in code.keys) {
-            Uri uri = base.resolve('$name?v${version++}');
-            inputProvider.cachedSources[uri] = new Future.value(code[name]);
-            uriMap[base.resolve(name)] = uri;
-          }
-          Future future = test.incrementalCompiler.compileUpdates(
-              uriMap, logVerbose: logger, logTime: logger);
-          bool compileUpdatesThrew = false;
-          future = future.catchError((error, trace) {
-            String statusMessage;
-            Future result;
-            compileUpdatesThrew = true;
-            if (program.compileUpdatesShouldThrow &&
-                error is IncrementalCompilationFailed) {
-              statusMessage = "Expected error in compileUpdates.";
-              result = null;
-            } else {
-              statusMessage = "Unexpected error in compileUpdates.";
-              result = new Future.error(error, trace);
-            }
-            status.append(new HeadingElement.h3()..appendText(statusMessage));
-            return result;
-          });
-          return future.then((String update) {
-            if (program.compileUpdatesShouldThrow) {
-              Expect.isTrue(
-                  compileUpdatesThrew,
-                  "Expected an exception in compileUpdates");
-              Expect.isNull( update, "Expected update == null");
-              return null;
-            }
-            print({'update': update});
-            iframe.contentWindow.postMessage(['apply-update', update], '*');
-
-            return listener.expect(
-                program.messagesWith('iframe-dart-updated-main-done'))
-                .then((_) {
-                  // TODO(ahe): Enable SerializeScopeTestCase for multiple
-                  // parts.
-                  if (program.code is! String) return null;
-                  return new SerializeScopeTestCase(
-                      program.code, test.incrementalCompiler.mainApp,
-                      test.incrementalCompiler.compiler).run();
-                });
-          });
-        });
-      });
-    });
-  }).then((_) {
-    status.style.color = 'limegreen';
-
-    // Remove the iframe and status to work around a bug in test.dart
-    // (https://code.google.com/p/dart/issues/detail?id=21691).
-    if (!verboseStatus) status.remove();
-    iframe.remove();
-  });
-}
-
-class SerializeScopeTestCase extends CompilerTestCase {
-  final String scopeInfo;
-
-  SerializeScopeTestCase(
-      String source,
-      LibraryElement library,
-      Compiler compiler)
-      : scopeInfo = computeScopeInfo(compiler, library),
-        super(source, '${library.canonicalUri}');
-
-  Future run() => loadMainApp().then(checkScopes);
-
-  void checkScopes(LibraryElement library) {
-    Expect.stringEquals(computeScopeInfo(compiler, library), scopeInfo);
-  }
-
-  static String computeScopeInfo(Compiler compiler, LibraryElement library) {
-    ScopeInformationVisitor visitor =
-        new ScopeInformationVisitor(compiler, library, 0);
-
-    visitor.ignoreImports = true;
-    visitor.sortMembers = true;
-    visitor.indented.write('[\n');
-    visitor.indentationLevel++;
-    visitor.indented;
-    library.accept(visitor);
-    library.forEachLocalMember((Element member) {
-      if (member.isClass) {
-        visitor.buffer.write(',\n');
-        visitor.indented;
-        member.accept(visitor);
-      }
-    });
-    visitor.buffer.write('\n');
-    visitor.indentationLevel--;
-    visitor.indented.write(']');
-    return '${visitor.buffer}';
-  }
-}
-
-void logger(x) {
-  print(x);
-  bool isCheckedMode = false;
-  assert(isCheckedMode = true);
-  int timeout = isCheckedMode ? TIMEOUT * 2 : TIMEOUT;
-  if (listener.elapsed > timeout) {
-    throw 'Test timed out.';
-  }
-}
-
-DivElement numberedLines(code) {
-  if (code is! Map) {
-    code = {'main.dart': code};
-  }
-  DivElement result = new DivElement();
-  code.forEach((String fileName, String code) {
-    result.append(new HeadingElement.h4()..appendText(fileName));
-    DivElement lines = new DivElement();
-    result.append(lines);
-    lines.classes.add("output");
-
-    for (String text in splitLines(code)) {
-      PreElement line = new PreElement()
-          ..appendText(text.trimRight())
-          ..classes.add("line");
-      lines.append(line);
-    }
-  });
-  return result;
-}
-
-StyleElement lineNumberStyle() {
-  StyleElement style = new StyleElement()..appendText('''
-h2, h3, h4 {
-  color: black;
-}
-
-.output {
-  padding: 0px;
-  counter-reset: line-number;
-  padding-bottom: 1em;
-}
-
-.line {
-  white-space: pre-wrap;
-  padding-left: 3.5em;
-  margin-top: 0;
-  margin-bottom: 0;
-}
-
-.line::before {
-  counter-increment: line-number;
-  content: counter(line-number) " ";
-  position: absolute;
-  left: 0px;
-  width: 3em;
-  text-align: right;
-  background-color: lightgoldenrodyellow;
-}
-''');
-  style.type = 'text/css';
-  return style;
-}
diff --git a/tests/try/web/internal_error_test.dart b/tests/try/web/internal_error_test.dart
deleted file mode 100644
index 05f447c..0000000
--- a/tests/try/web/internal_error_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.
-
-library trydart.internal_error_test;
-
-import 'dart:html';
-import 'dart:async';
-
-import 'package:try/src/interaction_manager.dart' show
-    InteractionManager,
-    TRY_DART_NEW_DEFECT;
-
-import 'package:try/src/ui.dart' show
-    mainEditorPane,
-    observer,
-    outputDiv;
-
-import 'package:try/src/user_option.dart' show
-    UserOption;
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-
-main() {
-  UserOption.storage = {};
-
-  var interaction = new InteractionManager();
-  mainEditorPane = new DivElement();
-  outputDiv = new PreElement();
-  document.body.append(mainEditorPane);
-  observer = new MutationObserver((mutations, observer) {
-    try {
-      interaction.onMutation(mutations, observer);
-    } catch (e) {
-      // Ignored.
-    }
-  });
-  observer.observe(
-      mainEditorPane, childList: true, characterData: true, subtree: true);
-
-  mainEditorPane.innerHtml = 'main() { print("hello"); }';
-
-  interaction.currentCompilationUnit = null; // This will provoke a crash.
-
-  asyncTest(() {
-    return new Future(() {
-      Expect.isTrue(outputDiv.text.contains(TRY_DART_NEW_DEFECT));
-    });
-  });
-}
diff --git a/tests/try/web/mock_try.dart b/tests/try/web/mock_try.dart
deleted file mode 100644
index 745bb71..0000000
--- a/tests/try/web/mock_try.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html' show
-    DivElement,
-    MutationObserver,
-    document;
-
-import 'package:try/src/interaction_manager.dart' show
-    InteractionManager;
-
-import 'package:try/src/ui.dart' show
-    hackDiv,
-    mainEditorPane,
-    observer;
-
-import 'package:try/src/user_option.dart' show
-    UserOption;
-
-InteractionManager mockTryDartInteraction() {
-  UserOption.storage = {};
-
-  InteractionManager interaction = new InteractionManager();
-
-  hackDiv = new DivElement();
-  mainEditorPane = new DivElement()
-      ..style.whiteSpace = 'pre'
-      ..contentEditable = 'true';
-
-  observer = new MutationObserver(interaction.onMutation);
-  observer.observe(
-      mainEditorPane, childList: true, characterData: true, subtree: true);
-
-  document.body.nodes.addAll([mainEditorPane, hackDiv]);
-
-  return interaction;
-}
-
-void clearEditorPaneWithoutNotifications() {
-  mainEditorPane.nodes.clear();
-  observer.takeRecords();
-}
diff --git a/tests/try/web/paste_content_rewriting_test.dart b/tests/try/web/paste_content_rewriting_test.dart
deleted file mode 100644
index 20e0159..0000000
--- a/tests/try/web/paste_content_rewriting_test.dart
+++ /dev/null
@@ -1,89 +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 trydart.paste_test;
-
-import 'dart:html';
-import 'dart:async';
-
-import 'package:try/src/interaction_manager.dart' show
-    InteractionManager;
-
-import 'package:try/src/ui.dart' show
-    mainEditorPane,
-    observer;
-
-import 'package:try/src/user_option.dart' show
-    UserOption;
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-
-const Map<String, String> tests = const <String, String> {
-  '<span><p>//...</p>}</span>': '//...\n}',
-  'someText': 'someText',
-  '"\$"': '"<DIAGNOSTIC>\$</DIAGNOSTIC>"',
-  '"\$\$"': '"<DIAGNOSTIC>\$</DIAGNOSTIC><DIAGNOSTIC>\$</DIAGNOSTIC>"',
-  '"\$\$4"': '"<DIAGNOSTIC>\$</DIAGNOSTIC><DIAGNOSTIC>\$</DIAGNOSTIC>4"',
-  '"\$\$4 "': '"<DIAGNOSTIC>\$</DIAGNOSTIC><DIAGNOSTIC>\$</DIAGNOSTIC>4 "',
-  '1e': '<DIAGNOSTIC>1e</DIAGNOSTIC>',
-  'r"""\n\n\'"""': 'r"""\n\n\'"""',
-  '"': '<DIAGNOSTIC>"</DIAGNOSTIC>',
-  '/**\n*/': '/**\n*/',
-
-  // The following case tests that single line strings can span multiple lines
-  // via ${}. The string is constructed so that it is possible to tell if the
-  // line-bases scanner (incorrectly) reverses the order of the string quotes
-  // in its state string. The example string is a complicated way of writing:
-  // '[[{{}: {}}]]'. See also
-  // tests/language/string_interpolation_newline_test.dart.
-  '"\${ [ "\${ [ \'\${ { \'\${\n{\n} }\' : {\n} } }\' ] }" ] }"':
-  '"\${ [ "\${ [ \'\${ { \'\${\n{\n} }\' : {\n} } }\' ] }" ] }"',
-};
-
-List<Node> queryDiagnosticNodes() {
-  return mainEditorPane.querySelectorAll('a.diagnostic>span');
-}
-
-Future runTests() {
-  Iterator<String> keys = tests.keys.iterator;
-  keys.moveNext();
-  mainEditorPane.innerHtml = keys.current;
-
-  Future makeFuture() => new Future(() {
-    String key = keys.current;
-    print('Checking $key');
-    queryDiagnosticNodes().forEach((Node node) {
-      node.parent.append(new Text('</DIAGNOSTIC>'));
-      node.replaceWith(new Text('<DIAGNOSTIC>'));
-      observer.takeRecords(); // Discard mutations.
-    });
-    Expect.stringEquals(tests[key], mainEditorPane.text);
-    if (keys.moveNext()) {
-      key = keys.current;
-      print('Setting $key');
-      mainEditorPane.innerHtml = key;
-      return makeFuture();
-    } else {
-      // Clear the DOM to work around a bug in test.dart.
-      document.body.nodes.clear();
-      return null;
-    }
-  });
-
-  return makeFuture();
-}
-
-void main() {
-  UserOption.storage = {};
-
-  var interaction = new InteractionManager();
-  mainEditorPane = new DivElement();
-  document.body.append(mainEditorPane);
-  observer = new MutationObserver(interaction.onMutation)
-      ..observe(
-          mainEditorPane, childList: true, characterData: true, subtree: true);
-
-  asyncTest(runTests);
-}
diff --git a/tests/try/web/print.js b/tests/try/web/print.js
deleted file mode 100644
index 8f2bd5b..0000000
--- a/tests/try/web/print.js
+++ /dev/null
@@ -1,10 +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.
-
-/// Unless overridden by a Zone, [print] in dart:core will call this function
-/// if defined.
-function dartPrint(message) {
-  console.log(message);
-  window.parent.postMessage(message, '*');
-}
diff --git a/tests/try/web/program_result.dart b/tests/try/web/program_result.dart
deleted file mode 100644
index b8f86cb..0000000
--- a/tests/try/web/program_result.dart
+++ /dev/null
@@ -1,144 +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 trydart.test.program_result;
-
-import 'dart:convert' show
-    JSON;
-
-import '../poi/source_update.dart';
-
-class ProgramResult {
-  final /* Map<String, String> or String */ code;
-
-  final List<String> messages;
-
-  final bool compileUpdatesShouldThrow;
-
-  const ProgramResult(
-      this.code, this.messages, {this.compileUpdatesShouldThrow: false});
-
-  List<String> messagesWith(String extra) {
-    return new List<String>.from(messages)..add(extra);
-  }
-
-  String toString() {
-    return """
-ProgramResult(
-    ${JSON.encode(code)},
-    ${JSON.encode(messages)},
-    compileUpdatesShouldThrow: $compileUpdatesShouldThrow)""";
-  }
-}
-
-class ProgramExpectation {
-  final List<String> messages;
-
-  final bool compileUpdatesShouldThrow;
-
-  const ProgramExpectation(
-      this.messages, {this.compileUpdatesShouldThrow: false});
-
-  ProgramResult toResult(String code) {
-    return new ProgramResult(
-        code, messages, compileUpdatesShouldThrow: compileUpdatesShouldThrow);
-  }
-}
-
-class EncodedResult {
-  final /* String or List */ updates;
-
-  final List expectations;
-
-  const EncodedResult(this.updates, this.expectations);
-
-  List<ProgramResult> decode() {
-    if (updates is List) {
-      if (updates.length == 1) {
-        throw new StateError("Trivial diff, no reason to use decode.");
-      }
-      List<String> sources = expandUpdates(updates);
-      if (sources.length != expectations.length) {
-        throw new StateError(
-            "Number of sources and expectations differ"
-            " (${sources.length} sources,"
-            " ${expectations.length} expectations).");
-      }
-      List<ProgramResult> result = new List<ProgramResult>(sources.length);
-      for (int i = 0; i < sources.length; i++) {
-        result[i] = expectations[i].toResult(sources[i]);
-      }
-      return result;
-    } else if (updates is String) {
-      Map<String, String> files = splitFiles(updates);
-      Map<String, List<String>> fileMap = <String, List<String>>{};
-      int updateCount = -1;
-      for (String name in files.keys) {
-        if (name.endsWith(".patch")) {
-          String realname = name.substring(0, name.length - ".patch".length);
-          if (files.containsKey(realname)) {
-            throw new StateError("Patch '$name' conflicts with '$realname'");
-          }
-          if (fileMap.containsKey(realname)) {
-            // Can't happen.
-            throw new StateError("Duplicated entry for '$realname'.");
-          }
-          List<String> updates = expandUpdates(expandDiff(files[name]));
-          if (updates.length == 1) {
-            throw new StateError("No patches found in:\n ${files[name]}");
-          }
-          if (updateCount == -1) {
-            updateCount = updates.length;
-          } else if (updateCount != updates.length) {
-            throw new StateError(
-                "Unexpected number of patches: ${updates.length},"
-                " expected ${updateCount}");
-          }
-          fileMap[realname] = updates;
-        }
-      }
-      if (updateCount == -1) {
-        throw new StateError("No patch files in $updates");
-      }
-      for (String name in files.keys) {
-        if (!name.endsWith(".patch")) {
-          fileMap[name] = new List<String>.filled(updateCount, files[name]);
-        }
-      }
-      if (updateCount != expectations.length) {
-        throw new StateError(
-            "Number of patches and expectations differ "
-            "(${updateCount} patches, ${expectations.length} expectations).");
-      }
-      List<ProgramResult> result = new List<ProgramResult>(updateCount);
-      for (int i = 0; i < updateCount; i++) {
-        ProgramExpectation expectation = decodeExpectation(expectations[i]);
-        result[i] = new ProgramResult(
-            <String, String>{},
-            expectation.messages,
-            compileUpdatesShouldThrow: expectation.compileUpdatesShouldThrow);
-      }
-      for (String name in fileMap.keys) {
-        for (int i = 0; i < updateCount; i++) {
-          result[i].code[name] = fileMap[name][i];
-        }
-      }
-      return result;
-    } else {
-      throw new StateError("Unknown encoding of updates");
-    }
-  }
-}
-
-ProgramExpectation decodeExpectation(expectation) {
-  if (expectation is ProgramExpectation) {
-    return expectation;
-  } else if (expectation is String) {
-    return new ProgramExpectation(<String>[expectation]);
-  } else if (expectation is List) {
-    return new ProgramExpectation(new List<String>.from(expectation));
-  } else {
-    throw new ArgumentError("Don't know how to decode $expectation");
-  }
-}
diff --git a/tests/try/web/sandbox.dart b/tests/try/web/sandbox.dart
deleted file mode 100644
index 61a7583..0000000
--- a/tests/try/web/sandbox.dart
+++ /dev/null
@@ -1,128 +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.
-
-/// Helper library that creates an iframe sandbox that can be used to load
-/// code.
-library trydart.test.sandbox;
-
-import 'dart:html';
-import 'dart:async';
-
-// TODO(ahe): Remove this import if issue 17936 is fixed.
-import 'dart:js' as hack;
-
-import 'package:expect/expect.dart' show
-    Expect;
-
-final Listener listener = new Listener();
-
-void onError(String message, String filename, int lineno, [int colno, error]) {
-  if (filename != null && filename != "" && lineno != 0) {
-    if (colno != null && colno != 0) {
-      message = '$filename:$lineno:$colno $message';
-    } else {
-      message = '$filename:$lineno: $message';
-    }
-  }
-  if (error != null) {
-    // See:
-    // https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
-    var stack = error['stack'];
-    if (stack != null) {
-      message += '\n$stack';
-    }
-  }
-  message = "Error occurred in iframe: $message";
-
-  // Synchronous, easier to read when running the browser manually.
-  window.console.log(message);
-
-  new Future(() {
-    // Browsers ignore errors throw in event listeners (or from
-    // window.onerror).
-    throw message;
-  });
-}
-
-void installErrorHandlerOn(IFrameElement iframe) {
-  // This method uses dart:js to install an error event handler on the content
-  // window of [iframe]. This is a workaround for http://dartbug.com/17936.
-  var iframeProxy = new hack.JsObject.fromBrowserObject(iframe);
-  var contentWindowProxy = iframeProxy['contentWindow'];
-  if (contentWindowProxy == null) {
-    print('No contentWindow in iframe');
-    throw 'No contentWindow in iframe';
-  }
-
-  // Note: we have two options, use "iframe.contentWindow.onerror = ..." or
-  // "iframe.contentWindow.addEventListener('error', ...)".  The former seems
-  // to provide more details on both Chrome and Firefox (which provides no
-  // information at all in error events).
-  contentWindowProxy['onerror'] = onError;
-}
-
-void onIframeLoaded(Event event) {
-  installErrorHandlerOn(event.target);
-}
-
-IFrameElement appendIFrame(String src, Element element) {
-  IFrameElement iframe = new IFrameElement()
-      ..src = src
-      ..onLoad.listen(onIframeLoaded);
-  element.append(iframe);
-  // Install an error handler both on the new iframe element, and when it has
-  // fired the load event.  That seems to matter according to some sources on
-  // stackoverflow.
-  installErrorHandlerOn(iframe);
-  return iframe;
-}
-
-class Listener {
-  Completer completer;
-
-  String expectedMessage;
-
-  Stopwatch wallclock;
-
-  int get elapsed => wallclock.elapsedMilliseconds ~/ 1000;
-
-  void onMessage(MessageEvent e) {
-    String message = e.data;
-    if (expectedMessage == message) {
-      completer.complete();
-    } else {
-      switch (message) {
-        case 'dart-calling-main':
-        case 'dart-main-done':
-        case 'unittest-suite-done':
-        case 'unittest-suite-fail':
-        case 'unittest-suite-success':
-        case 'unittest-suite-wait-for-done':
-          break;
-
-        default:
-          completer.completeError(
-              'Unexpected message: "$message" (expected "$expectedMessage").');
-      }
-    }
-  }
-
-  Future expect(data) {
-    if (data is String) {
-      Expect.isTrue(completer == null || completer.isCompleted);
-      expectedMessage = data;
-      completer = new Completer();
-      return completer.future;
-    } else if (data is Iterable) {
-      return Future.forEach(data, expect);
-    } else {
-      throw 'Unexpected data type: ${data.runtimeType}.';
-    }
-  }
-
-  void start() {
-    wallclock = new Stopwatch()..start();
-    window.onMessage.listen(onMessage);
-  }
-}
diff --git a/tests/try/web/source_update_test.dart b/tests/try/web/source_update_test.dart
deleted file mode 100644
index b40159a..0000000
--- a/tests/try/web/source_update_test.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.
-
-import 'test_try.dart';
-
-InteractionContext interaction;
-
-void main() {
-  interaction = mockTryDartInteraction();
-
-  runTests(<TestCase>[
-
-    new TestCase('Test setting full source', () {
-      clearEditorPaneWithoutNotifications();
-      mainEditorPane.appendText('Foo\nBar');
-    }, () {
-      expectSource('Foo\nBar');
-    }),
-
-    new TestCase('Test modifying a single line', () {
-      Element lastLine = mainEditorPane.lastChild;
-      lastLine.appendText('Baz');
-    }, () {
-      expectSource('Foo\nBarBaz');
-    }),
-
-  ]);
-}
-
-void expectSource(String expected) {
-  String actualSource = interaction.currentCompilationUnit.content;
-  Expect.stringEquals(expected, actualSource);
-}
diff --git a/tests/try/web/test_case.dart b/tests/try/web/test_case.dart
deleted file mode 100644
index 56e1157..0000000
--- a/tests/try/web/test_case.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library trydart.test_case;
-
-import 'dart:html' show
-    document;
-
-import 'dart:async';
-
-import 'package:async_helper/async_helper.dart';
-
-typedef void VoidFunction();
-
-class TestCase {
-  final String description;
-  final VoidFunction setup;
-  final VoidFunction validate;
-
-  TestCase(this.description, this.setup, this.validate);
-}
-
-/**
- * Executes [tests] each test in order using the following approach for each
- * test:
- *
- *   1. Run setup synchronously.
- *
- *   2. Schedule a new (async) Future which runs validate followed by the next
- *   test's setup.
- *
- *   3. Repeat step 2 until there are no more tests.
- *
- * The purpose of this test is to simulate edits (during setup), and then let
- * the mutation observer to process the mutations followed by validation.
- */
-void runTests(List<TestCase> tests) {
-  Completer completer = new Completer();
-  asyncTest(() => completer.future.then((_) {
-    // Clear the DOM to work around a bug in test.dart.
-    document.body.nodes.clear();
-  }));
-
-  void iterateTests(Iterator<TestCase> iterator) {
-    if (iterator.moveNext()) {
-      TestCase test = iterator.current;
-      print('${test.description}\nSetup.');
-      test.setup();
-      new Future(() {
-        test.validate();
-        print('${test.description}\nDone.');
-        iterateTests(iterator);
-      });
-    } else {
-      completer.complete(null);
-    }
-  }
-
-  iterateTests(tests.iterator);
-}
diff --git a/tests/try/web/test_try.dart b/tests/try/web/test_try.dart
deleted file mode 100644
index 52b8e84..0000000
--- a/tests/try/web/test_try.dart
+++ /dev/null
@@ -1,20 +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 trydart.test_try;
-
-export 'dart:html';
-
-export 'package:try/src/interaction_manager.dart' show
-    InteractionContext,
-    InteractionManager;
-
-export 'package:try/src/ui.dart' show
-    mainEditorPane;
-
-export 'package:expect/expect.dart';
-
-export 'test_case.dart';
-
-export 'mock_try.dart';
diff --git a/tests/try/web/web_compiler_test_case.dart b/tests/try/web/web_compiler_test_case.dart
deleted file mode 100644
index 8a9b026..0000000
--- a/tests/try/web/web_compiler_test_case.dart
+++ /dev/null
@@ -1,114 +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.
-
-// Helpers for writing compiler tests running in browser.
-library trydart.web_compiler_test_case;
-
-import 'dart:async' show
-    EventSink,
-    Future;
-
-import 'dart:html' show
-    HttpRequest;
-
-import '../poi/compiler_test_case.dart' show
-    customUri,
-    CompilerTestCase;
-
-import 'package:dart2js_incremental/dart2js_incremental.dart' show
-    IncrementalCompiler, OutputProvider;
-
-import 'package:compiler/compiler.dart' show
-    Diagnostic;
-
-const String WEB_SCHEME = 'org.trydart.web';
-
-/// A CompilerTestCase which runs in a browser.
-class WebCompilerTestCase extends CompilerTestCase {
-  final IncrementalCompiler incrementalCompiler;
-
-  WebCompilerTestCase.init(/* Map or String */ source, Uri uri)
-      : this.incrementalCompiler = makeCompiler(source, uri),
-        super.init(null, uri, null);
-
-  WebCompilerTestCase(/* Map or String */ source, [String path])
-      : this.init(source, customUri(path == null ? 'main.dart' : path));
-
-  Future run() {
-    return incrementalCompiler.compile(scriptUri).then((success) {
-      if (!success) throw 'Compilation failed';
-      OutputProvider outputProvider = incrementalCompiler.outputProvider;
-      return outputProvider['.js'];
-    });
-  }
-
-  static IncrementalCompiler makeCompiler(
-      /* Map or String */ source,
-      Uri mainUri) {
-    Uri libraryRoot = new Uri(scheme: WEB_SCHEME, path: '/sdk/');
-    Uri packageRoot = new Uri(scheme: WEB_SCHEME, path: '/packages/');
-
-    Map<Uri, String> sources = <Uri, String>{};
-    if (source is String) {
-      sources[mainUri] = source;
-    } else if (source is Map) {
-      source.forEach((String name, String code) {
-        sources[mainUri.resolve(name)] = code;
-      });
-    } else {
-      throw new ArgumentError("[source] should be a String or a Map");
-    }
-
-    WebInputProvider inputProvider =
-        new WebInputProvider(sources, libraryRoot, packageRoot);
-
-    void diagnosticHandler(
-        Uri uri, int begin, int end, String message, Diagnostic kind) {
-      if (uri == null) {
-        print('[$kind] $message');
-      } else {
-        print('$uri@$begin+${end - begin}: [$kind] $message');
-      }
-    }
-
-    return new IncrementalCompiler(
-        libraryRoot: libraryRoot,
-        packageRoot: packageRoot,
-        inputProvider: inputProvider,
-        diagnosticHandler: diagnosticHandler,
-        outputProvider: new OutputProvider());
-  }
-}
-
-/// An input provider which provides input via [HttpRequest].
-/// Includes one in-memory compilation unit [source] which is returned when
-/// [mainUri] is requested.
-class WebInputProvider {
-  final Map<Uri, String> sources;
-
-  final Uri libraryRoot;
-
-  final Uri packageRoot;
-
-  final Map<Uri, Future> cachedSources = new Map<Uri, Future>();
-
-  static final Map<String, Future> cachedRequests = new Map<String, Future>();
-
-  WebInputProvider(this.sources, this.libraryRoot, this.packageRoot);
-
-  Future call(Uri uri) {
-    return cachedSources.putIfAbsent(uri, () {
-      if (sources.containsKey(uri)) return new Future.value(sources[uri]);
-      if (uri.scheme == WEB_SCHEME) {
-        return cachedHttpRequest('/root_dart${uri.path}');
-      } else {
-        return cachedHttpRequest('$uri');
-      }
-    });
-  }
-
-  static Future cachedHttpRequest(String uri) {
-    return cachedRequests.putIfAbsent(uri, () => HttpRequest.getString(uri));
-  }
-}
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index 608e099..c8becb3 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -1,8 +1,6 @@
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=
-// VMOptions=--print-object-histogram
 
 // Smoke test of the dart2js compiler API.
 library dummy_compiler;
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index b1dc829..e2df361 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -20,3 +20,7 @@
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 dummy_compiler_test: Crash # Issue 24485
 recursive_import_test: Crash # Issue 24485
+
+[ $hot_reload || $hot_reload_rollback ]
+recursive_import_test: Skip # Running dart2js under frequent reloads is slow.
+dummy_compiler_test: Skip # Running dart2js under frequent reloads is slow.
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni
new file mode 100644
index 0000000..d1ac9be
--- /dev/null
+++ b/third_party/boringssl/BUILD.generated.gni
@@ -0,0 +1,458 @@
+# Copyright (c) 2016 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.
+
+# This file is created by generate_build_files.py. Do not edit manually.
+
+crypto_sources = [
+  "err_data.c",
+  "src/crypto/aes/aes.c",
+  "src/crypto/aes/mode_wrappers.c",
+  "src/crypto/asn1/a_bitstr.c",
+  "src/crypto/asn1/a_bool.c",
+  "src/crypto/asn1/a_bytes.c",
+  "src/crypto/asn1/a_d2i_fp.c",
+  "src/crypto/asn1/a_dup.c",
+  "src/crypto/asn1/a_enum.c",
+  "src/crypto/asn1/a_gentm.c",
+  "src/crypto/asn1/a_i2d_fp.c",
+  "src/crypto/asn1/a_int.c",
+  "src/crypto/asn1/a_mbstr.c",
+  "src/crypto/asn1/a_object.c",
+  "src/crypto/asn1/a_octet.c",
+  "src/crypto/asn1/a_print.c",
+  "src/crypto/asn1/a_strnid.c",
+  "src/crypto/asn1/a_time.c",
+  "src/crypto/asn1/a_type.c",
+  "src/crypto/asn1/a_utctm.c",
+  "src/crypto/asn1/a_utf8.c",
+  "src/crypto/asn1/asn1_lib.c",
+  "src/crypto/asn1/asn1_par.c",
+  "src/crypto/asn1/asn_pack.c",
+  "src/crypto/asn1/f_enum.c",
+  "src/crypto/asn1/f_int.c",
+  "src/crypto/asn1/f_string.c",
+  "src/crypto/asn1/t_bitst.c",
+  "src/crypto/asn1/tasn_dec.c",
+  "src/crypto/asn1/tasn_enc.c",
+  "src/crypto/asn1/tasn_fre.c",
+  "src/crypto/asn1/tasn_new.c",
+  "src/crypto/asn1/tasn_typ.c",
+  "src/crypto/asn1/tasn_utl.c",
+  "src/crypto/asn1/x_bignum.c",
+  "src/crypto/asn1/x_long.c",
+  "src/crypto/base64/base64.c",
+  "src/crypto/bio/bio.c",
+  "src/crypto/bio/bio_mem.c",
+  "src/crypto/bio/buffer.c",
+  "src/crypto/bio/connect.c",
+  "src/crypto/bio/fd.c",
+  "src/crypto/bio/file.c",
+  "src/crypto/bio/hexdump.c",
+  "src/crypto/bio/pair.c",
+  "src/crypto/bio/printf.c",
+  "src/crypto/bio/socket.c",
+  "src/crypto/bio/socket_helper.c",
+  "src/crypto/bn/add.c",
+  "src/crypto/bn/asm/x86_64-gcc.c",
+  "src/crypto/bn/bn.c",
+  "src/crypto/bn/bn_asn1.c",
+  "src/crypto/bn/cmp.c",
+  "src/crypto/bn/convert.c",
+  "src/crypto/bn/ctx.c",
+  "src/crypto/bn/div.c",
+  "src/crypto/bn/exponentiation.c",
+  "src/crypto/bn/gcd.c",
+  "src/crypto/bn/generic.c",
+  "src/crypto/bn/kronecker.c",
+  "src/crypto/bn/montgomery.c",
+  "src/crypto/bn/mul.c",
+  "src/crypto/bn/prime.c",
+  "src/crypto/bn/random.c",
+  "src/crypto/bn/rsaz_exp.c",
+  "src/crypto/bn/shift.c",
+  "src/crypto/bn/sqrt.c",
+  "src/crypto/buf/buf.c",
+  "src/crypto/bytestring/asn1_compat.c",
+  "src/crypto/bytestring/ber.c",
+  "src/crypto/bytestring/cbb.c",
+  "src/crypto/bytestring/cbs.c",
+  "src/crypto/chacha/chacha.c",
+  "src/crypto/cipher/aead.c",
+  "src/crypto/cipher/cipher.c",
+  "src/crypto/cipher/derive_key.c",
+  "src/crypto/cipher/e_aes.c",
+  "src/crypto/cipher/e_chacha20poly1305.c",
+  "src/crypto/cipher/e_des.c",
+  "src/crypto/cipher/e_null.c",
+  "src/crypto/cipher/e_rc2.c",
+  "src/crypto/cipher/e_rc4.c",
+  "src/crypto/cipher/e_ssl3.c",
+  "src/crypto/cipher/e_tls.c",
+  "src/crypto/cipher/tls_cbc.c",
+  "src/crypto/cmac/cmac.c",
+  "src/crypto/conf/conf.c",
+  "src/crypto/cpu-aarch64-linux.c",
+  "src/crypto/cpu-arm-linux.c",
+  "src/crypto/cpu-arm.c",
+  "src/crypto/cpu-intel.c",
+  "src/crypto/crypto.c",
+  "src/crypto/curve25519/curve25519.c",
+  "src/crypto/curve25519/spake25519.c",
+  "src/crypto/curve25519/x25519-x86_64.c",
+  "src/crypto/des/des.c",
+  "src/crypto/dh/check.c",
+  "src/crypto/dh/dh.c",
+  "src/crypto/dh/dh_asn1.c",
+  "src/crypto/dh/params.c",
+  "src/crypto/digest/digest.c",
+  "src/crypto/digest/digests.c",
+  "src/crypto/dsa/dsa.c",
+  "src/crypto/dsa/dsa_asn1.c",
+  "src/crypto/ec/ec.c",
+  "src/crypto/ec/ec_asn1.c",
+  "src/crypto/ec/ec_key.c",
+  "src/crypto/ec/ec_montgomery.c",
+  "src/crypto/ec/oct.c",
+  "src/crypto/ec/p224-64.c",
+  "src/crypto/ec/p256-64.c",
+  "src/crypto/ec/p256-x86_64.c",
+  "src/crypto/ec/simple.c",
+  "src/crypto/ec/util-64.c",
+  "src/crypto/ec/wnaf.c",
+  "src/crypto/ecdh/ecdh.c",
+  "src/crypto/ecdsa/ecdsa.c",
+  "src/crypto/ecdsa/ecdsa_asn1.c",
+  "src/crypto/engine/engine.c",
+  "src/crypto/err/err.c",
+  "src/crypto/evp/digestsign.c",
+  "src/crypto/evp/evp.c",
+  "src/crypto/evp/evp_asn1.c",
+  "src/crypto/evp/evp_ctx.c",
+  "src/crypto/evp/p_dsa_asn1.c",
+  "src/crypto/evp/p_ec.c",
+  "src/crypto/evp/p_ec_asn1.c",
+  "src/crypto/evp/p_rsa.c",
+  "src/crypto/evp/p_rsa_asn1.c",
+  "src/crypto/evp/pbkdf.c",
+  "src/crypto/evp/print.c",
+  "src/crypto/evp/sign.c",
+  "src/crypto/ex_data.c",
+  "src/crypto/hkdf/hkdf.c",
+  "src/crypto/hmac/hmac.c",
+  "src/crypto/lhash/lhash.c",
+  "src/crypto/md4/md4.c",
+  "src/crypto/md5/md5.c",
+  "src/crypto/mem.c",
+  "src/crypto/modes/cbc.c",
+  "src/crypto/modes/cfb.c",
+  "src/crypto/modes/ctr.c",
+  "src/crypto/modes/gcm.c",
+  "src/crypto/modes/ofb.c",
+  "src/crypto/newhope/error_correction.c",
+  "src/crypto/newhope/newhope.c",
+  "src/crypto/newhope/ntt.c",
+  "src/crypto/newhope/poly.c",
+  "src/crypto/newhope/precomp.c",
+  "src/crypto/newhope/reduce.c",
+  "src/crypto/obj/obj.c",
+  "src/crypto/obj/obj_xref.c",
+  "src/crypto/pem/pem_all.c",
+  "src/crypto/pem/pem_info.c",
+  "src/crypto/pem/pem_lib.c",
+  "src/crypto/pem/pem_oth.c",
+  "src/crypto/pem/pem_pk8.c",
+  "src/crypto/pem/pem_pkey.c",
+  "src/crypto/pem/pem_x509.c",
+  "src/crypto/pem/pem_xaux.c",
+  "src/crypto/pkcs8/p5_pbe.c",
+  "src/crypto/pkcs8/p5_pbev2.c",
+  "src/crypto/pkcs8/p8_pkey.c",
+  "src/crypto/pkcs8/pkcs8.c",
+  "src/crypto/poly1305/poly1305.c",
+  "src/crypto/poly1305/poly1305_arm.c",
+  "src/crypto/poly1305/poly1305_vec.c",
+  "src/crypto/rand/deterministic.c",
+  "src/crypto/rand/rand.c",
+  "src/crypto/rand/urandom.c",
+  "src/crypto/rand/windows.c",
+  "src/crypto/rc4/rc4.c",
+  "src/crypto/refcount_c11.c",
+  "src/crypto/refcount_lock.c",
+  "src/crypto/rsa/blinding.c",
+  "src/crypto/rsa/padding.c",
+  "src/crypto/rsa/rsa.c",
+  "src/crypto/rsa/rsa_asn1.c",
+  "src/crypto/rsa/rsa_impl.c",
+  "src/crypto/sha/sha1.c",
+  "src/crypto/sha/sha256.c",
+  "src/crypto/sha/sha512.c",
+  "src/crypto/stack/stack.c",
+  "src/crypto/thread.c",
+  "src/crypto/thread_none.c",
+  "src/crypto/thread_pthread.c",
+  "src/crypto/thread_win.c",
+  "src/crypto/time_support.c",
+  "src/crypto/x509/a_digest.c",
+  "src/crypto/x509/a_sign.c",
+  "src/crypto/x509/a_strex.c",
+  "src/crypto/x509/a_verify.c",
+  "src/crypto/x509/algorithm.c",
+  "src/crypto/x509/asn1_gen.c",
+  "src/crypto/x509/by_dir.c",
+  "src/crypto/x509/by_file.c",
+  "src/crypto/x509/i2d_pr.c",
+  "src/crypto/x509/pkcs7.c",
+  "src/crypto/x509/rsa_pss.c",
+  "src/crypto/x509/t_crl.c",
+  "src/crypto/x509/t_req.c",
+  "src/crypto/x509/t_x509.c",
+  "src/crypto/x509/t_x509a.c",
+  "src/crypto/x509/x509.c",
+  "src/crypto/x509/x509_att.c",
+  "src/crypto/x509/x509_cmp.c",
+  "src/crypto/x509/x509_d2.c",
+  "src/crypto/x509/x509_def.c",
+  "src/crypto/x509/x509_ext.c",
+  "src/crypto/x509/x509_lu.c",
+  "src/crypto/x509/x509_obj.c",
+  "src/crypto/x509/x509_r2x.c",
+  "src/crypto/x509/x509_req.c",
+  "src/crypto/x509/x509_set.c",
+  "src/crypto/x509/x509_trs.c",
+  "src/crypto/x509/x509_txt.c",
+  "src/crypto/x509/x509_v3.c",
+  "src/crypto/x509/x509_vfy.c",
+  "src/crypto/x509/x509_vpm.c",
+  "src/crypto/x509/x509cset.c",
+  "src/crypto/x509/x509name.c",
+  "src/crypto/x509/x509rset.c",
+  "src/crypto/x509/x509spki.c",
+  "src/crypto/x509/x509type.c",
+  "src/crypto/x509/x_algor.c",
+  "src/crypto/x509/x_all.c",
+  "src/crypto/x509/x_attrib.c",
+  "src/crypto/x509/x_crl.c",
+  "src/crypto/x509/x_exten.c",
+  "src/crypto/x509/x_info.c",
+  "src/crypto/x509/x_name.c",
+  "src/crypto/x509/x_pkey.c",
+  "src/crypto/x509/x_pubkey.c",
+  "src/crypto/x509/x_req.c",
+  "src/crypto/x509/x_sig.c",
+  "src/crypto/x509/x_spki.c",
+  "src/crypto/x509/x_val.c",
+  "src/crypto/x509/x_x509.c",
+  "src/crypto/x509/x_x509a.c",
+  "src/crypto/x509v3/pcy_cache.c",
+  "src/crypto/x509v3/pcy_data.c",
+  "src/crypto/x509v3/pcy_lib.c",
+  "src/crypto/x509v3/pcy_map.c",
+  "src/crypto/x509v3/pcy_node.c",
+  "src/crypto/x509v3/pcy_tree.c",
+  "src/crypto/x509v3/v3_akey.c",
+  "src/crypto/x509v3/v3_akeya.c",
+  "src/crypto/x509v3/v3_alt.c",
+  "src/crypto/x509v3/v3_bcons.c",
+  "src/crypto/x509v3/v3_bitst.c",
+  "src/crypto/x509v3/v3_conf.c",
+  "src/crypto/x509v3/v3_cpols.c",
+  "src/crypto/x509v3/v3_crld.c",
+  "src/crypto/x509v3/v3_enum.c",
+  "src/crypto/x509v3/v3_extku.c",
+  "src/crypto/x509v3/v3_genn.c",
+  "src/crypto/x509v3/v3_ia5.c",
+  "src/crypto/x509v3/v3_info.c",
+  "src/crypto/x509v3/v3_int.c",
+  "src/crypto/x509v3/v3_lib.c",
+  "src/crypto/x509v3/v3_ncons.c",
+  "src/crypto/x509v3/v3_pci.c",
+  "src/crypto/x509v3/v3_pcia.c",
+  "src/crypto/x509v3/v3_pcons.c",
+  "src/crypto/x509v3/v3_pku.c",
+  "src/crypto/x509v3/v3_pmaps.c",
+  "src/crypto/x509v3/v3_prn.c",
+  "src/crypto/x509v3/v3_purp.c",
+  "src/crypto/x509v3/v3_skey.c",
+  "src/crypto/x509v3/v3_sxnet.c",
+  "src/crypto/x509v3/v3_utl.c",
+]
+
+ssl_sources = [
+  "src/ssl/custom_extensions.c",
+  "src/ssl/d1_both.c",
+  "src/ssl/d1_lib.c",
+  "src/ssl/d1_pkt.c",
+  "src/ssl/d1_srtp.c",
+  "src/ssl/dtls_method.c",
+  "src/ssl/dtls_record.c",
+  "src/ssl/handshake_client.c",
+  "src/ssl/handshake_server.c",
+  "src/ssl/s3_both.c",
+  "src/ssl/s3_enc.c",
+  "src/ssl/s3_lib.c",
+  "src/ssl/s3_pkt.c",
+  "src/ssl/ssl_aead_ctx.c",
+  "src/ssl/ssl_asn1.c",
+  "src/ssl/ssl_buffer.c",
+  "src/ssl/ssl_cert.c",
+  "src/ssl/ssl_cipher.c",
+  "src/ssl/ssl_ecdh.c",
+  "src/ssl/ssl_file.c",
+  "src/ssl/ssl_lib.c",
+  "src/ssl/ssl_rsa.c",
+  "src/ssl/ssl_session.c",
+  "src/ssl/ssl_stat.c",
+  "src/ssl/t1_enc.c",
+  "src/ssl/t1_lib.c",
+  "src/ssl/tls_method.c",
+  "src/ssl/tls_record.c",
+]
+
+crypto_sources_linux_aarch64 = [
+  "linux-aarch64/crypto/aes/aesv8-armx64.S",
+  "linux-aarch64/crypto/bn/armv8-mont.S",
+  "linux-aarch64/crypto/chacha/chacha-armv8.S",
+  "linux-aarch64/crypto/modes/ghashv8-armx64.S",
+  "linux-aarch64/crypto/sha/sha1-armv8.S",
+  "linux-aarch64/crypto/sha/sha256-armv8.S",
+  "linux-aarch64/crypto/sha/sha512-armv8.S",
+]
+
+crypto_sources_linux_arm = [
+  "linux-arm/crypto/aes/aes-armv4.S",
+  "linux-arm/crypto/aes/aesv8-armx32.S",
+  "linux-arm/crypto/aes/bsaes-armv7.S",
+  "linux-arm/crypto/bn/armv4-mont.S",
+  "linux-arm/crypto/chacha/chacha-armv4.S",
+  "linux-arm/crypto/modes/ghash-armv4.S",
+  "linux-arm/crypto/modes/ghashv8-armx32.S",
+  "linux-arm/crypto/sha/sha1-armv4-large.S",
+  "linux-arm/crypto/sha/sha256-armv4.S",
+  "linux-arm/crypto/sha/sha512-armv4.S",
+  "src/crypto/curve25519/asm/x25519-asm-arm.S",
+  "src/crypto/poly1305/poly1305_arm_asm.S",
+]
+
+crypto_sources_linux_x86 = [
+  "linux-x86/crypto/aes/aes-586.S",
+  "linux-x86/crypto/aes/aesni-x86.S",
+  "linux-x86/crypto/aes/vpaes-x86.S",
+  "linux-x86/crypto/bn/bn-586.S",
+  "linux-x86/crypto/bn/co-586.S",
+  "linux-x86/crypto/bn/x86-mont.S",
+  "linux-x86/crypto/chacha/chacha-x86.S",
+  "linux-x86/crypto/md5/md5-586.S",
+  "linux-x86/crypto/modes/ghash-x86.S",
+  "linux-x86/crypto/rc4/rc4-586.S",
+  "linux-x86/crypto/sha/sha1-586.S",
+  "linux-x86/crypto/sha/sha256-586.S",
+  "linux-x86/crypto/sha/sha512-586.S",
+]
+
+crypto_sources_linux_x86_64 = [
+  "linux-x86_64/crypto/aes/aes-x86_64.S",
+  "linux-x86_64/crypto/aes/aesni-x86_64.S",
+  "linux-x86_64/crypto/aes/bsaes-x86_64.S",
+  "linux-x86_64/crypto/aes/vpaes-x86_64.S",
+  "linux-x86_64/crypto/bn/rsaz-avx2.S",
+  "linux-x86_64/crypto/bn/rsaz-x86_64.S",
+  "linux-x86_64/crypto/bn/x86_64-mont.S",
+  "linux-x86_64/crypto/bn/x86_64-mont5.S",
+  "linux-x86_64/crypto/chacha/chacha-x86_64.S",
+  "linux-x86_64/crypto/ec/p256-x86_64-asm.S",
+  "linux-x86_64/crypto/md5/md5-x86_64.S",
+  "linux-x86_64/crypto/modes/aesni-gcm-x86_64.S",
+  "linux-x86_64/crypto/modes/ghash-x86_64.S",
+  "linux-x86_64/crypto/rand/rdrand-x86_64.S",
+  "linux-x86_64/crypto/rc4/rc4-x86_64.S",
+  "linux-x86_64/crypto/sha/sha1-x86_64.S",
+  "linux-x86_64/crypto/sha/sha256-x86_64.S",
+  "linux-x86_64/crypto/sha/sha512-x86_64.S",
+  "src/crypto/curve25519/asm/x25519-asm-x86_64.S",
+]
+
+crypto_sources_mac_x86 = [
+  "mac-x86/crypto/aes/aes-586.S",
+  "mac-x86/crypto/aes/aesni-x86.S",
+  "mac-x86/crypto/aes/vpaes-x86.S",
+  "mac-x86/crypto/bn/bn-586.S",
+  "mac-x86/crypto/bn/co-586.S",
+  "mac-x86/crypto/bn/x86-mont.S",
+  "mac-x86/crypto/chacha/chacha-x86.S",
+  "mac-x86/crypto/md5/md5-586.S",
+  "mac-x86/crypto/modes/ghash-x86.S",
+  "mac-x86/crypto/rc4/rc4-586.S",
+  "mac-x86/crypto/sha/sha1-586.S",
+  "mac-x86/crypto/sha/sha256-586.S",
+  "mac-x86/crypto/sha/sha512-586.S",
+]
+
+crypto_sources_mac_x86_64 = [
+  "mac-x86_64/crypto/aes/aes-x86_64.S",
+  "mac-x86_64/crypto/aes/aesni-x86_64.S",
+  "mac-x86_64/crypto/aes/bsaes-x86_64.S",
+  "mac-x86_64/crypto/aes/vpaes-x86_64.S",
+  "mac-x86_64/crypto/bn/rsaz-avx2.S",
+  "mac-x86_64/crypto/bn/rsaz-x86_64.S",
+  "mac-x86_64/crypto/bn/x86_64-mont.S",
+  "mac-x86_64/crypto/bn/x86_64-mont5.S",
+  "mac-x86_64/crypto/chacha/chacha-x86_64.S",
+  "mac-x86_64/crypto/ec/p256-x86_64-asm.S",
+  "mac-x86_64/crypto/md5/md5-x86_64.S",
+  "mac-x86_64/crypto/modes/aesni-gcm-x86_64.S",
+  "mac-x86_64/crypto/modes/ghash-x86_64.S",
+  "mac-x86_64/crypto/rand/rdrand-x86_64.S",
+  "mac-x86_64/crypto/rc4/rc4-x86_64.S",
+  "mac-x86_64/crypto/sha/sha1-x86_64.S",
+  "mac-x86_64/crypto/sha/sha256-x86_64.S",
+  "mac-x86_64/crypto/sha/sha512-x86_64.S",
+  "src/crypto/curve25519/asm/x25519-asm-x86_64.S",
+]
+
+crypto_sources_win_x86 = [
+  "win-x86/crypto/aes/aes-586.asm",
+  "win-x86/crypto/aes/aesni-x86.asm",
+  "win-x86/crypto/aes/vpaes-x86.asm",
+  "win-x86/crypto/bn/bn-586.asm",
+  "win-x86/crypto/bn/co-586.asm",
+  "win-x86/crypto/bn/x86-mont.asm",
+  "win-x86/crypto/chacha/chacha-x86.asm",
+  "win-x86/crypto/md5/md5-586.asm",
+  "win-x86/crypto/modes/ghash-x86.asm",
+  "win-x86/crypto/rc4/rc4-586.asm",
+  "win-x86/crypto/sha/sha1-586.asm",
+  "win-x86/crypto/sha/sha256-586.asm",
+  "win-x86/crypto/sha/sha512-586.asm",
+]
+
+crypto_sources_win_x86_64 = [
+  "win-x86_64/crypto/aes/aes-x86_64.asm",
+  "win-x86_64/crypto/aes/aesni-x86_64.asm",
+  "win-x86_64/crypto/aes/bsaes-x86_64.asm",
+  "win-x86_64/crypto/aes/vpaes-x86_64.asm",
+  "win-x86_64/crypto/bn/rsaz-avx2.asm",
+  "win-x86_64/crypto/bn/rsaz-x86_64.asm",
+  "win-x86_64/crypto/bn/x86_64-mont.asm",
+  "win-x86_64/crypto/bn/x86_64-mont5.asm",
+  "win-x86_64/crypto/chacha/chacha-x86_64.asm",
+  "win-x86_64/crypto/ec/p256-x86_64-asm.asm",
+  "win-x86_64/crypto/md5/md5-x86_64.asm",
+  "win-x86_64/crypto/modes/aesni-gcm-x86_64.asm",
+  "win-x86_64/crypto/modes/ghash-x86_64.asm",
+  "win-x86_64/crypto/rand/rdrand-x86_64.asm",
+  "win-x86_64/crypto/rc4/rc4-x86_64.asm",
+  "win-x86_64/crypto/sha/sha1-x86_64.asm",
+  "win-x86_64/crypto/sha/sha256-x86_64.asm",
+  "win-x86_64/crypto/sha/sha512-x86_64.asm",
+]
+
+fuzzers = [
+  "cert",
+  "client",
+  "pkcs8",
+  "privkey",
+  "read_pem",
+  "server",
+  "spki",
+]
diff --git a/third_party/boringssl/BUILD.generated_tests.gni b/third_party/boringssl/BUILD.generated_tests.gni
new file mode 100644
index 0000000..16bddff
--- /dev/null
+++ b/third_party/boringssl/BUILD.generated_tests.gni
@@ -0,0 +1,584 @@
+# Copyright (c) 2016 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.
+
+# This file is created by generate_build_files.py. Do not edit manually.
+
+_test_support_sources = [
+  "src/crypto/test/file_test.cc",
+  "src/crypto/test/file_test.h",
+  "src/crypto/test/malloc.cc",
+  "src/crypto/test/scoped_types.h",
+  "src/crypto/test/test_util.cc",
+  "src/crypto/test/test_util.h",
+  "src/ssl/test/async_bio.h",
+  "src/ssl/test/packeted_bio.h",
+  "src/ssl/test/scoped_types.h",
+  "src/ssl/test/test_config.h",
+]
+
+template("create_tests") {
+  executable("boringssl_aes_test") {
+    sources = [
+      "src/crypto/aes/aes_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_asn1_test") {
+    sources = [
+      "src/crypto/asn1/asn1_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_base64_test") {
+    sources = [
+      "src/crypto/base64/base64_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_bio_test") {
+    sources = [
+      "src/crypto/bio/bio_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_bn_test") {
+    sources = [
+      "src/crypto/bn/bn_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_bytestring_test") {
+    sources = [
+      "src/crypto/bytestring/bytestring_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_chacha_test") {
+    sources = [
+      "src/crypto/chacha/chacha_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_aead_test") {
+    sources = [
+      "src/crypto/cipher/aead_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_cipher_test") {
+    sources = [
+      "src/crypto/cipher/cipher_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_cmac_test") {
+    sources = [
+      "src/crypto/cmac/cmac_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_constant_time_test") {
+    sources = [
+      "src/crypto/constant_time_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_ed25519_test") {
+    sources = [
+      "src/crypto/curve25519/ed25519_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_spake25519_test") {
+    sources = [
+      "src/crypto/curve25519/spake25519_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_x25519_test") {
+    sources = [
+      "src/crypto/curve25519/x25519_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_dh_test") {
+    sources = [
+      "src/crypto/dh/dh_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_digest_test") {
+    sources = [
+      "src/crypto/digest/digest_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_dsa_test") {
+    sources = [
+      "src/crypto/dsa/dsa_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_ec_test") {
+    sources = [
+      "src/crypto/ec/ec_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_example_mul") {
+    sources = [
+      "src/crypto/ec/example_mul.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_ecdsa_test") {
+    sources = [
+      "src/crypto/ecdsa/ecdsa_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_err_test") {
+    sources = [
+      "src/crypto/err/err_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_evp_extra_test") {
+    sources = [
+      "src/crypto/evp/evp_extra_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_evp_test") {
+    sources = [
+      "src/crypto/evp/evp_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_pbkdf_test") {
+    sources = [
+      "src/crypto/evp/pbkdf_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_hkdf_test") {
+    sources = [
+      "src/crypto/hkdf/hkdf_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_hmac_test") {
+    sources = [
+      "src/crypto/hmac/hmac_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_lhash_test") {
+    sources = [
+      "src/crypto/lhash/lhash_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_gcm_test") {
+    sources = [
+      "src/crypto/modes/gcm_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_newhope_statistical_test") {
+    sources = [
+      "src/crypto/newhope/newhope_statistical_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_newhope_test") {
+    sources = [
+      "src/crypto/newhope/newhope_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_newhope_vectors_test") {
+    sources = [
+      "src/crypto/newhope/newhope_vectors_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_obj_test") {
+    sources = [
+      "src/crypto/obj/obj_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_pkcs12_test") {
+    sources = [
+      "src/crypto/pkcs8/pkcs12_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_pkcs8_test") {
+    sources = [
+      "src/crypto/pkcs8/pkcs8_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_poly1305_test") {
+    sources = [
+      "src/crypto/poly1305/poly1305_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_refcount_test") {
+    sources = [
+      "src/crypto/refcount_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_rsa_test") {
+    sources = [
+      "src/crypto/rsa/rsa_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_thread_test") {
+    sources = [
+      "src/crypto/thread_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_pkcs7_test") {
+    sources = [
+      "src/crypto/x509/pkcs7_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_x509_test") {
+    sources = [
+      "src/crypto/x509/x509_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_tab_test") {
+    sources = [
+      "src/crypto/x509v3/tab_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_v3name_test") {
+    sources = [
+      "src/crypto/x509v3/v3name_test.c",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  executable("boringssl_ssl_test") {
+    sources = [
+      "src/ssl/ssl_test.cc",
+    ]
+    sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
+    configs += invoker.configs
+    deps = invoker.deps
+  }
+
+  group(target_name) {
+    deps = [
+      ":boringssl_aead_test",
+      ":boringssl_aes_test",
+      ":boringssl_asn1_test",
+      ":boringssl_base64_test",
+      ":boringssl_bio_test",
+      ":boringssl_bn_test",
+      ":boringssl_bytestring_test",
+      ":boringssl_chacha_test",
+      ":boringssl_cipher_test",
+      ":boringssl_cmac_test",
+      ":boringssl_constant_time_test",
+      ":boringssl_dh_test",
+      ":boringssl_digest_test",
+      ":boringssl_dsa_test",
+      ":boringssl_ec_test",
+      ":boringssl_ecdsa_test",
+      ":boringssl_ed25519_test",
+      ":boringssl_err_test",
+      ":boringssl_evp_extra_test",
+      ":boringssl_evp_test",
+      ":boringssl_example_mul",
+      ":boringssl_gcm_test",
+      ":boringssl_hkdf_test",
+      ":boringssl_hmac_test",
+      ":boringssl_lhash_test",
+      ":boringssl_newhope_statistical_test",
+      ":boringssl_newhope_test",
+      ":boringssl_newhope_vectors_test",
+      ":boringssl_obj_test",
+      ":boringssl_pbkdf_test",
+      ":boringssl_pkcs12_test",
+      ":boringssl_pkcs7_test",
+      ":boringssl_pkcs8_test",
+      ":boringssl_poly1305_test",
+      ":boringssl_refcount_test",
+      ":boringssl_rsa_test",
+      ":boringssl_spake25519_test",
+      ":boringssl_ssl_test",
+      ":boringssl_tab_test",
+      ":boringssl_thread_test",
+      ":boringssl_v3name_test",
+      ":boringssl_x25519_test",
+      ":boringssl_x509_test",
+    ]
+  }
+}
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
index dc26330..a71a735 100644
--- a/third_party/boringssl/BUILD.gn
+++ b/third_party/boringssl/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/android/config.gni")
 import("//build/config/sanitizers/sanitizers.gni")
+import("BUILD.generated.gni")
 
 # Config for us and everybody else depending on BoringSSL.
 config("external_config") {
@@ -13,83 +14,107 @@
   }
 }
 
-
 # Config internal to this build file, shared by boringssl and boringssl_fuzzer.
 config("internal_config") {
   visibility = [ ":*" ]  # Only targets in this file can depend on this.
   defines = [
     "BORINGSSL_IMPLEMENTATION",
     "BORINGSSL_NO_STATIC_INITIALIZER",
-    "OPENSSL_SMALL_FOOTPRINT",
+    "OPENSSL_SMALL",
   ]
+  # configs = [
+  #   # TODO(davidben): Fix size_t truncations in BoringSSL.
+  #   # https://crbug.com/429039
+  #   "//build/config/compiler:no_size_t_to_int_warning",
+  # ]
+  if (is_posix) {
+    cflags_c = [ "-std=c99" ]
+    defines += [ "_XOPEN_SOURCE=700" ]
+  }
 }
 
-
 config("no_asm_config") {
   visibility = [ ":*" ]  # Only targets in this file can depend on this.
   defines = [ "OPENSSL_NO_ASM" ]
 }
 
+all_sources = crypto_sources + ssl_sources
 
-# The list of BoringSSL files is kept in boringssl.gypi.
-gypi_values =
-    exec_script("../../tools/gypi_to_gn.py",
-                [ rebase_path("boringssl.gypi") ],
-                "scope",
-                [ "boringssl.gypi" ])
-boringssl_sources =
-    gypi_values.boringssl_crypto_sources + gypi_values.boringssl_ssl_sources
+# Windows' assembly is built with Yasm. The other platforms use the platform
+# assembler.
+if (is_win && !is_msan) {
+  import("//third_party/yasm/yasm_assemble.gni")
+  yasm_assemble("boringssl_asm") {
+    if (current_cpu == "x64") {
+      sources = crypto_sources_win_x86_64
+    } else if (current_cpu == "x86") {
+      sources = crypto_sources_win_x86
+    }
+  }
+} else {
+  # This has no sources on some platforms so must be a source_set.
+  source_set("boringssl_asm") {
+    visibility = [ ":*" ]  # Only targets in this file can depend on this.
 
+    defines = []
+    sources = []
+    include_dirs = [ "src/include" ]
 
-source_set("boringssl_asm") {
-  visibility = [ ":*" ]  # Only targets in this file can depend on this.
-  sources = []
-  #asmflags = []
-  include_dirs = [
-    "src/include",
-    # This is for arm_arch.h, which is needed by some asm files. Since the
-    # asm files are generated and kept in a different directory, they
-    # cannot use relative paths to find this file.
-    "src/crypto",
-  ]
+    if ((current_cpu == "arm" || current_cpu == "arm64") && is_clang) {
+      if (current_cpu == "arm") {
+        # TODO(hans) Enable integrated-as (crbug.com/124610).
+        asmflags += [ "-fno-integrated-as" ]
+      }
+      if (is_android) {
+        rebased_android_toolchain_root =
+            rebase_path(android_toolchain_root, root_build_dir)
 
-  if (current_cpu == "x64") {
-    if (is_ios) {
-      defines += [ "OPENSSL_NO_ASM" ]
-    } else if (is_mac) {
-      sources += gypi_values.boringssl_mac_x86_64_sources
-    } else if (is_linux || is_android) {
-      sources += gypi_values.boringssl_linux_x86_64_sources
+        # Else /usr/bin/as gets picked up.
+        asmflags += [ "-B${rebased_android_toolchain_root}/bin" ]
+      }
+    }
+
+    if (is_msan) {
+      public_configs = [ ":no_asm_config" ]
+    } else if (current_cpu == "x64") {
+      if (is_mac) {
+        sources += crypto_sources_mac_x86_64
+      } else if (is_linux || is_android) {
+        sources += crypto_sources_linux_x86_64
+      } else {
+        public_configs = [ ":no_asm_config" ]
+      }
+    } else if (current_cpu == "x86") {
+      if (is_mac) {
+        sources += crypto_sources_mac_x86
+      } else if (is_linux || is_android) {
+        sources += crypto_sources_linux_x86
+      } else {
+        public_configs = [ ":no_asm_config" ]
+      }
+    } else if (current_cpu == "arm" && (is_linux || is_android)) {
+      sources += crypto_sources_linux_arm
+    } else if (current_cpu == "arm64" && (is_linux || is_android)) {
+      sources += crypto_sources_linux_aarch64
+
+      # TODO(davidben): Remove explicit arch flag once https://crbug.com/576858
+      # is fixed.
+      asmflags += [ "-march=armv8-a+crypto" ]
     } else {
       public_configs = [ ":no_asm_config" ]
     }
-  } else if (current_cpu == "x86") {
-    if (is_ios) {
-      defines += [ "OPENSSL_NO_ASM" ]
-    } else if (is_mac) {
-      sources += gypi_values.boringssl_mac_x86_sources
-    } else if (is_linux || is_android) {
-      sources += gypi_values.boringssl_linux_x86_sources
-    } else {
-      public_configs = [ ":no_asm_config" ]
-    }
-  } else if (current_cpu == "arm" && (is_linux || is_android)) {
-    sources += gypi_values.boringssl_linux_arm_sources
-  } else if (current_cpu == "arm64" && (is_linux || is_android)) {
-    sources += gypi_values.boringssl_linux_aarch64_sources
-  } else {
-    public_configs = [ ":no_asm_config" ]
   }
 }
 
-
 component("boringssl") {
-  sources = boringssl_sources
+  sources = all_sources
   deps = [
     ":boringssl_asm",
   ]
+
   public_configs = [ ":external_config" ]
   configs += [ ":internal_config" ]
+
   configs -= [ "//build/config/compiler:chromium_code" ]
   configs += [ "//build/config/compiler:no_chromium_code" ]
 }
diff --git a/third_party/boringssl/boringssl.gypi b/third_party/boringssl/boringssl.gypi
index fb8e643..2c7e7c7 100644
--- a/third_party/boringssl/boringssl.gypi
+++ b/third_party/boringssl/boringssl.gypi
@@ -1,4 +1,4 @@
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Copyright (c) 2016 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.
 
@@ -7,34 +7,34 @@
 {
   'variables': {
     'boringssl_ssl_sources': [
+      'src/ssl/custom_extensions.c',
       'src/ssl/d1_both.c',
-      'src/ssl/d1_clnt.c',
       'src/ssl/d1_lib.c',
-      'src/ssl/d1_meth.c',
       'src/ssl/d1_pkt.c',
       'src/ssl/d1_srtp.c',
-      'src/ssl/d1_srvr.c',
-      'src/ssl/pqueue/pqueue.c',
+      'src/ssl/dtls_method.c',
+      'src/ssl/dtls_record.c',
+      'src/ssl/handshake_client.c',
+      'src/ssl/handshake_server.c',
       'src/ssl/s3_both.c',
-      'src/ssl/s3_clnt.c',
       'src/ssl/s3_enc.c',
       'src/ssl/s3_lib.c',
-      'src/ssl/s3_meth.c',
       'src/ssl/s3_pkt.c',
-      'src/ssl/s3_srvr.c',
       'src/ssl/ssl_aead_ctx.c',
-      'src/ssl/ssl_algs.c',
       'src/ssl/ssl_asn1.c',
+      'src/ssl/ssl_buffer.c',
       'src/ssl/ssl_cert.c',
       'src/ssl/ssl_cipher.c',
+      'src/ssl/ssl_ecdh.c',
+      'src/ssl/ssl_file.c',
       'src/ssl/ssl_lib.c',
       'src/ssl/ssl_rsa.c',
-      'src/ssl/ssl_sess.c',
+      'src/ssl/ssl_session.c',
       'src/ssl/ssl_stat.c',
-      'src/ssl/ssl_txt.c',
       'src/ssl/t1_enc.c',
       'src/ssl/t1_lib.c',
-      'src/ssl/t1_reneg.c',
+      'src/ssl/tls_method.c',
+      'src/ssl/tls_record.c',
     ],
     'boringssl_crypto_sources': [
       'err_data.c',
@@ -61,18 +61,14 @@
       'src/crypto/asn1/asn1_lib.c',
       'src/crypto/asn1/asn1_par.c',
       'src/crypto/asn1/asn_pack.c',
-      'src/crypto/asn1/bio_asn1.c',
-      'src/crypto/asn1/bio_ndef.c',
       'src/crypto/asn1/f_enum.c',
       'src/crypto/asn1/f_int.c',
       'src/crypto/asn1/f_string.c',
       'src/crypto/asn1/t_bitst.c',
-      'src/crypto/asn1/t_pkey.c',
       'src/crypto/asn1/tasn_dec.c',
       'src/crypto/asn1/tasn_enc.c',
       'src/crypto/asn1/tasn_fre.c',
       'src/crypto/asn1/tasn_new.c',
-      'src/crypto/asn1/tasn_prn.c',
       'src/crypto/asn1/tasn_typ.c',
       'src/crypto/asn1/tasn_utl.c',
       'src/crypto/asn1/x_bignum.c',
@@ -92,6 +88,7 @@
       'src/crypto/bn/add.c',
       'src/crypto/bn/asm/x86_64-gcc.c',
       'src/crypto/bn/bn.c',
+      'src/crypto/bn/bn_asn1.c',
       'src/crypto/bn/cmp.c',
       'src/crypto/bn/convert.c',
       'src/crypto/bn/ctx.c',
@@ -108,11 +105,11 @@
       'src/crypto/bn/shift.c',
       'src/crypto/bn/sqrt.c',
       'src/crypto/buf/buf.c',
+      'src/crypto/bytestring/asn1_compat.c',
       'src/crypto/bytestring/ber.c',
       'src/crypto/bytestring/cbb.c',
       'src/crypto/bytestring/cbs.c',
-      'src/crypto/chacha/chacha_generic.c',
-      'src/crypto/chacha/chacha_vec.c',
+      'src/crypto/chacha/chacha.c',
       'src/crypto/cipher/aead.c',
       'src/crypto/cipher/cipher.c',
       'src/crypto/cipher/derive_key.c',
@@ -127,28 +124,31 @@
       'src/crypto/cipher/tls_cbc.c',
       'src/crypto/cmac/cmac.c',
       'src/crypto/conf/conf.c',
+      'src/crypto/cpu-aarch64-linux.c',
+      'src/crypto/cpu-arm-linux.c',
       'src/crypto/cpu-arm.c',
       'src/crypto/cpu-intel.c',
       'src/crypto/crypto.c',
+      'src/crypto/curve25519/curve25519.c',
+      'src/crypto/curve25519/spake25519.c',
+      'src/crypto/curve25519/x25519-x86_64.c',
       'src/crypto/des/des.c',
       'src/crypto/dh/check.c',
       'src/crypto/dh/dh.c',
       'src/crypto/dh/dh_asn1.c',
-      'src/crypto/dh/dh_impl.c',
       'src/crypto/dh/params.c',
       'src/crypto/digest/digest.c',
       'src/crypto/digest/digests.c',
-      'src/crypto/directory_posix.c',
-      'src/crypto/directory_win.c',
       'src/crypto/dsa/dsa.c',
       'src/crypto/dsa/dsa_asn1.c',
-      'src/crypto/dsa/dsa_impl.c',
       'src/crypto/ec/ec.c',
       'src/crypto/ec/ec_asn1.c',
       'src/crypto/ec/ec_key.c',
       'src/crypto/ec/ec_montgomery.c',
       'src/crypto/ec/oct.c',
+      'src/crypto/ec/p224-64.c',
       'src/crypto/ec/p256-64.c',
+      'src/crypto/ec/p256-x86_64.c',
       'src/crypto/ec/simple.c',
       'src/crypto/ec/util-64.c',
       'src/crypto/ec/wnaf.c',
@@ -157,10 +157,9 @@
       'src/crypto/ecdsa/ecdsa_asn1.c',
       'src/crypto/engine/engine.c',
       'src/crypto/err/err.c',
-      'src/crypto/evp/algorithm.c',
-      'src/crypto/evp/asn1.c',
       'src/crypto/evp/digestsign.c',
       'src/crypto/evp/evp.c',
+      'src/crypto/evp/evp_asn1.c',
       'src/crypto/evp/evp_ctx.c',
       'src/crypto/evp/p_dsa_asn1.c',
       'src/crypto/evp/p_ec.c',
@@ -168,6 +167,7 @@
       'src/crypto/evp/p_rsa.c',
       'src/crypto/evp/p_rsa_asn1.c',
       'src/crypto/evp/pbkdf.c',
+      'src/crypto/evp/print.c',
       'src/crypto/evp/sign.c',
       'src/crypto/ex_data.c',
       'src/crypto/hkdf/hkdf.c',
@@ -181,6 +181,12 @@
       'src/crypto/modes/ctr.c',
       'src/crypto/modes/gcm.c',
       'src/crypto/modes/ofb.c',
+      'src/crypto/newhope/error_correction.c',
+      'src/crypto/newhope/newhope.c',
+      'src/crypto/newhope/ntt.c',
+      'src/crypto/newhope/poly.c',
+      'src/crypto/newhope/precomp.c',
+      'src/crypto/newhope/reduce.c',
       'src/crypto/obj/obj.c',
       'src/crypto/obj/obj_xref.c',
       'src/crypto/pem/pem_all.c',
@@ -198,7 +204,7 @@
       'src/crypto/poly1305/poly1305.c',
       'src/crypto/poly1305/poly1305_arm.c',
       'src/crypto/poly1305/poly1305_vec.c',
-      'src/crypto/rand/hwrand.c',
+      'src/crypto/rand/deterministic.c',
       'src/crypto/rand/rand.c',
       'src/crypto/rand/urandom.c',
       'src/crypto/rand/windows.c',
@@ -223,11 +229,13 @@
       'src/crypto/x509/a_sign.c',
       'src/crypto/x509/a_strex.c',
       'src/crypto/x509/a_verify.c',
+      'src/crypto/x509/algorithm.c',
       'src/crypto/x509/asn1_gen.c',
       'src/crypto/x509/by_dir.c',
       'src/crypto/x509/by_file.c',
       'src/crypto/x509/i2d_pr.c',
       'src/crypto/x509/pkcs7.c',
+      'src/crypto/x509/rsa_pss.c',
       'src/crypto/x509/t_crl.c',
       'src/crypto/x509/t_req.c',
       'src/crypto/x509/t_x509.c',
@@ -303,6 +311,8 @@
     ],
     'boringssl_linux_aarch64_sources': [
       'linux-aarch64/crypto/aes/aesv8-armx64.S',
+      'linux-aarch64/crypto/bn/armv8-mont.S',
+      'linux-aarch64/crypto/chacha/chacha-armv8.S',
       'linux-aarch64/crypto/modes/ghashv8-armx64.S',
       'linux-aarch64/crypto/sha/sha1-armv8.S',
       'linux-aarch64/crypto/sha/sha256-armv8.S',
@@ -313,13 +323,13 @@
       'linux-arm/crypto/aes/aesv8-armx32.S',
       'linux-arm/crypto/aes/bsaes-armv7.S',
       'linux-arm/crypto/bn/armv4-mont.S',
+      'linux-arm/crypto/chacha/chacha-armv4.S',
       'linux-arm/crypto/modes/ghash-armv4.S',
       'linux-arm/crypto/modes/ghashv8-armx32.S',
       'linux-arm/crypto/sha/sha1-armv4-large.S',
       'linux-arm/crypto/sha/sha256-armv4.S',
       'linux-arm/crypto/sha/sha512-armv4.S',
-      'src/crypto/chacha/chacha_vec_arm.S',
-      'src/crypto/cpu-arm-asm.S',
+      'src/crypto/curve25519/asm/x25519-asm-arm.S',
       'src/crypto/poly1305/poly1305_arm_asm.S',
     ],
     'boringssl_linux_x86_sources': [
@@ -329,7 +339,7 @@
       'linux-x86/crypto/bn/bn-586.S',
       'linux-x86/crypto/bn/co-586.S',
       'linux-x86/crypto/bn/x86-mont.S',
-      'linux-x86/crypto/cpu-x86-asm.S',
+      'linux-x86/crypto/chacha/chacha-x86.S',
       'linux-x86/crypto/md5/md5-586.S',
       'linux-x86/crypto/modes/ghash-x86.S',
       'linux-x86/crypto/rc4/rc4-586.S',
@@ -346,16 +356,17 @@
       'linux-x86_64/crypto/bn/rsaz-x86_64.S',
       'linux-x86_64/crypto/bn/x86_64-mont.S',
       'linux-x86_64/crypto/bn/x86_64-mont5.S',
-      'linux-x86_64/crypto/cpu-x86_64-asm.S',
+      'linux-x86_64/crypto/chacha/chacha-x86_64.S',
+      'linux-x86_64/crypto/ec/p256-x86_64-asm.S',
       'linux-x86_64/crypto/md5/md5-x86_64.S',
       'linux-x86_64/crypto/modes/aesni-gcm-x86_64.S',
       'linux-x86_64/crypto/modes/ghash-x86_64.S',
       'linux-x86_64/crypto/rand/rdrand-x86_64.S',
-      'linux-x86_64/crypto/rc4/rc4-md5-x86_64.S',
       'linux-x86_64/crypto/rc4/rc4-x86_64.S',
       'linux-x86_64/crypto/sha/sha1-x86_64.S',
       'linux-x86_64/crypto/sha/sha256-x86_64.S',
       'linux-x86_64/crypto/sha/sha512-x86_64.S',
+      'src/crypto/curve25519/asm/x25519-asm-x86_64.S',
     ],
     'boringssl_mac_x86_sources': [
       'mac-x86/crypto/aes/aes-586.S',
@@ -364,7 +375,7 @@
       'mac-x86/crypto/bn/bn-586.S',
       'mac-x86/crypto/bn/co-586.S',
       'mac-x86/crypto/bn/x86-mont.S',
-      'mac-x86/crypto/cpu-x86-asm.S',
+      'mac-x86/crypto/chacha/chacha-x86.S',
       'mac-x86/crypto/md5/md5-586.S',
       'mac-x86/crypto/modes/ghash-x86.S',
       'mac-x86/crypto/rc4/rc4-586.S',
@@ -381,16 +392,17 @@
       'mac-x86_64/crypto/bn/rsaz-x86_64.S',
       'mac-x86_64/crypto/bn/x86_64-mont.S',
       'mac-x86_64/crypto/bn/x86_64-mont5.S',
-      'mac-x86_64/crypto/cpu-x86_64-asm.S',
+      'mac-x86_64/crypto/chacha/chacha-x86_64.S',
+      'mac-x86_64/crypto/ec/p256-x86_64-asm.S',
       'mac-x86_64/crypto/md5/md5-x86_64.S',
       'mac-x86_64/crypto/modes/aesni-gcm-x86_64.S',
       'mac-x86_64/crypto/modes/ghash-x86_64.S',
       'mac-x86_64/crypto/rand/rdrand-x86_64.S',
-      'mac-x86_64/crypto/rc4/rc4-md5-x86_64.S',
       'mac-x86_64/crypto/rc4/rc4-x86_64.S',
       'mac-x86_64/crypto/sha/sha1-x86_64.S',
       'mac-x86_64/crypto/sha/sha256-x86_64.S',
       'mac-x86_64/crypto/sha/sha512-x86_64.S',
+      'src/crypto/curve25519/asm/x25519-asm-x86_64.S',
     ],
     'boringssl_win_x86_sources': [
       'win-x86/crypto/aes/aes-586.asm',
@@ -399,7 +411,7 @@
       'win-x86/crypto/bn/bn-586.asm',
       'win-x86/crypto/bn/co-586.asm',
       'win-x86/crypto/bn/x86-mont.asm',
-      'win-x86/crypto/cpu-x86-asm.asm',
+      'win-x86/crypto/chacha/chacha-x86.asm',
       'win-x86/crypto/md5/md5-586.asm',
       'win-x86/crypto/modes/ghash-x86.asm',
       'win-x86/crypto/rc4/rc4-586.asm',
@@ -416,12 +428,12 @@
       'win-x86_64/crypto/bn/rsaz-x86_64.asm',
       'win-x86_64/crypto/bn/x86_64-mont.asm',
       'win-x86_64/crypto/bn/x86_64-mont5.asm',
-      'win-x86_64/crypto/cpu-x86_64-asm.asm',
+      'win-x86_64/crypto/chacha/chacha-x86_64.asm',
+      'win-x86_64/crypto/ec/p256-x86_64-asm.asm',
       'win-x86_64/crypto/md5/md5-x86_64.asm',
       'win-x86_64/crypto/modes/aesni-gcm-x86_64.asm',
       'win-x86_64/crypto/modes/ghash-x86_64.asm',
       'win-x86_64/crypto/rand/rdrand-x86_64.asm',
-      'win-x86_64/crypto/rc4/rc4-md5-x86_64.asm',
       'win-x86_64/crypto/rc4/rc4-x86_64.asm',
       'win-x86_64/crypto/sha/sha1-x86_64.asm',
       'win-x86_64/crypto/sha/sha256-x86_64.asm',
diff --git a/third_party/boringssl/boringssl_configurations.gypi b/third_party/boringssl/boringssl_configurations.gypi
index b963505..3162d79 100644
--- a/third_party/boringssl/boringssl_configurations.gypi
+++ b/third_party/boringssl/boringssl_configurations.gypi
@@ -4,29 +4,20 @@
 
 # This file is included to modify the configurations to build third-party
 # code from BoringSSL.
-# This code is C code, not C++, and is not warning-free, so we need to remove
-# C++-specific flags, and add flags to supress the warnings in the code.
 {
-  'variables': {
-    # Used by third_party/nss, which is from Chromium.
-    # Include the built-in set of root certificate authorities.
-    'exclude_nss_root_certs': 0,
-    'os_posix%': 1,
-    'os_bsd%': 0,
-    'chromeos%': 0,
-    'clang%': 0,
-  },
   'target_defaults': {
-    'cflags': [
-      '-w',
-      '-UHAVE_CVAR_BUILT_ON_SEM',
+    'conditions': [
+      ['OS == "linux" or OS == "android"', {
+        'cflags_c': [
+          '-std=c99',
+        ],
+        'defines': [
+          '_XOPEN_SOURCE=700',
+        ],
+      }],
     ],
     # Removes these flags from the list cflags.
     'cflags!': [
-      # NSS code from upstream mozilla builds with warnings,
-      # so we must allow warnings without failing.
-      '-Werror',
-      '-Wall',
       '-ansi',
       # Not supported for C, only for C++.
       '-Wnon-virtual-dtor',
@@ -35,93 +26,5 @@
       '-fvisibility-inlines-hidden',
       '-Woverloaded-virtual',
     ],
-    'configurations': {
-      'Dart_Base': {
-        'xcode_settings': {
-          'WARNING_CFLAGS': [
-            '-w',
-          ],
-          'WARNING_CFLAGS!': [
-            '-Wall',
-            '-Wextra',
-          ],
-        },
-      },
-      # Dart_Macos_Debug and Dart_Macos_Release are merged after
-      # Dart_Macos_Base, so we can override the 'ansi' and '-Werror' flags set
-      # at the global level in tools/gyp/configurations_xcode.gypi.
-      'Dart_Macos_Debug': {
-        'abstract': 1,
-        'xcode_settings': {
-          # Remove 'ansi' setting.
-          'GCC_C_LANGUAGE_STANDARD': 'c99',
-          'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', # -Werror off
-        },
-      },
-      'Dart_Macos_Release': {
-        'abstract': 1,
-        'xcode_settings': {
-          # Remove 'ansi' setting.
-          'GCC_C_LANGUAGE_STANDARD': 'c99',
-          'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', # -Werror off
-        },
-      },
-      # Disable hand-coded assembly routines on ARMv6 and ARMv5TE.
-      'Dart_armv6_Base': {
-        'abstract': 1,
-        'defines': [
-          'OPENSSL_NO_ASM',
-        ],
-      },
-      'Dart_armv5te_Base': {
-        'abstract': 1,
-        'defines': [
-          'OPENSSL_NO_ASM',
-        ],
-      },
-      # TODO(24321): Also disable temporarily on arm64. Reenable after the next
-      # roll.
-      'Dart_arm64_Base': {
-        'abstract': 1,
-        'defines': [
-          'OPENSSL_NO_ASM',
-        ],
-      },
-      # Android 64-bit dbc build is for arm64, disable temporarily as well.
-      'Dart_Android_arm64_Base': {
-        'abstract': 1,
-        'defines': [
-          'OPENSSL_NO_ASM',
-        ],
-      },
-      # When being built for Android nss expects __linux__ to be defined.
-      'Dart_Android_Base': {
-        'target_conditions': [
-          ['_toolset=="host"', {
-            'defines!': [
-              'ANDROID',
-            ],
-            # Define __linux__ on Android build for NSS.
-            'defines': [
-              '__linux__',
-            ],
-            'cflags!': [
-              '-U__linux__',
-            ],
-          }],
-          ['_toolset=="target"', {
-            'defines': [
-              '__linux__',
-              'CHECK_FORK_GETPID',  # Android does not provide pthread_atfork.
-              '__USE_LARGEFILE64',
-            ],
-            # Define __linux__ on Android build for NSS.
-            'cflags!': [
-              '-U__linux__',
-            ],
-          }]
-        ],
-      },
-    },
   },
 }
diff --git a/third_party/boringssl/boringssl_dart.gyp b/third_party/boringssl/boringssl_dart.gyp
index 30270fa..1dc460f 100644
--- a/third_party/boringssl/boringssl_dart.gyp
+++ b/third_party/boringssl/boringssl_dart.gyp
@@ -22,6 +22,7 @@
       'defines': [
         'BORINGSSL_IMPLEMENTATION',
         'BORINGSSL_NO_STATIC_INITIALIZER',
+        'OPENSSL_SMALL'
       ],
       # TODO(davidben): Fix size_t truncations in BoringSSL.
       # https://crbug.com/429039
@@ -47,10 +48,6 @@
       ],
       'include_dirs': [
         'src/include',
-        # This is for arm_arch.h, which is needed by some asm files. Since the
-        # asm files are generated and kept in a different directory, they
-        # cannot use relative paths to find this file.
-        'src/crypto',
       ],
       'direct_dependent_settings': {
         'include_dirs': [
diff --git a/third_party/boringssl/boringssl_tests.gypi b/third_party/boringssl/boringssl_tests.gypi
index 9413d8c..1076214 100644
--- a/third_party/boringssl/boringssl_tests.gypi
+++ b/third_party/boringssl/boringssl_tests.gypi
@@ -1,4 +1,4 @@
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Copyright (c) 2016 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.
 
@@ -7,6 +7,34 @@
 {
   'targets': [
     {
+      'target_name': 'boringssl_aes_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/aes/aes_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'boringssl_asn1_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/asn1/asn1_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
       'target_name': 'boringssl_base64_test',
       'type': 'executable',
       'dependencies': [
@@ -63,6 +91,20 @@
       'msvs_disabled_warnings': [ 4267, ],
     },
     {
+      'target_name': 'boringssl_chacha_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/chacha/chacha_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
       'target_name': 'boringssl_aead_test',
       'type': 'executable',
       'dependencies': [
@@ -119,6 +161,48 @@
       'msvs_disabled_warnings': [ 4267, ],
     },
     {
+      'target_name': 'boringssl_ed25519_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/curve25519/ed25519_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'boringssl_spake25519_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/curve25519/spake25519_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'boringssl_x25519_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/curve25519/x25519_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
       'target_name': 'boringssl_dh_test',
       'type': 'executable',
       'dependencies': [
@@ -315,6 +399,62 @@
       'msvs_disabled_warnings': [ 4267, ],
     },
     {
+      'target_name': 'boringssl_newhope_statistical_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/newhope/newhope_statistical_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'boringssl_newhope_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/newhope/newhope_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'boringssl_newhope_vectors_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/newhope/newhope_vectors_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'boringssl_obj_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/obj/obj_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
       'target_name': 'boringssl_pkcs12_test',
       'type': 'executable',
       'dependencies': [
@@ -329,6 +469,34 @@
       'msvs_disabled_warnings': [ 4267, ],
     },
     {
+      'target_name': 'boringssl_pkcs8_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/pkcs8/pkcs8_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
+      'target_name': 'boringssl_poly1305_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/poly1305/poly1305_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
       'target_name': 'boringssl_refcount_test',
       'type': 'executable',
       'dependencies': [
@@ -385,6 +553,20 @@
       'msvs_disabled_warnings': [ 4267, ],
     },
     {
+      'target_name': 'boringssl_x509_test',
+      'type': 'executable',
+      'dependencies': [
+        'boringssl.gyp:boringssl',
+      ],
+      'sources': [
+        'src/crypto/x509/x509_test.cc',
+        '<@(boringssl_test_support_sources)',
+      ],
+      # TODO(davidben): Fix size_t truncations in BoringSSL.
+      # https://crbug.com/429039
+      'msvs_disabled_warnings': [ 4267, ],
+    },
+    {
       'target_name': 'boringssl_tab_test',
       'type': 'executable',
       'dependencies': [
@@ -413,20 +595,6 @@
       'msvs_disabled_warnings': [ 4267, ],
     },
     {
-      'target_name': 'boringssl_pqueue_test',
-      'type': 'executable',
-      'dependencies': [
-        'boringssl.gyp:boringssl',
-      ],
-      'sources': [
-        'src/ssl/pqueue/pqueue_test.c',
-        '<@(boringssl_test_support_sources)',
-      ],
-      # TODO(davidben): Fix size_t truncations in BoringSSL.
-      # https://crbug.com/429039
-      'msvs_disabled_warnings': [ 4267, ],
-    },
-    {
       'target_name': 'boringssl_ssl_test',
       'type': 'executable',
       'dependencies': [
@@ -444,14 +612,25 @@
   'variables': {
     'boringssl_test_support_sources': [
       'src/crypto/test/file_test.cc',
+      'src/crypto/test/file_test.h',
       'src/crypto/test/malloc.cc',
+      'src/crypto/test/scoped_types.h',
+      'src/crypto/test/test_util.cc',
+      'src/crypto/test/test_util.h',
+      'src/ssl/test/async_bio.h',
+      'src/ssl/test/packeted_bio.h',
+      'src/ssl/test/scoped_types.h',
+      'src/ssl/test/test_config.h',
     ],
     'boringssl_test_targets': [
       'boringssl_aead_test',
+      'boringssl_aes_test',
+      'boringssl_asn1_test',
       'boringssl_base64_test',
       'boringssl_bio_test',
       'boringssl_bn_test',
       'boringssl_bytestring_test',
+      'boringssl_chacha_test',
       'boringssl_cipher_test',
       'boringssl_cmac_test',
       'boringssl_constant_time_test',
@@ -460,6 +639,7 @@
       'boringssl_dsa_test',
       'boringssl_ec_test',
       'boringssl_ecdsa_test',
+      'boringssl_ed25519_test',
       'boringssl_err_test',
       'boringssl_evp_extra_test',
       'boringssl_evp_test',
@@ -468,16 +648,24 @@
       'boringssl_hkdf_test',
       'boringssl_hmac_test',
       'boringssl_lhash_test',
+      'boringssl_newhope_statistical_test',
+      'boringssl_newhope_test',
+      'boringssl_newhope_vectors_test',
+      'boringssl_obj_test',
       'boringssl_pbkdf_test',
       'boringssl_pkcs12_test',
       'boringssl_pkcs7_test',
-      'boringssl_pqueue_test',
+      'boringssl_pkcs8_test',
+      'boringssl_poly1305_test',
       'boringssl_refcount_test',
       'boringssl_rsa_test',
+      'boringssl_spake25519_test',
       'boringssl_ssl_test',
       'boringssl_tab_test',
       'boringssl_thread_test',
       'boringssl_v3name_test',
+      'boringssl_x25519_test',
+      'boringssl_x509_test',
     ],
   }
 }
diff --git a/third_party/boringssl/err_data.c b/third_party/boringssl/err_data.c
index 27acc89..d685679 100644
--- a/third_party/boringssl/err_data.c
+++ b/third_party/boringssl/err_data.c
@@ -49,1554 +49,171 @@
 OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28);
 OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29);
 OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30);
-OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 31, library_values_changed_31);
-OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 32, library_values_changed_32);
+OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31);
+OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32);
 OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num);
 
-const uint32_t kOpenSSLFunctionValues[] = {
-    0xc32054b,
-    0xc328556,
-    0xc330561,
-    0xc33856e,
-    0xc340578,
-    0xc348582,
-    0xc350589,
-    0xc358595,
-    0xc36059c,
-    0xc3685b2,
-    0xc3705d1,
-    0xc3785e2,
-    0xc3805f2,
-    0xc38860c,
-    0xc390621,
-    0xc398630,
-    0xc3a0649,
-    0xc3a865d,
-    0xc3b0669,
-    0xc3b8670,
-    0xc3c0678,
-    0xc3c8690,
-    0xc3d0698,
-    0xc3d86a0,
-    0xc3e06ab,
-    0xc3e85c7,
-    0xc3f0686,
-    0x1032193d,
-    0x10329954,
-    0x1033196d,
-    0x10339983,
-    0x10341993,
-    0x103499bb,
-    0x103519c9,
-    0x103599d8,
-    0x103619f8,
-    0x10369a17,
-    0x10371a34,
-    0x10379a51,
-    0x10381a66,
-    0x10389a88,
-    0x10391aa7,
-    0x10399ac6,
-    0x103a1add,
-    0x103a9af4,
-    0x103b1afd,
-    0x103b9b08,
-    0x103c1b22,
-    0x103c9b2a,
-    0x103d1b32,
-    0x103d99a6,
-    0x103e1b4b,
-    0x103e9b5d,
-    0x103f1b70,
-    0x103f9b79,
-    0x10401b39,
-    0x14320a4e,
-    0x14328a5c,
-    0x14330a68,
-    0x14338a75,
-    0x18361224,
-    0x18371252,
-    0x18379263,
-    0x18381279,
-    0x1839129c,
-    0x183992b1,
-    0x183a12c3,
-    0x183c1307,
-    0x183c9315,
-    0x183d1328,
-    0x183d9338,
-    0x183e935e,
-    0x183f1371,
-    0x183f9380,
-    0x184093aa,
-    0x18411416,
-    0x18419427,
-    0x1842143a,
-    0x1842944c,
-    0x1843145e,
-    0x1843946f,
-    0x18441480,
-    0x18449491,
-    0x184514a2,
-    0x184594af,
-    0x184614d1,
-    0x184694e4,
-    0x184714f8,
-    0x18479505,
-    0x18481514,
-    0x18489523,
-    0x18491534,
-    0x18499550,
-    0x184a155e,
-    0x184a956f,
-    0x184b1580,
-    0x184b958e,
-    0x184c159e,
-    0x184c95c4,
-    0x184d15d3,
-    0x184d95e3,
-    0x184e15f3,
-    0x184e9602,
-    0x184f1541,
-    0x184f91b3,
-    0x18501156,
-    0x1850916e,
-    0x18511190,
-    0x185191a2,
-    0x185211d4,
-    0x185291ed,
-    0x185311fe,
-    0x18539214,
-    0x18541239,
-    0x1854928a,
-    0x185512d3,
-    0x185592e8,
-    0x185612f5,
-    0x1856934d,
-    0x18571390,
-    0x1857939d,
-    0x185813b9,
-    0x185893ca,
-    0x185913da,
-    0x185993ea,
-    0x185a13f9,
-    0x185a9408,
-    0x185b14bd,
-    0x1c3206b8,
-    0x1c3286c4,
-    0x1c3306cf,
-    0x1c3386db,
-    0x20321616,
-    0x20329621,
-    0x20331629,
-    0x20339635,
-    0x24321641,
-    0x2432964f,
-    0x24331661,
-    0x24339670,
-    0x24341683,
-    0x24349696,
-    0x243516ad,
-    0x243596c5,
-    0x243616d3,
-    0x243696eb,
-    0x243716f4,
-    0x24379706,
-    0x2438171a,
-    0x24389727,
-    0x2439173d,
-    0x24399755,
-    0x243a176d,
-    0x243a9777,
-    0x243b178c,
-    0x243b979a,
-    0x243c17b2,
-    0x243c97c9,
-    0x243d17d4,
-    0x243d97e2,
-    0x28320aae,
-    0x28328abd,
-    0x28330ac8,
-    0x28338acd,
-    0x28340ad8,
-    0x2c322b99,
-    0x2c32aba5,
-    0x2c332bb8,
-    0x2c33abc9,
-    0x2c342be2,
-    0x2c34ac0a,
-    0x2c352c21,
-    0x2c35ac3e,
-    0x2c362c5b,
-    0x2c36ac78,
-    0x2c372c91,
-    0x2c37acaa,
-    0x2c382cc0,
-    0x2c38acce,
-    0x2c392ce0,
-    0x2c39acfd,
-    0x2c3a2d1a,
-    0x2c3aad28,
-    0x2c3b2d46,
-    0x2c3bad64,
-    0x2c3c2d7f,
-    0x2c3cad93,
-    0x2c3d2da5,
-    0x2c3dadb5,
-    0x2c3e2dc3,
-    0x2c3eadd3,
-    0x2c3f2de3,
-    0x2c3fae22,
-    0x2c402e33,
-    0x2c40ae4e,
-    0x2c412e62,
-    0x2c41ae75,
-    0x2c422e94,
-    0x2c42aea8,
-    0x2c432ebb,
-    0x2c43aeca,
-    0x2c442ed9,
-    0x2c44aef0,
-    0x2c452f0b,
-    0x2c45af23,
-    0x2c462f37,
-    0x2c46af4a,
-    0x2c472f5b,
-    0x2c47af6c,
-    0x2c482f7d,
-    0x2c48af8e,
-    0x2c492f9d,
-    0x2c49afaa,
-    0x2c4a2fb7,
-    0x2c4aafc4,
-    0x2c4b2fcd,
-    0x2c4bafe1,
-    0x2c4c2ff0,
-    0x2c4caffe,
-    0x2c4d3020,
-    0x2c4db031,
-    0x2c4e3042,
-    0x2c4eb00d,
-    0x2c4f2bfb,
-    0x2c4fadfe,
-    0x2c502e10,
-    0x30320000,
-    0x30328018,
-    0x3033002c,
-    0x30338042,
-    0x3034005b,
-    0x3034806c,
-    0x3035007f,
-    0x3035808f,
-    0x3036009d,
-    0x303680b3,
-    0x303700c3,
-    0x303780d8,
-    0x303800e6,
-    0x303880f7,
-    0x30390103,
-    0x3039810c,
-    0x303a011d,
-    0x303a812d,
-    0x303b013a,
-    0x303b8146,
-    0x303c0157,
-    0x303c8165,
-    0x303d0176,
-    0x303d8188,
-    0x303e0199,
-    0x303e81a8,
-    0x303f01b9,
-    0x303f81cd,
-    0x304001df,
-    0x304081ec,
-    0x30410202,
-    0x30418215,
-    0x30420225,
-    0x30428239,
-    0x3043024a,
-    0x3043825a,
-    0x30440265,
-    0x3044826d,
-    0x3045027d,
-    0x30458294,
-    0x304602a1,
-    0x304682b7,
-    0x304702c9,
-    0x304782d5,
-    0x304802e1,
-    0x304882ef,
-    0x30490308,
-    0x30498316,
-    0x304a032b,
-    0x304a8343,
-    0x304b034d,
-    0x304b8361,
-    0x304c0372,
-    0x304c8382,
-    0x304d038f,
-    0x304d83a0,
-    0x304e03b0,
-    0x304e83c2,
-    0x304f03d3,
-    0x304f83e2,
-    0x305003f6,
-    0x30508404,
-    0x30510413,
-    0x3051841c,
-    0x343209d6,
-    0x343289e6,
-    0x343309f1,
-    0x343389fe,
-    0x38320a07,
-    0x38328a1f,
-    0x38330a32,
-    0x38338a3c,
-    0x3c320aeb,
-    0x3c328af9,
-    0x3c330b10,
-    0x3c338b24,
-    0x3c340b56,
-    0x3c348b67,
-    0x3c350b73,
-    0x3c358ba0,
-    0x3c360bb2,
-    0x3c368bdb,
-    0x3c370be8,
-    0x3c378bf5,
-    0x3c380c03,
-    0x3c388c10,
-    0x3c390c1d,
-    0x3c398c41,
-    0x3c3a0c51,
-    0x3c3a8c69,
-    0x3c3b0c7e,
-    0x3c3b8c93,
-    0x3c3c0ca0,
-    0x3c3c8cb3,
-    0x3c3d0cc6,
-    0x3c3d8cea,
-    0x3c3e0d12,
-    0x3c3e8d2b,
-    0x3c3f0d41,
-    0x3c3f8d4e,
-    0x3c400d61,
-    0x3c408d72,
-    0x3c410d83,
-    0x3c418d9c,
-    0x3c420db5,
-    0x3c428dcb,
-    0x3c430de8,
-    0x3c438dfe,
-    0x3c440e82,
-    0x3c448ea9,
-    0x3c450ec7,
-    0x3c458ee1,
-    0x3c460ef9,
-    0x3c468f11,
-    0x3c470f3c,
-    0x3c478f67,
-    0x3c480f88,
-    0x3c488fb1,
-    0x3c490fcc,
-    0x3c498ff5,
-    0x3c4a1002,
-    0x3c4a9019,
-    0x3c4b1030,
-    0x3c4b9059,
-    0x3c4c1069,
-    0x3c4c9075,
-    0x3c4d108d,
-    0x3c4d90a0,
-    0x3c4e10b1,
-    0x3c4e90c2,
-    0x3c4f10e8,
-    0x3c4f8adf,
-    0x3c500e1a,
-    0x3c508e3a,
-    0x3c510e67,
-    0x3c518fe7,
-    0x3c5210d2,
-    0x3c528b87,
-    0x3c530b3f,
-    0x40321bb9,
-    0x40329bf2,
-    0x40331c1a,
-    0x40339c32,
-    0x40341c50,
-    0x40349cb6,
-    0x40351ccd,
-    0x40359ce9,
-    0x40361d05,
-    0x40369d1f,
-    0x40371d3e,
-    0x40379d5d,
-    0x40381d75,
-    0x40389d92,
-    0x40391db5,
-    0x40399dd2,
-    0x403a1e07,
-    0x403a9e61,
-    0x403b1e76,
-    0x403b9e92,
-    0x403c1eac,
-    0x403c9eb7,
-    0x403d1eda,
-    0x403d9efe,
-    0x403e1f14,
-    0x403e9f1e,
-    0x403f1f2a,
-    0x403f9f3b,
-    0x40401f53,
-    0x40409f5b,
-    0x40411f64,
-    0x40419f6d,
-    0x40421f95,
-    0x40429fa9,
-    0x40431fb4,
-    0x40439fc0,
-    0x40442014,
-    0x4044a020,
-    0x4045202d,
-    0x4045a040,
-    0x40462058,
-    0x4046a070,
-    0x40472086,
-    0x4047a0a1,
-    0x404820bc,
-    0x4048a0d0,
-    0x404920e9,
-    0x4049a102,
-    0x404a211c,
-    0x404aa126,
-    0x404b1e29,
-    0x404b9e48,
-    0x404c2136,
-    0x404ca144,
-    0x404d2151,
-    0x404da165,
-    0x404e217d,
-    0x404ea18b,
-    0x404f21b5,
-    0x404fa1cc,
-    0x405021de,
-    0x4050a20f,
-    0x40512240,
-    0x4051a255,
-    0x40522278,
-    0x4052a298,
-    0x405322ad,
-    0x4053a2bd,
-    0x4054a2c9,
-    0x405522df,
-    0x4055a31f,
-    0x4056232c,
-    0x4056a336,
-    0x40572344,
-    0x4057a35f,
-    0x4058237a,
-    0x4058a399,
-    0x405923ae,
-    0x4059a3c3,
-    0x405a23e0,
-    0x405aa3f4,
-    0x405b2410,
-    0x405ba426,
-    0x405c2443,
-    0x405ca455,
-    0x405d246c,
-    0x405da47d,
-    0x405e2499,
-    0x405ea4ad,
-    0x405f24bd,
-    0x405fa4d9,
-    0x406024ee,
-    0x4060a504,
-    0x40612521,
-    0x4061a53a,
-    0x40622564,
-    0x4062a56d,
-    0x4063257d,
-    0x4063a5b6,
-    0x406425cc,
-    0x4064a5ea,
-    0x406525ff,
-    0x4065a61c,
-    0x40662633,
-    0x4066a651,
-    0x4067266e,
-    0x4067a685,
-    0x406826a3,
-    0x4068a6ba,
-    0x406926d2,
-    0x4069a6e3,
-    0x406a26f6,
-    0x406aa709,
-    0x406b271d,
-    0x406ba741,
-    0x406c275c,
-    0x406ca77d,
-    0x406d27a1,
-    0x406da7bc,
-    0x406e27dd,
-    0x406ea7f2,
-    0x406f280b,
-    0x406fa818,
-    0x40702826,
-    0x4070a833,
-    0x40712850,
-    0x4071a870,
-    0x4072288b,
-    0x4072a8a4,
-    0x407328bb,
-    0x4073a8d5,
-    0x407428f9,
-    0x4074a90f,
-    0x40752923,
-    0x4075a938,
-    0x40762952,
-    0x4076a964,
-    0x40772979,
-    0x4077a99f,
-    0x407829bc,
-    0x4078a9df,
-    0x40792a05,
-    0x4079aa22,
-    0x407a2a45,
-    0x407aaa61,
-    0x407b2a7d,
-    0x407baa8f,
-    0x407c2a9c,
-    0x407e2aa9,
-    0x407eaabf,
-    0x407f2ad7,
-    0x407faaea,
-    0x40802aff,
-    0x4080ab18,
-    0x40812b36,
-    0x4081ab56,
-    0x40822b5f,
-    0x4082ab7b,
-    0x40832b84,
-    0x4083a19a,
-    0x40842229,
-    0x4084a1f9,
-    0x408525a5,
-    0x4085a589,
-    0x40861c8e,
-    0x40869ca1,
-    0x40871ff4,
-    0x4087a003,
-    0x40881bfe,
-    0x40889f7d,
-    0x40891fdb,
-    0x4089a54d,
-    0x408a1b84,
-    0x408a9b95,
-    0x408b1ba7,
-    0x408ba266,
-    0x408c1df0,
-    0x408c9e17,
-    0x408d22fd,
-    0x408d9bd3,
-    0x408e1c6f,
-    0x4432042a,
-    0x4432843c,
-    0x44330445,
-    0x4433844d,
-    0x4434045a,
-    0x44348475,
-    0x44350490,
-    0x443584b0,
-    0x443604cc,
-    0x443684ed,
-    0x443704f4,
-    0x44378502,
-    0x4438050c,
-    0x44388518,
-    0x44390522,
-    0x4439852d,
-    0x443a0537,
-    0x443a8541,
-    0x443b046a,
-    0x4c3217ea,
-    0x4c3297f9,
-    0x4c331808,
-    0x4c339821,
-    0x4c34183c,
-    0x4c349858,
-    0x4c35186a,
-    0x4c359878,
-    0x4c36188d,
-    0x4c36989e,
-    0x4c3718ac,
-    0x4c3798ba,
-    0x4c3818cc,
-    0x4c3898dc,
-    0x4c3918e6,
-    0x4c3998fe,
-    0x4c3a1916,
-    0x4c3a9929,
-    0x50323053,
-    0x5032b068,
-    0x50333079,
-    0x5033b08c,
-    0x5034309d,
-    0x5034b0b0,
-    0x503530bf,
-    0x5035b0d4,
-    0x503630e4,
-    0x5036b0f3,
-    0x50373104,
-    0x5037b114,
-    0x50383125,
-    0x5038b138,
-    0x5039314a,
-    0x5039b160,
-    0x503a3172,
-    0x503ab183,
-    0x503b3194,
-    0x503bb1a5,
-    0x503c31b0,
-    0x503cb1bc,
-    0x503d31c7,
-    0x503db1d2,
-    0x503e31df,
-    0x503eb1f4,
-    0x503f3202,
-    0x503fb216,
-    0x50403229,
-    0x5040b23a,
-    0x50413254,
-    0x5041b263,
-    0x5042326c,
-    0x5042b27b,
-    0x5043328d,
-    0x5043b299,
-    0x504432a1,
-    0x5044b2b4,
-    0x504532c5,
-    0x5045b2db,
-    0x504632e7,
-    0x5046b2fb,
-    0x50473309,
-    0x5047b31d,
-    0x50483337,
-    0x5048b34b,
-    0x50493361,
-    0x5049b378,
-    0x504a338a,
-    0x504ab39e,
-    0x504b33b3,
-    0x504bb3ca,
-    0x504c33de,
-    0x504cb3e7,
-    0x504d33ef,
-    0x504db3fe,
-    0x504e340e,
-    0x68321109,
-    0x6832911a,
-    0x6833112a,
-    0x68339138,
-    0x68341145,
-    0x6c3210f8,
-    0x74320a89,
-    0x74328a9b,
-    0x783206e8,
-    0x7832871b,
-    0x7833072d,
-    0x7833873f,
-    0x78340753,
-    0x78348767,
-    0x78350785,
-    0x78358797,
-    0x783607ab,
-    0x78368819,
-    0x7837082b,
-    0x7837883d,
-    0x7838084f,
-    0x78388866,
-    0x7839087d,
-    0x78398894,
-    0x783a08b0,
-    0x783a88cc,
-    0x783b08e8,
-    0x783b88fe,
-    0x783c0914,
-    0x783c892a,
-    0x783d0947,
-    0x783d8956,
-    0x783e0965,
-    0x783e8974,
-    0x783f0990,
-    0x783f899e,
-    0x784009ac,
-    0x784089ba,
-    0x784109c7,
-    0x784186fa,
-    0x784207bf,
-    0x784287dd,
-    0x784307fb,
-    0x80321611,
-};
-
-const size_t kOpenSSLFunctionValuesLen = sizeof(kOpenSSLFunctionValues) / sizeof(kOpenSSLFunctionValues[0]);
-
-const char kOpenSSLFunctionStringData[] =
-    "ASN1_BIT_STRING_set_bit\0"
-    "ASN1_ENUMERATED_set\0"
-    "ASN1_ENUMERATED_to_BN\0"
-    "ASN1_GENERALIZEDTIME_adj\0"
-    "ASN1_INTEGER_set\0"
-    "ASN1_INTEGER_to_BN\0"
-    "ASN1_OBJECT_new\0"
-    "ASN1_PCTX_new\0"
-    "ASN1_STRING_TABLE_add\0"
-    "ASN1_STRING_set\0"
-    "ASN1_STRING_type_new\0"
-    "ASN1_TIME_adj\0"
-    "ASN1_UTCTIME_adj\0"
-    "ASN1_d2i_fp\0"
-    "ASN1_dup\0"
-    "ASN1_generate_v3\0"
-    "ASN1_get_object\0"
-    "ASN1_i2d_bio\0"
-    "ASN1_i2d_fp\0"
-    "ASN1_item_d2i_fp\0"
-    "ASN1_item_dup\0"
-    "ASN1_item_ex_d2i\0"
-    "ASN1_item_i2d_bio\0"
-    "ASN1_item_i2d_fp\0"
-    "ASN1_item_pack\0"
-    "ASN1_item_unpack\0"
-    "ASN1_mbstring_ncopy\0"
-    "ASN1_template_new\0"
-    "BIO_new_NDEF\0"
-    "BN_to_ASN1_ENUMERATED\0"
-    "BN_to_ASN1_INTEGER\0"
-    "a2d_ASN1_OBJECT\0"
-    "a2i_ASN1_ENUMERATED\0"
-    "a2i_ASN1_INTEGER\0"
-    "a2i_ASN1_STRING\0"
-    "append_exp\0"
-    "asn1_cb\0"
-    "asn1_check_tlen\0"
-    "asn1_collate_primitive\0"
-    "asn1_collect\0"
-    "asn1_d2i_ex_primitive\0"
-    "asn1_d2i_read_bio\0"
-    "asn1_do_adb\0"
-    "asn1_ex_c2i\0"
-    "asn1_find_end\0"
-    "asn1_item_ex_combine_new\0"
-    "asn1_str2type\0"
-    "asn1_template_ex_d2i\0"
-    "asn1_template_noexp_d2i\0"
-    "bitstr_cb\0"
-    "c2i_ASN1_BIT_STRING\0"
-    "c2i_ASN1_INTEGER\0"
-    "c2i_ASN1_OBJECT\0"
-    "collect_data\0"
-    "d2i_ASN1_BOOLEAN\0"
-    "d2i_ASN1_OBJECT\0"
-    "d2i_ASN1_UINTEGER\0"
-    "d2i_ASN1_UTCTIME\0"
-    "d2i_ASN1_bytes\0"
-    "d2i_ASN1_type_bytes\0"
-    "i2d_ASN1_TIME\0"
-    "i2d_PrivateKey\0"
-    "long_c2i\0"
-    "parse_tagging\0"
-    "BIO_callback_ctrl\0"
-    "BIO_ctrl\0"
-    "BIO_new\0"
-    "BIO_new_file\0"
-    "BIO_new_mem_buf\0"
-    "BIO_printf\0"
-    "BIO_zero_copy_get_read_buf\0"
-    "BIO_zero_copy_get_read_buf_done\0"
-    "BIO_zero_copy_get_write_buf\0"
-    "BIO_zero_copy_get_write_buf_done\0"
-    "bio_io\0"
-    "bio_make_pair\0"
-    "bio_write\0"
-    "buffer_ctrl\0"
-    "conn_ctrl\0"
-    "conn_state\0"
-    "file_ctrl\0"
-    "file_read\0"
-    "mem_write\0"
-    "BN_CTX_get\0"
-    "BN_CTX_new\0"
-    "BN_CTX_start\0"
-    "BN_bn2dec\0"
-    "BN_bn2hex\0"
-    "BN_div\0"
-    "BN_div_recp\0"
-    "BN_exp\0"
-    "BN_generate_dsa_nonce\0"
-    "BN_generate_prime_ex\0"
-    "BN_lshift\0"
-    "BN_mod_exp2_mont\0"
-    "BN_mod_exp_mont\0"
-    "BN_mod_exp_mont_consttime\0"
-    "BN_mod_exp_mont_word\0"
-    "BN_mod_inverse\0"
-    "BN_mod_inverse_no_branch\0"
-    "BN_mod_lshift_quick\0"
-    "BN_mod_sqrt\0"
-    "BN_new\0"
-    "BN_rand\0"
-    "BN_rand_range\0"
-    "BN_rshift\0"
-    "BN_sqrt\0"
-    "BN_usub\0"
-    "bn_wexpand\0"
-    "mod_exp_recp\0"
-    "BUF_MEM_new\0"
-    "BUF_memdup\0"
-    "BUF_strndup\0"
-    "buf_mem_grow\0"
-    "EVP_AEAD_CTX_init\0"
-    "EVP_AEAD_CTX_init_with_direction\0"
-    "EVP_AEAD_CTX_open\0"
-    "EVP_AEAD_CTX_seal\0"
-    "EVP_CIPHER_CTX_copy\0"
-    "EVP_CIPHER_CTX_ctrl\0"
-    "EVP_CIPHER_CTX_set_key_length\0"
-    "EVP_CipherInit_ex\0"
-    "EVP_DecryptFinal_ex\0"
-    "EVP_EncryptFinal_ex\0"
-    "aead_aes_ctr_hmac_sha256_init\0"
-    "aead_aes_ctr_hmac_sha256_open\0"
-    "aead_aes_ctr_hmac_sha256_seal\0"
-    "aead_aes_gcm_init\0"
-    "aead_aes_gcm_open\0"
-    "aead_aes_gcm_seal\0"
-    "aead_aes_key_wrap_init\0"
-    "aead_aes_key_wrap_open\0"
-    "aead_aes_key_wrap_seal\0"
-    "aead_chacha20_poly1305_init\0"
-    "aead_chacha20_poly1305_open\0"
-    "aead_chacha20_poly1305_seal\0"
-    "aead_rc4_md5_tls_init\0"
-    "aead_rc4_md5_tls_open\0"
-    "aead_rc4_md5_tls_seal\0"
-    "aead_ssl3_ensure_cipher_init\0"
-    "aead_ssl3_init\0"
-    "aead_ssl3_open\0"
-    "aead_ssl3_seal\0"
-    "aead_tls_ensure_cipher_init\0"
-    "aead_tls_init\0"
-    "aead_tls_open\0"
-    "aead_tls_seal\0"
-    "aes_init_key\0"
-    "aesni_init_key\0"
-    "CONF_parse_list\0"
-    "NCONF_load\0"
-    "def_load_bio\0"
-    "str_copy\0"
-    "CRYPTO_get_ex_new_index\0"
-    "CRYPTO_set_ex_data\0"
-    "get_class\0"
-    "get_func_pointers\0"
-    "DH_new_method\0"
-    "compute_key\0"
-    "generate_key\0"
-    "generate_parameters\0"
-    "EVP_DigestInit_ex\0"
-    "EVP_MD_CTX_copy_ex\0"
-    "DSA_new_method\0"
-    "dsa_sig_cb\0"
-    "sign\0"
-    "sign_setup\0"
-    "verify\0"
-    "BN_to_felem\0"
-    "EC_GROUP_copy\0"
-    "EC_GROUP_get_curve_GFp\0"
-    "EC_GROUP_get_degree\0"
-    "EC_GROUP_new_by_curve_name\0"
-    "EC_GROUP_new_curve_GFp\0"
-    "EC_KEY_check_key\0"
-    "EC_KEY_copy\0"
-    "EC_KEY_generate_key\0"
-    "EC_KEY_new_by_curve_name\0"
-    "EC_KEY_new_method\0"
-    "EC_KEY_set_public_key_affine_coordinates\0"
-    "EC_POINT_add\0"
-    "EC_POINT_cmp\0"
-    "EC_POINT_copy\0"
-    "EC_POINT_dbl\0"
-    "EC_POINT_dup\0"
-    "EC_POINT_get_affine_coordinates_GFp\0"
-    "EC_POINT_invert\0"
-    "EC_POINT_is_at_infinity\0"
-    "EC_POINT_is_on_curve\0"
-    "EC_POINT_make_affine\0"
-    "EC_POINT_new\0"
-    "EC_POINT_oct2point\0"
-    "EC_POINT_point2oct\0"
-    "EC_POINT_set_affine_coordinates_GFp\0"
-    "EC_POINT_set_compressed_coordinates_GFp\0"
-    "EC_POINT_set_to_infinity\0"
-    "EC_POINTs_make_affine\0"
-    "compute_wNAF\0"
-    "d2i_ECPKParameters\0"
-    "d2i_ECParameters\0"
-    "d2i_ECPrivateKey\0"
-    "ec_GFp_mont_field_decode\0"
-    "ec_GFp_mont_field_encode\0"
-    "ec_GFp_mont_field_mul\0"
-    "ec_GFp_mont_field_set_to_one\0"
-    "ec_GFp_mont_field_sqr\0"
-    "ec_GFp_mont_group_set_curve\0"
-    "ec_GFp_nistp256_group_set_curve\0"
-    "ec_GFp_nistp256_point_get_affine_coordinates\0"
-    "ec_GFp_nistp256_points_mul\0"
-    "ec_GFp_simple_group_check_discriminant\0"
-    "ec_GFp_simple_group_set_curve\0"
-    "ec_GFp_simple_make_affine\0"
-    "ec_GFp_simple_oct2point\0"
-    "ec_GFp_simple_point2oct\0"
-    "ec_GFp_simple_point_get_affine_coordinates\0"
-    "ec_GFp_simple_point_set_affine_coordinates\0"
-    "ec_GFp_simple_points_make_affine\0"
-    "ec_GFp_simple_set_compressed_coordinates\0"
-    "ec_asn1_group2pkparameters\0"
-    "ec_asn1_pkparameters2group\0"
-    "ec_group_copy\0"
-    "ec_group_new\0"
-    "ec_group_new_curve_GFp\0"
-    "ec_group_new_from_data\0"
-    "ec_point_set_Jprojective_coordinates_GFp\0"
-    "ec_pre_comp_new\0"
-    "ec_wNAF_mul\0"
-    "ec_wNAF_precompute_mult\0"
-    "i2d_ECPKParameters\0"
-    "i2d_ECParameters\0"
-    "i2d_ECPrivateKey\0"
-    "i2o_ECPublicKey\0"
-    "nistp256_pre_comp_new\0"
-    "o2i_ECPublicKey\0"
-    "ECDH_compute_key\0"
-    "ECDSA_do_sign_ex\0"
-    "ECDSA_do_verify\0"
-    "ECDSA_sign_ex\0"
-    "digest_to_bn\0"
-    "ecdsa_sign_setup\0"
-    "EVP_DigestSignAlgorithm\0"
-    "EVP_DigestVerifyInitFromAlgorithm\0"
-    "EVP_PKEY_CTX_ctrl\0"
-    "EVP_PKEY_CTX_dup\0"
-    "EVP_PKEY_CTX_get0_rsa_oaep_label\0"
-    "EVP_PKEY_copy_parameters\0"
-    "EVP_PKEY_decrypt\0"
-    "EVP_PKEY_decrypt_init\0"
-    "EVP_PKEY_derive\0"
-    "EVP_PKEY_derive_init\0"
-    "EVP_PKEY_derive_set_peer\0"
-    "EVP_PKEY_encrypt\0"
-    "EVP_PKEY_encrypt_init\0"
-    "EVP_PKEY_get1_DH\0"
-    "EVP_PKEY_get1_DSA\0"
-    "EVP_PKEY_get1_EC_KEY\0"
-    "EVP_PKEY_get1_RSA\0"
-    "EVP_PKEY_keygen\0"
-    "EVP_PKEY_keygen_init\0"
-    "EVP_PKEY_new\0"
-    "EVP_PKEY_set_type\0"
-    "EVP_PKEY_sign\0"
-    "EVP_PKEY_sign_init\0"
-    "EVP_PKEY_verify\0"
-    "EVP_PKEY_verify_init\0"
-    "check_padding_md\0"
-    "d2i_AutoPrivateKey\0"
-    "d2i_PrivateKey\0"
-    "do_EC_KEY_print\0"
-    "do_dsa_print\0"
-    "do_rsa_print\0"
-    "do_sigver_init\0"
-    "dsa_param_decode\0"
-    "dsa_priv_decode\0"
-    "dsa_priv_encode\0"
-    "dsa_pub_decode\0"
-    "dsa_pub_encode\0"
-    "dsa_sig_print\0"
-    "eckey_param2type\0"
-    "eckey_param_decode\0"
-    "eckey_priv_decode\0"
-    "eckey_priv_encode\0"
-    "eckey_pub_decode\0"
-    "eckey_pub_encode\0"
-    "eckey_type2param\0"
-    "evp_pkey_ctx_new\0"
-    "hmac_signctx\0"
-    "i2d_PublicKey\0"
-    "old_dsa_priv_decode\0"
-    "old_ec_priv_decode\0"
-    "old_rsa_priv_decode\0"
-    "pkey_ec_ctrl\0"
-    "pkey_ec_derive\0"
-    "pkey_ec_keygen\0"
-    "pkey_ec_paramgen\0"
-    "pkey_ec_sign\0"
-    "pkey_hmac_ctrl\0"
-    "pkey_rsa_ctrl\0"
-    "pkey_rsa_decrypt\0"
-    "pkey_rsa_encrypt\0"
-    "pkey_rsa_sign\0"
-    "rsa_algor_to_md\0"
-    "rsa_digest_verify_init_from_algorithm\0"
-    "rsa_mgf1_to_md\0"
-    "rsa_priv_decode\0"
-    "rsa_priv_encode\0"
-    "rsa_pss_to_ctx\0"
-    "rsa_pub_decode\0"
-    "HKDF\0"
-    "OBJ_create\0"
-    "OBJ_dup\0"
-    "OBJ_nid2obj\0"
-    "OBJ_txt2obj\0"
-    "PEM_ASN1_read\0"
-    "PEM_ASN1_read_bio\0"
-    "PEM_ASN1_write\0"
-    "PEM_ASN1_write_bio\0"
-    "PEM_X509_INFO_read\0"
-    "PEM_X509_INFO_read_bio\0"
-    "PEM_X509_INFO_write_bio\0"
-    "PEM_do_header\0"
-    "PEM_get_EVP_CIPHER_INFO\0"
-    "PEM_read\0"
-    "PEM_read_DHparams\0"
-    "PEM_read_PrivateKey\0"
-    "PEM_read_bio\0"
-    "PEM_read_bio_DHparams\0"
-    "PEM_read_bio_Parameters\0"
-    "PEM_read_bio_PrivateKey\0"
-    "PEM_write\0"
-    "PEM_write_PrivateKey\0"
-    "PEM_write_bio\0"
-    "d2i_PKCS8PrivateKey_bio\0"
-    "d2i_PKCS8PrivateKey_fp\0"
-    "do_pk8pkey\0"
-    "do_pk8pkey_fp\0"
-    "load_iv\0"
-    "EVP_PKCS82PKEY\0"
-    "EVP_PKEY2PKCS8\0"
-    "PKCS12_get_key_and_certs\0"
-    "PKCS12_handle_content_info\0"
-    "PKCS12_handle_content_infos\0"
-    "PKCS5_pbe2_set_iv\0"
-    "PKCS5_pbe_set\0"
-    "PKCS5_pbe_set0_algor\0"
-    "PKCS5_pbkdf2_set\0"
-    "PKCS8_decrypt\0"
-    "PKCS8_encrypt\0"
-    "PKCS8_encrypt_pbe\0"
-    "pbe_cipher_init\0"
-    "pbe_crypt\0"
-    "pkcs12_item_decrypt_d2i\0"
-    "pkcs12_item_i2d_encrypt\0"
-    "pkcs12_key_gen_raw\0"
-    "pkcs12_pbe_keyivgen\0"
-    "BN_BLINDING_convert_ex\0"
-    "BN_BLINDING_create_param\0"
-    "BN_BLINDING_invert_ex\0"
-    "BN_BLINDING_new\0"
-    "BN_BLINDING_update\0"
-    "RSA_add_pkcs1_prefix\0"
-    "RSA_check_key\0"
-    "RSA_new_method\0"
-    "RSA_padding_add_PKCS1_OAEP_mgf1\0"
-    "RSA_padding_add_PKCS1_PSS_mgf1\0"
-    "RSA_padding_add_PKCS1_type_1\0"
-    "RSA_padding_add_PKCS1_type_2\0"
-    "RSA_padding_add_none\0"
-    "RSA_padding_check_PKCS1_OAEP_mgf1\0"
-    "RSA_padding_check_PKCS1_type_1\0"
-    "RSA_padding_check_PKCS1_type_2\0"
-    "RSA_padding_check_none\0"
-    "RSA_recover_crt_params\0"
-    "RSA_sign\0"
-    "RSA_verify\0"
-    "RSA_verify_PKCS1_PSS_mgf1\0"
-    "decrypt\0"
-    "encrypt\0"
-    "keygen\0"
-    "keygen_multiprime\0"
-    "private_transform\0"
-    "rsa_setup_blinding\0"
-    "sign_raw\0"
-    "verify_raw\0"
-    "SSL_AEAD_CTX_new\0"
-    "SSL_AEAD_CTX_open\0"
-    "SSL_AEAD_CTX_seal\0"
-    "SSL_CTX_check_private_key\0"
-    "SSL_CTX_get_tlsext_ticket_keys\0"
-    "SSL_CTX_new\0"
-    "SSL_CTX_set1_tls_channel_id\0"
-    "SSL_CTX_set_cipher_list\0"
-    "SSL_CTX_set_cipher_list_tls11\0"
-    "SSL_CTX_set_session_id_context\0"
-    "SSL_CTX_set_tlsext_ticket_keys\0"
-    "SSL_CTX_set_tmp_dh\0"
-    "SSL_CTX_set_tmp_ecdh\0"
-    "SSL_CTX_use_PrivateKey\0"
-    "SSL_CTX_use_PrivateKey_ASN1\0"
-    "SSL_CTX_use_PrivateKey_file\0"
-    "SSL_CTX_use_RSAPrivateKey\0"
-    "SSL_CTX_use_RSAPrivateKey_ASN1\0"
-    "SSL_CTX_use_RSAPrivateKey_file\0"
-    "SSL_CTX_use_certificate\0"
-    "SSL_CTX_use_certificate_ASN1\0"
-    "SSL_CTX_use_certificate_chain_file\0"
-    "SSL_CTX_use_certificate_file\0"
-    "SSL_CTX_use_psk_identity_hint\0"
-    "SSL_SESSION_from_bytes\0"
-    "SSL_SESSION_new\0"
-    "SSL_SESSION_parse\0"
-    "SSL_SESSION_parse_octet_string\0"
-    "SSL_SESSION_parse_string\0"
-    "SSL_SESSION_print_fp\0"
-    "SSL_SESSION_set1_id_context\0"
-    "SSL_SESSION_to_bytes_full\0"
-    "SSL_accept\0"
-    "SSL_add_dir_cert_subjects_to_stack\0"
-    "SSL_add_file_cert_subjects_to_stack\0"
-    "SSL_check_private_key\0"
-    "SSL_clear\0"
-    "SSL_connect\0"
-    "SSL_do_handshake\0"
-    "SSL_load_client_CA_file\0"
-    "SSL_new\0"
-    "SSL_peek\0"
-    "SSL_read\0"
-    "SSL_renegotiate\0"
-    "SSL_set1_tls_channel_id\0"
-    "SSL_set_cipher_list\0"
-    "SSL_set_fd\0"
-    "SSL_set_rfd\0"
-    "SSL_set_session_id_context\0"
-    "SSL_set_tlsext_host_name\0"
-    "SSL_set_tmp_dh\0"
-    "SSL_set_tmp_ecdh\0"
-    "SSL_set_wfd\0"
-    "SSL_shutdown\0"
-    "SSL_use_PrivateKey\0"
-    "SSL_use_PrivateKey_ASN1\0"
-    "SSL_use_PrivateKey_file\0"
-    "SSL_use_RSAPrivateKey\0"
-    "SSL_use_RSAPrivateKey_ASN1\0"
-    "SSL_use_RSAPrivateKey_file\0"
-    "SSL_use_certificate\0"
-    "SSL_use_certificate_ASN1\0"
-    "SSL_use_certificate_file\0"
-    "SSL_use_psk_identity_hint\0"
-    "SSL_write\0"
-    "d2i_SSL_SESSION\0"
-    "do_ssl3_write\0"
-    "dtls1_accept\0"
-    "dtls1_buffer_record\0"
-    "dtls1_check_timeout_num\0"
-    "dtls1_connect\0"
-    "dtls1_do_write\0"
-    "dtls1_get_buffered_message\0"
-    "dtls1_get_hello_verify\0"
-    "dtls1_get_message\0"
-    "dtls1_get_message_fragment\0"
-    "dtls1_hm_fragment_new\0"
-    "dtls1_preprocess_fragment\0"
-    "dtls1_process_fragment\0"
-    "dtls1_process_record\0"
-    "dtls1_read_bytes\0"
-    "dtls1_seal_record\0"
-    "dtls1_send_hello_verify_request\0"
-    "dtls1_write_app_data\0"
-    "i2d_SSL_SESSION\0"
-    "ssl3_accept\0"
-    "ssl3_cert_verify_hash\0"
-    "ssl3_check_cert_and_algorithm\0"
-    "ssl3_check_certificate_for_cipher\0"
-    "ssl3_connect\0"
-    "ssl3_ctrl\0"
-    "ssl3_ctx_ctrl\0"
-    "ssl3_digest_cached_records\0"
-    "ssl3_do_change_cipher_spec\0"
-    "ssl3_expect_change_cipher_spec\0"
-    "ssl3_get_cert_status\0"
-    "ssl3_get_cert_verify\0"
-    "ssl3_get_certificate_request\0"
-    "ssl3_get_channel_id\0"
-    "ssl3_get_client_certificate\0"
-    "ssl3_get_client_hello\0"
-    "ssl3_get_client_key_exchange\0"
-    "ssl3_get_finished\0"
-    "ssl3_get_initial_bytes\0"
-    "ssl3_get_message\0"
-    "ssl3_get_new_session_ticket\0"
-    "ssl3_get_next_proto\0"
-    "ssl3_get_record\0"
-    "ssl3_get_server_certificate\0"
-    "ssl3_get_server_done\0"
-    "ssl3_get_server_hello\0"
-    "ssl3_get_server_key_exchange\0"
-    "ssl3_get_v2_client_hello\0"
-    "ssl3_handshake_mac\0"
-    "ssl3_output_cert_chain\0"
-    "ssl3_prf\0"
-    "ssl3_read_bytes\0"
-    "ssl3_read_n\0"
-    "ssl3_record_sequence_update\0"
-    "ssl3_seal_record\0"
-    "ssl3_send_cert_verify\0"
-    "ssl3_send_certificate_request\0"
-    "ssl3_send_channel_id\0"
-    "ssl3_send_client_certificate\0"
-    "ssl3_send_client_hello\0"
-    "ssl3_send_client_key_exchange\0"
-    "ssl3_send_server_certificate\0"
-    "ssl3_send_server_hello\0"
-    "ssl3_send_server_key_exchange\0"
-    "ssl3_setup_read_buffer\0"
-    "ssl3_setup_write_buffer\0"
-    "ssl3_write_bytes\0"
-    "ssl3_write_pending\0"
-    "ssl_add_cert_chain\0"
-    "ssl_add_cert_to_buf\0"
-    "ssl_add_clienthello_renegotiate_ext\0"
-    "ssl_add_clienthello_tlsext\0"
-    "ssl_add_clienthello_use_srtp_ext\0"
-    "ssl_add_serverhello_renegotiate_ext\0"
-    "ssl_add_serverhello_tlsext\0"
-    "ssl_add_serverhello_use_srtp_ext\0"
-    "ssl_build_cert_chain\0"
-    "ssl_bytes_to_cipher_list\0"
-    "ssl_cert_dup\0"
-    "ssl_cert_inst\0"
-    "ssl_cert_new\0"
-    "ssl_check_serverhello_tlsext\0"
-    "ssl_check_srvr_ecc_cert_and_alg\0"
-    "ssl_cipher_process_rulestr\0"
-    "ssl_cipher_strength_sort\0"
-    "ssl_create_cipher_list\0"
-    "ssl_ctx_log_master_secret\0"
-    "ssl_ctx_log_rsa_client_key_exchange\0"
-    "ssl_ctx_make_profiles\0"
-    "ssl_get_new_session\0"
-    "ssl_get_prev_session\0"
-    "ssl_get_server_cert_index\0"
-    "ssl_get_sign_pkey\0"
-    "ssl_init_wbio_buffer\0"
-    "ssl_parse_clienthello_renegotiate_ext\0"
-    "ssl_parse_clienthello_tlsext\0"
-    "ssl_parse_clienthello_use_srtp_ext\0"
-    "ssl_parse_serverhello_renegotiate_ext\0"
-    "ssl_parse_serverhello_tlsext\0"
-    "ssl_parse_serverhello_use_srtp_ext\0"
-    "ssl_scan_clienthello_tlsext\0"
-    "ssl_scan_serverhello_tlsext\0"
-    "ssl_sess_cert_new\0"
-    "ssl_set_cert\0"
-    "ssl_set_pkey\0"
-    "ssl_verify_cert_chain\0"
-    "tls12_check_peer_sigalg\0"
-    "tls1_aead_ctx_init\0"
-    "tls1_cert_verify_mac\0"
-    "tls1_change_cipher_state\0"
-    "tls1_change_cipher_state_aead\0"
-    "tls1_check_duplicate_extensions\0"
-    "tls1_enc\0"
-    "tls1_export_keying_material\0"
-    "tls1_prf\0"
-    "tls1_setup_key_block\0"
-    "ASN1_digest\0"
-    "ASN1_item_sign_ctx\0"
-    "ASN1_item_verify\0"
-    "NETSCAPE_SPKI_b64_decode\0"
-    "NETSCAPE_SPKI_b64_encode\0"
-    "PKCS7_get_CRLs\0"
-    "PKCS7_get_certificates\0"
-    "X509_ATTRIBUTE_create_by_NID\0"
-    "X509_ATTRIBUTE_create_by_OBJ\0"
-    "X509_ATTRIBUTE_create_by_txt\0"
-    "X509_ATTRIBUTE_get0_data\0"
-    "X509_ATTRIBUTE_set1_data\0"
-    "X509_CRL_add0_revoked\0"
-    "X509_CRL_diff\0"
-    "X509_CRL_print_fp\0"
-    "X509_EXTENSION_create_by_NID\0"
-    "X509_EXTENSION_create_by_OBJ\0"
-    "X509_INFO_new\0"
-    "X509_NAME_ENTRY_create_by_NID\0"
-    "X509_NAME_ENTRY_create_by_txt\0"
-    "X509_NAME_ENTRY_set_object\0"
-    "X509_NAME_add_entry\0"
-    "X509_NAME_oneline\0"
-    "X509_NAME_print\0"
-    "X509_PKEY_new\0"
-    "X509_PUBKEY_get\0"
-    "X509_PUBKEY_set\0"
-    "X509_REQ_check_private_key\0"
-    "X509_REQ_print_ex\0"
-    "X509_REQ_print_fp\0"
-    "X509_REQ_to_X509\0"
-    "X509_STORE_CTX_get1_issuer\0"
-    "X509_STORE_CTX_init\0"
-    "X509_STORE_CTX_new\0"
-    "X509_STORE_CTX_purpose_inherit\0"
-    "X509_STORE_add_cert\0"
-    "X509_STORE_add_crl\0"
-    "X509_TRUST_add\0"
-    "X509_TRUST_set\0"
-    "X509_check_private_key\0"
-    "X509_get_pubkey_parameters\0"
-    "X509_load_cert_crl_file\0"
-    "X509_load_cert_file\0"
-    "X509_load_crl_file\0"
-    "X509_print_ex_fp\0"
-    "X509_to_X509_REQ\0"
-    "X509_verify_cert\0"
-    "X509at_add1_attr\0"
-    "X509v3_add_ext\0"
-    "add_cert_dir\0"
-    "by_file_ctrl\0"
-    "check_policy\0"
-    "dir_ctrl\0"
-    "get_cert_by_subject\0"
-    "i2d_DSA_PUBKEY\0"
-    "i2d_EC_PUBKEY\0"
-    "i2d_RSA_PUBKEY\0"
-    "pkcs7_parse_header\0"
-    "x509_name_encode\0"
-    "x509_name_ex_d2i\0"
-    "x509_name_ex_new\0"
-    "SXNET_add_id_INTEGER\0"
-    "SXNET_add_id_asc\0"
-    "SXNET_add_id_ulong\0"
-    "SXNET_get_id_asc\0"
-    "SXNET_get_id_ulong\0"
-    "X509V3_EXT_add\0"
-    "X509V3_EXT_add_alias\0"
-    "X509V3_EXT_free\0"
-    "X509V3_EXT_i2d\0"
-    "X509V3_EXT_nconf\0"
-    "X509V3_add1_i2d\0"
-    "X509V3_add_value\0"
-    "X509V3_get_section\0"
-    "X509V3_get_string\0"
-    "X509V3_get_value_bool\0"
-    "X509V3_parse_list\0"
-    "X509_PURPOSE_add\0"
-    "X509_PURPOSE_set\0"
-    "a2i_GENERAL_NAME\0"
-    "copy_email\0"
-    "copy_issuer\0"
-    "do_dirname\0"
-    "do_ext_i2d\0"
-    "do_ext_nconf\0"
-    "gnames_from_sectname\0"
-    "hex_to_string\0"
-    "i2s_ASN1_ENUMERATED\0"
-    "i2s_ASN1_IA5STRING\0"
-    "i2s_ASN1_INTEGER\0"
-    "i2v_AUTHORITY_INFO_ACCESS\0"
-    "notice_section\0"
-    "nref_nos\0"
-    "policy_section\0"
-    "process_pci_value\0"
-    "r2i_certpol\0"
-    "r2i_pci\0"
-    "s2i_ASN1_IA5STRING\0"
-    "s2i_ASN1_INTEGER\0"
-    "s2i_ASN1_OCTET_STRING\0"
-    "s2i_skey_id\0"
-    "set_dist_point_name\0"
-    "string_to_hex\0"
-    "v2i_ASN1_BIT_STRING\0"
-    "v2i_AUTHORITY_INFO_ACCESS\0"
-    "v2i_AUTHORITY_KEYID\0"
-    "v2i_BASIC_CONSTRAINTS\0"
-    "v2i_EXTENDED_KEY_USAGE\0"
-    "v2i_GENERAL_NAMES\0"
-    "v2i_GENERAL_NAME_ex\0"
-    "v2i_NAME_CONSTRAINTS\0"
-    "v2i_POLICY_CONSTRAINTS\0"
-    "v2i_POLICY_MAPPINGS\0"
-    "v2i_crld\0"
-    "v2i_idp\0"
-    "v2i_issuer_alt\0"
-    "v2i_subject_alt\0"
-    "v3_generic_extension\0"
-    "";
-
 const uint32_t kOpenSSLReasonValues[] = {
-    0xc3207ba,
-    0xc3287c7,
-    0xc3307d6,
-    0xc3387e6,
-    0xc3407f5,
-    0xc34880e,
-    0xc35081a,
-    0xc358837,
-    0xc360849,
-    0xc368857,
-    0xc370867,
-    0xc378874,
-    0xc380884,
-    0xc38888f,
-    0xc3908a5,
-    0xc3988b4,
-    0xc3a08c8,
-    0x1032146b,
-    0x10329477,
-    0x10331490,
-    0x103394a3,
-    0x10340dd4,
-    0x103494b6,
-    0x103514cb,
-    0x103594fd,
-    0x10361516,
-    0x1036952b,
-    0x10371549,
-    0x10379558,
-    0x10381574,
-    0x1038958f,
-    0x1039159e,
-    0x103995ba,
-    0x103a15d5,
-    0x103a95ec,
-    0x103b15fd,
-    0x103b9611,
-    0x103c1630,
-    0x103c963f,
-    0x103d1656,
-    0x103d9669,
-    0x103e0b5f,
-    0x103e969a,
-    0x103f16ad,
-    0x103f96c7,
-    0x104016d7,
-    0x104096eb,
-    0x10411701,
-    0x10419719,
-    0x1042172e,
-    0x10429742,
-    0x10431754,
-    0x104385d0,
-    0x104408b4,
-    0x10449769,
-    0x10451780,
-    0x10459795,
-    0x104617a3,
-    0x1046967c,
-    0x104714de,
-    0x14320b42,
-    0x14328b50,
-    0x14330b5f,
-    0x14338b71,
+    0xc320838,
+    0xc328852,
+    0xc330861,
+    0xc338871,
+    0xc340880,
+    0xc348899,
+    0xc3508a5,
+    0xc3588c2,
+    0xc3608d4,
+    0xc3688e2,
+    0xc3708f2,
+    0xc3788ff,
+    0xc38090f,
+    0xc38891a,
+    0xc390930,
+    0xc39893f,
+    0xc3a0953,
+    0xc3a8845,
+    0xc3b00ea,
+    0x10320845,
+    0x103293ab,
+    0x103313b7,
+    0x103393d0,
+    0x103413e3,
+    0x10348e8b,
+    0x10350c19,
+    0x103593f6,
+    0x1036140b,
+    0x1036941e,
+    0x1037143d,
+    0x10379456,
+    0x1038146b,
+    0x10389489,
+    0x10391498,
+    0x103994b4,
+    0x103a14cf,
+    0x103a94de,
+    0x103b14fa,
+    0x103b9515,
+    0x103c152c,
+    0x103c80ea,
+    0x103d153d,
+    0x103d9551,
+    0x103e1570,
+    0x103e957f,
+    0x103f1596,
+    0x103f95a9,
+    0x10400bea,
+    0x104095bc,
+    0x104115da,
+    0x104195ed,
+    0x10421607,
+    0x10429617,
+    0x1043162b,
+    0x10439641,
+    0x10441659,
+    0x1044966e,
+    0x10451682,
+    0x10459694,
+    0x104605fb,
+    0x1046893f,
+    0x104716a9,
+    0x104796c0,
+    0x104816d5,
+    0x104896e3,
+    0x14320bcd,
+    0x14328bdb,
+    0x14330bea,
+    0x14338bfc,
+    0x143400ac,
+    0x143480ea,
     0x18320083,
-    0x18328e3a,
-    0x18340e68,
-    0x18348e7c,
-    0x18358eb3,
-    0x18368ee0,
-    0x18370ef3,
-    0x18378f07,
-    0x18380f2b,
-    0x18388f39,
-    0x18390f4f,
-    0x18398f63,
-    0x183a0f73,
-    0x183b0f83,
-    0x183b8f98,
-    0x183c8fc3,
-    0x183d0fd7,
-    0x183d8fe7,
-    0x183e0b8e,
-    0x183e8ff4,
-    0x183f1006,
-    0x183f9011,
-    0x18401021,
-    0x18409032,
-    0x18411043,
-    0x18419055,
-    0x1842107e,
-    0x184290b0,
-    0x184310bf,
-    0x18451128,
-    0x1845913e,
-    0x18461159,
-    0x18468ecb,
-    0x184709cc,
-    0x18478094,
-    0x18480faf,
-    0x184890f4,
-    0x18490e50,
-    0x18498e91,
-    0x184a118f,
-    0x184a910c,
-    0x184b10d3,
-    0x184b8e2a,
-    0x184c1097,
-    0x184c866b,
-    0x184d1174,
-    0x203211b6,
-    0x243211c2,
-    0x243288fa,
-    0x243311d4,
-    0x243391e1,
-    0x243411ee,
-    0x24349200,
-    0x2435120f,
-    0x2435922c,
-    0x24361239,
-    0x24369247,
-    0x24371255,
-    0x24379263,
-    0x2438126c,
-    0x24389279,
-    0x2439128c,
-    0x28320b82,
-    0x28328b8e,
-    0x28330b5f,
-    0x28338ba1,
-    0x2c322b08,
-    0x2c32ab16,
-    0x2c332b28,
-    0x2c33ab3a,
-    0x2c342b4e,
-    0x2c34ab60,
-    0x2c352b7b,
-    0x2c35ab8d,
-    0x2c362ba0,
-    0x2c3682f3,
-    0x2c372bad,
-    0x2c37abbf,
-    0x2c382bd2,
-    0x2c38abe0,
-    0x2c392bf0,
-    0x2c39ac02,
-    0x2c3a2c16,
-    0x2c3aac27,
-    0x2c3b134c,
-    0x2c3bac38,
-    0x2c3c2c4c,
-    0x2c3cac62,
-    0x2c3d2c7b,
-    0x2c3daca9,
-    0x2c3e2cb7,
-    0x2c3eaccf,
-    0x2c3f2ce7,
-    0x2c3facf4,
-    0x2c402d17,
-    0x2c40ad36,
-    0x2c4111b6,
-    0x2c41ad47,
-    0x2c422d5a,
-    0x2c429128,
-    0x2c432d6b,
-    0x2c4386a2,
-    0x2c442c98,
+    0x18328ee1,
+    0x183300ac,
+    0x18338ef7,
+    0x18340f0b,
+    0x183480ea,
+    0x18350f20,
+    0x18358f38,
+    0x18360f4d,
+    0x18368f61,
+    0x18370f85,
+    0x18378f9b,
+    0x18380faf,
+    0x18388fbf,
+    0x18390a57,
+    0x18398fcf,
+    0x183a0fe4,
+    0x183a8ff8,
+    0x183b0c25,
+    0x183b9005,
+    0x183c1017,
+    0x183c9022,
+    0x183d1032,
+    0x183d9043,
+    0x183e1054,
+    0x183e9066,
+    0x183f108f,
+    0x183f90a8,
+    0x184010c0,
+    0x184086d3,
+    0x203210e7,
+    0x243210f3,
+    0x24328985,
+    0x24331105,
+    0x24339112,
+    0x2434111f,
+    0x24349131,
+    0x24351140,
+    0x2435915d,
+    0x2436116a,
+    0x24369178,
+    0x24371186,
+    0x24379194,
+    0x2438119d,
+    0x243891aa,
+    0x243911bd,
+    0x28320c0d,
+    0x28328c25,
+    0x28330bea,
+    0x28338c38,
+    0x28340c19,
+    0x283480ac,
+    0x283500ea,
+    0x2c3227cb,
+    0x2c32a7d9,
+    0x2c3327eb,
+    0x2c33a7fd,
+    0x2c342811,
+    0x2c34a823,
+    0x2c35283e,
+    0x2c35a850,
+    0x2c362863,
+    0x2c36832d,
+    0x2c372870,
+    0x2c37a882,
+    0x2c382895,
+    0x2c38a8ac,
+    0x2c3928ba,
+    0x2c39a8ca,
+    0x2c3a28dc,
+    0x2c3aa8f0,
+    0x2c3b2901,
+    0x2c3ba920,
+    0x2c3c2934,
+    0x2c3ca94a,
+    0x2c3d2963,
+    0x2c3da980,
+    0x2c3e2991,
+    0x2c3ea99f,
+    0x2c3f29b7,
+    0x2c3fa9cf,
+    0x2c4029dc,
+    0x2c4090e7,
+    0x2c4129ed,
+    0x2c41aa00,
+    0x2c4210c0,
+    0x2c42aa11,
+    0x2c430720,
+    0x2c43a912,
     0x30320000,
     0x30328015,
     0x3033001f,
@@ -1606,469 +223,454 @@
     0x3035006b,
     0x30358083,
     0x30360094,
-    0x303680a1,
-    0x303700b0,
-    0x303780bd,
-    0x303800d0,
-    0x303880eb,
-    0x30390100,
-    0x30398114,
-    0x303a0128,
-    0x303a8139,
-    0x303b0152,
-    0x303b816f,
-    0x303c017d,
-    0x303c8191,
-    0x303d01a1,
-    0x303d81ba,
-    0x303e01ca,
-    0x303e81dd,
-    0x303f01ec,
-    0x303f81f8,
-    0x3040020d,
-    0x3040821d,
-    0x30410234,
-    0x30418241,
-    0x30420254,
-    0x30428263,
-    0x30430278,
-    0x30438299,
-    0x304402ac,
-    0x304482bf,
-    0x304502d8,
-    0x304582f3,
-    0x30460310,
-    0x30468329,
-    0x30470337,
-    0x30478348,
-    0x30480357,
-    0x3048836f,
-    0x30490381,
-    0x30498395,
-    0x304a03b4,
-    0x304a83c7,
-    0x304b03d2,
-    0x304b83e1,
-    0x304c03f2,
-    0x304c83fe,
-    0x304d0414,
-    0x304d8422,
-    0x304e0438,
-    0x304e844a,
-    0x304f045c,
-    0x304f846f,
-    0x30500482,
-    0x30508493,
-    0x305104a3,
-    0x305184bb,
-    0x305204d0,
-    0x305284e8,
-    0x305304fc,
-    0x30538514,
-    0x3054052d,
-    0x30548546,
-    0x30550563,
-    0x3055856e,
-    0x30560586,
-    0x30568596,
-    0x305705a7,
-    0x305785ba,
-    0x305805d0,
-    0x305885d9,
-    0x305905ee,
-    0x30598601,
-    0x305a0610,
-    0x305a8630,
-    0x305b063f,
-    0x305b864b,
-    0x305c066b,
-    0x305c8687,
-    0x305d0698,
-    0x305d86a2,
-    0x34320abc,
-    0x34328ad0,
-    0x34330aed,
-    0x34338b00,
-    0x34340b0f,
-    0x34348b2c,
+    0x303680ac,
+    0x303700b9,
+    0x303780c8,
+    0x303800ea,
+    0x303880f7,
+    0x3039010a,
+    0x30398125,
+    0x303a013a,
+    0x303a814e,
+    0x303b0162,
+    0x303b8173,
+    0x303c018c,
+    0x303c81a9,
+    0x303d01b7,
+    0x303d81cb,
+    0x303e01db,
+    0x303e81f4,
+    0x303f0204,
+    0x303f8217,
+    0x30400226,
+    0x30408232,
+    0x30410247,
+    0x30418257,
+    0x3042026e,
+    0x3042827b,
+    0x3043028e,
+    0x3043829d,
+    0x304402b2,
+    0x304482d3,
+    0x304502e6,
+    0x304582f9,
+    0x30460312,
+    0x3046832d,
+    0x3047034a,
+    0x30478363,
+    0x30480371,
+    0x30488382,
+    0x30490391,
+    0x304983a9,
+    0x304a03bb,
+    0x304a83cf,
+    0x304b03ee,
+    0x304b8401,
+    0x304c040c,
+    0x304c841d,
+    0x304d0429,
+    0x304d843f,
+    0x304e044d,
+    0x304e8463,
+    0x304f0475,
+    0x304f8487,
+    0x3050049a,
+    0x305084ad,
+    0x305104be,
+    0x305184ce,
+    0x305204e6,
+    0x305284fb,
+    0x30530513,
+    0x30538527,
+    0x3054053f,
+    0x30548558,
+    0x30550571,
+    0x3055858e,
+    0x30560599,
+    0x305685b1,
+    0x305705c1,
+    0x305785d2,
+    0x305805e5,
+    0x305885fb,
+    0x30590604,
+    0x30598619,
+    0x305a062c,
+    0x305a863b,
+    0x305b065b,
+    0x305b866a,
+    0x305c068b,
+    0x305c86a7,
+    0x305d06b3,
+    0x305d86d3,
+    0x305e06ef,
+    0x305e8700,
+    0x305f0716,
+    0x305f8720,
+    0x34320b47,
+    0x34328b5b,
+    0x34330b78,
+    0x34338b8b,
+    0x34340b9a,
+    0x34348bb7,
     0x3c320083,
-    0x3c328bcb,
-    0x3c330be4,
-    0x3c338bff,
-    0x3c340c1c,
-    0x3c348c37,
-    0x3c350c52,
-    0x3c358c67,
-    0x3c360c80,
-    0x3c368c98,
-    0x3c370ca9,
-    0x3c378cb7,
-    0x3c380cc4,
-    0x3c388cd8,
-    0x3c390b8e,
-    0x3c398cec,
-    0x3c3a0d00,
-    0x3c3a8874,
-    0x3c3b0d10,
-    0x3c3b8d2b,
-    0x3c3c0d3d,
-    0x3c3c8d53,
-    0x3c3d0d5d,
-    0x3c3d8d71,
-    0x3c3e0d7f,
-    0x3c3e8da4,
-    0x3c3f0bb7,
-    0x3c3f8d8d,
-    0x403217ba,
-    0x403297d0,
-    0x403317fe,
-    0x40339808,
-    0x4034181f,
-    0x4034983d,
-    0x4035184d,
-    0x4035985f,
-    0x4036186c,
-    0x40369878,
-    0x4037188d,
-    0x403798a2,
-    0x403818b4,
-    0x403898bf,
-    0x403918d1,
-    0x40398dd4,
-    0x403a18e1,
-    0x403a98f4,
-    0x403b1915,
-    0x403b9926,
-    0x403c1936,
-    0x403c8064,
-    0x403d1942,
-    0x403d995e,
-    0x403e1974,
-    0x403e9983,
-    0x403f1996,
-    0x403f99b0,
-    0x404019be,
-    0x404099d3,
-    0x404119e7,
-    0x40419a04,
-    0x40421a1d,
-    0x40429a38,
-    0x40431a51,
-    0x40439a64,
-    0x40441a78,
-    0x40449a90,
-    0x40451aa0,
-    0x40459aae,
-    0x40461acc,
-    0x40468094,
-    0x40471ae1,
-    0x40479af3,
-    0x40481b17,
-    0x40489b37,
-    0x40491b4b,
-    0x40499b60,
-    0x404a1b79,
-    0x404a9bb3,
-    0x404b1bcd,
-    0x404b9beb,
-    0x404c1c06,
-    0x404c9c20,
-    0x404d1c37,
-    0x404d9c5f,
-    0x404e1c76,
-    0x404e9c92,
-    0x404f1cae,
-    0x404f9ccf,
-    0x40501cf1,
-    0x40509d0d,
-    0x40511d21,
-    0x40519d2e,
-    0x40521d45,
-    0x40529d55,
-    0x40531d65,
-    0x40539d79,
-    0x40541d94,
-    0x40549da4,
-    0x40551dbb,
-    0x40559dca,
-    0x40561de5,
-    0x40569dfd,
-    0x40571e19,
-    0x40579e32,
-    0x40581e45,
-    0x40589e5a,
-    0x40591e7d,
-    0x40599e8b,
-    0x405a1e98,
-    0x405a9eb1,
-    0x405b1ec9,
-    0x405b9edc,
-    0x405c1ef1,
-    0x405c9f03,
-    0x405d1f18,
-    0x405d9f28,
-    0x405e1f41,
-    0x405e9f55,
-    0x405f1f65,
-    0x405f9f7d,
-    0x40601f8e,
-    0x40609fa1,
-    0x40611fb2,
-    0x40619fd0,
-    0x40621fe1,
-    0x40629fee,
-    0x40632005,
-    0x4063a046,
-    0x4064205d,
-    0x4064a06a,
-    0x40652078,
-    0x4065a09a,
-    0x406620c2,
-    0x4066a0d7,
-    0x406720ee,
-    0x4067a0ff,
-    0x40682110,
-    0x4068a121,
-    0x40692136,
-    0x4069a14d,
-    0x406a215e,
-    0x406aa177,
-    0x406b2192,
-    0x406ba1a9,
-    0x406c2216,
-    0x406ca237,
-    0x406d224a,
-    0x406da26b,
-    0x406e2286,
-    0x406ea2a1,
-    0x406f22c2,
-    0x406fa2e8,
-    0x40702308,
-    0x4070a324,
-    0x407124b1,
-    0x4071a4d4,
-    0x407224ea,
-    0x4072a509,
-    0x40732521,
-    0x4073a541,
-    0x4074276b,
-    0x4074a790,
-    0x407527ab,
-    0x4075a7ca,
-    0x407627f9,
-    0x4076a821,
-    0x40772852,
-    0x4077a871,
-    0x40782896,
-    0x4078a8ad,
-    0x407928c0,
-    0x4079a8dd,
-    0x407a0782,
-    0x407aa8ef,
-    0x407b2902,
-    0x407ba91b,
-    0x407c2933,
-    0x407c90b0,
-    0x407d2947,
-    0x407da961,
-    0x407e2972,
-    0x407ea986,
-    0x407f2994,
-    0x407fa9af,
-    0x40801279,
-    0x4080a9d4,
-    0x408129f6,
-    0x4081aa11,
-    0x40822a26,
-    0x4082aa3e,
-    0x40832a56,
-    0x4083aa6d,
-    0x40842a83,
-    0x4084aa8f,
-    0x40852aa2,
-    0x4085aab7,
-    0x40862ac9,
-    0x4086aade,
-    0x40872ae7,
-    0x40879c4d,
-    0x40880083,
-    0x4088a025,
-    0x40890a0a,
-    0x4089a1c1,
-    0x408a1b9c,
-    0x408aa1eb,
-    0x408b283a,
-    0x41f423dc,
-    0x41f9246e,
-    0x41fe2361,
-    0x41fea592,
-    0x41ff2683,
-    0x420323f5,
-    0x42082417,
-    0x4208a453,
-    0x42092345,
-    0x4209a48d,
-    0x420a239c,
-    0x420aa37c,
-    0x420b23bc,
-    0x420ba435,
-    0x420c269f,
-    0x420ca55f,
-    0x420d2579,
-    0x420da5b0,
-    0x421225ca,
-    0x42172666,
-    0x4217a60c,
-    0x421c262e,
-    0x421f25e9,
-    0x422126b6,
-    0x42262649,
-    0x422b274f,
-    0x422ba718,
-    0x422c2737,
-    0x422ca6f2,
-    0x422d26d1,
-    0x443206ad,
-    0x443286bc,
-    0x443306c8,
-    0x443386d6,
-    0x443406e9,
-    0x443486fa,
-    0x44350701,
-    0x4435870b,
-    0x4436071e,
-    0x44368734,
-    0x44370746,
-    0x44378753,
-    0x44380762,
-    0x4438876a,
-    0x44390782,
-    0x44398790,
-    0x443a07a3,
-    0x4c3212a3,
-    0x4c3292b3,
-    0x4c3312c6,
-    0x4c3392e6,
-    0x4c340094,
-    0x4c3480b0,
-    0x4c3512f2,
-    0x4c359300,
-    0x4c36131c,
-    0x4c36932f,
-    0x4c37133e,
-    0x4c37934c,
-    0x4c381361,
-    0x4c38936d,
-    0x4c39138d,
-    0x4c3993b7,
-    0x4c3a13d0,
-    0x4c3a93e9,
-    0x4c3b05d0,
-    0x4c3b9402,
-    0x4c3c1414,
-    0x4c3c9423,
-    0x4c3d10b0,
-    0x4c3d943c,
-    0x4c3e1449,
-    0x50322d7d,
-    0x5032ad8c,
-    0x50332d97,
-    0x5033ada7,
-    0x50342dc0,
-    0x5034adda,
-    0x50352de8,
-    0x5035adfe,
-    0x50362e10,
-    0x5036ae26,
-    0x50372e3f,
-    0x5037ae52,
-    0x50382e6a,
-    0x5038ae7b,
-    0x50392e90,
-    0x5039aea4,
-    0x503a2ec4,
-    0x503aaeda,
-    0x503b2ef2,
-    0x503baf04,
-    0x503c2f20,
-    0x503caf37,
-    0x503d2f50,
-    0x503daf66,
-    0x503e2f73,
-    0x503eaf89,
-    0x503f2f9b,
-    0x503f8348,
-    0x50402fae,
-    0x5040afbe,
-    0x50412fd8,
-    0x5041afe7,
-    0x50423001,
-    0x5042b01e,
-    0x5043302e,
-    0x5043b03e,
-    0x5044304d,
-    0x50448414,
-    0x50453061,
-    0x5045b07f,
-    0x50463092,
-    0x5046b0a8,
-    0x504730ba,
-    0x5047b0cf,
-    0x504830f5,
-    0x5048b103,
-    0x50493116,
-    0x5049b12b,
-    0x504a3141,
-    0x504ab151,
-    0x504b3171,
-    0x504bb184,
-    0x504c31a7,
-    0x504cb1d5,
-    0x504d31e7,
-    0x504db204,
-    0x504e321f,
-    0x504eb23b,
-    0x504f324d,
-    0x504fb264,
-    0x50503273,
-    0x50508687,
-    0x50513286,
-    0x58320e12,
-    0x68320dd4,
-    0x68328b8e,
-    0x68330ba1,
-    0x68338de2,
-    0x68340df2,
-    0x6c320db0,
-    0x6c328b71,
-    0x6c330dbb,
-    0x74320980,
-    0x783208e5,
-    0x783288fa,
-    0x78330906,
+    0x3c328c62,
+    0x3c330c7b,
+    0x3c338c96,
+    0x3c340cb3,
+    0x3c348cdd,
+    0x3c350cf8,
+    0x3c358d1e,
+    0x3c360d37,
+    0x3c368d4f,
+    0x3c370d60,
+    0x3c378d6e,
+    0x3c380d7b,
+    0x3c388d8f,
+    0x3c390c25,
+    0x3c398da3,
+    0x3c3a0db7,
+    0x3c3a88ff,
+    0x3c3b0dc7,
+    0x3c3b8de2,
+    0x3c3c0df4,
+    0x3c3c8e0a,
+    0x3c3d0e14,
+    0x3c3d8e28,
+    0x3c3e0e36,
+    0x3c3e8e5b,
+    0x3c3f0c4e,
+    0x3c3f8e44,
+    0x3c4000ac,
+    0x3c4080ea,
+    0x3c410cce,
+    0x3c418d0d,
+    0x403216fa,
+    0x40329710,
+    0x4033173e,
+    0x40339748,
+    0x4034175f,
+    0x4034977d,
+    0x4035178d,
+    0x4035979f,
+    0x403617ac,
+    0x403697b8,
+    0x403717cd,
+    0x403797df,
+    0x403817ea,
+    0x403897fc,
+    0x40390e8b,
+    0x4039980c,
+    0x403a181f,
+    0x403a9840,
+    0x403b1851,
+    0x403b9861,
+    0x403c0064,
+    0x403c8083,
+    0x403d186d,
+    0x403d9883,
+    0x403e1892,
+    0x403e98a5,
+    0x403f18bf,
+    0x403f98cd,
+    0x404018e2,
+    0x404098f6,
+    0x40411913,
+    0x4041992e,
+    0x40421947,
+    0x4042995a,
+    0x4043196e,
+    0x40439986,
+    0x4044199d,
+    0x404480ac,
+    0x404519b2,
+    0x404599c4,
+    0x404619e8,
+    0x40469a08,
+    0x40471a16,
+    0x40479a3d,
+    0x40481a52,
+    0x40489a6b,
+    0x40491a82,
+    0x40499a9c,
+    0x404a1ab3,
+    0x404a9ad1,
+    0x404b1ae9,
+    0x404b9b00,
+    0x404c1b16,
+    0x404c9b28,
+    0x404d1b49,
+    0x404d9b6b,
+    0x404e1b7f,
+    0x404e9b8c,
+    0x404f1ba3,
+    0x404f9bb3,
+    0x40501bdd,
+    0x40509bf1,
+    0x40511c0c,
+    0x40519c1c,
+    0x40521c33,
+    0x40529c45,
+    0x40531c5d,
+    0x40539c70,
+    0x40541c85,
+    0x40549ca8,
+    0x40551cb6,
+    0x40559cd3,
+    0x40561ce0,
+    0x40569cf9,
+    0x40571d11,
+    0x40579d24,
+    0x40581d39,
+    0x40589d4b,
+    0x40591d7a,
+    0x40599d93,
+    0x405a1da7,
+    0x405a9db7,
+    0x405b1dcf,
+    0x405b9de0,
+    0x405c1df3,
+    0x405c9e04,
+    0x405d1e11,
+    0x405d9e28,
+    0x405e1e48,
+    0x405e8a95,
+    0x405f1e69,
+    0x405f9e76,
+    0x40601e84,
+    0x40609ea6,
+    0x40611ece,
+    0x40619ee3,
+    0x40621efa,
+    0x40629f0b,
+    0x40631f1c,
+    0x40639f31,
+    0x40641f48,
+    0x40649f59,
+    0x40651f74,
+    0x40659f8b,
+    0x40661fa3,
+    0x40669fcd,
+    0x40671ff8,
+    0x4067a019,
+    0x4068202c,
+    0x4068a04d,
+    0x4069207f,
+    0x4069a0ad,
+    0x406a20ce,
+    0x406aa0ee,
+    0x406b2276,
+    0x406ba299,
+    0x406c22af,
+    0x406ca4db,
+    0x406d250a,
+    0x406da532,
+    0x406e254b,
+    0x406ea563,
+    0x406f2582,
+    0x406fa597,
+    0x407025aa,
+    0x4070a5c7,
+    0x40710800,
+    0x4071a5d9,
+    0x407225ec,
+    0x4072a605,
+    0x4073261d,
+    0x4073936d,
+    0x40742631,
+    0x4074a64b,
+    0x4075265c,
+    0x4075a670,
+    0x4076267e,
+    0x407691aa,
+    0x407726a3,
+    0x4077a6c5,
+    0x407826e0,
+    0x4078a719,
+    0x40792730,
+    0x4079a746,
+    0x407a2752,
+    0x407aa765,
+    0x407b277a,
+    0x407ba78c,
+    0x407c27a1,
+    0x407ca7aa,
+    0x407d2068,
+    0x407d9bc3,
+    0x407e26f5,
+    0x407e9d5b,
+    0x407f1a2a,
+    0x41f421a1,
+    0x41f92233,
+    0x41fe2126,
+    0x41fea302,
+    0x41ff23f3,
+    0x420321ba,
+    0x420821dc,
+    0x4208a218,
+    0x4209210a,
+    0x4209a252,
+    0x420a2161,
+    0x420aa141,
+    0x420b2181,
+    0x420ba1fa,
+    0x420c240f,
+    0x420ca2cf,
+    0x420d22e9,
+    0x420da320,
+    0x4212233a,
+    0x421723d6,
+    0x4217a37c,
+    0x421c239e,
+    0x421f2359,
+    0x42212426,
+    0x422623b9,
+    0x422b24bf,
+    0x422ba488,
+    0x422c24a7,
+    0x422ca462,
+    0x422d2441,
+    0x4432072b,
+    0x4432873a,
+    0x44330746,
+    0x44338754,
+    0x44340767,
+    0x44348778,
+    0x4435077f,
+    0x44358789,
+    0x4436079c,
+    0x443687b2,
+    0x443707c4,
+    0x443787d1,
+    0x443807e0,
+    0x443887e8,
+    0x44390800,
+    0x4439880e,
+    0x443a0821,
+    0x4c3211d4,
+    0x4c3291e4,
+    0x4c3311f7,
+    0x4c339217,
+    0x4c3400ac,
+    0x4c3480ea,
+    0x4c351223,
+    0x4c359231,
+    0x4c36124d,
+    0x4c369260,
+    0x4c37126f,
+    0x4c37927d,
+    0x4c381292,
+    0x4c38929e,
+    0x4c3912be,
+    0x4c3992e8,
+    0x4c3a1301,
+    0x4c3a931a,
+    0x4c3b05fb,
+    0x4c3b9333,
+    0x4c3c1345,
+    0x4c3c9354,
+    0x4c3d136d,
+    0x4c3d937c,
+    0x4c3e1389,
+    0x50322a23,
+    0x5032aa32,
+    0x50332a3d,
+    0x5033aa4d,
+    0x50342a66,
+    0x5034aa80,
+    0x50352a8e,
+    0x5035aaa4,
+    0x50362ab6,
+    0x5036aacc,
+    0x50372ae5,
+    0x5037aaf8,
+    0x50382b10,
+    0x5038ab21,
+    0x50392b36,
+    0x5039ab4a,
+    0x503a2b6a,
+    0x503aab80,
+    0x503b2b98,
+    0x503babaa,
+    0x503c2bc6,
+    0x503cabdd,
+    0x503d2bf6,
+    0x503dac0c,
+    0x503e2c19,
+    0x503eac2f,
+    0x503f2c41,
+    0x503f8382,
+    0x50402c54,
+    0x5040ac64,
+    0x50412c7e,
+    0x5041ac8d,
+    0x50422ca7,
+    0x5042acc4,
+    0x50432cd4,
+    0x5043ace4,
+    0x50442cf3,
+    0x5044843f,
+    0x50452d07,
+    0x5045ad25,
+    0x50462d38,
+    0x5046ad4e,
+    0x50472d60,
+    0x5047ad75,
+    0x50482d9b,
+    0x5048ada9,
+    0x50492dbc,
+    0x5049add1,
+    0x504a2de7,
+    0x504aadf7,
+    0x504b2e17,
+    0x504bae2a,
+    0x504c2e4d,
+    0x504cae7b,
+    0x504d2e8d,
+    0x504daeaa,
+    0x504e2ec5,
+    0x504eaee1,
+    0x504f2ef3,
+    0x504faf0a,
+    0x50502f19,
+    0x505086ef,
+    0x50512f2c,
+    0x58320ec9,
+    0x68320e8b,
+    0x68328c25,
+    0x68330c38,
+    0x68338e99,
+    0x68340ea9,
+    0x683480ea,
+    0x6c320e67,
+    0x6c328bfc,
+    0x6c330e72,
+    0x74320a0b,
+    0x78320970,
+    0x78328985,
+    0x78330991,
     0x78338083,
-    0x78340915,
-    0x7834892a,
-    0x78350949,
-    0x7835896b,
-    0x78360980,
-    0x78368996,
-    0x783709a6,
-    0x783789b9,
-    0x783809cc,
-    0x783889de,
-    0x783909eb,
-    0x78398a0a,
-    0x783a0a1f,
-    0x783a8a2d,
-    0x783b0a37,
-    0x783b8a4b,
-    0x783c0a62,
-    0x783c8a77,
-    0x783d0a8e,
-    0x783d8aa3,
-    0x783e09f9,
-    0x803211a5,
+    0x783409a0,
+    0x783489b5,
+    0x783509d4,
+    0x783589f6,
+    0x78360a0b,
+    0x78368a21,
+    0x78370a31,
+    0x78378a44,
+    0x78380a57,
+    0x78388a69,
+    0x78390a76,
+    0x78398a95,
+    0x783a0aaa,
+    0x783a8ab8,
+    0x783b0ac2,
+    0x783b8ad6,
+    0x783c0aed,
+    0x783c8b02,
+    0x783d0b19,
+    0x783d8b2e,
+    0x783e0a84,
+    0x7c3210d6,
 };
 
 const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]);
@@ -2082,8 +684,10 @@
     "BN_LIB\0"
     "BOOLEAN_IS_WRONG_LENGTH\0"
     "BUFFER_TOO_SMALL\0"
+    "CONTEXT_NOT_INITIALISED\0"
     "DECODE_ERROR\0"
     "DEPTH_EXCEEDED\0"
+    "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0"
     "ENCODE_ERROR\0"
     "ERROR_GETTING_TIME\0"
     "EXPECTING_AN_ASN1_SEQUENCE\0"
@@ -2124,7 +728,6 @@
     "INVALID_UNIVERSALSTRING_LENGTH\0"
     "INVALID_UTF8STRING\0"
     "LIST_ERROR\0"
-    "MALLOC_FAILURE\0"
     "MISSING_ASN1_EOS\0"
     "MISSING_EOC\0"
     "MISSING_SECOND_NUMBER\0"
@@ -2156,10 +759,13 @@
     "UNEXPECTED_EOC\0"
     "UNIVERSALSTRING_IS_WRONG_LENGTH\0"
     "UNKNOWN_FORMAT\0"
+    "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0"
+    "UNKNOWN_SIGNATURE_ALGORITHM\0"
     "UNKNOWN_TAG\0"
     "UNSUPPORTED_ANY_DEFINED_BY_TYPE\0"
     "UNSUPPORTED_PUBLIC_KEY_TYPE\0"
     "UNSUPPORTED_TYPE\0"
+    "WRONG_PUBLIC_KEY_TYPE\0"
     "WRONG_TAG\0"
     "WRONG_TYPE\0"
     "BAD_FOPEN_MODE\0"
@@ -2180,6 +786,7 @@
     "UNSUPPORTED_METHOD\0"
     "WRITE_TO_READ_ONLY_BIO\0"
     "ARG2_LT_ARG3\0"
+    "BAD_ENCODING\0"
     "BAD_RECIPROCAL\0"
     "BIGNUM_TOO_LONG\0"
     "BITS_TOO_SMALL\0"
@@ -2231,6 +838,7 @@
     "MODULUS_TOO_LARGE\0"
     "NO_PRIVATE_VALUE\0"
     "BAD_Q_VALUE\0"
+    "BAD_VERSION\0"
     "MISSING_PARAMETERS\0"
     "NEED_NEW_SETUP_VALUES\0"
     "BIGNUM_OUT_OF_RANGE\0"
@@ -2238,8 +846,10 @@
     "D2I_ECPKPARAMETERS_FAILURE\0"
     "EC_GROUP_NEW_BY_NAME_FAILURE\0"
     "GROUP2PKPARAMETERS_FAILURE\0"
+    "GROUP_MISMATCH\0"
     "I2D_ECPKPARAMETERS_FAILURE\0"
     "INCOMPATIBLE_OBJECTS\0"
+    "INVALID_COFACTOR\0"
     "INVALID_COMPRESSED_POINT\0"
     "INVALID_COMPRESSION_BIT\0"
     "INVALID_ENCODING\0"
@@ -2264,27 +874,19 @@
     "NOT_IMPLEMENTED\0"
     "RANDOM_NUMBER_GENERATION_FAILED\0"
     "OPERATION_NOT_SUPPORTED\0"
-    "BN_DECODE_ERROR\0"
     "COMMAND_NOT_SUPPORTED\0"
-    "CONTEXT_NOT_INITIALISED\0"
     "DIFFERENT_KEY_TYPES\0"
     "DIFFERENT_PARAMETERS\0"
-    "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0"
     "EXPECTING_AN_EC_KEY_KEY\0"
     "EXPECTING_AN_RSA_KEY\0"
-    "EXPECTING_A_DH_KEY\0"
     "EXPECTING_A_DSA_KEY\0"
     "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0"
-    "INVALID_CURVE\0"
     "INVALID_DIGEST_LENGTH\0"
     "INVALID_DIGEST_TYPE\0"
     "INVALID_KEYBITS\0"
     "INVALID_MGF1_MD\0"
     "INVALID_PADDING_MODE\0"
-    "INVALID_PSS_PARAMETERS\0"
     "INVALID_PSS_SALTLEN\0"
-    "INVALID_SALT_LENGTH\0"
-    "INVALID_TRAILER\0"
     "KEYS_NOT_SET\0"
     "NO_DEFAULT_DIGEST\0"
     "NO_KEY_SET\0"
@@ -2294,17 +896,8 @@
     "NO_PARAMETERS_SET\0"
     "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\0"
     "OPERATON_NOT_INITIALIZED\0"
-    "PARAMETER_ENCODING_ERROR\0"
-    "UNKNOWN_DIGEST\0"
-    "UNKNOWN_MASK_DIGEST\0"
-    "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0"
     "UNKNOWN_PUBLIC_KEY_TYPE\0"
-    "UNKNOWN_SIGNATURE_ALGORITHM\0"
     "UNSUPPORTED_ALGORITHM\0"
-    "UNSUPPORTED_MASK_ALGORITHM\0"
-    "UNSUPPORTED_MASK_PARAMETER\0"
-    "UNSUPPORTED_SIGNATURE_TYPE\0"
-    "WRONG_PUBLIC_KEY_TYPE\0"
     "OUTPUT_TOO_LARGE\0"
     "UNKNOWN_NID\0"
     "BAD_BASE64_DECODE\0"
@@ -2340,6 +933,7 @@
     "UNKNOWN_ALGORITHM\0"
     "UNKNOWN_CIPHER\0"
     "UNKNOWN_CIPHER_ALGORITHM\0"
+    "UNKNOWN_DIGEST\0"
     "UNKNOWN_HASH\0"
     "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\0"
     "BAD_E_VALUE\0"
@@ -2390,7 +984,6 @@
     "BAD_DIGEST_LENGTH\0"
     "BAD_ECC_CERT\0"
     "BAD_ECPOINT\0"
-    "BAD_HANDSHAKE_LENGTH\0"
     "BAD_HANDSHAKE_RECORD\0"
     "BAD_HELLO_REQUEST\0"
     "BAD_LENGTH\0"
@@ -2401,7 +994,6 @@
     "BAD_SSL_FILETYPE\0"
     "BAD_WRITE_RETRY\0"
     "BIO_NOT_SET\0"
-    "CANNOT_SERIALIZE_PUBLIC_KEY\0"
     "CA_DN_LENGTH_MISMATCH\0"
     "CA_DN_TOO_LONG\0"
     "CCS_RECEIVED_EARLY\0"
@@ -2410,63 +1002,56 @@
     "CERT_LENGTH_MISMATCH\0"
     "CHANNEL_ID_NOT_P256\0"
     "CHANNEL_ID_SIGNATURE_INVALID\0"
-    "CIPHER_CODE_WRONG_LENGTH\0"
     "CIPHER_OR_HASH_UNAVAILABLE\0"
     "CLIENTHELLO_PARSE_FAILED\0"
     "CLIENTHELLO_TLSEXT\0"
     "CONNECTION_REJECTED\0"
     "CONNECTION_TYPE_NOT_SET\0"
-    "COOKIE_MISMATCH\0"
-    "D2I_ECDSA_SIG\0"
-    "DATA_BETWEEN_CCS_AND_FINISHED\0"
+    "CUSTOM_EXTENSION_ERROR\0"
     "DATA_LENGTH_TOO_LONG\0"
     "DECRYPTION_FAILED\0"
     "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\0"
     "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\0"
+    "DH_P_TOO_LONG\0"
     "DIGEST_CHECK_FAILED\0"
+    "DOWNGRADE_DETECTED\0"
     "DTLS_MESSAGE_TOO_BIG\0"
     "ECC_CERT_NOT_FOR_SIGNING\0"
-    "EMPTY_SRTP_PROTECTION_PROFILE_LIST\0"
     "EMS_STATE_INCONSISTENT\0"
     "ENCRYPTED_LENGTH_TOO_LONG\0"
+    "ERROR_ADDING_EXTENSION\0"
     "ERROR_IN_RECEIVED_CIPHER_LIST\0"
-    "EVP_DIGESTSIGNFINAL_FAILED\0"
-    "EVP_DIGESTSIGNINIT_FAILED\0"
+    "ERROR_PARSING_EXTENSION\0"
     "EXCESSIVE_MESSAGE_SIZE\0"
     "EXTRA_DATA_IN_MESSAGE\0"
     "FRAGMENT_MISMATCH\0"
-    "GOT_A_FIN_BEFORE_A_CCS\0"
-    "GOT_CHANNEL_ID_BEFORE_A_CCS\0"
-    "GOT_NEXT_PROTO_BEFORE_A_CCS\0"
     "GOT_NEXT_PROTO_WITHOUT_EXTENSION\0"
     "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\0"
-    "HANDSHAKE_RECORD_BEFORE_CCS\0"
     "HTTPS_PROXY_REQUEST\0"
     "HTTP_REQUEST\0"
     "INAPPROPRIATE_FALLBACK\0"
     "INVALID_COMMAND\0"
     "INVALID_MESSAGE\0"
+    "INVALID_OUTER_RECORD_TYPE\0"
     "INVALID_SSL_SESSION\0"
     "INVALID_TICKET_KEYS_LENGTH\0"
     "LENGTH_MISMATCH\0"
     "LIBRARY_HAS_NO_CIPHERS\0"
-    "MISSING_DH_KEY\0"
-    "MISSING_ECDSA_SIGNING_CERT\0"
+    "MISSING_EXTENSION\0"
     "MISSING_RSA_CERTIFICATE\0"
-    "MISSING_RSA_ENCRYPTING_CERT\0"
-    "MISSING_RSA_SIGNING_CERT\0"
     "MISSING_TMP_DH_KEY\0"
     "MISSING_TMP_ECDH_KEY\0"
     "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0"
     "MTU_TOO_SMALL\0"
+    "NEGOTIATED_BOTH_NPN_AND_ALPN\0"
     "NESTED_GROUP\0"
     "NO_CERTIFICATES_RETURNED\0"
     "NO_CERTIFICATE_ASSIGNED\0"
     "NO_CERTIFICATE_SET\0"
     "NO_CIPHERS_AVAILABLE\0"
     "NO_CIPHERS_PASSED\0"
-    "NO_CIPHERS_SPECIFIED\0"
     "NO_CIPHER_MATCH\0"
+    "NO_COMMON_SIGNATURE_ALGORITHMS\0"
     "NO_COMPRESSION_SPECIFIED\0"
     "NO_METHOD_SPECIFIED\0"
     "NO_P256_SUPPORT\0"
@@ -2474,13 +1059,10 @@
     "NO_RENEGOTIATION\0"
     "NO_REQUIRED_DIGEST\0"
     "NO_SHARED_CIPHER\0"
-    "NO_SHARED_SIGATURE_ALGORITHMS\0"
-    "NO_SRTP_PROFILES\0"
     "NULL_SSL_CTX\0"
     "NULL_SSL_METHOD_PASSED\0"
     "OLD_SESSION_CIPHER_NOT_RETURNED\0"
     "OLD_SESSION_VERSION_NOT_RETURNED\0"
-    "PACKET_LENGTH_TOO_LONG\0"
     "PARSE_TLSEXT\0"
     "PATH_TOO_LONG\0"
     "PEER_DID_NOT_RETURN_A_CERTIFICATE\0"
@@ -2489,11 +1071,9 @@
     "PSK_IDENTITY_NOT_FOUND\0"
     "PSK_NO_CLIENT_CB\0"
     "PSK_NO_SERVER_CB\0"
-    "READ_BIO_NOT_SET\0"
     "READ_TIMEOUT_EXPIRED\0"
     "RECORD_LENGTH_MISMATCH\0"
     "RECORD_TOO_LARGE\0"
-    "RENEGOTIATE_EXT_TOO_LONG\0"
     "RENEGOTIATION_ENCODING_ERR\0"
     "RENEGOTIATION_MISMATCH\0"
     "REQUIRED_CIPHER_MISSING\0"
@@ -2503,12 +1083,11 @@
     "SERVERHELLO_TLSEXT\0"
     "SESSION_ID_CONTEXT_UNINITIALIZED\0"
     "SESSION_MAY_NOT_BE_CREATED\0"
-    "SIGNATURE_ALGORITHMS_ERROR\0"
+    "SHUTDOWN_WHILE_IN_INIT\0"
+    "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0"
     "SRTP_COULD_NOT_ALLOCATE_PROFILES\0"
-    "SRTP_PROTECTION_PROFILE_LIST_TOO_LONG\0"
     "SRTP_UNKNOWN_PROTECTION_PROFILE\0"
     "SSL3_EXT_INVALID_SERVERNAME\0"
-    "SSL3_EXT_INVALID_SERVERNAME_TYPE\0"
     "SSLV3_ALERT_BAD_CERTIFICATE\0"
     "SSLV3_ALERT_BAD_RECORD_MAC\0"
     "SSLV3_ALERT_CERTIFICATE_EXPIRED\0"
@@ -2523,10 +1102,7 @@
     "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\0"
     "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\0"
     "SSL_HANDSHAKE_FAILURE\0"
-    "SSL_SESSION_ID_CALLBACK_FAILED\0"
-    "SSL_SESSION_ID_CONFLICT\0"
     "SSL_SESSION_ID_CONTEXT_TOO_LONG\0"
-    "SSL_SESSION_ID_HAS_BAD_LENGTH\0"
     "TLSV1_ALERT_ACCESS_DENIED\0"
     "TLSV1_ALERT_DECODE_ERROR\0"
     "TLSV1_ALERT_DECRYPTION_FAILED\0"
@@ -2545,16 +1121,12 @@
     "TLSV1_CERTIFICATE_UNOBTAINABLE\0"
     "TLSV1_UNRECOGNIZED_NAME\0"
     "TLSV1_UNSUPPORTED_EXTENSION\0"
-    "TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER\0"
-    "TLS_ILLEGAL_EXPORTER_LABEL\0"
-    "TLS_INVALID_ECPOINTFORMAT_LIST\0"
     "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0"
     "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0"
     "TOO_MANY_EMPTY_FRAGMENTS\0"
     "TOO_MANY_WARNING_ALERTS\0"
     "UNABLE_TO_FIND_ECDH_PARAMETERS\0"
-    "UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS\0"
-    "UNEXPECTED_GROUP_CLOSE\0"
+    "UNEXPECTED_EXTENSION\0"
     "UNEXPECTED_MESSAGE\0"
     "UNEXPECTED_OPERATOR_IN_GROUP\0"
     "UNEXPECTED_RECORD\0"
@@ -2566,13 +1138,11 @@
     "UNKNOWN_PROTOCOL\0"
     "UNKNOWN_SSL_VERSION\0"
     "UNKNOWN_STATE\0"
-    "UNPROCESSED_HANDSHAKE_DATA\0"
     "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\0"
     "UNSUPPORTED_COMPRESSION_ALGORITHM\0"
     "UNSUPPORTED_ELLIPTIC_CURVE\0"
     "UNSUPPORTED_PROTOCOL\0"
-    "UNSUPPORTED_SSL_VERSION\0"
-    "USE_SRTP_NOT_NEGOTIATED\0"
+    "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\0"
     "WRONG_CERTIFICATE_TYPE\0"
     "WRONG_CIPHER_RETURNED\0"
     "WRONG_CURVE\0"
@@ -2593,12 +1163,14 @@
     "IDP_MISMATCH\0"
     "INVALID_DIRECTORY\0"
     "INVALID_FIELD_NAME\0"
+    "INVALID_PSS_PARAMETERS\0"
     "INVALID_TRUST\0"
     "ISSUER_MISMATCH\0"
     "KEY_TYPE_MISMATCH\0"
     "KEY_VALUES_MISMATCH\0"
     "LOADING_CERT_DIR\0"
     "LOADING_DEFAULTS\0"
+    "NAME_TOO_LONG\0"
     "NEWER_CRL_NOT_NEWER\0"
     "NOT_PKCS7_SIGNED_DATA\0"
     "NO_CERTIFICATES_INCLUDED\0"
@@ -2608,8 +1180,6 @@
     "PUBLIC_KEY_DECODE_ERROR\0"
     "PUBLIC_KEY_ENCODE_ERROR\0"
     "SHOULD_RETRY\0"
-    "UNABLE_TO_FIND_PARAMETERS_IN_CHAIN\0"
-    "UNABLE_TO_GET_CERTS_PUBLIC_KEY\0"
     "UNKNOWN_KEY_TYPE\0"
     "UNKNOWN_PURPOSE_ID\0"
     "UNKNOWN_TRUST_ID\0"
diff --git a/third_party/boringssl/linux-aarch64/crypto/aes/aesv8-armx64.S b/third_party/boringssl/linux-aarch64/crypto/aes/aesv8-armx64.S
index c414476..3e8cb16 100644
--- a/third_party/boringssl/linux-aarch64/crypto/aes/aesv8-armx64.S
+++ b/third_party/boringssl/linux-aarch64/crypto/aes/aesv8-armx64.S
@@ -1,5 +1,5 @@
 #if defined(__aarch64__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 #if __ARM_MAX_ARCH__>=7
 .text
@@ -13,6 +13,7 @@
 .long	0x1b,0x1b,0x1b,0x1b
 
 .globl	aes_v8_set_encrypt_key
+.hidden	aes_v8_set_encrypt_key
 .type	aes_v8_set_encrypt_key,%function
 .align	5
 aes_v8_set_encrypt_key:
@@ -180,6 +181,7 @@
 .size	aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
 
 .globl	aes_v8_set_decrypt_key
+.hidden	aes_v8_set_decrypt_key
 .type	aes_v8_set_decrypt_key,%function
 .align	5
 aes_v8_set_decrypt_key:
@@ -219,6 +221,7 @@
 	ret
 .size	aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
 .globl	aes_v8_encrypt
+.hidden	aes_v8_encrypt
 .type	aes_v8_encrypt,%function
 .align	5
 aes_v8_encrypt:
@@ -248,6 +251,7 @@
 	ret
 .size	aes_v8_encrypt,.-aes_v8_encrypt
 .globl	aes_v8_decrypt
+.hidden	aes_v8_decrypt
 .type	aes_v8_decrypt,%function
 .align	5
 aes_v8_decrypt:
@@ -277,6 +281,7 @@
 	ret
 .size	aes_v8_decrypt,.-aes_v8_decrypt
 .globl	aes_v8_cbc_encrypt
+.hidden	aes_v8_cbc_encrypt
 .type	aes_v8_cbc_encrypt,%function
 .align	5
 aes_v8_cbc_encrypt:
@@ -567,6 +572,7 @@
 	ret
 .size	aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
 .globl	aes_v8_ctr32_encrypt_blocks
+.hidden	aes_v8_ctr32_encrypt_blocks
 .type	aes_v8_ctr32_encrypt_blocks,%function
 .align	5
 aes_v8_ctr32_encrypt_blocks:
@@ -748,4 +754,4 @@
 	ret
 .size	aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-aarch64/crypto/bn/armv8-mont.S b/third_party/boringssl/linux-aarch64/crypto/bn/armv8-mont.S
new file mode 100644
index 0000000..74702db
--- /dev/null
+++ b/third_party/boringssl/linux-aarch64/crypto/bn/armv8-mont.S
@@ -0,0 +1,1407 @@
+#if defined(__aarch64__)
+.text
+
+.globl	bn_mul_mont
+.hidden	bn_mul_mont
+.type	bn_mul_mont,%function
+.align	5
+bn_mul_mont:
+	tst	x5,#7
+	b.eq	__bn_sqr8x_mont
+	tst	x5,#3
+	b.eq	__bn_mul4x_mont
+.Lmul_mont:
+	stp	x29,x30,[sp,#-64]!
+	add	x29,sp,#0
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+
+	ldr	x9,[x2],#8		// bp[0]
+	sub	x22,sp,x5,lsl#3
+	ldp	x7,x8,[x1],#16	// ap[0..1]
+	lsl	x5,x5,#3
+	ldr	x4,[x4]		// *n0
+	and	x22,x22,#-16		// ABI says so
+	ldp	x13,x14,[x3],#16	// np[0..1]
+
+	mul	x6,x7,x9		// ap[0]*bp[0]
+	sub	x21,x5,#16		// j=num-2
+	umulh	x7,x7,x9
+	mul	x10,x8,x9		// ap[1]*bp[0]
+	umulh	x11,x8,x9
+
+	mul	x15,x6,x4		// "tp[0]"*n0
+	mov	sp,x22			// alloca
+
+	// (*)	mul	x12,x13,x15	// np[0]*m1
+	umulh	x13,x13,x15
+	mul	x16,x14,x15		// np[1]*m1
+	// (*)	adds	x12,x12,x6	// discarded
+	// (*)	As for removal of first multiplication and addition
+	//	instructions. The outcome of first addition is
+	//	guaranteed to be zero, which leaves two computationally
+	//	significant outcomes: it either carries or not. Then
+	//	question is when does it carry? Is there alternative
+	//	way to deduce it? If you follow operations, you can
+	//	observe that condition for carry is quite simple:
+	//	x6 being non-zero. So that carry can be calculated
+	//	by adding -1 to x6. That's what next instruction does.
+	subs	xzr,x6,#1		// (*)
+	umulh	x17,x14,x15
+	adc	x13,x13,xzr
+	cbz	x21,.L1st_skip
+
+.L1st:
+	ldr	x8,[x1],#8
+	adds	x6,x10,x7
+	sub	x21,x21,#8		// j--
+	adc	x7,x11,xzr
+
+	ldr	x14,[x3],#8
+	adds	x12,x16,x13
+	mul	x10,x8,x9		// ap[j]*bp[0]
+	adc	x13,x17,xzr
+	umulh	x11,x8,x9
+
+	adds	x12,x12,x6
+	mul	x16,x14,x15		// np[j]*m1
+	adc	x13,x13,xzr
+	umulh	x17,x14,x15
+	str	x12,[x22],#8		// tp[j-1]
+	cbnz	x21,.L1st
+
+.L1st_skip:
+	adds	x6,x10,x7
+	sub	x1,x1,x5		// rewind x1
+	adc	x7,x11,xzr
+
+	adds	x12,x16,x13
+	sub	x3,x3,x5		// rewind x3
+	adc	x13,x17,xzr
+
+	adds	x12,x12,x6
+	sub	x20,x5,#8		// i=num-1
+	adcs	x13,x13,x7
+
+	adc	x19,xzr,xzr		// upmost overflow bit
+	stp	x12,x13,[x22]
+
+.Louter:
+	ldr	x9,[x2],#8		// bp[i]
+	ldp	x7,x8,[x1],#16
+	ldr	x23,[sp]		// tp[0]
+	add	x22,sp,#8
+
+	mul	x6,x7,x9		// ap[0]*bp[i]
+	sub	x21,x5,#16		// j=num-2
+	umulh	x7,x7,x9
+	ldp	x13,x14,[x3],#16
+	mul	x10,x8,x9		// ap[1]*bp[i]
+	adds	x6,x6,x23
+	umulh	x11,x8,x9
+	adc	x7,x7,xzr
+
+	mul	x15,x6,x4
+	sub	x20,x20,#8		// i--
+
+	// (*)	mul	x12,x13,x15	// np[0]*m1
+	umulh	x13,x13,x15
+	mul	x16,x14,x15		// np[1]*m1
+	// (*)	adds	x12,x12,x6
+	subs	xzr,x6,#1		// (*)
+	umulh	x17,x14,x15
+	cbz	x21,.Linner_skip
+
+.Linner:
+	ldr	x8,[x1],#8
+	adc	x13,x13,xzr
+	ldr	x23,[x22],#8		// tp[j]
+	adds	x6,x10,x7
+	sub	x21,x21,#8		// j--
+	adc	x7,x11,xzr
+
+	adds	x12,x16,x13
+	ldr	x14,[x3],#8
+	adc	x13,x17,xzr
+
+	mul	x10,x8,x9		// ap[j]*bp[i]
+	adds	x6,x6,x23
+	umulh	x11,x8,x9
+	adc	x7,x7,xzr
+
+	mul	x16,x14,x15		// np[j]*m1
+	adds	x12,x12,x6
+	umulh	x17,x14,x15
+	str	x12,[x22,#-16]		// tp[j-1]
+	cbnz	x21,.Linner
+
+.Linner_skip:
+	ldr	x23,[x22],#8		// tp[j]
+	adc	x13,x13,xzr
+	adds	x6,x10,x7
+	sub	x1,x1,x5		// rewind x1
+	adc	x7,x11,xzr
+
+	adds	x12,x16,x13
+	sub	x3,x3,x5		// rewind x3
+	adcs	x13,x17,x19
+	adc	x19,xzr,xzr
+
+	adds	x6,x6,x23
+	adc	x7,x7,xzr
+
+	adds	x12,x12,x6
+	adcs	x13,x13,x7
+	adc	x19,x19,xzr		// upmost overflow bit
+	stp	x12,x13,[x22,#-16]
+
+	cbnz	x20,.Louter
+
+	// Final step. We see if result is larger than modulus, and
+	// if it is, subtract the modulus. But comparison implies
+	// subtraction. So we subtract modulus, see if it borrowed,
+	// and conditionally copy original value.
+	ldr	x23,[sp]		// tp[0]
+	add	x22,sp,#8
+	ldr	x14,[x3],#8		// np[0]
+	subs	x21,x5,#8		// j=num-1 and clear borrow
+	mov	x1,x0
+.Lsub:
+	sbcs	x8,x23,x14		// tp[j]-np[j]
+	ldr	x23,[x22],#8
+	sub	x21,x21,#8		// j--
+	ldr	x14,[x3],#8
+	str	x8,[x1],#8		// rp[j]=tp[j]-np[j]
+	cbnz	x21,.Lsub
+
+	sbcs	x8,x23,x14
+	sbcs	x19,x19,xzr		// did it borrow?
+	str	x8,[x1],#8		// rp[num-1]
+
+	ldr	x23,[sp]		// tp[0]
+	add	x22,sp,#8
+	ldr	x8,[x0],#8		// rp[0]
+	sub	x5,x5,#8		// num--
+	nop
+.Lcond_copy:
+	sub	x5,x5,#8		// num--
+	csel	x14,x23,x8,lo		// did it borrow?
+	ldr	x23,[x22],#8
+	ldr	x8,[x0],#8
+	str	xzr,[x22,#-16]		// wipe tp
+	str	x14,[x0,#-16]
+	cbnz	x5,.Lcond_copy
+
+	csel	x14,x23,x8,lo
+	str	xzr,[x22,#-8]		// wipe tp
+	str	x14,[x0,#-8]
+
+	ldp	x19,x20,[x29,#16]
+	mov	sp,x29
+	ldp	x21,x22,[x29,#32]
+	mov	x0,#1
+	ldp	x23,x24,[x29,#48]
+	ldr	x29,[sp],#64
+	ret
+.size	bn_mul_mont,.-bn_mul_mont
+.type	__bn_sqr8x_mont,%function
+.align	5
+__bn_sqr8x_mont:
+	cmp	x1,x2
+	b.ne	__bn_mul4x_mont
+.Lsqr8x_mont:
+	stp	x29,x30,[sp,#-128]!
+	add	x29,sp,#0
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+	stp	x0,x3,[sp,#96]	// offload rp and np
+
+	ldp	x6,x7,[x1,#8*0]
+	ldp	x8,x9,[x1,#8*2]
+	ldp	x10,x11,[x1,#8*4]
+	ldp	x12,x13,[x1,#8*6]
+
+	sub	x2,sp,x5,lsl#4
+	lsl	x5,x5,#3
+	ldr	x4,[x4]		// *n0
+	mov	sp,x2			// alloca
+	sub	x27,x5,#8*8
+	b	.Lsqr8x_zero_start
+
+.Lsqr8x_zero:
+	sub	x27,x27,#8*8
+	stp	xzr,xzr,[x2,#8*0]
+	stp	xzr,xzr,[x2,#8*2]
+	stp	xzr,xzr,[x2,#8*4]
+	stp	xzr,xzr,[x2,#8*6]
+.Lsqr8x_zero_start:
+	stp	xzr,xzr,[x2,#8*8]
+	stp	xzr,xzr,[x2,#8*10]
+	stp	xzr,xzr,[x2,#8*12]
+	stp	xzr,xzr,[x2,#8*14]
+	add	x2,x2,#8*16
+	cbnz	x27,.Lsqr8x_zero
+
+	add	x3,x1,x5
+	add	x1,x1,#8*8
+	mov	x19,xzr
+	mov	x20,xzr
+	mov	x21,xzr
+	mov	x22,xzr
+	mov	x23,xzr
+	mov	x24,xzr
+	mov	x25,xzr
+	mov	x26,xzr
+	mov	x2,sp
+	str	x4,[x29,#112]		// offload n0
+
+	// Multiply everything but a[i]*a[i]
+.align	4
+.Lsqr8x_outer_loop:
+        //                                                 a[1]a[0]	(i)
+        //                                             a[2]a[0]
+        //                                         a[3]a[0]
+        //                                     a[4]a[0]
+        //                                 a[5]a[0]
+        //                             a[6]a[0]
+        //                         a[7]a[0]
+        //                                         a[2]a[1]		(ii)
+        //                                     a[3]a[1]
+        //                                 a[4]a[1]
+        //                             a[5]a[1]
+        //                         a[6]a[1]
+        //                     a[7]a[1]
+        //                                 a[3]a[2]			(iii)
+        //                             a[4]a[2]
+        //                         a[5]a[2]
+        //                     a[6]a[2]
+        //                 a[7]a[2]
+        //                         a[4]a[3]				(iv)
+        //                     a[5]a[3]
+        //                 a[6]a[3]
+        //             a[7]a[3]
+        //                 a[5]a[4]					(v)
+        //             a[6]a[4]
+        //         a[7]a[4]
+        //         a[6]a[5]						(vi)
+        //     a[7]a[5]
+        // a[7]a[6]							(vii)
+
+	mul	x14,x7,x6		// lo(a[1..7]*a[0])		(i)
+	mul	x15,x8,x6
+	mul	x16,x9,x6
+	mul	x17,x10,x6
+	adds	x20,x20,x14		// t[1]+lo(a[1]*a[0])
+	mul	x14,x11,x6
+	adcs	x21,x21,x15
+	mul	x15,x12,x6
+	adcs	x22,x22,x16
+	mul	x16,x13,x6
+	adcs	x23,x23,x17
+	umulh	x17,x7,x6		// hi(a[1..7]*a[0])
+	adcs	x24,x24,x14
+	umulh	x14,x8,x6
+	adcs	x25,x25,x15
+	umulh	x15,x9,x6
+	adcs	x26,x26,x16
+	umulh	x16,x10,x6
+	stp	x19,x20,[x2],#8*2	// t[0..1]
+	adc	x19,xzr,xzr		// t[8]
+	adds	x21,x21,x17		// t[2]+lo(a[1]*a[0])
+	umulh	x17,x11,x6
+	adcs	x22,x22,x14
+	umulh	x14,x12,x6
+	adcs	x23,x23,x15
+	umulh	x15,x13,x6
+	adcs	x24,x24,x16
+	mul	x16,x8,x7		// lo(a[2..7]*a[1])		(ii)
+	adcs	x25,x25,x17
+	mul	x17,x9,x7
+	adcs	x26,x26,x14
+	mul	x14,x10,x7
+	adc	x19,x19,x15
+
+	mul	x15,x11,x7
+	adds	x22,x22,x16
+	mul	x16,x12,x7
+	adcs	x23,x23,x17
+	mul	x17,x13,x7
+	adcs	x24,x24,x14
+	umulh	x14,x8,x7		// hi(a[2..7]*a[1])
+	adcs	x25,x25,x15
+	umulh	x15,x9,x7
+	adcs	x26,x26,x16
+	umulh	x16,x10,x7
+	adcs	x19,x19,x17
+	umulh	x17,x11,x7
+	stp	x21,x22,[x2],#8*2	// t[2..3]
+	adc	x20,xzr,xzr		// t[9]
+	adds	x23,x23,x14
+	umulh	x14,x12,x7
+	adcs	x24,x24,x15
+	umulh	x15,x13,x7
+	adcs	x25,x25,x16
+	mul	x16,x9,x8		// lo(a[3..7]*a[2])		(iii)
+	adcs	x26,x26,x17
+	mul	x17,x10,x8
+	adcs	x19,x19,x14
+	mul	x14,x11,x8
+	adc	x20,x20,x15
+
+	mul	x15,x12,x8
+	adds	x24,x24,x16
+	mul	x16,x13,x8
+	adcs	x25,x25,x17
+	umulh	x17,x9,x8		// hi(a[3..7]*a[2])
+	adcs	x26,x26,x14
+	umulh	x14,x10,x8
+	adcs	x19,x19,x15
+	umulh	x15,x11,x8
+	adcs	x20,x20,x16
+	umulh	x16,x12,x8
+	stp	x23,x24,[x2],#8*2	// t[4..5]
+	adc	x21,xzr,xzr		// t[10]
+	adds	x25,x25,x17
+	umulh	x17,x13,x8
+	adcs	x26,x26,x14
+	mul	x14,x10,x9		// lo(a[4..7]*a[3])		(iv)
+	adcs	x19,x19,x15
+	mul	x15,x11,x9
+	adcs	x20,x20,x16
+	mul	x16,x12,x9
+	adc	x21,x21,x17
+
+	mul	x17,x13,x9
+	adds	x26,x26,x14
+	umulh	x14,x10,x9		// hi(a[4..7]*a[3])
+	adcs	x19,x19,x15
+	umulh	x15,x11,x9
+	adcs	x20,x20,x16
+	umulh	x16,x12,x9
+	adcs	x21,x21,x17
+	umulh	x17,x13,x9
+	stp	x25,x26,[x2],#8*2	// t[6..7]
+	adc	x22,xzr,xzr		// t[11]
+	adds	x19,x19,x14
+	mul	x14,x11,x10		// lo(a[5..7]*a[4])		(v)
+	adcs	x20,x20,x15
+	mul	x15,x12,x10
+	adcs	x21,x21,x16
+	mul	x16,x13,x10
+	adc	x22,x22,x17
+
+	umulh	x17,x11,x10		// hi(a[5..7]*a[4])
+	adds	x20,x20,x14
+	umulh	x14,x12,x10
+	adcs	x21,x21,x15
+	umulh	x15,x13,x10
+	adcs	x22,x22,x16
+	mul	x16,x12,x11		// lo(a[6..7]*a[5])		(vi)
+	adc	x23,xzr,xzr		// t[12]
+	adds	x21,x21,x17
+	mul	x17,x13,x11
+	adcs	x22,x22,x14
+	umulh	x14,x12,x11		// hi(a[6..7]*a[5])
+	adc	x23,x23,x15
+
+	umulh	x15,x13,x11
+	adds	x22,x22,x16
+	mul	x16,x13,x12		// lo(a[7]*a[6])		(vii)
+	adcs	x23,x23,x17
+	umulh	x17,x13,x12		// hi(a[7]*a[6])
+	adc	x24,xzr,xzr		// t[13]
+	adds	x23,x23,x14
+	sub	x27,x3,x1	// done yet?
+	adc	x24,x24,x15
+
+	adds	x24,x24,x16
+	sub	x14,x3,x5	// rewinded ap
+	adc	x25,xzr,xzr		// t[14]
+	add	x25,x25,x17
+
+	cbz	x27,.Lsqr8x_outer_break
+
+	mov	x4,x6
+	ldp	x6,x7,[x2,#8*0]
+	ldp	x8,x9,[x2,#8*2]
+	ldp	x10,x11,[x2,#8*4]
+	ldp	x12,x13,[x2,#8*6]
+	adds	x19,x19,x6
+	adcs	x20,x20,x7
+	ldp	x6,x7,[x1,#8*0]
+	adcs	x21,x21,x8
+	adcs	x22,x22,x9
+	ldp	x8,x9,[x1,#8*2]
+	adcs	x23,x23,x10
+	adcs	x24,x24,x11
+	ldp	x10,x11,[x1,#8*4]
+	adcs	x25,x25,x12
+	mov	x0,x1
+	adcs	x26,xzr,x13
+	ldp	x12,x13,[x1,#8*6]
+	add	x1,x1,#8*8
+	//adc	x28,xzr,xzr		// moved below
+	mov	x27,#-8*8
+
+	//                                                         a[8]a[0]
+	//                                                     a[9]a[0]
+	//                                                 a[a]a[0]
+	//                                             a[b]a[0]
+	//                                         a[c]a[0]
+	//                                     a[d]a[0]
+	//                                 a[e]a[0]
+	//                             a[f]a[0]
+	//                                                     a[8]a[1]
+	//                         a[f]a[1]........................
+	//                                                 a[8]a[2]
+	//                     a[f]a[2]........................
+	//                                             a[8]a[3]
+	//                 a[f]a[3]........................
+	//                                         a[8]a[4]
+	//             a[f]a[4]........................
+	//                                     a[8]a[5]
+	//         a[f]a[5]........................
+	//                                 a[8]a[6]
+	//     a[f]a[6]........................
+	//                             a[8]a[7]
+	// a[f]a[7]........................
+.Lsqr8x_mul:
+	mul	x14,x6,x4
+	adc	x28,xzr,xzr		// carry bit, modulo-scheduled
+	mul	x15,x7,x4
+	add	x27,x27,#8
+	mul	x16,x8,x4
+	mul	x17,x9,x4
+	adds	x19,x19,x14
+	mul	x14,x10,x4
+	adcs	x20,x20,x15
+	mul	x15,x11,x4
+	adcs	x21,x21,x16
+	mul	x16,x12,x4
+	adcs	x22,x22,x17
+	mul	x17,x13,x4
+	adcs	x23,x23,x14
+	umulh	x14,x6,x4
+	adcs	x24,x24,x15
+	umulh	x15,x7,x4
+	adcs	x25,x25,x16
+	umulh	x16,x8,x4
+	adcs	x26,x26,x17
+	umulh	x17,x9,x4
+	adc	x28,x28,xzr
+	str	x19,[x2],#8
+	adds	x19,x20,x14
+	umulh	x14,x10,x4
+	adcs	x20,x21,x15
+	umulh	x15,x11,x4
+	adcs	x21,x22,x16
+	umulh	x16,x12,x4
+	adcs	x22,x23,x17
+	umulh	x17,x13,x4
+	ldr	x4,[x0,x27]
+	adcs	x23,x24,x14
+	adcs	x24,x25,x15
+	adcs	x25,x26,x16
+	adcs	x26,x28,x17
+	//adc	x28,xzr,xzr		// moved above
+	cbnz	x27,.Lsqr8x_mul
+					// note that carry flag is guaranteed
+					// to be zero at this point
+	cmp	x1,x3		// done yet?
+	b.eq	.Lsqr8x_break
+
+	ldp	x6,x7,[x2,#8*0]
+	ldp	x8,x9,[x2,#8*2]
+	ldp	x10,x11,[x2,#8*4]
+	ldp	x12,x13,[x2,#8*6]
+	adds	x19,x19,x6
+	ldr	x4,[x0,#-8*8]
+	adcs	x20,x20,x7
+	ldp	x6,x7,[x1,#8*0]
+	adcs	x21,x21,x8
+	adcs	x22,x22,x9
+	ldp	x8,x9,[x1,#8*2]
+	adcs	x23,x23,x10
+	adcs	x24,x24,x11
+	ldp	x10,x11,[x1,#8*4]
+	adcs	x25,x25,x12
+	mov	x27,#-8*8
+	adcs	x26,x26,x13
+	ldp	x12,x13,[x1,#8*6]
+	add	x1,x1,#8*8
+	//adc	x28,xzr,xzr		// moved above
+	b	.Lsqr8x_mul
+
+.align	4
+.Lsqr8x_break:
+	ldp	x6,x7,[x0,#8*0]
+	add	x1,x0,#8*8
+	ldp	x8,x9,[x0,#8*2]
+	sub	x14,x3,x1		// is it last iteration?
+	ldp	x10,x11,[x0,#8*4]
+	sub	x15,x2,x14
+	ldp	x12,x13,[x0,#8*6]
+	cbz	x14,.Lsqr8x_outer_loop
+
+	stp	x19,x20,[x2,#8*0]
+	ldp	x19,x20,[x15,#8*0]
+	stp	x21,x22,[x2,#8*2]
+	ldp	x21,x22,[x15,#8*2]
+	stp	x23,x24,[x2,#8*4]
+	ldp	x23,x24,[x15,#8*4]
+	stp	x25,x26,[x2,#8*6]
+	mov	x2,x15
+	ldp	x25,x26,[x15,#8*6]
+	b	.Lsqr8x_outer_loop
+
+.align	4
+.Lsqr8x_outer_break:
+	// Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0]
+	ldp	x7,x9,[x14,#8*0]	// recall that x14 is &a[0]
+	ldp	x15,x16,[sp,#8*1]
+	ldp	x11,x13,[x14,#8*2]
+	add	x1,x14,#8*4
+	ldp	x17,x14,[sp,#8*3]
+
+	stp	x19,x20,[x2,#8*0]
+	mul	x19,x7,x7
+	stp	x21,x22,[x2,#8*2]
+	umulh	x7,x7,x7
+	stp	x23,x24,[x2,#8*4]
+	mul	x8,x9,x9
+	stp	x25,x26,[x2,#8*6]
+	mov	x2,sp
+	umulh	x9,x9,x9
+	adds	x20,x7,x15,lsl#1
+	extr	x15,x16,x15,#63
+	sub	x27,x5,#8*4
+
+.Lsqr4x_shift_n_add:
+	adcs	x21,x8,x15
+	extr	x16,x17,x16,#63
+	sub	x27,x27,#8*4
+	adcs	x22,x9,x16
+	ldp	x15,x16,[x2,#8*5]
+	mul	x10,x11,x11
+	ldp	x7,x9,[x1],#8*2
+	umulh	x11,x11,x11
+	mul	x12,x13,x13
+	umulh	x13,x13,x13
+	extr	x17,x14,x17,#63
+	stp	x19,x20,[x2,#8*0]
+	adcs	x23,x10,x17
+	extr	x14,x15,x14,#63
+	stp	x21,x22,[x2,#8*2]
+	adcs	x24,x11,x14
+	ldp	x17,x14,[x2,#8*7]
+	extr	x15,x16,x15,#63
+	adcs	x25,x12,x15
+	extr	x16,x17,x16,#63
+	adcs	x26,x13,x16
+	ldp	x15,x16,[x2,#8*9]
+	mul	x6,x7,x7
+	ldp	x11,x13,[x1],#8*2
+	umulh	x7,x7,x7
+	mul	x8,x9,x9
+	umulh	x9,x9,x9
+	stp	x23,x24,[x2,#8*4]
+	extr	x17,x14,x17,#63
+	stp	x25,x26,[x2,#8*6]
+	add	x2,x2,#8*8
+	adcs	x19,x6,x17
+	extr	x14,x15,x14,#63
+	adcs	x20,x7,x14
+	ldp	x17,x14,[x2,#8*3]
+	extr	x15,x16,x15,#63
+	cbnz	x27,.Lsqr4x_shift_n_add
+	ldp	x1,x4,[x29,#104]	// pull np and n0
+
+	adcs	x21,x8,x15
+	extr	x16,x17,x16,#63
+	adcs	x22,x9,x16
+	ldp	x15,x16,[x2,#8*5]
+	mul	x10,x11,x11
+	umulh	x11,x11,x11
+	stp	x19,x20,[x2,#8*0]
+	mul	x12,x13,x13
+	umulh	x13,x13,x13
+	stp	x21,x22,[x2,#8*2]
+	extr	x17,x14,x17,#63
+	adcs	x23,x10,x17
+	extr	x14,x15,x14,#63
+	ldp	x19,x20,[sp,#8*0]
+	adcs	x24,x11,x14
+	extr	x15,x16,x15,#63
+	ldp	x6,x7,[x1,#8*0]
+	adcs	x25,x12,x15
+	extr	x16,xzr,x16,#63
+	ldp	x8,x9,[x1,#8*2]
+	adc	x26,x13,x16
+	ldp	x10,x11,[x1,#8*4]
+
+	// Reduce by 512 bits per iteration
+	mul	x28,x4,x19		// t[0]*n0
+	ldp	x12,x13,[x1,#8*6]
+	add	x3,x1,x5
+	ldp	x21,x22,[sp,#8*2]
+	stp	x23,x24,[x2,#8*4]
+	ldp	x23,x24,[sp,#8*4]
+	stp	x25,x26,[x2,#8*6]
+	ldp	x25,x26,[sp,#8*6]
+	add	x1,x1,#8*8
+	mov	x30,xzr		// initial top-most carry
+	mov	x2,sp
+	mov	x27,#8
+
+.Lsqr8x_reduction:
+	// (*)	mul	x14,x6,x28	// lo(n[0-7])*lo(t[0]*n0)
+	mul	x15,x7,x28
+	sub	x27,x27,#1
+	mul	x16,x8,x28
+	str	x28,[x2],#8		// put aside t[0]*n0 for tail processing
+	mul	x17,x9,x28
+	// (*)	adds	xzr,x19,x14
+	subs	xzr,x19,#1		// (*)
+	mul	x14,x10,x28
+	adcs	x19,x20,x15
+	mul	x15,x11,x28
+	adcs	x20,x21,x16
+	mul	x16,x12,x28
+	adcs	x21,x22,x17
+	mul	x17,x13,x28
+	adcs	x22,x23,x14
+	umulh	x14,x6,x28		// hi(n[0-7])*lo(t[0]*n0)
+	adcs	x23,x24,x15
+	umulh	x15,x7,x28
+	adcs	x24,x25,x16
+	umulh	x16,x8,x28
+	adcs	x25,x26,x17
+	umulh	x17,x9,x28
+	adc	x26,xzr,xzr
+	adds	x19,x19,x14
+	umulh	x14,x10,x28
+	adcs	x20,x20,x15
+	umulh	x15,x11,x28
+	adcs	x21,x21,x16
+	umulh	x16,x12,x28
+	adcs	x22,x22,x17
+	umulh	x17,x13,x28
+	mul	x28,x4,x19		// next t[0]*n0
+	adcs	x23,x23,x14
+	adcs	x24,x24,x15
+	adcs	x25,x25,x16
+	adc	x26,x26,x17
+	cbnz	x27,.Lsqr8x_reduction
+
+	ldp	x14,x15,[x2,#8*0]
+	ldp	x16,x17,[x2,#8*2]
+	mov	x0,x2
+	sub	x27,x3,x1	// done yet?
+	adds	x19,x19,x14
+	adcs	x20,x20,x15
+	ldp	x14,x15,[x2,#8*4]
+	adcs	x21,x21,x16
+	adcs	x22,x22,x17
+	ldp	x16,x17,[x2,#8*6]
+	adcs	x23,x23,x14
+	adcs	x24,x24,x15
+	adcs	x25,x25,x16
+	adcs	x26,x26,x17
+	//adc	x28,xzr,xzr		// moved below
+	cbz	x27,.Lsqr8x8_post_condition
+
+	ldr	x4,[x2,#-8*8]
+	ldp	x6,x7,[x1,#8*0]
+	ldp	x8,x9,[x1,#8*2]
+	ldp	x10,x11,[x1,#8*4]
+	mov	x27,#-8*8
+	ldp	x12,x13,[x1,#8*6]
+	add	x1,x1,#8*8
+
+.Lsqr8x_tail:
+	mul	x14,x6,x4
+	adc	x28,xzr,xzr		// carry bit, modulo-scheduled
+	mul	x15,x7,x4
+	add	x27,x27,#8
+	mul	x16,x8,x4
+	mul	x17,x9,x4
+	adds	x19,x19,x14
+	mul	x14,x10,x4
+	adcs	x20,x20,x15
+	mul	x15,x11,x4
+	adcs	x21,x21,x16
+	mul	x16,x12,x4
+	adcs	x22,x22,x17
+	mul	x17,x13,x4
+	adcs	x23,x23,x14
+	umulh	x14,x6,x4
+	adcs	x24,x24,x15
+	umulh	x15,x7,x4
+	adcs	x25,x25,x16
+	umulh	x16,x8,x4
+	adcs	x26,x26,x17
+	umulh	x17,x9,x4
+	adc	x28,x28,xzr
+	str	x19,[x2],#8
+	adds	x19,x20,x14
+	umulh	x14,x10,x4
+	adcs	x20,x21,x15
+	umulh	x15,x11,x4
+	adcs	x21,x22,x16
+	umulh	x16,x12,x4
+	adcs	x22,x23,x17
+	umulh	x17,x13,x4
+	ldr	x4,[x0,x27]
+	adcs	x23,x24,x14
+	adcs	x24,x25,x15
+	adcs	x25,x26,x16
+	adcs	x26,x28,x17
+	//adc	x28,xzr,xzr		// moved above
+	cbnz	x27,.Lsqr8x_tail
+					// note that carry flag is guaranteed
+					// to be zero at this point
+	ldp	x6,x7,[x2,#8*0]
+	sub	x27,x3,x1	// done yet?
+	sub	x16,x3,x5	// rewinded np
+	ldp	x8,x9,[x2,#8*2]
+	ldp	x10,x11,[x2,#8*4]
+	ldp	x12,x13,[x2,#8*6]
+	cbz	x27,.Lsqr8x_tail_break
+
+	ldr	x4,[x0,#-8*8]
+	adds	x19,x19,x6
+	adcs	x20,x20,x7
+	ldp	x6,x7,[x1,#8*0]
+	adcs	x21,x21,x8
+	adcs	x22,x22,x9
+	ldp	x8,x9,[x1,#8*2]
+	adcs	x23,x23,x10
+	adcs	x24,x24,x11
+	ldp	x10,x11,[x1,#8*4]
+	adcs	x25,x25,x12
+	mov	x27,#-8*8
+	adcs	x26,x26,x13
+	ldp	x12,x13,[x1,#8*6]
+	add	x1,x1,#8*8
+	//adc	x28,xzr,xzr		// moved above
+	b	.Lsqr8x_tail
+
+.align	4
+.Lsqr8x_tail_break:
+	ldr	x4,[x29,#112]		// pull n0
+	add	x27,x2,#8*8		// end of current t[num] window
+
+	subs	xzr,x30,#1		// "move" top-most carry to carry bit
+	adcs	x14,x19,x6
+	adcs	x15,x20,x7
+	ldp	x19,x20,[x0,#8*0]
+	adcs	x21,x21,x8
+	ldp	x6,x7,[x16,#8*0]	// recall that x16 is &n[0]
+	adcs	x22,x22,x9
+	ldp	x8,x9,[x16,#8*2]
+	adcs	x23,x23,x10
+	adcs	x24,x24,x11
+	ldp	x10,x11,[x16,#8*4]
+	adcs	x25,x25,x12
+	adcs	x26,x26,x13
+	ldp	x12,x13,[x16,#8*6]
+	add	x1,x16,#8*8
+	adc	x30,xzr,xzr	// top-most carry
+	mul	x28,x4,x19
+	stp	x14,x15,[x2,#8*0]
+	stp	x21,x22,[x2,#8*2]
+	ldp	x21,x22,[x0,#8*2]
+	stp	x23,x24,[x2,#8*4]
+	ldp	x23,x24,[x0,#8*4]
+	cmp	x27,x29		// did we hit the bottom?
+	stp	x25,x26,[x2,#8*6]
+	mov	x2,x0			// slide the window
+	ldp	x25,x26,[x0,#8*6]
+	mov	x27,#8
+	b.ne	.Lsqr8x_reduction
+
+	// Final step. We see if result is larger than modulus, and
+	// if it is, subtract the modulus. But comparison implies
+	// subtraction. So we subtract modulus, see if it borrowed,
+	// and conditionally copy original value.
+	ldr	x0,[x29,#96]		// pull rp
+	add	x2,x2,#8*8
+	subs	x14,x19,x6
+	sbcs	x15,x20,x7
+	sub	x27,x5,#8*8
+	mov	x3,x0		// x0 copy
+
+.Lsqr8x_sub:
+	sbcs	x16,x21,x8
+	ldp	x6,x7,[x1,#8*0]
+	sbcs	x17,x22,x9
+	stp	x14,x15,[x0,#8*0]
+	sbcs	x14,x23,x10
+	ldp	x8,x9,[x1,#8*2]
+	sbcs	x15,x24,x11
+	stp	x16,x17,[x0,#8*2]
+	sbcs	x16,x25,x12
+	ldp	x10,x11,[x1,#8*4]
+	sbcs	x17,x26,x13
+	ldp	x12,x13,[x1,#8*6]
+	add	x1,x1,#8*8
+	ldp	x19,x20,[x2,#8*0]
+	sub	x27,x27,#8*8
+	ldp	x21,x22,[x2,#8*2]
+	ldp	x23,x24,[x2,#8*4]
+	ldp	x25,x26,[x2,#8*6]
+	add	x2,x2,#8*8
+	stp	x14,x15,[x0,#8*4]
+	sbcs	x14,x19,x6
+	stp	x16,x17,[x0,#8*6]
+	add	x0,x0,#8*8
+	sbcs	x15,x20,x7
+	cbnz	x27,.Lsqr8x_sub
+
+	sbcs	x16,x21,x8
+	mov	x2,sp
+	add	x1,sp,x5
+	ldp	x6,x7,[x3,#8*0]
+	sbcs	x17,x22,x9
+	stp	x14,x15,[x0,#8*0]
+	sbcs	x14,x23,x10
+	ldp	x8,x9,[x3,#8*2]
+	sbcs	x15,x24,x11
+	stp	x16,x17,[x0,#8*2]
+	sbcs	x16,x25,x12
+	ldp	x19,x20,[x1,#8*0]
+	sbcs	x17,x26,x13
+	ldp	x21,x22,[x1,#8*2]
+	sbcs	xzr,x30,xzr	// did it borrow?
+	ldr	x30,[x29,#8]		// pull return address
+	stp	x14,x15,[x0,#8*4]
+	stp	x16,x17,[x0,#8*6]
+
+	sub	x27,x5,#8*4
+.Lsqr4x_cond_copy:
+	sub	x27,x27,#8*4
+	csel	x14,x19,x6,lo
+	stp	xzr,xzr,[x2,#8*0]
+	csel	x15,x20,x7,lo
+	ldp	x6,x7,[x3,#8*4]
+	ldp	x19,x20,[x1,#8*4]
+	csel	x16,x21,x8,lo
+	stp	xzr,xzr,[x2,#8*2]
+	add	x2,x2,#8*4
+	csel	x17,x22,x9,lo
+	ldp	x8,x9,[x3,#8*6]
+	ldp	x21,x22,[x1,#8*6]
+	add	x1,x1,#8*4
+	stp	x14,x15,[x3,#8*0]
+	stp	x16,x17,[x3,#8*2]
+	add	x3,x3,#8*4
+	stp	xzr,xzr,[x1,#8*0]
+	stp	xzr,xzr,[x1,#8*2]
+	cbnz	x27,.Lsqr4x_cond_copy
+
+	csel	x14,x19,x6,lo
+	stp	xzr,xzr,[x2,#8*0]
+	csel	x15,x20,x7,lo
+	stp	xzr,xzr,[x2,#8*2]
+	csel	x16,x21,x8,lo
+	csel	x17,x22,x9,lo
+	stp	x14,x15,[x3,#8*0]
+	stp	x16,x17,[x3,#8*2]
+
+	b	.Lsqr8x_done
+
+.align	4
+.Lsqr8x8_post_condition:
+	adc	x28,xzr,xzr
+	ldr	x30,[x29,#8]		// pull return address
+	// x19-7,x28 hold result, x6-7 hold modulus
+	subs	x6,x19,x6
+	ldr	x1,[x29,#96]		// pull rp
+	sbcs	x7,x20,x7
+	stp	xzr,xzr,[sp,#8*0]
+	sbcs	x8,x21,x8
+	stp	xzr,xzr,[sp,#8*2]
+	sbcs	x9,x22,x9
+	stp	xzr,xzr,[sp,#8*4]
+	sbcs	x10,x23,x10
+	stp	xzr,xzr,[sp,#8*6]
+	sbcs	x11,x24,x11
+	stp	xzr,xzr,[sp,#8*8]
+	sbcs	x12,x25,x12
+	stp	xzr,xzr,[sp,#8*10]
+	sbcs	x13,x26,x13
+	stp	xzr,xzr,[sp,#8*12]
+	sbcs	x28,x28,xzr	// did it borrow?
+	stp	xzr,xzr,[sp,#8*14]
+
+	// x6-7 hold result-modulus
+	csel	x6,x19,x6,lo
+	csel	x7,x20,x7,lo
+	csel	x8,x21,x8,lo
+	csel	x9,x22,x9,lo
+	stp	x6,x7,[x1,#8*0]
+	csel	x10,x23,x10,lo
+	csel	x11,x24,x11,lo
+	stp	x8,x9,[x1,#8*2]
+	csel	x12,x25,x12,lo
+	csel	x13,x26,x13,lo
+	stp	x10,x11,[x1,#8*4]
+	stp	x12,x13,[x1,#8*6]
+
+.Lsqr8x_done:
+	ldp	x19,x20,[x29,#16]
+	mov	sp,x29
+	ldp	x21,x22,[x29,#32]
+	mov	x0,#1
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldr	x29,[sp],#128
+	ret
+.size	__bn_sqr8x_mont,.-__bn_sqr8x_mont
+.type	__bn_mul4x_mont,%function
+.align	5
+__bn_mul4x_mont:
+	stp	x29,x30,[sp,#-128]!
+	add	x29,sp,#0
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+
+	sub	x26,sp,x5,lsl#3
+	lsl	x5,x5,#3
+	ldr	x4,[x4]		// *n0
+	sub	sp,x26,#8*4		// alloca
+
+	add	x10,x2,x5
+	add	x27,x1,x5
+	stp	x0,x10,[x29,#96]	// offload rp and &b[num]
+
+	ldr	x24,[x2,#8*0]		// b[0]
+	ldp	x6,x7,[x1,#8*0]	// a[0..3]
+	ldp	x8,x9,[x1,#8*2]
+	add	x1,x1,#8*4
+	mov	x19,xzr
+	mov	x20,xzr
+	mov	x21,xzr
+	mov	x22,xzr
+	ldp	x14,x15,[x3,#8*0]	// n[0..3]
+	ldp	x16,x17,[x3,#8*2]
+	adds	x3,x3,#8*4		// clear carry bit
+	mov	x0,xzr
+	mov	x28,#0
+	mov	x26,sp
+
+.Loop_mul4x_1st_reduction:
+	mul	x10,x6,x24		// lo(a[0..3]*b[0])
+	adc	x0,x0,xzr	// modulo-scheduled
+	mul	x11,x7,x24
+	add	x28,x28,#8
+	mul	x12,x8,x24
+	and	x28,x28,#31
+	mul	x13,x9,x24
+	adds	x19,x19,x10
+	umulh	x10,x6,x24		// hi(a[0..3]*b[0])
+	adcs	x20,x20,x11
+	mul	x25,x19,x4		// t[0]*n0
+	adcs	x21,x21,x12
+	umulh	x11,x7,x24
+	adcs	x22,x22,x13
+	umulh	x12,x8,x24
+	adc	x23,xzr,xzr
+	umulh	x13,x9,x24
+	ldr	x24,[x2,x28]		// next b[i] (or b[0])
+	adds	x20,x20,x10
+	// (*)	mul	x10,x14,x25	// lo(n[0..3]*t[0]*n0)
+	str	x25,[x26],#8		// put aside t[0]*n0 for tail processing
+	adcs	x21,x21,x11
+	mul	x11,x15,x25
+	adcs	x22,x22,x12
+	mul	x12,x16,x25
+	adc	x23,x23,x13		// can't overflow
+	mul	x13,x17,x25
+	// (*)	adds	xzr,x19,x10
+	subs	xzr,x19,#1		// (*)
+	umulh	x10,x14,x25		// hi(n[0..3]*t[0]*n0)
+	adcs	x19,x20,x11
+	umulh	x11,x15,x25
+	adcs	x20,x21,x12
+	umulh	x12,x16,x25
+	adcs	x21,x22,x13
+	umulh	x13,x17,x25
+	adcs	x22,x23,x0
+	adc	x0,xzr,xzr
+	adds	x19,x19,x10
+	sub	x10,x27,x1
+	adcs	x20,x20,x11
+	adcs	x21,x21,x12
+	adcs	x22,x22,x13
+	//adc	x0,x0,xzr
+	cbnz	x28,.Loop_mul4x_1st_reduction
+
+	cbz	x10,.Lmul4x4_post_condition
+
+	ldp	x6,x7,[x1,#8*0]	// a[4..7]
+	ldp	x8,x9,[x1,#8*2]
+	add	x1,x1,#8*4
+	ldr	x25,[sp]		// a[0]*n0
+	ldp	x14,x15,[x3,#8*0]	// n[4..7]
+	ldp	x16,x17,[x3,#8*2]
+	add	x3,x3,#8*4
+
+.Loop_mul4x_1st_tail:
+	mul	x10,x6,x24		// lo(a[4..7]*b[i])
+	adc	x0,x0,xzr	// modulo-scheduled
+	mul	x11,x7,x24
+	add	x28,x28,#8
+	mul	x12,x8,x24
+	and	x28,x28,#31
+	mul	x13,x9,x24
+	adds	x19,x19,x10
+	umulh	x10,x6,x24		// hi(a[4..7]*b[i])
+	adcs	x20,x20,x11
+	umulh	x11,x7,x24
+	adcs	x21,x21,x12
+	umulh	x12,x8,x24
+	adcs	x22,x22,x13
+	umulh	x13,x9,x24
+	adc	x23,xzr,xzr
+	ldr	x24,[x2,x28]		// next b[i] (or b[0])
+	adds	x20,x20,x10
+	mul	x10,x14,x25		// lo(n[4..7]*a[0]*n0)
+	adcs	x21,x21,x11
+	mul	x11,x15,x25
+	adcs	x22,x22,x12
+	mul	x12,x16,x25
+	adc	x23,x23,x13		// can't overflow
+	mul	x13,x17,x25
+	adds	x19,x19,x10
+	umulh	x10,x14,x25		// hi(n[4..7]*a[0]*n0)
+	adcs	x20,x20,x11
+	umulh	x11,x15,x25
+	adcs	x21,x21,x12
+	umulh	x12,x16,x25
+	adcs	x22,x22,x13
+	adcs	x23,x23,x0
+	umulh	x13,x17,x25
+	adc	x0,xzr,xzr
+	ldr	x25,[sp,x28]		// next t[0]*n0
+	str	x19,[x26],#8		// result!!!
+	adds	x19,x20,x10
+	sub	x10,x27,x1		// done yet?
+	adcs	x20,x21,x11
+	adcs	x21,x22,x12
+	adcs	x22,x23,x13
+	//adc	x0,x0,xzr
+	cbnz	x28,.Loop_mul4x_1st_tail
+
+	sub	x11,x27,x5	// rewinded x1
+	cbz	x10,.Lmul4x_proceed
+
+	ldp	x6,x7,[x1,#8*0]
+	ldp	x8,x9,[x1,#8*2]
+	add	x1,x1,#8*4
+	ldp	x14,x15,[x3,#8*0]
+	ldp	x16,x17,[x3,#8*2]
+	add	x3,x3,#8*4
+	b	.Loop_mul4x_1st_tail
+
+.align	5
+.Lmul4x_proceed:
+	ldr	x24,[x2,#8*4]!		// *++b
+	adc	x30,x0,xzr
+	ldp	x6,x7,[x11,#8*0]	// a[0..3]
+	sub	x3,x3,x5		// rewind np
+	ldp	x8,x9,[x11,#8*2]
+	add	x1,x11,#8*4
+
+	stp	x19,x20,[x26,#8*0]	// result!!!
+	ldp	x19,x20,[sp,#8*4]	// t[0..3]
+	stp	x21,x22,[x26,#8*2]	// result!!!
+	ldp	x21,x22,[sp,#8*6]
+
+	ldp	x14,x15,[x3,#8*0]	// n[0..3]
+	mov	x26,sp
+	ldp	x16,x17,[x3,#8*2]
+	adds	x3,x3,#8*4		// clear carry bit
+	mov	x0,xzr
+
+.align	4
+.Loop_mul4x_reduction:
+	mul	x10,x6,x24		// lo(a[0..3]*b[4])
+	adc	x0,x0,xzr	// modulo-scheduled
+	mul	x11,x7,x24
+	add	x28,x28,#8
+	mul	x12,x8,x24
+	and	x28,x28,#31
+	mul	x13,x9,x24
+	adds	x19,x19,x10
+	umulh	x10,x6,x24		// hi(a[0..3]*b[4])
+	adcs	x20,x20,x11
+	mul	x25,x19,x4		// t[0]*n0
+	adcs	x21,x21,x12
+	umulh	x11,x7,x24
+	adcs	x22,x22,x13
+	umulh	x12,x8,x24
+	adc	x23,xzr,xzr
+	umulh	x13,x9,x24
+	ldr	x24,[x2,x28]		// next b[i]
+	adds	x20,x20,x10
+	// (*)	mul	x10,x14,x25
+	str	x25,[x26],#8		// put aside t[0]*n0 for tail processing
+	adcs	x21,x21,x11
+	mul	x11,x15,x25		// lo(n[0..3]*t[0]*n0
+	adcs	x22,x22,x12
+	mul	x12,x16,x25
+	adc	x23,x23,x13		// can't overflow
+	mul	x13,x17,x25
+	// (*)	adds	xzr,x19,x10
+	subs	xzr,x19,#1		// (*)
+	umulh	x10,x14,x25		// hi(n[0..3]*t[0]*n0
+	adcs	x19,x20,x11
+	umulh	x11,x15,x25
+	adcs	x20,x21,x12
+	umulh	x12,x16,x25
+	adcs	x21,x22,x13
+	umulh	x13,x17,x25
+	adcs	x22,x23,x0
+	adc	x0,xzr,xzr
+	adds	x19,x19,x10
+	adcs	x20,x20,x11
+	adcs	x21,x21,x12
+	adcs	x22,x22,x13
+	//adc	x0,x0,xzr
+	cbnz	x28,.Loop_mul4x_reduction
+
+	adc	x0,x0,xzr
+	ldp	x10,x11,[x26,#8*4]	// t[4..7]
+	ldp	x12,x13,[x26,#8*6]
+	ldp	x6,x7,[x1,#8*0]	// a[4..7]
+	ldp	x8,x9,[x1,#8*2]
+	add	x1,x1,#8*4
+	adds	x19,x19,x10
+	adcs	x20,x20,x11
+	adcs	x21,x21,x12
+	adcs	x22,x22,x13
+	//adc	x0,x0,xzr
+
+	ldr	x25,[sp]		// t[0]*n0
+	ldp	x14,x15,[x3,#8*0]	// n[4..7]
+	ldp	x16,x17,[x3,#8*2]
+	add	x3,x3,#8*4
+
+.align	4
+.Loop_mul4x_tail:
+	mul	x10,x6,x24		// lo(a[4..7]*b[4])
+	adc	x0,x0,xzr	// modulo-scheduled
+	mul	x11,x7,x24
+	add	x28,x28,#8
+	mul	x12,x8,x24
+	and	x28,x28,#31
+	mul	x13,x9,x24
+	adds	x19,x19,x10
+	umulh	x10,x6,x24		// hi(a[4..7]*b[4])
+	adcs	x20,x20,x11
+	umulh	x11,x7,x24
+	adcs	x21,x21,x12
+	umulh	x12,x8,x24
+	adcs	x22,x22,x13
+	umulh	x13,x9,x24
+	adc	x23,xzr,xzr
+	ldr	x24,[x2,x28]		// next b[i]
+	adds	x20,x20,x10
+	mul	x10,x14,x25		// lo(n[4..7]*t[0]*n0)
+	adcs	x21,x21,x11
+	mul	x11,x15,x25
+	adcs	x22,x22,x12
+	mul	x12,x16,x25
+	adc	x23,x23,x13		// can't overflow
+	mul	x13,x17,x25
+	adds	x19,x19,x10
+	umulh	x10,x14,x25		// hi(n[4..7]*t[0]*n0)
+	adcs	x20,x20,x11
+	umulh	x11,x15,x25
+	adcs	x21,x21,x12
+	umulh	x12,x16,x25
+	adcs	x22,x22,x13
+	umulh	x13,x17,x25
+	adcs	x23,x23,x0
+	ldr	x25,[sp,x28]		// next a[0]*n0
+	adc	x0,xzr,xzr
+	str	x19,[x26],#8		// result!!!
+	adds	x19,x20,x10
+	sub	x10,x27,x1		// done yet?
+	adcs	x20,x21,x11
+	adcs	x21,x22,x12
+	adcs	x22,x23,x13
+	//adc	x0,x0,xzr
+	cbnz	x28,.Loop_mul4x_tail
+
+	sub	x11,x3,x5		// rewinded np?
+	adc	x0,x0,xzr
+	cbz	x10,.Loop_mul4x_break
+
+	ldp	x10,x11,[x26,#8*4]
+	ldp	x12,x13,[x26,#8*6]
+	ldp	x6,x7,[x1,#8*0]
+	ldp	x8,x9,[x1,#8*2]
+	add	x1,x1,#8*4
+	adds	x19,x19,x10
+	adcs	x20,x20,x11
+	adcs	x21,x21,x12
+	adcs	x22,x22,x13
+	//adc	x0,x0,xzr
+	ldp	x14,x15,[x3,#8*0]
+	ldp	x16,x17,[x3,#8*2]
+	add	x3,x3,#8*4
+	b	.Loop_mul4x_tail
+
+.align	4
+.Loop_mul4x_break:
+	ldp	x12,x13,[x29,#96]	// pull rp and &b[num]
+	adds	x19,x19,x30
+	add	x2,x2,#8*4		// bp++
+	adcs	x20,x20,xzr
+	sub	x1,x1,x5		// rewind ap
+	adcs	x21,x21,xzr
+	stp	x19,x20,[x26,#8*0]	// result!!!
+	adcs	x22,x22,xzr
+	ldp	x19,x20,[sp,#8*4]	// t[0..3]
+	adc	x30,x0,xzr
+	stp	x21,x22,[x26,#8*2]	// result!!!
+	cmp	x2,x13			// done yet?
+	ldp	x21,x22,[sp,#8*6]
+	ldp	x14,x15,[x11,#8*0]	// n[0..3]
+	ldp	x16,x17,[x11,#8*2]
+	add	x3,x11,#8*4
+	b.eq	.Lmul4x_post
+
+	ldr	x24,[x2]
+	ldp	x6,x7,[x1,#8*0]	// a[0..3]
+	ldp	x8,x9,[x1,#8*2]
+	adds	x1,x1,#8*4		// clear carry bit
+	mov	x0,xzr
+	mov	x26,sp
+	b	.Loop_mul4x_reduction
+
+.align	4
+.Lmul4x_post:
+	// Final step. We see if result is larger than modulus, and
+	// if it is, subtract the modulus. But comparison implies
+	// subtraction. So we subtract modulus, see if it borrowed,
+	// and conditionally copy original value.
+	mov	x0,x12
+	mov	x27,x12		// x0 copy
+	subs	x10,x19,x14
+	add	x26,sp,#8*8
+	sbcs	x11,x20,x15
+	sub	x28,x5,#8*4
+
+.Lmul4x_sub:
+	sbcs	x12,x21,x16
+	ldp	x14,x15,[x3,#8*0]
+	sub	x28,x28,#8*4
+	ldp	x19,x20,[x26,#8*0]
+	sbcs	x13,x22,x17
+	ldp	x16,x17,[x3,#8*2]
+	add	x3,x3,#8*4
+	ldp	x21,x22,[x26,#8*2]
+	add	x26,x26,#8*4
+	stp	x10,x11,[x0,#8*0]
+	sbcs	x10,x19,x14
+	stp	x12,x13,[x0,#8*2]
+	add	x0,x0,#8*4
+	sbcs	x11,x20,x15
+	cbnz	x28,.Lmul4x_sub
+
+	sbcs	x12,x21,x16
+	mov	x26,sp
+	add	x1,sp,#8*4
+	ldp	x6,x7,[x27,#8*0]
+	sbcs	x13,x22,x17
+	stp	x10,x11,[x0,#8*0]
+	ldp	x8,x9,[x27,#8*2]
+	stp	x12,x13,[x0,#8*2]
+	ldp	x19,x20,[x1,#8*0]
+	ldp	x21,x22,[x1,#8*2]
+	sbcs	xzr,x30,xzr	// did it borrow?
+	ldr	x30,[x29,#8]		// pull return address
+
+	sub	x28,x5,#8*4
+.Lmul4x_cond_copy:
+	sub	x28,x28,#8*4
+	csel	x10,x19,x6,lo
+	stp	xzr,xzr,[x26,#8*0]
+	csel	x11,x20,x7,lo
+	ldp	x6,x7,[x27,#8*4]
+	ldp	x19,x20,[x1,#8*4]
+	csel	x12,x21,x8,lo
+	stp	xzr,xzr,[x26,#8*2]
+	add	x26,x26,#8*4
+	csel	x13,x22,x9,lo
+	ldp	x8,x9,[x27,#8*6]
+	ldp	x21,x22,[x1,#8*6]
+	add	x1,x1,#8*4
+	stp	x10,x11,[x27,#8*0]
+	stp	x12,x13,[x27,#8*2]
+	add	x27,x27,#8*4
+	cbnz	x28,.Lmul4x_cond_copy
+
+	csel	x10,x19,x6,lo
+	stp	xzr,xzr,[x26,#8*0]
+	csel	x11,x20,x7,lo
+	stp	xzr,xzr,[x26,#8*2]
+	csel	x12,x21,x8,lo
+	stp	xzr,xzr,[x26,#8*3]
+	csel	x13,x22,x9,lo
+	stp	xzr,xzr,[x26,#8*4]
+	stp	x10,x11,[x27,#8*0]
+	stp	x12,x13,[x27,#8*2]
+
+	b	.Lmul4x_done
+
+.align	4
+.Lmul4x4_post_condition:
+	adc	x0,x0,xzr
+	ldr	x1,[x29,#96]		// pull rp
+	// x19-3,x0 hold result, x14-7 hold modulus
+	subs	x6,x19,x14
+	ldr	x30,[x29,#8]		// pull return address
+	sbcs	x7,x20,x15
+	stp	xzr,xzr,[sp,#8*0]
+	sbcs	x8,x21,x16
+	stp	xzr,xzr,[sp,#8*2]
+	sbcs	x9,x22,x17
+	stp	xzr,xzr,[sp,#8*4]
+	sbcs	xzr,x0,xzr		// did it borrow?
+	stp	xzr,xzr,[sp,#8*6]
+
+	// x6-3 hold result-modulus
+	csel	x6,x19,x6,lo
+	csel	x7,x20,x7,lo
+	csel	x8,x21,x8,lo
+	csel	x9,x22,x9,lo
+	stp	x6,x7,[x1,#8*0]
+	stp	x8,x9,[x1,#8*2]
+
+.Lmul4x_done:
+	ldp	x19,x20,[x29,#16]
+	mov	sp,x29
+	ldp	x21,x22,[x29,#32]
+	mov	x0,#1
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldr	x29,[sp],#128
+	ret
+.size	__bn_mul4x_mont,.-__bn_mul4x_mont
+.byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	2
+.align	4
+#endif
diff --git a/third_party/boringssl/linux-aarch64/crypto/chacha/chacha-armv8.S b/third_party/boringssl/linux-aarch64/crypto/chacha/chacha-armv8.S
new file mode 100644
index 0000000..6ff6bff
--- /dev/null
+++ b/third_party/boringssl/linux-aarch64/crypto/chacha/chacha-armv8.S
@@ -0,0 +1,1971 @@
+#if defined(__aarch64__)
+#include <openssl/arm_arch.h>
+
+.text
+
+
+
+.align	5
+.Lsigma:
+.quad	0x3320646e61707865,0x6b20657479622d32		// endian-neutral
+.Lone:
+.long	1,0,0,0
+.LOPENSSL_armcap_P:
+#ifdef	__ILP32__
+.long	OPENSSL_armcap_P-.
+#else
+.quad	OPENSSL_armcap_P-.
+#endif
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align	2
+
+.globl	ChaCha20_ctr32
+.hidden	ChaCha20_ctr32
+.type	ChaCha20_ctr32,%function
+.align	5
+ChaCha20_ctr32:
+	cbz	x2,.Labort
+	adr	x5,.LOPENSSL_armcap_P
+	cmp	x2,#192
+	b.lo	.Lshort
+#ifdef	__ILP32__
+	ldrsw	x6,[x5]
+#else
+	ldr	x6,[x5]
+#endif
+	ldr	w17,[x6,x5]
+	tst	w17,#ARMV7_NEON
+	b.ne	ChaCha20_neon
+
+.Lshort:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	x5,.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+	sub	sp,sp,#64
+
+	ldp	x22,x23,[x5]		// load sigma
+	ldp	x24,x25,[x3]		// load key
+	ldp	x26,x27,[x3,#16]
+	ldp	x28,x30,[x4]		// load counter
+#ifdef	__ARMEB__
+	ror	x24,x24,#32
+	ror	x25,x25,#32
+	ror	x26,x26,#32
+	ror	x27,x27,#32
+	ror	x28,x28,#32
+	ror	x30,x30,#32
+#endif
+
+.Loop_outer:
+	mov	w5,w22			// unpack key block
+	lsr	x6,x22,#32
+	mov	w7,w23
+	lsr	x8,x23,#32
+	mov	w9,w24
+	lsr	x10,x24,#32
+	mov	w11,w25
+	lsr	x12,x25,#32
+	mov	w13,w26
+	lsr	x14,x26,#32
+	mov	w15,w27
+	lsr	x16,x27,#32
+	mov	w17,w28
+	lsr	x19,x28,#32
+	mov	w20,w30
+	lsr	x21,x30,#32
+
+	mov	x4,#10
+	subs	x2,x2,#64
+.Loop:
+	sub	x4,x4,#1
+	add	w5,w5,w9
+	add	w6,w6,w10
+	add	w7,w7,w11
+	add	w8,w8,w12
+	eor	w17,w17,w5
+	eor	w19,w19,w6
+	eor	w20,w20,w7
+	eor	w21,w21,w8
+	ror	w17,w17,#16
+	ror	w19,w19,#16
+	ror	w20,w20,#16
+	ror	w21,w21,#16
+	add	w13,w13,w17
+	add	w14,w14,w19
+	add	w15,w15,w20
+	add	w16,w16,w21
+	eor	w9,w9,w13
+	eor	w10,w10,w14
+	eor	w11,w11,w15
+	eor	w12,w12,w16
+	ror	w9,w9,#20
+	ror	w10,w10,#20
+	ror	w11,w11,#20
+	ror	w12,w12,#20
+	add	w5,w5,w9
+	add	w6,w6,w10
+	add	w7,w7,w11
+	add	w8,w8,w12
+	eor	w17,w17,w5
+	eor	w19,w19,w6
+	eor	w20,w20,w7
+	eor	w21,w21,w8
+	ror	w17,w17,#24
+	ror	w19,w19,#24
+	ror	w20,w20,#24
+	ror	w21,w21,#24
+	add	w13,w13,w17
+	add	w14,w14,w19
+	add	w15,w15,w20
+	add	w16,w16,w21
+	eor	w9,w9,w13
+	eor	w10,w10,w14
+	eor	w11,w11,w15
+	eor	w12,w12,w16
+	ror	w9,w9,#25
+	ror	w10,w10,#25
+	ror	w11,w11,#25
+	ror	w12,w12,#25
+	add	w5,w5,w10
+	add	w6,w6,w11
+	add	w7,w7,w12
+	add	w8,w8,w9
+	eor	w21,w21,w5
+	eor	w17,w17,w6
+	eor	w19,w19,w7
+	eor	w20,w20,w8
+	ror	w21,w21,#16
+	ror	w17,w17,#16
+	ror	w19,w19,#16
+	ror	w20,w20,#16
+	add	w15,w15,w21
+	add	w16,w16,w17
+	add	w13,w13,w19
+	add	w14,w14,w20
+	eor	w10,w10,w15
+	eor	w11,w11,w16
+	eor	w12,w12,w13
+	eor	w9,w9,w14
+	ror	w10,w10,#20
+	ror	w11,w11,#20
+	ror	w12,w12,#20
+	ror	w9,w9,#20
+	add	w5,w5,w10
+	add	w6,w6,w11
+	add	w7,w7,w12
+	add	w8,w8,w9
+	eor	w21,w21,w5
+	eor	w17,w17,w6
+	eor	w19,w19,w7
+	eor	w20,w20,w8
+	ror	w21,w21,#24
+	ror	w17,w17,#24
+	ror	w19,w19,#24
+	ror	w20,w20,#24
+	add	w15,w15,w21
+	add	w16,w16,w17
+	add	w13,w13,w19
+	add	w14,w14,w20
+	eor	w10,w10,w15
+	eor	w11,w11,w16
+	eor	w12,w12,w13
+	eor	w9,w9,w14
+	ror	w10,w10,#25
+	ror	w11,w11,#25
+	ror	w12,w12,#25
+	ror	w9,w9,#25
+	cbnz	x4,.Loop
+
+	add	w5,w5,w22		// accumulate key block
+	add	x6,x6,x22,lsr#32
+	add	w7,w7,w23
+	add	x8,x8,x23,lsr#32
+	add	w9,w9,w24
+	add	x10,x10,x24,lsr#32
+	add	w11,w11,w25
+	add	x12,x12,x25,lsr#32
+	add	w13,w13,w26
+	add	x14,x14,x26,lsr#32
+	add	w15,w15,w27
+	add	x16,x16,x27,lsr#32
+	add	w17,w17,w28
+	add	x19,x19,x28,lsr#32
+	add	w20,w20,w30
+	add	x21,x21,x30,lsr#32
+
+	b.lo	.Ltail
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	x15,x15,x16
+	eor	x17,x17,x19
+	eor	x20,x20,x21
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#1			// increment counter
+	stp	x9,x11,[x0,#16]
+	stp	x13,x15,[x0,#32]
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+
+	b.hi	.Loop_outer
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+.Labort:
+	ret
+
+.align	4
+.Ltail:
+	add	x2,x2,#64
+.Less_than_64:
+	sub	x0,x0,#1
+	add	x1,x1,x2
+	add	x0,x0,x2
+	add	x4,sp,x2
+	neg	x2,x2
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	stp	x5,x7,[sp,#0]
+	stp	x9,x11,[sp,#16]
+	stp	x13,x15,[sp,#32]
+	stp	x17,x20,[sp,#48]
+
+.Loop_tail:
+	ldrb	w10,[x1,x2]
+	ldrb	w11,[x4,x2]
+	add	x2,x2,#1
+	eor	w10,w10,w11
+	strb	w10,[x0,x2]
+	cbnz	x2,.Loop_tail
+
+	stp	xzr,xzr,[sp,#0]
+	stp	xzr,xzr,[sp,#16]
+	stp	xzr,xzr,[sp,#32]
+	stp	xzr,xzr,[sp,#48]
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+
+.type	ChaCha20_neon,%function
+.align	5
+ChaCha20_neon:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	x5,.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+	cmp	x2,#512
+	b.hs	.L512_or_more_neon
+
+	sub	sp,sp,#64
+
+	ldp	x22,x23,[x5]		// load sigma
+	ld1	{v24.4s},[x5],#16
+	ldp	x24,x25,[x3]		// load key
+	ldp	x26,x27,[x3,#16]
+	ld1	{v25.4s,v26.4s},[x3]
+	ldp	x28,x30,[x4]		// load counter
+	ld1	{v27.4s},[x4]
+	ld1	{v31.4s},[x5]
+#ifdef	__ARMEB__
+	rev64	v24.4s,v24.4s
+	ror	x24,x24,#32
+	ror	x25,x25,#32
+	ror	x26,x26,#32
+	ror	x27,x27,#32
+	ror	x28,x28,#32
+	ror	x30,x30,#32
+#endif
+	add	v27.4s,v27.4s,v31.4s		// += 1
+	add	v28.4s,v27.4s,v31.4s
+	add	v29.4s,v28.4s,v31.4s
+	shl	v31.4s,v31.4s,#2			// 1 -> 4
+
+.Loop_outer_neon:
+	mov	w5,w22			// unpack key block
+	lsr	x6,x22,#32
+	mov	v0.16b,v24.16b
+	mov	w7,w23
+	lsr	x8,x23,#32
+	mov	v4.16b,v24.16b
+	mov	w9,w24
+	lsr	x10,x24,#32
+	mov	v16.16b,v24.16b
+	mov	w11,w25
+	mov	v1.16b,v25.16b
+	lsr	x12,x25,#32
+	mov	v5.16b,v25.16b
+	mov	w13,w26
+	mov	v17.16b,v25.16b
+	lsr	x14,x26,#32
+	mov	v3.16b,v27.16b
+	mov	w15,w27
+	mov	v7.16b,v28.16b
+	lsr	x16,x27,#32
+	mov	v19.16b,v29.16b
+	mov	w17,w28
+	mov	v2.16b,v26.16b
+	lsr	x19,x28,#32
+	mov	v6.16b,v26.16b
+	mov	w20,w30
+	mov	v18.16b,v26.16b
+	lsr	x21,x30,#32
+
+	mov	x4,#10
+	subs	x2,x2,#256
+.Loop_neon:
+	sub	x4,x4,#1
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v16.4s,v16.4s,v17.4s
+	add	w7,w7,w11
+	eor	v3.16b,v3.16b,v0.16b
+	add	w8,w8,w12
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w17,w17,w5
+	eor	v19.16b,v19.16b,v16.16b
+	eor	w19,w19,w6
+	rev32	v3.8h,v3.8h
+	eor	w20,w20,w7
+	rev32	v7.8h,v7.8h
+	eor	w21,w21,w8
+	rev32	v19.8h,v19.8h
+	ror	w17,w17,#16
+	add	v2.4s,v2.4s,v3.4s
+	ror	w19,w19,#16
+	add	v6.4s,v6.4s,v7.4s
+	ror	w20,w20,#16
+	add	v18.4s,v18.4s,v19.4s
+	ror	w21,w21,#16
+	eor	v20.16b,v1.16b,v2.16b
+	add	w13,w13,w17
+	eor	v21.16b,v5.16b,v6.16b
+	add	w14,w14,w19
+	eor	v22.16b,v17.16b,v18.16b
+	add	w15,w15,w20
+	ushr	v1.4s,v20.4s,#20
+	add	w16,w16,w21
+	ushr	v5.4s,v21.4s,#20
+	eor	w9,w9,w13
+	ushr	v17.4s,v22.4s,#20
+	eor	w10,w10,w14
+	sli	v1.4s,v20.4s,#12
+	eor	w11,w11,w15
+	sli	v5.4s,v21.4s,#12
+	eor	w12,w12,w16
+	sli	v17.4s,v22.4s,#12
+	ror	w9,w9,#20
+	add	v0.4s,v0.4s,v1.4s
+	ror	w10,w10,#20
+	add	v4.4s,v4.4s,v5.4s
+	ror	w11,w11,#20
+	add	v16.4s,v16.4s,v17.4s
+	ror	w12,w12,#20
+	eor	v20.16b,v3.16b,v0.16b
+	add	w5,w5,w9
+	eor	v21.16b,v7.16b,v4.16b
+	add	w6,w6,w10
+	eor	v22.16b,v19.16b,v16.16b
+	add	w7,w7,w11
+	ushr	v3.4s,v20.4s,#24
+	add	w8,w8,w12
+	ushr	v7.4s,v21.4s,#24
+	eor	w17,w17,w5
+	ushr	v19.4s,v22.4s,#24
+	eor	w19,w19,w6
+	sli	v3.4s,v20.4s,#8
+	eor	w20,w20,w7
+	sli	v7.4s,v21.4s,#8
+	eor	w21,w21,w8
+	sli	v19.4s,v22.4s,#8
+	ror	w17,w17,#24
+	add	v2.4s,v2.4s,v3.4s
+	ror	w19,w19,#24
+	add	v6.4s,v6.4s,v7.4s
+	ror	w20,w20,#24
+	add	v18.4s,v18.4s,v19.4s
+	ror	w21,w21,#24
+	eor	v20.16b,v1.16b,v2.16b
+	add	w13,w13,w17
+	eor	v21.16b,v5.16b,v6.16b
+	add	w14,w14,w19
+	eor	v22.16b,v17.16b,v18.16b
+	add	w15,w15,w20
+	ushr	v1.4s,v20.4s,#25
+	add	w16,w16,w21
+	ushr	v5.4s,v21.4s,#25
+	eor	w9,w9,w13
+	ushr	v17.4s,v22.4s,#25
+	eor	w10,w10,w14
+	sli	v1.4s,v20.4s,#7
+	eor	w11,w11,w15
+	sli	v5.4s,v21.4s,#7
+	eor	w12,w12,w16
+	sli	v17.4s,v22.4s,#7
+	ror	w9,w9,#25
+	ext	v2.16b,v2.16b,v2.16b,#8
+	ror	w10,w10,#25
+	ext	v6.16b,v6.16b,v6.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v3.16b,v3.16b,v3.16b,#12
+	ext	v7.16b,v7.16b,v7.16b,#12
+	ext	v19.16b,v19.16b,v19.16b,#12
+	ext	v1.16b,v1.16b,v1.16b,#4
+	ext	v5.16b,v5.16b,v5.16b,#4
+	ext	v17.16b,v17.16b,v17.16b,#4
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w10
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w11
+	add	v16.4s,v16.4s,v17.4s
+	add	w7,w7,w12
+	eor	v3.16b,v3.16b,v0.16b
+	add	w8,w8,w9
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w5
+	eor	v19.16b,v19.16b,v16.16b
+	eor	w17,w17,w6
+	rev32	v3.8h,v3.8h
+	eor	w19,w19,w7
+	rev32	v7.8h,v7.8h
+	eor	w20,w20,w8
+	rev32	v19.8h,v19.8h
+	ror	w21,w21,#16
+	add	v2.4s,v2.4s,v3.4s
+	ror	w17,w17,#16
+	add	v6.4s,v6.4s,v7.4s
+	ror	w19,w19,#16
+	add	v18.4s,v18.4s,v19.4s
+	ror	w20,w20,#16
+	eor	v20.16b,v1.16b,v2.16b
+	add	w15,w15,w21
+	eor	v21.16b,v5.16b,v6.16b
+	add	w16,w16,w17
+	eor	v22.16b,v17.16b,v18.16b
+	add	w13,w13,w19
+	ushr	v1.4s,v20.4s,#20
+	add	w14,w14,w20
+	ushr	v5.4s,v21.4s,#20
+	eor	w10,w10,w15
+	ushr	v17.4s,v22.4s,#20
+	eor	w11,w11,w16
+	sli	v1.4s,v20.4s,#12
+	eor	w12,w12,w13
+	sli	v5.4s,v21.4s,#12
+	eor	w9,w9,w14
+	sli	v17.4s,v22.4s,#12
+	ror	w10,w10,#20
+	add	v0.4s,v0.4s,v1.4s
+	ror	w11,w11,#20
+	add	v4.4s,v4.4s,v5.4s
+	ror	w12,w12,#20
+	add	v16.4s,v16.4s,v17.4s
+	ror	w9,w9,#20
+	eor	v20.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v21.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v22.16b,v19.16b,v16.16b
+	add	w7,w7,w12
+	ushr	v3.4s,v20.4s,#24
+	add	w8,w8,w9
+	ushr	v7.4s,v21.4s,#24
+	eor	w21,w21,w5
+	ushr	v19.4s,v22.4s,#24
+	eor	w17,w17,w6
+	sli	v3.4s,v20.4s,#8
+	eor	w19,w19,w7
+	sli	v7.4s,v21.4s,#8
+	eor	w20,w20,w8
+	sli	v19.4s,v22.4s,#8
+	ror	w21,w21,#24
+	add	v2.4s,v2.4s,v3.4s
+	ror	w17,w17,#24
+	add	v6.4s,v6.4s,v7.4s
+	ror	w19,w19,#24
+	add	v18.4s,v18.4s,v19.4s
+	ror	w20,w20,#24
+	eor	v20.16b,v1.16b,v2.16b
+	add	w15,w15,w21
+	eor	v21.16b,v5.16b,v6.16b
+	add	w16,w16,w17
+	eor	v22.16b,v17.16b,v18.16b
+	add	w13,w13,w19
+	ushr	v1.4s,v20.4s,#25
+	add	w14,w14,w20
+	ushr	v5.4s,v21.4s,#25
+	eor	w10,w10,w15
+	ushr	v17.4s,v22.4s,#25
+	eor	w11,w11,w16
+	sli	v1.4s,v20.4s,#7
+	eor	w12,w12,w13
+	sli	v5.4s,v21.4s,#7
+	eor	w9,w9,w14
+	sli	v17.4s,v22.4s,#7
+	ror	w10,w10,#25
+	ext	v2.16b,v2.16b,v2.16b,#8
+	ror	w11,w11,#25
+	ext	v6.16b,v6.16b,v6.16b,#8
+	ror	w12,w12,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#4
+	ext	v7.16b,v7.16b,v7.16b,#4
+	ext	v19.16b,v19.16b,v19.16b,#4
+	ext	v1.16b,v1.16b,v1.16b,#12
+	ext	v5.16b,v5.16b,v5.16b,#12
+	ext	v17.16b,v17.16b,v17.16b,#12
+	cbnz	x4,.Loop_neon
+
+	add	w5,w5,w22		// accumulate key block
+	add	v0.4s,v0.4s,v24.4s
+	add	x6,x6,x22,lsr#32
+	add	v4.4s,v4.4s,v24.4s
+	add	w7,w7,w23
+	add	v16.4s,v16.4s,v24.4s
+	add	x8,x8,x23,lsr#32
+	add	v2.4s,v2.4s,v26.4s
+	add	w9,w9,w24
+	add	v6.4s,v6.4s,v26.4s
+	add	x10,x10,x24,lsr#32
+	add	v18.4s,v18.4s,v26.4s
+	add	w11,w11,w25
+	add	v3.4s,v3.4s,v27.4s
+	add	x12,x12,x25,lsr#32
+	add	w13,w13,w26
+	add	v7.4s,v7.4s,v28.4s
+	add	x14,x14,x26,lsr#32
+	add	w15,w15,w27
+	add	v19.4s,v19.4s,v29.4s
+	add	x16,x16,x27,lsr#32
+	add	w17,w17,w28
+	add	v1.4s,v1.4s,v25.4s
+	add	x19,x19,x28,lsr#32
+	add	w20,w20,w30
+	add	v5.4s,v5.4s,v25.4s
+	add	x21,x21,x30,lsr#32
+	add	v17.4s,v17.4s,v25.4s
+
+	b.lo	.Ltail_neon
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	v0.16b,v0.16b,v20.16b
+	eor	x15,x15,x16
+	eor	v1.16b,v1.16b,v21.16b
+	eor	x17,x17,x19
+	eor	v2.16b,v2.16b,v22.16b
+	eor	x20,x20,x21
+	eor	v3.16b,v3.16b,v23.16b
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#4			// increment counter
+	stp	x9,x11,[x0,#16]
+	add	v27.4s,v27.4s,v31.4s		// += 4
+	stp	x13,x15,[x0,#32]
+	add	v28.4s,v28.4s,v31.4s
+	stp	x17,x20,[x0,#48]
+	add	v29.4s,v29.4s,v31.4s
+	add	x0,x0,#64
+
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+	ld1	{v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64
+
+	eor	v4.16b,v4.16b,v20.16b
+	eor	v5.16b,v5.16b,v21.16b
+	eor	v6.16b,v6.16b,v22.16b
+	eor	v7.16b,v7.16b,v23.16b
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+
+	eor	v16.16b,v16.16b,v0.16b
+	eor	v17.16b,v17.16b,v1.16b
+	eor	v18.16b,v18.16b,v2.16b
+	eor	v19.16b,v19.16b,v3.16b
+	st1	{v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64
+
+	b.hi	.Loop_outer_neon
+
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+
+.Ltail_neon:
+	add	x2,x2,#256
+	cmp	x2,#64
+	b.lo	.Less_than_64
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	x15,x15,x16
+	eor	x17,x17,x19
+	eor	x20,x20,x21
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#4			// increment counter
+	stp	x9,x11,[x0,#16]
+	stp	x13,x15,[x0,#32]
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+	b.eq	.Ldone_neon
+	sub	x2,x2,#64
+	cmp	x2,#64
+	b.lo	.Less_than_128
+
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+	eor	v0.16b,v0.16b,v20.16b
+	eor	v1.16b,v1.16b,v21.16b
+	eor	v2.16b,v2.16b,v22.16b
+	eor	v3.16b,v3.16b,v23.16b
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+	b.eq	.Ldone_neon
+	sub	x2,x2,#64
+	cmp	x2,#64
+	b.lo	.Less_than_192
+
+	ld1	{v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+	eor	v4.16b,v4.16b,v20.16b
+	eor	v5.16b,v5.16b,v21.16b
+	eor	v6.16b,v6.16b,v22.16b
+	eor	v7.16b,v7.16b,v23.16b
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+	b.eq	.Ldone_neon
+	sub	x2,x2,#64
+
+	st1	{v16.16b,v17.16b,v18.16b,v19.16b},[sp]
+	b	.Last_neon
+
+.Less_than_128:
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[sp]
+	b	.Last_neon
+.Less_than_192:
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[sp]
+	b	.Last_neon
+
+.align	4
+.Last_neon:
+	sub	x0,x0,#1
+	add	x1,x1,x2
+	add	x0,x0,x2
+	add	x4,sp,x2
+	neg	x2,x2
+
+.Loop_tail_neon:
+	ldrb	w10,[x1,x2]
+	ldrb	w11,[x4,x2]
+	add	x2,x2,#1
+	eor	w10,w10,w11
+	strb	w10,[x0,x2]
+	cbnz	x2,.Loop_tail_neon
+
+	stp	xzr,xzr,[sp,#0]
+	stp	xzr,xzr,[sp,#16]
+	stp	xzr,xzr,[sp,#32]
+	stp	xzr,xzr,[sp,#48]
+
+.Ldone_neon:
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_neon,.-ChaCha20_neon
+.type	ChaCha20_512_neon,%function
+.align	5
+ChaCha20_512_neon:
+	stp	x29,x30,[sp,#-96]!
+	add	x29,sp,#0
+
+	adr	x5,.Lsigma
+	stp	x19,x20,[sp,#16]
+	stp	x21,x22,[sp,#32]
+	stp	x23,x24,[sp,#48]
+	stp	x25,x26,[sp,#64]
+	stp	x27,x28,[sp,#80]
+
+.L512_or_more_neon:
+	sub	sp,sp,#128+64
+
+	ldp	x22,x23,[x5]		// load sigma
+	ld1	{v24.4s},[x5],#16
+	ldp	x24,x25,[x3]		// load key
+	ldp	x26,x27,[x3,#16]
+	ld1	{v25.4s,v26.4s},[x3]
+	ldp	x28,x30,[x4]		// load counter
+	ld1	{v27.4s},[x4]
+	ld1	{v31.4s},[x5]
+#ifdef	__ARMEB__
+	rev64	v24.4s,v24.4s
+	ror	x24,x24,#32
+	ror	x25,x25,#32
+	ror	x26,x26,#32
+	ror	x27,x27,#32
+	ror	x28,x28,#32
+	ror	x30,x30,#32
+#endif
+	add	v27.4s,v27.4s,v31.4s		// += 1
+	stp	q24,q25,[sp,#0]		// off-load key block, invariant part
+	add	v27.4s,v27.4s,v31.4s		// not typo
+	str	q26,[sp,#32]
+	add	v28.4s,v27.4s,v31.4s
+	add	v29.4s,v28.4s,v31.4s
+	add	v30.4s,v29.4s,v31.4s
+	shl	v31.4s,v31.4s,#2			// 1 -> 4
+
+	stp	d8,d9,[sp,#128+0]		// meet ABI requirements
+	stp	d10,d11,[sp,#128+16]
+	stp	d12,d13,[sp,#128+32]
+	stp	d14,d15,[sp,#128+48]
+
+	sub	x2,x2,#512			// not typo
+
+.Loop_outer_512_neon:
+	mov	v0.16b,v24.16b
+	mov	v4.16b,v24.16b
+	mov	v8.16b,v24.16b
+	mov	v12.16b,v24.16b
+	mov	v16.16b,v24.16b
+	mov	v20.16b,v24.16b
+	mov	v1.16b,v25.16b
+	mov	w5,w22			// unpack key block
+	mov	v5.16b,v25.16b
+	lsr	x6,x22,#32
+	mov	v9.16b,v25.16b
+	mov	w7,w23
+	mov	v13.16b,v25.16b
+	lsr	x8,x23,#32
+	mov	v17.16b,v25.16b
+	mov	w9,w24
+	mov	v21.16b,v25.16b
+	lsr	x10,x24,#32
+	mov	v3.16b,v27.16b
+	mov	w11,w25
+	mov	v7.16b,v28.16b
+	lsr	x12,x25,#32
+	mov	v11.16b,v29.16b
+	mov	w13,w26
+	mov	v15.16b,v30.16b
+	lsr	x14,x26,#32
+	mov	v2.16b,v26.16b
+	mov	w15,w27
+	mov	v6.16b,v26.16b
+	lsr	x16,x27,#32
+	add	v19.4s,v3.4s,v31.4s			// +4
+	mov	w17,w28
+	add	v23.4s,v7.4s,v31.4s			// +4
+	lsr	x19,x28,#32
+	mov	v10.16b,v26.16b
+	mov	w20,w30
+	mov	v14.16b,v26.16b
+	lsr	x21,x30,#32
+	mov	v18.16b,v26.16b
+	stp	q27,q28,[sp,#48]		// off-load key block, variable part
+	mov	v22.16b,v26.16b
+	str	q29,[sp,#80]
+
+	mov	x4,#5
+	subs	x2,x2,#512
+.Loop_upper_neon:
+	sub	x4,x4,#1
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#12
+	ext	v7.16b,v7.16b,v7.16b,#12
+	ext	v11.16b,v11.16b,v11.16b,#12
+	ext	v15.16b,v15.16b,v15.16b,#12
+	ext	v19.16b,v19.16b,v19.16b,#12
+	ext	v23.16b,v23.16b,v23.16b,#12
+	ext	v1.16b,v1.16b,v1.16b,#4
+	ext	v5.16b,v5.16b,v5.16b,#4
+	ext	v9.16b,v9.16b,v9.16b,#4
+	ext	v13.16b,v13.16b,v13.16b,#4
+	ext	v17.16b,v17.16b,v17.16b,#4
+	ext	v21.16b,v21.16b,v21.16b,#4
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#4
+	ext	v7.16b,v7.16b,v7.16b,#4
+	ext	v11.16b,v11.16b,v11.16b,#4
+	ext	v15.16b,v15.16b,v15.16b,#4
+	ext	v19.16b,v19.16b,v19.16b,#4
+	ext	v23.16b,v23.16b,v23.16b,#4
+	ext	v1.16b,v1.16b,v1.16b,#12
+	ext	v5.16b,v5.16b,v5.16b,#12
+	ext	v9.16b,v9.16b,v9.16b,#12
+	ext	v13.16b,v13.16b,v13.16b,#12
+	ext	v17.16b,v17.16b,v17.16b,#12
+	ext	v21.16b,v21.16b,v21.16b,#12
+	cbnz	x4,.Loop_upper_neon
+
+	add	w5,w5,w22		// accumulate key block
+	add	x6,x6,x22,lsr#32
+	add	w7,w7,w23
+	add	x8,x8,x23,lsr#32
+	add	w9,w9,w24
+	add	x10,x10,x24,lsr#32
+	add	w11,w11,w25
+	add	x12,x12,x25,lsr#32
+	add	w13,w13,w26
+	add	x14,x14,x26,lsr#32
+	add	w15,w15,w27
+	add	x16,x16,x27,lsr#32
+	add	w17,w17,w28
+	add	x19,x19,x28,lsr#32
+	add	w20,w20,w30
+	add	x21,x21,x30,lsr#32
+
+	add	x5,x5,x6,lsl#32	// pack
+	add	x7,x7,x8,lsl#32
+	ldp	x6,x8,[x1,#0]		// load input
+	add	x9,x9,x10,lsl#32
+	add	x11,x11,x12,lsl#32
+	ldp	x10,x12,[x1,#16]
+	add	x13,x13,x14,lsl#32
+	add	x15,x15,x16,lsl#32
+	ldp	x14,x16,[x1,#32]
+	add	x17,x17,x19,lsl#32
+	add	x20,x20,x21,lsl#32
+	ldp	x19,x21,[x1,#48]
+	add	x1,x1,#64
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	x15,x15,x16
+	eor	x17,x17,x19
+	eor	x20,x20,x21
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#1			// increment counter
+	mov	w5,w22			// unpack key block
+	lsr	x6,x22,#32
+	stp	x9,x11,[x0,#16]
+	mov	w7,w23
+	lsr	x8,x23,#32
+	stp	x13,x15,[x0,#32]
+	mov	w9,w24
+	lsr	x10,x24,#32
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+	mov	w11,w25
+	lsr	x12,x25,#32
+	mov	w13,w26
+	lsr	x14,x26,#32
+	mov	w15,w27
+	lsr	x16,x27,#32
+	mov	w17,w28
+	lsr	x19,x28,#32
+	mov	w20,w30
+	lsr	x21,x30,#32
+
+	mov	x4,#5
+.Loop_lower_neon:
+	sub	x4,x4,#1
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#12
+	ext	v7.16b,v7.16b,v7.16b,#12
+	ext	v11.16b,v11.16b,v11.16b,#12
+	ext	v15.16b,v15.16b,v15.16b,#12
+	ext	v19.16b,v19.16b,v19.16b,#12
+	ext	v23.16b,v23.16b,v23.16b,#12
+	ext	v1.16b,v1.16b,v1.16b,#4
+	ext	v5.16b,v5.16b,v5.16b,#4
+	ext	v9.16b,v9.16b,v9.16b,#4
+	ext	v13.16b,v13.16b,v13.16b,#4
+	ext	v17.16b,v17.16b,v17.16b,#4
+	ext	v21.16b,v21.16b,v21.16b,#4
+	add	v0.4s,v0.4s,v1.4s
+	add	w5,w5,w9
+	add	v4.4s,v4.4s,v5.4s
+	add	w6,w6,w10
+	add	v8.4s,v8.4s,v9.4s
+	add	w7,w7,w11
+	add	v12.4s,v12.4s,v13.4s
+	add	w8,w8,w12
+	add	v16.4s,v16.4s,v17.4s
+	eor	w17,w17,w5
+	add	v20.4s,v20.4s,v21.4s
+	eor	w19,w19,w6
+	eor	v3.16b,v3.16b,v0.16b
+	eor	w20,w20,w7
+	eor	v7.16b,v7.16b,v4.16b
+	eor	w21,w21,w8
+	eor	v11.16b,v11.16b,v8.16b
+	ror	w17,w17,#16
+	eor	v15.16b,v15.16b,v12.16b
+	ror	w19,w19,#16
+	eor	v19.16b,v19.16b,v16.16b
+	ror	w20,w20,#16
+	eor	v23.16b,v23.16b,v20.16b
+	ror	w21,w21,#16
+	rev32	v3.8h,v3.8h
+	add	w13,w13,w17
+	rev32	v7.8h,v7.8h
+	add	w14,w14,w19
+	rev32	v11.8h,v11.8h
+	add	w15,w15,w20
+	rev32	v15.8h,v15.8h
+	add	w16,w16,w21
+	rev32	v19.8h,v19.8h
+	eor	w9,w9,w13
+	rev32	v23.8h,v23.8h
+	eor	w10,w10,w14
+	add	v2.4s,v2.4s,v3.4s
+	eor	w11,w11,w15
+	add	v6.4s,v6.4s,v7.4s
+	eor	w12,w12,w16
+	add	v10.4s,v10.4s,v11.4s
+	ror	w9,w9,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w10,w10,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w11,w11,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w12,w12,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w9
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w10
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w11
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w12
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w17,w17,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w19,w19,w6
+	ushr	v1.4s,v24.4s,#20
+	eor	w20,w20,w7
+	ushr	v5.4s,v25.4s,#20
+	eor	w21,w21,w8
+	ushr	v9.4s,v26.4s,#20
+	ror	w17,w17,#24
+	ushr	v13.4s,v27.4s,#20
+	ror	w19,w19,#24
+	ushr	v17.4s,v28.4s,#20
+	ror	w20,w20,#24
+	ushr	v21.4s,v29.4s,#20
+	ror	w21,w21,#24
+	sli	v1.4s,v24.4s,#12
+	add	w13,w13,w17
+	sli	v5.4s,v25.4s,#12
+	add	w14,w14,w19
+	sli	v9.4s,v26.4s,#12
+	add	w15,w15,w20
+	sli	v13.4s,v27.4s,#12
+	add	w16,w16,w21
+	sli	v17.4s,v28.4s,#12
+	eor	w9,w9,w13
+	sli	v21.4s,v29.4s,#12
+	eor	w10,w10,w14
+	add	v0.4s,v0.4s,v1.4s
+	eor	w11,w11,w15
+	add	v4.4s,v4.4s,v5.4s
+	eor	w12,w12,w16
+	add	v8.4s,v8.4s,v9.4s
+	ror	w9,w9,#25
+	add	v12.4s,v12.4s,v13.4s
+	ror	w10,w10,#25
+	add	v16.4s,v16.4s,v17.4s
+	ror	w11,w11,#25
+	add	v20.4s,v20.4s,v21.4s
+	ror	w12,w12,#25
+	eor	v24.16b,v3.16b,v0.16b
+	add	w5,w5,w10
+	eor	v25.16b,v7.16b,v4.16b
+	add	w6,w6,w11
+	eor	v26.16b,v11.16b,v8.16b
+	add	w7,w7,w12
+	eor	v27.16b,v15.16b,v12.16b
+	add	w8,w8,w9
+	eor	v28.16b,v19.16b,v16.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v23.16b,v20.16b
+	eor	w17,w17,w6
+	ushr	v3.4s,v24.4s,#24
+	eor	w19,w19,w7
+	ushr	v7.4s,v25.4s,#24
+	eor	w20,w20,w8
+	ushr	v11.4s,v26.4s,#24
+	ror	w21,w21,#16
+	ushr	v15.4s,v27.4s,#24
+	ror	w17,w17,#16
+	ushr	v19.4s,v28.4s,#24
+	ror	w19,w19,#16
+	ushr	v23.4s,v29.4s,#24
+	ror	w20,w20,#16
+	sli	v3.4s,v24.4s,#8
+	add	w15,w15,w21
+	sli	v7.4s,v25.4s,#8
+	add	w16,w16,w17
+	sli	v11.4s,v26.4s,#8
+	add	w13,w13,w19
+	sli	v15.4s,v27.4s,#8
+	add	w14,w14,w20
+	sli	v19.4s,v28.4s,#8
+	eor	w10,w10,w15
+	sli	v23.4s,v29.4s,#8
+	eor	w11,w11,w16
+	add	v2.4s,v2.4s,v3.4s
+	eor	w12,w12,w13
+	add	v6.4s,v6.4s,v7.4s
+	eor	w9,w9,w14
+	add	v10.4s,v10.4s,v11.4s
+	ror	w10,w10,#20
+	add	v14.4s,v14.4s,v15.4s
+	ror	w11,w11,#20
+	add	v18.4s,v18.4s,v19.4s
+	ror	w12,w12,#20
+	add	v22.4s,v22.4s,v23.4s
+	ror	w9,w9,#20
+	eor	v24.16b,v1.16b,v2.16b
+	add	w5,w5,w10
+	eor	v25.16b,v5.16b,v6.16b
+	add	w6,w6,w11
+	eor	v26.16b,v9.16b,v10.16b
+	add	w7,w7,w12
+	eor	v27.16b,v13.16b,v14.16b
+	add	w8,w8,w9
+	eor	v28.16b,v17.16b,v18.16b
+	eor	w21,w21,w5
+	eor	v29.16b,v21.16b,v22.16b
+	eor	w17,w17,w6
+	ushr	v1.4s,v24.4s,#25
+	eor	w19,w19,w7
+	ushr	v5.4s,v25.4s,#25
+	eor	w20,w20,w8
+	ushr	v9.4s,v26.4s,#25
+	ror	w21,w21,#24
+	ushr	v13.4s,v27.4s,#25
+	ror	w17,w17,#24
+	ushr	v17.4s,v28.4s,#25
+	ror	w19,w19,#24
+	ushr	v21.4s,v29.4s,#25
+	ror	w20,w20,#24
+	sli	v1.4s,v24.4s,#7
+	add	w15,w15,w21
+	sli	v5.4s,v25.4s,#7
+	add	w16,w16,w17
+	sli	v9.4s,v26.4s,#7
+	add	w13,w13,w19
+	sli	v13.4s,v27.4s,#7
+	add	w14,w14,w20
+	sli	v17.4s,v28.4s,#7
+	eor	w10,w10,w15
+	sli	v21.4s,v29.4s,#7
+	eor	w11,w11,w16
+	ext	v2.16b,v2.16b,v2.16b,#8
+	eor	w12,w12,w13
+	ext	v6.16b,v6.16b,v6.16b,#8
+	eor	w9,w9,w14
+	ext	v10.16b,v10.16b,v10.16b,#8
+	ror	w10,w10,#25
+	ext	v14.16b,v14.16b,v14.16b,#8
+	ror	w11,w11,#25
+	ext	v18.16b,v18.16b,v18.16b,#8
+	ror	w12,w12,#25
+	ext	v22.16b,v22.16b,v22.16b,#8
+	ror	w9,w9,#25
+	ext	v3.16b,v3.16b,v3.16b,#4
+	ext	v7.16b,v7.16b,v7.16b,#4
+	ext	v11.16b,v11.16b,v11.16b,#4
+	ext	v15.16b,v15.16b,v15.16b,#4
+	ext	v19.16b,v19.16b,v19.16b,#4
+	ext	v23.16b,v23.16b,v23.16b,#4
+	ext	v1.16b,v1.16b,v1.16b,#12
+	ext	v5.16b,v5.16b,v5.16b,#12
+	ext	v9.16b,v9.16b,v9.16b,#12
+	ext	v13.16b,v13.16b,v13.16b,#12
+	ext	v17.16b,v17.16b,v17.16b,#12
+	ext	v21.16b,v21.16b,v21.16b,#12
+	cbnz	x4,.Loop_lower_neon
+
+	add	w5,w5,w22		// accumulate key block
+	ldp	q24,q25,[sp,#0]
+	add	x6,x6,x22,lsr#32
+	ldp	q26,q27,[sp,#32]
+	add	w7,w7,w23
+	ldp	q28,q29,[sp,#64]
+	add	x8,x8,x23,lsr#32
+	add	v0.4s,v0.4s,v24.4s
+	add	w9,w9,w24
+	add	v4.4s,v4.4s,v24.4s
+	add	x10,x10,x24,lsr#32
+	add	v8.4s,v8.4s,v24.4s
+	add	w11,w11,w25
+	add	v12.4s,v12.4s,v24.4s
+	add	x12,x12,x25,lsr#32
+	add	v16.4s,v16.4s,v24.4s
+	add	w13,w13,w26
+	add	v20.4s,v20.4s,v24.4s
+	add	x14,x14,x26,lsr#32
+	add	v2.4s,v2.4s,v26.4s
+	add	w15,w15,w27
+	add	v6.4s,v6.4s,v26.4s
+	add	x16,x16,x27,lsr#32
+	add	v10.4s,v10.4s,v26.4s
+	add	w17,w17,w28
+	add	v14.4s,v14.4s,v26.4s
+	add	x19,x19,x28,lsr#32
+	add	v18.4s,v18.4s,v26.4s
+	add	w20,w20,w30
+	add	v22.4s,v22.4s,v26.4s
+	add	x21,x21,x30,lsr#32
+	add	v19.4s,v19.4s,v31.4s			// +4
+	add	x5,x5,x6,lsl#32	// pack
+	add	v23.4s,v23.4s,v31.4s			// +4
+	add	x7,x7,x8,lsl#32
+	add	v3.4s,v3.4s,v27.4s
+	ldp	x6,x8,[x1,#0]		// load input
+	add	v7.4s,v7.4s,v28.4s
+	add	x9,x9,x10,lsl#32
+	add	v11.4s,v11.4s,v29.4s
+	add	x11,x11,x12,lsl#32
+	add	v15.4s,v15.4s,v30.4s
+	ldp	x10,x12,[x1,#16]
+	add	v19.4s,v19.4s,v27.4s
+	add	x13,x13,x14,lsl#32
+	add	v23.4s,v23.4s,v28.4s
+	add	x15,x15,x16,lsl#32
+	add	v1.4s,v1.4s,v25.4s
+	ldp	x14,x16,[x1,#32]
+	add	v5.4s,v5.4s,v25.4s
+	add	x17,x17,x19,lsl#32
+	add	v9.4s,v9.4s,v25.4s
+	add	x20,x20,x21,lsl#32
+	add	v13.4s,v13.4s,v25.4s
+	ldp	x19,x21,[x1,#48]
+	add	v17.4s,v17.4s,v25.4s
+	add	x1,x1,#64
+	add	v21.4s,v21.4s,v25.4s
+
+#ifdef	__ARMEB__
+	rev	x5,x5
+	rev	x7,x7
+	rev	x9,x9
+	rev	x11,x11
+	rev	x13,x13
+	rev	x15,x15
+	rev	x17,x17
+	rev	x20,x20
+#endif
+	ld1	{v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64
+	eor	x5,x5,x6
+	eor	x7,x7,x8
+	eor	x9,x9,x10
+	eor	x11,x11,x12
+	eor	x13,x13,x14
+	eor	v0.16b,v0.16b,v24.16b
+	eor	x15,x15,x16
+	eor	v1.16b,v1.16b,v25.16b
+	eor	x17,x17,x19
+	eor	v2.16b,v2.16b,v26.16b
+	eor	x20,x20,x21
+	eor	v3.16b,v3.16b,v27.16b
+	ld1	{v24.16b,v25.16b,v26.16b,v27.16b},[x1],#64
+
+	stp	x5,x7,[x0,#0]		// store output
+	add	x28,x28,#7			// increment counter
+	stp	x9,x11,[x0,#16]
+	stp	x13,x15,[x0,#32]
+	stp	x17,x20,[x0,#48]
+	add	x0,x0,#64
+	st1	{v0.16b,v1.16b,v2.16b,v3.16b},[x0],#64
+
+	ld1	{v0.16b,v1.16b,v2.16b,v3.16b},[x1],#64
+	eor	v4.16b,v4.16b,v24.16b
+	eor	v5.16b,v5.16b,v25.16b
+	eor	v6.16b,v6.16b,v26.16b
+	eor	v7.16b,v7.16b,v27.16b
+	st1	{v4.16b,v5.16b,v6.16b,v7.16b},[x0],#64
+
+	ld1	{v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64
+	eor	v8.16b,v8.16b,v0.16b
+	ldp	q24,q25,[sp,#0]
+	eor	v9.16b,v9.16b,v1.16b
+	ldp	q26,q27,[sp,#32]
+	eor	v10.16b,v10.16b,v2.16b
+	eor	v11.16b,v11.16b,v3.16b
+	st1	{v8.16b,v9.16b,v10.16b,v11.16b},[x0],#64
+
+	ld1	{v8.16b,v9.16b,v10.16b,v11.16b},[x1],#64
+	eor	v12.16b,v12.16b,v4.16b
+	eor	v13.16b,v13.16b,v5.16b
+	eor	v14.16b,v14.16b,v6.16b
+	eor	v15.16b,v15.16b,v7.16b
+	st1	{v12.16b,v13.16b,v14.16b,v15.16b},[x0],#64
+
+	ld1	{v12.16b,v13.16b,v14.16b,v15.16b},[x1],#64
+	eor	v16.16b,v16.16b,v8.16b
+	eor	v17.16b,v17.16b,v9.16b
+	eor	v18.16b,v18.16b,v10.16b
+	eor	v19.16b,v19.16b,v11.16b
+	st1	{v16.16b,v17.16b,v18.16b,v19.16b},[x0],#64
+
+	shl	v0.4s,v31.4s,#1			// 4 -> 8
+	eor	v20.16b,v20.16b,v12.16b
+	eor	v21.16b,v21.16b,v13.16b
+	eor	v22.16b,v22.16b,v14.16b
+	eor	v23.16b,v23.16b,v15.16b
+	st1	{v20.16b,v21.16b,v22.16b,v23.16b},[x0],#64
+
+	add	v27.4s,v27.4s,v0.4s			// += 8
+	add	v28.4s,v28.4s,v0.4s
+	add	v29.4s,v29.4s,v0.4s
+	add	v30.4s,v30.4s,v0.4s
+
+	b.hs	.Loop_outer_512_neon
+
+	adds	x2,x2,#512
+	ushr	v0.4s,v31.4s,#2			// 4 -> 1
+
+	ldp	d8,d9,[sp,#128+0]		// meet ABI requirements
+	ldp	d10,d11,[sp,#128+16]
+	ldp	d12,d13,[sp,#128+32]
+	ldp	d14,d15,[sp,#128+48]
+
+	stp	q24,q31,[sp,#0]		// wipe off-load area
+	stp	q24,q31,[sp,#32]
+	stp	q24,q31,[sp,#64]
+
+	b.eq	.Ldone_512_neon
+
+	cmp	x2,#192
+	sub	v27.4s,v27.4s,v0.4s			// -= 1
+	sub	v28.4s,v28.4s,v0.4s
+	sub	v29.4s,v29.4s,v0.4s
+	add	sp,sp,#128
+	b.hs	.Loop_outer_neon
+
+	eor	v25.16b,v25.16b,v25.16b
+	eor	v26.16b,v26.16b,v26.16b
+	eor	v27.16b,v27.16b,v27.16b
+	eor	v28.16b,v28.16b,v28.16b
+	eor	v29.16b,v29.16b,v29.16b
+	eor	v30.16b,v30.16b,v30.16b
+	b	.Loop_outer
+
+.Ldone_512_neon:
+	ldp	x19,x20,[x29,#16]
+	add	sp,sp,#128+64
+	ldp	x21,x22,[x29,#32]
+	ldp	x23,x24,[x29,#48]
+	ldp	x25,x26,[x29,#64]
+	ldp	x27,x28,[x29,#80]
+	ldp	x29,x30,[sp],#96
+	ret
+.size	ChaCha20_512_neon,.-ChaCha20_512_neon
+#endif
diff --git a/third_party/boringssl/linux-aarch64/crypto/modes/ghashv8-armx64.S b/third_party/boringssl/linux-aarch64/crypto/modes/ghashv8-armx64.S
index a0a9b680..f39f3ba 100644
--- a/third_party/boringssl/linux-aarch64/crypto/modes/ghashv8-armx64.S
+++ b/third_party/boringssl/linux-aarch64/crypto/modes/ghashv8-armx64.S
@@ -1,11 +1,12 @@
 #if defined(__aarch64__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 #if !defined(__clang__)
 .arch	armv8-a+crypto
 #endif
 .globl	gcm_init_v8
+.hidden	gcm_init_v8
 .type	gcm_init_v8,%function
 .align	4
 gcm_init_v8:
@@ -56,6 +57,7 @@
 	ret
 .size	gcm_init_v8,.-gcm_init_v8
 .globl	gcm_gmult_v8
+.hidden	gcm_gmult_v8
 .type	gcm_gmult_v8,%function
 .align	4
 gcm_gmult_v8:
@@ -68,10 +70,10 @@
 #endif
 	ext	v3.16b,v17.16b,v17.16b,#8
 
-	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
+	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
 	eor	v17.16b,v17.16b,v3.16b		//Karatsuba pre-processing
-	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
-	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
+	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
+	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	ext	v17.16b,v0.16b,v2.16b,#8		//Karatsuba post-processing
 	eor	v18.16b,v0.16b,v2.16b
@@ -97,6 +99,7 @@
 	ret
 .size	gcm_gmult_v8,.-gcm_gmult_v8
 .globl	gcm_ghash_v8
+.hidden	gcm_ghash_v8
 .type	gcm_ghash_v8,%function
 .align	4
 gcm_ghash_v8:
@@ -135,7 +138,7 @@
 #endif
 	ext	v7.16b,v17.16b,v17.16b,#8
 	eor	v3.16b,v3.16b,v0.16b		//I[i]^=Xi
-	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
+	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
 	eor	v17.16b,v17.16b,v7.16b		//Karatsuba pre-processing
 	pmull2	v6.1q,v20.2d,v7.2d
 	b	.Loop_mod2x_v8
@@ -144,14 +147,14 @@
 .Loop_mod2x_v8:
 	ext	v18.16b,v3.16b,v3.16b,#8
 	subs	x3,x3,#32		//is there more data?
-	pmull	v0.1q,v22.1d,v3.1d		//H^2.lo·Xi.lo
+	pmull	v0.1q,v22.1d,v3.1d		//H^2.lo·Xi.lo
 	csel	x12,xzr,x12,lo			//is it time to zero x12?
 
 	pmull	v5.1q,v21.1d,v17.1d
 	eor	v18.16b,v18.16b,v3.16b		//Karatsuba pre-processing
-	pmull2	v2.1q,v22.2d,v3.2d		//H^2.hi·Xi.hi
+	pmull2	v2.1q,v22.2d,v3.2d		//H^2.hi·Xi.hi
 	eor	v0.16b,v0.16b,v4.16b		//accumulate
-	pmull2	v1.1q,v21.2d,v18.2d		//(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+	pmull2	v1.1q,v21.2d,v18.2d		//(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
 	ld1	{v16.2d},[x2],x12	//load [rotated] I[i+2]
 
 	eor	v2.16b,v2.16b,v6.16b
@@ -176,7 +179,7 @@
 	ext	v7.16b,v17.16b,v17.16b,#8
 	ext	v3.16b,v16.16b,v16.16b,#8
 	eor	v0.16b,v1.16b,v18.16b
-	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
+	pmull	v4.1q,v20.1d,v7.1d		//H·Ii+1
 	eor	v3.16b,v3.16b,v2.16b		//accumulate v3.16b early
 
 	ext	v18.16b,v0.16b,v0.16b,#8		//2nd phase of reduction
@@ -197,10 +200,10 @@
 	eor	v3.16b,v3.16b,v0.16b		//inp^=Xi
 	eor	v17.16b,v16.16b,v18.16b		//v17.16b is rotated inp^Xi
 
-	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
+	pmull	v0.1q,v20.1d,v3.1d		//H.lo·Xi.lo
 	eor	v17.16b,v17.16b,v3.16b		//Karatsuba pre-processing
-	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
-	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
+	pmull2	v2.1q,v20.2d,v3.2d		//H.hi·Xi.hi
+	pmull	v1.1q,v21.1d,v17.1d		//(H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	ext	v17.16b,v0.16b,v2.16b,#8		//Karatsuba post-processing
 	eor	v18.16b,v0.16b,v2.16b
@@ -229,4 +232,4 @@
 .byte	71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 .align	2
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-aarch64/crypto/sha/sha1-armv8.S b/third_party/boringssl/linux-aarch64/crypto/sha/sha1-armv8.S
index 487a497..cfb4aa02 100644
--- a/third_party/boringssl/linux-aarch64/crypto/sha/sha1-armv8.S
+++ b/third_party/boringssl/linux-aarch64/crypto/sha/sha1-armv8.S
@@ -1,10 +1,11 @@
 #if defined(__aarch64__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 
 
 .globl	sha1_block_data_order
+.hidden	sha1_block_data_order
 .type	sha1_block_data_order,%function
 .align	6
 sha1_block_data_order:
@@ -1212,4 +1213,4 @@
 .align	2
 .align	2
 .comm	OPENSSL_armcap_P,4,4
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-aarch64/crypto/sha/sha256-armv8.S b/third_party/boringssl/linux-aarch64/crypto/sha/sha256-armv8.S
index 4834553..bfc552c 100644
--- a/third_party/boringssl/linux-aarch64/crypto/sha/sha256-armv8.S
+++ b/third_party/boringssl/linux-aarch64/crypto/sha/sha256-armv8.S
@@ -1,10 +1,11 @@
 #if defined(__aarch64__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 
 
 .globl	sha256_block_data_order
+.hidden	sha256_block_data_order
 .type	sha256_block_data_order,%function
 .align	6
 sha256_block_data_order:
@@ -1142,4 +1143,4 @@
 	ret
 .size	sha256_block_armv8,.-sha256_block_armv8
 .comm	OPENSSL_armcap_P,4,4
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-aarch64/crypto/sha/sha512-armv8.S b/third_party/boringssl/linux-aarch64/crypto/sha/sha512-armv8.S
index 654c473..4645722 100644
--- a/third_party/boringssl/linux-aarch64/crypto/sha/sha512-armv8.S
+++ b/third_party/boringssl/linux-aarch64/crypto/sha/sha512-armv8.S
@@ -1,10 +1,11 @@
 #if defined(__aarch64__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 
 
 .globl	sha512_block_data_order
+.hidden	sha512_block_data_order
 .type	sha512_block_data_order,%function
 .align	6
 sha512_block_data_order:
@@ -1022,4 +1023,4 @@
 .align	2
 .align	2
 .comm	OPENSSL_armcap_P,4,4
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/aes/aes-armv4.S b/third_party/boringssl/linux-arm/crypto/aes/aes-armv4.S
index cb94841..bc11e3f 100644
--- a/third_party/boringssl/linux-arm/crypto/aes/aes-armv4.S
+++ b/third_party/boringssl/linux-arm/crypto/aes/aes-armv4.S
@@ -34,7 +34,7 @@
 
 #if defined(__arm__)
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 #else
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 #endif
@@ -1197,4 +1197,4 @@
 .align	2
 
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/aes/aesv8-armx32.S b/third_party/boringssl/linux-arm/crypto/aes/aesv8-armx32.S
index 6f0ee7d..95a2ea4 100644
--- a/third_party/boringssl/linux-arm/crypto/aes/aesv8-armx32.S
+++ b/third_party/boringssl/linux-arm/crypto/aes/aesv8-armx32.S
@@ -1,5 +1,5 @@
 #if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 #if __ARM_MAX_ARCH__>=7
 .text
@@ -13,6 +13,7 @@
 .long	0x1b,0x1b,0x1b,0x1b
 
 .globl	aes_v8_set_encrypt_key
+.hidden	aes_v8_set_encrypt_key
 .type	aes_v8_set_encrypt_key,%function
 .align	5
 aes_v8_set_encrypt_key:
@@ -183,6 +184,7 @@
 .size	aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
 
 .globl	aes_v8_set_decrypt_key
+.hidden	aes_v8_set_decrypt_key
 .type	aes_v8_set_decrypt_key,%function
 .align	5
 aes_v8_set_decrypt_key:
@@ -220,6 +222,7 @@
 	ldmia	sp!,{r4,pc}
 .size	aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
 .globl	aes_v8_encrypt
+.hidden	aes_v8_encrypt
 .type	aes_v8_encrypt,%function
 .align	5
 aes_v8_encrypt:
@@ -249,6 +252,7 @@
 	bx	lr
 .size	aes_v8_encrypt,.-aes_v8_encrypt
 .globl	aes_v8_decrypt
+.hidden	aes_v8_decrypt
 .type	aes_v8_decrypt,%function
 .align	5
 aes_v8_decrypt:
@@ -278,6 +282,7 @@
 	bx	lr
 .size	aes_v8_decrypt,.-aes_v8_decrypt
 .globl	aes_v8_cbc_encrypt
+.hidden	aes_v8_cbc_encrypt
 .type	aes_v8_cbc_encrypt,%function
 .align	5
 aes_v8_cbc_encrypt:
@@ -570,6 +575,7 @@
 	ldmia	sp!,{r4,r5,r6,r7,r8,pc}
 .size	aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
 .globl	aes_v8_ctr32_encrypt_blocks
+.hidden	aes_v8_ctr32_encrypt_blocks
 .type	aes_v8_ctr32_encrypt_blocks,%function
 .align	5
 aes_v8_ctr32_encrypt_blocks:
@@ -753,4 +759,4 @@
 	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,pc}
 .size	aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/aes/bsaes-armv7.S b/third_party/boringssl/linux-arm/crypto/aes/bsaes-armv7.S
index dd84f35..abb414d 100644
--- a/third_party/boringssl/linux-arm/crypto/aes/bsaes-armv7.S
+++ b/third_party/boringssl/linux-arm/crypto/aes/bsaes-armv7.S
@@ -47,9 +47,8 @@
 @
 @					<ard.biesheuvel@linaro.org>
 
-#if defined(__arm__)
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 
 # define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
 # define VFP_ABI_POP	vldmia	sp!,{d8-d15}
@@ -2576,4 +2575,3 @@
 .size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
 #endif
 #endif
-#endif
\ No newline at end of file
diff --git a/third_party/boringssl/linux-arm/crypto/bn/armv4-mont.S b/third_party/boringssl/linux-arm/crypto/bn/armv4-mont.S
index 68dfb2c..e59599f 100644
--- a/third_party/boringssl/linux-arm/crypto/bn/armv4-mont.S
+++ b/third_party/boringssl/linux-arm/crypto/bn/armv4-mont.S
@@ -1,5 +1,5 @@
 #if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 .code	32
@@ -28,7 +28,7 @@
 #ifdef	__APPLE__
 	ldr	r0,[r0]
 #endif
-	tst	r0,#1			@ NEON available?
+	tst	r0,#ARMV7_NEON		@ NEON available?
 	ldmia	sp, {r0,r2}
 	beq	.Lialu
 	add	sp,sp,#8
@@ -586,4 +586,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/chacha/chacha-armv4.S b/third_party/boringssl/linux-arm/crypto/chacha/chacha-armv4.S
new file mode 100644
index 0000000..19a4d2c
--- /dev/null
+++ b/third_party/boringssl/linux-arm/crypto/chacha/chacha-armv4.S
@@ -0,0 +1,1471 @@
+#if defined(__arm__)
+#include <openssl/arm_arch.h>
+
+.text
+#if defined(__thumb2__)
+.syntax	unified
+.thumb
+#else
+.code	32
+#endif
+
+#if defined(__thumb2__) || defined(__clang__)
+#define ldrhsb	ldrbhs
+#endif
+
+.align	5
+.Lsigma:
+.long	0x61707865,0x3320646e,0x79622d32,0x6b206574	@ endian-neutral
+.Lone:
+.long	1,0,0,0
+#if __ARM_MAX_ARCH__>=7
+.LOPENSSL_armcap:
+.word	OPENSSL_armcap_P-.LChaCha20_ctr32
+#else
+.word	-1
+#endif
+
+.globl	ChaCha20_ctr32
+.hidden	ChaCha20_ctr32
+.type	ChaCha20_ctr32,%function
+.align	5
+ChaCha20_ctr32:
+.LChaCha20_ctr32:
+	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
+	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
+#if __ARM_ARCH__<7 && !defined(__thumb2__)
+	sub	r14,pc,#16		@ ChaCha20_ctr32
+#else
+	adr	r14,.LChaCha20_ctr32
+#endif
+	cmp	r2,#0			@ len==0?
+#ifdef	__thumb2__
+	itt	eq
+#endif
+	addeq	sp,sp,#4*3
+	beq	.Lno_data
+#if __ARM_MAX_ARCH__>=7
+	cmp	r2,#192			@ test len
+	bls	.Lshort
+	ldr	r4,[r14,#-32]
+	ldr	r4,[r14,r4]
+# ifdef	__APPLE__
+	ldr	r4,[r4]
+# endif
+	tst	r4,#ARMV7_NEON
+	bne	.LChaCha20_neon
+.Lshort:
+#endif
+	ldmia	r12,{r4,r5,r6,r7}		@ load counter and nonce
+	sub	sp,sp,#4*(16)		@ off-load area
+	sub	r14,r14,#64		@ .Lsigma
+	stmdb	sp!,{r4,r5,r6,r7}		@ copy counter and nonce
+	ldmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}		@ load key
+	ldmia	r14,{r0,r1,r2,r3}		@ load sigma
+	stmdb	sp!,{r4,r5,r6,r7,r8,r9,r10,r11}		@ copy key
+	stmdb	sp!,{r0,r1,r2,r3}		@ copy sigma
+	str	r10,[sp,#4*(16+10)]	@ off-load "rx"
+	str	r11,[sp,#4*(16+11)]	@ off-load "rx"
+	b	.Loop_outer_enter
+
+.align	4
+.Loop_outer:
+	ldmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9}		@ load key material
+	str	r11,[sp,#4*(32+2)]	@ save len
+	str	r12,  [sp,#4*(32+1)]	@ save inp
+	str	r14,  [sp,#4*(32+0)]	@ save out
+.Loop_outer_enter:
+	ldr	r11, [sp,#4*(15)]
+	ldr	r12,[sp,#4*(12)]	@ modulo-scheduled load
+	ldr	r10, [sp,#4*(13)]
+	ldr	r14,[sp,#4*(14)]
+	str	r11, [sp,#4*(16+15)]
+	mov	r11,#10
+	b	.Loop
+
+.align	4
+.Loop:
+	subs	r11,r11,#1
+	add	r0,r0,r4
+	mov	r12,r12,ror#16
+	add	r1,r1,r5
+	mov	r10,r10,ror#16
+	eor	r12,r12,r0,ror#16
+	eor	r10,r10,r1,ror#16
+	add	r8,r8,r12
+	mov	r4,r4,ror#20
+	add	r9,r9,r10
+	mov	r5,r5,ror#20
+	eor	r4,r4,r8,ror#20
+	eor	r5,r5,r9,ror#20
+	add	r0,r0,r4
+	mov	r12,r12,ror#24
+	add	r1,r1,r5
+	mov	r10,r10,ror#24
+	eor	r12,r12,r0,ror#24
+	eor	r10,r10,r1,ror#24
+	add	r8,r8,r12
+	mov	r4,r4,ror#25
+	add	r9,r9,r10
+	mov	r5,r5,ror#25
+	str	r10,[sp,#4*(16+13)]
+	ldr	r10,[sp,#4*(16+15)]
+	eor	r4,r4,r8,ror#25
+	eor	r5,r5,r9,ror#25
+	str	r8,[sp,#4*(16+8)]
+	ldr	r8,[sp,#4*(16+10)]
+	add	r2,r2,r6
+	mov	r14,r14,ror#16
+	str	r9,[sp,#4*(16+9)]
+	ldr	r9,[sp,#4*(16+11)]
+	add	r3,r3,r7
+	mov	r10,r10,ror#16
+	eor	r14,r14,r2,ror#16
+	eor	r10,r10,r3,ror#16
+	add	r8,r8,r14
+	mov	r6,r6,ror#20
+	add	r9,r9,r10
+	mov	r7,r7,ror#20
+	eor	r6,r6,r8,ror#20
+	eor	r7,r7,r9,ror#20
+	add	r2,r2,r6
+	mov	r14,r14,ror#24
+	add	r3,r3,r7
+	mov	r10,r10,ror#24
+	eor	r14,r14,r2,ror#24
+	eor	r10,r10,r3,ror#24
+	add	r8,r8,r14
+	mov	r6,r6,ror#25
+	add	r9,r9,r10
+	mov	r7,r7,ror#25
+	eor	r6,r6,r8,ror#25
+	eor	r7,r7,r9,ror#25
+	add	r0,r0,r5
+	mov	r10,r10,ror#16
+	add	r1,r1,r6
+	mov	r12,r12,ror#16
+	eor	r10,r10,r0,ror#16
+	eor	r12,r12,r1,ror#16
+	add	r8,r8,r10
+	mov	r5,r5,ror#20
+	add	r9,r9,r12
+	mov	r6,r6,ror#20
+	eor	r5,r5,r8,ror#20
+	eor	r6,r6,r9,ror#20
+	add	r0,r0,r5
+	mov	r10,r10,ror#24
+	add	r1,r1,r6
+	mov	r12,r12,ror#24
+	eor	r10,r10,r0,ror#24
+	eor	r12,r12,r1,ror#24
+	add	r8,r8,r10
+	mov	r5,r5,ror#25
+	str	r10,[sp,#4*(16+15)]
+	ldr	r10,[sp,#4*(16+13)]
+	add	r9,r9,r12
+	mov	r6,r6,ror#25
+	eor	r5,r5,r8,ror#25
+	eor	r6,r6,r9,ror#25
+	str	r8,[sp,#4*(16+10)]
+	ldr	r8,[sp,#4*(16+8)]
+	add	r2,r2,r7
+	mov	r10,r10,ror#16
+	str	r9,[sp,#4*(16+11)]
+	ldr	r9,[sp,#4*(16+9)]
+	add	r3,r3,r4
+	mov	r14,r14,ror#16
+	eor	r10,r10,r2,ror#16
+	eor	r14,r14,r3,ror#16
+	add	r8,r8,r10
+	mov	r7,r7,ror#20
+	add	r9,r9,r14
+	mov	r4,r4,ror#20
+	eor	r7,r7,r8,ror#20
+	eor	r4,r4,r9,ror#20
+	add	r2,r2,r7
+	mov	r10,r10,ror#24
+	add	r3,r3,r4
+	mov	r14,r14,ror#24
+	eor	r10,r10,r2,ror#24
+	eor	r14,r14,r3,ror#24
+	add	r8,r8,r10
+	mov	r7,r7,ror#25
+	add	r9,r9,r14
+	mov	r4,r4,ror#25
+	eor	r7,r7,r8,ror#25
+	eor	r4,r4,r9,ror#25
+	bne	.Loop
+
+	ldr	r11,[sp,#4*(32+2)]	@ load len
+
+	str	r8, [sp,#4*(16+8)]	@ modulo-scheduled store
+	str	r9, [sp,#4*(16+9)]
+	str	r12,[sp,#4*(16+12)]
+	str	r10, [sp,#4*(16+13)]
+	str	r14,[sp,#4*(16+14)]
+
+	@ at this point we have first half of 512-bit result in
+	@ rx and second half at sp+4*(16+8)
+
+	cmp	r11,#64		@ done yet?
+#ifdef	__thumb2__
+	itete	lo
+#endif
+	addlo	r12,sp,#4*(0)		@ shortcut or ...
+	ldrhs	r12,[sp,#4*(32+1)]	@ ... load inp
+	addlo	r14,sp,#4*(0)		@ shortcut or ...
+	ldrhs	r14,[sp,#4*(32+0)]	@ ... load out
+
+	ldr	r8,[sp,#4*(0)]	@ load key material
+	ldr	r9,[sp,#4*(1)]
+
+#if __ARM_ARCH__>=6 || !defined(__ARMEB__)
+# if __ARM_ARCH__<7
+	orr	r10,r12,r14
+	tst	r10,#3		@ are input and output aligned?
+	ldr	r10,[sp,#4*(2)]
+	bne	.Lunaligned
+	cmp	r11,#64		@ restore flags
+# else
+	ldr	r10,[sp,#4*(2)]
+# endif
+	ldr	r11,[sp,#4*(3)]
+
+	add	r0,r0,r8	@ accumulate key material
+	add	r1,r1,r9
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+
+	add	r2,r2,r10
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r0,r0,r8	@ xor with input
+	eorhs	r1,r1,r9
+	add	r8,sp,#4*(4)
+	str	r0,[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r2,r2,r10
+	eorhs	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r1,[r14,#-12]
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r5,r5,r9
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+	add	r6,r6,r10
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r4,r4,r8
+	eorhs	r5,r5,r9
+	add	r8,sp,#4*(8)
+	str	r4,[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r6,r6,r10
+	eorhs	r7,r7,r11
+	str	r5,[r14,#-12]
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r6,[r14,#-8]
+	add	r0,sp,#4*(16+8)
+	str	r7,[r14,#-4]
+
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
+
+	add	r0,r0,r8	@ accumulate key material
+	add	r1,r1,r9
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	strhi	r10,[sp,#4*(16+10)]	@ copy "rx" while at it
+	strhi	r11,[sp,#4*(16+11)]	@ copy "rx" while at it
+	add	r2,r2,r10
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r0,r0,r8
+	eorhs	r1,r1,r9
+	add	r8,sp,#4*(12)
+	str	r0,[r14],#16		@ store output
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r2,r2,r10
+	eorhs	r3,r3,r11
+	str	r1,[r14,#-12]
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r5,r5,r9
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	addhi	r8,r8,#1		@ next counter value
+	strhi	r8,[sp,#4*(12)]	@ save next counter value
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r8,[r12],#16		@ load input
+	ldrhs	r9,[r12,#-12]
+	add	r6,r6,r10
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhs	r10,[r12,#-8]
+	ldrhs	r11,[r12,#-4]
+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r4,r4,r8
+	eorhs	r5,r5,r9
+# ifdef	__thumb2__
+	it	ne
+# endif
+	ldrne	r8,[sp,#4*(32+2)]	@ re-load len
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	eorhs	r6,r6,r10
+	eorhs	r7,r7,r11
+	str	r4,[r14],#16		@ store output
+	str	r5,[r14,#-12]
+# ifdef	__thumb2__
+	it	hs
+# endif
+	subhs	r11,r8,#64		@ len-=64
+	str	r6,[r14,#-8]
+	str	r7,[r14,#-4]
+	bhi	.Loop_outer
+
+	beq	.Ldone
+# if __ARM_ARCH__<7
+	b	.Ltail
+
+.align	4
+.Lunaligned:@ unaligned endian-neutral path
+	cmp	r11,#64		@ restore flags
+# endif
+#endif
+#if __ARM_ARCH__<7
+	ldr	r11,[sp,#4*(3)]
+	add	r0,r0,r8		@ accumulate key material
+	add	r1,r1,r9
+	add	r2,r2,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r0,r8,r0		@ xor with input (or zero)
+	eor	r1,r9,r1
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r2,r10,r2
+	strb	r0,[r14],#16		@ store output
+	eor	r3,r11,r3
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r1,[r14,#-12]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-8]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r3,[r14,#-4]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-15]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r1,[r14,#-11]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-7]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r3,[r14,#-3]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-14]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r1,[r14,#-10]
+	strb	r2,[r14,#-6]
+	eor	r0,r8,r0,lsr#8
+	strb	r3,[r14,#-2]
+	eor	r1,r9,r1,lsr#8
+	strb	r0,[r14,#-13]
+	eor	r2,r10,r2,lsr#8
+	strb	r1,[r14,#-9]
+	eor	r3,r11,r3,lsr#8
+	strb	r2,[r14,#-5]
+	strb	r3,[r14,#-1]
+	add	r8,sp,#4*(4+0)
+	ldmia	r8,{r8,r9,r10,r11}		@ load key material
+	add	r0,sp,#4*(16+8)
+	add	r4,r4,r8		@ accumulate key material
+	add	r5,r5,r9
+	add	r6,r6,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r4,r8,r4		@ xor with input (or zero)
+	eor	r5,r9,r5
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r6,r10,r6
+	strb	r4,[r14],#16		@ store output
+	eor	r7,r11,r7
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r5,[r14,#-12]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-8]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r7,[r14,#-4]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-15]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r5,[r14,#-11]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-7]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r7,[r14,#-3]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-14]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r5,[r14,#-10]
+	strb	r6,[r14,#-6]
+	eor	r4,r8,r4,lsr#8
+	strb	r7,[r14,#-2]
+	eor	r5,r9,r5,lsr#8
+	strb	r4,[r14,#-13]
+	eor	r6,r10,r6,lsr#8
+	strb	r5,[r14,#-9]
+	eor	r7,r11,r7,lsr#8
+	strb	r6,[r14,#-5]
+	strb	r7,[r14,#-1]
+	add	r8,sp,#4*(4+4)
+	ldmia	r8,{r8,r9,r10,r11}		@ load key material
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}		@ load second half
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	strhi	r10,[sp,#4*(16+10)]		@ copy "rx"
+	strhi	r11,[sp,#4*(16+11)]		@ copy "rx"
+	add	r0,r0,r8		@ accumulate key material
+	add	r1,r1,r9
+	add	r2,r2,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r3,r3,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r0,r8,r0		@ xor with input (or zero)
+	eor	r1,r9,r1
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r2,r10,r2
+	strb	r0,[r14],#16		@ store output
+	eor	r3,r11,r3
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r1,[r14,#-12]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-8]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r3,[r14,#-4]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-15]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r1,[r14,#-11]
+	eor	r0,r8,r0,lsr#8
+	strb	r2,[r14,#-7]
+	eor	r1,r9,r1,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r3,[r14,#-3]
+	eor	r2,r10,r2,lsr#8
+	strb	r0,[r14,#-14]
+	eor	r3,r11,r3,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r1,[r14,#-10]
+	strb	r2,[r14,#-6]
+	eor	r0,r8,r0,lsr#8
+	strb	r3,[r14,#-2]
+	eor	r1,r9,r1,lsr#8
+	strb	r0,[r14,#-13]
+	eor	r2,r10,r2,lsr#8
+	strb	r1,[r14,#-9]
+	eor	r3,r11,r3,lsr#8
+	strb	r2,[r14,#-5]
+	strb	r3,[r14,#-1]
+	add	r8,sp,#4*(4+8)
+	ldmia	r8,{r8,r9,r10,r11}		@ load key material
+	add	r4,r4,r8		@ accumulate key material
+# ifdef	__thumb2__
+	itt	hi
+# endif
+	addhi	r8,r8,#1			@ next counter value
+	strhi	r8,[sp,#4*(12)]		@ save next counter value
+	add	r5,r5,r9
+	add	r6,r6,r10
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r8,r8,r8		@ zero or ...
+	ldrhsb	r8,[r12],#16			@ ... load input
+	eorlo	r9,r9,r9
+	ldrhsb	r9,[r12,#-12]
+
+	add	r7,r7,r11
+# ifdef	__thumb2__
+	itete	lo
+# endif
+	eorlo	r10,r10,r10
+	ldrhsb	r10,[r12,#-8]
+	eorlo	r11,r11,r11
+	ldrhsb	r11,[r12,#-4]
+
+	eor	r4,r8,r4		@ xor with input (or zero)
+	eor	r5,r9,r5
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-15]		@ load more input
+	ldrhsb	r9,[r12,#-11]
+	eor	r6,r10,r6
+	strb	r4,[r14],#16		@ store output
+	eor	r7,r11,r7
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-7]
+	ldrhsb	r11,[r12,#-3]
+	strb	r5,[r14,#-12]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-8]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-14]		@ load more input
+	ldrhsb	r9,[r12,#-10]
+	strb	r7,[r14,#-4]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-15]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-6]
+	ldrhsb	r11,[r12,#-2]
+	strb	r5,[r14,#-11]
+	eor	r4,r8,r4,lsr#8
+	strb	r6,[r14,#-7]
+	eor	r5,r9,r5,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r8,[r12,#-13]		@ load more input
+	ldrhsb	r9,[r12,#-9]
+	strb	r7,[r14,#-3]
+	eor	r6,r10,r6,lsr#8
+	strb	r4,[r14,#-14]
+	eor	r7,r11,r7,lsr#8
+# ifdef	__thumb2__
+	itt	hs
+# endif
+	ldrhsb	r10,[r12,#-5]
+	ldrhsb	r11,[r12,#-1]
+	strb	r5,[r14,#-10]
+	strb	r6,[r14,#-6]
+	eor	r4,r8,r4,lsr#8
+	strb	r7,[r14,#-2]
+	eor	r5,r9,r5,lsr#8
+	strb	r4,[r14,#-13]
+	eor	r6,r10,r6,lsr#8
+	strb	r5,[r14,#-9]
+	eor	r7,r11,r7,lsr#8
+	strb	r6,[r14,#-5]
+	strb	r7,[r14,#-1]
+# ifdef	__thumb2__
+	it	ne
+# endif
+	ldrne	r8,[sp,#4*(32+2)]		@ re-load len
+# ifdef	__thumb2__
+	it	hs
+# endif
+	subhs	r11,r8,#64			@ len-=64
+	bhi	.Loop_outer
+
+	beq	.Ldone
+#endif
+
+.Ltail:
+	ldr	r12,[sp,#4*(32+1)]	@ load inp
+	add	r9,sp,#4*(0)
+	ldr	r14,[sp,#4*(32+0)]	@ load out
+
+.Loop_tail:
+	ldrb	r10,[r9],#1	@ read buffer on stack
+	ldrb	r11,[r12],#1		@ read input
+	subs	r8,r8,#1
+	eor	r11,r11,r10
+	strb	r11,[r14],#1		@ store output
+	bne	.Loop_tail
+
+.Ldone:
+	add	sp,sp,#4*(32+3)
+.Lno_data:
+	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+#if __ARM_MAX_ARCH__>=7
+.arch	armv7-a
+.fpu	neon
+
+.type	ChaCha20_neon,%function
+.align	5
+ChaCha20_neon:
+	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
+	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
+.LChaCha20_neon:
+	adr	r14,.Lsigma
+	vstmdb	sp!,{d8,d9,d10,d11,d12,d13,d14,d15}		@ ABI spec says so
+	stmdb	sp!,{r0,r1,r2,r3}
+
+	vld1.32	{q1,q2},[r3]		@ load key
+	ldmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}		@ load key
+
+	sub	sp,sp,#4*(16+16)
+	vld1.32	{q3},[r12]		@ load counter and nonce
+	add	r12,sp,#4*8
+	ldmia	r14,{r0,r1,r2,r3}		@ load sigma
+	vld1.32	{q0},[r14]!		@ load sigma
+	vld1.32	{q12},[r14]		@ one
+	vst1.32	{q2,q3},[r12]		@ copy 1/2key|counter|nonce
+	vst1.32	{q0,q1},[sp]		@ copy sigma|1/2key
+
+	str	r10,[sp,#4*(16+10)]	@ off-load "rx"
+	str	r11,[sp,#4*(16+11)]	@ off-load "rx"
+	vshl.i32	d26,d24,#1	@ two
+	vstr	d24,[sp,#4*(16+0)]
+	vshl.i32	d28,d24,#2	@ four
+	vstr	d26,[sp,#4*(16+2)]
+	vmov	q4,q0
+	vstr	d28,[sp,#4*(16+4)]
+	vmov	q8,q0
+	vmov	q5,q1
+	vmov	q9,q1
+	b	.Loop_neon_enter
+
+.align	4
+.Loop_neon_outer:
+	ldmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9}		@ load key material
+	cmp	r11,#64*2		@ if len<=64*2
+	bls	.Lbreak_neon		@ switch to integer-only
+	vmov	q4,q0
+	str	r11,[sp,#4*(32+2)]	@ save len
+	vmov	q8,q0
+	str	r12,  [sp,#4*(32+1)]	@ save inp
+	vmov	q5,q1
+	str	r14,  [sp,#4*(32+0)]	@ save out
+	vmov	q9,q1
+.Loop_neon_enter:
+	ldr	r11, [sp,#4*(15)]
+	vadd.i32	q7,q3,q12		@ counter+1
+	ldr	r12,[sp,#4*(12)]	@ modulo-scheduled load
+	vmov	q6,q2
+	ldr	r10, [sp,#4*(13)]
+	vmov	q10,q2
+	ldr	r14,[sp,#4*(14)]
+	vadd.i32	q11,q7,q12		@ counter+2
+	str	r11, [sp,#4*(16+15)]
+	mov	r11,#10
+	add	r12,r12,#3	@ counter+3
+	b	.Loop_neon
+
+.align	4
+.Loop_neon:
+	subs	r11,r11,#1
+	vadd.i32	q0,q0,q1
+	add	r0,r0,r4
+	vadd.i32	q4,q4,q5
+	mov	r12,r12,ror#16
+	vadd.i32	q8,q8,q9
+	add	r1,r1,r5
+	veor	q3,q3,q0
+	mov	r10,r10,ror#16
+	veor	q7,q7,q4
+	eor	r12,r12,r0,ror#16
+	veor	q11,q11,q8
+	eor	r10,r10,r1,ror#16
+	vrev32.16	q3,q3
+	add	r8,r8,r12
+	vrev32.16	q7,q7
+	mov	r4,r4,ror#20
+	vrev32.16	q11,q11
+	add	r9,r9,r10
+	vadd.i32	q2,q2,q3
+	mov	r5,r5,ror#20
+	vadd.i32	q6,q6,q7
+	eor	r4,r4,r8,ror#20
+	vadd.i32	q10,q10,q11
+	eor	r5,r5,r9,ror#20
+	veor	q12,q1,q2
+	add	r0,r0,r4
+	veor	q13,q5,q6
+	mov	r12,r12,ror#24
+	veor	q14,q9,q10
+	add	r1,r1,r5
+	vshr.u32	q1,q12,#20
+	mov	r10,r10,ror#24
+	vshr.u32	q5,q13,#20
+	eor	r12,r12,r0,ror#24
+	vshr.u32	q9,q14,#20
+	eor	r10,r10,r1,ror#24
+	vsli.32	q1,q12,#12
+	add	r8,r8,r12
+	vsli.32	q5,q13,#12
+	mov	r4,r4,ror#25
+	vsli.32	q9,q14,#12
+	add	r9,r9,r10
+	vadd.i32	q0,q0,q1
+	mov	r5,r5,ror#25
+	vadd.i32	q4,q4,q5
+	str	r10,[sp,#4*(16+13)]
+	vadd.i32	q8,q8,q9
+	ldr	r10,[sp,#4*(16+15)]
+	veor	q12,q3,q0
+	eor	r4,r4,r8,ror#25
+	veor	q13,q7,q4
+	eor	r5,r5,r9,ror#25
+	veor	q14,q11,q8
+	str	r8,[sp,#4*(16+8)]
+	vshr.u32	q3,q12,#24
+	ldr	r8,[sp,#4*(16+10)]
+	vshr.u32	q7,q13,#24
+	add	r2,r2,r6
+	vshr.u32	q11,q14,#24
+	mov	r14,r14,ror#16
+	vsli.32	q3,q12,#8
+	str	r9,[sp,#4*(16+9)]
+	vsli.32	q7,q13,#8
+	ldr	r9,[sp,#4*(16+11)]
+	vsli.32	q11,q14,#8
+	add	r3,r3,r7
+	vadd.i32	q2,q2,q3
+	mov	r10,r10,ror#16
+	vadd.i32	q6,q6,q7
+	eor	r14,r14,r2,ror#16
+	vadd.i32	q10,q10,q11
+	eor	r10,r10,r3,ror#16
+	veor	q12,q1,q2
+	add	r8,r8,r14
+	veor	q13,q5,q6
+	mov	r6,r6,ror#20
+	veor	q14,q9,q10
+	add	r9,r9,r10
+	vshr.u32	q1,q12,#25
+	mov	r7,r7,ror#20
+	vshr.u32	q5,q13,#25
+	eor	r6,r6,r8,ror#20
+	vshr.u32	q9,q14,#25
+	eor	r7,r7,r9,ror#20
+	vsli.32	q1,q12,#7
+	add	r2,r2,r6
+	vsli.32	q5,q13,#7
+	mov	r14,r14,ror#24
+	vsli.32	q9,q14,#7
+	add	r3,r3,r7
+	vext.8	q2,q2,q2,#8
+	mov	r10,r10,ror#24
+	vext.8	q6,q6,q6,#8
+	eor	r14,r14,r2,ror#24
+	vext.8	q10,q10,q10,#8
+	eor	r10,r10,r3,ror#24
+	vext.8	q1,q1,q1,#4
+	add	r8,r8,r14
+	vext.8	q5,q5,q5,#4
+	mov	r6,r6,ror#25
+	vext.8	q9,q9,q9,#4
+	add	r9,r9,r10
+	vext.8	q3,q3,q3,#12
+	mov	r7,r7,ror#25
+	vext.8	q7,q7,q7,#12
+	eor	r6,r6,r8,ror#25
+	vext.8	q11,q11,q11,#12
+	eor	r7,r7,r9,ror#25
+	vadd.i32	q0,q0,q1
+	add	r0,r0,r5
+	vadd.i32	q4,q4,q5
+	mov	r10,r10,ror#16
+	vadd.i32	q8,q8,q9
+	add	r1,r1,r6
+	veor	q3,q3,q0
+	mov	r12,r12,ror#16
+	veor	q7,q7,q4
+	eor	r10,r10,r0,ror#16
+	veor	q11,q11,q8
+	eor	r12,r12,r1,ror#16
+	vrev32.16	q3,q3
+	add	r8,r8,r10
+	vrev32.16	q7,q7
+	mov	r5,r5,ror#20
+	vrev32.16	q11,q11
+	add	r9,r9,r12
+	vadd.i32	q2,q2,q3
+	mov	r6,r6,ror#20
+	vadd.i32	q6,q6,q7
+	eor	r5,r5,r8,ror#20
+	vadd.i32	q10,q10,q11
+	eor	r6,r6,r9,ror#20
+	veor	q12,q1,q2
+	add	r0,r0,r5
+	veor	q13,q5,q6
+	mov	r10,r10,ror#24
+	veor	q14,q9,q10
+	add	r1,r1,r6
+	vshr.u32	q1,q12,#20
+	mov	r12,r12,ror#24
+	vshr.u32	q5,q13,#20
+	eor	r10,r10,r0,ror#24
+	vshr.u32	q9,q14,#20
+	eor	r12,r12,r1,ror#24
+	vsli.32	q1,q12,#12
+	add	r8,r8,r10
+	vsli.32	q5,q13,#12
+	mov	r5,r5,ror#25
+	vsli.32	q9,q14,#12
+	str	r10,[sp,#4*(16+15)]
+	vadd.i32	q0,q0,q1
+	ldr	r10,[sp,#4*(16+13)]
+	vadd.i32	q4,q4,q5
+	add	r9,r9,r12
+	vadd.i32	q8,q8,q9
+	mov	r6,r6,ror#25
+	veor	q12,q3,q0
+	eor	r5,r5,r8,ror#25
+	veor	q13,q7,q4
+	eor	r6,r6,r9,ror#25
+	veor	q14,q11,q8
+	str	r8,[sp,#4*(16+10)]
+	vshr.u32	q3,q12,#24
+	ldr	r8,[sp,#4*(16+8)]
+	vshr.u32	q7,q13,#24
+	add	r2,r2,r7
+	vshr.u32	q11,q14,#24
+	mov	r10,r10,ror#16
+	vsli.32	q3,q12,#8
+	str	r9,[sp,#4*(16+11)]
+	vsli.32	q7,q13,#8
+	ldr	r9,[sp,#4*(16+9)]
+	vsli.32	q11,q14,#8
+	add	r3,r3,r4
+	vadd.i32	q2,q2,q3
+	mov	r14,r14,ror#16
+	vadd.i32	q6,q6,q7
+	eor	r10,r10,r2,ror#16
+	vadd.i32	q10,q10,q11
+	eor	r14,r14,r3,ror#16
+	veor	q12,q1,q2
+	add	r8,r8,r10
+	veor	q13,q5,q6
+	mov	r7,r7,ror#20
+	veor	q14,q9,q10
+	add	r9,r9,r14
+	vshr.u32	q1,q12,#25
+	mov	r4,r4,ror#20
+	vshr.u32	q5,q13,#25
+	eor	r7,r7,r8,ror#20
+	vshr.u32	q9,q14,#25
+	eor	r4,r4,r9,ror#20
+	vsli.32	q1,q12,#7
+	add	r2,r2,r7
+	vsli.32	q5,q13,#7
+	mov	r10,r10,ror#24
+	vsli.32	q9,q14,#7
+	add	r3,r3,r4
+	vext.8	q2,q2,q2,#8
+	mov	r14,r14,ror#24
+	vext.8	q6,q6,q6,#8
+	eor	r10,r10,r2,ror#24
+	vext.8	q10,q10,q10,#8
+	eor	r14,r14,r3,ror#24
+	vext.8	q1,q1,q1,#12
+	add	r8,r8,r10
+	vext.8	q5,q5,q5,#12
+	mov	r7,r7,ror#25
+	vext.8	q9,q9,q9,#12
+	add	r9,r9,r14
+	vext.8	q3,q3,q3,#4
+	mov	r4,r4,ror#25
+	vext.8	q7,q7,q7,#4
+	eor	r7,r7,r8,ror#25
+	vext.8	q11,q11,q11,#4
+	eor	r4,r4,r9,ror#25
+	bne	.Loop_neon
+
+	add	r11,sp,#32
+	vld1.32	{q12,q13},[sp]		@ load key material
+	vld1.32	{q14,q15},[r11]
+
+	ldr	r11,[sp,#4*(32+2)]	@ load len
+
+	str	r8, [sp,#4*(16+8)]	@ modulo-scheduled store
+	str	r9, [sp,#4*(16+9)]
+	str	r12,[sp,#4*(16+12)]
+	str	r10, [sp,#4*(16+13)]
+	str	r14,[sp,#4*(16+14)]
+
+	@ at this point we have first half of 512-bit result in
+	@ rx and second half at sp+4*(16+8)
+
+	ldr	r12,[sp,#4*(32+1)]	@ load inp
+	ldr	r14,[sp,#4*(32+0)]	@ load out
+
+	vadd.i32	q0,q0,q12		@ accumulate key material
+	vadd.i32	q4,q4,q12
+	vadd.i32	q8,q8,q12
+	vldr	d24,[sp,#4*(16+0)]	@ one
+
+	vadd.i32	q1,q1,q13
+	vadd.i32	q5,q5,q13
+	vadd.i32	q9,q9,q13
+	vldr	d26,[sp,#4*(16+2)]	@ two
+
+	vadd.i32	q2,q2,q14
+	vadd.i32	q6,q6,q14
+	vadd.i32	q10,q10,q14
+	vadd.i32	d14,d14,d24	@ counter+1
+	vadd.i32	d22,d22,d26	@ counter+2
+
+	vadd.i32	q3,q3,q15
+	vadd.i32	q7,q7,q15
+	vadd.i32	q11,q11,q15
+
+	cmp	r11,#64*4
+	blo	.Ltail_neon
+
+	vld1.8	{q12,q13},[r12]!	@ load input
+	mov	r11,sp
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12		@ xor with input
+	veor	q1,q1,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q4,q4,q12
+	vst1.8	{q0,q1},[r14]!	@ store output
+	veor	q5,q5,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q6,q6,q14
+	vst1.8	{q2,q3},[r14]!
+	veor	q7,q7,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q8,q8,q12
+	vld1.32	{q0,q1},[r11]!	@ load for next iteration
+	veor	d25,d25,d25
+	vldr	d24,[sp,#4*(16+4)]	@ four
+	veor	q9,q9,q13
+	vld1.32	{q2,q3},[r11]
+	veor	q10,q10,q14
+	vst1.8	{q4,q5},[r14]!
+	veor	q11,q11,q15
+	vst1.8	{q6,q7},[r14]!
+
+	vadd.i32	d6,d6,d24	@ next counter value
+	vldr	d24,[sp,#4*(16+0)]	@ one
+
+	ldmia	sp,{r8,r9,r10,r11}	@ load key material
+	add	r0,r0,r8	@ accumulate key material
+	ldr	r8,[r12],#16		@ load input
+	vst1.8	{q8,q9},[r14]!
+	add	r1,r1,r9
+	ldr	r9,[r12,#-12]
+	vst1.8	{q10,q11},[r14]!
+	add	r2,r2,r10
+	ldr	r10,[r12,#-8]
+	add	r3,r3,r11
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+	eor	r0,r0,r8	@ xor with input
+	add	r8,sp,#4*(4)
+	eor	r1,r1,r9
+	str	r0,[r14],#16		@ store output
+	eor	r2,r2,r10
+	str	r1,[r14,#-12]
+	eor	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	ldr	r8,[r12],#16		@ load input
+	add	r5,r5,r9
+	ldr	r9,[r12,#-12]
+	add	r6,r6,r10
+	ldr	r10,[r12,#-8]
+	add	r7,r7,r11
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	eor	r4,r4,r8
+	add	r8,sp,#4*(8)
+	eor	r5,r5,r9
+	str	r4,[r14],#16		@ store output
+	eor	r6,r6,r10
+	str	r5,[r14,#-12]
+	eor	r7,r7,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r6,[r14,#-8]
+	add	r0,sp,#4*(16+8)
+	str	r7,[r14,#-4]
+
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
+
+	add	r0,r0,r8	@ accumulate key material
+	ldr	r8,[r12],#16		@ load input
+	add	r1,r1,r9
+	ldr	r9,[r12,#-12]
+# ifdef	__thumb2__
+	it	hi
+# endif
+	strhi	r10,[sp,#4*(16+10)]	@ copy "rx" while at it
+	add	r2,r2,r10
+	ldr	r10,[r12,#-8]
+# ifdef	__thumb2__
+	it	hi
+# endif
+	strhi	r11,[sp,#4*(16+11)]	@ copy "rx" while at it
+	add	r3,r3,r11
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+# endif
+	eor	r0,r0,r8
+	add	r8,sp,#4*(12)
+	eor	r1,r1,r9
+	str	r0,[r14],#16		@ store output
+	eor	r2,r2,r10
+	str	r1,[r14,#-12]
+	eor	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+	str	r2,[r14,#-8]
+	str	r3,[r14,#-4]
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r8,r8,#4		@ next counter value
+	add	r5,r5,r9
+	str	r8,[sp,#4*(12)]	@ save next counter value
+	ldr	r8,[r12],#16		@ load input
+	add	r6,r6,r10
+	add	r4,r4,#3		@ counter+3
+	ldr	r9,[r12,#-12]
+	add	r7,r7,r11
+	ldr	r10,[r12,#-8]
+	ldr	r11,[r12,#-4]
+# ifdef	__ARMEB__
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	eor	r4,r4,r8
+# ifdef	__thumb2__
+	it	hi
+# endif
+	ldrhi	r8,[sp,#4*(32+2)]	@ re-load len
+	eor	r5,r5,r9
+	eor	r6,r6,r10
+	str	r4,[r14],#16		@ store output
+	eor	r7,r7,r11
+	str	r5,[r14,#-12]
+	sub	r11,r8,#64*4	@ len-=64*4
+	str	r6,[r14,#-8]
+	str	r7,[r14,#-4]
+	bhi	.Loop_neon_outer
+
+	b	.Ldone_neon
+
+.align	4
+.Lbreak_neon:
+	@ harmonize NEON and integer-only stack frames: load data
+	@ from NEON frame, but save to integer-only one; distance
+	@ between the two is 4*(32+4+16-32)=4*(20).
+
+	str	r11, [sp,#4*(20+32+2)]	@ save len
+	add	r11,sp,#4*(32+4)
+	str	r12,   [sp,#4*(20+32+1)]	@ save inp
+	str	r14,   [sp,#4*(20+32+0)]	@ save out
+
+	ldr	r12,[sp,#4*(16+10)]
+	ldr	r14,[sp,#4*(16+11)]
+	vldmia	r11,{d8,d9,d10,d11,d12,d13,d14,d15}			@ fulfill ABI requirement
+	str	r12,[sp,#4*(20+16+10)]	@ copy "rx"
+	str	r14,[sp,#4*(20+16+11)]	@ copy "rx"
+
+	ldr	r11, [sp,#4*(15)]
+	ldr	r12,[sp,#4*(12)]		@ modulo-scheduled load
+	ldr	r10, [sp,#4*(13)]
+	ldr	r14,[sp,#4*(14)]
+	str	r11, [sp,#4*(20+16+15)]
+	add	r11,sp,#4*(20)
+	vst1.32	{q0,q1},[r11]!		@ copy key
+	add	sp,sp,#4*(20)			@ switch frame
+	vst1.32	{q2,q3},[r11]
+	mov	r11,#10
+	b	.Loop				@ go integer-only
+
+.align	4
+.Ltail_neon:
+	cmp	r11,#64*3
+	bhs	.L192_or_more_neon
+	cmp	r11,#64*2
+	bhs	.L128_or_more_neon
+	cmp	r11,#64*1
+	bhs	.L64_or_more_neon
+
+	add	r8,sp,#4*(8)
+	vst1.8	{q0,q1},[sp]
+	add	r10,sp,#4*(0)
+	vst1.8	{q2,q3},[r8]
+	b	.Loop_tail_neon
+
+.align	4
+.L64_or_more_neon:
+	vld1.8	{q12,q13},[r12]!
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12
+	veor	q1,q1,q13
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vst1.8	{q0,q1},[r14]!
+	vst1.8	{q2,q3},[r14]!
+
+	beq	.Ldone_neon
+
+	add	r8,sp,#4*(8)
+	vst1.8	{q4,q5},[sp]
+	add	r10,sp,#4*(0)
+	vst1.8	{q6,q7},[r8]
+	sub	r11,r11,#64*1	@ len-=64*1
+	b	.Loop_tail_neon
+
+.align	4
+.L128_or_more_neon:
+	vld1.8	{q12,q13},[r12]!
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12
+	veor	q1,q1,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q4,q4,q12
+	veor	q5,q5,q13
+	vst1.8	{q0,q1},[r14]!
+	veor	q6,q6,q14
+	vst1.8	{q2,q3},[r14]!
+	veor	q7,q7,q15
+	vst1.8	{q4,q5},[r14]!
+	vst1.8	{q6,q7},[r14]!
+
+	beq	.Ldone_neon
+
+	add	r8,sp,#4*(8)
+	vst1.8	{q8,q9},[sp]
+	add	r10,sp,#4*(0)
+	vst1.8	{q10,q11},[r8]
+	sub	r11,r11,#64*2	@ len-=64*2
+	b	.Loop_tail_neon
+
+.align	4
+.L192_or_more_neon:
+	vld1.8	{q12,q13},[r12]!
+	vld1.8	{q14,q15},[r12]!
+	veor	q0,q0,q12
+	veor	q1,q1,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q2,q2,q14
+	veor	q3,q3,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q4,q4,q12
+	veor	q5,q5,q13
+	vld1.8	{q12,q13},[r12]!
+	veor	q6,q6,q14
+	vst1.8	{q0,q1},[r14]!
+	veor	q7,q7,q15
+	vld1.8	{q14,q15},[r12]!
+
+	veor	q8,q8,q12
+	vst1.8	{q2,q3},[r14]!
+	veor	q9,q9,q13
+	vst1.8	{q4,q5},[r14]!
+	veor	q10,q10,q14
+	vst1.8	{q6,q7},[r14]!
+	veor	q11,q11,q15
+	vst1.8	{q8,q9},[r14]!
+	vst1.8	{q10,q11},[r14]!
+
+	beq	.Ldone_neon
+
+	ldmia	sp,{r8,r9,r10,r11}	@ load key material
+	add	r0,r0,r8	@ accumulate key material
+	add	r8,sp,#4*(4)
+	add	r1,r1,r9
+	add	r2,r2,r10
+	add	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r8,sp,#4*(8)
+	add	r5,r5,r9
+	add	r6,r6,r10
+	add	r7,r7,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	stmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7}
+	add	r0,sp,#4*(16+8)
+
+	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
+
+	add	r0,r0,r8	@ accumulate key material
+	add	r8,sp,#4*(12)
+	add	r1,r1,r9
+	add	r2,r2,r10
+	add	r3,r3,r11
+	ldmia	r8,{r8,r9,r10,r11}	@ load key material
+
+	add	r4,r4,r8	@ accumulate key material
+	add	r8,sp,#4*(8)
+	add	r5,r5,r9
+	add	r4,r4,#3		@ counter+3
+	add	r6,r6,r10
+	add	r7,r7,r11
+	ldr	r11,[sp,#4*(32+2)]	@ re-load len
+# ifdef	__ARMEB__
+	rev	r0,r0
+	rev	r1,r1
+	rev	r2,r2
+	rev	r3,r3
+	rev	r4,r4
+	rev	r5,r5
+	rev	r6,r6
+	rev	r7,r7
+# endif
+	stmia	r8,{r0,r1,r2,r3,r4,r5,r6,r7}
+	add	r10,sp,#4*(0)
+	sub	r11,r11,#64*3	@ len-=64*3
+
+.Loop_tail_neon:
+	ldrb	r8,[r10],#1	@ read buffer on stack
+	ldrb	r9,[r12],#1		@ read input
+	subs	r11,r11,#1
+	eor	r8,r8,r9
+	strb	r8,[r14],#1		@ store ouput
+	bne	.Loop_tail_neon
+
+.Ldone_neon:
+	add	sp,sp,#4*(32+4)
+	vldmia	sp,{d8,d9,d10,d11,d12,d13,d14,d15}
+	add	sp,sp,#4*(16+3)
+	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
+.size	ChaCha20_neon,.-ChaCha20_neon
+.comm	OPENSSL_armcap_P,4,4
+#endif
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/modes/ghash-armv4.S b/third_party/boringssl/linux-arm/crypto/modes/ghash-armv4.S
index c6f025d..791b289 100644
--- a/third_party/boringssl/linux-arm/crypto/modes/ghash-armv4.S
+++ b/third_party/boringssl/linux-arm/crypto/modes/ghash-armv4.S
@@ -1,13 +1,12 @@
 #if defined(__arm__)
-#if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .syntax	unified
 
 .text
 .code	32
 
-#ifdef  __APPLE__
+#ifdef  __clang__
 #define ldrplb  ldrbpl
 #define ldrneb  ldrbne
 #endif
@@ -536,6 +535,4 @@
 .byte	71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 .align	2
-
 #endif
-#endif
\ No newline at end of file
diff --git a/third_party/boringssl/linux-arm/crypto/modes/ghashv8-armx32.S b/third_party/boringssl/linux-arm/crypto/modes/ghashv8-armx32.S
index bdbbae9..0e1e631 100644
--- a/third_party/boringssl/linux-arm/crypto/modes/ghashv8-armx32.S
+++ b/third_party/boringssl/linux-arm/crypto/modes/ghashv8-armx32.S
@@ -1,10 +1,11 @@
 #if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 .fpu	neon
 .code	32
 .globl	gcm_init_v8
+.hidden	gcm_init_v8
 .type	gcm_init_v8,%function
 .align	4
 gcm_init_v8:
@@ -55,6 +56,7 @@
 	bx	lr
 .size	gcm_init_v8,.-gcm_init_v8
 .globl	gcm_gmult_v8
+.hidden	gcm_gmult_v8
 .type	gcm_gmult_v8,%function
 .align	4
 gcm_gmult_v8:
@@ -67,10 +69,10 @@
 #endif
 	vext.8	q3,q9,q9,#8
 
-.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
+.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
 	veor	q9,q9,q3		@ Karatsuba pre-processing
-.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
-.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
+.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	vext.8	q9,q0,q2,#8		@ Karatsuba post-processing
 	veor	q10,q0,q2
@@ -96,6 +98,7 @@
 	bx	lr
 .size	gcm_gmult_v8,.-gcm_gmult_v8
 .globl	gcm_ghash_v8
+.hidden	gcm_ghash_v8
 .type	gcm_ghash_v8,%function
 .align	4
 gcm_ghash_v8:
@@ -135,7 +138,7 @@
 #endif
 	vext.8	q7,q9,q9,#8
 	veor	q3,q3,q0		@ I[i]^=Xi
-.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
+.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
 	veor	q9,q9,q7		@ Karatsuba pre-processing
 .byte	0x8f,0xce,0xa9,0xf2	@ pmull2 q6,q12,q7
 	b	.Loop_mod2x_v8
@@ -144,14 +147,14 @@
 .Loop_mod2x_v8:
 	vext.8	q10,q3,q3,#8
 	subs	r3,r3,#32		@ is there more data?
-.byte	0x86,0x0e,0xac,0xf2	@ pmull q0,q14,q3		@ H^2.lo·Xi.lo
+.byte	0x86,0x0e,0xac,0xf2	@ pmull q0,q14,q3		@ H^2.lo·Xi.lo
 	movlo	r12,#0			@ is it time to zero r12?
 
 .byte	0xa2,0xae,0xaa,0xf2	@ pmull q5,q13,q9
 	veor	q10,q10,q3		@ Karatsuba pre-processing
-.byte	0x87,0x4e,0xad,0xf2	@ pmull2 q2,q14,q3		@ H^2.hi·Xi.hi
+.byte	0x87,0x4e,0xad,0xf2	@ pmull2 q2,q14,q3		@ H^2.hi·Xi.hi
 	veor	q0,q0,q4		@ accumulate
-.byte	0xa5,0x2e,0xab,0xf2	@ pmull2 q1,q13,q10		@ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+.byte	0xa5,0x2e,0xab,0xf2	@ pmull2 q1,q13,q10		@ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
 	vld1.64	{q8},[r2],r12	@ load [rotated] I[i+2]
 
 	veor	q2,q2,q6
@@ -176,7 +179,7 @@
 	vext.8	q7,q9,q9,#8
 	vext.8	q3,q8,q8,#8
 	veor	q0,q1,q10
-.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
+.byte	0x8e,0x8e,0xa8,0xf2	@ pmull q4,q12,q7		@ H·Ii+1
 	veor	q3,q3,q2		@ accumulate q3 early
 
 	vext.8	q10,q0,q0,#8		@ 2nd phase of reduction
@@ -197,10 +200,10 @@
 	veor	q3,q3,q0		@ inp^=Xi
 	veor	q9,q8,q10		@ q9 is rotated inp^Xi
 
-.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
+.byte	0x86,0x0e,0xa8,0xf2	@ pmull q0,q12,q3		@ H.lo·Xi.lo
 	veor	q9,q9,q3		@ Karatsuba pre-processing
-.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
-.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+.byte	0x87,0x4e,0xa9,0xf2	@ pmull2 q2,q12,q3		@ H.hi·Xi.hi
+.byte	0xa2,0x2e,0xaa,0xf2	@ pmull q1,q13,q9		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
 
 	vext.8	q9,q0,q2,#8		@ Karatsuba post-processing
 	veor	q10,q0,q2
@@ -230,4 +233,4 @@
 .byte	71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 .align	2
 .align	2
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/sha/sha1-armv4-large.S b/third_party/boringssl/linux-arm/crypto/sha/sha1-armv4-large.S
index 4911458..36955fa 100644
--- a/third_party/boringssl/linux-arm/crypto/sha/sha1-armv4-large.S
+++ b/third_party/boringssl/linux-arm/crypto/sha/sha1-armv4-large.S
@@ -1,10 +1,11 @@
 #if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
 
 .text
 .code	32
 
 .globl	sha1_block_data_order
+.hidden	sha1_block_data_order
 .type	sha1_block_data_order,%function
 
 .align	5
@@ -1459,4 +1460,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/sha/sha256-armv4.S b/third_party/boringssl/linux-arm/crypto/sha/sha256-armv4.S
index ac9f2f1..6040041 100644
--- a/third_party/boringssl/linux-arm/crypto/sha/sha256-armv4.S
+++ b/third_party/boringssl/linux-arm/crypto/sha/sha256-armv4.S
@@ -38,7 +38,7 @@
 @ Add ARMv8 code path performing at 2.0 cpb on Apple A7.
 
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 #else
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 # define __ARM_MAX_ARCH__ 7
@@ -85,6 +85,7 @@
 .align	5
 
 .globl	sha256_block_data_order
+.hidden	sha256_block_data_order
 .type	sha256_block_data_order,%function
 sha256_block_data_order:
 .Lsha256_block_data_order:
@@ -1875,6 +1876,7 @@
 .fpu	neon
 
 .globl	sha256_block_data_order_neon
+.hidden	sha256_block_data_order_neon
 .type	sha256_block_data_order_neon,%function
 .align	4
 sha256_block_data_order_neon:
@@ -2815,4 +2817,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-arm/crypto/sha/sha512-armv4.S b/third_party/boringssl/linux-arm/crypto/sha/sha512-armv4.S
index c794f87..93a7bf8 100644
--- a/third_party/boringssl/linux-arm/crypto/sha/sha512-armv4.S
+++ b/third_party/boringssl/linux-arm/crypto/sha/sha512-armv4.S
@@ -47,7 +47,7 @@
 @ was reflected in below two parameters as 0 and 4. Now caller is
 @ expected to maintain native byte order for whole 64-bit values.
 #ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
 # define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
 # define VFP_ABI_POP	vldmia	sp!,{d8-d15}
 #else
@@ -133,6 +133,7 @@
 #endif
 
 .globl	sha512_block_data_order
+.hidden	sha512_block_data_order
 .type	sha512_block_data_order,%function
 sha512_block_data_order:
 .Lsha512_block_data_order:
@@ -147,7 +148,7 @@
 #ifdef	__APPLE__
 	ldr	r12,[r12]
 #endif
-	tst	r12,#1
+	tst	r12,#ARMV7_NEON
 	bne	.LNEON
 #endif
 	add	r2,r1,r2,lsl#7	@ len to point at the end of inp
@@ -533,6 +534,7 @@
 .fpu	neon
 
 .globl	sha512_block_data_order_neon
+.hidden	sha512_block_data_order_neon
 .type	sha512_block_data_order_neon,%function
 .align	4
 sha512_block_data_order_neon:
@@ -1866,4 +1868,4 @@
 .comm	OPENSSL_armcap_P,4,4
 .hidden	OPENSSL_armcap_P
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/third_party/boringssl/linux-x86/crypto/chacha/chacha-x86.S b/third_party/boringssl/linux-x86/crypto/chacha/chacha-x86.S
new file mode 100644
index 0000000..d3c39ac
--- /dev/null
+++ b/third_party/boringssl/linux-x86/crypto/chacha/chacha-x86.S
@@ -0,0 +1,969 @@
+#if defined(__i386__)
+.file	"chacha-x86.S"
+.text
+.globl	ChaCha20_ctr32
+.hidden	ChaCha20_ctr32
+.type	ChaCha20_ctr32,@function
+.align	16
+ChaCha20_ctr32:
+.L_ChaCha20_ctr32_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	xorl	%eax,%eax
+	cmpl	28(%esp),%eax
+	je	.L000no_data
+	call	.Lpic_point
+.Lpic_point:
+	popl	%eax
+	leal	OPENSSL_ia32cap_P-.Lpic_point(%eax),%ebp
+	testl	$16777216,(%ebp)
+	jz	.L001x86
+	testl	$512,4(%ebp)
+	jz	.L001x86
+	jmp	.Lssse3_shortcut
+.L001x86:
+	movl	32(%esp),%esi
+	movl	36(%esp),%edi
+	subl	$132,%esp
+	movl	(%esi),%eax
+	movl	4(%esi),%ebx
+	movl	8(%esi),%ecx
+	movl	12(%esi),%edx
+	movl	%eax,80(%esp)
+	movl	%ebx,84(%esp)
+	movl	%ecx,88(%esp)
+	movl	%edx,92(%esp)
+	movl	16(%esi),%eax
+	movl	20(%esi),%ebx
+	movl	24(%esi),%ecx
+	movl	28(%esi),%edx
+	movl	%eax,96(%esp)
+	movl	%ebx,100(%esp)
+	movl	%ecx,104(%esp)
+	movl	%edx,108(%esp)
+	movl	(%edi),%eax
+	movl	4(%edi),%ebx
+	movl	8(%edi),%ecx
+	movl	12(%edi),%edx
+	subl	$1,%eax
+	movl	%eax,112(%esp)
+	movl	%ebx,116(%esp)
+	movl	%ecx,120(%esp)
+	movl	%edx,124(%esp)
+	jmp	.L002entry
+.align	16
+.L003outer_loop:
+	movl	%ebx,156(%esp)
+	movl	%eax,152(%esp)
+	movl	%ecx,160(%esp)
+.L002entry:
+	movl	$1634760805,%eax
+	movl	$857760878,4(%esp)
+	movl	$2036477234,8(%esp)
+	movl	$1797285236,12(%esp)
+	movl	84(%esp),%ebx
+	movl	88(%esp),%ebp
+	movl	104(%esp),%ecx
+	movl	108(%esp),%esi
+	movl	116(%esp),%edx
+	movl	120(%esp),%edi
+	movl	%ebx,20(%esp)
+	movl	%ebp,24(%esp)
+	movl	%ecx,40(%esp)
+	movl	%esi,44(%esp)
+	movl	%edx,52(%esp)
+	movl	%edi,56(%esp)
+	movl	92(%esp),%ebx
+	movl	124(%esp),%edi
+	movl	112(%esp),%edx
+	movl	80(%esp),%ebp
+	movl	96(%esp),%ecx
+	movl	100(%esp),%esi
+	addl	$1,%edx
+	movl	%ebx,28(%esp)
+	movl	%edi,60(%esp)
+	movl	%edx,112(%esp)
+	movl	$10,%ebx
+	jmp	.L004loop
+.align	16
+.L004loop:
+	addl	%ebp,%eax
+	movl	%ebx,128(%esp)
+	movl	%ebp,%ebx
+	xorl	%eax,%edx
+	roll	$16,%edx
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	52(%esp),%edi
+	roll	$12,%ebx
+	movl	20(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,48(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,32(%esp)
+	roll	$16,%edi
+	movl	%ebx,16(%esp)
+	addl	%edi,%esi
+	movl	40(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	56(%esp),%edx
+	roll	$12,%ebp
+	movl	24(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,52(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,36(%esp)
+	roll	$16,%edx
+	movl	%ebp,20(%esp)
+	addl	%edx,%ecx
+	movl	44(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	60(%esp),%edi
+	roll	$12,%ebx
+	movl	28(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,56(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,24(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	roll	$12,%ebp
+	movl	20(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,%edx
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	roll	$16,%edx
+	movl	%ebp,28(%esp)
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	48(%esp),%edi
+	roll	$12,%ebx
+	movl	24(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,60(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,40(%esp)
+	roll	$16,%edi
+	movl	%ebx,20(%esp)
+	addl	%edi,%esi
+	movl	32(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	52(%esp),%edx
+	roll	$12,%ebp
+	movl	28(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,48(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,44(%esp)
+	roll	$16,%edx
+	movl	%ebp,24(%esp)
+	addl	%edx,%ecx
+	movl	36(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	56(%esp),%edi
+	roll	$12,%ebx
+	movl	16(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,52(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,28(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	movl	48(%esp),%edx
+	roll	$12,%ebp
+	movl	128(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,56(%esp)
+	xorl	%esi,%ebp
+	roll	$7,%ebp
+	decl	%ebx
+	jnz	.L004loop
+	movl	160(%esp),%ebx
+	addl	$1634760805,%eax
+	addl	80(%esp),%ebp
+	addl	96(%esp),%ecx
+	addl	100(%esp),%esi
+	cmpl	$64,%ebx
+	jb	.L005tail
+	movl	156(%esp),%ebx
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	xorl	(%ebx),%eax
+	xorl	16(%ebx),%ebp
+	movl	%eax,(%esp)
+	movl	152(%esp),%eax
+	xorl	32(%ebx),%ecx
+	xorl	36(%ebx),%esi
+	xorl	48(%ebx),%edx
+	xorl	56(%ebx),%edi
+	movl	%ebp,16(%eax)
+	movl	%ecx,32(%eax)
+	movl	%esi,36(%eax)
+	movl	%edx,48(%eax)
+	movl	%edi,56(%eax)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	xorl	4(%ebx),%ebp
+	xorl	8(%ebx),%ecx
+	xorl	12(%ebx),%esi
+	xorl	20(%ebx),%edx
+	xorl	24(%ebx),%edi
+	movl	%ebp,4(%eax)
+	movl	%ecx,8(%eax)
+	movl	%esi,12(%eax)
+	movl	%edx,20(%eax)
+	movl	%edi,24(%eax)
+	movl	28(%esp),%ebp
+	movl	40(%esp),%ecx
+	movl	44(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	92(%esp),%ebp
+	addl	104(%esp),%ecx
+	addl	108(%esp),%esi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	xorl	28(%ebx),%ebp
+	xorl	40(%ebx),%ecx
+	xorl	44(%ebx),%esi
+	xorl	52(%ebx),%edx
+	xorl	60(%ebx),%edi
+	leal	64(%ebx),%ebx
+	movl	%ebp,28(%eax)
+	movl	(%esp),%ebp
+	movl	%ecx,40(%eax)
+	movl	160(%esp),%ecx
+	movl	%esi,44(%eax)
+	movl	%edx,52(%eax)
+	movl	%edi,60(%eax)
+	movl	%ebp,(%eax)
+	leal	64(%eax),%eax
+	subl	$64,%ecx
+	jnz	.L003outer_loop
+	jmp	.L006done
+.L005tail:
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	movl	%eax,(%esp)
+	movl	%ebp,16(%esp)
+	movl	%ecx,32(%esp)
+	movl	%esi,36(%esp)
+	movl	%edx,48(%esp)
+	movl	%edi,56(%esp)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	movl	%ebp,4(%esp)
+	movl	%ecx,8(%esp)
+	movl	%esi,12(%esp)
+	movl	%edx,20(%esp)
+	movl	%edi,24(%esp)
+	movl	28(%esp),%ebp
+	movl	40(%esp),%ecx
+	movl	44(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	92(%esp),%ebp
+	addl	104(%esp),%ecx
+	addl	108(%esp),%esi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	movl	%ebp,28(%esp)
+	movl	156(%esp),%ebp
+	movl	%ecx,40(%esp)
+	movl	152(%esp),%ecx
+	movl	%esi,44(%esp)
+	xorl	%esi,%esi
+	movl	%edx,52(%esp)
+	movl	%edi,60(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+.L007tail_loop:
+	movb	(%esi,%ebp,1),%al
+	movb	(%esp,%esi,1),%dl
+	leal	1(%esi),%esi
+	xorb	%dl,%al
+	movb	%al,-1(%ecx,%esi,1)
+	decl	%ebx
+	jnz	.L007tail_loop
+.L006done:
+	addl	$132,%esp
+.L000no_data:
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.size	ChaCha20_ctr32,.-.L_ChaCha20_ctr32_begin
+.globl	ChaCha20_ssse3
+.hidden	ChaCha20_ssse3
+.type	ChaCha20_ssse3,@function
+.align	16
+ChaCha20_ssse3:
+.L_ChaCha20_ssse3_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+.Lssse3_shortcut:
+	movl	20(%esp),%edi
+	movl	24(%esp),%esi
+	movl	28(%esp),%ecx
+	movl	32(%esp),%edx
+	movl	36(%esp),%ebx
+	movl	%esp,%ebp
+	subl	$524,%esp
+	andl	$-64,%esp
+	movl	%ebp,512(%esp)
+	leal	.Lssse3_data-.Lpic_point(%eax),%eax
+	movdqu	(%ebx),%xmm3
+	cmpl	$256,%ecx
+	jb	.L0081x
+	movl	%edx,516(%esp)
+	movl	%ebx,520(%esp)
+	subl	$256,%ecx
+	leal	384(%esp),%ebp
+	movdqu	(%edx),%xmm7
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	paddd	48(%eax),%xmm0
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	psubd	64(%eax),%xmm0
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,64(%ebp)
+	movdqa	%xmm1,80(%ebp)
+	movdqa	%xmm2,96(%ebp)
+	movdqa	%xmm3,112(%ebp)
+	movdqu	16(%edx),%xmm3
+	movdqa	%xmm4,-64(%ebp)
+	movdqa	%xmm5,-48(%ebp)
+	movdqa	%xmm6,-32(%ebp)
+	movdqa	%xmm7,-16(%ebp)
+	movdqa	32(%eax),%xmm7
+	leal	128(%esp),%ebx
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,(%ebp)
+	movdqa	%xmm1,16(%ebp)
+	movdqa	%xmm2,32(%ebp)
+	movdqa	%xmm3,48(%ebp)
+	movdqa	%xmm4,-128(%ebp)
+	movdqa	%xmm5,-112(%ebp)
+	movdqa	%xmm6,-96(%ebp)
+	movdqa	%xmm7,-80(%ebp)
+	leal	128(%esi),%esi
+	leal	128(%edi),%edi
+	jmp	.L009outer_loop
+.align	16
+.L009outer_loop:
+	movdqa	-112(%ebp),%xmm1
+	movdqa	-96(%ebp),%xmm2
+	movdqa	-80(%ebp),%xmm3
+	movdqa	-48(%ebp),%xmm5
+	movdqa	-32(%ebp),%xmm6
+	movdqa	-16(%ebp),%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	movdqa	%xmm2,-96(%ebx)
+	movdqa	%xmm3,-80(%ebx)
+	movdqa	%xmm5,-48(%ebx)
+	movdqa	%xmm6,-32(%ebx)
+	movdqa	%xmm7,-16(%ebx)
+	movdqa	32(%ebp),%xmm2
+	movdqa	48(%ebp),%xmm3
+	movdqa	64(%ebp),%xmm4
+	movdqa	80(%ebp),%xmm5
+	movdqa	96(%ebp),%xmm6
+	movdqa	112(%ebp),%xmm7
+	paddd	64(%eax),%xmm4
+	movdqa	%xmm2,32(%ebx)
+	movdqa	%xmm3,48(%ebx)
+	movdqa	%xmm4,64(%ebx)
+	movdqa	%xmm5,80(%ebx)
+	movdqa	%xmm6,96(%ebx)
+	movdqa	%xmm7,112(%ebx)
+	movdqa	%xmm4,64(%ebp)
+	movdqa	-128(%ebp),%xmm0
+	movdqa	%xmm4,%xmm6
+	movdqa	-64(%ebp),%xmm3
+	movdqa	(%ebp),%xmm4
+	movdqa	16(%ebp),%xmm5
+	movl	$10,%edx
+	nop
+.align	16
+.L010loop:
+	paddd	%xmm3,%xmm0
+	movdqa	%xmm3,%xmm2
+	pxor	%xmm0,%xmm6
+	pshufb	(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-48(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	80(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,64(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-64(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	32(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-32(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	96(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,80(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,16(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-48(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	48(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-16(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	112(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,96(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-32(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	-48(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,%xmm6
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-16(%ebx)
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-32(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	64(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,112(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,32(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-48(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-16(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	80(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,64(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,48(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-32(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	16(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-64(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	96(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,80(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-16(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	64(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,96(%ebx)
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	por	%xmm1,%xmm3
+	decl	%edx
+	jnz	.L010loop
+	movdqa	%xmm3,-64(%ebx)
+	movdqa	%xmm4,(%ebx)
+	movdqa	%xmm5,16(%ebx)
+	movdqa	%xmm6,64(%ebx)
+	movdqa	%xmm7,96(%ebx)
+	movdqa	-112(%ebx),%xmm1
+	movdqa	-96(%ebx),%xmm2
+	movdqa	-80(%ebx),%xmm3
+	paddd	-128(%ebp),%xmm0
+	paddd	-112(%ebp),%xmm1
+	paddd	-96(%ebp),%xmm2
+	paddd	-80(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	16(%esi),%esi
+	pxor	%xmm0,%xmm4
+	movdqa	-64(%ebx),%xmm0
+	pxor	%xmm1,%xmm5
+	movdqa	-48(%ebx),%xmm1
+	pxor	%xmm2,%xmm6
+	movdqa	-32(%ebx),%xmm2
+	pxor	%xmm3,%xmm7
+	movdqa	-16(%ebx),%xmm3
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	16(%edi),%edi
+	paddd	-64(%ebp),%xmm0
+	paddd	-48(%ebp),%xmm1
+	paddd	-32(%ebp),%xmm2
+	paddd	-16(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	16(%esi),%esi
+	pxor	%xmm0,%xmm4
+	movdqa	(%ebx),%xmm0
+	pxor	%xmm1,%xmm5
+	movdqa	16(%ebx),%xmm1
+	pxor	%xmm2,%xmm6
+	movdqa	32(%ebx),%xmm2
+	pxor	%xmm3,%xmm7
+	movdqa	48(%ebx),%xmm3
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	16(%edi),%edi
+	paddd	(%ebp),%xmm0
+	paddd	16(%ebp),%xmm1
+	paddd	32(%ebp),%xmm2
+	paddd	48(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	16(%esi),%esi
+	pxor	%xmm0,%xmm4
+	movdqa	64(%ebx),%xmm0
+	pxor	%xmm1,%xmm5
+	movdqa	80(%ebx),%xmm1
+	pxor	%xmm2,%xmm6
+	movdqa	96(%ebx),%xmm2
+	pxor	%xmm3,%xmm7
+	movdqa	112(%ebx),%xmm3
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	16(%edi),%edi
+	paddd	64(%ebp),%xmm0
+	paddd	80(%ebp),%xmm1
+	paddd	96(%ebp),%xmm2
+	paddd	112(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	208(%esi),%esi
+	pxor	%xmm0,%xmm4
+	pxor	%xmm1,%xmm5
+	pxor	%xmm2,%xmm6
+	pxor	%xmm3,%xmm7
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	208(%edi),%edi
+	subl	$256,%ecx
+	jnc	.L009outer_loop
+	addl	$256,%ecx
+	jz	.L011done
+	movl	520(%esp),%ebx
+	leal	-128(%esi),%esi
+	movl	516(%esp),%edx
+	leal	-128(%edi),%edi
+	movd	64(%ebp),%xmm2
+	movdqu	(%ebx),%xmm3
+	paddd	96(%eax),%xmm2
+	pand	112(%eax),%xmm3
+	por	%xmm2,%xmm3
+.L0081x:
+	movdqa	32(%eax),%xmm0
+	movdqu	(%edx),%xmm1
+	movdqu	16(%edx),%xmm2
+	movdqa	(%eax),%xmm6
+	movdqa	16(%eax),%xmm7
+	movl	%ebp,48(%esp)
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	movl	$10,%edx
+	jmp	.L012loop1x
+.align	16
+.L013outer1x:
+	movdqa	80(%eax),%xmm3
+	movdqa	(%esp),%xmm0
+	movdqa	16(%esp),%xmm1
+	movdqa	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	movl	$10,%edx
+	movdqa	%xmm3,48(%esp)
+	jmp	.L012loop1x
+.align	16
+.L012loop1x:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%edx
+	jnz	.L012loop1x
+	paddd	(%esp),%xmm0
+	paddd	16(%esp),%xmm1
+	paddd	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	cmpl	$64,%ecx
+	jb	.L014tail
+	movdqu	(%esi),%xmm4
+	movdqu	16(%esi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%esi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%esi),%xmm5
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+	leal	64(%esi),%esi
+	movdqu	%xmm0,(%edi)
+	movdqu	%xmm1,16(%edi)
+	movdqu	%xmm2,32(%edi)
+	movdqu	%xmm3,48(%edi)
+	leal	64(%edi),%edi
+	subl	$64,%ecx
+	jnz	.L013outer1x
+	jmp	.L011done
+.L014tail:
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+	xorl	%ebp,%ebp
+.L015tail_loop:
+	movb	(%esp,%ebp,1),%al
+	movb	(%esi,%ebp,1),%dl
+	leal	1(%ebp),%ebp
+	xorb	%dl,%al
+	movb	%al,-1(%edi,%ebp,1)
+	decl	%ecx
+	jnz	.L015tail_loop
+.L011done:
+	movl	512(%esp),%esp
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.size	ChaCha20_ssse3,.-.L_ChaCha20_ssse3_begin
+.align	64
+.Lssse3_data:
+.byte	2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.byte	3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.long	1634760805,857760878,2036477234,1797285236
+.long	0,1,2,3
+.long	4,4,4,4
+.long	1,0,0,0
+.long	4,0,0,0
+.long	0,-1,-1,-1
+.align	64
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+.byte	44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+.byte	60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+.byte	114,103,62,0
+#endif
diff --git a/third_party/boringssl/linux-x86/crypto/cpu-x86-asm.S b/third_party/boringssl/linux-x86/crypto/cpu-x86-asm.S
deleted file mode 100644
index 24a8dd4..0000000
--- a/third_party/boringssl/linux-x86/crypto/cpu-x86-asm.S
+++ /dev/null
@@ -1,322 +0,0 @@
-#if defined(__i386__)
-.file	"crypto/cpu-x86-asm.S"
-.text
-.globl	OPENSSL_ia32_cpuid
-.hidden	OPENSSL_ia32_cpuid
-.type	OPENSSL_ia32_cpuid,@function
-.align	16
-OPENSSL_ia32_cpuid:
-.L_OPENSSL_ia32_cpuid_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	xorl	%edx,%edx
-	pushfl
-	popl	%eax
-	movl	%eax,%ecx
-	xorl	$2097152,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	xorl	%eax,%ecx
-	xorl	%eax,%eax
-	btl	$21,%ecx
-	jnc	.L000nocpuid
-	movl	20(%esp),%esi
-	movl	%eax,8(%esi)
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%ebp
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%ebp
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%ebp
-	jz	.L001intel
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%esi
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%esi
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%esi
-	jnz	.L001intel
-	movl	$2147483648,%eax
-	.byte	0x0f,0xa2
-	cmpl	$2147483649,%eax
-	jb	.L001intel
-	movl	%eax,%esi
-	movl	$2147483649,%eax
-	.byte	0x0f,0xa2
-	orl	%ecx,%ebp
-	andl	$2049,%ebp
-	cmpl	$2147483656,%esi
-	jb	.L001intel
-	movl	$2147483656,%eax
-	.byte	0x0f,0xa2
-	movzbl	%cl,%esi
-	incl	%esi
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	btl	$28,%edx
-	jnc	.L002generic
-	shrl	$16,%ebx
-	andl	$255,%ebx
-	cmpl	%esi,%ebx
-	ja	.L002generic
-	andl	$4026531839,%edx
-	jmp	.L002generic
-.L001intel:
-	cmpl	$7,%edi
-	jb	.L003cacheinfo
-	movl	20(%esp),%esi
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	movl	%ebx,8(%esi)
-.L003cacheinfo:
-	cmpl	$4,%edi
-	movl	$-1,%edi
-	jb	.L004nocacheinfo
-	movl	$4,%eax
-	movl	$0,%ecx
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	shrl	$14,%edi
-	andl	$4095,%edi
-.L004nocacheinfo:
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	andl	$3220176895,%edx
-	cmpl	$0,%ebp
-	jne	.L005notintel
-	orl	$1073741824,%edx
-.L005notintel:
-	btl	$28,%edx
-	jnc	.L002generic
-	andl	$4026531839,%edx
-	cmpl	$0,%edi
-	je	.L002generic
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	.L002generic
-	andl	$4026531839,%edx
-.L002generic:
-	andl	$2048,%ebp
-	andl	$4294965247,%ecx
-	movl	%edx,%esi
-	orl	%ecx,%ebp
-	btl	$27,%ecx
-	jnc	.L006clear_avx
-	xorl	%ecx,%ecx
-.byte	15,1,208
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	.L007done
-	cmpl	$2,%eax
-	je	.L006clear_avx
-.L008clear_xmm:
-	andl	$4261412861,%ebp
-	andl	$4278190079,%esi
-.L006clear_avx:
-	andl	$4026525695,%ebp
-	movl	20(%esp),%edi
-	andl	$4294967263,8(%edi)
-.L007done:
-	movl	%esi,%eax
-	movl	%ebp,%edx
-.L000nocpuid:
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.size	OPENSSL_ia32_cpuid,.-.L_OPENSSL_ia32_cpuid_begin
-.globl	OPENSSL_rdtsc
-.hidden	OPENSSL_rdtsc
-.type	OPENSSL_rdtsc,@function
-.align	16
-OPENSSL_rdtsc:
-.L_OPENSSL_rdtsc_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	.L009PIC_me_up
-.L009PIC_me_up:
-	popl	%ecx
-	leal	OPENSSL_ia32cap_P-.L009PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	.L010notsc
-	.byte	0x0f,0x31
-.L010notsc:
-	ret
-.size	OPENSSL_rdtsc,.-.L_OPENSSL_rdtsc_begin
-.globl	OPENSSL_instrument_halt
-.hidden	OPENSSL_instrument_halt
-.type	OPENSSL_instrument_halt,@function
-.align	16
-OPENSSL_instrument_halt:
-.L_OPENSSL_instrument_halt_begin:
-	call	.L011PIC_me_up
-.L011PIC_me_up:
-	popl	%ecx
-	leal	OPENSSL_ia32cap_P-.L011PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	.L012nohalt
-.long	2421723150
-	andl	$3,%eax
-	jnz	.L012nohalt
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	.L012nohalt
-	.byte	0x0f,0x31
-	pushl	%edx
-	pushl	%eax
-	hlt
-	.byte	0x0f,0x31
-	subl	(%esp),%eax
-	sbbl	4(%esp),%edx
-	addl	$8,%esp
-	ret
-.L012nohalt:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.size	OPENSSL_instrument_halt,.-.L_OPENSSL_instrument_halt_begin
-.globl	OPENSSL_far_spin
-.hidden	OPENSSL_far_spin
-.type	OPENSSL_far_spin,@function
-.align	16
-OPENSSL_far_spin:
-.L_OPENSSL_far_spin_begin:
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	.L013nospin
-	movl	4(%esp),%eax
-	movl	8(%esp),%ecx
-.long	2430111262
-	xorl	%eax,%eax
-	movl	(%ecx),%edx
-	jmp	.L014spin
-.align	16
-.L014spin:
-	incl	%eax
-	cmpl	(%ecx),%edx
-	je	.L014spin
-.long	529567888
-	ret
-.L013nospin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.size	OPENSSL_far_spin,.-.L_OPENSSL_far_spin_begin
-.globl	OPENSSL_wipe_cpu
-.hidden	OPENSSL_wipe_cpu
-.type	OPENSSL_wipe_cpu,@function
-.align	16
-OPENSSL_wipe_cpu:
-.L_OPENSSL_wipe_cpu_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	.L015PIC_me_up
-.L015PIC_me_up:
-	popl	%ecx
-	leal	OPENSSL_ia32cap_P-.L015PIC_me_up(%ecx),%ecx
-	movl	(%ecx),%ecx
-	btl	$1,(%ecx)
-	jnc	.L016no_x87
-	andl	$83886080,%ecx
-	cmpl	$83886080,%ecx
-	jne	.L017no_sse2
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-.L017no_sse2:
-.long	4007259865,4007259865,4007259865,4007259865,2430851995
-.L016no_x87:
-	leal	4(%esp),%eax
-	ret
-.size	OPENSSL_wipe_cpu,.-.L_OPENSSL_wipe_cpu_begin
-.globl	OPENSSL_atomic_add
-.hidden	OPENSSL_atomic_add
-.type	OPENSSL_atomic_add,@function
-.align	16
-OPENSSL_atomic_add:
-.L_OPENSSL_atomic_add_begin:
-	movl	4(%esp),%edx
-	movl	8(%esp),%ecx
-	pushl	%ebx
-	nop
-	movl	(%edx),%eax
-.L018spin:
-	leal	(%eax,%ecx,1),%ebx
-	nop
-.long	447811568
-	jne	.L018spin
-	movl	%ebx,%eax
-	popl	%ebx
-	ret
-.size	OPENSSL_atomic_add,.-.L_OPENSSL_atomic_add_begin
-.globl	OPENSSL_indirect_call
-.hidden	OPENSSL_indirect_call
-.type	OPENSSL_indirect_call,@function
-.align	16
-OPENSSL_indirect_call:
-.L_OPENSSL_indirect_call_begin:
-	pushl	%ebp
-	movl	%esp,%ebp
-	subl	$28,%esp
-	movl	12(%ebp),%ecx
-	movl	%ecx,(%esp)
-	movl	16(%ebp),%edx
-	movl	%edx,4(%esp)
-	movl	20(%ebp),%eax
-	movl	%eax,8(%esp)
-	movl	24(%ebp),%eax
-	movl	%eax,12(%esp)
-	movl	28(%ebp),%eax
-	movl	%eax,16(%esp)
-	movl	32(%ebp),%eax
-	movl	%eax,20(%esp)
-	movl	36(%ebp),%eax
-	movl	%eax,24(%esp)
-	call	*8(%ebp)
-	movl	%ebp,%esp
-	popl	%ebp
-	ret
-.size	OPENSSL_indirect_call,.-.L_OPENSSL_indirect_call_begin
-.globl	OPENSSL_ia32_rdrand
-.hidden	OPENSSL_ia32_rdrand
-.type	OPENSSL_ia32_rdrand,@function
-.align	16
-OPENSSL_ia32_rdrand:
-.L_OPENSSL_ia32_rdrand_begin:
-	movl	$8,%ecx
-.L019loop:
-.byte	15,199,240
-	jc	.L020break
-	loop	.L019loop
-.L020break:
-	cmpl	$0,%eax
-	cmovel	%ecx,%eax
-	ret
-.size	OPENSSL_ia32_rdrand,.-.L_OPENSSL_ia32_rdrand_begin
-.hidden	OPENSSL_ia32cap_P
-#endif
diff --git a/third_party/boringssl/linux-x86/crypto/rc4/rc4-586.S b/third_party/boringssl/linux-x86/crypto/rc4/rc4-586.S
index a5cce47..d245589 100644
--- a/third_party/boringssl/linux-x86/crypto/rc4/rc4-586.S
+++ b/third_party/boringssl/linux-x86/crypto/rc4/rc4-586.S
@@ -347,39 +347,4 @@
 	popl	%ebp
 	ret
 .size	asm_RC4_set_key,.-.L_asm_RC4_set_key_begin
-.globl	RC4_options
-.hidden	RC4_options
-.type	RC4_options,@function
-.align	16
-RC4_options:
-.L_RC4_options_begin:
-	call	.L018pic_point
-.L018pic_point:
-	popl	%eax
-	leal	.L019opts-.L018pic_point(%eax),%eax
-	call	.L020PIC_me_up
-.L020PIC_me_up:
-	popl	%edx
-	leal	OPENSSL_ia32cap_P-.L020PIC_me_up(%edx),%edx
-	movl	(%edx),%edx
-	btl	$20,%edx
-	jc	.L0211xchar
-	btl	$26,%edx
-	jnc	.L022ret
-	addl	$25,%eax
-	ret
-.L0211xchar:
-	addl	$12,%eax
-.L022ret:
-	ret
-.align	64
-.L019opts:
-.byte	114,99,52,40,52,120,44,105,110,116,41,0
-.byte	114,99,52,40,49,120,44,99,104,97,114,41,0
-.byte	114,99,52,40,56,120,44,109,109,120,41,0
-.byte	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.align	64
-.size	RC4_options,.-.L_RC4_options_begin
 #endif
diff --git a/third_party/boringssl/linux-x86/crypto/sha/sha1-586.S b/third_party/boringssl/linux-x86/crypto/sha/sha1-586.S
index 808ccac..58d0bc1 100644
--- a/third_party/boringssl/linux-x86/crypto/sha/sha1-586.S
+++ b/third_party/boringssl/linux-x86/crypto/sha/sha1-586.S
@@ -23,8 +23,11 @@
 	movl	8(%esi),%ecx
 	testl	$16777216,%eax
 	jz	.L001x86
-	testl	$536870912,%ecx
-	jnz	.Lshaext_shortcut
+	andl	$268435456,%edx
+	andl	$1073741824,%eax
+	orl	%edx,%eax
+	cmpl	$1342177280,%eax
+	je	.Lavx_shortcut
 	jmp	.Lssse3_shortcut
 .align	16
 .L001x86:
@@ -1393,177 +1396,6 @@
 	popl	%ebp
 	ret
 .size	sha1_block_data_order,.-.L_sha1_block_data_order_begin
-.hidden	_sha1_block_data_order_shaext
-.type	_sha1_block_data_order_shaext,@function
-.align	16
-_sha1_block_data_order_shaext:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	call	.L003pic_point
-.L003pic_point:
-	popl	%ebp
-	leal	.LK_XX_XX-.L003pic_point(%ebp),%ebp
-.Lshaext_shortcut:
-	movl	20(%esp),%edi
-	movl	%esp,%ebx
-	movl	24(%esp),%esi
-	movl	28(%esp),%ecx
-	subl	$32,%esp
-	movdqu	(%edi),%xmm0
-	movd	16(%edi),%xmm1
-	andl	$-32,%esp
-	movdqa	80(%ebp),%xmm3
-	movdqu	(%esi),%xmm4
-	pshufd	$27,%xmm0,%xmm0
-	movdqu	16(%esi),%xmm5
-	pshufd	$27,%xmm1,%xmm1
-	movdqu	32(%esi),%xmm6
-.byte	102,15,56,0,227
-	movdqu	48(%esi),%xmm7
-.byte	102,15,56,0,235
-.byte	102,15,56,0,243
-.byte	102,15,56,0,251
-	jmp	.L004loop_shaext
-.align	16
-.L004loop_shaext:
-	decl	%ecx
-	leal	64(%esi),%eax
-	movdqa	%xmm1,(%esp)
-	paddd	%xmm4,%xmm1
-	cmovnel	%eax,%esi
-	movdqa	%xmm0,16(%esp)
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,0
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,0
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,0
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,0
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,0
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,1
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,1
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,1
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,1
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,1
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,2
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,2
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,2
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,2
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,2
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,3
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-	movdqu	(%esi),%xmm4
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,3
-.byte	15,56,200,213
-	movdqu	16(%esi),%xmm5
-.byte	102,15,56,0,227
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,3
-.byte	15,56,200,206
-	movdqu	32(%esi),%xmm6
-.byte	102,15,56,0,235
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,3
-.byte	15,56,200,215
-	movdqu	48(%esi),%xmm7
-.byte	102,15,56,0,243
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,3
-	movdqa	(%esp),%xmm2
-.byte	102,15,56,0,251
-.byte	15,56,200,202
-	paddd	16(%esp),%xmm0
-	jnz	.L004loop_shaext
-	pshufd	$27,%xmm0,%xmm0
-	pshufd	$27,%xmm1,%xmm1
-	movdqu	%xmm0,(%edi)
-	movd	%xmm1,16(%edi)
-	movl	%ebx,%esp
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.size	_sha1_block_data_order_shaext,.-_sha1_block_data_order_shaext
 .hidden	_sha1_block_data_order_ssse3
 .type	_sha1_block_data_order_ssse3,@function
 .align	16
@@ -1572,10 +1404,10 @@
 	pushl	%ebx
 	pushl	%esi
 	pushl	%edi
-	call	.L005pic_point
-.L005pic_point:
+	call	.L003pic_point
+.L003pic_point:
 	popl	%ebp
-	leal	.LK_XX_XX-.L005pic_point(%ebp),%ebp
+	leal	.LK_XX_XX-.L003pic_point(%ebp),%ebp
 .Lssse3_shortcut:
 	movdqa	(%ebp),%xmm7
 	movdqa	16(%ebp),%xmm0
@@ -1628,9 +1460,9 @@
 	xorl	%edx,%ebp
 	pshufd	$238,%xmm0,%xmm4
 	andl	%ebp,%esi
-	jmp	.L006loop
+	jmp	.L004loop
 .align	16
-.L006loop:
+.L004loop:
 	rorl	$2,%ebx
 	xorl	%edx,%esi
 	movl	%eax,%ebp
@@ -2533,7 +2365,7 @@
 	addl	%edx,%ecx
 	movl	196(%esp),%ebp
 	cmpl	200(%esp),%ebp
-	je	.L007done
+	je	.L005done
 	movdqa	160(%esp),%xmm7
 	movdqa	176(%esp),%xmm6
 	movdqu	(%ebp),%xmm0
@@ -2668,9 +2500,9 @@
 	pshufd	$238,%xmm0,%xmm4
 	andl	%ebx,%esi
 	movl	%ebp,%ebx
-	jmp	.L006loop
+	jmp	.L004loop
 .align	16
-.L007done:
+.L005done:
 	addl	16(%esp),%ebx
 	xorl	%edi,%esi
 	movl	%ecx,%ebp
@@ -2784,6 +2616,1177 @@
 	popl	%ebp
 	ret
 .size	_sha1_block_data_order_ssse3,.-_sha1_block_data_order_ssse3
+.hidden	_sha1_block_data_order_avx
+.type	_sha1_block_data_order_avx,@function
+.align	16
+_sha1_block_data_order_avx:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	call	.L006pic_point
+.L006pic_point:
+	popl	%ebp
+	leal	.LK_XX_XX-.L006pic_point(%ebp),%ebp
+.Lavx_shortcut:
+	vzeroall
+	vmovdqa	(%ebp),%xmm7
+	vmovdqa	16(%ebp),%xmm0
+	vmovdqa	32(%ebp),%xmm1
+	vmovdqa	48(%ebp),%xmm2
+	vmovdqa	64(%ebp),%xmm6
+	movl	20(%esp),%edi
+	movl	24(%esp),%ebp
+	movl	28(%esp),%edx
+	movl	%esp,%esi
+	subl	$208,%esp
+	andl	$-64,%esp
+	vmovdqa	%xmm0,112(%esp)
+	vmovdqa	%xmm1,128(%esp)
+	vmovdqa	%xmm2,144(%esp)
+	shll	$6,%edx
+	vmovdqa	%xmm7,160(%esp)
+	addl	%ebp,%edx
+	vmovdqa	%xmm6,176(%esp)
+	addl	$64,%ebp
+	movl	%edi,192(%esp)
+	movl	%ebp,196(%esp)
+	movl	%edx,200(%esp)
+	movl	%esi,204(%esp)
+	movl	(%edi),%eax
+	movl	4(%edi),%ebx
+	movl	8(%edi),%ecx
+	movl	12(%edi),%edx
+	movl	16(%edi),%edi
+	movl	%ebx,%esi
+	vmovdqu	-64(%ebp),%xmm0
+	vmovdqu	-48(%ebp),%xmm1
+	vmovdqu	-32(%ebp),%xmm2
+	vmovdqu	-16(%ebp),%xmm3
+	vpshufb	%xmm6,%xmm0,%xmm0
+	vpshufb	%xmm6,%xmm1,%xmm1
+	vpshufb	%xmm6,%xmm2,%xmm2
+	vmovdqa	%xmm7,96(%esp)
+	vpshufb	%xmm6,%xmm3,%xmm3
+	vpaddd	%xmm7,%xmm0,%xmm4
+	vpaddd	%xmm7,%xmm1,%xmm5
+	vpaddd	%xmm7,%xmm2,%xmm6
+	vmovdqa	%xmm4,(%esp)
+	movl	%ecx,%ebp
+	vmovdqa	%xmm5,16(%esp)
+	xorl	%edx,%ebp
+	vmovdqa	%xmm6,32(%esp)
+	andl	%ebp,%esi
+	jmp	.L007loop
+.align	16
+.L007loop:
+	shrdl	$2,%ebx,%ebx
+	xorl	%edx,%esi
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	movl	%eax,%ebp
+	addl	(%esp),%edi
+	vpaddd	%xmm3,%xmm7,%xmm7
+	vmovdqa	%xmm0,64(%esp)
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrldq	$4,%xmm3,%xmm6
+	addl	%esi,%edi
+	andl	%ebx,%ebp
+	vpxor	%xmm0,%xmm4,%xmm4
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpxor	%xmm2,%xmm6,%xmm6
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%ebp
+	vmovdqa	%xmm7,48(%esp)
+	movl	%edi,%esi
+	addl	4(%esp),%edx
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	andl	%eax,%esi
+	vpsrld	$31,%xmm4,%xmm6
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%esi
+	vpslldq	$12,%xmm4,%xmm0
+	vpaddd	%xmm4,%xmm4,%xmm4
+	movl	%edx,%ebp
+	addl	8(%esp),%ecx
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm0,%xmm7
+	vpor	%xmm6,%xmm4,%xmm4
+	addl	%esi,%ecx
+	andl	%edi,%ebp
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	vpslld	$2,%xmm0,%xmm0
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%ebp
+	vpxor	%xmm7,%xmm4,%xmm4
+	movl	%ecx,%esi
+	addl	12(%esp),%ebx
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	vpxor	%xmm0,%xmm4,%xmm4
+	addl	%ebp,%ebx
+	andl	%edx,%esi
+	vmovdqa	96(%esp),%xmm0
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%edi,%esi
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	movl	%ebx,%ebp
+	addl	16(%esp),%eax
+	vpaddd	%xmm4,%xmm0,%xmm0
+	vmovdqa	%xmm1,80(%esp)
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrldq	$4,%xmm4,%xmm7
+	addl	%esi,%eax
+	andl	%ecx,%ebp
+	vpxor	%xmm1,%xmm5,%xmm5
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm3,%xmm7,%xmm7
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%ebp
+	vmovdqa	%xmm0,(%esp)
+	movl	%eax,%esi
+	addl	20(%esp),%edi
+	vpxor	%xmm7,%xmm5,%xmm5
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	andl	%ebx,%esi
+	vpsrld	$31,%xmm5,%xmm7
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	vpslldq	$12,%xmm5,%xmm1
+	vpaddd	%xmm5,%xmm5,%xmm5
+	movl	%edi,%ebp
+	addl	24(%esp),%edx
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	vpsrld	$30,%xmm1,%xmm0
+	vpor	%xmm7,%xmm5,%xmm5
+	addl	%esi,%edx
+	andl	%eax,%ebp
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	vpslld	$2,%xmm1,%xmm1
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%ebp
+	vpxor	%xmm0,%xmm5,%xmm5
+	movl	%edx,%esi
+	addl	28(%esp),%ecx
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpxor	%xmm1,%xmm5,%xmm5
+	addl	%ebp,%ecx
+	andl	%edi,%esi
+	vmovdqa	112(%esp),%xmm1
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	vpalignr	$8,%xmm2,%xmm3,%xmm6
+	movl	%ecx,%ebp
+	addl	32(%esp),%ebx
+	vpaddd	%xmm5,%xmm1,%xmm1
+	vmovdqa	%xmm2,96(%esp)
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	vpsrldq	$4,%xmm5,%xmm0
+	addl	%esi,%ebx
+	andl	%edx,%ebp
+	vpxor	%xmm2,%xmm6,%xmm6
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%ecx,%ecx
+	xorl	%edi,%ebp
+	vmovdqa	%xmm1,16(%esp)
+	movl	%ebx,%esi
+	addl	36(%esp),%eax
+	vpxor	%xmm0,%xmm6,%xmm6
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	andl	%ecx,%esi
+	vpsrld	$31,%xmm6,%xmm0
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%esi
+	vpslldq	$12,%xmm6,%xmm2
+	vpaddd	%xmm6,%xmm6,%xmm6
+	movl	%eax,%ebp
+	addl	40(%esp),%edi
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm2,%xmm1
+	vpor	%xmm0,%xmm6,%xmm6
+	addl	%esi,%edi
+	andl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpslld	$2,%xmm2,%xmm2
+	vmovdqa	64(%esp),%xmm0
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%ebp
+	vpxor	%xmm1,%xmm6,%xmm6
+	movl	%edi,%esi
+	addl	44(%esp),%edx
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	vpxor	%xmm2,%xmm6,%xmm6
+	addl	%ebp,%edx
+	andl	%eax,%esi
+	vmovdqa	112(%esp),%xmm2
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%esi
+	vpalignr	$8,%xmm3,%xmm4,%xmm7
+	movl	%edx,%ebp
+	addl	48(%esp),%ecx
+	vpaddd	%xmm6,%xmm2,%xmm2
+	vmovdqa	%xmm3,64(%esp)
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpsrldq	$4,%xmm6,%xmm1
+	addl	%esi,%ecx
+	andl	%edi,%ebp
+	vpxor	%xmm3,%xmm7,%xmm7
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	vpxor	%xmm5,%xmm1,%xmm1
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%ebp
+	vmovdqa	%xmm2,32(%esp)
+	movl	%ecx,%esi
+	addl	52(%esp),%ebx
+	vpxor	%xmm1,%xmm7,%xmm7
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	andl	%edx,%esi
+	vpsrld	$31,%xmm7,%xmm1
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%edi,%esi
+	vpslldq	$12,%xmm7,%xmm3
+	vpaddd	%xmm7,%xmm7,%xmm7
+	movl	%ebx,%ebp
+	addl	56(%esp),%eax
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm3,%xmm2
+	vpor	%xmm1,%xmm7,%xmm7
+	addl	%esi,%eax
+	andl	%ecx,%ebp
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm3,%xmm3
+	vmovdqa	80(%esp),%xmm1
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%ebp
+	vpxor	%xmm2,%xmm7,%xmm7
+	movl	%eax,%esi
+	addl	60(%esp),%edi
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpxor	%xmm3,%xmm7,%xmm7
+	addl	%ebp,%edi
+	andl	%ebx,%esi
+	vmovdqa	112(%esp),%xmm3
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpalignr	$8,%xmm6,%xmm7,%xmm2
+	vpxor	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	movl	%edi,%ebp
+	addl	(%esp),%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	vmovdqa	%xmm4,80(%esp)
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	vmovdqa	%xmm3,%xmm4
+	vpaddd	%xmm7,%xmm3,%xmm3
+	addl	%esi,%edx
+	andl	%eax,%ebp
+	vpxor	%xmm2,%xmm0,%xmm0
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%ebp
+	vpsrld	$30,%xmm0,%xmm2
+	vmovdqa	%xmm3,48(%esp)
+	movl	%edx,%esi
+	addl	4(%esp),%ecx
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpslld	$2,%xmm0,%xmm0
+	addl	%ebp,%ecx
+	andl	%edi,%esi
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	movl	%ecx,%ebp
+	addl	8(%esp),%ebx
+	vpor	%xmm2,%xmm0,%xmm0
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	vmovdqa	96(%esp),%xmm2
+	addl	%esi,%ebx
+	andl	%edx,%ebp
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	12(%esp),%eax
+	xorl	%edi,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm7,%xmm0,%xmm3
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	vpxor	%xmm2,%xmm1,%xmm1
+	vmovdqa	%xmm5,96(%esp)
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	vmovdqa	%xmm4,%xmm5
+	vpaddd	%xmm0,%xmm4,%xmm4
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpxor	%xmm3,%xmm1,%xmm1
+	addl	20(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	vpsrld	$30,%xmm1,%xmm3
+	vmovdqa	%xmm4,(%esp)
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpslld	$2,%xmm1,%xmm1
+	addl	24(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpor	%xmm3,%xmm1,%xmm1
+	addl	28(%esp),%ebx
+	xorl	%edi,%ebp
+	vmovdqa	64(%esp),%xmm3
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	vpxor	%xmm3,%xmm2,%xmm2
+	vmovdqa	%xmm6,64(%esp)
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	vmovdqa	128(%esp),%xmm6
+	vpaddd	%xmm1,%xmm5,%xmm5
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm4,%xmm2,%xmm2
+	addl	36(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm2,%xmm4
+	vmovdqa	%xmm5,16(%esp)
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpslld	$2,%xmm2,%xmm2
+	addl	40(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpor	%xmm4,%xmm2,%xmm2
+	addl	44(%esp),%ecx
+	xorl	%eax,%ebp
+	vmovdqa	80(%esp),%xmm4
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	vpxor	%xmm4,%xmm3,%xmm3
+	vmovdqa	%xmm7,80(%esp)
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	vmovdqa	%xmm6,%xmm7
+	vpaddd	%xmm2,%xmm6,%xmm6
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm5,%xmm3,%xmm3
+	addl	52(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm3,%xmm5
+	vmovdqa	%xmm6,32(%esp)
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpor	%xmm5,%xmm3,%xmm3
+	addl	60(%esp),%edx
+	xorl	%ebx,%ebp
+	vmovdqa	96(%esp),%xmm5
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpalignr	$8,%xmm2,%xmm3,%xmm6
+	vpxor	%xmm0,%xmm4,%xmm4
+	addl	(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	vpxor	%xmm5,%xmm4,%xmm4
+	vmovdqa	%xmm0,96(%esp)
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	vmovdqa	%xmm7,%xmm0
+	vpaddd	%xmm3,%xmm7,%xmm7
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpxor	%xmm6,%xmm4,%xmm4
+	addl	4(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	vpsrld	$30,%xmm4,%xmm6
+	vmovdqa	%xmm7,48(%esp)
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpslld	$2,%xmm4,%xmm4
+	addl	8(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpor	%xmm6,%xmm4,%xmm4
+	addl	12(%esp),%edi
+	xorl	%ecx,%ebp
+	vmovdqa	64(%esp),%xmm6
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpalignr	$8,%xmm3,%xmm4,%xmm7
+	vpxor	%xmm1,%xmm5,%xmm5
+	addl	16(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	vpxor	%xmm6,%xmm5,%xmm5
+	vmovdqa	%xmm1,64(%esp)
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	vmovdqa	%xmm0,%xmm1
+	vpaddd	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpxor	%xmm7,%xmm5,%xmm5
+	addl	20(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm5,%xmm7
+	vmovdqa	%xmm0,(%esp)
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpslld	$2,%xmm5,%xmm5
+	addl	24(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpor	%xmm7,%xmm5,%xmm5
+	addl	28(%esp),%eax
+	vmovdqa	80(%esp),%xmm7
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm4,%xmm5,%xmm0
+	vpxor	%xmm2,%xmm6,%xmm6
+	addl	32(%esp),%edi
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	vmovdqa	%xmm2,80(%esp)
+	movl	%eax,%ebp
+	xorl	%ecx,%esi
+	vmovdqa	%xmm1,%xmm2
+	vpaddd	%xmm5,%xmm1,%xmm1
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	vpxor	%xmm0,%xmm6,%xmm6
+	xorl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	addl	36(%esp),%edx
+	vpsrld	$30,%xmm6,%xmm0
+	vmovdqa	%xmm1,16(%esp)
+	andl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%edi,%esi
+	vpslld	$2,%xmm6,%xmm6
+	xorl	%ebx,%ebp
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	addl	40(%esp),%ecx
+	andl	%eax,%esi
+	vpor	%xmm0,%xmm6,%xmm6
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	vmovdqa	96(%esp),%xmm0
+	movl	%edx,%ebp
+	xorl	%eax,%esi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%edi,%ebp
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	addl	44(%esp),%ebx
+	andl	%edi,%ebp
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	xorl	%edi,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edx,%esi
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm5,%xmm6,%xmm1
+	vpxor	%xmm3,%xmm7,%xmm7
+	addl	48(%esp),%eax
+	andl	%edx,%esi
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	vpxor	%xmm0,%xmm7,%xmm7
+	vmovdqa	%xmm3,96(%esp)
+	movl	%ebx,%ebp
+	xorl	%edx,%esi
+	vmovdqa	144(%esp),%xmm3
+	vpaddd	%xmm6,%xmm2,%xmm2
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vpxor	%xmm1,%xmm7,%xmm7
+	xorl	%ecx,%ebp
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	52(%esp),%edi
+	vpsrld	$30,%xmm7,%xmm1
+	vmovdqa	%xmm2,32(%esp)
+	andl	%ecx,%ebp
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	vpslld	$2,%xmm7,%xmm7
+	xorl	%ecx,%ebp
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	addl	56(%esp),%edx
+	andl	%ebx,%esi
+	vpor	%xmm1,%xmm7,%xmm7
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	vmovdqa	64(%esp),%xmm1
+	movl	%edi,%ebp
+	xorl	%ebx,%esi
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%eax,%ebp
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	addl	60(%esp),%ecx
+	andl	%eax,%ebp
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	movl	%edx,%esi
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%edi,%esi
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm6,%xmm7,%xmm2
+	vpxor	%xmm4,%xmm0,%xmm0
+	addl	(%esp),%ebx
+	andl	%edi,%esi
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	vmovdqa	%xmm4,64(%esp)
+	movl	%ecx,%ebp
+	xorl	%edi,%esi
+	vmovdqa	%xmm3,%xmm4
+	vpaddd	%xmm7,%xmm3,%xmm3
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	vpxor	%xmm2,%xmm0,%xmm0
+	xorl	%edx,%ebp
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	4(%esp),%eax
+	vpsrld	$30,%xmm0,%xmm2
+	vmovdqa	%xmm3,48(%esp)
+	andl	%edx,%ebp
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	vpslld	$2,%xmm0,%xmm0
+	xorl	%edx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	8(%esp),%edi
+	andl	%ecx,%esi
+	vpor	%xmm2,%xmm0,%xmm0
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	vmovdqa	80(%esp),%xmm2
+	movl	%eax,%ebp
+	xorl	%ecx,%esi
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	addl	12(%esp),%edx
+	andl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%edi,%esi
+	xorl	%ebx,%ebp
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	vpalignr	$8,%xmm7,%xmm0,%xmm3
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%esp),%ecx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	vpxor	%xmm2,%xmm1,%xmm1
+	vmovdqa	%xmm5,80(%esp)
+	movl	%edx,%ebp
+	xorl	%eax,%esi
+	vmovdqa	%xmm4,%xmm5
+	vpaddd	%xmm0,%xmm4,%xmm4
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	vpxor	%xmm3,%xmm1,%xmm1
+	xorl	%edi,%ebp
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	addl	20(%esp),%ebx
+	vpsrld	$30,%xmm1,%xmm3
+	vmovdqa	%xmm4,(%esp)
+	andl	%edi,%ebp
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	vpslld	$2,%xmm1,%xmm1
+	xorl	%edi,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edx,%esi
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	24(%esp),%eax
+	andl	%edx,%esi
+	vpor	%xmm3,%xmm1,%xmm1
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	vmovdqa	96(%esp),%xmm3
+	movl	%ebx,%ebp
+	xorl	%edx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%ecx,%ebp
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	28(%esp),%edi
+	andl	%ecx,%ebp
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	xorl	%ecx,%ebp
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%esp),%edx
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	vpxor	%xmm3,%xmm2,%xmm2
+	vmovdqa	%xmm6,96(%esp)
+	movl	%edi,%ebp
+	xorl	%ebx,%esi
+	vmovdqa	%xmm5,%xmm6
+	vpaddd	%xmm1,%xmm5,%xmm5
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	vpxor	%xmm4,%xmm2,%xmm2
+	xorl	%eax,%ebp
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	addl	36(%esp),%ecx
+	vpsrld	$30,%xmm2,%xmm4
+	vmovdqa	%xmm5,16(%esp)
+	andl	%eax,%ebp
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	movl	%edx,%esi
+	vpslld	$2,%xmm2,%xmm2
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%edi,%esi
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	addl	40(%esp),%ebx
+	andl	%edi,%esi
+	vpor	%xmm4,%xmm2,%xmm2
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	vmovdqa	64(%esp),%xmm4
+	movl	%ecx,%ebp
+	xorl	%edi,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edx,%ebp
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	44(%esp),%eax
+	andl	%edx,%ebp
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	vpxor	%xmm4,%xmm3,%xmm3
+	vmovdqa	%xmm7,64(%esp)
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	vmovdqa	%xmm6,%xmm7
+	vpaddd	%xmm2,%xmm6,%xmm6
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpxor	%xmm5,%xmm3,%xmm3
+	addl	52(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	vpsrld	$30,%xmm3,%xmm5
+	vmovdqa	%xmm6,32(%esp)
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpor	%xmm5,%xmm3,%xmm3
+	addl	60(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	(%esp),%eax
+	vpaddd	%xmm3,%xmm7,%xmm7
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vmovdqa	%xmm7,48(%esp)
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	4(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	8(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	12(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	movl	196(%esp),%ebp
+	cmpl	200(%esp),%ebp
+	je	.L008done
+	vmovdqa	160(%esp),%xmm7
+	vmovdqa	176(%esp),%xmm6
+	vmovdqu	(%ebp),%xmm0
+	vmovdqu	16(%ebp),%xmm1
+	vmovdqu	32(%ebp),%xmm2
+	vmovdqu	48(%ebp),%xmm3
+	addl	$64,%ebp
+	vpshufb	%xmm6,%xmm0,%xmm0
+	movl	%ebp,196(%esp)
+	vmovdqa	%xmm7,96(%esp)
+	addl	16(%esp),%ebx
+	xorl	%edi,%esi
+	vpshufb	%xmm6,%xmm1,%xmm1
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	vpaddd	%xmm7,%xmm0,%xmm4
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vmovdqa	%xmm4,(%esp)
+	addl	20(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	28(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	32(%esp),%ecx
+	xorl	%eax,%esi
+	vpshufb	%xmm6,%xmm2,%xmm2
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	vpaddd	%xmm7,%xmm1,%xmm5
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vmovdqa	%xmm5,16(%esp)
+	addl	36(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	48(%esp),%edx
+	xorl	%ebx,%esi
+	vpshufb	%xmm6,%xmm3,%xmm3
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	vpaddd	%xmm7,%xmm2,%xmm6
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vmovdqa	%xmm6,32(%esp)
+	addl	52(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	addl	56(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	movl	192(%esp),%ebp
+	addl	(%ebp),%eax
+	addl	4(%ebp),%esi
+	addl	8(%ebp),%ecx
+	movl	%eax,(%ebp)
+	addl	12(%ebp),%edx
+	movl	%esi,4(%ebp)
+	addl	16(%ebp),%edi
+	movl	%ecx,%ebx
+	movl	%ecx,8(%ebp)
+	xorl	%edx,%ebx
+	movl	%edx,12(%ebp)
+	movl	%edi,16(%ebp)
+	movl	%esi,%ebp
+	andl	%ebx,%esi
+	movl	%ebp,%ebx
+	jmp	.L007loop
+.align	16
+.L008done:
+	addl	16(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	20(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	28(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	32(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	addl	36(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	48(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	52(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	addl	56(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vzeroall
+	movl	192(%esp),%ebp
+	addl	(%ebp),%eax
+	movl	204(%esp),%esp
+	addl	4(%ebp),%esi
+	addl	8(%ebp),%ecx
+	movl	%eax,(%ebp)
+	addl	12(%ebp),%edx
+	movl	%esi,4(%ebp)
+	addl	16(%ebp),%edi
+	movl	%ecx,8(%ebp)
+	movl	%edx,12(%ebp)
+	movl	%edi,16(%ebp)
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.size	_sha1_block_data_order_avx,.-_sha1_block_data_order_avx
 .align	64
 .LK_XX_XX:
 .long	1518500249,1518500249,1518500249,1518500249
diff --git a/third_party/boringssl/linux-x86/crypto/sha/sha256-586.S b/third_party/boringssl/linux-x86/crypto/sha/sha256-586.S
index 08d9484..38acbd8 100644
--- a/third_party/boringssl/linux-x86/crypto/sha/sha256-586.S
+++ b/third_party/boringssl/linux-x86/crypto/sha/sha256-586.S
@@ -37,11 +37,10 @@
 	jz	.L003no_xmm
 	andl	$1073741824,%ecx
 	andl	$268435968,%ebx
-	testl	$536870912,%edx
-	jnz	.L004shaext
 	orl	%ebx,%ecx
 	andl	$1342177280,%ecx
 	cmpl	$1342177280,%ecx
+	je	.L004AVX
 	testl	$512,%ebx
 	jnz	.L005SSSE3
 .L003no_xmm:
@@ -3167,204 +3166,6 @@
 	popl	%ebp
 	ret
 .align	32
-.L004shaext:
-	subl	$32,%esp
-	movdqu	(%esi),%xmm1
-	leal	128(%ebp),%ebp
-	movdqu	16(%esi),%xmm2
-	movdqa	128(%ebp),%xmm7
-	pshufd	$27,%xmm1,%xmm0
-	pshufd	$177,%xmm1,%xmm1
-	pshufd	$27,%xmm2,%xmm2
-.byte	102,15,58,15,202,8
-	punpcklqdq	%xmm0,%xmm2
-	jmp	.L010loop_shaext
-.align	16
-.L010loop_shaext:
-	movdqu	(%edi),%xmm3
-	movdqu	16(%edi),%xmm4
-	movdqu	32(%edi),%xmm5
-.byte	102,15,56,0,223
-	movdqu	48(%edi),%xmm6
-	movdqa	%xmm2,16(%esp)
-	movdqa	-128(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	102,15,56,0,231
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	nop
-	movdqa	%xmm1,(%esp)
-.byte	15,56,203,202
-	movdqa	-112(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	102,15,56,0,239
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	leal	64(%edi),%edi
-.byte	15,56,204,220
-.byte	15,56,203,202
-	movdqa	-96(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	102,15,56,0,247
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm6,%xmm7
-.byte	102,15,58,15,253,4
-	nop
-	paddd	%xmm7,%xmm3
-.byte	15,56,204,229
-.byte	15,56,203,202
-	movdqa	-80(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-.byte	15,56,205,222
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm3,%xmm7
-.byte	102,15,58,15,254,4
-	nop
-	paddd	%xmm7,%xmm4
-.byte	15,56,204,238
-.byte	15,56,203,202
-	movdqa	-64(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	15,56,205,227
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm4,%xmm7
-.byte	102,15,58,15,251,4
-	nop
-	paddd	%xmm7,%xmm5
-.byte	15,56,204,243
-.byte	15,56,203,202
-	movdqa	-48(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	15,56,205,236
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm5,%xmm7
-.byte	102,15,58,15,252,4
-	nop
-	paddd	%xmm7,%xmm6
-.byte	15,56,204,220
-.byte	15,56,203,202
-	movdqa	-32(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	15,56,205,245
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm6,%xmm7
-.byte	102,15,58,15,253,4
-	nop
-	paddd	%xmm7,%xmm3
-.byte	15,56,204,229
-.byte	15,56,203,202
-	movdqa	-16(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-.byte	15,56,205,222
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm3,%xmm7
-.byte	102,15,58,15,254,4
-	nop
-	paddd	%xmm7,%xmm4
-.byte	15,56,204,238
-.byte	15,56,203,202
-	movdqa	(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	15,56,205,227
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm4,%xmm7
-.byte	102,15,58,15,251,4
-	nop
-	paddd	%xmm7,%xmm5
-.byte	15,56,204,243
-.byte	15,56,203,202
-	movdqa	16(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	15,56,205,236
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm5,%xmm7
-.byte	102,15,58,15,252,4
-	nop
-	paddd	%xmm7,%xmm6
-.byte	15,56,204,220
-.byte	15,56,203,202
-	movdqa	32(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	15,56,205,245
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm6,%xmm7
-.byte	102,15,58,15,253,4
-	nop
-	paddd	%xmm7,%xmm3
-.byte	15,56,204,229
-.byte	15,56,203,202
-	movdqa	48(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-.byte	15,56,205,222
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm3,%xmm7
-.byte	102,15,58,15,254,4
-	nop
-	paddd	%xmm7,%xmm4
-.byte	15,56,204,238
-.byte	15,56,203,202
-	movdqa	64(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	15,56,205,227
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm4,%xmm7
-.byte	102,15,58,15,251,4
-	nop
-	paddd	%xmm7,%xmm5
-.byte	15,56,204,243
-.byte	15,56,203,202
-	movdqa	80(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	15,56,205,236
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm5,%xmm7
-.byte	102,15,58,15,252,4
-.byte	15,56,203,202
-	paddd	%xmm7,%xmm6
-	movdqa	96(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-.byte	15,56,205,245
-	movdqa	128(%ebp),%xmm7
-.byte	15,56,203,202
-	movdqa	112(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-	nop
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	cmpl	%edi,%eax
-	nop
-.byte	15,56,203,202
-	paddd	16(%esp),%xmm2
-	paddd	(%esp),%xmm1
-	jnz	.L010loop_shaext
-	pshufd	$177,%xmm2,%xmm2
-	pshufd	$27,%xmm1,%xmm7
-	pshufd	$177,%xmm1,%xmm1
-	punpckhqdq	%xmm2,%xmm1
-.byte	102,15,58,15,215,8
-	movl	44(%esp),%esp
-	movdqu	%xmm1,(%esi)
-	movdqu	%xmm2,16(%esi)
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.align	32
 .L005SSSE3:
 	leal	-96(%esp),%esp
 	movl	(%esi),%eax
@@ -3384,9 +3185,9 @@
 	movl	%ecx,24(%esp)
 	movl	%esi,28(%esp)
 	movdqa	256(%ebp),%xmm7
-	jmp	.L011grand_ssse3
+	jmp	.L010grand_ssse3
 .align	16
-.L011grand_ssse3:
+.L010grand_ssse3:
 	movdqu	(%edi),%xmm0
 	movdqu	16(%edi),%xmm1
 	movdqu	32(%edi),%xmm2
@@ -3409,9 +3210,9 @@
 	paddd	%xmm3,%xmm7
 	movdqa	%xmm6,64(%esp)
 	movdqa	%xmm7,80(%esp)
-	jmp	.L012ssse3_00_47
+	jmp	.L011ssse3_00_47
 .align	16
-.L012ssse3_00_47:
+.L011ssse3_00_47:
 	addl	$64,%ebp
 	movl	%edx,%ecx
 	movdqa	%xmm1,%xmm4
@@ -4054,7 +3855,7 @@
 	addl	%ecx,%eax
 	movdqa	%xmm6,80(%esp)
 	cmpl	$66051,64(%ebp)
-	jne	.L012ssse3_00_47
+	jne	.L011ssse3_00_47
 	movl	%edx,%ecx
 	rorl	$14,%edx
 	movl	20(%esp),%esi
@@ -4568,12 +4369,1193 @@
 	movdqa	64(%ebp),%xmm7
 	subl	$192,%ebp
 	cmpl	104(%esp),%edi
-	jb	.L011grand_ssse3
+	jb	.L010grand_ssse3
 	movl	108(%esp),%esp
 	popl	%edi
 	popl	%esi
 	popl	%ebx
 	popl	%ebp
 	ret
+.align	32
+.L004AVX:
+	leal	-96(%esp),%esp
+	vzeroall
+	movl	(%esi),%eax
+	movl	4(%esi),%ebx
+	movl	8(%esi),%ecx
+	movl	12(%esi),%edi
+	movl	%ebx,4(%esp)
+	xorl	%ecx,%ebx
+	movl	%ecx,8(%esp)
+	movl	%edi,12(%esp)
+	movl	16(%esi),%edx
+	movl	20(%esi),%edi
+	movl	24(%esi),%ecx
+	movl	28(%esi),%esi
+	movl	%edi,20(%esp)
+	movl	100(%esp),%edi
+	movl	%ecx,24(%esp)
+	movl	%esi,28(%esp)
+	vmovdqa	256(%ebp),%xmm7
+	jmp	.L012grand_avx
+.align	32
+.L012grand_avx:
+	vmovdqu	(%edi),%xmm0
+	vmovdqu	16(%edi),%xmm1
+	vmovdqu	32(%edi),%xmm2
+	vmovdqu	48(%edi),%xmm3
+	addl	$64,%edi
+	vpshufb	%xmm7,%xmm0,%xmm0
+	movl	%edi,100(%esp)
+	vpshufb	%xmm7,%xmm1,%xmm1
+	vpshufb	%xmm7,%xmm2,%xmm2
+	vpaddd	(%ebp),%xmm0,%xmm4
+	vpshufb	%xmm7,%xmm3,%xmm3
+	vpaddd	16(%ebp),%xmm1,%xmm5
+	vpaddd	32(%ebp),%xmm2,%xmm6
+	vpaddd	48(%ebp),%xmm3,%xmm7
+	vmovdqa	%xmm4,32(%esp)
+	vmovdqa	%xmm5,48(%esp)
+	vmovdqa	%xmm6,64(%esp)
+	vmovdqa	%xmm7,80(%esp)
+	jmp	.L013avx_00_47
+.align	16
+.L013avx_00_47:
+	addl	$64,%ebp
+	vpalignr	$4,%xmm0,%xmm1,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	vpalignr	$4,%xmm2,%xmm3,%xmm7
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	vpaddd	%xmm7,%xmm0,%xmm0
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	vpshufd	$250,%xmm3,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	32(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	vpaddd	%xmm4,%xmm0,%xmm0
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	36(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	vpaddd	%xmm7,%xmm0,%xmm0
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm0,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	40(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm0,%xmm0
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	vpaddd	(%ebp),%xmm0,%xmm6
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	44(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,32(%esp)
+	vpalignr	$4,%xmm1,%xmm2,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	vpalignr	$4,%xmm3,%xmm0,%xmm7
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	vpaddd	%xmm7,%xmm1,%xmm1
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	vpshufd	$250,%xmm0,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	48(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	vpaddd	%xmm4,%xmm1,%xmm1
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	52(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	vpaddd	%xmm7,%xmm1,%xmm1
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm1,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	56(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm1,%xmm1
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	vpaddd	16(%ebp),%xmm1,%xmm6
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	60(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,48(%esp)
+	vpalignr	$4,%xmm2,%xmm3,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	vpalignr	$4,%xmm0,%xmm1,%xmm7
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	vpaddd	%xmm7,%xmm2,%xmm2
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	vpshufd	$250,%xmm1,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	64(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	vpaddd	%xmm4,%xmm2,%xmm2
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	68(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	vpaddd	%xmm7,%xmm2,%xmm2
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm2,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	72(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm2,%xmm2
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	vpaddd	32(%ebp),%xmm2,%xmm6
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	76(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,64(%esp)
+	vpalignr	$4,%xmm3,%xmm0,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	vpalignr	$4,%xmm1,%xmm2,%xmm7
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	vpaddd	%xmm7,%xmm3,%xmm3
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	vpshufd	$250,%xmm2,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	80(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	vpaddd	%xmm4,%xmm3,%xmm3
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	84(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	vpaddd	%xmm7,%xmm3,%xmm3
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm3,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	88(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm3,%xmm3
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	vpaddd	48(%ebp),%xmm3,%xmm6
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	92(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,80(%esp)
+	cmpl	$66051,64(%ebp)
+	jne	.L013avx_00_47
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	32(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	36(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	40(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	44(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	48(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	52(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	56(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	60(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	64(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	68(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	72(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	76(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	80(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	84(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	88(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	92(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	movl	96(%esp),%esi
+	xorl	%edi,%ebx
+	movl	12(%esp),%ecx
+	addl	(%esi),%eax
+	addl	4(%esi),%ebx
+	addl	8(%esi),%edi
+	addl	12(%esi),%ecx
+	movl	%eax,(%esi)
+	movl	%ebx,4(%esi)
+	movl	%edi,8(%esi)
+	movl	%ecx,12(%esi)
+	movl	%ebx,4(%esp)
+	xorl	%edi,%ebx
+	movl	%edi,8(%esp)
+	movl	%ecx,12(%esp)
+	movl	20(%esp),%edi
+	movl	24(%esp),%ecx
+	addl	16(%esi),%edx
+	addl	20(%esi),%edi
+	addl	24(%esi),%ecx
+	movl	%edx,16(%esi)
+	movl	%edi,20(%esi)
+	movl	%edi,20(%esp)
+	movl	28(%esp),%edi
+	movl	%ecx,24(%esi)
+	addl	28(%esi),%edi
+	movl	%ecx,24(%esp)
+	movl	%edi,28(%esi)
+	movl	%edi,28(%esp)
+	movl	100(%esp),%edi
+	vmovdqa	64(%ebp),%xmm7
+	subl	$192,%ebp
+	cmpl	104(%esp),%edi
+	jb	.L012grand_avx
+	movl	108(%esp),%esp
+	vzeroall
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
 .size	sha256_block_data_order,.-.L_sha256_block_data_order_begin
 #endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/aes/aes-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/aes/aes-x86_64.S
index 5f4b057..361e84c 100644
--- a/third_party/boringssl/linux-x86_64/crypto/aes/aes-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/aes/aes-x86_64.S
@@ -82,8 +82,8 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$65280,%edi
-	andl	$65280,%ebp
+	andl	$0x0000ff00,%edi
+	andl	$0x0000ff00,%ebp
 
 	xorl	%edi,%r10d
 	xorl	%ebp,%r11d
@@ -95,8 +95,8 @@
 	movl	0(%r14,%rsi,8),%esi
 	movl	0(%r14,%rdi,8),%edi
 
-	andl	$65280,%esi
-	andl	$65280,%edi
+	andl	$0x0000ff00,%esi
+	andl	$0x0000ff00,%edi
 	shrl	$16,%ebx
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -109,9 +109,9 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$16711680,%edi
-	andl	$16711680,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0x00ff0000,%edi
+	andl	$0x00ff0000,%ebp
 
 	xorl	%esi,%r10d
 	xorl	%edi,%r11d
@@ -124,9 +124,9 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	2(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$4278190080,%edi
-	andl	$4278190080,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0xff000000,%edi
+	andl	$0xff000000,%ebp
 
 	xorl	%esi,%r8d
 	xorl	%edi,%r10d
@@ -139,8 +139,8 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	16+0(%r15),%eax
 
-	andl	$4278190080,%esi
-	andl	$4278190080,%edi
+	andl	$0xff000000,%esi
+	andl	$0xff000000,%edi
 
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -242,8 +242,8 @@
 	xorl	%r8d,%edx
 	cmpq	16(%rsp),%r15
 	je	.Lenc_compact_done
-	movl	$2155905152,%r10d
-	movl	$2155905152,%r11d
+	movl	$0x80808080,%r10d
+	movl	$0x80808080,%r11d
 	andl	%eax,%r10d
 	andl	%ebx,%r11d
 	movl	%r10d,%esi
@@ -254,10 +254,10 @@
 	leal	(%rbx,%rbx,1),%r9d
 	subl	%r10d,%esi
 	subl	%r11d,%edi
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%eax,%r10d
 	movl	%ebx,%r11d
 	xorl	%esi,%r8d
@@ -265,9 +265,9 @@
 
 	xorl	%r8d,%eax
 	xorl	%r9d,%ebx
-	movl	$2155905152,%r12d
+	movl	$0x80808080,%r12d
 	roll	$24,%eax
-	movl	$2155905152,%ebp
+	movl	$0x80808080,%ebp
 	roll	$24,%ebx
 	andl	%ecx,%r12d
 	andl	%edx,%ebp
@@ -290,10 +290,10 @@
 	xorl	%r10d,%eax
 	xorl	%r11d,%ebx
 
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%ecx,%r12d
 	movl	%edx,%ebp
 	xorl	%esi,%r8d
@@ -345,7 +345,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -370,7 +370,7 @@
 	leaq	.LAES_Te+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 
 	call	_x86_64_AES_encrypt_compact
@@ -791,7 +791,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -816,7 +816,7 @@
 	leaq	.LAES_Td+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 	shrq	$3,%rbp
 	addq	%rbp,%r14
@@ -1334,9 +1334,9 @@
 	movq	%r14,%r10
 	leaq	2304(%r14),%r11
 	movq	%r15,%r12
-	andq	$4095,%r10
-	andq	$4095,%r11
-	andq	$4095,%r12
+	andq	$0xFFF,%r10
+	andq	$0xFFF,%r11
+	andq	$0xFFF,%r12
 
 	cmpq	%r11,%r12
 	jb	.Lcbc_te_break_out
@@ -1345,7 +1345,7 @@
 	jmp	.Lcbc_te_ok
 .Lcbc_te_break_out:
 	subq	%r10,%r12
-	andq	$4095,%r12
+	andq	$0xFFF,%r12
 	addq	$320,%r12
 	subq	%r12,%r15
 .align	4
@@ -1371,7 +1371,7 @@
 
 	movq	%r15,%r10
 	subq	%r14,%r10
-	andq	$4095,%r10
+	andq	$0xfff,%r10
 	cmpq	$2304,%r10
 	jb	.Lcbc_do_ecopy
 	cmpq	$4096-248,%r10
@@ -1558,7 +1558,7 @@
 	leaq	-88-63(%rcx),%r10
 	subq	%rbp,%r10
 	negq	%r10
-	andq	$960,%r10
+	andq	$0x3c0,%r10
 	subq	%r10,%rbp
 
 	xchgq	%rsp,%rbp
@@ -1587,7 +1587,7 @@
 	leaq	2048(%r14),%r14
 	leaq	768-8(%rsp),%rax
 	subq	%r14,%rax
-	andq	$768,%rax
+	andq	$0x300,%rax
 	leaq	(%r14,%rax,1),%r14
 
 	cmpq	$0,%rbx
diff --git a/third_party/boringssl/linux-x86_64/crypto/aes/aesni-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/aes/aesni-x86_64.S
index 1d51d5b..5709a2d 100644
--- a/third_party/boringssl/linux-x86_64/crypto/aes/aesni-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/aes/aesni-x86_64.S
@@ -508,7 +508,7 @@
 	testl	%r8d,%r8d
 	jz	.Lecb_decrypt
 
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	.Lecb_enc_tail
 
 	movdqu	(%rdi),%xmm2
@@ -520,7 +520,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	.Lecb_enc_loop8_enter
 .align	16
 .Lecb_enc_loop8:
@@ -548,7 +548,7 @@
 
 	call	_aesni_encrypt8
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	.Lecb_enc_loop8
 
 	movups	%xmm2,(%rsi)
@@ -562,22 +562,22 @@
 	movups	%xmm8,96(%rsi)
 	movups	%xmm9,112(%rsi)
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	.Lecb_ret
 
 .Lecb_enc_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lecb_enc_one
 	movups	16(%rdi),%xmm3
 	je	.Lecb_enc_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lecb_enc_three
 	movups	48(%rdi),%xmm5
 	je	.Lecb_enc_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	.Lecb_enc_five
 	movups	80(%rdi),%xmm7
 	je	.Lecb_enc_six
@@ -651,7 +651,7 @@
 
 .align	16
 .Lecb_decrypt:
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	.Lecb_dec_tail
 
 	movdqu	(%rdi),%xmm2
@@ -663,7 +663,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	.Lecb_dec_loop8_enter
 .align	16
 .Lecb_dec_loop8:
@@ -692,7 +692,7 @@
 	call	_aesni_decrypt8
 
 	movups	(%r11),%xmm0
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	.Lecb_dec_loop8
 
 	movups	%xmm2,(%rsi)
@@ -714,22 +714,22 @@
 	movups	%xmm9,112(%rsi)
 	pxor	%xmm9,%xmm9
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	.Lecb_ret
 
 .Lecb_dec_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lecb_dec_one
 	movups	16(%rdi),%xmm3
 	je	.Lecb_dec_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lecb_dec_three
 	movups	48(%rdi),%xmm5
 	je	.Lecb_dec_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	.Lecb_dec_five
 	movups	80(%rdi),%xmm7
 	je	.Lecb_dec_six
@@ -1607,7 +1607,7 @@
 
 	movdqa	.Lxts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -1706,7 +1706,7 @@
 .byte	102,15,56,220,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	.Lxts_enc_loop6
 .align	32
 .Lxts_enc_loop6:
@@ -1845,13 +1845,13 @@
 	jz	.Lxts_enc_done
 
 	pxor	%xmm0,%xmm11
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lxts_enc_one
 	pxor	%xmm0,%xmm12
 	je	.Lxts_enc_two
 
 	pxor	%xmm0,%xmm13
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lxts_enc_three
 	pxor	%xmm0,%xmm14
 	je	.Lxts_enc_four
@@ -2079,7 +2079,7 @@
 
 	movdqa	.Lxts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -2178,7 +2178,7 @@
 .byte	102,15,56,222,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	.Lxts_dec_loop6
 .align	32
 .Lxts_dec_loop6:
@@ -2318,13 +2318,13 @@
 	jz	.Lxts_dec_done
 
 	pxor	%xmm0,%xmm12
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	.Lxts_dec_one
 	pxor	%xmm0,%xmm13
 	je	.Lxts_dec_two
 
 	pxor	%xmm0,%xmm14
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	.Lxts_dec_three
 	je	.Lxts_dec_four
 
@@ -2355,7 +2355,7 @@
 	pcmpgtd	%xmm15,%xmm14
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	pshufd	$19,%xmm14,%xmm11
+	pshufd	$0x13,%xmm14,%xmm11
 	andq	$15,%r9
 	jz	.Lxts_dec_ret
 
@@ -2645,7 +2645,7 @@
 	leaq	-8(%rax),%rbp
 	movups	(%r8),%xmm10
 	movl	%r10d,%eax
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	.Lcbc_dec_tail
 
 	movups	(%rcx),%xmm0
@@ -2661,14 +2661,14 @@
 	movdqu	80(%rdi),%xmm7
 	movdqa	%xmm6,%xmm15
 	movl	OPENSSL_ia32cap_P+4(%rip),%r9d
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	jbe	.Lcbc_dec_six_or_seven
 
 	andl	$71303168,%r9d
-	subq	$80,%rdx
+	subq	$0x50,%rdx
 	cmpl	$4194304,%r9d
 	je	.Lcbc_dec_loop6_enter
-	subq	$32,%rdx
+	subq	$0x20,%rdx
 	leaq	112(%rcx),%rcx
 	jmp	.Lcbc_dec_loop8_enter
 .align	16
@@ -2683,7 +2683,7 @@
 	movups	16-112(%rcx),%xmm1
 	pxor	%xmm0,%xmm4
 	xorq	%r11,%r11
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	pxor	%xmm0,%xmm5
 	pxor	%xmm0,%xmm6
 	pxor	%xmm0,%xmm7
@@ -2868,21 +2868,21 @@
 	movups	%xmm8,96(%rsi)
 	leaq	112(%rsi),%rsi
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	ja	.Lcbc_dec_loop8
 
 	movaps	%xmm9,%xmm2
 	leaq	-112(%rcx),%rcx
-	addq	$112,%rdx
+	addq	$0x70,%rdx
 	jle	.Lcbc_dec_clear_tail_collected
 	movups	%xmm9,(%rsi)
 	leaq	16(%rsi),%rsi
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	.Lcbc_dec_tail
 
 	movaps	%xmm11,%xmm2
 .Lcbc_dec_six_or_seven:
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	ja	.Lcbc_dec_seven
 
 	movaps	%xmm7,%xmm8
@@ -2975,33 +2975,33 @@
 	movl	%r10d,%eax
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	subq	$96,%rdx
+	subq	$0x60,%rdx
 	ja	.Lcbc_dec_loop6
 
 	movdqa	%xmm7,%xmm2
-	addq	$80,%rdx
+	addq	$0x50,%rdx
 	jle	.Lcbc_dec_clear_tail_collected
 	movups	%xmm7,(%rsi)
 	leaq	16(%rsi),%rsi
 
 .Lcbc_dec_tail:
 	movups	(%rdi),%xmm2
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_one
 
 	movups	16(%rdi),%xmm3
 	movaps	%xmm2,%xmm11
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_two
 
 	movups	32(%rdi),%xmm4
 	movaps	%xmm3,%xmm12
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_three
 
 	movups	48(%rdi),%xmm5
 	movaps	%xmm4,%xmm13
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	.Lcbc_dec_four
 
 	movups	64(%rdi),%xmm6
@@ -3026,7 +3026,7 @@
 	movdqa	%xmm6,%xmm2
 	pxor	%xmm6,%xmm6
 	pxor	%xmm7,%xmm7
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jmp	.Lcbc_dec_tail_collected
 
 .align	16
@@ -3345,7 +3345,7 @@
 	pslldq	$4,%xmm0
 	pxor	%xmm3,%xmm0
 
-	pshufd	$255,%xmm0,%xmm3
+	pshufd	$0xff,%xmm0,%xmm3
 	pxor	%xmm1,%xmm3
 	pslldq	$4,%xmm1
 	pxor	%xmm1,%xmm3
@@ -3432,7 +3432,7 @@
 	decl	%r10d
 	jz	.Ldone_key256
 
-	pshufd	$255,%xmm0,%xmm2
+	pshufd	$0xff,%xmm0,%xmm2
 	pxor	%xmm3,%xmm3
 .byte	102,15,56,221,211
 
diff --git a/third_party/boringssl/linux-x86_64/crypto/aes/bsaes-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/aes/bsaes-x86_64.S
index 8cfa4df..c5491ce4 100644
--- a/third_party/boringssl/linux-x86_64/crypto/aes/bsaes-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/aes/bsaes-x86_64.S
@@ -327,45 +327,45 @@
 	pxor	%xmm2,%xmm5
 	decl	%r10d
 	jl	.Lenc_done
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm3,%xmm9
+	pshufd	$0x93,%xmm3,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm5,%xmm10
+	pshufd	$0x93,%xmm5,%xmm10
 	pxor	%xmm9,%xmm3
-	pshufd	$147,%xmm2,%xmm11
+	pshufd	$0x93,%xmm2,%xmm11
 	pxor	%xmm10,%xmm5
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm2
-	pshufd	$147,%xmm1,%xmm13
+	pshufd	$0x93,%xmm1,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm1
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm2,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm5,%xmm11
-	pshufd	$78,%xmm2,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm7
 	pxor	%xmm1,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm3,%xmm10
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm1,%xmm5
+	pshufd	$0x4E,%xmm1,%xmm5
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm12,%xmm8
 	pxor	%xmm10,%xmm2
 	pxor	%xmm14,%xmm6
@@ -799,24 +799,24 @@
 	decl	%r10d
 	jl	.Ldec_done
 
-	pshufd	$78,%xmm15,%xmm7
-	pshufd	$78,%xmm2,%xmm13
+	pshufd	$0x4E,%xmm15,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm13
 	pxor	%xmm15,%xmm7
-	pshufd	$78,%xmm4,%xmm14
+	pshufd	$0x4E,%xmm4,%xmm14
 	pxor	%xmm2,%xmm13
-	pshufd	$78,%xmm0,%xmm8
+	pshufd	$0x4E,%xmm0,%xmm8
 	pxor	%xmm4,%xmm14
-	pshufd	$78,%xmm5,%xmm9
+	pshufd	$0x4E,%xmm5,%xmm9
 	pxor	%xmm0,%xmm8
-	pshufd	$78,%xmm3,%xmm10
+	pshufd	$0x4E,%xmm3,%xmm10
 	pxor	%xmm5,%xmm9
 	pxor	%xmm13,%xmm15
 	pxor	%xmm13,%xmm0
-	pshufd	$78,%xmm1,%xmm11
+	pshufd	$0x4E,%xmm1,%xmm11
 	pxor	%xmm3,%xmm10
 	pxor	%xmm7,%xmm5
 	pxor	%xmm8,%xmm3
-	pshufd	$78,%xmm6,%xmm12
+	pshufd	$0x4E,%xmm6,%xmm12
 	pxor	%xmm1,%xmm11
 	pxor	%xmm14,%xmm0
 	pxor	%xmm9,%xmm1
@@ -830,45 +830,45 @@
 	pxor	%xmm14,%xmm1
 	pxor	%xmm14,%xmm6
 	pxor	%xmm12,%xmm4
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm5,%xmm9
+	pshufd	$0x93,%xmm5,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm3,%xmm10
+	pshufd	$0x93,%xmm3,%xmm10
 	pxor	%xmm9,%xmm5
-	pshufd	$147,%xmm1,%xmm11
+	pshufd	$0x93,%xmm1,%xmm11
 	pxor	%xmm10,%xmm3
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm1
-	pshufd	$147,%xmm2,%xmm13
+	pshufd	$0x93,%xmm2,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm2
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm1,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm3,%xmm11
-	pshufd	$78,%xmm1,%xmm7
+	pshufd	$0x4E,%xmm1,%xmm7
 	pxor	%xmm2,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm5,%xmm10
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm2,%xmm3
+	pshufd	$0x4E,%xmm2,%xmm3
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm12,%xmm8
 	pxor	%xmm1,%xmm10
 	pxor	%xmm14,%xmm6
@@ -1559,20 +1559,20 @@
 	movdqa	%xmm7,(%rax)
 
 	andq	$-16,%r14
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	.Lxts_enc_short
 	jmp	.Lxts_enc_loop
 
 .align	16
 .Lxts_enc_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1580,7 +1580,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1589,7 +1589,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1599,7 +1599,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1609,7 +1609,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1619,7 +1619,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1629,7 +1629,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -1673,20 +1673,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	.Lxts_enc_loop
 
 .Lxts_enc_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	.Lxts_enc_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1694,7 +1694,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1705,7 +1705,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	.Lxts_enc_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1717,7 +1717,7 @@
 	cmpq	$32,%r14
 	je	.Lxts_enc_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1729,7 +1729,7 @@
 	cmpq	$48,%r14
 	je	.Lxts_enc_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1741,7 +1741,7 @@
 	cmpq	$64,%r14
 	je	.Lxts_enc_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1753,7 +1753,7 @@
 	cmpq	$80,%r14
 	je	.Lxts_enc_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2019,20 +2019,20 @@
 	shlq	$4,%rax
 	subq	%rax,%r14
 
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	.Lxts_dec_short
 	jmp	.Lxts_dec_loop
 
 .align	16
 .Lxts_dec_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2040,7 +2040,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2049,7 +2049,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2059,7 +2059,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2069,7 +2069,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2079,7 +2079,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2089,7 +2089,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2133,20 +2133,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	.Lxts_dec_loop
 
 .Lxts_dec_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	.Lxts_dec_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2154,7 +2154,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2165,7 +2165,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	.Lxts_dec_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2177,7 +2177,7 @@
 	cmpq	$32,%r14
 	je	.Lxts_dec_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2189,7 +2189,7 @@
 	cmpq	$48,%r14
 	je	.Lxts_dec_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2201,7 +2201,7 @@
 	cmpq	$64,%r14
 	je	.Lxts_dec_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2213,7 +2213,7 @@
 	cmpq	$80,%r14
 	je	.Lxts_dec_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2390,7 +2390,7 @@
 	pxor	%xmm14,%xmm14
 	movdqa	.Lxts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	movdqa	%xmm6,%xmm5
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
diff --git a/third_party/boringssl/linux-x86_64/crypto/aes/vpaes-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/aes/vpaes-x86_64.S
index 1d12424..4dfafa9 100644
--- a/third_party/boringssl/linux-x86_64/crypto/aes/vpaes-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/aes/vpaes-x86_64.S
@@ -61,7 +61,7 @@
 	addq	$16,%r11
 	pxor	%xmm0,%xmm3
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	subq	$1,%rax
 	pxor	%xmm3,%xmm0
 
@@ -121,10 +121,10 @@
 	pand	%xmm9,%xmm0
 .byte	102,15,56,0,208
 	movdqa	.Lk_dipt+16(%rip),%xmm0
-	xorq	$48,%r11
+	xorq	$0x30,%r11
 	leaq	.Lk_dsbd(%rip),%r10
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	pxor	%xmm5,%xmm2
 	movdqa	.Lk_mc_forward+48(%rip),%xmm5
 	pxor	%xmm2,%xmm0
@@ -243,7 +243,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	movdqu	%xmm3,(%rdx)
-	xorq	$48,%r8
+	xorq	$0x30,%r8
 
 .Lschedule_go:
 	cmpl	$192,%esi
@@ -333,7 +333,7 @@
 	call	_vpaes_schedule_mangle
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 	movdqa	%xmm7,%xmm5
 	movdqa	%xmm6,%xmm7
 	call	_vpaes_schedule_low_round
@@ -400,8 +400,8 @@
 .type	_vpaes_schedule_192_smear,@function
 .align	16
 _vpaes_schedule_192_smear:
-	pshufd	$128,%xmm6,%xmm1
-	pshufd	$254,%xmm7,%xmm0
+	pshufd	$0x80,%xmm6,%xmm1
+	pshufd	$0xFE,%xmm7,%xmm0
 	pxor	%xmm1,%xmm6
 	pxor	%xmm1,%xmm1
 	pxor	%xmm0,%xmm6
@@ -438,7 +438,7 @@
 	pxor	%xmm1,%xmm7
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 .byte	102,15,58,15,192,1
 
 
@@ -597,7 +597,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	addq	$-16,%r8
-	andq	$48,%r8
+	andq	$0x30,%r8
 	movdqu	%xmm3,(%rdx)
 	.byte	0xf3,0xc3
 .size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
@@ -616,7 +616,7 @@
 	movl	%eax,240(%rdx)
 
 	movl	$0,%ecx
-	movl	$48,%r8d
+	movl	$0x30,%r8d
 	call	_vpaes_schedule_core
 	xorl	%eax,%eax
 	.byte	0xf3,0xc3
diff --git a/third_party/boringssl/linux-x86_64/crypto/bn/rsaz-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/bn/rsaz-x86_64.S
index dd3d310..21531d1 100644
--- a/third_party/boringssl/linux-x86_64/crypto/bn/rsaz-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/bn/rsaz-x86_64.S
@@ -466,48 +466,94 @@
 	pushq	%r14
 	pushq	%r15
 
-	movl	%r9d,%r9d
-	subq	$128+24,%rsp
+	subq	$152,%rsp
 .Lmul_gather4_body:
-	movl	64(%rdx,%r9,4),%eax
-.byte	102,72,15,110,199
-	movl	(%rdx,%r9,4),%ebx
-.byte	102,72,15,110,201
-	movq	%r8,128(%rsp)
+	movd	%r9d,%xmm8
+	movdqa	.Linc+16(%rip),%xmm1
+	movdqa	.Linc(%rip),%xmm0
 
-	shlq	$32,%rax
-	orq	%rax,%rbx
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
+
+	movdqa	0(%rdx),%xmm8
+	movdqa	16(%rdx),%xmm9
+	movdqa	32(%rdx),%xmm10
+	movdqa	48(%rdx),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rdx),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rdx),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rdx),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rdx),%xmm15
+	leaq	128(%rdx),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
+	movq	%r8,128(%rsp)
+	movq	%rdi,128+8(%rsp)
+	movq	%rcx,128+16(%rsp)
+
 	movq	(%rsi),%rax
 	movq	8(%rsi),%rcx
-	leaq	128(%rdx,%r9,4),%rbp
 	mulq	%rbx
 	movq	%rax,(%rsp)
 	movq	%rcx,%rax
 	movq	%rdx,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r8
 	movq	16(%rsi),%rax
 	movq	%rdx,%r9
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r9
 	movq	24(%rsi),%rax
 	movq	%rdx,%r10
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r10
 	movq	32(%rsi),%rax
 	movq	%rdx,%r11
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r11
 	movq	40(%rsi),%rax
 	movq	%rdx,%r12
@@ -520,14 +566,12 @@
 	adcq	$0,%r13
 
 	mulq	%rbx
-	leaq	128(%rbp),%rbp
 	addq	%rax,%r13
 	movq	56(%rsi),%rax
 	movq	%rdx,%r14
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r14
 	movq	(%rsi),%rax
 	movq	%rdx,%r15
@@ -539,6 +583,35 @@
 
 .align	32
 .Loop_mul_gather:
+	movdqa	0(%rbp),%xmm8
+	movdqa	16(%rbp),%xmm9
+	movdqa	32(%rbp),%xmm10
+	movdqa	48(%rbp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rbp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rbp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rbp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rbp),%xmm15
+	leaq	128(%rbp),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
 	mulq	%rbx
 	addq	%rax,%r8
 	movq	8(%rsi),%rax
@@ -547,7 +620,6 @@
 	adcq	$0,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r9
 	movq	16(%rsi),%rax
 	adcq	$0,%rdx
@@ -556,7 +628,6 @@
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r10
 	movq	24(%rsi),%rax
 	adcq	$0,%rdx
@@ -565,7 +636,6 @@
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r11
 	movq	32(%rsi),%rax
 	adcq	$0,%rdx
@@ -574,7 +644,6 @@
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r12
 	movq	40(%rsi),%rax
 	adcq	$0,%rdx
@@ -599,7 +668,6 @@
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r15
 	movq	(%rsi),%rax
 	adcq	$0,%rdx
@@ -607,7 +675,6 @@
 	movq	%rdx,%r15
 	adcq	$0,%r15
 
-	leaq	128(%rbp),%rbp
 	leaq	8(%rdi),%rdi
 
 	decl	%ecx
@@ -622,8 +689,8 @@
 	movq	%r14,48(%rdi)
 	movq	%r15,56(%rdi)
 
-.byte	102,72,15,126,199
-.byte	102,72,15,126,205
+	movq	128+8(%rsp),%rdi
+	movq	128+16(%rsp),%rbp
 
 	movq	(%rsp),%r8
 	movq	8(%rsp),%r9
@@ -673,7 +740,7 @@
 	movl	%r9d,%r9d
 	subq	$128+24,%rsp
 .Lmul_scatter4_body:
-	leaq	(%r8,%r9,4),%r8
+	leaq	(%r8,%r9,8),%r8
 .byte	102,72,15,110,199
 .byte	102,72,15,110,202
 .byte	102,73,15,110,208
@@ -709,30 +776,14 @@
 
 	call	__rsaz_512_subtract
 
-	movl	%r8d,0(%rsi)
-	shrq	$32,%r8
-	movl	%r9d,128(%rsi)
-	shrq	$32,%r9
-	movl	%r10d,256(%rsi)
-	shrq	$32,%r10
-	movl	%r11d,384(%rsi)
-	shrq	$32,%r11
-	movl	%r12d,512(%rsi)
-	shrq	$32,%r12
-	movl	%r13d,640(%rsi)
-	shrq	$32,%r13
-	movl	%r14d,768(%rsi)
-	shrq	$32,%r14
-	movl	%r15d,896(%rsi)
-	shrq	$32,%r15
-	movl	%r8d,64(%rsi)
-	movl	%r9d,192(%rsi)
-	movl	%r10d,320(%rsi)
-	movl	%r11d,448(%rsi)
-	movl	%r12d,576(%rsi)
-	movl	%r13d,704(%rsi)
-	movl	%r14d,832(%rsi)
-	movl	%r15d,960(%rsi)
+	movq	%r8,0(%rsi)
+	movq	%r9,128(%rsi)
+	movq	%r10,256(%rsi)
+	movq	%r11,384(%rsi)
+	movq	%r12,512(%rsi)
+	movq	%r13,640(%rsi)
+	movq	%r14,768(%rsi)
+	movq	%r15,896(%rsi)
 
 	leaq	128+24+48(%rsp),%rax
 	movq	-48(%rax),%r15
@@ -1087,16 +1138,14 @@
 .type	rsaz_512_scatter4,@function
 .align	16
 rsaz_512_scatter4:
-	leaq	(%rdi,%rdx,4),%rdi
+	leaq	(%rdi,%rdx,8),%rdi
 	movl	$8,%r9d
 	jmp	.Loop_scatter
 .align	16
 .Loop_scatter:
 	movq	(%rsi),%rax
 	leaq	8(%rsi),%rsi
-	movl	%eax,(%rdi)
-	shrq	$32,%rax
-	movl	%eax,64(%rdi)
+	movq	%rax,(%rdi)
 	leaq	128(%rdi),%rdi
 	decl	%r9d
 	jnz	.Loop_scatter
@@ -1108,20 +1157,73 @@
 .type	rsaz_512_gather4,@function
 .align	16
 rsaz_512_gather4:
-	leaq	(%rsi,%rdx,4),%rsi
+	movd	%edx,%xmm8
+	movdqa	.Linc+16(%rip),%xmm1
+	movdqa	.Linc(%rip),%xmm0
+
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
 	movl	$8,%r9d
 	jmp	.Loop_gather
 .align	16
 .Loop_gather:
-	movl	(%rsi),%eax
-	movl	64(%rsi),%r8d
+	movdqa	0(%rsi),%xmm8
+	movdqa	16(%rsi),%xmm9
+	movdqa	32(%rsi),%xmm10
+	movdqa	48(%rsi),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rsi),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rsi),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rsi),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rsi),%xmm15
 	leaq	128(%rsi),%rsi
-	shlq	$32,%r8
-	orq	%r8,%rax
-	movq	%rax,(%rdi)
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+	movq	%xmm8,(%rdi)
 	leaq	8(%rdi),%rdi
 	decl	%r9d
 	jnz	.Loop_gather
 	.byte	0xf3,0xc3
+.LSEH_end_rsaz_512_gather4:
 .size	rsaz_512_gather4,.-rsaz_512_gather4
+
+.align	64
+.Linc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 #endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont.S b/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont.S
index 4d401c6..83926ad 100644
--- a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont.S
+++ b/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont.S
@@ -636,20 +636,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,4),%r11
+	leaq	-64(%rsp,%r9,2),%r11
 	movq	(%r8),%r8
 	subq	%rsi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lsqr8x_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	-64(%rsp,%r9,2),%rsp
 	jmp	.Lsqr8x_sp_done
 
 .align	32
 .Lsqr8x_sp_alt:
-	leaq	4096-64(,%r9,4),%r10
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	4096-64(,%r9,2),%r10
+	leaq	-64(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -659,58 +659,80 @@
 	movq	%r9,%r10
 	negq	%r9
 
-	leaq	64(%rsp,%r9,2),%r11
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 .Lsqr8x_body:
 
-	movq	%r9,%rbp
-.byte	102,73,15,110,211
-	shrq	$3+2,%rbp
-	movl	OPENSSL_ia32cap_P+8(%rip),%eax
-	jmp	.Lsqr8x_copy_n
-
-.align	32
-.Lsqr8x_copy_n:
-	movq	0(%rcx),%xmm0
-	movq	8(%rcx),%xmm1
-	movq	16(%rcx),%xmm3
-	movq	24(%rcx),%xmm4
-	leaq	32(%rcx),%rcx
-	movdqa	%xmm0,0(%r11)
-	movdqa	%xmm1,16(%r11)
-	movdqa	%xmm3,32(%r11)
-	movdqa	%xmm4,48(%r11)
-	leaq	64(%r11),%r11
-	decq	%rbp
-	jnz	.Lsqr8x_copy_n
-
+.byte	102,72,15,110,209
 	pxor	%xmm0,%xmm0
 .byte	102,72,15,110,207
 .byte	102,73,15,110,218
 	call	bn_sqr8x_internal
 
-	pxor	%xmm0,%xmm0
-	leaq	48(%rsp),%rax
-	leaq	64(%rsp,%r9,2),%rdx
-	shrq	$3+2,%r9
-	movq	40(%rsp),%rsi
-	jmp	.Lsqr8x_zero
+
+
+
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+	movq	%r9,%rdx
+.byte	102,72,15,126,207
+	sarq	$3+2,%rcx
+	jmp	.Lsqr8x_sub
 
 .align	32
-.Lsqr8x_zero:
-	movdqa	%xmm0,0(%rax)
-	movdqa	%xmm0,16(%rax)
-	movdqa	%xmm0,32(%rax)
-	movdqa	%xmm0,48(%rax)
-	leaq	64(%rax),%rax
-	movdqa	%xmm0,0(%rdx)
-	movdqa	%xmm0,16(%rdx)
-	movdqa	%xmm0,32(%rdx)
-	movdqa	%xmm0,48(%rdx)
-	leaq	64(%rdx),%rdx
-	decq	%r9
-	jnz	.Lsqr8x_zero
+.Lsqr8x_sub:
+	movq	0(%rbx),%r12
+	movq	8(%rbx),%r13
+	movq	16(%rbx),%r14
+	movq	24(%rbx),%r15
+	leaq	32(%rbx),%rbx
+	sbbq	0(%rbp),%r12
+	sbbq	8(%rbp),%r13
+	sbbq	16(%rbp),%r14
+	sbbq	24(%rbp),%r15
+	leaq	32(%rbp),%rbp
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+	leaq	32(%rdi),%rdi
+	incq	%rcx
+	jnz	.Lsqr8x_sub
+
+	sbbq	$0,%rax
+	leaq	(%rbx,%r9,1),%rbx
+	leaq	(%rdi,%r9,1),%rdi
+
+.byte	102,72,15,110,200
+	pxor	%xmm0,%xmm0
+	pshufd	$0,%xmm1,%xmm1
+	movq	40(%rsp),%rsi
+	jmp	.Lsqr8x_cond_copy
+
+.align	32
+.Lsqr8x_cond_copy:
+	movdqa	0(%rbx),%xmm2
+	movdqa	16(%rbx),%xmm3
+	leaq	32(%rbx),%rbx
+	movdqu	0(%rdi),%xmm4
+	movdqu	16(%rdi),%xmm5
+	leaq	32(%rdi),%rdi
+	movdqa	%xmm0,-32(%rbx)
+	movdqa	%xmm0,-16(%rbx)
+	movdqa	%xmm0,-32(%rbx,%rdx,1)
+	movdqa	%xmm0,-16(%rbx,%rdx,1)
+	pcmpeqd	%xmm1,%xmm0
+	pand	%xmm1,%xmm2
+	pand	%xmm1,%xmm3
+	pand	%xmm0,%xmm4
+	pand	%xmm0,%xmm5
+	pxor	%xmm0,%xmm0
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqu	%xmm4,-32(%rdi)
+	movdqu	%xmm5,-16(%rdi)
+	addq	$32,%r9
+	jnz	.Lsqr8x_cond_copy
 
 	movq	$1,%rax
 	movq	-48(%rsi),%r15
diff --git a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S b/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S
index 02edc69..554df1f 100644
--- a/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S
+++ b/third_party/boringssl/linux-x86_64/crypto/bn/x86_64-mont5.S
@@ -17,46 +17,151 @@
 .Lmul_enter:
 	movl	%r9d,%r9d
 	movq	%rsp,%rax
-	movl	8(%rsp),%r10d
+	movd	8(%rsp),%xmm5
+	leaq	.Linc(%rip),%r10
 	pushq	%rbx
 	pushq	%rbp
 	pushq	%r12
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 	leaq	2(%r9),%r11
 	negq	%r11
-	leaq	(%rsp,%r11,8),%rsp
+	leaq	-264(%rsp,%r11,8),%rsp
 	andq	$-1024,%rsp
 
 	movq	%rax,8(%rsp,%r9,8)
 .Lmul_body:
-	movq	%rdx,%r12
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	.Lmagic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%r12,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
+	leaq	128(%rdx),%r12
+	movdqa	0(%r10),%xmm0
+	movdqa	16(%r10),%xmm1
+	leaq	24-112(%rsp,%r9,8),%r10
+	andq	$-16,%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+.byte	0x67
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
+.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
 	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 .byte	102,72,15,126,195
 
 	movq	(%r8),%r8
@@ -65,29 +170,14 @@
 	xorq	%r14,%r14
 	xorq	%r15,%r15
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	movq	%r8,%rbp
 	mulq	%rbx
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -120,14 +210,12 @@
 	cmpq	%r9,%r15
 	jne	.L1st
 
-.byte	102,72,15,126,195
 
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r13
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 	movq	%r10,%r11
 
@@ -141,33 +229,78 @@
 	jmp	.Louter
 .align	16
 .Louter:
+	leaq	24+128(%rsp,%r9,8),%rdx
+	andq	$-16,%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+
+	movq	(%rsi),%rax
+.byte	102,72,15,126,195
+
 	xorq	%r15,%r15
 	movq	%r8,%rbp
 	movq	(%rsp),%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	mulq	%rbx
 	addq	%rax,%r10
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -203,15 +336,12 @@
 	cmpq	%r9,%r15
 	jne	.Linner
 
-.byte	102,72,15,126,195
-
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r13
-	movq	(%rsp,%r15,8),%r10
+	movq	(%rsp,%r9,8),%r10
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 
 	xorq	%rdx,%rdx
@@ -257,6 +387,7 @@
 
 	movq	8(%rsp,%r9,8),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -279,10 +410,10 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 .byte	0x67
-	movl	%r9d,%r10d
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 
 
@@ -292,19 +423,21 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lmul4xsp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	.Lmul4xsp_done
 
 .align	32
 .Lmul4xsp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -320,6 +453,7 @@
 
 	movq	40(%rsp),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -335,47 +469,141 @@
 .align	32
 mul4x_internal:
 	shlq	$5,%r9
-	movl	8(%rax),%r10d
-	leaq	256(%rdx,%r9,1),%r13
+	movd	8(%rax),%xmm5
+	leaq	.Linc(%rip),%rax
+	leaq	128(%rdx,%r9,1),%r13
 	shrq	$5,%r9
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	.Lmagic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%rdx,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	addq	$7,%r11
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
-	andq	$7,%r11
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	88-112(%rsp,%r9,1),%r10
+	leaq	128(%rdx),%r12
 
-	movq	-96(%r12),%xmm0
-	leaq	256(%r12),%r14
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+.byte	0x67,0x67
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
 .byte	0x67
-	por	%xmm1,%xmm0
-	movq	-96(%r14),%xmm1
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
 .byte	0x67
-	pand	%xmm7,%xmm3
-.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
-	movq	-32(%r14),%xmm2
-.byte	0x67
-	pand	%xmm4,%xmm1
-.byte	0x67
-	por	%xmm3,%xmm0
-	movq	32(%r14),%xmm3
-
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
+	leaq	256(%r12),%r12
 .byte	102,72,15,126,195
-	movq	96(%r14),%xmm0
+
 	movq	%r13,16+8(%rsp)
 	movq	%rdi,56+8(%rsp)
 
@@ -389,26 +617,10 @@
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	pand	%xmm5,%xmm2
-	pand	%xmm6,%xmm3
-	por	%xmm2,%xmm1
-
 	imulq	%r10,%rbp
-
-
-
-
-
-
-
-	leaq	64+8(%rsp,%r11,8),%r14
+	leaq	64+8(%rsp),%r14
 	movq	%rdx,%r11
 
-	pand	%xmm7,%xmm0
-	por	%xmm3,%xmm1
-	leaq	512(%r12),%r12
-	por	%xmm1,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi,%r9,1),%rax
@@ -417,7 +629,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -427,7 +639,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -437,7 +649,7 @@
 .L1st4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -453,7 +665,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -483,7 +695,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -492,7 +704,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -502,7 +714,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -518,7 +730,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -531,8 +743,7 @@
 	movq	%rdi,-16(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -543,6 +754,63 @@
 
 .align	32
 .Louter4x:
+	leaq	16+128(%r14),%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+.byte	102,72,15,126,195
+
 	movq	(%r14,%r9,1),%r10
 	movq	%r8,%rbp
 	mulq	%rbx
@@ -550,25 +818,11 @@
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-
 	imulq	%r10,%rbp
-.byte	0x67
 	movq	%rdx,%r11
 	movq	%rdi,(%r14)
 
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-	por	%xmm2,%xmm0
 	leaq	(%r14,%r9,1),%r14
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
 
 	mulq	%rbp
 	addq	%rax,%r10
@@ -578,7 +832,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -590,7 +844,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdx,%r13
 	jmp	.Linner4x
@@ -599,7 +853,7 @@
 .Linner4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -617,7 +871,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -651,7 +905,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -662,7 +916,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%r13,-8(%r14)
 	movq	%rdx,%r13
@@ -672,7 +926,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -691,7 +945,7 @@
 	mulq	%rbx
 	addq	%rax,%r11
 	movq	%rbp,%rax
-	movq	-16(%rcx),%rbp
+	movq	-8(%rcx),%rbp
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -706,9 +960,8 @@
 	movq	%r13,-24(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
 	movq	%rdi,-16(%r14)
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -719,16 +972,23 @@
 
 	cmpq	16+8(%rsp),%r12
 	jb	.Louter4x
+	xorq	%rax,%rax
 	subq	%r13,%rbp
 	adcq	%r15,%r15
 	orq	%r15,%rdi
-	xorq	$1,%rdi
+	subq	%rdi,%rax
 	leaq	(%r14,%r9,1),%rbx
-	leaq	(%rcx,%rdi,8),%rbp
+	movq	(%rcx),%r12
+	leaq	(%rcx),%rbp
 	movq	%r9,%rcx
 	sarq	$3+2,%rcx
 	movq	56+8(%rsp),%rdi
-	jmp	.Lsqr4x_sub
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	.Lsqr4x_sub_entry
 .size	mul4x_internal,.-mul4x_internal
 .globl	bn_power5
 .hidden bn_power5
@@ -742,9 +1002,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leal	(%r9,%r9,2),%r10d
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -754,19 +1014,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lpwr_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	.Lpwr_sp_done
 
 .align	32
 .Lpwr_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -794,10 +1055,15 @@
 .byte	102,72,15,110,226
 
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 
 .byte	102,72,15,126,209
 .byte	102,72,15,126,226
@@ -1342,9 +1608,9 @@
 	movq	%rbx,-16(%rdi)
 	movq	%r8,-8(%rdi)
 .byte	102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
 	xorq	%rax,%rax
-	leaq	(%rbp,%r9,2),%rcx
+	leaq	(%r9,%rbp,1),%rcx
 	leaq	48+8(%rsp,%r9,2),%rdx
 	movq	%rcx,0+8(%rsp)
 	leaq	48+8(%rsp,%r9,1),%rdi
@@ -1377,14 +1643,14 @@
 .align	32
 .L8x_reduce:
 	mulq	%rbx
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	negq	%r8
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	movq	%rbx,48-8+8(%rsp,%rcx,8)
@@ -1393,7 +1659,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	32+8(%rsp),%rsi
@@ -1402,7 +1668,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	imulq	%r8,%rsi
 	addq	%r11,%r10
@@ -1411,7 +1677,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1419,7 +1685,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1427,7 +1693,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1445,7 +1711,7 @@
 	decl	%ecx
 	jnz	.L8x_reduce
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	xorq	%rax,%rax
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
@@ -1471,14 +1737,14 @@
 .L8x_tail:
 	mulq	%rbx
 	addq	%rax,%r8
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	movq	%r8,(%rdi)
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	leaq	8(%rdi),%rdi
@@ -1487,7 +1753,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	%rdx,%r10
@@ -1495,7 +1761,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r10
 	movq	%rdx,%r11
@@ -1503,7 +1769,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1511,7 +1777,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1519,7 +1785,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1537,7 +1803,7 @@
 	decl	%ecx
 	jnz	.L8x_tail
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
 	jae	.L8x_tail_done
@@ -1561,6 +1827,15 @@
 .align	32
 .L8x_tail_done:
 	addq	(%rdx),%r8
+	adcq	$0,%r9
+	adcq	$0,%r10
+	adcq	$0,%r11
+	adcq	$0,%r12
+	adcq	$0,%r13
+	adcq	$0,%r14
+	adcq	$0,%r15
+
+
 	xorq	%rax,%rax
 
 	negq	%rsi
@@ -1574,7 +1849,7 @@
 	adcq	48(%rdi),%r14
 	adcq	56(%rdi),%r15
 	adcq	$0,%rax
-	movq	-16(%rbp),%rcx
+	movq	-8(%rbp),%rcx
 	xorq	%rsi,%rsi
 
 .byte	102,72,15,126,213
@@ -1592,44 +1867,62 @@
 
 	cmpq	%rdx,%rdi
 	jb	.L8x_reduction_loop
-
-	subq	%r15,%rcx
-	leaq	(%rdi,%r9,1),%rbx
-	adcq	%rsi,%rsi
-	movq	%r9,%rcx
-	orq	%rsi,%rax
-.byte	102,72,15,126,207
-	xorq	$1,%rax
-.byte	102,72,15,126,206
-	leaq	(%rbp,%rax,8),%rbp
-	sarq	$3+2,%rcx
-	jmp	.Lsqr4x_sub
-
+	.byte	0xf3,0xc3
+.size	bn_sqr8x_internal,.-bn_sqr8x_internal
+.type	__bn_post4x_internal,@function
 .align	32
+__bn_post4x_internal:
+	movq	0(%rbp),%r12
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+.byte	102,72,15,126,207
+	negq	%rax
+.byte	102,72,15,126,206
+	sarq	$3+2,%rcx
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	.Lsqr4x_sub_entry
+
+.align	16
 .Lsqr4x_sub:
-.byte	0x66
-	movq	0(%rbx),%r12
-	movq	8(%rbx),%r13
-	sbbq	0(%rbp),%r12
-	movq	16(%rbx),%r14
-	sbbq	16(%rbp),%r13
-	movq	24(%rbx),%r15
-	leaq	32(%rbx),%rbx
-	sbbq	32(%rbp),%r14
+	movq	0(%rbp),%r12
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+.Lsqr4x_sub_entry:
+	leaq	32(%rbp),%rbp
+	notq	%r12
+	notq	%r13
+	notq	%r14
+	notq	%r15
+	andq	%rax,%r12
+	andq	%rax,%r13
+	andq	%rax,%r14
+	andq	%rax,%r15
+
+	negq	%r10
+	adcq	0(%rbx),%r12
+	adcq	8(%rbx),%r13
+	adcq	16(%rbx),%r14
+	adcq	24(%rbx),%r15
 	movq	%r12,0(%rdi)
-	sbbq	48(%rbp),%r15
-	leaq	64(%rbp),%rbp
+	leaq	32(%rbx),%rbx
 	movq	%r13,8(%rdi)
+	sbbq	%r10,%r10
 	movq	%r14,16(%rdi)
 	movq	%r15,24(%rdi)
 	leaq	32(%rdi),%rdi
 
 	incq	%rcx
 	jnz	.Lsqr4x_sub
+
 	movq	%r9,%r10
 	negq	%r9
 	.byte	0xf3,0xc3
-.size	bn_sqr8x_internal,.-bn_sqr8x_internal
+.size	__bn_post4x_internal,.-__bn_post4x_internal
 .globl	bn_from_montgomery
 .hidden bn_from_montgomery
 .type	bn_from_montgomery,@function
@@ -1652,10 +1945,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-.byte	0x67
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -1665,19 +1957,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	.Lfrom_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	.Lfrom_sp_done
 
 .align	32
 .Lfrom_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -1728,7 +2021,8 @@
 .byte	0x67
 	movq	%rcx,%rbp
 .byte	102,73,15,110,218
-	call	sqr8x_reduction
+	call	__bn_sqr8x_reduction
+	call	__bn_post4x_internal
 
 	pxor	%xmm0,%xmm0
 	leaq	48(%rsp),%rax
@@ -1778,46 +2072,170 @@
 .globl	bn_gather5
 .hidden bn_gather5
 .type	bn_gather5,@function
-.align	16
+.align	32
 bn_gather5:
-	movl	%ecx,%r11d
-	shrl	$3,%ecx
-	andq	$7,%r11
-	notl	%ecx
-	leaq	.Lmagic_masks(%rip),%rax
-	andl	$3,%ecx
-	leaq	128(%rdx,%r11,8),%rdx
-	movq	0(%rax,%rcx,8),%xmm4
-	movq	8(%rax,%rcx,8),%xmm5
-	movq	16(%rax,%rcx,8),%xmm6
-	movq	24(%rax,%rcx,8),%xmm7
-	jmp	.Lgather
-.align	16
-.Lgather:
-	movq	-128(%rdx),%xmm0
-	movq	-64(%rdx),%xmm1
-	pand	%xmm4,%xmm0
-	movq	0(%rdx),%xmm2
-	pand	%xmm5,%xmm1
-	movq	64(%rdx),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-.byte	0x67,0x67
-	por	%xmm2,%xmm0
-	leaq	256(%rdx),%rdx
-	por	%xmm3,%xmm0
+.LSEH_begin_bn_gather5:
 
+.byte	0x4c,0x8d,0x14,0x24
+.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00
+	leaq	.Linc(%rip),%rax
+	andq	$-16,%rsp
+
+	movd	%ecx,%xmm5
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	128(%rdx),%r11
+	leaq	128(%rsp),%rax
+
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-128(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-112(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-96(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-80(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-48(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-16(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,16(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,48(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,80(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,96(%rax)
+	movdqa	%xmm4,%xmm2
+	movdqa	%xmm3,112(%rax)
+	jmp	.Lgather
+
+.align	32
+.Lgather:
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r11),%xmm0
+	movdqa	-112(%r11),%xmm1
+	movdqa	-96(%r11),%xmm2
+	pand	-128(%rax),%xmm0
+	movdqa	-80(%r11),%xmm3
+	pand	-112(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r11),%xmm0
+	movdqa	-48(%r11),%xmm1
+	movdqa	-32(%r11),%xmm2
+	pand	-64(%rax),%xmm0
+	movdqa	-16(%r11),%xmm3
+	pand	-48(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r11),%xmm0
+	movdqa	16(%r11),%xmm1
+	movdqa	32(%r11),%xmm2
+	pand	0(%rax),%xmm0
+	movdqa	48(%r11),%xmm3
+	pand	16(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r11),%xmm0
+	movdqa	80(%r11),%xmm1
+	movdqa	96(%r11),%xmm2
+	pand	64(%rax),%xmm0
+	movdqa	112(%r11),%xmm3
+	pand	80(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	leaq	256(%r11),%r11
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
 	movq	%xmm0,(%rdi)
 	leaq	8(%rdi),%rdi
 	subl	$1,%esi
 	jnz	.Lgather
+
+	leaq	(%r10),%rsp
 	.byte	0xf3,0xc3
 .LSEH_end_bn_gather5:
 .size	bn_gather5,.-bn_gather5
 .align	64
-.Lmagic_masks:
-.long	0,0, 0,0, 0,0, -1,-1
-.long	0,0, 0,0, 0,0,  0,0
+.Linc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 .byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 #endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/chacha/chacha-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/chacha/chacha-x86_64.S
new file mode 100644
index 0000000..e994940
--- /dev/null
+++ b/third_party/boringssl/linux-x86_64/crypto/chacha/chacha-x86_64.S
@@ -0,0 +1,1585 @@
+#if defined(__x86_64__)
+.text	
+
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
+
+.align	64
+.Lzero:
+.long	0,0,0,0
+.Lone:
+.long	1,0,0,0
+.Linc:
+.long	0,1,2,3
+.Lfour:
+.long	4,4,4,4
+.Lincy:
+.long	0,2,4,6,1,3,5,7
+.Leight:
+.long	8,8,8,8,8,8,8,8
+.Lrot16:
+.byte	0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+.Lrot24:
+.byte	0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+.Lsigma:
+.byte	101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.globl	ChaCha20_ctr32
+.hidden ChaCha20_ctr32
+.type	ChaCha20_ctr32,@function
+.align	64
+ChaCha20_ctr32:
+	cmpq	$0,%rdx
+	je	.Lno_data
+	movq	OPENSSL_ia32cap_P+4(%rip),%r10
+	testl	$512,%r10d
+	jnz	.LChaCha20_ssse3
+
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$64+24,%rsp
+
+
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	.Lone(%rip),%xmm4
+
+
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movq	%rdx,%rbp
+	jmp	.Loop_outer
+
+.align	32
+.Loop_outer:
+	movl	$0x61707865,%eax
+	movl	$0x3320646e,%ebx
+	movl	$0x79622d32,%ecx
+	movl	$0x6b206574,%edx
+	movl	16(%rsp),%r8d
+	movl	20(%rsp),%r9d
+	movl	24(%rsp),%r10d
+	movl	28(%rsp),%r11d
+	movd	%xmm3,%r12d
+	movl	52(%rsp),%r13d
+	movl	56(%rsp),%r14d
+	movl	60(%rsp),%r15d
+
+	movq	%rbp,64+0(%rsp)
+	movl	$10,%ebp
+	movq	%rsi,64+8(%rsp)
+.byte	102,72,15,126,214
+	movq	%rdi,64+16(%rsp)
+	movq	%rsi,%rdi
+	shrq	$32,%rdi
+	jmp	.Loop
+
+.align	32
+.Loop:
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$16,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$16,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$12,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$12,%r9d
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$8,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$8,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$7,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$7,%r9d
+	movl	%esi,32(%rsp)
+	movl	%edi,36(%rsp)
+	movl	40(%rsp),%esi
+	movl	44(%rsp),%edi
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$16,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$16,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$12,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$12,%r11d
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$8,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$8,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$7,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$7,%r11d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$16,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$16,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$12,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$12,%r10d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$8,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$8,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$7,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$7,%r10d
+	movl	%esi,40(%rsp)
+	movl	%edi,44(%rsp)
+	movl	32(%rsp),%esi
+	movl	36(%rsp),%edi
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$16,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$16,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$12,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$12,%r8d
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$8,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$8,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$7,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$7,%r8d
+	decl	%ebp
+	jnz	.Loop
+	movl	%edi,36(%rsp)
+	movl	%esi,32(%rsp)
+	movq	64(%rsp),%rbp
+	movdqa	%xmm2,%xmm1
+	movq	64+8(%rsp),%rsi
+	paddd	%xmm4,%xmm3
+	movq	64+16(%rsp),%rdi
+
+	addl	$0x61707865,%eax
+	addl	$0x3320646e,%ebx
+	addl	$0x79622d32,%ecx
+	addl	$0x6b206574,%edx
+	addl	16(%rsp),%r8d
+	addl	20(%rsp),%r9d
+	addl	24(%rsp),%r10d
+	addl	28(%rsp),%r11d
+	addl	48(%rsp),%r12d
+	addl	52(%rsp),%r13d
+	addl	56(%rsp),%r14d
+	addl	60(%rsp),%r15d
+	paddd	32(%rsp),%xmm1
+
+	cmpq	$64,%rbp
+	jb	.Ltail
+
+	xorl	0(%rsi),%eax
+	xorl	4(%rsi),%ebx
+	xorl	8(%rsi),%ecx
+	xorl	12(%rsi),%edx
+	xorl	16(%rsi),%r8d
+	xorl	20(%rsi),%r9d
+	xorl	24(%rsi),%r10d
+	xorl	28(%rsi),%r11d
+	movdqu	32(%rsi),%xmm0
+	xorl	48(%rsi),%r12d
+	xorl	52(%rsi),%r13d
+	xorl	56(%rsi),%r14d
+	xorl	60(%rsi),%r15d
+	leaq	64(%rsi),%rsi
+	pxor	%xmm1,%xmm0
+
+	movdqa	%xmm2,32(%rsp)
+	movd	%xmm3,48(%rsp)
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	movdqu	%xmm0,32(%rdi)
+	movl	%r12d,48(%rdi)
+	movl	%r13d,52(%rdi)
+	movl	%r14d,56(%rdi)
+	movl	%r15d,60(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rbp
+	jnz	.Loop_outer
+
+	jmp	.Ldone
+
+.align	16
+.Ltail:
+	movl	%eax,0(%rsp)
+	movl	%ebx,4(%rsp)
+	xorq	%rbx,%rbx
+	movl	%ecx,8(%rsp)
+	movl	%edx,12(%rsp)
+	movl	%r8d,16(%rsp)
+	movl	%r9d,20(%rsp)
+	movl	%r10d,24(%rsp)
+	movl	%r11d,28(%rsp)
+	movdqa	%xmm1,32(%rsp)
+	movl	%r12d,48(%rsp)
+	movl	%r13d,52(%rsp)
+	movl	%r14d,56(%rsp)
+	movl	%r15d,60(%rsp)
+
+.Loop_tail:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%edx
+	leaq	1(%rbx),%rbx
+	xorl	%edx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rbp
+	jnz	.Loop_tail
+
+.Ldone:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+.Lno_data:
+	.byte	0xf3,0xc3
+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
+.type	ChaCha20_ssse3,@function
+.align	32
+ChaCha20_ssse3:
+.LChaCha20_ssse3:
+	cmpq	$128,%rdx
+	ja	.LChaCha20_4x
+
+.Ldo_sse3_after_all:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	subq	$64+24,%rsp
+	movdqa	.Lsigma(%rip),%xmm0
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	.Lrot16(%rip),%xmm6
+	movdqa	.Lrot24(%rip),%xmm7
+
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movl	$10,%ebp
+	jmp	.Loop_ssse3
+
+.align	32
+.Loop_outer_ssse3:
+	movdqa	.Lone(%rip),%xmm3
+	movdqa	0(%rsp),%xmm0
+	movdqa	16(%rsp),%xmm1
+	movdqa	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+	movl	$10,%ebp
+	movdqa	%xmm3,48(%rsp)
+	jmp	.Loop_ssse3
+
+.align	32
+.Loop_ssse3:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%ebp
+	jnz	.Loop_ssse3
+	paddd	0(%rsp),%xmm0
+	paddd	16(%rsp),%xmm1
+	paddd	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+
+	cmpq	$64,%rdx
+	jb	.Ltail_ssse3
+
+	movdqu	0(%rsi),%xmm4
+	movdqu	16(%rsi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%rsi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%rsi),%xmm5
+	leaq	64(%rsi),%rsi
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+
+	movdqu	%xmm0,0(%rdi)
+	movdqu	%xmm1,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rdx
+	jnz	.Loop_outer_ssse3
+
+	jmp	.Ldone_ssse3
+
+.align	16
+.Ltail_ssse3:
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	xorq	%rbx,%rbx
+
+.Loop_tail_ssse3:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%ecx
+	leaq	1(%rbx),%rbx
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rdx
+	jnz	.Loop_tail_ssse3
+
+.Ldone_ssse3:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+	.byte	0xf3,0xc3
+.size	ChaCha20_ssse3,.-ChaCha20_ssse3
+.type	ChaCha20_4x,@function
+.align	32
+ChaCha20_4x:
+.LChaCha20_4x:
+	movq	%r10,%r11
+	shrq	$32,%r10
+	testq	$32,%r10
+	jnz	.LChaCha20_8x
+	cmpq	$192,%rdx
+	ja	.Lproceed4x
+
+	andq	$71303168,%r11
+	cmpq	$4194304,%r11
+	je	.Ldo_sse3_after_all
+
+.Lproceed4x:
+	leaq	-120(%rsp),%r11
+	subq	$0x148+0,%rsp
+	movdqa	.Lsigma(%rip),%xmm11
+	movdqu	(%rcx),%xmm15
+	movdqu	16(%rcx),%xmm7
+	movdqu	(%r8),%xmm3
+	leaq	256(%rsp),%rcx
+	leaq	.Lrot16(%rip),%r10
+	leaq	.Lrot24(%rip),%r11
+
+	pshufd	$0x00,%xmm11,%xmm8
+	pshufd	$0x55,%xmm11,%xmm9
+	movdqa	%xmm8,64(%rsp)
+	pshufd	$0xaa,%xmm11,%xmm10
+	movdqa	%xmm9,80(%rsp)
+	pshufd	$0xff,%xmm11,%xmm11
+	movdqa	%xmm10,96(%rsp)
+	movdqa	%xmm11,112(%rsp)
+
+	pshufd	$0x00,%xmm15,%xmm12
+	pshufd	$0x55,%xmm15,%xmm13
+	movdqa	%xmm12,128-256(%rcx)
+	pshufd	$0xaa,%xmm15,%xmm14
+	movdqa	%xmm13,144-256(%rcx)
+	pshufd	$0xff,%xmm15,%xmm15
+	movdqa	%xmm14,160-256(%rcx)
+	movdqa	%xmm15,176-256(%rcx)
+
+	pshufd	$0x00,%xmm7,%xmm4
+	pshufd	$0x55,%xmm7,%xmm5
+	movdqa	%xmm4,192-256(%rcx)
+	pshufd	$0xaa,%xmm7,%xmm6
+	movdqa	%xmm5,208-256(%rcx)
+	pshufd	$0xff,%xmm7,%xmm7
+	movdqa	%xmm6,224-256(%rcx)
+	movdqa	%xmm7,240-256(%rcx)
+
+	pshufd	$0x00,%xmm3,%xmm0
+	pshufd	$0x55,%xmm3,%xmm1
+	paddd	.Linc(%rip),%xmm0
+	pshufd	$0xaa,%xmm3,%xmm2
+	movdqa	%xmm1,272-256(%rcx)
+	pshufd	$0xff,%xmm3,%xmm3
+	movdqa	%xmm2,288-256(%rcx)
+	movdqa	%xmm3,304-256(%rcx)
+
+	jmp	.Loop_enter4x
+
+.align	32
+.Loop_outer4x:
+	movdqa	64(%rsp),%xmm8
+	movdqa	80(%rsp),%xmm9
+	movdqa	96(%rsp),%xmm10
+	movdqa	112(%rsp),%xmm11
+	movdqa	128-256(%rcx),%xmm12
+	movdqa	144-256(%rcx),%xmm13
+	movdqa	160-256(%rcx),%xmm14
+	movdqa	176-256(%rcx),%xmm15
+	movdqa	192-256(%rcx),%xmm4
+	movdqa	208-256(%rcx),%xmm5
+	movdqa	224-256(%rcx),%xmm6
+	movdqa	240-256(%rcx),%xmm7
+	movdqa	256-256(%rcx),%xmm0
+	movdqa	272-256(%rcx),%xmm1
+	movdqa	288-256(%rcx),%xmm2
+	movdqa	304-256(%rcx),%xmm3
+	paddd	.Lfour(%rip),%xmm0
+
+.Loop_enter4x:
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm7,48(%rsp)
+	movdqa	(%r10),%xmm7
+	movl	$10,%eax
+	movdqa	%xmm0,256-256(%rcx)
+	jmp	.Loop4x
+
+.align	32
+.Loop4x:
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,199
+.byte	102,15,56,0,207
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm6
+	pslld	$12,%xmm12
+	psrld	$20,%xmm6
+	movdqa	%xmm13,%xmm7
+	pslld	$12,%xmm13
+	por	%xmm6,%xmm12
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm13
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,198
+.byte	102,15,56,0,206
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm7
+	pslld	$7,%xmm12
+	psrld	$25,%xmm7
+	movdqa	%xmm13,%xmm6
+	pslld	$7,%xmm13
+	por	%xmm7,%xmm12
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm13
+	movdqa	%xmm4,0(%rsp)
+	movdqa	%xmm5,16(%rsp)
+	movdqa	32(%rsp),%xmm4
+	movdqa	48(%rsp),%xmm5
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,215
+.byte	102,15,56,0,223
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm6
+	pslld	$12,%xmm14
+	psrld	$20,%xmm6
+	movdqa	%xmm15,%xmm7
+	pslld	$12,%xmm15
+	por	%xmm6,%xmm14
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm15
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm7
+	pslld	$7,%xmm14
+	psrld	$25,%xmm7
+	movdqa	%xmm15,%xmm6
+	pslld	$7,%xmm15
+	por	%xmm7,%xmm14
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm15
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,223
+.byte	102,15,56,0,199
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm6
+	pslld	$12,%xmm13
+	psrld	$20,%xmm6
+	movdqa	%xmm14,%xmm7
+	pslld	$12,%xmm14
+	por	%xmm6,%xmm13
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm14
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,222
+.byte	102,15,56,0,198
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm7
+	pslld	$7,%xmm13
+	psrld	$25,%xmm7
+	movdqa	%xmm14,%xmm6
+	pslld	$7,%xmm14
+	por	%xmm7,%xmm13
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm14
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm5,48(%rsp)
+	movdqa	0(%rsp),%xmm4
+	movdqa	16(%rsp),%xmm5
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,207
+.byte	102,15,56,0,215
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm6
+	pslld	$12,%xmm15
+	psrld	$20,%xmm6
+	movdqa	%xmm12,%xmm7
+	pslld	$12,%xmm12
+	por	%xmm6,%xmm15
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm12
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm7
+	pslld	$7,%xmm15
+	psrld	$25,%xmm7
+	movdqa	%xmm12,%xmm6
+	pslld	$7,%xmm12
+	por	%xmm7,%xmm15
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm12
+	decl	%eax
+	jnz	.Loop4x
+
+	paddd	64(%rsp),%xmm8
+	paddd	80(%rsp),%xmm9
+	paddd	96(%rsp),%xmm10
+	paddd	112(%rsp),%xmm11
+
+	movdqa	%xmm8,%xmm6
+	punpckldq	%xmm9,%xmm8
+	movdqa	%xmm10,%xmm7
+	punpckldq	%xmm11,%xmm10
+	punpckhdq	%xmm9,%xmm6
+	punpckhdq	%xmm11,%xmm7
+	movdqa	%xmm8,%xmm9
+	punpcklqdq	%xmm10,%xmm8
+	movdqa	%xmm6,%xmm11
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm10,%xmm9
+	punpckhqdq	%xmm7,%xmm11
+	paddd	128-256(%rcx),%xmm12
+	paddd	144-256(%rcx),%xmm13
+	paddd	160-256(%rcx),%xmm14
+	paddd	176-256(%rcx),%xmm15
+
+	movdqa	%xmm8,0(%rsp)
+	movdqa	%xmm9,16(%rsp)
+	movdqa	32(%rsp),%xmm8
+	movdqa	48(%rsp),%xmm9
+
+	movdqa	%xmm12,%xmm10
+	punpckldq	%xmm13,%xmm12
+	movdqa	%xmm14,%xmm7
+	punpckldq	%xmm15,%xmm14
+	punpckhdq	%xmm13,%xmm10
+	punpckhdq	%xmm15,%xmm7
+	movdqa	%xmm12,%xmm13
+	punpcklqdq	%xmm14,%xmm12
+	movdqa	%xmm10,%xmm15
+	punpcklqdq	%xmm7,%xmm10
+	punpckhqdq	%xmm14,%xmm13
+	punpckhqdq	%xmm7,%xmm15
+	paddd	192-256(%rcx),%xmm4
+	paddd	208-256(%rcx),%xmm5
+	paddd	224-256(%rcx),%xmm8
+	paddd	240-256(%rcx),%xmm9
+
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm11,48(%rsp)
+
+	movdqa	%xmm4,%xmm14
+	punpckldq	%xmm5,%xmm4
+	movdqa	%xmm8,%xmm7
+	punpckldq	%xmm9,%xmm8
+	punpckhdq	%xmm5,%xmm14
+	punpckhdq	%xmm9,%xmm7
+	movdqa	%xmm4,%xmm5
+	punpcklqdq	%xmm8,%xmm4
+	movdqa	%xmm14,%xmm9
+	punpcklqdq	%xmm7,%xmm14
+	punpckhqdq	%xmm8,%xmm5
+	punpckhqdq	%xmm7,%xmm9
+	paddd	256-256(%rcx),%xmm0
+	paddd	272-256(%rcx),%xmm1
+	paddd	288-256(%rcx),%xmm2
+	paddd	304-256(%rcx),%xmm3
+
+	movdqa	%xmm0,%xmm8
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm8
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm8,%xmm3
+	punpcklqdq	%xmm7,%xmm8
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	cmpq	$256,%rdx
+	jb	.Ltail4x
+
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	48(%rsp),%xmm6
+	pxor	%xmm15,%xmm11
+	pxor	%xmm9,%xmm2
+	pxor	%xmm3,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$256,%rdx
+	jnz	.Loop_outer4x
+
+	jmp	.Ldone4x
+
+.Ltail4x:
+	cmpq	$192,%rdx
+	jae	.L192_or_more4x
+	cmpq	$128,%rdx
+	jae	.L128_or_more4x
+	cmpq	$64,%rdx
+	jae	.L64_or_more4x
+
+
+	xorq	%r10,%r10
+
+	movdqa	%xmm12,16(%rsp)
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm0,48(%rsp)
+	jmp	.Loop_tail4x
+
+.align	32
+.L64_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	.Ldone4x
+
+	movdqa	16(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm13,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm5,32(%rsp)
+	subq	$64,%rdx
+	movdqa	%xmm1,48(%rsp)
+	jmp	.Loop_tail4x
+
+.align	32
+.L128_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	je	.Ldone4x
+
+	movdqa	32(%rsp),%xmm6
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm10,16(%rsp)
+	leaq	128(%rdi),%rdi
+	movdqa	%xmm14,32(%rsp)
+	subq	$128,%rdx
+	movdqa	%xmm8,48(%rsp)
+	jmp	.Loop_tail4x
+
+.align	32
+.L192_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	.Ldone4x
+
+	movdqa	48(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm15,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm9,32(%rsp)
+	subq	$192,%rdx
+	movdqa	%xmm3,48(%rsp)
+
+.Loop_tail4x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	.Loop_tail4x
+
+.Ldone4x:
+	addq	$0x148+0,%rsp
+	.byte	0xf3,0xc3
+.size	ChaCha20_4x,.-ChaCha20_4x
+.type	ChaCha20_8x,@function
+.align	32
+ChaCha20_8x:
+.LChaCha20_8x:
+	movq	%rsp,%r10
+	subq	$0x280+8,%rsp
+	andq	$-32,%rsp
+	vzeroupper
+	movq	%r10,640(%rsp)
+
+
+
+
+
+
+
+
+
+
+	vbroadcasti128	.Lsigma(%rip),%ymm11
+	vbroadcasti128	(%rcx),%ymm3
+	vbroadcasti128	16(%rcx),%ymm15
+	vbroadcasti128	(%r8),%ymm7
+	leaq	256(%rsp),%rcx
+	leaq	512(%rsp),%rax
+	leaq	.Lrot16(%rip),%r10
+	leaq	.Lrot24(%rip),%r11
+
+	vpshufd	$0x00,%ymm11,%ymm8
+	vpshufd	$0x55,%ymm11,%ymm9
+	vmovdqa	%ymm8,128-256(%rcx)
+	vpshufd	$0xaa,%ymm11,%ymm10
+	vmovdqa	%ymm9,160-256(%rcx)
+	vpshufd	$0xff,%ymm11,%ymm11
+	vmovdqa	%ymm10,192-256(%rcx)
+	vmovdqa	%ymm11,224-256(%rcx)
+
+	vpshufd	$0x00,%ymm3,%ymm0
+	vpshufd	$0x55,%ymm3,%ymm1
+	vmovdqa	%ymm0,256-256(%rcx)
+	vpshufd	$0xaa,%ymm3,%ymm2
+	vmovdqa	%ymm1,288-256(%rcx)
+	vpshufd	$0xff,%ymm3,%ymm3
+	vmovdqa	%ymm2,320-256(%rcx)
+	vmovdqa	%ymm3,352-256(%rcx)
+
+	vpshufd	$0x00,%ymm15,%ymm12
+	vpshufd	$0x55,%ymm15,%ymm13
+	vmovdqa	%ymm12,384-512(%rax)
+	vpshufd	$0xaa,%ymm15,%ymm14
+	vmovdqa	%ymm13,416-512(%rax)
+	vpshufd	$0xff,%ymm15,%ymm15
+	vmovdqa	%ymm14,448-512(%rax)
+	vmovdqa	%ymm15,480-512(%rax)
+
+	vpshufd	$0x00,%ymm7,%ymm4
+	vpshufd	$0x55,%ymm7,%ymm5
+	vpaddd	.Lincy(%rip),%ymm4,%ymm4
+	vpshufd	$0xaa,%ymm7,%ymm6
+	vmovdqa	%ymm5,544-512(%rax)
+	vpshufd	$0xff,%ymm7,%ymm7
+	vmovdqa	%ymm6,576-512(%rax)
+	vmovdqa	%ymm7,608-512(%rax)
+
+	jmp	.Loop_enter8x
+
+.align	32
+.Loop_outer8x:
+	vmovdqa	128-256(%rcx),%ymm8
+	vmovdqa	160-256(%rcx),%ymm9
+	vmovdqa	192-256(%rcx),%ymm10
+	vmovdqa	224-256(%rcx),%ymm11
+	vmovdqa	256-256(%rcx),%ymm0
+	vmovdqa	288-256(%rcx),%ymm1
+	vmovdqa	320-256(%rcx),%ymm2
+	vmovdqa	352-256(%rcx),%ymm3
+	vmovdqa	384-512(%rax),%ymm12
+	vmovdqa	416-512(%rax),%ymm13
+	vmovdqa	448-512(%rax),%ymm14
+	vmovdqa	480-512(%rax),%ymm15
+	vmovdqa	512-512(%rax),%ymm4
+	vmovdqa	544-512(%rax),%ymm5
+	vmovdqa	576-512(%rax),%ymm6
+	vmovdqa	608-512(%rax),%ymm7
+	vpaddd	.Leight(%rip),%ymm4,%ymm4
+
+.Loop_enter8x:
+	vmovdqa	%ymm14,64(%rsp)
+	vmovdqa	%ymm15,96(%rsp)
+	vbroadcasti128	(%r10),%ymm15
+	vmovdqa	%ymm4,512-512(%rax)
+	movl	$10,%eax
+	jmp	.Loop8x
+
+.align	32
+.Loop8x:
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$12,%ymm0,%ymm14
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$12,%ymm1,%ymm15
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$7,%ymm0,%ymm15
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$7,%ymm1,%ymm14
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vmovdqa	%ymm12,0(%rsp)
+	vmovdqa	%ymm13,32(%rsp)
+	vmovdqa	64(%rsp),%ymm12
+	vmovdqa	96(%rsp),%ymm13
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$12,%ymm2,%ymm14
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$12,%ymm3,%ymm15
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$7,%ymm2,%ymm15
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$7,%ymm3,%ymm14
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$12,%ymm1,%ymm14
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$12,%ymm2,%ymm15
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$7,%ymm1,%ymm15
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$7,%ymm2,%ymm14
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vmovdqa	%ymm12,64(%rsp)
+	vmovdqa	%ymm13,96(%rsp)
+	vmovdqa	0(%rsp),%ymm12
+	vmovdqa	32(%rsp),%ymm13
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$12,%ymm3,%ymm14
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$12,%ymm0,%ymm15
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$7,%ymm3,%ymm15
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$7,%ymm0,%ymm14
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	decl	%eax
+	jnz	.Loop8x
+
+	leaq	512(%rsp),%rax
+	vpaddd	128-256(%rcx),%ymm8,%ymm8
+	vpaddd	160-256(%rcx),%ymm9,%ymm9
+	vpaddd	192-256(%rcx),%ymm10,%ymm10
+	vpaddd	224-256(%rcx),%ymm11,%ymm11
+
+	vpunpckldq	%ymm9,%ymm8,%ymm14
+	vpunpckldq	%ymm11,%ymm10,%ymm15
+	vpunpckhdq	%ymm9,%ymm8,%ymm8
+	vpunpckhdq	%ymm11,%ymm10,%ymm10
+	vpunpcklqdq	%ymm15,%ymm14,%ymm9
+	vpunpckhqdq	%ymm15,%ymm14,%ymm14
+	vpunpcklqdq	%ymm10,%ymm8,%ymm11
+	vpunpckhqdq	%ymm10,%ymm8,%ymm8
+	vpaddd	256-256(%rcx),%ymm0,%ymm0
+	vpaddd	288-256(%rcx),%ymm1,%ymm1
+	vpaddd	320-256(%rcx),%ymm2,%ymm2
+	vpaddd	352-256(%rcx),%ymm3,%ymm3
+
+	vpunpckldq	%ymm1,%ymm0,%ymm10
+	vpunpckldq	%ymm3,%ymm2,%ymm15
+	vpunpckhdq	%ymm1,%ymm0,%ymm0
+	vpunpckhdq	%ymm3,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm10,%ymm1
+	vpunpckhqdq	%ymm15,%ymm10,%ymm10
+	vpunpcklqdq	%ymm2,%ymm0,%ymm3
+	vpunpckhqdq	%ymm2,%ymm0,%ymm0
+	vperm2i128	$0x20,%ymm1,%ymm9,%ymm15
+	vperm2i128	$0x31,%ymm1,%ymm9,%ymm1
+	vperm2i128	$0x20,%ymm10,%ymm14,%ymm9
+	vperm2i128	$0x31,%ymm10,%ymm14,%ymm10
+	vperm2i128	$0x20,%ymm3,%ymm11,%ymm14
+	vperm2i128	$0x31,%ymm3,%ymm11,%ymm3
+	vperm2i128	$0x20,%ymm0,%ymm8,%ymm11
+	vperm2i128	$0x31,%ymm0,%ymm8,%ymm0
+	vmovdqa	%ymm15,0(%rsp)
+	vmovdqa	%ymm9,32(%rsp)
+	vmovdqa	64(%rsp),%ymm15
+	vmovdqa	96(%rsp),%ymm9
+
+	vpaddd	384-512(%rax),%ymm12,%ymm12
+	vpaddd	416-512(%rax),%ymm13,%ymm13
+	vpaddd	448-512(%rax),%ymm15,%ymm15
+	vpaddd	480-512(%rax),%ymm9,%ymm9
+
+	vpunpckldq	%ymm13,%ymm12,%ymm2
+	vpunpckldq	%ymm9,%ymm15,%ymm8
+	vpunpckhdq	%ymm13,%ymm12,%ymm12
+	vpunpckhdq	%ymm9,%ymm15,%ymm15
+	vpunpcklqdq	%ymm8,%ymm2,%ymm13
+	vpunpckhqdq	%ymm8,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm12,%ymm9
+	vpunpckhqdq	%ymm15,%ymm12,%ymm12
+	vpaddd	512-512(%rax),%ymm4,%ymm4
+	vpaddd	544-512(%rax),%ymm5,%ymm5
+	vpaddd	576-512(%rax),%ymm6,%ymm6
+	vpaddd	608-512(%rax),%ymm7,%ymm7
+
+	vpunpckldq	%ymm5,%ymm4,%ymm15
+	vpunpckldq	%ymm7,%ymm6,%ymm8
+	vpunpckhdq	%ymm5,%ymm4,%ymm4
+	vpunpckhdq	%ymm7,%ymm6,%ymm6
+	vpunpcklqdq	%ymm8,%ymm15,%ymm5
+	vpunpckhqdq	%ymm8,%ymm15,%ymm15
+	vpunpcklqdq	%ymm6,%ymm4,%ymm7
+	vpunpckhqdq	%ymm6,%ymm4,%ymm4
+	vperm2i128	$0x20,%ymm5,%ymm13,%ymm8
+	vperm2i128	$0x31,%ymm5,%ymm13,%ymm5
+	vperm2i128	$0x20,%ymm15,%ymm2,%ymm13
+	vperm2i128	$0x31,%ymm15,%ymm2,%ymm15
+	vperm2i128	$0x20,%ymm7,%ymm9,%ymm2
+	vperm2i128	$0x31,%ymm7,%ymm9,%ymm7
+	vperm2i128	$0x20,%ymm4,%ymm12,%ymm9
+	vperm2i128	$0x31,%ymm4,%ymm12,%ymm4
+	vmovdqa	0(%rsp),%ymm6
+	vmovdqa	32(%rsp),%ymm12
+
+	cmpq	$512,%rdx
+	jb	.Ltail8x
+
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm12,%ymm12
+	vpxor	32(%rsi),%ymm13,%ymm13
+	vpxor	64(%rsi),%ymm10,%ymm10
+	vpxor	96(%rsi),%ymm15,%ymm15
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm12,0(%rdi)
+	vmovdqu	%ymm13,32(%rdi)
+	vmovdqu	%ymm10,64(%rdi)
+	vmovdqu	%ymm15,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm14,%ymm14
+	vpxor	32(%rsi),%ymm2,%ymm2
+	vpxor	64(%rsi),%ymm3,%ymm3
+	vpxor	96(%rsi),%ymm7,%ymm7
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm14,0(%rdi)
+	vmovdqu	%ymm2,32(%rdi)
+	vmovdqu	%ymm3,64(%rdi)
+	vmovdqu	%ymm7,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm11,%ymm11
+	vpxor	32(%rsi),%ymm9,%ymm9
+	vpxor	64(%rsi),%ymm0,%ymm0
+	vpxor	96(%rsi),%ymm4,%ymm4
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm11,0(%rdi)
+	vmovdqu	%ymm9,32(%rdi)
+	vmovdqu	%ymm0,64(%rdi)
+	vmovdqu	%ymm4,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$512,%rdx
+	jnz	.Loop_outer8x
+
+	jmp	.Ldone8x
+
+.Ltail8x:
+	cmpq	$448,%rdx
+	jae	.L448_or_more8x
+	cmpq	$384,%rdx
+	jae	.L384_or_more8x
+	cmpq	$320,%rdx
+	jae	.L320_or_more8x
+	cmpq	$256,%rdx
+	jae	.L256_or_more8x
+	cmpq	$192,%rdx
+	jae	.L192_or_more8x
+	cmpq	$128,%rdx
+	jae	.L128_or_more8x
+	cmpq	$64,%rdx
+	jae	.L64_or_more8x
+
+	xorq	%r10,%r10
+	vmovdqa	%ymm6,0(%rsp)
+	vmovdqa	%ymm8,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L64_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	je	.Ldone8x
+
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm1,0(%rsp)
+	leaq	64(%rdi),%rdi
+	subq	$64,%rdx
+	vmovdqa	%ymm5,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L128_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	je	.Ldone8x
+
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm12,0(%rsp)
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	vmovdqa	%ymm13,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L192_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	je	.Ldone8x
+
+	leaq	192(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm10,0(%rsp)
+	leaq	192(%rdi),%rdi
+	subq	$192,%rdx
+	vmovdqa	%ymm15,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L256_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	je	.Ldone8x
+
+	leaq	256(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm14,0(%rsp)
+	leaq	256(%rdi),%rdi
+	subq	$256,%rdx
+	vmovdqa	%ymm2,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L320_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	je	.Ldone8x
+
+	leaq	320(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm3,0(%rsp)
+	leaq	320(%rdi),%rdi
+	subq	$320,%rdx
+	vmovdqa	%ymm7,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L384_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	je	.Ldone8x
+
+	leaq	384(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm11,0(%rsp)
+	leaq	384(%rdi),%rdi
+	subq	$384,%rdx
+	vmovdqa	%ymm9,32(%rsp)
+	jmp	.Loop_tail8x
+
+.align	32
+.L448_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vpxor	384(%rsi),%ymm11,%ymm11
+	vpxor	416(%rsi),%ymm9,%ymm9
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	vmovdqu	%ymm11,384(%rdi)
+	vmovdqu	%ymm9,416(%rdi)
+	je	.Ldone8x
+
+	leaq	448(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm0,0(%rsp)
+	leaq	448(%rdi),%rdi
+	subq	$448,%rdx
+	vmovdqa	%ymm4,32(%rsp)
+
+.Loop_tail8x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	.Loop_tail8x
+
+.Ldone8x:
+	vzeroall
+	movq	640(%rsp),%rsp
+	.byte	0xf3,0xc3
+.size	ChaCha20_8x,.-ChaCha20_8x
+#endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/cpu-x86_64-asm.S b/third_party/boringssl/linux-x86_64/crypto/cpu-x86_64-asm.S
deleted file mode 100644
index 9eef154..0000000
--- a/third_party/boringssl/linux-x86_64/crypto/cpu-x86_64-asm.S
+++ /dev/null
@@ -1,143 +0,0 @@
-#if defined(__x86_64__)
-.text	
-
-.globl	OPENSSL_ia32_cpuid
-.hidden OPENSSL_ia32_cpuid
-.type	OPENSSL_ia32_cpuid,@function
-.align	16
-OPENSSL_ia32_cpuid:
-
-
-	movq	%rdi,%rdi
-	movq	%rbx,%r8
-
-	xorl	%eax,%eax
-	movl	%eax,8(%rdi)
-	cpuid
-	movl	%eax,%r11d
-
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%r9d
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%r9d
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%r9d
-	jz	.Lintel
-
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%r10d
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%r10d
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%r10d
-	jnz	.Lintel
-
-
-
-
-	movl	$2147483648,%eax
-	cpuid
-
-
-	cmpl	$2147483649,%eax
-	jb	.Lintel
-	movl	%eax,%r10d
-	movl	$2147483649,%eax
-	cpuid
-
-
-	orl	%ecx,%r9d
-	andl	$2049,%r9d
-
-	cmpl	$2147483656,%r10d
-	jb	.Lintel
-
-	movl	$2147483656,%eax
-	cpuid
-
-	movzbq	%cl,%r10
-	incq	%r10
-
-	movl	$1,%eax
-	cpuid
-
-	btl	$28,%edx
-	jnc	.Lgeneric
-	shrl	$16,%ebx
-	cmpb	%r10b,%bl
-	ja	.Lgeneric
-	andl	$4026531839,%edx
-	jmp	.Lgeneric
-
-.Lintel:
-	cmpl	$4,%r11d
-	movl	$-1,%r10d
-	jb	.Lnocacheinfo
-
-	movl	$4,%eax
-	movl	$0,%ecx
-	cpuid
-	movl	%eax,%r10d
-	shrl	$14,%r10d
-	andl	$4095,%r10d
-
-	cmpl	$7,%r11d
-	jb	.Lnocacheinfo
-
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	cpuid
-	movl	%ebx,8(%rdi)
-
-.Lnocacheinfo:
-	movl	$1,%eax
-	cpuid
-
-	andl	$3220176895,%edx
-	cmpl	$0,%r9d
-	jne	.Lnotintel
-	orl	$1073741824,%edx
-.Lnotintel:
-	btl	$28,%edx
-	jnc	.Lgeneric
-	andl	$4026531839,%edx
-	cmpl	$0,%r10d
-	je	.Lgeneric
-
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	.Lgeneric
-	andl	$4026531839,%edx
-.Lgeneric:
-	andl	$2048,%r9d
-	andl	$4294965247,%ecx
-	orl	%ecx,%r9d
-
-	movl	%edx,%r10d
-	btl	$27,%r9d
-	jnc	.Lclear_avx
-	xorl	%ecx,%ecx
-.byte	0x0f,0x01,0xd0
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	.Ldone
-.Lclear_avx:
-	movl	$4026525695,%eax
-	andl	%eax,%r9d
-	andl	$4294967263,8(%rdi)
-.Ldone:
-	movl	%r9d,4(%rdi)
-	movl	%r10d,0(%rdi)
-	movq	%r8,%rbx
-	.byte	0xf3,0xc3
-.size	OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
-
-#endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S b/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S
new file mode 100644
index 0000000..4abce6f
--- /dev/null
+++ b/third_party/boringssl/linux-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -0,0 +1,1789 @@
+#if defined(__x86_64__)
+.text	
+.extern	OPENSSL_ia32cap_P
+.hidden OPENSSL_ia32cap_P
+
+
+.align	64
+.Lpoly:
+.quad	0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
+
+.LOne:
+.long	1,1,1,1,1,1,1,1
+.LTwo:
+.long	2,2,2,2,2,2,2,2
+.LThree:
+.long	3,3,3,3,3,3,3,3
+.LONE_mont:
+.quad	0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
+
+.type	ecp_nistz256_mul_by_2,@function
+.align	64
+ecp_nistz256_mul_by_2:
+	pushq	%r12
+	pushq	%r13
+
+	movq	0(%rsi),%r8
+	movq	8(%rsi),%r9
+	addq	%r8,%r8
+	movq	16(%rsi),%r10
+	adcq	%r9,%r9
+	movq	24(%rsi),%r11
+	leaq	.Lpoly(%rip),%rsi
+	movq	%r8,%rax
+	adcq	%r10,%r10
+	adcq	%r11,%r11
+	movq	%r9,%rdx
+	sbbq	%r13,%r13
+
+	subq	0(%rsi),%r8
+	movq	%r10,%rcx
+	sbbq	8(%rsi),%r9
+	sbbq	16(%rsi),%r10
+	movq	%r11,%r12
+	sbbq	24(%rsi),%r11
+	testq	%r13,%r13
+
+	cmovzq	%rax,%r8
+	cmovzq	%rdx,%r9
+	movq	%r8,0(%rdi)
+	cmovzq	%rcx,%r10
+	movq	%r9,8(%rdi)
+	cmovzq	%r12,%r11
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+
+	popq	%r13
+	popq	%r12
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
+
+
+
+.globl	ecp_nistz256_neg
+.hidden ecp_nistz256_neg
+.type	ecp_nistz256_neg,@function
+.align	32
+ecp_nistz256_neg:
+	pushq	%r12
+	pushq	%r13
+
+	xorq	%r8,%r8
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+	xorq	%r13,%r13
+
+	subq	0(%rsi),%r8
+	sbbq	8(%rsi),%r9
+	sbbq	16(%rsi),%r10
+	movq	%r8,%rax
+	sbbq	24(%rsi),%r11
+	leaq	.Lpoly(%rip),%rsi
+	movq	%r9,%rdx
+	sbbq	$0,%r13
+
+	addq	0(%rsi),%r8
+	movq	%r10,%rcx
+	adcq	8(%rsi),%r9
+	adcq	16(%rsi),%r10
+	movq	%r11,%r12
+	adcq	24(%rsi),%r11
+	testq	%r13,%r13
+
+	cmovzq	%rax,%r8
+	cmovzq	%rdx,%r9
+	movq	%r8,0(%rdi)
+	cmovzq	%rcx,%r10
+	movq	%r9,8(%rdi)
+	cmovzq	%r12,%r11
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+
+	popq	%r13
+	popq	%r12
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_neg,.-ecp_nistz256_neg
+
+
+
+
+
+
+.globl	ecp_nistz256_mul_mont
+.hidden ecp_nistz256_mul_mont
+.type	ecp_nistz256_mul_mont,@function
+.align	32
+ecp_nistz256_mul_mont:
+.Lmul_mont:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rdx,%rbx
+	movq	0(%rdx),%rax
+	movq	0(%rsi),%r9
+	movq	8(%rsi),%r10
+	movq	16(%rsi),%r11
+	movq	24(%rsi),%r12
+
+	call	__ecp_nistz256_mul_montq
+.Lmul_mont_done:
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
+
+.type	__ecp_nistz256_mul_montq,@function
+.align	32
+__ecp_nistz256_mul_montq:
+
+
+	movq	%rax,%rbp
+	mulq	%r9
+	movq	.Lpoly+8(%rip),%r14
+	movq	%rax,%r8
+	movq	%rbp,%rax
+	movq	%rdx,%r9
+
+	mulq	%r10
+	movq	.Lpoly+24(%rip),%r15
+	addq	%rax,%r9
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%r11
+	addq	%rax,%r10
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%r12
+	addq	%rax,%r11
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	xorq	%r13,%r13
+	movq	%rdx,%r12
+
+
+
+
+
+
+
+
+
+
+	movq	%r8,%rbp
+	shlq	$32,%r8
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r8,%r9
+	adcq	%rbp,%r10
+	adcq	%rax,%r11
+	movq	8(%rbx),%rax
+	adcq	%rdx,%r12
+	adcq	$0,%r13
+	xorq	%r8,%r8
+
+
+
+	movq	%rax,%rbp
+	mulq	0(%rsi)
+	addq	%rax,%r9
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	8(%rsi)
+	addq	%rcx,%r10
+	adcq	$0,%rdx
+	addq	%rax,%r10
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	16(%rsi)
+	addq	%rcx,%r11
+	adcq	$0,%rdx
+	addq	%rax,%r11
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	24(%rsi)
+	addq	%rcx,%r12
+	adcq	$0,%rdx
+	addq	%rax,%r12
+	movq	%r9,%rax
+	adcq	%rdx,%r13
+	adcq	$0,%r8
+
+
+
+	movq	%r9,%rbp
+	shlq	$32,%r9
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r9,%r10
+	adcq	%rbp,%r11
+	adcq	%rax,%r12
+	movq	16(%rbx),%rax
+	adcq	%rdx,%r13
+	adcq	$0,%r8
+	xorq	%r9,%r9
+
+
+
+	movq	%rax,%rbp
+	mulq	0(%rsi)
+	addq	%rax,%r10
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	8(%rsi)
+	addq	%rcx,%r11
+	adcq	$0,%rdx
+	addq	%rax,%r11
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	16(%rsi)
+	addq	%rcx,%r12
+	adcq	$0,%rdx
+	addq	%rax,%r12
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	24(%rsi)
+	addq	%rcx,%r13
+	adcq	$0,%rdx
+	addq	%rax,%r13
+	movq	%r10,%rax
+	adcq	%rdx,%r8
+	adcq	$0,%r9
+
+
+
+	movq	%r10,%rbp
+	shlq	$32,%r10
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r10,%r11
+	adcq	%rbp,%r12
+	adcq	%rax,%r13
+	movq	24(%rbx),%rax
+	adcq	%rdx,%r8
+	adcq	$0,%r9
+	xorq	%r10,%r10
+
+
+
+	movq	%rax,%rbp
+	mulq	0(%rsi)
+	addq	%rax,%r11
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	8(%rsi)
+	addq	%rcx,%r12
+	adcq	$0,%rdx
+	addq	%rax,%r12
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	16(%rsi)
+	addq	%rcx,%r13
+	adcq	$0,%rdx
+	addq	%rax,%r13
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	24(%rsi)
+	addq	%rcx,%r8
+	adcq	$0,%rdx
+	addq	%rax,%r8
+	movq	%r11,%rax
+	adcq	%rdx,%r9
+	adcq	$0,%r10
+
+
+
+	movq	%r11,%rbp
+	shlq	$32,%r11
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r11,%r12
+	adcq	%rbp,%r13
+	movq	%r12,%rcx
+	adcq	%rax,%r8
+	adcq	%rdx,%r9
+	movq	%r13,%rbp
+	adcq	$0,%r10
+
+
+
+	subq	$-1,%r12
+	movq	%r8,%rbx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%rdx
+	sbbq	%r15,%r9
+	sbbq	$0,%r10
+
+	cmovcq	%rcx,%r12
+	cmovcq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovcq	%rbx,%r8
+	movq	%r13,8(%rdi)
+	cmovcq	%rdx,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+.size	__ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
+
+
+
+
+
+
+
+
+.globl	ecp_nistz256_sqr_mont
+.hidden ecp_nistz256_sqr_mont
+.type	ecp_nistz256_sqr_mont,@function
+.align	32
+ecp_nistz256_sqr_mont:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r15
+	movq	24(%rsi),%r8
+
+	call	__ecp_nistz256_sqr_montq
+.Lsqr_mont_done:
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
+
+.type	__ecp_nistz256_sqr_montq,@function
+.align	32
+__ecp_nistz256_sqr_montq:
+	movq	%rax,%r13
+	mulq	%r14
+	movq	%rax,%r9
+	movq	%r15,%rax
+	movq	%rdx,%r10
+
+	mulq	%r13
+	addq	%rax,%r10
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%r13
+	addq	%rax,%r11
+	movq	%r15,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+
+
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rbp
+
+	mulq	%r14
+	addq	%rax,%r12
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	addq	%rbp,%r12
+	movq	%rdx,%r13
+	adcq	$0,%r13
+
+
+	mulq	%r15
+	xorq	%r15,%r15
+	addq	%rax,%r13
+	movq	0(%rsi),%rax
+	movq	%rdx,%r14
+	adcq	$0,%r14
+
+	addq	%r9,%r9
+	adcq	%r10,%r10
+	adcq	%r11,%r11
+	adcq	%r12,%r12
+	adcq	%r13,%r13
+	adcq	%r14,%r14
+	adcq	$0,%r15
+
+	mulq	%rax
+	movq	%rax,%r8
+	movq	8(%rsi),%rax
+	movq	%rdx,%rcx
+
+	mulq	%rax
+	addq	%rcx,%r9
+	adcq	%rax,%r10
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	%rax
+	addq	%rcx,%r11
+	adcq	%rax,%r12
+	movq	24(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	%rax
+	addq	%rcx,%r13
+	adcq	%rax,%r14
+	movq	%r8,%rax
+	adcq	%rdx,%r15
+
+	movq	.Lpoly+8(%rip),%rsi
+	movq	.Lpoly+24(%rip),%rbp
+
+
+
+
+	movq	%r8,%rcx
+	shlq	$32,%r8
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r8,%r9
+	adcq	%rcx,%r10
+	adcq	%rax,%r11
+	movq	%r9,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r9,%rcx
+	shlq	$32,%r9
+	movq	%rdx,%r8
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r9,%r10
+	adcq	%rcx,%r11
+	adcq	%rax,%r8
+	movq	%r10,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r10,%rcx
+	shlq	$32,%r10
+	movq	%rdx,%r9
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r10,%r11
+	adcq	%rcx,%r8
+	adcq	%rax,%r9
+	movq	%r11,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r11,%rcx
+	shlq	$32,%r11
+	movq	%rdx,%r10
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r11,%r8
+	adcq	%rcx,%r9
+	adcq	%rax,%r10
+	adcq	$0,%rdx
+	xorq	%r11,%r11
+
+
+
+	addq	%r8,%r12
+	adcq	%r9,%r13
+	movq	%r12,%r8
+	adcq	%r10,%r14
+	adcq	%rdx,%r15
+	movq	%r13,%r9
+	adcq	$0,%r11
+
+	subq	$-1,%r12
+	movq	%r14,%r10
+	sbbq	%rsi,%r13
+	sbbq	$0,%r14
+	movq	%r15,%rcx
+	sbbq	%rbp,%r15
+	sbbq	$0,%r11
+
+	cmovcq	%r8,%r12
+	cmovcq	%r9,%r13
+	movq	%r12,0(%rdi)
+	cmovcq	%r10,%r14
+	movq	%r13,8(%rdi)
+	cmovcq	%rcx,%r15
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+
+	.byte	0xf3,0xc3
+.size	__ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
+
+
+
+
+
+
+.globl	ecp_nistz256_from_mont
+.hidden ecp_nistz256_from_mont
+.type	ecp_nistz256_from_mont,@function
+.align	32
+ecp_nistz256_from_mont:
+	pushq	%r12
+	pushq	%r13
+
+	movq	0(%rsi),%rax
+	movq	.Lpoly+24(%rip),%r13
+	movq	8(%rsi),%r9
+	movq	16(%rsi),%r10
+	movq	24(%rsi),%r11
+	movq	%rax,%r8
+	movq	.Lpoly+8(%rip),%r12
+
+
+
+	movq	%rax,%rcx
+	shlq	$32,%r8
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r8,%r9
+	adcq	%rcx,%r10
+	adcq	%rax,%r11
+	movq	%r9,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r9,%rcx
+	shlq	$32,%r9
+	movq	%rdx,%r8
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r9,%r10
+	adcq	%rcx,%r11
+	adcq	%rax,%r8
+	movq	%r10,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r10,%rcx
+	shlq	$32,%r10
+	movq	%rdx,%r9
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r10,%r11
+	adcq	%rcx,%r8
+	adcq	%rax,%r9
+	movq	%r11,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r11,%rcx
+	shlq	$32,%r11
+	movq	%rdx,%r10
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r11,%r8
+	adcq	%rcx,%r9
+	movq	%r8,%rcx
+	adcq	%rax,%r10
+	movq	%r9,%rsi
+	adcq	$0,%rdx
+
+	subq	$-1,%r8
+	movq	%r10,%rax
+	sbbq	%r12,%r9
+	sbbq	$0,%r10
+	movq	%rdx,%r11
+	sbbq	%r13,%rdx
+	sbbq	%r13,%r13
+
+	cmovnzq	%rcx,%r8
+	cmovnzq	%rsi,%r9
+	movq	%r8,0(%rdi)
+	cmovnzq	%rax,%r10
+	movq	%r9,8(%rdi)
+	cmovzq	%rdx,%r11
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+
+	popq	%r13
+	popq	%r12
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
+
+
+.globl	ecp_nistz256_select_w5
+.hidden ecp_nistz256_select_w5
+.type	ecp_nistz256_select_w5,@function
+.align	32
+ecp_nistz256_select_w5:
+	movdqa	.LOne(%rip),%xmm0
+	movd	%edx,%xmm1
+
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	pxor	%xmm6,%xmm6
+	pxor	%xmm7,%xmm7
+
+	movdqa	%xmm0,%xmm8
+	pshufd	$0,%xmm1,%xmm1
+
+	movq	$16,%rax
+.Lselect_loop_sse_w5:
+
+	movdqa	%xmm8,%xmm15
+	paddd	%xmm0,%xmm8
+	pcmpeqd	%xmm1,%xmm15
+
+	movdqa	0(%rsi),%xmm9
+	movdqa	16(%rsi),%xmm10
+	movdqa	32(%rsi),%xmm11
+	movdqa	48(%rsi),%xmm12
+	movdqa	64(%rsi),%xmm13
+	movdqa	80(%rsi),%xmm14
+	leaq	96(%rsi),%rsi
+
+	pand	%xmm15,%xmm9
+	pand	%xmm15,%xmm10
+	por	%xmm9,%xmm2
+	pand	%xmm15,%xmm11
+	por	%xmm10,%xmm3
+	pand	%xmm15,%xmm12
+	por	%xmm11,%xmm4
+	pand	%xmm15,%xmm13
+	por	%xmm12,%xmm5
+	pand	%xmm15,%xmm14
+	por	%xmm13,%xmm6
+	por	%xmm14,%xmm7
+
+	decq	%rax
+	jnz	.Lselect_loop_sse_w5
+
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+	movdqu	%xmm4,32(%rdi)
+	movdqu	%xmm5,48(%rdi)
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm7,80(%rdi)
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_select_w5,.-ecp_nistz256_select_w5
+
+
+
+.globl	ecp_nistz256_select_w7
+.hidden ecp_nistz256_select_w7
+.type	ecp_nistz256_select_w7,@function
+.align	32
+ecp_nistz256_select_w7:
+	movdqa	.LOne(%rip),%xmm8
+	movd	%edx,%xmm1
+
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+
+	movdqa	%xmm8,%xmm0
+	pshufd	$0,%xmm1,%xmm1
+	movq	$64,%rax
+
+.Lselect_loop_sse_w7:
+	movdqa	%xmm8,%xmm15
+	paddd	%xmm0,%xmm8
+	movdqa	0(%rsi),%xmm9
+	movdqa	16(%rsi),%xmm10
+	pcmpeqd	%xmm1,%xmm15
+	movdqa	32(%rsi),%xmm11
+	movdqa	48(%rsi),%xmm12
+	leaq	64(%rsi),%rsi
+
+	pand	%xmm15,%xmm9
+	pand	%xmm15,%xmm10
+	por	%xmm9,%xmm2
+	pand	%xmm15,%xmm11
+	por	%xmm10,%xmm3
+	pand	%xmm15,%xmm12
+	por	%xmm11,%xmm4
+	prefetcht0	255(%rsi)
+	por	%xmm12,%xmm5
+
+	decq	%rax
+	jnz	.Lselect_loop_sse_w7
+
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+	movdqu	%xmm4,32(%rdi)
+	movdqu	%xmm5,48(%rdi)
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_select_w7,.-ecp_nistz256_select_w7
+.globl	ecp_nistz256_avx2_select_w7
+.hidden ecp_nistz256_avx2_select_w7
+.type	ecp_nistz256_avx2_select_w7,@function
+.align	32
+ecp_nistz256_avx2_select_w7:
+.byte	0x0f,0x0b
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
+.type	__ecp_nistz256_add_toq,@function
+.align	32
+__ecp_nistz256_add_toq:
+	addq	0(%rbx),%r12
+	adcq	8(%rbx),%r13
+	movq	%r12,%rax
+	adcq	16(%rbx),%r8
+	adcq	24(%rbx),%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	cmovzq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovzq	%rcx,%r8
+	movq	%r13,8(%rdi)
+	cmovzq	%r10,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+.size	__ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq
+
+.type	__ecp_nistz256_sub_fromq,@function
+.align	32
+__ecp_nistz256_sub_fromq:
+	subq	0(%rbx),%r12
+	sbbq	8(%rbx),%r13
+	movq	%r12,%rax
+	sbbq	16(%rbx),%r8
+	sbbq	24(%rbx),%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	addq	$-1,%r12
+	movq	%r8,%rcx
+	adcq	%r14,%r13
+	adcq	$0,%r8
+	movq	%r9,%r10
+	adcq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	cmovzq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovzq	%rcx,%r8
+	movq	%r13,8(%rdi)
+	cmovzq	%r10,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+.size	__ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq
+
+.type	__ecp_nistz256_subq,@function
+.align	32
+__ecp_nistz256_subq:
+	subq	%r12,%rax
+	sbbq	%r13,%rbp
+	movq	%rax,%r12
+	sbbq	%r8,%rcx
+	sbbq	%r9,%r10
+	movq	%rbp,%r13
+	sbbq	%r11,%r11
+
+	addq	$-1,%rax
+	movq	%rcx,%r8
+	adcq	%r14,%rbp
+	adcq	$0,%rcx
+	movq	%r10,%r9
+	adcq	%r15,%r10
+	testq	%r11,%r11
+
+	cmovnzq	%rax,%r12
+	cmovnzq	%rbp,%r13
+	cmovnzq	%rcx,%r8
+	cmovnzq	%r10,%r9
+
+	.byte	0xf3,0xc3
+.size	__ecp_nistz256_subq,.-__ecp_nistz256_subq
+
+.type	__ecp_nistz256_mul_by_2q,@function
+.align	32
+__ecp_nistz256_mul_by_2q:
+	addq	%r12,%r12
+	adcq	%r13,%r13
+	movq	%r12,%rax
+	adcq	%r8,%r8
+	adcq	%r9,%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	cmovzq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovzq	%rcx,%r8
+	movq	%r13,8(%rdi)
+	cmovzq	%r10,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+.size	__ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q
+.globl	ecp_nistz256_point_double
+.hidden ecp_nistz256_point_double
+.type	ecp_nistz256_point_double,@function
+.align	32
+ecp_nistz256_point_double:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$160+8,%rsp
+
+.Lpoint_double_shortcutq:
+	movdqu	0(%rsi),%xmm0
+	movq	%rsi,%rbx
+	movdqu	16(%rsi),%xmm1
+	movq	32+0(%rsi),%r12
+	movq	32+8(%rsi),%r13
+	movq	32+16(%rsi),%r8
+	movq	32+24(%rsi),%r9
+	movq	.Lpoly+8(%rip),%r14
+	movq	.Lpoly+24(%rip),%r15
+	movdqa	%xmm0,96(%rsp)
+	movdqa	%xmm1,96+16(%rsp)
+	leaq	32(%rdi),%r10
+	leaq	64(%rdi),%r11
+.byte	102,72,15,110,199
+.byte	102,73,15,110,202
+.byte	102,73,15,110,211
+
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_by_2q
+
+	movq	64+0(%rsi),%rax
+	movq	64+8(%rsi),%r14
+	movq	64+16(%rsi),%r15
+	movq	64+24(%rsi),%r8
+	leaq	64-0(%rsi),%rsi
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	0+0(%rsp),%rax
+	movq	8+0(%rsp),%r14
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r15
+	movq	24+0(%rsp),%r8
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	32(%rbx),%rax
+	movq	64+0(%rbx),%r9
+	movq	64+8(%rbx),%r10
+	movq	64+16(%rbx),%r11
+	movq	64+24(%rbx),%r12
+	leaq	64-0(%rbx),%rsi
+	leaq	32(%rbx),%rbx
+.byte	102,72,15,126,215
+	call	__ecp_nistz256_mul_montq
+	call	__ecp_nistz256_mul_by_2q
+
+	movq	96+0(%rsp),%r12
+	movq	96+8(%rsp),%r13
+	leaq	64(%rsp),%rbx
+	movq	96+16(%rsp),%r8
+	movq	96+24(%rsp),%r9
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_add_toq
+
+	movq	96+0(%rsp),%r12
+	movq	96+8(%rsp),%r13
+	leaq	64(%rsp),%rbx
+	movq	96+16(%rsp),%r8
+	movq	96+24(%rsp),%r9
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+0(%rsp),%rax
+	movq	8+0(%rsp),%r14
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r15
+	movq	24+0(%rsp),%r8
+.byte	102,72,15,126,207
+	call	__ecp_nistz256_sqr_montq
+	xorq	%r9,%r9
+	movq	%r12,%rax
+	addq	$-1,%r12
+	movq	%r13,%r10
+	adcq	%rsi,%r13
+	movq	%r14,%rcx
+	adcq	$0,%r14
+	movq	%r15,%r8
+	adcq	%rbp,%r15
+	adcq	$0,%r9
+	xorq	%rsi,%rsi
+	testq	$1,%rax
+
+	cmovzq	%rax,%r12
+	cmovzq	%r10,%r13
+	cmovzq	%rcx,%r14
+	cmovzq	%r8,%r15
+	cmovzq	%rsi,%r9
+
+	movq	%r13,%rax
+	shrq	$1,%r12
+	shlq	$63,%rax
+	movq	%r14,%r10
+	shrq	$1,%r13
+	orq	%rax,%r12
+	shlq	$63,%r10
+	movq	%r15,%rcx
+	shrq	$1,%r14
+	orq	%r10,%r13
+	shlq	$63,%rcx
+	movq	%r12,0(%rdi)
+	shrq	$1,%r15
+	movq	%r13,8(%rdi)
+	shlq	$63,%r9
+	orq	%rcx,%r14
+	orq	%r9,%r15
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+	movq	64(%rsp),%rax
+	leaq	64(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_mul_by_2q
+
+	leaq	32(%rsp),%rbx
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_add_toq
+
+	movq	96(%rsp),%rax
+	leaq	96(%rsp),%rbx
+	movq	0+0(%rsp),%r9
+	movq	8+0(%rsp),%r10
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r11
+	movq	24+0(%rsp),%r12
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_mul_by_2q
+
+	movq	0+32(%rsp),%rax
+	movq	8+32(%rsp),%r14
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r15
+	movq	24+32(%rsp),%r8
+.byte	102,72,15,126,199
+	call	__ecp_nistz256_sqr_montq
+
+	leaq	128(%rsp),%rbx
+	movq	%r14,%r8
+	movq	%r15,%r9
+	movq	%rsi,%r14
+	movq	%rbp,%r15
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+0(%rsp),%rax
+	movq	0+8(%rsp),%rbp
+	movq	0+16(%rsp),%rcx
+	movq	0+24(%rsp),%r10
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_subq
+
+	movq	32(%rsp),%rax
+	leaq	32(%rsp),%rbx
+	movq	%r12,%r14
+	xorl	%ecx,%ecx
+	movq	%r12,0+0(%rsp)
+	movq	%r13,%r10
+	movq	%r13,0+8(%rsp)
+	cmovzq	%r8,%r11
+	movq	%r8,0+16(%rsp)
+	leaq	0-0(%rsp),%rsi
+	cmovzq	%r9,%r12
+	movq	%r9,0+24(%rsp)
+	movq	%r14,%r9
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+.byte	102,72,15,126,203
+.byte	102,72,15,126,207
+	call	__ecp_nistz256_sub_fromq
+
+	addq	$160+8,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_point_double,.-ecp_nistz256_point_double
+.globl	ecp_nistz256_point_add
+.hidden ecp_nistz256_point_add
+.type	ecp_nistz256_point_add,@function
+.align	32
+ecp_nistz256_point_add:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$576+8,%rsp
+
+	movdqu	0(%rsi),%xmm0
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm3
+	movdqu	64(%rsi),%xmm4
+	movdqu	80(%rsi),%xmm5
+	movq	%rsi,%rbx
+	movq	%rdx,%rsi
+	movdqa	%xmm0,384(%rsp)
+	movdqa	%xmm1,384+16(%rsp)
+	por	%xmm0,%xmm1
+	movdqa	%xmm2,416(%rsp)
+	movdqa	%xmm3,416+16(%rsp)
+	por	%xmm2,%xmm3
+	movdqa	%xmm4,448(%rsp)
+	movdqa	%xmm5,448+16(%rsp)
+	por	%xmm1,%xmm3
+
+	movdqu	0(%rsi),%xmm0
+	pshufd	$0xb1,%xmm3,%xmm5
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	por	%xmm3,%xmm5
+	movdqu	48(%rsi),%xmm3
+	movq	64+0(%rsi),%rax
+	movq	64+8(%rsi),%r14
+	movq	64+16(%rsi),%r15
+	movq	64+24(%rsi),%r8
+	movdqa	%xmm0,480(%rsp)
+	pshufd	$0x1e,%xmm5,%xmm4
+	movdqa	%xmm1,480+16(%rsp)
+	por	%xmm0,%xmm1
+.byte	102,72,15,110,199
+	movdqa	%xmm2,512(%rsp)
+	movdqa	%xmm3,512+16(%rsp)
+	por	%xmm2,%xmm3
+	por	%xmm4,%xmm5
+	pxor	%xmm4,%xmm4
+	por	%xmm1,%xmm3
+
+	leaq	64-0(%rsi),%rsi
+	movq	%rax,544+0(%rsp)
+	movq	%r14,544+8(%rsp)
+	movq	%r15,544+16(%rsp)
+	movq	%r8,544+24(%rsp)
+	leaq	96(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	pcmpeqd	%xmm4,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm4
+	por	%xmm3,%xmm4
+	pshufd	$0,%xmm5,%xmm5
+	pshufd	$0x1e,%xmm4,%xmm3
+	por	%xmm3,%xmm4
+	pxor	%xmm3,%xmm3
+	pcmpeqd	%xmm3,%xmm4
+	pshufd	$0,%xmm4,%xmm4
+	movq	64+0(%rbx),%rax
+	movq	64+8(%rbx),%r14
+	movq	64+16(%rbx),%r15
+	movq	64+24(%rbx),%r8
+.byte	102,72,15,110,203
+
+	leaq	64-0(%rbx),%rsi
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	544(%rsp),%rax
+	leaq	544(%rsp),%rbx
+	movq	0+96(%rsp),%r9
+	movq	8+96(%rsp),%r10
+	leaq	0+96(%rsp),%rsi
+	movq	16+96(%rsp),%r11
+	movq	24+96(%rsp),%r12
+	leaq	224(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	448(%rsp),%rax
+	leaq	448(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	416(%rsp),%rax
+	leaq	416(%rsp),%rbx
+	movq	0+224(%rsp),%r9
+	movq	8+224(%rsp),%r10
+	leaq	0+224(%rsp),%rsi
+	movq	16+224(%rsp),%r11
+	movq	24+224(%rsp),%r12
+	leaq	224(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	512(%rsp),%rax
+	leaq	512(%rsp),%rbx
+	movq	0+256(%rsp),%r9
+	movq	8+256(%rsp),%r10
+	leaq	0+256(%rsp),%rsi
+	movq	16+256(%rsp),%r11
+	movq	24+256(%rsp),%r12
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	224(%rsp),%rbx
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	orq	%r13,%r12
+	movdqa	%xmm4,%xmm2
+	orq	%r8,%r12
+	orq	%r9,%r12
+	por	%xmm5,%xmm2
+.byte	102,73,15,110,220
+
+	movq	384(%rsp),%rax
+	leaq	384(%rsp),%rbx
+	movq	0+96(%rsp),%r9
+	movq	8+96(%rsp),%r10
+	leaq	0+96(%rsp),%rsi
+	movq	16+96(%rsp),%r11
+	movq	24+96(%rsp),%r12
+	leaq	160(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	480(%rsp),%rax
+	leaq	480(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	192(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	160(%rsp),%rbx
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	orq	%r13,%r12
+	orq	%r8,%r12
+	orq	%r9,%r12
+
+.byte	0x3e
+	jnz	.Ladd_proceedq
+.byte	102,73,15,126,208
+.byte	102,73,15,126,217
+	testq	%r8,%r8
+	jnz	.Ladd_proceedq
+	testq	%r9,%r9
+	jz	.Ladd_doubleq
+
+.byte	102,72,15,126,199
+	pxor	%xmm0,%xmm0
+	movdqu	%xmm0,0(%rdi)
+	movdqu	%xmm0,16(%rdi)
+	movdqu	%xmm0,32(%rdi)
+	movdqu	%xmm0,48(%rdi)
+	movdqu	%xmm0,64(%rdi)
+	movdqu	%xmm0,80(%rdi)
+	jmp	.Ladd_doneq
+
+.align	32
+.Ladd_doubleq:
+.byte	102,72,15,126,206
+.byte	102,72,15,126,199
+	addq	$416,%rsp
+	jmp	.Lpoint_double_shortcutq
+
+.align	32
+.Ladd_proceedq:
+	movq	0+64(%rsp),%rax
+	movq	8+64(%rsp),%r14
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r15
+	movq	24+64(%rsp),%r8
+	leaq	96(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	448(%rsp),%rax
+	leaq	448(%rsp),%rbx
+	movq	0+0(%rsp),%r9
+	movq	8+0(%rsp),%r10
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r11
+	movq	24+0(%rsp),%r12
+	leaq	352(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	0+0(%rsp),%rax
+	movq	8+0(%rsp),%r14
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r15
+	movq	24+0(%rsp),%r8
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	544(%rsp),%rax
+	leaq	544(%rsp),%rbx
+	movq	0+352(%rsp),%r9
+	movq	8+352(%rsp),%r10
+	leaq	0+352(%rsp),%rsi
+	movq	16+352(%rsp),%r11
+	movq	24+352(%rsp),%r12
+	leaq	352(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	0(%rsp),%rax
+	leaq	0(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	160(%rsp),%rax
+	leaq	160(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	192(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+
+
+
+	addq	%r12,%r12
+	leaq	96(%rsp),%rsi
+	adcq	%r13,%r13
+	movq	%r12,%rax
+	adcq	%r8,%r8
+	adcq	%r9,%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	movq	0(%rsi),%rax
+	cmovzq	%rbp,%r13
+	movq	8(%rsi),%rbp
+	cmovzq	%rcx,%r8
+	movq	16(%rsi),%rcx
+	cmovzq	%r10,%r9
+	movq	24(%rsi),%r10
+
+	call	__ecp_nistz256_subq
+
+	leaq	128(%rsp),%rbx
+	leaq	288(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	192+0(%rsp),%rax
+	movq	192+8(%rsp),%rbp
+	movq	192+16(%rsp),%rcx
+	movq	192+24(%rsp),%r10
+	leaq	320(%rsp),%rdi
+
+	call	__ecp_nistz256_subq
+
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+	movq	128(%rsp),%rax
+	leaq	128(%rsp),%rbx
+	movq	0+224(%rsp),%r9
+	movq	8+224(%rsp),%r10
+	leaq	0+224(%rsp),%rsi
+	movq	16+224(%rsp),%r11
+	movq	24+224(%rsp),%r12
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	320(%rsp),%rax
+	leaq	320(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	320(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	256(%rsp),%rbx
+	leaq	320(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+.byte	102,72,15,126,199
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	352(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	352+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	544(%rsp),%xmm2
+	pand	544+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	448(%rsp),%xmm2
+	pand	448+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,64(%rdi)
+	movdqu	%xmm3,80(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	288(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	288+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	480(%rsp),%xmm2
+	pand	480+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	384(%rsp),%xmm2
+	pand	384+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	320(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	320+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	512(%rsp),%xmm2
+	pand	512+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	416(%rsp),%xmm2
+	pand	416+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+
+.Ladd_doneq:
+	addq	$576+8,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_point_add,.-ecp_nistz256_point_add
+.globl	ecp_nistz256_point_add_affine
+.hidden ecp_nistz256_point_add_affine
+.type	ecp_nistz256_point_add_affine,@function
+.align	32
+ecp_nistz256_point_add_affine:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$480+8,%rsp
+
+	movdqu	0(%rsi),%xmm0
+	movq	%rdx,%rbx
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm3
+	movdqu	64(%rsi),%xmm4
+	movdqu	80(%rsi),%xmm5
+	movq	64+0(%rsi),%rax
+	movq	64+8(%rsi),%r14
+	movq	64+16(%rsi),%r15
+	movq	64+24(%rsi),%r8
+	movdqa	%xmm0,320(%rsp)
+	movdqa	%xmm1,320+16(%rsp)
+	por	%xmm0,%xmm1
+	movdqa	%xmm2,352(%rsp)
+	movdqa	%xmm3,352+16(%rsp)
+	por	%xmm2,%xmm3
+	movdqa	%xmm4,384(%rsp)
+	movdqa	%xmm5,384+16(%rsp)
+	por	%xmm1,%xmm3
+
+	movdqu	0(%rbx),%xmm0
+	pshufd	$0xb1,%xmm3,%xmm5
+	movdqu	16(%rbx),%xmm1
+	movdqu	32(%rbx),%xmm2
+	por	%xmm3,%xmm5
+	movdqu	48(%rbx),%xmm3
+	movdqa	%xmm0,416(%rsp)
+	pshufd	$0x1e,%xmm5,%xmm4
+	movdqa	%xmm1,416+16(%rsp)
+	por	%xmm0,%xmm1
+.byte	102,72,15,110,199
+	movdqa	%xmm2,448(%rsp)
+	movdqa	%xmm3,448+16(%rsp)
+	por	%xmm2,%xmm3
+	por	%xmm4,%xmm5
+	pxor	%xmm4,%xmm4
+	por	%xmm1,%xmm3
+
+	leaq	64-0(%rsi),%rsi
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	pcmpeqd	%xmm4,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm4
+	movq	0(%rbx),%rax
+
+	movq	%r12,%r9
+	por	%xmm3,%xmm4
+	pshufd	$0,%xmm5,%xmm5
+	pshufd	$0x1e,%xmm4,%xmm3
+	movq	%r13,%r10
+	por	%xmm3,%xmm4
+	pxor	%xmm3,%xmm3
+	movq	%r14,%r11
+	pcmpeqd	%xmm3,%xmm4
+	pshufd	$0,%xmm4,%xmm4
+
+	leaq	32-0(%rsp),%rsi
+	movq	%r15,%r12
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	320(%rsp),%rbx
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	384(%rsp),%rax
+	leaq	384(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	384(%rsp),%rax
+	leaq	384(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	288(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	448(%rsp),%rax
+	leaq	448(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	352(%rsp),%rbx
+	leaq	96(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+64(%rsp),%rax
+	movq	8+64(%rsp),%r14
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r15
+	movq	24+64(%rsp),%r8
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	0+96(%rsp),%rax
+	movq	8+96(%rsp),%r14
+	leaq	0+96(%rsp),%rsi
+	movq	16+96(%rsp),%r15
+	movq	24+96(%rsp),%r8
+	leaq	192(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	128(%rsp),%rax
+	leaq	128(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	160(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	320(%rsp),%rax
+	leaq	320(%rsp),%rbx
+	movq	0+128(%rsp),%r9
+	movq	8+128(%rsp),%r10
+	leaq	0+128(%rsp),%rsi
+	movq	16+128(%rsp),%r11
+	movq	24+128(%rsp),%r12
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+
+
+
+	addq	%r12,%r12
+	leaq	192(%rsp),%rsi
+	adcq	%r13,%r13
+	movq	%r12,%rax
+	adcq	%r8,%r8
+	adcq	%r9,%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	movq	0(%rsi),%rax
+	cmovzq	%rbp,%r13
+	movq	8(%rsi),%rbp
+	cmovzq	%rcx,%r8
+	movq	16(%rsi),%rcx
+	cmovzq	%r10,%r9
+	movq	24(%rsi),%r10
+
+	call	__ecp_nistz256_subq
+
+	leaq	160(%rsp),%rbx
+	leaq	224(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+0(%rsp),%rax
+	movq	0+8(%rsp),%rbp
+	movq	0+16(%rsp),%rcx
+	movq	0+24(%rsp),%r10
+	leaq	64(%rsp),%rdi
+
+	call	__ecp_nistz256_subq
+
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+	movq	352(%rsp),%rax
+	leaq	352(%rsp),%rbx
+	movq	0+160(%rsp),%r9
+	movq	8+160(%rsp),%r10
+	leaq	0+160(%rsp),%rsi
+	movq	16+160(%rsp),%r11
+	movq	24+160(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	96(%rsp),%rax
+	leaq	96(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	32(%rsp),%rbx
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+.byte	102,72,15,126,199
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	288(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	288+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	.LONE_mont(%rip),%xmm2
+	pand	.LONE_mont+16(%rip),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	384(%rsp),%xmm2
+	pand	384+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,64(%rdi)
+	movdqu	%xmm3,80(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	224(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	224+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	416(%rsp),%xmm2
+	pand	416+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	320(%rsp),%xmm2
+	pand	320+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	256(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	256+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	448(%rsp),%xmm2
+	pand	448+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	352(%rsp),%xmm2
+	pand	352+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+
+	addq	$480+8,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+.size	ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
+#endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/md5/md5-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/md5/md5-x86_64.S
index 7644689..05369e2 100644
--- a/third_party/boringssl/linux-x86_64/crypto/md5/md5-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/md5/md5-x86_64.S
@@ -495,14 +495,14 @@
 	movl	%ecx,%r11d
 	addl	%ecx,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	xorl	%edx,%r11d
 	leal	-198630844(%rax,%r10,1),%eax
 	orl	%ebx,%r11d
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	28(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -511,7 +511,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	56(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -520,7 +520,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	20(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -529,7 +529,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	48(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -538,7 +538,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	12(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -547,7 +547,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	40(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -556,7 +556,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	4(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -565,7 +565,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	32(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -574,7 +574,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	60(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -583,7 +583,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	24(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -592,7 +592,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	52(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -601,7 +601,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	16(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -610,7 +610,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	44(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -619,7 +619,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	8(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -628,7 +628,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	36(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -637,7 +637,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
diff --git a/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S
index 1db7d69..b47bdc9b 100644
--- a/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/modes/ghash-x86_64.S
@@ -23,14 +23,14 @@
 	movq	$14,%rcx
 	movq	8(%rsi,%rax,1),%r8
 	movq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	movq	%r8,%rdx
 	jmp	.Loop1
 
 .align	16
 .Loop1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	movb	(%rdi,%rcx,1),%al
 	shrq	$4,%r9
@@ -46,13 +46,13 @@
 	js	.Lbreak1
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
@@ -61,19 +61,19 @@
 .align	16
 .Lbreak1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rbx,1),%r8
@@ -881,20 +881,20 @@
 	movdqu	32(%rsi),%xmm7
 .byte	102,65,15,56,0,194
 
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	.Lodd_tail
 
 	movdqu	16(%rsi),%xmm6
 	movl	OPENSSL_ia32cap_P+4(%rip),%eax
-	cmpq	$48,%rcx
+	cmpq	$0x30,%rcx
 	jb	.Lskip4x
 
 	andl	$71303168,%eax
 	cmpl	$4194304,%eax
 	je	.Lskip4x
 
-	subq	$48,%rcx
-	movq	$11547335547999543296,%rax
+	subq	$0x30,%rcx
+	movq	$0xA040608020C0E000,%rax
 	movdqu	48(%rsi),%xmm14
 	movdqu	64(%rsi),%xmm15
 
@@ -941,7 +941,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jc	.Ltail4x
 
 	jmp	.Lmod4_loop
@@ -1024,7 +1024,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jnc	.Lmod4_loop
 
 .Ltail4x:
@@ -1068,10 +1068,10 @@
 	pxor	%xmm4,%xmm0
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
-	addq	$64,%rcx
+	addq	$0x40,%rcx
 	jz	.Ldone
 	movdqu	32(%rsi),%xmm7
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	.Lodd_tail
 .Lskip4x:
 
@@ -1094,7 +1094,7 @@
 
 	leaq	32(%rdx),%rdx
 	nop
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	jbe	.Leven_tail
 	nop
 	jmp	.Lmod_loop
@@ -1157,7 +1157,7 @@
 .byte	102,15,58,68,231,0
 	pxor	%xmm1,%xmm0
 
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	ja	.Lmod_loop
 
 .Leven_tail:
diff --git a/third_party/boringssl/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S
deleted file mode 100644
index 06c8d67..0000000
--- a/third_party/boringssl/linux-x86_64/crypto/rc4/rc4-md5-x86_64.S
+++ /dev/null
@@ -1,1262 +0,0 @@
-#if defined(__x86_64__)
-.text	
-.align	16
-
-.globl	rc4_md5_enc
-.hidden rc4_md5_enc
-.type	rc4_md5_enc,@function
-rc4_md5_enc:
-	cmpq	$0,%r9
-	je	.Labort
-	pushq	%rbx
-	pushq	%rbp
-	pushq	%r12
-	pushq	%r13
-	pushq	%r14
-	pushq	%r15
-	subq	$40,%rsp
-.Lbody:
-	movq	%rcx,%r11
-	movq	%r9,%r12
-	movq	%rsi,%r13
-	movq	%rdx,%r14
-	movq	%r8,%r15
-	xorq	%rbp,%rbp
-	xorq	%rcx,%rcx
-
-	leaq	8(%rdi),%rdi
-	movb	-8(%rdi),%bpl
-	movb	-4(%rdi),%cl
-
-	incb	%bpl
-	subq	%r13,%r14
-	movl	(%rdi,%rbp,4),%eax
-	addb	%al,%cl
-	leaq	(%rdi,%rbp,4),%rsi
-	shlq	$6,%r12
-	addq	%r15,%r12
-	movq	%r12,16(%rsp)
-
-	movq	%r11,24(%rsp)
-	movl	0(%r11),%r8d
-	movl	4(%r11),%r9d
-	movl	8(%r11),%r10d
-	movl	12(%r11),%r11d
-	jmp	.Loop
-
-.align	16
-.Loop:
-	movl	%r8d,0(%rsp)
-	movl	%r9d,4(%rsp)
-	movl	%r10d,8(%rsp)
-	movl	%r11d,%r12d
-	movl	%r11d,12(%rsp)
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	0(%r15),%r8d
-	addb	%dl,%al
-	movl	4(%rsi),%ebx
-	addl	$3614090360,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,0(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	4(%r15),%r11d
-	addb	%dl,%bl
-	movl	8(%rsi),%eax
-	addl	$3905402710,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,4(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	8(%r15),%r10d
-	addb	%dl,%al
-	movl	12(%rsi),%ebx
-	addl	$606105819,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,8(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	12(%r15),%r9d
-	addb	%dl,%bl
-	movl	16(%rsi),%eax
-	addl	$3250441966,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,12(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	16(%r15),%r8d
-	addb	%dl,%al
-	movl	20(%rsi),%ebx
-	addl	$4118548399,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,16(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	20(%r15),%r11d
-	addb	%dl,%bl
-	movl	24(%rsi),%eax
-	addl	$1200080426,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,20(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	24(%r15),%r10d
-	addb	%dl,%al
-	movl	28(%rsi),%ebx
-	addl	$2821735955,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,24(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	28(%r15),%r9d
-	addb	%dl,%bl
-	movl	32(%rsi),%eax
-	addl	$4249261313,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,28(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	32(%r15),%r8d
-	addb	%dl,%al
-	movl	36(%rsi),%ebx
-	addl	$1770035416,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,32(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	36(%r15),%r11d
-	addb	%dl,%bl
-	movl	40(%rsi),%eax
-	addl	$2336552879,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,36(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	40(%r15),%r10d
-	addb	%dl,%al
-	movl	44(%rsi),%ebx
-	addl	$4294925233,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,40(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	44(%r15),%r9d
-	addb	%dl,%bl
-	movl	48(%rsi),%eax
-	addl	$2304563134,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,44(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	48(%r15),%r8d
-	addb	%dl,%al
-	movl	52(%rsi),%ebx
-	addl	$1804603682,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,48(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	52(%r15),%r11d
-	addb	%dl,%bl
-	movl	56(%rsi),%eax
-	addl	$4254626195,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,52(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	56(%r15),%r10d
-	addb	%dl,%al
-	movl	60(%rsi),%ebx
-	addl	$2792965006,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,56(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	(%r13),%xmm2
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	60(%r15),%r9d
-	addb	%dl,%bl
-	movl	64(%rsi),%eax
-	addl	$1236535329,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,60(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm2
-	pxor	%xmm1,%xmm2
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	4(%r15),%r8d
-	addb	%dl,%al
-	movl	68(%rsi),%ebx
-	addl	$4129170786,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,64(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	24(%r15),%r11d
-	addb	%dl,%bl
-	movl	72(%rsi),%eax
-	addl	$3225465664,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,68(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	44(%r15),%r10d
-	addb	%dl,%al
-	movl	76(%rsi),%ebx
-	addl	$643717713,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,72(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	0(%r15),%r9d
-	addb	%dl,%bl
-	movl	80(%rsi),%eax
-	addl	$3921069994,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,76(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	20(%r15),%r8d
-	addb	%dl,%al
-	movl	84(%rsi),%ebx
-	addl	$3593408605,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,80(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	40(%r15),%r11d
-	addb	%dl,%bl
-	movl	88(%rsi),%eax
-	addl	$38016083,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,84(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	60(%r15),%r10d
-	addb	%dl,%al
-	movl	92(%rsi),%ebx
-	addl	$3634488961,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,88(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	16(%r15),%r9d
-	addb	%dl,%bl
-	movl	96(%rsi),%eax
-	addl	$3889429448,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,92(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	36(%r15),%r8d
-	addb	%dl,%al
-	movl	100(%rsi),%ebx
-	addl	$568446438,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,96(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	56(%r15),%r11d
-	addb	%dl,%bl
-	movl	104(%rsi),%eax
-	addl	$3275163606,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,100(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	12(%r15),%r10d
-	addb	%dl,%al
-	movl	108(%rsi),%ebx
-	addl	$4107603335,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,104(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	32(%r15),%r9d
-	addb	%dl,%bl
-	movl	112(%rsi),%eax
-	addl	$1163531501,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,108(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	52(%r15),%r8d
-	addb	%dl,%al
-	movl	116(%rsi),%ebx
-	addl	$2850285829,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,112(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	8(%r15),%r11d
-	addb	%dl,%bl
-	movl	120(%rsi),%eax
-	addl	$4243563512,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,116(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	28(%r15),%r10d
-	addb	%dl,%al
-	movl	124(%rsi),%ebx
-	addl	$1735328473,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,120(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	16(%r13),%xmm3
-	addb	$32,%bpl
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	48(%r15),%r9d
-	addb	%dl,%bl
-	movl	0(%rdi,%rbp,4),%eax
-	addl	$2368359562,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,124(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movq	%rcx,%rsi
-	xorq	%rcx,%rcx
-	movb	%sil,%cl
-	leaq	(%rdi,%rbp,4),%rsi
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm3
-	pxor	%xmm1,%xmm3
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	20(%r15),%r8d
-	addb	%dl,%al
-	movl	4(%rsi),%ebx
-	addl	$4294588738,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,0(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	32(%r15),%r11d
-	addb	%dl,%bl
-	movl	8(%rsi),%eax
-	addl	$2272392833,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,4(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	44(%r15),%r10d
-	addb	%dl,%al
-	movl	12(%rsi),%ebx
-	addl	$1839030562,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,8(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	56(%r15),%r9d
-	addb	%dl,%bl
-	movl	16(%rsi),%eax
-	addl	$4259657740,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,12(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	4(%r15),%r8d
-	addb	%dl,%al
-	movl	20(%rsi),%ebx
-	addl	$2763975236,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,16(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	16(%r15),%r11d
-	addb	%dl,%bl
-	movl	24(%rsi),%eax
-	addl	$1272893353,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,20(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	28(%r15),%r10d
-	addb	%dl,%al
-	movl	28(%rsi),%ebx
-	addl	$4139469664,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,24(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	40(%r15),%r9d
-	addb	%dl,%bl
-	movl	32(%rsi),%eax
-	addl	$3200236656,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,28(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	52(%r15),%r8d
-	addb	%dl,%al
-	movl	36(%rsi),%ebx
-	addl	$681279174,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,32(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	0(%r15),%r11d
-	addb	%dl,%bl
-	movl	40(%rsi),%eax
-	addl	$3936430074,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,36(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	12(%r15),%r10d
-	addb	%dl,%al
-	movl	44(%rsi),%ebx
-	addl	$3572445317,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,40(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	24(%r15),%r9d
-	addb	%dl,%bl
-	movl	48(%rsi),%eax
-	addl	$76029189,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,44(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	36(%r15),%r8d
-	addb	%dl,%al
-	movl	52(%rsi),%ebx
-	addl	$3654602809,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,48(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	48(%r15),%r11d
-	addb	%dl,%bl
-	movl	56(%rsi),%eax
-	addl	$3873151461,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,52(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	60(%r15),%r10d
-	addb	%dl,%al
-	movl	60(%rsi),%ebx
-	addl	$530742520,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,56(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	32(%r13),%xmm4
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	8(%r15),%r9d
-	addb	%dl,%bl
-	movl	64(%rsi),%eax
-	addl	$3299628645,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,60(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	$-1,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm4
-	pxor	%xmm1,%xmm4
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	0(%r15),%r8d
-	addb	%dl,%al
-	movl	68(%rsi),%ebx
-	addl	$4096336452,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,64(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	28(%r15),%r11d
-	addb	%dl,%bl
-	movl	72(%rsi),%eax
-	addl	$1126891415,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,68(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	56(%r15),%r10d
-	addb	%dl,%al
-	movl	76(%rsi),%ebx
-	addl	$2878612391,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,72(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	20(%r15),%r9d
-	addb	%dl,%bl
-	movl	80(%rsi),%eax
-	addl	$4237533241,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,76(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	48(%r15),%r8d
-	addb	%dl,%al
-	movl	84(%rsi),%ebx
-	addl	$1700485571,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,80(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	12(%r15),%r11d
-	addb	%dl,%bl
-	movl	88(%rsi),%eax
-	addl	$2399980690,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,84(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	40(%r15),%r10d
-	addb	%dl,%al
-	movl	92(%rsi),%ebx
-	addl	$4293915773,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,88(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	4(%r15),%r9d
-	addb	%dl,%bl
-	movl	96(%rsi),%eax
-	addl	$2240044497,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,92(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	32(%r15),%r8d
-	addb	%dl,%al
-	movl	100(%rsi),%ebx
-	addl	$1873313359,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,96(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	60(%r15),%r11d
-	addb	%dl,%bl
-	movl	104(%rsi),%eax
-	addl	$4264355552,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,100(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	24(%r15),%r10d
-	addb	%dl,%al
-	movl	108(%rsi),%ebx
-	addl	$2734768916,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,104(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	52(%r15),%r9d
-	addb	%dl,%bl
-	movl	112(%rsi),%eax
-	addl	$1309151649,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,108(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	16(%r15),%r8d
-	addb	%dl,%al
-	movl	116(%rsi),%ebx
-	addl	$4149444226,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,112(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	44(%r15),%r11d
-	addb	%dl,%bl
-	movl	120(%rsi),%eax
-	addl	$3174756917,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,116(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	8(%r15),%r10d
-	addb	%dl,%al
-	movl	124(%rsi),%ebx
-	addl	$718787259,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,120(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	48(%r13),%xmm5
-	addb	$32,%bpl
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	36(%r15),%r9d
-	addb	%dl,%bl
-	movl	0(%rdi,%rbp,4),%eax
-	addl	$3951481745,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,124(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movq	%rbp,%rsi
-	xorq	%rbp,%rbp
-	movb	%sil,%bpl
-	movq	%rcx,%rsi
-	xorq	%rcx,%rcx
-	movb	%sil,%cl
-	leaq	(%rdi,%rbp,4),%rsi
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm5
-	pxor	%xmm1,%xmm5
-	addl	0(%rsp),%r8d
-	addl	4(%rsp),%r9d
-	addl	8(%rsp),%r10d
-	addl	12(%rsp),%r11d
-
-	movdqu	%xmm2,(%r14,%r13,1)
-	movdqu	%xmm3,16(%r14,%r13,1)
-	movdqu	%xmm4,32(%r14,%r13,1)
-	movdqu	%xmm5,48(%r14,%r13,1)
-	leaq	64(%r15),%r15
-	leaq	64(%r13),%r13
-	cmpq	16(%rsp),%r15
-	jb	.Loop
-
-	movq	24(%rsp),%r12
-	subb	%al,%cl
-	movl	%r8d,0(%r12)
-	movl	%r9d,4(%r12)
-	movl	%r10d,8(%r12)
-	movl	%r11d,12(%r12)
-	subb	$1,%bpl
-	movl	%ebp,-8(%rdi)
-	movl	%ecx,-4(%rdi)
-
-	movq	40(%rsp),%r15
-	movq	48(%rsp),%r14
-	movq	56(%rsp),%r13
-	movq	64(%rsp),%r12
-	movq	72(%rsp),%rbp
-	movq	80(%rsp),%rbx
-	leaq	88(%rsp),%rsp
-.Lepilogue:
-.Labort:
-	.byte	0xf3,0xc3
-.size	rc4_md5_enc,.-rc4_md5_enc
-#endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/sha/sha1-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/sha/sha1-x86_64.S
index 7668c2b..d830b53 100644
--- a/third_party/boringssl/linux-x86_64/crypto/sha/sha1-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/sha/sha1-x86_64.S
@@ -13,6 +13,11 @@
 	movl	OPENSSL_ia32cap_P+8(%rip),%r10d
 	testl	$512,%r8d
 	jz	.Lialu
+	andl	$268435456,%r8d
+	andl	$1073741824,%r9d
+	orl	%r9d,%r8d
+	cmpl	$1342177280,%r8d
+	je	_avx_shortcut
 	jmp	_ssse3_shortcut
 
 .align	16
@@ -2408,6 +2413,1122 @@
 .Lepilogue_ssse3:
 	.byte	0xf3,0xc3
 .size	sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3
+.type	sha1_block_data_order_avx,@function
+.align	16
+sha1_block_data_order_avx:
+_avx_shortcut:
+	movq	%rsp,%rax
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	leaq	-64(%rsp),%rsp
+	vzeroupper
+	movq	%rax,%r14
+	andq	$-64,%rsp
+	movq	%rdi,%r8
+	movq	%rsi,%r9
+	movq	%rdx,%r10
+
+	shlq	$6,%r10
+	addq	%r9,%r10
+	leaq	K_XX_XX+64(%rip),%r11
+
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movl	%ebx,%esi
+	movl	16(%r8),%ebp
+	movl	%ecx,%edi
+	xorl	%edx,%edi
+	andl	%edi,%esi
+
+	vmovdqa	64(%r11),%xmm6
+	vmovdqa	-64(%r11),%xmm11
+	vmovdqu	0(%r9),%xmm0
+	vmovdqu	16(%r9),%xmm1
+	vmovdqu	32(%r9),%xmm2
+	vmovdqu	48(%r9),%xmm3
+	vpshufb	%xmm6,%xmm0,%xmm0
+	addq	$64,%r9
+	vpshufb	%xmm6,%xmm1,%xmm1
+	vpshufb	%xmm6,%xmm2,%xmm2
+	vpshufb	%xmm6,%xmm3,%xmm3
+	vpaddd	%xmm11,%xmm0,%xmm4
+	vpaddd	%xmm11,%xmm1,%xmm5
+	vpaddd	%xmm11,%xmm2,%xmm6
+	vmovdqa	%xmm4,0(%rsp)
+	vmovdqa	%xmm5,16(%rsp)
+	vmovdqa	%xmm6,32(%rsp)
+	jmp	.Loop_avx
+.align	16
+.Loop_avx:
+	shrdl	$2,%ebx,%ebx
+	xorl	%edx,%esi
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	movl	%eax,%edi
+	addl	0(%rsp),%ebp
+	vpaddd	%xmm3,%xmm11,%xmm9
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrldq	$4,%xmm3,%xmm8
+	addl	%esi,%ebp
+	andl	%ebx,%edi
+	vpxor	%xmm0,%xmm4,%xmm4
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpxor	%xmm2,%xmm8,%xmm8
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	addl	4(%rsp),%edx
+	vpxor	%xmm8,%xmm4,%xmm4
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	vmovdqa	%xmm9,48(%rsp)
+	addl	%edi,%edx
+	andl	%eax,%esi
+	vpsrld	$31,%xmm4,%xmm8
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%esi
+	vpslldq	$12,%xmm4,%xmm10
+	vpaddd	%xmm4,%xmm4,%xmm4
+	movl	%edx,%edi
+	addl	8(%rsp),%ecx
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm4,%xmm4
+	addl	%esi,%ecx
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm4,%xmm4
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	addl	12(%rsp),%ebx
+	vpxor	%xmm10,%xmm4,%xmm4
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%ebp,%esi
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	movl	%ebx,%edi
+	addl	16(%rsp),%eax
+	vpaddd	%xmm4,%xmm11,%xmm9
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrldq	$4,%xmm4,%xmm8
+	addl	%esi,%eax
+	andl	%ecx,%edi
+	vpxor	%xmm1,%xmm5,%xmm5
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm3,%xmm8,%xmm8
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	addl	20(%rsp),%ebp
+	vpxor	%xmm8,%xmm5,%xmm5
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vmovdqa	%xmm9,0(%rsp)
+	addl	%edi,%ebp
+	andl	%ebx,%esi
+	vpsrld	$31,%xmm5,%xmm8
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	vpslldq	$12,%xmm5,%xmm10
+	vpaddd	%xmm5,%xmm5,%xmm5
+	movl	%ebp,%edi
+	addl	24(%rsp),%edx
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm5,%xmm5
+	addl	%esi,%edx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm5,%xmm5
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	addl	28(%rsp),%ecx
+	vpxor	%xmm10,%xmm5,%xmm5
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vmovdqa	-32(%r11),%xmm11
+	addl	%edi,%ecx
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	vpalignr	$8,%xmm2,%xmm3,%xmm6
+	movl	%ecx,%edi
+	addl	32(%rsp),%ebx
+	vpaddd	%xmm5,%xmm11,%xmm9
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	vpsrldq	$4,%xmm5,%xmm8
+	addl	%esi,%ebx
+	andl	%edx,%edi
+	vpxor	%xmm2,%xmm6,%xmm6
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm4,%xmm8,%xmm8
+	shrdl	$7,%ecx,%ecx
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	addl	36(%rsp),%eax
+	vpxor	%xmm8,%xmm6,%xmm6
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vmovdqa	%xmm9,16(%rsp)
+	addl	%edi,%eax
+	andl	%ecx,%esi
+	vpsrld	$31,%xmm6,%xmm8
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%esi
+	vpslldq	$12,%xmm6,%xmm10
+	vpaddd	%xmm6,%xmm6,%xmm6
+	movl	%eax,%edi
+	addl	40(%rsp),%ebp
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm6,%xmm6
+	addl	%esi,%ebp
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm6,%xmm6
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	addl	44(%rsp),%edx
+	vpxor	%xmm10,%xmm6,%xmm6
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%esi
+	vpalignr	$8,%xmm3,%xmm4,%xmm7
+	movl	%edx,%edi
+	addl	48(%rsp),%ecx
+	vpaddd	%xmm6,%xmm11,%xmm9
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vpsrldq	$4,%xmm6,%xmm8
+	addl	%esi,%ecx
+	andl	%ebp,%edi
+	vpxor	%xmm3,%xmm7,%xmm7
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	vpxor	%xmm5,%xmm8,%xmm8
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	addl	52(%rsp),%ebx
+	vpxor	%xmm8,%xmm7,%xmm7
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	vmovdqa	%xmm9,32(%rsp)
+	addl	%edi,%ebx
+	andl	%edx,%esi
+	vpsrld	$31,%xmm7,%xmm8
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%ebp,%esi
+	vpslldq	$12,%xmm7,%xmm10
+	vpaddd	%xmm7,%xmm7,%xmm7
+	movl	%ebx,%edi
+	addl	56(%rsp),%eax
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm7,%xmm7
+	addl	%esi,%eax
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm7,%xmm7
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	addl	60(%rsp),%ebp
+	vpxor	%xmm10,%xmm7,%xmm7
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	vpxor	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	addl	0(%rsp),%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	vpaddd	%xmm7,%xmm11,%xmm9
+	addl	%esi,%edx
+	andl	%eax,%edi
+	vpxor	%xmm8,%xmm0,%xmm0
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%edi
+	vpsrld	$30,%xmm0,%xmm8
+	vmovdqa	%xmm9,48(%rsp)
+	movl	%edx,%esi
+	addl	4(%rsp),%ecx
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vpslld	$2,%xmm0,%xmm0
+	addl	%edi,%ecx
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	addl	8(%rsp),%ebx
+	vpor	%xmm8,%xmm0,%xmm0
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	12(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	vpxor	%xmm2,%xmm1,%xmm1
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	vpaddd	%xmm0,%xmm11,%xmm9
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpxor	%xmm8,%xmm1,%xmm1
+	addl	20(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	vpsrld	$30,%xmm1,%xmm8
+	vmovdqa	%xmm9,0(%rsp)
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpslld	$2,%xmm1,%xmm1
+	addl	24(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpor	%xmm8,%xmm1,%xmm1
+	addl	28(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	vpxor	%xmm3,%xmm2,%xmm2
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	vpaddd	%xmm1,%xmm11,%xmm9
+	vmovdqa	0(%r11),%xmm11
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm8,%xmm2,%xmm2
+	addl	36(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm2,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpslld	$2,%xmm2,%xmm2
+	addl	40(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpor	%xmm8,%xmm2,%xmm2
+	addl	44(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	vpxor	%xmm4,%xmm3,%xmm3
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	vpaddd	%xmm2,%xmm11,%xmm9
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm8,%xmm3,%xmm3
+	addl	52(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm3,%xmm8
+	vmovdqa	%xmm9,32(%rsp)
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpor	%xmm8,%xmm3,%xmm3
+	addl	60(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpalignr	$8,%xmm2,%xmm3,%xmm8
+	vpxor	%xmm0,%xmm4,%xmm4
+	addl	0(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	vpaddd	%xmm3,%xmm11,%xmm9
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpxor	%xmm8,%xmm4,%xmm4
+	addl	4(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	vpsrld	$30,%xmm4,%xmm8
+	vmovdqa	%xmm9,48(%rsp)
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpslld	$2,%xmm4,%xmm4
+	addl	8(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpor	%xmm8,%xmm4,%xmm4
+	addl	12(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpalignr	$8,%xmm3,%xmm4,%xmm8
+	vpxor	%xmm1,%xmm5,%xmm5
+	addl	16(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	vpxor	%xmm6,%xmm5,%xmm5
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	vpaddd	%xmm4,%xmm11,%xmm9
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpxor	%xmm8,%xmm5,%xmm5
+	addl	20(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm5,%xmm8
+	vmovdqa	%xmm9,0(%rsp)
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpslld	$2,%xmm5,%xmm5
+	addl	24(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpor	%xmm8,%xmm5,%xmm5
+	addl	28(%rsp),%eax
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm4,%xmm5,%xmm8
+	vpxor	%xmm2,%xmm6,%xmm6
+	addl	32(%rsp),%ebp
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%eax,%edi
+	xorl	%ecx,%esi
+	vpaddd	%xmm5,%xmm11,%xmm9
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	vpxor	%xmm8,%xmm6,%xmm6
+	xorl	%ebx,%edi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	addl	36(%rsp),%edx
+	vpsrld	$30,%xmm6,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%ebp,%esi
+	vpslld	$2,%xmm6,%xmm6
+	xorl	%ebx,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	addl	40(%rsp),%ecx
+	andl	%eax,%esi
+	vpor	%xmm8,%xmm6,%xmm6
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	movl	%edx,%edi
+	xorl	%eax,%esi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%ebp,%edi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	addl	44(%rsp),%ebx
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	xorl	%ebp,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm5,%xmm6,%xmm8
+	vpxor	%xmm3,%xmm7,%xmm7
+	addl	48(%rsp),%eax
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	vpxor	%xmm0,%xmm7,%xmm7
+	movl	%ebx,%edi
+	xorl	%edx,%esi
+	vpaddd	%xmm6,%xmm11,%xmm9
+	vmovdqa	32(%r11),%xmm11
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vpxor	%xmm8,%xmm7,%xmm7
+	xorl	%ecx,%edi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	52(%rsp),%ebp
+	vpsrld	$30,%xmm7,%xmm8
+	vmovdqa	%xmm9,32(%rsp)
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	vpslld	$2,%xmm7,%xmm7
+	xorl	%ecx,%edi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	addl	56(%rsp),%edx
+	andl	%ebx,%esi
+	vpor	%xmm8,%xmm7,%xmm7
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%ebp,%edi
+	xorl	%ebx,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%eax,%edi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	addl	60(%rsp),%ecx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	movl	%edx,%esi
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	vpxor	%xmm4,%xmm0,%xmm0
+	addl	0(%rsp),%ebx
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	movl	%ecx,%edi
+	xorl	%ebp,%esi
+	vpaddd	%xmm7,%xmm11,%xmm9
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	vpxor	%xmm8,%xmm0,%xmm0
+	xorl	%edx,%edi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	4(%rsp),%eax
+	vpsrld	$30,%xmm0,%xmm8
+	vmovdqa	%xmm9,48(%rsp)
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	vpslld	$2,%xmm0,%xmm0
+	xorl	%edx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	8(%rsp),%ebp
+	andl	%ecx,%esi
+	vpor	%xmm8,%xmm0,%xmm0
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%edi
+	xorl	%ecx,%esi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ebx,%edi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	addl	12(%rsp),%edx
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%ebp,%esi
+	xorl	%ebx,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%rsp),%ecx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	vpxor	%xmm2,%xmm1,%xmm1
+	movl	%edx,%edi
+	xorl	%eax,%esi
+	vpaddd	%xmm0,%xmm11,%xmm9
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	vpxor	%xmm8,%xmm1,%xmm1
+	xorl	%ebp,%edi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	addl	20(%rsp),%ebx
+	vpsrld	$30,%xmm1,%xmm8
+	vmovdqa	%xmm9,0(%rsp)
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	vpslld	$2,%xmm1,%xmm1
+	xorl	%ebp,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	24(%rsp),%eax
+	andl	%edx,%esi
+	vpor	%xmm8,%xmm1,%xmm1
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%edi
+	xorl	%edx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%ecx,%edi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	28(%rsp),%ebp
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	xorl	%ecx,%edi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%rsp),%edx
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	vpxor	%xmm3,%xmm2,%xmm2
+	movl	%ebp,%edi
+	xorl	%ebx,%esi
+	vpaddd	%xmm1,%xmm11,%xmm9
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	vpxor	%xmm8,%xmm2,%xmm2
+	xorl	%eax,%edi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	addl	36(%rsp),%ecx
+	vpsrld	$30,%xmm2,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	movl	%edx,%esi
+	vpslld	$2,%xmm2,%xmm2
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	addl	40(%rsp),%ebx
+	andl	%ebp,%esi
+	vpor	%xmm8,%xmm2,%xmm2
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%edi
+	xorl	%ebp,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edx,%edi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	44(%rsp),%eax
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	vpxor	%xmm4,%xmm3,%xmm3
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	vpaddd	%xmm2,%xmm11,%xmm9
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpxor	%xmm8,%xmm3,%xmm3
+	addl	52(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	vpsrld	$30,%xmm3,%xmm8
+	vmovdqa	%xmm9,32(%rsp)
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpor	%xmm8,%xmm3,%xmm3
+	addl	60(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	0(%rsp),%eax
+	vpaddd	%xmm3,%xmm11,%xmm9
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vmovdqa	%xmm9,48(%rsp)
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	4(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	8(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	12(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	cmpq	%r10,%r9
+	je	.Ldone_avx
+	vmovdqa	64(%r11),%xmm6
+	vmovdqa	-64(%r11),%xmm11
+	vmovdqu	0(%r9),%xmm0
+	vmovdqu	16(%r9),%xmm1
+	vmovdqu	32(%r9),%xmm2
+	vmovdqu	48(%r9),%xmm3
+	vpshufb	%xmm6,%xmm0,%xmm0
+	addq	$64,%r9
+	addl	16(%rsp),%ebx
+	xorl	%ebp,%esi
+	vpshufb	%xmm6,%xmm1,%xmm1
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	vpaddd	%xmm11,%xmm0,%xmm4
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vmovdqa	%xmm4,0(%rsp)
+	addl	20(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	32(%rsp),%ecx
+	xorl	%eax,%esi
+	vpshufb	%xmm6,%xmm2,%xmm2
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	vpaddd	%xmm11,%xmm1,%xmm5
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vmovdqa	%xmm5,16(%rsp)
+	addl	36(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ebx,%esi
+	vpshufb	%xmm6,%xmm3,%xmm3
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	vpaddd	%xmm11,%xmm2,%xmm6
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vmovdqa	%xmm6,32(%rsp)
+	addl	52(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	addl	12(%r8),%edx
+	movl	%eax,0(%r8)
+	addl	16(%r8),%ebp
+	movl	%esi,4(%r8)
+	movl	%esi,%ebx
+	movl	%ecx,8(%r8)
+	movl	%ecx,%edi
+	movl	%edx,12(%r8)
+	xorl	%edx,%edi
+	movl	%ebp,16(%r8)
+	andl	%edi,%esi
+	jmp	.Loop_avx
+
+.align	16
+.Ldone_avx:
+	addl	16(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	20(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	32(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	addl	36(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	52(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vzeroupper
+
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	movl	%eax,0(%r8)
+	addl	12(%r8),%edx
+	movl	%esi,4(%r8)
+	addl	16(%r8),%ebp
+	movl	%ecx,8(%r8)
+	movl	%edx,12(%r8)
+	movl	%ebp,16(%r8)
+	leaq	(%r14),%rsi
+	movq	-40(%rsi),%r14
+	movq	-32(%rsi),%r13
+	movq	-24(%rsi),%r12
+	movq	-16(%rsi),%rbp
+	movq	-8(%rsi),%rbx
+	leaq	(%rsi),%rsp
+.Lepilogue_avx:
+	.byte	0xf3,0xc3
+.size	sha1_block_data_order_avx,.-sha1_block_data_order_avx
 .align	64
 K_XX_XX:
 .long	0x5a827999,0x5a827999,0x5a827999,0x5a827999
diff --git a/third_party/boringssl/linux-x86_64/crypto/sha/sha256-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/sha/sha256-x86_64.S
index f526de5..445b497 100644
--- a/third_party/boringssl/linux-x86_64/crypto/sha/sha256-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/sha/sha256-x86_64.S
@@ -12,6 +12,11 @@
 	movl	0(%r11),%r9d
 	movl	4(%r11),%r10d
 	movl	8(%r11),%r11d
+	andl	$1073741824,%r9d
+	andl	$268435968,%r10d
+	orl	%r9d,%r10d
+	cmpl	$1342177792,%r10d
+	je	.Lavx_shortcut
 	testl	$512,%r10d
 	jnz	.Lssse3_shortcut
 	pushq	%rbx
@@ -2841,4 +2846,1061 @@
 .Lepilogue_ssse3:
 	.byte	0xf3,0xc3
 .size	sha256_block_data_order_ssse3,.-sha256_block_data_order_ssse3
+.type	sha256_block_data_order_avx,@function
+.align	64
+sha256_block_data_order_avx:
+.Lavx_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$96,%rsp
+	leaq	(%rsi,%rdx,4),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,64+0(%rsp)
+	movq	%rsi,64+8(%rsp)
+	movq	%rdx,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+.Lprologue_avx:
+
+	vzeroupper
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+	movl	16(%rdi),%r8d
+	movl	20(%rdi),%r9d
+	movl	24(%rdi),%r10d
+	movl	28(%rdi),%r11d
+	vmovdqa	K256+512+32(%rip),%xmm8
+	vmovdqa	K256+512+64(%rip),%xmm9
+	jmp	.Lloop_avx
+.align	16
+.Lloop_avx:
+	vmovdqa	K256+512(%rip),%xmm7
+	vmovdqu	0(%rsi),%xmm0
+	vmovdqu	16(%rsi),%xmm1
+	vmovdqu	32(%rsi),%xmm2
+	vmovdqu	48(%rsi),%xmm3
+	vpshufb	%xmm7,%xmm0,%xmm0
+	leaq	K256(%rip),%rbp
+	vpshufb	%xmm7,%xmm1,%xmm1
+	vpshufb	%xmm7,%xmm2,%xmm2
+	vpaddd	0(%rbp),%xmm0,%xmm4
+	vpshufb	%xmm7,%xmm3,%xmm3
+	vpaddd	32(%rbp),%xmm1,%xmm5
+	vpaddd	64(%rbp),%xmm2,%xmm6
+	vpaddd	96(%rbp),%xmm3,%xmm7
+	vmovdqa	%xmm4,0(%rsp)
+	movl	%eax,%r14d
+	vmovdqa	%xmm5,16(%rsp)
+	movl	%ebx,%edi
+	vmovdqa	%xmm6,32(%rsp)
+	xorl	%ecx,%edi
+	vmovdqa	%xmm7,48(%rsp)
+	movl	%r8d,%r13d
+	jmp	.Lavx_00_47
+
+.align	16
+.Lavx_00_47:
+	subq	$-128,%rbp
+	vpalignr	$4,%xmm0,%xmm1,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	vpalignr	$4,%xmm2,%xmm3,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	vpaddd	%xmm7,%xmm0,%xmm0
+	xorl	%r8d,%r13d
+	addl	0(%rsp),%r11d
+	movl	%eax,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	vpshufd	$250,%xmm3,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	4(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	vpaddd	%xmm4,%xmm0,%xmm0
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	vpaddd	%xmm6,%xmm0,%xmm0
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	8(%rsp),%r9d
+	vpshufd	$80,%xmm0,%xmm7
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	vpaddd	%xmm6,%xmm0,%xmm0
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	vpaddd	0(%rbp),%xmm0,%xmm6
+	xorl	%ebx,%r13d
+	addl	12(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	vmovdqa	%xmm6,0(%rsp)
+	vpalignr	$4,%xmm1,%xmm2,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	vpalignr	$4,%xmm3,%xmm0,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	vpaddd	%xmm7,%xmm1,%xmm1
+	xorl	%eax,%r13d
+	addl	16(%rsp),%edx
+	movl	%r8d,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	vpshufd	$250,%xmm0,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	20(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	vpaddd	%xmm4,%xmm1,%xmm1
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	vpaddd	%xmm6,%xmm1,%xmm1
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	24(%rsp),%ebx
+	vpshufd	$80,%xmm1,%xmm7
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	vpaddd	%xmm6,%xmm1,%xmm1
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	vpaddd	32(%rbp),%xmm1,%xmm6
+	xorl	%r9d,%r13d
+	addl	28(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	vmovdqa	%xmm6,16(%rsp)
+	vpalignr	$4,%xmm2,%xmm3,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	vpalignr	$4,%xmm0,%xmm1,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	vpaddd	%xmm7,%xmm2,%xmm2
+	xorl	%r8d,%r13d
+	addl	32(%rsp),%r11d
+	movl	%eax,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	vpshufd	$250,%xmm1,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	36(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	vpaddd	%xmm4,%xmm2,%xmm2
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	vpaddd	%xmm6,%xmm2,%xmm2
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	40(%rsp),%r9d
+	vpshufd	$80,%xmm2,%xmm7
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	vpaddd	%xmm6,%xmm2,%xmm2
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	vpaddd	64(%rbp),%xmm2,%xmm6
+	xorl	%ebx,%r13d
+	addl	44(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	vmovdqa	%xmm6,32(%rsp)
+	vpalignr	$4,%xmm3,%xmm0,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	vpalignr	$4,%xmm1,%xmm2,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	vpaddd	%xmm7,%xmm3,%xmm3
+	xorl	%eax,%r13d
+	addl	48(%rsp),%edx
+	movl	%r8d,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	vpshufd	$250,%xmm2,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	52(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	vpaddd	%xmm4,%xmm3,%xmm3
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	vpaddd	%xmm6,%xmm3,%xmm3
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	56(%rsp),%ebx
+	vpshufd	$80,%xmm3,%xmm7
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	vpaddd	%xmm6,%xmm3,%xmm3
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	vpaddd	96(%rbp),%xmm3,%xmm6
+	xorl	%r9d,%r13d
+	addl	60(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	vmovdqa	%xmm6,48(%rsp)
+	cmpb	$0,131(%rbp)
+	jne	.Lavx_00_47
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	xorl	%r8d,%r13d
+	addl	0(%rsp),%r11d
+	movl	%eax,%r15d
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	addl	4(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	8(%rsp),%r9d
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	xorl	%ebx,%r13d
+	addl	12(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	xorl	%eax,%r13d
+	addl	16(%rsp),%edx
+	movl	%r8d,%r15d
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	addl	20(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	24(%rsp),%ebx
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	xorl	%r9d,%r13d
+	addl	28(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	xorl	%r8d,%r13d
+	addl	32(%rsp),%r11d
+	movl	%eax,%r15d
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	addl	36(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	40(%rsp),%r9d
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	xorl	%ebx,%r13d
+	addl	44(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	xorl	%eax,%r13d
+	addl	48(%rsp),%edx
+	movl	%r8d,%r15d
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	addl	52(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	56(%rsp),%ebx
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	xorl	%r9d,%r13d
+	addl	60(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	movq	64+0(%rsp),%rdi
+	movl	%r14d,%eax
+
+	addl	0(%rdi),%eax
+	leaq	64(%rsi),%rsi
+	addl	4(%rdi),%ebx
+	addl	8(%rdi),%ecx
+	addl	12(%rdi),%edx
+	addl	16(%rdi),%r8d
+	addl	20(%rdi),%r9d
+	addl	24(%rdi),%r10d
+	addl	28(%rdi),%r11d
+
+	cmpq	64+16(%rsp),%rsi
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	jb	.Lloop_avx
+
+	movq	64+24(%rsp),%rsi
+	vzeroupper
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lepilogue_avx:
+	.byte	0xf3,0xc3
+.size	sha256_block_data_order_avx,.-sha256_block_data_order_avx
 #endif
diff --git a/third_party/boringssl/linux-x86_64/crypto/sha/sha512-x86_64.S b/third_party/boringssl/linux-x86_64/crypto/sha/sha512-x86_64.S
index ca3a3a1..d65743f 100644
--- a/third_party/boringssl/linux-x86_64/crypto/sha/sha512-x86_64.S
+++ b/third_party/boringssl/linux-x86_64/crypto/sha/sha512-x86_64.S
@@ -8,6 +8,17 @@
 .type	sha512_block_data_order,@function
 .align	16
 sha512_block_data_order:
+	leaq	OPENSSL_ia32cap_P(%rip),%r11
+	movl	0(%r11),%r9d
+	movl	4(%r11),%r10d
+	movl	8(%r11),%r11d
+	testl	$2048,%r10d
+	jnz	.Lxop_shortcut
+	andl	$1073741824,%r9d
+	andl	$268435968,%r10d
+	orl	%r9d,%r10d
+	cmpl	$1342177792,%r10d
+	je	.Lavx_shortcut
 	pushq	%rbx
 	pushq	%rbp
 	pushq	%r12
@@ -1784,4 +1795,2234 @@
 .quad	0x0001020304050607,0x08090a0b0c0d0e0f
 .quad	0x0001020304050607,0x08090a0b0c0d0e0f
 .byte	83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.type	sha512_block_data_order_xop,@function
+.align	64
+sha512_block_data_order_xop:
+.Lxop_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$160,%rsp
+	leaq	(%rsi,%rdx,8),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,128+0(%rsp)
+	movq	%rsi,128+8(%rsp)
+	movq	%rdx,128+16(%rsp)
+	movq	%r11,128+24(%rsp)
+.Lprologue_xop:
+
+	vzeroupper
+	movq	0(%rdi),%rax
+	movq	8(%rdi),%rbx
+	movq	16(%rdi),%rcx
+	movq	24(%rdi),%rdx
+	movq	32(%rdi),%r8
+	movq	40(%rdi),%r9
+	movq	48(%rdi),%r10
+	movq	56(%rdi),%r11
+	jmp	.Lloop_xop
+.align	16
+.Lloop_xop:
+	vmovdqa	K512+1280(%rip),%xmm11
+	vmovdqu	0(%rsi),%xmm0
+	leaq	K512+128(%rip),%rbp
+	vmovdqu	16(%rsi),%xmm1
+	vmovdqu	32(%rsi),%xmm2
+	vpshufb	%xmm11,%xmm0,%xmm0
+	vmovdqu	48(%rsi),%xmm3
+	vpshufb	%xmm11,%xmm1,%xmm1
+	vmovdqu	64(%rsi),%xmm4
+	vpshufb	%xmm11,%xmm2,%xmm2
+	vmovdqu	80(%rsi),%xmm5
+	vpshufb	%xmm11,%xmm3,%xmm3
+	vmovdqu	96(%rsi),%xmm6
+	vpshufb	%xmm11,%xmm4,%xmm4
+	vmovdqu	112(%rsi),%xmm7
+	vpshufb	%xmm11,%xmm5,%xmm5
+	vpaddq	-128(%rbp),%xmm0,%xmm8
+	vpshufb	%xmm11,%xmm6,%xmm6
+	vpaddq	-96(%rbp),%xmm1,%xmm9
+	vpshufb	%xmm11,%xmm7,%xmm7
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	vpaddq	-32(%rbp),%xmm3,%xmm11
+	vmovdqa	%xmm8,0(%rsp)
+	vpaddq	0(%rbp),%xmm4,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	vpaddq	32(%rbp),%xmm5,%xmm9
+	vmovdqa	%xmm10,32(%rsp)
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	vmovdqa	%xmm11,48(%rsp)
+	vpaddq	96(%rbp),%xmm7,%xmm11
+	vmovdqa	%xmm8,64(%rsp)
+	movq	%rax,%r14
+	vmovdqa	%xmm9,80(%rsp)
+	movq	%rbx,%rdi
+	vmovdqa	%xmm10,96(%rsp)
+	xorq	%rcx,%rdi
+	vmovdqa	%xmm11,112(%rsp)
+	movq	%r8,%r13
+	jmp	.Lxop_00_47
+
+.align	16
+.Lxop_00_47:
+	addq	$256,%rbp
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm4,%xmm5,%xmm11
+	movq	%r9,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	vpaddq	%xmm11,%xmm0,%xmm0
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,223,3
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm7,%xmm10
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpaddq	%xmm8,%xmm0,%xmm0
+	movq	%rdx,%r13
+	addq	%r11,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r11
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpaddq	%xmm11,%xmm0,%xmm0
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	vpaddq	-128(%rbp),%xmm0,%xmm10
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,0(%rsp)
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm5,%xmm6,%xmm11
+	movq	%rdx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	vpaddq	%xmm11,%xmm1,%xmm1
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,216,3
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm0,%xmm10
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpaddq	%xmm8,%xmm1,%xmm1
+	movq	%rbx,%r13
+	addq	%r9,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r9
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpaddq	%xmm11,%xmm1,%xmm1
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	vpaddq	-96(%rbp),%xmm1,%xmm10
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,16(%rsp)
+	vpalignr	$8,%xmm2,%xmm3,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm6,%xmm7,%xmm11
+	movq	%rbx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	vpaddq	%xmm11,%xmm2,%xmm2
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,217,3
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm1,%xmm10
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpaddq	%xmm8,%xmm2,%xmm2
+	movq	%r11,%r13
+	addq	%rdx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpaddq	%xmm11,%xmm2,%xmm2
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,32(%rsp)
+	vpalignr	$8,%xmm3,%xmm4,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm7,%xmm0,%xmm11
+	movq	%r11,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	vpaddq	%xmm11,%xmm3,%xmm3
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,218,3
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm2,%xmm10
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpaddq	%xmm8,%xmm3,%xmm3
+	movq	%r9,%r13
+	addq	%rbx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpaddq	%xmm11,%xmm3,%xmm3
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	vpaddq	-32(%rbp),%xmm3,%xmm10
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,48(%rsp)
+	vpalignr	$8,%xmm4,%xmm5,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm0,%xmm1,%xmm11
+	movq	%r9,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	vpaddq	%xmm11,%xmm4,%xmm4
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,219,3
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm3,%xmm10
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpaddq	%xmm8,%xmm4,%xmm4
+	movq	%rdx,%r13
+	addq	%r11,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r11
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpaddq	%xmm11,%xmm4,%xmm4
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	vpaddq	0(%rbp),%xmm4,%xmm10
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,64(%rsp)
+	vpalignr	$8,%xmm5,%xmm6,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm1,%xmm2,%xmm11
+	movq	%rdx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	vpaddq	%xmm11,%xmm5,%xmm5
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,220,3
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm4,%xmm10
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpaddq	%xmm8,%xmm5,%xmm5
+	movq	%rbx,%r13
+	addq	%r9,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r9
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpaddq	%xmm11,%xmm5,%xmm5
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	vpaddq	32(%rbp),%xmm5,%xmm10
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,80(%rsp)
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm2,%xmm3,%xmm11
+	movq	%rbx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	vpaddq	%xmm11,%xmm6,%xmm6
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,221,3
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm5,%xmm10
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpaddq	%xmm8,%xmm6,%xmm6
+	movq	%r11,%r13
+	addq	%rdx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpaddq	%xmm11,%xmm6,%xmm6
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,96(%rsp)
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm3,%xmm4,%xmm11
+	movq	%r11,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	vpaddq	%xmm11,%xmm7,%xmm7
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,222,3
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm6,%xmm10
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpaddq	%xmm8,%xmm7,%xmm7
+	movq	%r9,%r13
+	addq	%rbx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpaddq	%xmm11,%xmm7,%xmm7
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	vpaddq	96(%rbp),%xmm7,%xmm10
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,112(%rsp)
+	cmpb	$0,135(%rbp)
+	jne	.Lxop_00_47
+	rorq	$23,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	rorq	$23,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	rorq	$23,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	rorq	$23,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	rorq	$23,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	rorq	$23,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	rorq	$23,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	rorq	$23,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	movq	128+0(%rsp),%rdi
+	movq	%r14,%rax
+
+	addq	0(%rdi),%rax
+	leaq	128(%rsi),%rsi
+	addq	8(%rdi),%rbx
+	addq	16(%rdi),%rcx
+	addq	24(%rdi),%rdx
+	addq	32(%rdi),%r8
+	addq	40(%rdi),%r9
+	addq	48(%rdi),%r10
+	addq	56(%rdi),%r11
+
+	cmpq	128+16(%rsp),%rsi
+
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+	movq	%r8,32(%rdi)
+	movq	%r9,40(%rdi)
+	movq	%r10,48(%rdi)
+	movq	%r11,56(%rdi)
+	jb	.Lloop_xop
+
+	movq	128+24(%rsp),%rsi
+	vzeroupper
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lepilogue_xop:
+	.byte	0xf3,0xc3
+.size	sha512_block_data_order_xop,.-sha512_block_data_order_xop
+.type	sha512_block_data_order_avx,@function
+.align	64
+sha512_block_data_order_avx:
+.Lavx_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$160,%rsp
+	leaq	(%rsi,%rdx,8),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,128+0(%rsp)
+	movq	%rsi,128+8(%rsp)
+	movq	%rdx,128+16(%rsp)
+	movq	%r11,128+24(%rsp)
+.Lprologue_avx:
+
+	vzeroupper
+	movq	0(%rdi),%rax
+	movq	8(%rdi),%rbx
+	movq	16(%rdi),%rcx
+	movq	24(%rdi),%rdx
+	movq	32(%rdi),%r8
+	movq	40(%rdi),%r9
+	movq	48(%rdi),%r10
+	movq	56(%rdi),%r11
+	jmp	.Lloop_avx
+.align	16
+.Lloop_avx:
+	vmovdqa	K512+1280(%rip),%xmm11
+	vmovdqu	0(%rsi),%xmm0
+	leaq	K512+128(%rip),%rbp
+	vmovdqu	16(%rsi),%xmm1
+	vmovdqu	32(%rsi),%xmm2
+	vpshufb	%xmm11,%xmm0,%xmm0
+	vmovdqu	48(%rsi),%xmm3
+	vpshufb	%xmm11,%xmm1,%xmm1
+	vmovdqu	64(%rsi),%xmm4
+	vpshufb	%xmm11,%xmm2,%xmm2
+	vmovdqu	80(%rsi),%xmm5
+	vpshufb	%xmm11,%xmm3,%xmm3
+	vmovdqu	96(%rsi),%xmm6
+	vpshufb	%xmm11,%xmm4,%xmm4
+	vmovdqu	112(%rsi),%xmm7
+	vpshufb	%xmm11,%xmm5,%xmm5
+	vpaddq	-128(%rbp),%xmm0,%xmm8
+	vpshufb	%xmm11,%xmm6,%xmm6
+	vpaddq	-96(%rbp),%xmm1,%xmm9
+	vpshufb	%xmm11,%xmm7,%xmm7
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	vpaddq	-32(%rbp),%xmm3,%xmm11
+	vmovdqa	%xmm8,0(%rsp)
+	vpaddq	0(%rbp),%xmm4,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	vpaddq	32(%rbp),%xmm5,%xmm9
+	vmovdqa	%xmm10,32(%rsp)
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	vmovdqa	%xmm11,48(%rsp)
+	vpaddq	96(%rbp),%xmm7,%xmm11
+	vmovdqa	%xmm8,64(%rsp)
+	movq	%rax,%r14
+	vmovdqa	%xmm9,80(%rsp)
+	movq	%rbx,%rdi
+	vmovdqa	%xmm10,96(%rsp)
+	xorq	%rcx,%rdi
+	vmovdqa	%xmm11,112(%rsp)
+	movq	%r8,%r13
+	jmp	.Lavx_00_47
+
+.align	16
+.Lavx_00_47:
+	addq	$256,%rbp
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm4,%xmm5,%xmm11
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpaddq	%xmm11,%xmm0,%xmm0
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm7,%xmm11
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	vpsllq	$3,%xmm7,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	vpaddq	%xmm8,%xmm0,%xmm0
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm7,%xmm9
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm0,%xmm0
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	vpaddq	-128(%rbp),%xmm0,%xmm10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,0(%rsp)
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm5,%xmm6,%xmm11
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpaddq	%xmm11,%xmm1,%xmm1
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm0,%xmm11
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	vpsllq	$3,%xmm0,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	vpaddq	%xmm8,%xmm1,%xmm1
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm0,%xmm9
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm1,%xmm1
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	vpaddq	-96(%rbp),%xmm1,%xmm10
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,16(%rsp)
+	vpalignr	$8,%xmm2,%xmm3,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm6,%xmm7,%xmm11
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpaddq	%xmm11,%xmm2,%xmm2
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm1,%xmm11
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	vpsllq	$3,%xmm1,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	vpaddq	%xmm8,%xmm2,%xmm2
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm1,%xmm9
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm2,%xmm2
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,32(%rsp)
+	vpalignr	$8,%xmm3,%xmm4,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm7,%xmm0,%xmm11
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpaddq	%xmm11,%xmm3,%xmm3
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm2,%xmm11
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	vpsllq	$3,%xmm2,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	vpaddq	%xmm8,%xmm3,%xmm3
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm2,%xmm9
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm3,%xmm3
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	vpaddq	-32(%rbp),%xmm3,%xmm10
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,48(%rsp)
+	vpalignr	$8,%xmm4,%xmm5,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm0,%xmm1,%xmm11
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpaddq	%xmm11,%xmm4,%xmm4
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm3,%xmm11
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	vpsllq	$3,%xmm3,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	vpaddq	%xmm8,%xmm4,%xmm4
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm3,%xmm9
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm4,%xmm4
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	vpaddq	0(%rbp),%xmm4,%xmm10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,64(%rsp)
+	vpalignr	$8,%xmm5,%xmm6,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm1,%xmm2,%xmm11
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpaddq	%xmm11,%xmm5,%xmm5
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm4,%xmm11
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	vpsllq	$3,%xmm4,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	vpaddq	%xmm8,%xmm5,%xmm5
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm4,%xmm9
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm5,%xmm5
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	vpaddq	32(%rbp),%xmm5,%xmm10
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,80(%rsp)
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm2,%xmm3,%xmm11
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpaddq	%xmm11,%xmm6,%xmm6
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm5,%xmm11
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	vpsllq	$3,%xmm5,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	vpaddq	%xmm8,%xmm6,%xmm6
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm5,%xmm9
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm6,%xmm6
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,96(%rsp)
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm3,%xmm4,%xmm11
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpaddq	%xmm11,%xmm7,%xmm7
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm6,%xmm11
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	vpsllq	$3,%xmm6,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	vpaddq	%xmm8,%xmm7,%xmm7
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm6,%xmm9
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm7,%xmm7
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	vpaddq	96(%rbp),%xmm7,%xmm10
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,112(%rsp)
+	cmpb	$0,135(%rbp)
+	jne	.Lavx_00_47
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	movq	128+0(%rsp),%rdi
+	movq	%r14,%rax
+
+	addq	0(%rdi),%rax
+	leaq	128(%rsi),%rsi
+	addq	8(%rdi),%rbx
+	addq	16(%rdi),%rcx
+	addq	24(%rdi),%rdx
+	addq	32(%rdi),%r8
+	addq	40(%rdi),%r9
+	addq	48(%rdi),%r10
+	addq	56(%rdi),%r11
+
+	cmpq	128+16(%rsp),%rsi
+
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+	movq	%r8,32(%rdi)
+	movq	%r9,40(%rdi)
+	movq	%r10,48(%rdi)
+	movq	%r11,56(%rdi)
+	jb	.Lloop_avx
+
+	movq	128+24(%rsp),%rsi
+	vzeroupper
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+.Lepilogue_avx:
+	.byte	0xf3,0xc3
+.size	sha512_block_data_order_avx,.-sha512_block_data_order_avx
 #endif
diff --git a/third_party/boringssl/mac-x86/crypto/chacha/chacha-x86.S b/third_party/boringssl/mac-x86/crypto/chacha/chacha-x86.S
new file mode 100644
index 0000000..5de98a3
--- /dev/null
+++ b/third_party/boringssl/mac-x86/crypto/chacha/chacha-x86.S
@@ -0,0 +1,969 @@
+#if defined(__i386__)
+.file	"chacha-x86.S"
+.text
+.globl	_ChaCha20_ctr32
+.private_extern	_ChaCha20_ctr32
+.align	4
+_ChaCha20_ctr32:
+L_ChaCha20_ctr32_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	xorl	%eax,%eax
+	cmpl	28(%esp),%eax
+	je	L000no_data
+	call	Lpic_point
+Lpic_point:
+	popl	%eax
+	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-Lpic_point(%eax),%ebp
+	testl	$16777216,(%ebp)
+	jz	L001x86
+	testl	$512,4(%ebp)
+	jz	L001x86
+	jmp	Lssse3_shortcut
+L001x86:
+	movl	32(%esp),%esi
+	movl	36(%esp),%edi
+	subl	$132,%esp
+	movl	(%esi),%eax
+	movl	4(%esi),%ebx
+	movl	8(%esi),%ecx
+	movl	12(%esi),%edx
+	movl	%eax,80(%esp)
+	movl	%ebx,84(%esp)
+	movl	%ecx,88(%esp)
+	movl	%edx,92(%esp)
+	movl	16(%esi),%eax
+	movl	20(%esi),%ebx
+	movl	24(%esi),%ecx
+	movl	28(%esi),%edx
+	movl	%eax,96(%esp)
+	movl	%ebx,100(%esp)
+	movl	%ecx,104(%esp)
+	movl	%edx,108(%esp)
+	movl	(%edi),%eax
+	movl	4(%edi),%ebx
+	movl	8(%edi),%ecx
+	movl	12(%edi),%edx
+	subl	$1,%eax
+	movl	%eax,112(%esp)
+	movl	%ebx,116(%esp)
+	movl	%ecx,120(%esp)
+	movl	%edx,124(%esp)
+	jmp	L002entry
+.align	4,0x90
+L003outer_loop:
+	movl	%ebx,156(%esp)
+	movl	%eax,152(%esp)
+	movl	%ecx,160(%esp)
+L002entry:
+	movl	$1634760805,%eax
+	movl	$857760878,4(%esp)
+	movl	$2036477234,8(%esp)
+	movl	$1797285236,12(%esp)
+	movl	84(%esp),%ebx
+	movl	88(%esp),%ebp
+	movl	104(%esp),%ecx
+	movl	108(%esp),%esi
+	movl	116(%esp),%edx
+	movl	120(%esp),%edi
+	movl	%ebx,20(%esp)
+	movl	%ebp,24(%esp)
+	movl	%ecx,40(%esp)
+	movl	%esi,44(%esp)
+	movl	%edx,52(%esp)
+	movl	%edi,56(%esp)
+	movl	92(%esp),%ebx
+	movl	124(%esp),%edi
+	movl	112(%esp),%edx
+	movl	80(%esp),%ebp
+	movl	96(%esp),%ecx
+	movl	100(%esp),%esi
+	addl	$1,%edx
+	movl	%ebx,28(%esp)
+	movl	%edi,60(%esp)
+	movl	%edx,112(%esp)
+	movl	$10,%ebx
+	jmp	L004loop
+.align	4,0x90
+L004loop:
+	addl	%ebp,%eax
+	movl	%ebx,128(%esp)
+	movl	%ebp,%ebx
+	xorl	%eax,%edx
+	roll	$16,%edx
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	52(%esp),%edi
+	roll	$12,%ebx
+	movl	20(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,48(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,32(%esp)
+	roll	$16,%edi
+	movl	%ebx,16(%esp)
+	addl	%edi,%esi
+	movl	40(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	56(%esp),%edx
+	roll	$12,%ebp
+	movl	24(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,52(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,36(%esp)
+	roll	$16,%edx
+	movl	%ebp,20(%esp)
+	addl	%edx,%ecx
+	movl	44(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	60(%esp),%edi
+	roll	$12,%ebx
+	movl	28(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,56(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,24(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	roll	$12,%ebp
+	movl	20(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,%edx
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	roll	$16,%edx
+	movl	%ebp,28(%esp)
+	addl	%edx,%ecx
+	xorl	%ecx,%ebx
+	movl	48(%esp),%edi
+	roll	$12,%ebx
+	movl	24(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,(%esp)
+	roll	$8,%edx
+	movl	4(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,60(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	movl	%ecx,40(%esp)
+	roll	$16,%edi
+	movl	%ebx,20(%esp)
+	addl	%edi,%esi
+	movl	32(%esp),%ecx
+	xorl	%esi,%ebp
+	movl	52(%esp),%edx
+	roll	$12,%ebp
+	movl	28(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,4(%esp)
+	roll	$8,%edi
+	movl	8(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,48(%esp)
+	xorl	%esi,%ebp
+	addl	%ebx,%eax
+	roll	$7,%ebp
+	xorl	%eax,%edx
+	movl	%esi,44(%esp)
+	roll	$16,%edx
+	movl	%ebp,24(%esp)
+	addl	%edx,%ecx
+	movl	36(%esp),%esi
+	xorl	%ecx,%ebx
+	movl	56(%esp),%edi
+	roll	$12,%ebx
+	movl	16(%esp),%ebp
+	addl	%ebx,%eax
+	xorl	%eax,%edx
+	movl	%eax,8(%esp)
+	roll	$8,%edx
+	movl	12(%esp),%eax
+	addl	%edx,%ecx
+	movl	%edx,52(%esp)
+	xorl	%ecx,%ebx
+	addl	%ebp,%eax
+	roll	$7,%ebx
+	xorl	%eax,%edi
+	roll	$16,%edi
+	movl	%ebx,28(%esp)
+	addl	%edi,%esi
+	xorl	%esi,%ebp
+	movl	48(%esp),%edx
+	roll	$12,%ebp
+	movl	128(%esp),%ebx
+	addl	%ebp,%eax
+	xorl	%eax,%edi
+	movl	%eax,12(%esp)
+	roll	$8,%edi
+	movl	(%esp),%eax
+	addl	%edi,%esi
+	movl	%edi,56(%esp)
+	xorl	%esi,%ebp
+	roll	$7,%ebp
+	decl	%ebx
+	jnz	L004loop
+	movl	160(%esp),%ebx
+	addl	$1634760805,%eax
+	addl	80(%esp),%ebp
+	addl	96(%esp),%ecx
+	addl	100(%esp),%esi
+	cmpl	$64,%ebx
+	jb	L005tail
+	movl	156(%esp),%ebx
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	xorl	(%ebx),%eax
+	xorl	16(%ebx),%ebp
+	movl	%eax,(%esp)
+	movl	152(%esp),%eax
+	xorl	32(%ebx),%ecx
+	xorl	36(%ebx),%esi
+	xorl	48(%ebx),%edx
+	xorl	56(%ebx),%edi
+	movl	%ebp,16(%eax)
+	movl	%ecx,32(%eax)
+	movl	%esi,36(%eax)
+	movl	%edx,48(%eax)
+	movl	%edi,56(%eax)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	xorl	4(%ebx),%ebp
+	xorl	8(%ebx),%ecx
+	xorl	12(%ebx),%esi
+	xorl	20(%ebx),%edx
+	xorl	24(%ebx),%edi
+	movl	%ebp,4(%eax)
+	movl	%ecx,8(%eax)
+	movl	%esi,12(%eax)
+	movl	%edx,20(%eax)
+	movl	%edi,24(%eax)
+	movl	28(%esp),%ebp
+	movl	40(%esp),%ecx
+	movl	44(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	92(%esp),%ebp
+	addl	104(%esp),%ecx
+	addl	108(%esp),%esi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	xorl	28(%ebx),%ebp
+	xorl	40(%ebx),%ecx
+	xorl	44(%ebx),%esi
+	xorl	52(%ebx),%edx
+	xorl	60(%ebx),%edi
+	leal	64(%ebx),%ebx
+	movl	%ebp,28(%eax)
+	movl	(%esp),%ebp
+	movl	%ecx,40(%eax)
+	movl	160(%esp),%ecx
+	movl	%esi,44(%eax)
+	movl	%edx,52(%eax)
+	movl	%edi,60(%eax)
+	movl	%ebp,(%eax)
+	leal	64(%eax),%eax
+	subl	$64,%ecx
+	jnz	L003outer_loop
+	jmp	L006done
+L005tail:
+	addl	112(%esp),%edx
+	addl	120(%esp),%edi
+	movl	%eax,(%esp)
+	movl	%ebp,16(%esp)
+	movl	%ecx,32(%esp)
+	movl	%esi,36(%esp)
+	movl	%edx,48(%esp)
+	movl	%edi,56(%esp)
+	movl	4(%esp),%ebp
+	movl	8(%esp),%ecx
+	movl	12(%esp),%esi
+	movl	20(%esp),%edx
+	movl	24(%esp),%edi
+	addl	$857760878,%ebp
+	addl	$2036477234,%ecx
+	addl	$1797285236,%esi
+	addl	84(%esp),%edx
+	addl	88(%esp),%edi
+	movl	%ebp,4(%esp)
+	movl	%ecx,8(%esp)
+	movl	%esi,12(%esp)
+	movl	%edx,20(%esp)
+	movl	%edi,24(%esp)
+	movl	28(%esp),%ebp
+	movl	40(%esp),%ecx
+	movl	44(%esp),%esi
+	movl	52(%esp),%edx
+	movl	60(%esp),%edi
+	addl	92(%esp),%ebp
+	addl	104(%esp),%ecx
+	addl	108(%esp),%esi
+	addl	116(%esp),%edx
+	addl	124(%esp),%edi
+	movl	%ebp,28(%esp)
+	movl	156(%esp),%ebp
+	movl	%ecx,40(%esp)
+	movl	152(%esp),%ecx
+	movl	%esi,44(%esp)
+	xorl	%esi,%esi
+	movl	%edx,52(%esp)
+	movl	%edi,60(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+L007tail_loop:
+	movb	(%esi,%ebp,1),%al
+	movb	(%esp,%esi,1),%dl
+	leal	1(%esi),%esi
+	xorb	%dl,%al
+	movb	%al,-1(%ecx,%esi,1)
+	decl	%ebx
+	jnz	L007tail_loop
+L006done:
+	addl	$132,%esp
+L000no_data:
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.globl	_ChaCha20_ssse3
+.private_extern	_ChaCha20_ssse3
+.align	4
+_ChaCha20_ssse3:
+L_ChaCha20_ssse3_begin:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+Lssse3_shortcut:
+	movl	20(%esp),%edi
+	movl	24(%esp),%esi
+	movl	28(%esp),%ecx
+	movl	32(%esp),%edx
+	movl	36(%esp),%ebx
+	movl	%esp,%ebp
+	subl	$524,%esp
+	andl	$-64,%esp
+	movl	%ebp,512(%esp)
+	leal	Lssse3_data-Lpic_point(%eax),%eax
+	movdqu	(%ebx),%xmm3
+	cmpl	$256,%ecx
+	jb	L0081x
+	movl	%edx,516(%esp)
+	movl	%ebx,520(%esp)
+	subl	$256,%ecx
+	leal	384(%esp),%ebp
+	movdqu	(%edx),%xmm7
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	paddd	48(%eax),%xmm0
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	psubd	64(%eax),%xmm0
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,64(%ebp)
+	movdqa	%xmm1,80(%ebp)
+	movdqa	%xmm2,96(%ebp)
+	movdqa	%xmm3,112(%ebp)
+	movdqu	16(%edx),%xmm3
+	movdqa	%xmm4,-64(%ebp)
+	movdqa	%xmm5,-48(%ebp)
+	movdqa	%xmm6,-32(%ebp)
+	movdqa	%xmm7,-16(%ebp)
+	movdqa	32(%eax),%xmm7
+	leal	128(%esp),%ebx
+	pshufd	$0,%xmm3,%xmm0
+	pshufd	$85,%xmm3,%xmm1
+	pshufd	$170,%xmm3,%xmm2
+	pshufd	$255,%xmm3,%xmm3
+	pshufd	$0,%xmm7,%xmm4
+	pshufd	$85,%xmm7,%xmm5
+	pshufd	$170,%xmm7,%xmm6
+	pshufd	$255,%xmm7,%xmm7
+	movdqa	%xmm0,(%ebp)
+	movdqa	%xmm1,16(%ebp)
+	movdqa	%xmm2,32(%ebp)
+	movdqa	%xmm3,48(%ebp)
+	movdqa	%xmm4,-128(%ebp)
+	movdqa	%xmm5,-112(%ebp)
+	movdqa	%xmm6,-96(%ebp)
+	movdqa	%xmm7,-80(%ebp)
+	leal	128(%esi),%esi
+	leal	128(%edi),%edi
+	jmp	L009outer_loop
+.align	4,0x90
+L009outer_loop:
+	movdqa	-112(%ebp),%xmm1
+	movdqa	-96(%ebp),%xmm2
+	movdqa	-80(%ebp),%xmm3
+	movdqa	-48(%ebp),%xmm5
+	movdqa	-32(%ebp),%xmm6
+	movdqa	-16(%ebp),%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	movdqa	%xmm2,-96(%ebx)
+	movdqa	%xmm3,-80(%ebx)
+	movdqa	%xmm5,-48(%ebx)
+	movdqa	%xmm6,-32(%ebx)
+	movdqa	%xmm7,-16(%ebx)
+	movdqa	32(%ebp),%xmm2
+	movdqa	48(%ebp),%xmm3
+	movdqa	64(%ebp),%xmm4
+	movdqa	80(%ebp),%xmm5
+	movdqa	96(%ebp),%xmm6
+	movdqa	112(%ebp),%xmm7
+	paddd	64(%eax),%xmm4
+	movdqa	%xmm2,32(%ebx)
+	movdqa	%xmm3,48(%ebx)
+	movdqa	%xmm4,64(%ebx)
+	movdqa	%xmm5,80(%ebx)
+	movdqa	%xmm6,96(%ebx)
+	movdqa	%xmm7,112(%ebx)
+	movdqa	%xmm4,64(%ebp)
+	movdqa	-128(%ebp),%xmm0
+	movdqa	%xmm4,%xmm6
+	movdqa	-64(%ebp),%xmm3
+	movdqa	(%ebp),%xmm4
+	movdqa	16(%ebp),%xmm5
+	movl	$10,%edx
+	nop
+.align	4,0x90
+L010loop:
+	paddd	%xmm3,%xmm0
+	movdqa	%xmm3,%xmm2
+	pxor	%xmm0,%xmm6
+	pshufb	(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-48(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	80(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,64(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-64(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	32(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-32(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	96(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,80(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,16(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-48(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	48(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-16(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	112(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,96(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-32(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	-48(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,%xmm6
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-16(%ebx)
+	paddd	%xmm6,%xmm4
+	pxor	%xmm4,%xmm2
+	movdqa	-32(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-112(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	64(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-128(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,112(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	movdqa	%xmm4,32(%ebx)
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-48(%ebx)
+	paddd	%xmm7,%xmm5
+	movdqa	(%ebx),%xmm4
+	pxor	%xmm5,%xmm3
+	movdqa	-16(%ebx),%xmm2
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-96(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	80(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-112(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,64(%ebx)
+	pxor	%xmm5,%xmm3
+	paddd	%xmm2,%xmm0
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	pxor	%xmm0,%xmm6
+	por	%xmm1,%xmm3
+	movdqa	%xmm5,48(%ebx)
+	pshufb	(%eax),%xmm6
+	movdqa	%xmm3,-32(%ebx)
+	paddd	%xmm6,%xmm4
+	movdqa	16(%ebx),%xmm5
+	pxor	%xmm4,%xmm2
+	movdqa	-64(%ebx),%xmm3
+	movdqa	%xmm2,%xmm1
+	pslld	$12,%xmm2
+	psrld	$20,%xmm1
+	por	%xmm1,%xmm2
+	movdqa	-80(%ebx),%xmm1
+	paddd	%xmm2,%xmm0
+	movdqa	96(%ebx),%xmm7
+	pxor	%xmm0,%xmm6
+	movdqa	%xmm0,-96(%ebx)
+	pshufb	16(%eax),%xmm6
+	paddd	%xmm6,%xmm4
+	movdqa	%xmm6,80(%ebx)
+	pxor	%xmm4,%xmm2
+	paddd	%xmm3,%xmm1
+	movdqa	%xmm2,%xmm0
+	pslld	$7,%xmm2
+	psrld	$25,%xmm0
+	pxor	%xmm1,%xmm7
+	por	%xmm0,%xmm2
+	pshufb	(%eax),%xmm7
+	movdqa	%xmm2,-16(%ebx)
+	paddd	%xmm7,%xmm5
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm0
+	pslld	$12,%xmm3
+	psrld	$20,%xmm0
+	por	%xmm0,%xmm3
+	movdqa	-128(%ebx),%xmm0
+	paddd	%xmm3,%xmm1
+	movdqa	64(%ebx),%xmm6
+	pxor	%xmm1,%xmm7
+	movdqa	%xmm1,-80(%ebx)
+	pshufb	16(%eax),%xmm7
+	paddd	%xmm7,%xmm5
+	movdqa	%xmm7,96(%ebx)
+	pxor	%xmm5,%xmm3
+	movdqa	%xmm3,%xmm1
+	pslld	$7,%xmm3
+	psrld	$25,%xmm1
+	por	%xmm1,%xmm3
+	decl	%edx
+	jnz	L010loop
+	movdqa	%xmm3,-64(%ebx)
+	movdqa	%xmm4,(%ebx)
+	movdqa	%xmm5,16(%ebx)
+	movdqa	%xmm6,64(%ebx)
+	movdqa	%xmm7,96(%ebx)
+	movdqa	-112(%ebx),%xmm1
+	movdqa	-96(%ebx),%xmm2
+	movdqa	-80(%ebx),%xmm3
+	paddd	-128(%ebp),%xmm0
+	paddd	-112(%ebp),%xmm1
+	paddd	-96(%ebp),%xmm2
+	paddd	-80(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	16(%esi),%esi
+	pxor	%xmm0,%xmm4
+	movdqa	-64(%ebx),%xmm0
+	pxor	%xmm1,%xmm5
+	movdqa	-48(%ebx),%xmm1
+	pxor	%xmm2,%xmm6
+	movdqa	-32(%ebx),%xmm2
+	pxor	%xmm3,%xmm7
+	movdqa	-16(%ebx),%xmm3
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	16(%edi),%edi
+	paddd	-64(%ebp),%xmm0
+	paddd	-48(%ebp),%xmm1
+	paddd	-32(%ebp),%xmm2
+	paddd	-16(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	16(%esi),%esi
+	pxor	%xmm0,%xmm4
+	movdqa	(%ebx),%xmm0
+	pxor	%xmm1,%xmm5
+	movdqa	16(%ebx),%xmm1
+	pxor	%xmm2,%xmm6
+	movdqa	32(%ebx),%xmm2
+	pxor	%xmm3,%xmm7
+	movdqa	48(%ebx),%xmm3
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	16(%edi),%edi
+	paddd	(%ebp),%xmm0
+	paddd	16(%ebp),%xmm1
+	paddd	32(%ebp),%xmm2
+	paddd	48(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	16(%esi),%esi
+	pxor	%xmm0,%xmm4
+	movdqa	64(%ebx),%xmm0
+	pxor	%xmm1,%xmm5
+	movdqa	80(%ebx),%xmm1
+	pxor	%xmm2,%xmm6
+	movdqa	96(%ebx),%xmm2
+	pxor	%xmm3,%xmm7
+	movdqa	112(%ebx),%xmm3
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	16(%edi),%edi
+	paddd	64(%ebp),%xmm0
+	paddd	80(%ebp),%xmm1
+	paddd	96(%ebp),%xmm2
+	paddd	112(%ebp),%xmm3
+	movdqa	%xmm0,%xmm6
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm6
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm6,%xmm3
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	movdqu	-128(%esi),%xmm4
+	movdqu	-64(%esi),%xmm5
+	movdqu	(%esi),%xmm2
+	movdqu	64(%esi),%xmm7
+	leal	208(%esi),%esi
+	pxor	%xmm0,%xmm4
+	pxor	%xmm1,%xmm5
+	pxor	%xmm2,%xmm6
+	pxor	%xmm3,%xmm7
+	movdqu	%xmm4,-128(%edi)
+	movdqu	%xmm5,-64(%edi)
+	movdqu	%xmm6,(%edi)
+	movdqu	%xmm7,64(%edi)
+	leal	208(%edi),%edi
+	subl	$256,%ecx
+	jnc	L009outer_loop
+	addl	$256,%ecx
+	jz	L011done
+	movl	520(%esp),%ebx
+	leal	-128(%esi),%esi
+	movl	516(%esp),%edx
+	leal	-128(%edi),%edi
+	movd	64(%ebp),%xmm2
+	movdqu	(%ebx),%xmm3
+	paddd	96(%eax),%xmm2
+	pand	112(%eax),%xmm3
+	por	%xmm2,%xmm3
+L0081x:
+	movdqa	32(%eax),%xmm0
+	movdqu	(%edx),%xmm1
+	movdqu	16(%edx),%xmm2
+	movdqa	(%eax),%xmm6
+	movdqa	16(%eax),%xmm7
+	movl	%ebp,48(%esp)
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	movl	$10,%edx
+	jmp	L012loop1x
+.align	4,0x90
+L013outer1x:
+	movdqa	80(%eax),%xmm3
+	movdqa	(%esp),%xmm0
+	movdqa	16(%esp),%xmm1
+	movdqa	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	movl	$10,%edx
+	movdqa	%xmm3,48(%esp)
+	jmp	L012loop1x
+.align	4,0x90
+L012loop1x:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%edx
+	jnz	L012loop1x
+	paddd	(%esp),%xmm0
+	paddd	16(%esp),%xmm1
+	paddd	32(%esp),%xmm2
+	paddd	48(%esp),%xmm3
+	cmpl	$64,%ecx
+	jb	L014tail
+	movdqu	(%esi),%xmm4
+	movdqu	16(%esi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%esi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%esi),%xmm5
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+	leal	64(%esi),%esi
+	movdqu	%xmm0,(%edi)
+	movdqu	%xmm1,16(%edi)
+	movdqu	%xmm2,32(%edi)
+	movdqu	%xmm3,48(%edi)
+	leal	64(%edi),%edi
+	subl	$64,%ecx
+	jnz	L013outer1x
+	jmp	L011done
+L014tail:
+	movdqa	%xmm0,(%esp)
+	movdqa	%xmm1,16(%esp)
+	movdqa	%xmm2,32(%esp)
+	movdqa	%xmm3,48(%esp)
+	xorl	%eax,%eax
+	xorl	%edx,%edx
+	xorl	%ebp,%ebp
+L015tail_loop:
+	movb	(%esp,%ebp,1),%al
+	movb	(%esi,%ebp,1),%dl
+	leal	1(%ebp),%ebp
+	xorb	%dl,%al
+	movb	%al,-1(%edi,%ebp,1)
+	decl	%ecx
+	jnz	L015tail_loop
+L011done:
+	movl	512(%esp),%esp
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
+.align	6,0x90
+Lssse3_data:
+.byte	2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+.byte	3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+.long	1634760805,857760878,2036477234,1797285236
+.long	0,1,2,3
+.long	4,4,4,4
+.long	1,0,0,0
+.long	4,0,0,0
+.long	0,-1,-1,-1
+.align	6,0x90
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+.byte	44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+.byte	60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+.byte	114,103,62,0
+.section __IMPORT,__pointers,non_lazy_symbol_pointers
+L_OPENSSL_ia32cap_P$non_lazy_ptr:
+.indirect_symbol	_OPENSSL_ia32cap_P
+.long	0
+#endif
diff --git a/third_party/boringssl/mac-x86/crypto/cpu-x86-asm.S b/third_party/boringssl/mac-x86/crypto/cpu-x86-asm.S
deleted file mode 100644
index bfb292c..0000000
--- a/third_party/boringssl/mac-x86/crypto/cpu-x86-asm.S
+++ /dev/null
@@ -1,309 +0,0 @@
-#if defined(__i386__)
-.file	"crypto/cpu-x86-asm.S"
-.text
-.globl	_OPENSSL_ia32_cpuid
-.private_extern	_OPENSSL_ia32_cpuid
-.align	4
-_OPENSSL_ia32_cpuid:
-L_OPENSSL_ia32_cpuid_begin:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	xorl	%edx,%edx
-	pushfl
-	popl	%eax
-	movl	%eax,%ecx
-	xorl	$2097152,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	xorl	%eax,%ecx
-	xorl	%eax,%eax
-	btl	$21,%ecx
-	jnc	L000nocpuid
-	movl	20(%esp),%esi
-	movl	%eax,8(%esi)
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%ebp
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%ebp
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%ebp
-	jz	L001intel
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%esi
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%esi
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%esi
-	jnz	L001intel
-	movl	$2147483648,%eax
-	.byte	0x0f,0xa2
-	cmpl	$2147483649,%eax
-	jb	L001intel
-	movl	%eax,%esi
-	movl	$2147483649,%eax
-	.byte	0x0f,0xa2
-	orl	%ecx,%ebp
-	andl	$2049,%ebp
-	cmpl	$2147483656,%esi
-	jb	L001intel
-	movl	$2147483656,%eax
-	.byte	0x0f,0xa2
-	movzbl	%cl,%esi
-	incl	%esi
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	btl	$28,%edx
-	jnc	L002generic
-	shrl	$16,%ebx
-	andl	$255,%ebx
-	cmpl	%esi,%ebx
-	ja	L002generic
-	andl	$4026531839,%edx
-	jmp	L002generic
-L001intel:
-	cmpl	$7,%edi
-	jb	L003cacheinfo
-	movl	20(%esp),%esi
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	movl	%ebx,8(%esi)
-L003cacheinfo:
-	cmpl	$4,%edi
-	movl	$-1,%edi
-	jb	L004nocacheinfo
-	movl	$4,%eax
-	movl	$0,%ecx
-	.byte	0x0f,0xa2
-	movl	%eax,%edi
-	shrl	$14,%edi
-	andl	$4095,%edi
-L004nocacheinfo:
-	movl	$1,%eax
-	xorl	%ecx,%ecx
-	.byte	0x0f,0xa2
-	andl	$3220176895,%edx
-	cmpl	$0,%ebp
-	jne	L005notintel
-	orl	$1073741824,%edx
-L005notintel:
-	btl	$28,%edx
-	jnc	L002generic
-	andl	$4026531839,%edx
-	cmpl	$0,%edi
-	je	L002generic
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	L002generic
-	andl	$4026531839,%edx
-L002generic:
-	andl	$2048,%ebp
-	andl	$4294965247,%ecx
-	movl	%edx,%esi
-	orl	%ecx,%ebp
-	btl	$27,%ecx
-	jnc	L006clear_avx
-	xorl	%ecx,%ecx
-.byte	15,1,208
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	L007done
-	cmpl	$2,%eax
-	je	L006clear_avx
-L008clear_xmm:
-	andl	$4261412861,%ebp
-	andl	$4278190079,%esi
-L006clear_avx:
-	andl	$4026525695,%ebp
-	movl	20(%esp),%edi
-	andl	$4294967263,8(%edi)
-L007done:
-	movl	%esi,%eax
-	movl	%ebp,%edx
-L000nocpuid:
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.globl	_OPENSSL_rdtsc
-.private_extern	_OPENSSL_rdtsc
-.align	4
-_OPENSSL_rdtsc:
-L_OPENSSL_rdtsc_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	L009PIC_me_up
-L009PIC_me_up:
-	popl	%ecx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L009PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	L010notsc
-	.byte	0x0f,0x31
-L010notsc:
-	ret
-.globl	_OPENSSL_instrument_halt
-.private_extern	_OPENSSL_instrument_halt
-.align	4
-_OPENSSL_instrument_halt:
-L_OPENSSL_instrument_halt_begin:
-	call	L011PIC_me_up
-L011PIC_me_up:
-	popl	%ecx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L011PIC_me_up(%ecx),%ecx
-	btl	$4,(%ecx)
-	jnc	L012nohalt
-.long	2421723150
-	andl	$3,%eax
-	jnz	L012nohalt
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	L012nohalt
-	.byte	0x0f,0x31
-	pushl	%edx
-	pushl	%eax
-	hlt
-	.byte	0x0f,0x31
-	subl	(%esp),%eax
-	sbbl	4(%esp),%edx
-	addl	$8,%esp
-	ret
-L012nohalt:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.globl	_OPENSSL_far_spin
-.private_extern	_OPENSSL_far_spin
-.align	4
-_OPENSSL_far_spin:
-L_OPENSSL_far_spin_begin:
-	pushfl
-	popl	%eax
-	btl	$9,%eax
-	jnc	L013nospin
-	movl	4(%esp),%eax
-	movl	8(%esp),%ecx
-.long	2430111262
-	xorl	%eax,%eax
-	movl	(%ecx),%edx
-	jmp	L014spin
-.align	4,0x90
-L014spin:
-	incl	%eax
-	cmpl	(%ecx),%edx
-	je	L014spin
-.long	529567888
-	ret
-L013nospin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	ret
-.globl	_OPENSSL_wipe_cpu
-.private_extern	_OPENSSL_wipe_cpu
-.align	4
-_OPENSSL_wipe_cpu:
-L_OPENSSL_wipe_cpu_begin:
-	xorl	%eax,%eax
-	xorl	%edx,%edx
-	call	L015PIC_me_up
-L015PIC_me_up:
-	popl	%ecx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L015PIC_me_up(%ecx),%ecx
-	movl	(%ecx),%ecx
-	btl	$1,(%ecx)
-	jnc	L016no_x87
-	andl	$83886080,%ecx
-	cmpl	$83886080,%ecx
-	jne	L017no_sse2
-	pxor	%xmm0,%xmm0
-	pxor	%xmm1,%xmm1
-	pxor	%xmm2,%xmm2
-	pxor	%xmm3,%xmm3
-	pxor	%xmm4,%xmm4
-	pxor	%xmm5,%xmm5
-	pxor	%xmm6,%xmm6
-	pxor	%xmm7,%xmm7
-L017no_sse2:
-.long	4007259865,4007259865,4007259865,4007259865,2430851995
-L016no_x87:
-	leal	4(%esp),%eax
-	ret
-.globl	_OPENSSL_atomic_add
-.private_extern	_OPENSSL_atomic_add
-.align	4
-_OPENSSL_atomic_add:
-L_OPENSSL_atomic_add_begin:
-	movl	4(%esp),%edx
-	movl	8(%esp),%ecx
-	pushl	%ebx
-	nop
-	movl	(%edx),%eax
-L018spin:
-	leal	(%eax,%ecx,1),%ebx
-	nop
-.long	447811568
-	jne	L018spin
-	movl	%ebx,%eax
-	popl	%ebx
-	ret
-.globl	_OPENSSL_indirect_call
-.private_extern	_OPENSSL_indirect_call
-.align	4
-_OPENSSL_indirect_call:
-L_OPENSSL_indirect_call_begin:
-	pushl	%ebp
-	movl	%esp,%ebp
-	subl	$28,%esp
-	movl	12(%ebp),%ecx
-	movl	%ecx,(%esp)
-	movl	16(%ebp),%edx
-	movl	%edx,4(%esp)
-	movl	20(%ebp),%eax
-	movl	%eax,8(%esp)
-	movl	24(%ebp),%eax
-	movl	%eax,12(%esp)
-	movl	28(%ebp),%eax
-	movl	%eax,16(%esp)
-	movl	32(%ebp),%eax
-	movl	%eax,20(%esp)
-	movl	36(%ebp),%eax
-	movl	%eax,24(%esp)
-	call	*8(%ebp)
-	movl	%ebp,%esp
-	popl	%ebp
-	ret
-.globl	_OPENSSL_ia32_rdrand
-.private_extern	_OPENSSL_ia32_rdrand
-.align	4
-_OPENSSL_ia32_rdrand:
-L_OPENSSL_ia32_rdrand_begin:
-	movl	$8,%ecx
-L019loop:
-.byte	15,199,240
-	jc	L020break
-	loop	L019loop
-L020break:
-	cmpl	$0,%eax
-	cmovel	%ecx,%eax
-	ret
-.section __IMPORT,__pointers,non_lazy_symbol_pointers
-L_OPENSSL_ia32cap_P$non_lazy_ptr:
-.indirect_symbol	_OPENSSL_ia32cap_P
-.long	0
-#endif
diff --git a/third_party/boringssl/mac-x86/crypto/rc4/rc4-586.S b/third_party/boringssl/mac-x86/crypto/rc4/rc4-586.S
index faecdfa..dcddc58 100644
--- a/third_party/boringssl/mac-x86/crypto/rc4/rc4-586.S
+++ b/third_party/boringssl/mac-x86/crypto/rc4/rc4-586.S
@@ -343,39 +343,6 @@
 	popl	%ebx
 	popl	%ebp
 	ret
-.globl	_RC4_options
-.private_extern	_RC4_options
-.align	4
-_RC4_options:
-L_RC4_options_begin:
-	call	L018pic_point
-L018pic_point:
-	popl	%eax
-	leal	L019opts-L018pic_point(%eax),%eax
-	call	L020PIC_me_up
-L020PIC_me_up:
-	popl	%edx
-	movl	L_OPENSSL_ia32cap_P$non_lazy_ptr-L020PIC_me_up(%edx),%edx
-	movl	(%edx),%edx
-	btl	$20,%edx
-	jc	L0211xchar
-	btl	$26,%edx
-	jnc	L022ret
-	addl	$25,%eax
-	ret
-L0211xchar:
-	addl	$12,%eax
-L022ret:
-	ret
-.align	6,0x90
-L019opts:
-.byte	114,99,52,40,52,120,44,105,110,116,41,0
-.byte	114,99,52,40,49,120,44,99,104,97,114,41,0
-.byte	114,99,52,40,56,120,44,109,109,120,41,0
-.byte	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-.byte	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-.byte	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-.align	6,0x90
 .section __IMPORT,__pointers,non_lazy_symbol_pointers
 L_OPENSSL_ia32cap_P$non_lazy_ptr:
 .indirect_symbol	_OPENSSL_ia32cap_P
diff --git a/third_party/boringssl/mac-x86/crypto/sha/sha1-586.S b/third_party/boringssl/mac-x86/crypto/sha/sha1-586.S
index 97aafbf..72a7205 100644
--- a/third_party/boringssl/mac-x86/crypto/sha/sha1-586.S
+++ b/third_party/boringssl/mac-x86/crypto/sha/sha1-586.S
@@ -22,8 +22,11 @@
 	movl	8(%esi),%ecx
 	testl	$16777216,%eax
 	jz	L001x86
-	testl	$536870912,%ecx
-	jnz	Lshaext_shortcut
+	andl	$268435456,%edx
+	andl	$1073741824,%eax
+	orl	%edx,%eax
+	cmpl	$1342177280,%eax
+	je	Lavx_shortcut
 	jmp	Lssse3_shortcut
 .align	4,0x90
 L001x86:
@@ -1391,9 +1394,9 @@
 	popl	%ebx
 	popl	%ebp
 	ret
-.private_extern	__sha1_block_data_order_shaext
+.private_extern	__sha1_block_data_order_ssse3
 .align	4
-__sha1_block_data_order_shaext:
+__sha1_block_data_order_ssse3:
 	pushl	%ebp
 	pushl	%ebx
 	pushl	%esi
@@ -1402,175 +1405,6 @@
 L003pic_point:
 	popl	%ebp
 	leal	LK_XX_XX-L003pic_point(%ebp),%ebp
-Lshaext_shortcut:
-	movl	20(%esp),%edi
-	movl	%esp,%ebx
-	movl	24(%esp),%esi
-	movl	28(%esp),%ecx
-	subl	$32,%esp
-	movdqu	(%edi),%xmm0
-	movd	16(%edi),%xmm1
-	andl	$-32,%esp
-	movdqa	80(%ebp),%xmm3
-	movdqu	(%esi),%xmm4
-	pshufd	$27,%xmm0,%xmm0
-	movdqu	16(%esi),%xmm5
-	pshufd	$27,%xmm1,%xmm1
-	movdqu	32(%esi),%xmm6
-.byte	102,15,56,0,227
-	movdqu	48(%esi),%xmm7
-.byte	102,15,56,0,235
-.byte	102,15,56,0,243
-.byte	102,15,56,0,251
-	jmp	L004loop_shaext
-.align	4,0x90
-L004loop_shaext:
-	decl	%ecx
-	leal	64(%esi),%eax
-	movdqa	%xmm1,(%esp)
-	paddd	%xmm4,%xmm1
-	cmovnel	%eax,%esi
-	movdqa	%xmm0,16(%esp)
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,0
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,0
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,0
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,0
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,0
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,1
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,1
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,1
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,1
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,1
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,2
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,2
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-.byte	15,56,201,229
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,2
-.byte	15,56,200,213
-	pxor	%xmm6,%xmm4
-.byte	15,56,201,238
-.byte	15,56,202,231
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,2
-.byte	15,56,200,206
-	pxor	%xmm7,%xmm5
-.byte	15,56,202,236
-.byte	15,56,201,247
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,2
-.byte	15,56,200,215
-	pxor	%xmm4,%xmm6
-.byte	15,56,201,252
-.byte	15,56,202,245
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,3
-.byte	15,56,200,204
-	pxor	%xmm5,%xmm7
-.byte	15,56,202,254
-	movdqu	(%esi),%xmm4
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,3
-.byte	15,56,200,213
-	movdqu	16(%esi),%xmm5
-.byte	102,15,56,0,227
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,3
-.byte	15,56,200,206
-	movdqu	32(%esi),%xmm6
-.byte	102,15,56,0,235
-	movdqa	%xmm0,%xmm2
-.byte	15,58,204,193,3
-.byte	15,56,200,215
-	movdqu	48(%esi),%xmm7
-.byte	102,15,56,0,243
-	movdqa	%xmm0,%xmm1
-.byte	15,58,204,194,3
-	movdqa	(%esp),%xmm2
-.byte	102,15,56,0,251
-.byte	15,56,200,202
-	paddd	16(%esp),%xmm0
-	jnz	L004loop_shaext
-	pshufd	$27,%xmm0,%xmm0
-	pshufd	$27,%xmm1,%xmm1
-	movdqu	%xmm0,(%edi)
-	movd	%xmm1,16(%edi)
-	movl	%ebx,%esp
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.private_extern	__sha1_block_data_order_ssse3
-.align	4
-__sha1_block_data_order_ssse3:
-	pushl	%ebp
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	call	L005pic_point
-L005pic_point:
-	popl	%ebp
-	leal	LK_XX_XX-L005pic_point(%ebp),%ebp
 Lssse3_shortcut:
 	movdqa	(%ebp),%xmm7
 	movdqa	16(%ebp),%xmm0
@@ -1623,9 +1457,9 @@
 	xorl	%edx,%ebp
 	pshufd	$238,%xmm0,%xmm4
 	andl	%ebp,%esi
-	jmp	L006loop
+	jmp	L004loop
 .align	4,0x90
-L006loop:
+L004loop:
 	rorl	$2,%ebx
 	xorl	%edx,%esi
 	movl	%eax,%ebp
@@ -2528,7 +2362,7 @@
 	addl	%edx,%ecx
 	movl	196(%esp),%ebp
 	cmpl	200(%esp),%ebp
-	je	L007done
+	je	L005done
 	movdqa	160(%esp),%xmm7
 	movdqa	176(%esp),%xmm6
 	movdqu	(%ebp),%xmm0
@@ -2663,9 +2497,9 @@
 	pshufd	$238,%xmm0,%xmm4
 	andl	%ebx,%esi
 	movl	%ebp,%ebx
-	jmp	L006loop
+	jmp	L004loop
 .align	4,0x90
-L007done:
+L005done:
 	addl	16(%esp),%ebx
 	xorl	%edi,%esi
 	movl	%ecx,%ebp
@@ -2778,6 +2612,1175 @@
 	popl	%ebx
 	popl	%ebp
 	ret
+.private_extern	__sha1_block_data_order_avx
+.align	4
+__sha1_block_data_order_avx:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
+	call	L006pic_point
+L006pic_point:
+	popl	%ebp
+	leal	LK_XX_XX-L006pic_point(%ebp),%ebp
+Lavx_shortcut:
+	vzeroall
+	vmovdqa	(%ebp),%xmm7
+	vmovdqa	16(%ebp),%xmm0
+	vmovdqa	32(%ebp),%xmm1
+	vmovdqa	48(%ebp),%xmm2
+	vmovdqa	64(%ebp),%xmm6
+	movl	20(%esp),%edi
+	movl	24(%esp),%ebp
+	movl	28(%esp),%edx
+	movl	%esp,%esi
+	subl	$208,%esp
+	andl	$-64,%esp
+	vmovdqa	%xmm0,112(%esp)
+	vmovdqa	%xmm1,128(%esp)
+	vmovdqa	%xmm2,144(%esp)
+	shll	$6,%edx
+	vmovdqa	%xmm7,160(%esp)
+	addl	%ebp,%edx
+	vmovdqa	%xmm6,176(%esp)
+	addl	$64,%ebp
+	movl	%edi,192(%esp)
+	movl	%ebp,196(%esp)
+	movl	%edx,200(%esp)
+	movl	%esi,204(%esp)
+	movl	(%edi),%eax
+	movl	4(%edi),%ebx
+	movl	8(%edi),%ecx
+	movl	12(%edi),%edx
+	movl	16(%edi),%edi
+	movl	%ebx,%esi
+	vmovdqu	-64(%ebp),%xmm0
+	vmovdqu	-48(%ebp),%xmm1
+	vmovdqu	-32(%ebp),%xmm2
+	vmovdqu	-16(%ebp),%xmm3
+	vpshufb	%xmm6,%xmm0,%xmm0
+	vpshufb	%xmm6,%xmm1,%xmm1
+	vpshufb	%xmm6,%xmm2,%xmm2
+	vmovdqa	%xmm7,96(%esp)
+	vpshufb	%xmm6,%xmm3,%xmm3
+	vpaddd	%xmm7,%xmm0,%xmm4
+	vpaddd	%xmm7,%xmm1,%xmm5
+	vpaddd	%xmm7,%xmm2,%xmm6
+	vmovdqa	%xmm4,(%esp)
+	movl	%ecx,%ebp
+	vmovdqa	%xmm5,16(%esp)
+	xorl	%edx,%ebp
+	vmovdqa	%xmm6,32(%esp)
+	andl	%ebp,%esi
+	jmp	L007loop
+.align	4,0x90
+L007loop:
+	shrdl	$2,%ebx,%ebx
+	xorl	%edx,%esi
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	movl	%eax,%ebp
+	addl	(%esp),%edi
+	vpaddd	%xmm3,%xmm7,%xmm7
+	vmovdqa	%xmm0,64(%esp)
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrldq	$4,%xmm3,%xmm6
+	addl	%esi,%edi
+	andl	%ebx,%ebp
+	vpxor	%xmm0,%xmm4,%xmm4
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpxor	%xmm2,%xmm6,%xmm6
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%ebp
+	vmovdqa	%xmm7,48(%esp)
+	movl	%edi,%esi
+	addl	4(%esp),%edx
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	andl	%eax,%esi
+	vpsrld	$31,%xmm4,%xmm6
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%esi
+	vpslldq	$12,%xmm4,%xmm0
+	vpaddd	%xmm4,%xmm4,%xmm4
+	movl	%edx,%ebp
+	addl	8(%esp),%ecx
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm0,%xmm7
+	vpor	%xmm6,%xmm4,%xmm4
+	addl	%esi,%ecx
+	andl	%edi,%ebp
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	vpslld	$2,%xmm0,%xmm0
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%ebp
+	vpxor	%xmm7,%xmm4,%xmm4
+	movl	%ecx,%esi
+	addl	12(%esp),%ebx
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	vpxor	%xmm0,%xmm4,%xmm4
+	addl	%ebp,%ebx
+	andl	%edx,%esi
+	vmovdqa	96(%esp),%xmm0
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%edi,%esi
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	movl	%ebx,%ebp
+	addl	16(%esp),%eax
+	vpaddd	%xmm4,%xmm0,%xmm0
+	vmovdqa	%xmm1,80(%esp)
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrldq	$4,%xmm4,%xmm7
+	addl	%esi,%eax
+	andl	%ecx,%ebp
+	vpxor	%xmm1,%xmm5,%xmm5
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm3,%xmm7,%xmm7
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%ebp
+	vmovdqa	%xmm0,(%esp)
+	movl	%eax,%esi
+	addl	20(%esp),%edi
+	vpxor	%xmm7,%xmm5,%xmm5
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	andl	%ebx,%esi
+	vpsrld	$31,%xmm5,%xmm7
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	vpslldq	$12,%xmm5,%xmm1
+	vpaddd	%xmm5,%xmm5,%xmm5
+	movl	%edi,%ebp
+	addl	24(%esp),%edx
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	vpsrld	$30,%xmm1,%xmm0
+	vpor	%xmm7,%xmm5,%xmm5
+	addl	%esi,%edx
+	andl	%eax,%ebp
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	vpslld	$2,%xmm1,%xmm1
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%ebp
+	vpxor	%xmm0,%xmm5,%xmm5
+	movl	%edx,%esi
+	addl	28(%esp),%ecx
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpxor	%xmm1,%xmm5,%xmm5
+	addl	%ebp,%ecx
+	andl	%edi,%esi
+	vmovdqa	112(%esp),%xmm1
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	vpalignr	$8,%xmm2,%xmm3,%xmm6
+	movl	%ecx,%ebp
+	addl	32(%esp),%ebx
+	vpaddd	%xmm5,%xmm1,%xmm1
+	vmovdqa	%xmm2,96(%esp)
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	vpsrldq	$4,%xmm5,%xmm0
+	addl	%esi,%ebx
+	andl	%edx,%ebp
+	vpxor	%xmm2,%xmm6,%xmm6
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%ecx,%ecx
+	xorl	%edi,%ebp
+	vmovdqa	%xmm1,16(%esp)
+	movl	%ebx,%esi
+	addl	36(%esp),%eax
+	vpxor	%xmm0,%xmm6,%xmm6
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	andl	%ecx,%esi
+	vpsrld	$31,%xmm6,%xmm0
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%esi
+	vpslldq	$12,%xmm6,%xmm2
+	vpaddd	%xmm6,%xmm6,%xmm6
+	movl	%eax,%ebp
+	addl	40(%esp),%edi
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm2,%xmm1
+	vpor	%xmm0,%xmm6,%xmm6
+	addl	%esi,%edi
+	andl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpslld	$2,%xmm2,%xmm2
+	vmovdqa	64(%esp),%xmm0
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%ebp
+	vpxor	%xmm1,%xmm6,%xmm6
+	movl	%edi,%esi
+	addl	44(%esp),%edx
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	vpxor	%xmm2,%xmm6,%xmm6
+	addl	%ebp,%edx
+	andl	%eax,%esi
+	vmovdqa	112(%esp),%xmm2
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%esi
+	vpalignr	$8,%xmm3,%xmm4,%xmm7
+	movl	%edx,%ebp
+	addl	48(%esp),%ecx
+	vpaddd	%xmm6,%xmm2,%xmm2
+	vmovdqa	%xmm3,64(%esp)
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpsrldq	$4,%xmm6,%xmm1
+	addl	%esi,%ecx
+	andl	%edi,%ebp
+	vpxor	%xmm3,%xmm7,%xmm7
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	vpxor	%xmm5,%xmm1,%xmm1
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%ebp
+	vmovdqa	%xmm2,32(%esp)
+	movl	%ecx,%esi
+	addl	52(%esp),%ebx
+	vpxor	%xmm1,%xmm7,%xmm7
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	andl	%edx,%esi
+	vpsrld	$31,%xmm7,%xmm1
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%edi,%esi
+	vpslldq	$12,%xmm7,%xmm3
+	vpaddd	%xmm7,%xmm7,%xmm7
+	movl	%ebx,%ebp
+	addl	56(%esp),%eax
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm3,%xmm2
+	vpor	%xmm1,%xmm7,%xmm7
+	addl	%esi,%eax
+	andl	%ecx,%ebp
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm3,%xmm3
+	vmovdqa	80(%esp),%xmm1
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%ebp
+	vpxor	%xmm2,%xmm7,%xmm7
+	movl	%eax,%esi
+	addl	60(%esp),%edi
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpxor	%xmm3,%xmm7,%xmm7
+	addl	%ebp,%edi
+	andl	%ebx,%esi
+	vmovdqa	112(%esp),%xmm3
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpalignr	$8,%xmm6,%xmm7,%xmm2
+	vpxor	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	movl	%edi,%ebp
+	addl	(%esp),%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	vmovdqa	%xmm4,80(%esp)
+	xorl	%ebx,%eax
+	shldl	$5,%edi,%edi
+	vmovdqa	%xmm3,%xmm4
+	vpaddd	%xmm7,%xmm3,%xmm3
+	addl	%esi,%edx
+	andl	%eax,%ebp
+	vpxor	%xmm2,%xmm0,%xmm0
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	shrdl	$7,%edi,%edi
+	xorl	%ebx,%ebp
+	vpsrld	$30,%xmm0,%xmm2
+	vmovdqa	%xmm3,48(%esp)
+	movl	%edx,%esi
+	addl	4(%esp),%ecx
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	vpslld	$2,%xmm0,%xmm0
+	addl	%ebp,%ecx
+	andl	%edi,%esi
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	movl	%ecx,%ebp
+	addl	8(%esp),%ebx
+	vpor	%xmm2,%xmm0,%xmm0
+	xorl	%edi,%edx
+	shldl	$5,%ecx,%ecx
+	vmovdqa	96(%esp),%xmm2
+	addl	%esi,%ebx
+	andl	%edx,%ebp
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	12(%esp),%eax
+	xorl	%edi,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm7,%xmm0,%xmm3
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	vpxor	%xmm2,%xmm1,%xmm1
+	vmovdqa	%xmm5,96(%esp)
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	vmovdqa	%xmm4,%xmm5
+	vpaddd	%xmm0,%xmm4,%xmm4
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpxor	%xmm3,%xmm1,%xmm1
+	addl	20(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	vpsrld	$30,%xmm1,%xmm3
+	vmovdqa	%xmm4,(%esp)
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpslld	$2,%xmm1,%xmm1
+	addl	24(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpor	%xmm3,%xmm1,%xmm1
+	addl	28(%esp),%ebx
+	xorl	%edi,%ebp
+	vmovdqa	64(%esp),%xmm3
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	vpxor	%xmm3,%xmm2,%xmm2
+	vmovdqa	%xmm6,64(%esp)
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	vmovdqa	128(%esp),%xmm6
+	vpaddd	%xmm1,%xmm5,%xmm5
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm4,%xmm2,%xmm2
+	addl	36(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm2,%xmm4
+	vmovdqa	%xmm5,16(%esp)
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpslld	$2,%xmm2,%xmm2
+	addl	40(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpor	%xmm4,%xmm2,%xmm2
+	addl	44(%esp),%ecx
+	xorl	%eax,%ebp
+	vmovdqa	80(%esp),%xmm4
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	vpxor	%xmm4,%xmm3,%xmm3
+	vmovdqa	%xmm7,80(%esp)
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	vmovdqa	%xmm6,%xmm7
+	vpaddd	%xmm2,%xmm6,%xmm6
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm5,%xmm3,%xmm3
+	addl	52(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm3,%xmm5
+	vmovdqa	%xmm6,32(%esp)
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpor	%xmm5,%xmm3,%xmm3
+	addl	60(%esp),%edx
+	xorl	%ebx,%ebp
+	vmovdqa	96(%esp),%xmm5
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpalignr	$8,%xmm2,%xmm3,%xmm6
+	vpxor	%xmm0,%xmm4,%xmm4
+	addl	(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	vpxor	%xmm5,%xmm4,%xmm4
+	vmovdqa	%xmm0,96(%esp)
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	vmovdqa	%xmm7,%xmm0
+	vpaddd	%xmm3,%xmm7,%xmm7
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpxor	%xmm6,%xmm4,%xmm4
+	addl	4(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	vpsrld	$30,%xmm4,%xmm6
+	vmovdqa	%xmm7,48(%esp)
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpslld	$2,%xmm4,%xmm4
+	addl	8(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpor	%xmm6,%xmm4,%xmm4
+	addl	12(%esp),%edi
+	xorl	%ecx,%ebp
+	vmovdqa	64(%esp),%xmm6
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpalignr	$8,%xmm3,%xmm4,%xmm7
+	vpxor	%xmm1,%xmm5,%xmm5
+	addl	16(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	vpxor	%xmm6,%xmm5,%xmm5
+	vmovdqa	%xmm1,64(%esp)
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	vmovdqa	%xmm0,%xmm1
+	vpaddd	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpxor	%xmm7,%xmm5,%xmm5
+	addl	20(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm5,%xmm7
+	vmovdqa	%xmm0,(%esp)
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpslld	$2,%xmm5,%xmm5
+	addl	24(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpor	%xmm7,%xmm5,%xmm5
+	addl	28(%esp),%eax
+	vmovdqa	80(%esp),%xmm7
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm4,%xmm5,%xmm0
+	vpxor	%xmm2,%xmm6,%xmm6
+	addl	32(%esp),%edi
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	vmovdqa	%xmm2,80(%esp)
+	movl	%eax,%ebp
+	xorl	%ecx,%esi
+	vmovdqa	%xmm1,%xmm2
+	vpaddd	%xmm5,%xmm1,%xmm1
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	vpxor	%xmm0,%xmm6,%xmm6
+	xorl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	addl	36(%esp),%edx
+	vpsrld	$30,%xmm6,%xmm0
+	vmovdqa	%xmm1,16(%esp)
+	andl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%edi,%esi
+	vpslld	$2,%xmm6,%xmm6
+	xorl	%ebx,%ebp
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	addl	40(%esp),%ecx
+	andl	%eax,%esi
+	vpor	%xmm0,%xmm6,%xmm6
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	vmovdqa	96(%esp),%xmm0
+	movl	%edx,%ebp
+	xorl	%eax,%esi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%edi,%ebp
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	addl	44(%esp),%ebx
+	andl	%edi,%ebp
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	xorl	%edi,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edx,%esi
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm5,%xmm6,%xmm1
+	vpxor	%xmm3,%xmm7,%xmm7
+	addl	48(%esp),%eax
+	andl	%edx,%esi
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	vpxor	%xmm0,%xmm7,%xmm7
+	vmovdqa	%xmm3,96(%esp)
+	movl	%ebx,%ebp
+	xorl	%edx,%esi
+	vmovdqa	144(%esp),%xmm3
+	vpaddd	%xmm6,%xmm2,%xmm2
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vpxor	%xmm1,%xmm7,%xmm7
+	xorl	%ecx,%ebp
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	52(%esp),%edi
+	vpsrld	$30,%xmm7,%xmm1
+	vmovdqa	%xmm2,32(%esp)
+	andl	%ecx,%ebp
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	vpslld	$2,%xmm7,%xmm7
+	xorl	%ecx,%ebp
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	addl	56(%esp),%edx
+	andl	%ebx,%esi
+	vpor	%xmm1,%xmm7,%xmm7
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	vmovdqa	64(%esp),%xmm1
+	movl	%edi,%ebp
+	xorl	%ebx,%esi
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%eax,%ebp
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	addl	60(%esp),%ecx
+	andl	%eax,%ebp
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	movl	%edx,%esi
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%edi,%esi
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm6,%xmm7,%xmm2
+	vpxor	%xmm4,%xmm0,%xmm0
+	addl	(%esp),%ebx
+	andl	%edi,%esi
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	vmovdqa	%xmm4,64(%esp)
+	movl	%ecx,%ebp
+	xorl	%edi,%esi
+	vmovdqa	%xmm3,%xmm4
+	vpaddd	%xmm7,%xmm3,%xmm3
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	vpxor	%xmm2,%xmm0,%xmm0
+	xorl	%edx,%ebp
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	4(%esp),%eax
+	vpsrld	$30,%xmm0,%xmm2
+	vmovdqa	%xmm3,48(%esp)
+	andl	%edx,%ebp
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	vpslld	$2,%xmm0,%xmm0
+	xorl	%edx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	8(%esp),%edi
+	andl	%ecx,%esi
+	vpor	%xmm2,%xmm0,%xmm0
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	vmovdqa	80(%esp),%xmm2
+	movl	%eax,%ebp
+	xorl	%ecx,%esi
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	addl	12(%esp),%edx
+	andl	%ebx,%ebp
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%edi,%esi
+	xorl	%ebx,%ebp
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	vpalignr	$8,%xmm7,%xmm0,%xmm3
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%esp),%ecx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	vpxor	%xmm2,%xmm1,%xmm1
+	vmovdqa	%xmm5,80(%esp)
+	movl	%edx,%ebp
+	xorl	%eax,%esi
+	vmovdqa	%xmm4,%xmm5
+	vpaddd	%xmm0,%xmm4,%xmm4
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	vpxor	%xmm3,%xmm1,%xmm1
+	xorl	%edi,%ebp
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	addl	20(%esp),%ebx
+	vpsrld	$30,%xmm1,%xmm3
+	vmovdqa	%xmm4,(%esp)
+	andl	%edi,%ebp
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	vpslld	$2,%xmm1,%xmm1
+	xorl	%edi,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edx,%esi
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	24(%esp),%eax
+	andl	%edx,%esi
+	vpor	%xmm3,%xmm1,%xmm1
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	vmovdqa	96(%esp),%xmm3
+	movl	%ebx,%ebp
+	xorl	%edx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%ecx,%ebp
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	28(%esp),%edi
+	andl	%ecx,%ebp
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	xorl	%ecx,%ebp
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%edi
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%esp),%edx
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	vpxor	%xmm3,%xmm2,%xmm2
+	vmovdqa	%xmm6,96(%esp)
+	movl	%edi,%ebp
+	xorl	%ebx,%esi
+	vmovdqa	%xmm5,%xmm6
+	vpaddd	%xmm1,%xmm5,%xmm5
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	vpxor	%xmm4,%xmm2,%xmm2
+	xorl	%eax,%ebp
+	xorl	%ebx,%eax
+	addl	%edi,%edx
+	addl	36(%esp),%ecx
+	vpsrld	$30,%xmm2,%xmm4
+	vmovdqa	%xmm5,16(%esp)
+	andl	%eax,%ebp
+	xorl	%ebx,%eax
+	shrdl	$7,%edi,%edi
+	movl	%edx,%esi
+	vpslld	$2,%xmm2,%xmm2
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%edi,%esi
+	xorl	%eax,%edi
+	addl	%edx,%ecx
+	addl	40(%esp),%ebx
+	andl	%edi,%esi
+	vpor	%xmm4,%xmm2,%xmm2
+	xorl	%eax,%edi
+	shrdl	$7,%edx,%edx
+	vmovdqa	64(%esp),%xmm4
+	movl	%ecx,%ebp
+	xorl	%edi,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edx,%ebp
+	xorl	%edi,%edx
+	addl	%ecx,%ebx
+	addl	44(%esp),%eax
+	andl	%edx,%ebp
+	xorl	%edi,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	vpxor	%xmm4,%xmm3,%xmm3
+	vmovdqa	%xmm7,64(%esp)
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	vmovdqa	%xmm6,%xmm7
+	vpaddd	%xmm2,%xmm6,%xmm6
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	vpxor	%xmm5,%xmm3,%xmm3
+	addl	52(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	vpsrld	$30,%xmm3,%xmm5
+	vmovdqa	%xmm6,32(%esp)
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vpor	%xmm5,%xmm3,%xmm3
+	addl	60(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	(%esp),%eax
+	vpaddd	%xmm3,%xmm7,%xmm7
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vmovdqa	%xmm7,48(%esp)
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	4(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	8(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	12(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	movl	196(%esp),%ebp
+	cmpl	200(%esp),%ebp
+	je	L008done
+	vmovdqa	160(%esp),%xmm7
+	vmovdqa	176(%esp),%xmm6
+	vmovdqu	(%ebp),%xmm0
+	vmovdqu	16(%ebp),%xmm1
+	vmovdqu	32(%ebp),%xmm2
+	vmovdqu	48(%ebp),%xmm3
+	addl	$64,%ebp
+	vpshufb	%xmm6,%xmm0,%xmm0
+	movl	%ebp,196(%esp)
+	vmovdqa	%xmm7,96(%esp)
+	addl	16(%esp),%ebx
+	xorl	%edi,%esi
+	vpshufb	%xmm6,%xmm1,%xmm1
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	vpaddd	%xmm7,%xmm0,%xmm4
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vmovdqa	%xmm4,(%esp)
+	addl	20(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	28(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	32(%esp),%ecx
+	xorl	%eax,%esi
+	vpshufb	%xmm6,%xmm2,%xmm2
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	vpaddd	%xmm7,%xmm1,%xmm5
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	vmovdqa	%xmm5,16(%esp)
+	addl	36(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	48(%esp),%edx
+	xorl	%ebx,%esi
+	vpshufb	%xmm6,%xmm3,%xmm3
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	vpaddd	%xmm7,%xmm2,%xmm6
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	vmovdqa	%xmm6,32(%esp)
+	addl	52(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	addl	56(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	movl	192(%esp),%ebp
+	addl	(%ebp),%eax
+	addl	4(%ebp),%esi
+	addl	8(%ebp),%ecx
+	movl	%eax,(%ebp)
+	addl	12(%ebp),%edx
+	movl	%esi,4(%ebp)
+	addl	16(%ebp),%edi
+	movl	%ecx,%ebx
+	movl	%ecx,8(%ebp)
+	xorl	%edx,%ebx
+	movl	%edx,12(%ebp)
+	movl	%edi,16(%ebp)
+	movl	%esi,%ebp
+	andl	%ebx,%esi
+	movl	%ebp,%ebx
+	jmp	L007loop
+.align	4,0x90
+L008done:
+	addl	16(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	20(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%esp),%edi
+	xorl	%ecx,%esi
+	movl	%eax,%ebp
+	shldl	$5,%eax,%eax
+	addl	%esi,%edi
+	xorl	%ecx,%ebp
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	28(%esp),%edx
+	xorl	%ebx,%ebp
+	movl	%edi,%esi
+	shldl	$5,%edi,%edi
+	addl	%ebp,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	32(%esp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%ebp
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%ebp
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	addl	36(%esp),%ebx
+	xorl	%edi,%ebp
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%ebp,%ebx
+	xorl	%edi,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%esp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%ebp
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%ebp
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%esp),%edi
+	xorl	%ecx,%ebp
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%ebp,%edi
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%edi
+	addl	48(%esp),%edx
+	xorl	%ebx,%esi
+	movl	%edi,%ebp
+	shldl	$5,%edi,%edi
+	addl	%esi,%edx
+	xorl	%ebx,%ebp
+	shrdl	$7,%eax,%eax
+	addl	%edi,%edx
+	addl	52(%esp),%ecx
+	xorl	%eax,%ebp
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%ebp,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%edi,%edi
+	addl	%edx,%ecx
+	addl	56(%esp),%ebx
+	xorl	%edi,%esi
+	movl	%ecx,%ebp
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edi,%ebp
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%esp),%eax
+	xorl	%edx,%ebp
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%ebp,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vzeroall
+	movl	192(%esp),%ebp
+	addl	(%ebp),%eax
+	movl	204(%esp),%esp
+	addl	4(%ebp),%esi
+	addl	8(%ebp),%ecx
+	movl	%eax,(%ebp)
+	addl	12(%ebp),%edx
+	movl	%esi,4(%ebp)
+	addl	16(%ebp),%edi
+	movl	%ecx,8(%ebp)
+	movl	%edx,12(%ebp)
+	movl	%edi,16(%ebp)
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
 .align	6,0x90
 LK_XX_XX:
 .long	1518500249,1518500249,1518500249,1518500249
diff --git a/third_party/boringssl/mac-x86/crypto/sha/sha256-586.S b/third_party/boringssl/mac-x86/crypto/sha/sha256-586.S
index f0ba612..841854f 100644
--- a/third_party/boringssl/mac-x86/crypto/sha/sha256-586.S
+++ b/third_party/boringssl/mac-x86/crypto/sha/sha256-586.S
@@ -36,11 +36,10 @@
 	jz	L003no_xmm
 	andl	$1073741824,%ecx
 	andl	$268435968,%ebx
-	testl	$536870912,%edx
-	jnz	L004shaext
 	orl	%ebx,%ecx
 	andl	$1342177280,%ecx
 	cmpl	$1342177280,%ecx
+	je	L004AVX
 	testl	$512,%ebx
 	jnz	L005SSSE3
 L003no_xmm:
@@ -3166,204 +3165,6 @@
 	popl	%ebp
 	ret
 .align	5,0x90
-L004shaext:
-	subl	$32,%esp
-	movdqu	(%esi),%xmm1
-	leal	128(%ebp),%ebp
-	movdqu	16(%esi),%xmm2
-	movdqa	128(%ebp),%xmm7
-	pshufd	$27,%xmm1,%xmm0
-	pshufd	$177,%xmm1,%xmm1
-	pshufd	$27,%xmm2,%xmm2
-.byte	102,15,58,15,202,8
-	punpcklqdq	%xmm0,%xmm2
-	jmp	L010loop_shaext
-.align	4,0x90
-L010loop_shaext:
-	movdqu	(%edi),%xmm3
-	movdqu	16(%edi),%xmm4
-	movdqu	32(%edi),%xmm5
-.byte	102,15,56,0,223
-	movdqu	48(%edi),%xmm6
-	movdqa	%xmm2,16(%esp)
-	movdqa	-128(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	102,15,56,0,231
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	nop
-	movdqa	%xmm1,(%esp)
-.byte	15,56,203,202
-	movdqa	-112(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	102,15,56,0,239
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	leal	64(%edi),%edi
-.byte	15,56,204,220
-.byte	15,56,203,202
-	movdqa	-96(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	102,15,56,0,247
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm6,%xmm7
-.byte	102,15,58,15,253,4
-	nop
-	paddd	%xmm7,%xmm3
-.byte	15,56,204,229
-.byte	15,56,203,202
-	movdqa	-80(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-.byte	15,56,205,222
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm3,%xmm7
-.byte	102,15,58,15,254,4
-	nop
-	paddd	%xmm7,%xmm4
-.byte	15,56,204,238
-.byte	15,56,203,202
-	movdqa	-64(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	15,56,205,227
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm4,%xmm7
-.byte	102,15,58,15,251,4
-	nop
-	paddd	%xmm7,%xmm5
-.byte	15,56,204,243
-.byte	15,56,203,202
-	movdqa	-48(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	15,56,205,236
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm5,%xmm7
-.byte	102,15,58,15,252,4
-	nop
-	paddd	%xmm7,%xmm6
-.byte	15,56,204,220
-.byte	15,56,203,202
-	movdqa	-32(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	15,56,205,245
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm6,%xmm7
-.byte	102,15,58,15,253,4
-	nop
-	paddd	%xmm7,%xmm3
-.byte	15,56,204,229
-.byte	15,56,203,202
-	movdqa	-16(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-.byte	15,56,205,222
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm3,%xmm7
-.byte	102,15,58,15,254,4
-	nop
-	paddd	%xmm7,%xmm4
-.byte	15,56,204,238
-.byte	15,56,203,202
-	movdqa	(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	15,56,205,227
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm4,%xmm7
-.byte	102,15,58,15,251,4
-	nop
-	paddd	%xmm7,%xmm5
-.byte	15,56,204,243
-.byte	15,56,203,202
-	movdqa	16(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	15,56,205,236
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm5,%xmm7
-.byte	102,15,58,15,252,4
-	nop
-	paddd	%xmm7,%xmm6
-.byte	15,56,204,220
-.byte	15,56,203,202
-	movdqa	32(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	15,56,205,245
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm6,%xmm7
-.byte	102,15,58,15,253,4
-	nop
-	paddd	%xmm7,%xmm3
-.byte	15,56,204,229
-.byte	15,56,203,202
-	movdqa	48(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-.byte	15,56,205,222
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm3,%xmm7
-.byte	102,15,58,15,254,4
-	nop
-	paddd	%xmm7,%xmm4
-.byte	15,56,204,238
-.byte	15,56,203,202
-	movdqa	64(%ebp),%xmm0
-	paddd	%xmm3,%xmm0
-.byte	15,56,205,227
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm4,%xmm7
-.byte	102,15,58,15,251,4
-	nop
-	paddd	%xmm7,%xmm5
-.byte	15,56,204,243
-.byte	15,56,203,202
-	movdqa	80(%ebp),%xmm0
-	paddd	%xmm4,%xmm0
-.byte	15,56,205,236
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	movdqa	%xmm5,%xmm7
-.byte	102,15,58,15,252,4
-.byte	15,56,203,202
-	paddd	%xmm7,%xmm6
-	movdqa	96(%ebp),%xmm0
-	paddd	%xmm5,%xmm0
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-.byte	15,56,205,245
-	movdqa	128(%ebp),%xmm7
-.byte	15,56,203,202
-	movdqa	112(%ebp),%xmm0
-	paddd	%xmm6,%xmm0
-	nop
-.byte	15,56,203,209
-	pshufd	$14,%xmm0,%xmm0
-	cmpl	%edi,%eax
-	nop
-.byte	15,56,203,202
-	paddd	16(%esp),%xmm2
-	paddd	(%esp),%xmm1
-	jnz	L010loop_shaext
-	pshufd	$177,%xmm2,%xmm2
-	pshufd	$27,%xmm1,%xmm7
-	pshufd	$177,%xmm1,%xmm1
-	punpckhqdq	%xmm2,%xmm1
-.byte	102,15,58,15,215,8
-	movl	44(%esp),%esp
-	movdqu	%xmm1,(%esi)
-	movdqu	%xmm2,16(%esi)
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-	popl	%ebp
-	ret
-.align	5,0x90
 L005SSSE3:
 	leal	-96(%esp),%esp
 	movl	(%esi),%eax
@@ -3383,9 +3184,9 @@
 	movl	%ecx,24(%esp)
 	movl	%esi,28(%esp)
 	movdqa	256(%ebp),%xmm7
-	jmp	L011grand_ssse3
+	jmp	L010grand_ssse3
 .align	4,0x90
-L011grand_ssse3:
+L010grand_ssse3:
 	movdqu	(%edi),%xmm0
 	movdqu	16(%edi),%xmm1
 	movdqu	32(%edi),%xmm2
@@ -3408,9 +3209,9 @@
 	paddd	%xmm3,%xmm7
 	movdqa	%xmm6,64(%esp)
 	movdqa	%xmm7,80(%esp)
-	jmp	L012ssse3_00_47
+	jmp	L011ssse3_00_47
 .align	4,0x90
-L012ssse3_00_47:
+L011ssse3_00_47:
 	addl	$64,%ebp
 	movl	%edx,%ecx
 	movdqa	%xmm1,%xmm4
@@ -4053,7 +3854,7 @@
 	addl	%ecx,%eax
 	movdqa	%xmm6,80(%esp)
 	cmpl	$66051,64(%ebp)
-	jne	L012ssse3_00_47
+	jne	L011ssse3_00_47
 	movl	%edx,%ecx
 	rorl	$14,%edx
 	movl	20(%esp),%esi
@@ -4567,13 +4368,1194 @@
 	movdqa	64(%ebp),%xmm7
 	subl	$192,%ebp
 	cmpl	104(%esp),%edi
-	jb	L011grand_ssse3
+	jb	L010grand_ssse3
 	movl	108(%esp),%esp
 	popl	%edi
 	popl	%esi
 	popl	%ebx
 	popl	%ebp
 	ret
+.align	5,0x90
+L004AVX:
+	leal	-96(%esp),%esp
+	vzeroall
+	movl	(%esi),%eax
+	movl	4(%esi),%ebx
+	movl	8(%esi),%ecx
+	movl	12(%esi),%edi
+	movl	%ebx,4(%esp)
+	xorl	%ecx,%ebx
+	movl	%ecx,8(%esp)
+	movl	%edi,12(%esp)
+	movl	16(%esi),%edx
+	movl	20(%esi),%edi
+	movl	24(%esi),%ecx
+	movl	28(%esi),%esi
+	movl	%edi,20(%esp)
+	movl	100(%esp),%edi
+	movl	%ecx,24(%esp)
+	movl	%esi,28(%esp)
+	vmovdqa	256(%ebp),%xmm7
+	jmp	L012grand_avx
+.align	5,0x90
+L012grand_avx:
+	vmovdqu	(%edi),%xmm0
+	vmovdqu	16(%edi),%xmm1
+	vmovdqu	32(%edi),%xmm2
+	vmovdqu	48(%edi),%xmm3
+	addl	$64,%edi
+	vpshufb	%xmm7,%xmm0,%xmm0
+	movl	%edi,100(%esp)
+	vpshufb	%xmm7,%xmm1,%xmm1
+	vpshufb	%xmm7,%xmm2,%xmm2
+	vpaddd	(%ebp),%xmm0,%xmm4
+	vpshufb	%xmm7,%xmm3,%xmm3
+	vpaddd	16(%ebp),%xmm1,%xmm5
+	vpaddd	32(%ebp),%xmm2,%xmm6
+	vpaddd	48(%ebp),%xmm3,%xmm7
+	vmovdqa	%xmm4,32(%esp)
+	vmovdqa	%xmm5,48(%esp)
+	vmovdqa	%xmm6,64(%esp)
+	vmovdqa	%xmm7,80(%esp)
+	jmp	L013avx_00_47
+.align	4,0x90
+L013avx_00_47:
+	addl	$64,%ebp
+	vpalignr	$4,%xmm0,%xmm1,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	vpalignr	$4,%xmm2,%xmm3,%xmm7
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	vpaddd	%xmm7,%xmm0,%xmm0
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	vpshufd	$250,%xmm3,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	32(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	vpaddd	%xmm4,%xmm0,%xmm0
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	36(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	vpaddd	%xmm7,%xmm0,%xmm0
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm0,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	40(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm0,%xmm0
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	vpaddd	(%ebp),%xmm0,%xmm6
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	44(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,32(%esp)
+	vpalignr	$4,%xmm1,%xmm2,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	vpalignr	$4,%xmm3,%xmm0,%xmm7
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	vpaddd	%xmm7,%xmm1,%xmm1
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	vpshufd	$250,%xmm0,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	48(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	vpaddd	%xmm4,%xmm1,%xmm1
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	52(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	vpaddd	%xmm7,%xmm1,%xmm1
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm1,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	56(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm1,%xmm1
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	vpaddd	16(%ebp),%xmm1,%xmm6
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	60(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,48(%esp)
+	vpalignr	$4,%xmm2,%xmm3,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	vpalignr	$4,%xmm0,%xmm1,%xmm7
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	vpaddd	%xmm7,%xmm2,%xmm2
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	vpshufd	$250,%xmm1,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	64(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	vpaddd	%xmm4,%xmm2,%xmm2
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	68(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	vpaddd	%xmm7,%xmm2,%xmm2
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm2,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	72(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm2,%xmm2
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	vpaddd	32(%ebp),%xmm2,%xmm6
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	76(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,64(%esp)
+	vpalignr	$4,%xmm3,%xmm0,%xmm4
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	vpalignr	$4,%xmm1,%xmm2,%xmm7
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	vpaddd	%xmm7,%xmm3,%xmm3
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrld	$3,%xmm4,%xmm7
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	vpslld	$14,%xmm4,%xmm5
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	vpshufd	$250,%xmm2,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpsrld	$11,%xmm6,%xmm6
+	addl	80(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	vpslld	$11,%xmm5,%xmm5
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	vpsrld	$10,%xmm7,%xmm6
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	vpxor	%xmm5,%xmm4,%xmm4
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	vpaddd	%xmm4,%xmm3,%xmm3
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	vpxor	%xmm5,%xmm6,%xmm6
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	vpsrlq	$19,%xmm7,%xmm7
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	84(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	vpshufd	$132,%xmm6,%xmm7
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	vpsrldq	$8,%xmm7,%xmm7
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	vpaddd	%xmm7,%xmm3,%xmm3
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	vpshufd	$80,%xmm3,%xmm7
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	vpsrlq	$17,%xmm7,%xmm5
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	vpxor	%xmm5,%xmm6,%xmm6
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	vpsrlq	$19,%xmm7,%xmm7
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	vpshufd	$232,%xmm6,%xmm7
+	addl	88(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	vpslldq	$8,%xmm7,%xmm7
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	vpaddd	%xmm7,%xmm3,%xmm3
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	vpaddd	48(%ebp),%xmm3,%xmm6
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	92(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	vmovdqa	%xmm6,80(%esp)
+	cmpl	$66051,64(%ebp)
+	jne	L013avx_00_47
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	32(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	36(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	40(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	44(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	48(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	52(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	56(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	60(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	20(%esp),%esi
+	xorl	%ecx,%edx
+	movl	24(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,16(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	4(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	28(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	64(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	12(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	16(%esp),%esi
+	xorl	%ecx,%edx
+	movl	20(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,12(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,28(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	24(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	68(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	8(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	12(%esp),%esi
+	xorl	%ecx,%edx
+	movl	16(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,8(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	28(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,24(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	20(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	72(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	4(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	8(%esp),%esi
+	xorl	%ecx,%edx
+	movl	12(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,4(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	24(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,20(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	16(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	76(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	4(%esp),%esi
+	xorl	%ecx,%edx
+	movl	8(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	20(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,16(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	12(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	80(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	28(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	(%esp),%esi
+	xorl	%ecx,%edx
+	movl	4(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,28(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	16(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,12(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	8(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	84(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	24(%esp),%edx
+	addl	%ecx,%eax
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	28(%esp),%esi
+	xorl	%ecx,%edx
+	movl	(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,24(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%eax,%ecx
+	addl	%edi,%edx
+	movl	12(%esp),%edi
+	movl	%eax,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%eax,8(%esp)
+	xorl	%eax,%ecx
+	xorl	%edi,%eax
+	addl	4(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%eax,%ebx
+	xorl	%esi,%ecx
+	addl	88(%esp),%edx
+	xorl	%edi,%ebx
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%ebx
+	addl	20(%esp),%edx
+	addl	%ecx,%ebx
+	movl	%edx,%ecx
+	shrdl	$14,%edx,%edx
+	movl	24(%esp),%esi
+	xorl	%ecx,%edx
+	movl	28(%esp),%edi
+	xorl	%edi,%esi
+	shrdl	$5,%edx,%edx
+	andl	%ecx,%esi
+	movl	%ecx,20(%esp)
+	xorl	%ecx,%edx
+	xorl	%esi,%edi
+	shrdl	$6,%edx,%edx
+	movl	%ebx,%ecx
+	addl	%edi,%edx
+	movl	8(%esp),%edi
+	movl	%ebx,%esi
+	shrdl	$9,%ecx,%ecx
+	movl	%ebx,4(%esp)
+	xorl	%ebx,%ecx
+	xorl	%edi,%ebx
+	addl	(%esp),%edx
+	shrdl	$11,%ecx,%ecx
+	andl	%ebx,%eax
+	xorl	%esi,%ecx
+	addl	92(%esp),%edx
+	xorl	%edi,%eax
+	shrdl	$2,%ecx,%ecx
+	addl	%edx,%eax
+	addl	16(%esp),%edx
+	addl	%ecx,%eax
+	movl	96(%esp),%esi
+	xorl	%edi,%ebx
+	movl	12(%esp),%ecx
+	addl	(%esi),%eax
+	addl	4(%esi),%ebx
+	addl	8(%esi),%edi
+	addl	12(%esi),%ecx
+	movl	%eax,(%esi)
+	movl	%ebx,4(%esi)
+	movl	%edi,8(%esi)
+	movl	%ecx,12(%esi)
+	movl	%ebx,4(%esp)
+	xorl	%edi,%ebx
+	movl	%edi,8(%esp)
+	movl	%ecx,12(%esp)
+	movl	20(%esp),%edi
+	movl	24(%esp),%ecx
+	addl	16(%esi),%edx
+	addl	20(%esi),%edi
+	addl	24(%esi),%ecx
+	movl	%edx,16(%esi)
+	movl	%edi,20(%esi)
+	movl	%edi,20(%esp)
+	movl	28(%esp),%edi
+	movl	%ecx,24(%esi)
+	addl	28(%esi),%edi
+	movl	%ecx,24(%esp)
+	movl	%edi,28(%esi)
+	movl	%edi,28(%esp)
+	movl	100(%esp),%edi
+	vmovdqa	64(%ebp),%xmm7
+	subl	$192,%ebp
+	cmpl	104(%esp),%edi
+	jb	L012grand_avx
+	movl	108(%esp),%esp
+	vzeroall
+	popl	%edi
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+	ret
 .section __IMPORT,__pointers,non_lazy_symbol_pointers
 L_OPENSSL_ia32cap_P$non_lazy_ptr:
 .indirect_symbol	_OPENSSL_ia32cap_P
diff --git a/third_party/boringssl/mac-x86_64/crypto/aes/aes-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/aes/aes-x86_64.S
index 02f378b..b5d188a 100644
--- a/third_party/boringssl/mac-x86_64/crypto/aes/aes-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/aes/aes-x86_64.S
@@ -82,8 +82,8 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$65280,%edi
-	andl	$65280,%ebp
+	andl	$0x0000ff00,%edi
+	andl	$0x0000ff00,%ebp
 
 	xorl	%edi,%r10d
 	xorl	%ebp,%r11d
@@ -95,8 +95,8 @@
 	movl	0(%r14,%rsi,8),%esi
 	movl	0(%r14,%rdi,8),%edi
 
-	andl	$65280,%esi
-	andl	$65280,%edi
+	andl	$0x0000ff00,%esi
+	andl	$0x0000ff00,%edi
 	shrl	$16,%ebx
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -109,9 +109,9 @@
 	movl	0(%r14,%rdi,8),%edi
 	movl	0(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$16711680,%edi
-	andl	$16711680,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0x00ff0000,%edi
+	andl	$0x00ff0000,%ebp
 
 	xorl	%esi,%r10d
 	xorl	%edi,%r11d
@@ -124,9 +124,9 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	2(%r14,%rbp,8),%ebp
 
-	andl	$16711680,%esi
-	andl	$4278190080,%edi
-	andl	$4278190080,%ebp
+	andl	$0x00ff0000,%esi
+	andl	$0xff000000,%edi
+	andl	$0xff000000,%ebp
 
 	xorl	%esi,%r8d
 	xorl	%edi,%r10d
@@ -139,8 +139,8 @@
 	movl	2(%r14,%rdi,8),%edi
 	movl	16+0(%r15),%eax
 
-	andl	$4278190080,%esi
-	andl	$4278190080,%edi
+	andl	$0xff000000,%esi
+	andl	$0xff000000,%edi
 
 	xorl	%esi,%r12d
 	xorl	%edi,%r8d
@@ -242,8 +242,8 @@
 	xorl	%r8d,%edx
 	cmpq	16(%rsp),%r15
 	je	L$enc_compact_done
-	movl	$2155905152,%r10d
-	movl	$2155905152,%r11d
+	movl	$0x80808080,%r10d
+	movl	$0x80808080,%r11d
 	andl	%eax,%r10d
 	andl	%ebx,%r11d
 	movl	%r10d,%esi
@@ -254,10 +254,10 @@
 	leal	(%rbx,%rbx,1),%r9d
 	subl	%r10d,%esi
 	subl	%r11d,%edi
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%eax,%r10d
 	movl	%ebx,%r11d
 	xorl	%esi,%r8d
@@ -265,9 +265,9 @@
 
 	xorl	%r8d,%eax
 	xorl	%r9d,%ebx
-	movl	$2155905152,%r12d
+	movl	$0x80808080,%r12d
 	roll	$24,%eax
-	movl	$2155905152,%ebp
+	movl	$0x80808080,%ebp
 	roll	$24,%ebx
 	andl	%ecx,%r12d
 	andl	%edx,%ebp
@@ -290,10 +290,10 @@
 	xorl	%r10d,%eax
 	xorl	%r11d,%ebx
 
-	andl	$4278124286,%r8d
-	andl	$4278124286,%r9d
-	andl	$454761243,%esi
-	andl	$454761243,%edi
+	andl	$0xfefefefe,%r8d
+	andl	$0xfefefefe,%r9d
+	andl	$0x1b1b1b1b,%esi
+	andl	$0x1b1b1b1b,%edi
 	movl	%ecx,%r12d
 	movl	%edx,%ebp
 	xorl	%esi,%r8d
@@ -345,7 +345,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -370,7 +370,7 @@
 	leaq	L$AES_Te+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 
 	call	_x86_64_AES_encrypt_compact
@@ -791,7 +791,7 @@
 	andq	$-64,%rsp
 	subq	%rsp,%rcx
 	negq	%rcx
-	andq	$960,%rcx
+	andq	$0x3c0,%rcx
 	subq	%rcx,%rsp
 	subq	$32,%rsp
 
@@ -816,7 +816,7 @@
 	leaq	L$AES_Td+2048(%rip),%r14
 	leaq	768(%rsp),%rbp
 	subq	%r14,%rbp
-	andq	$768,%rbp
+	andq	$0x300,%rbp
 	leaq	(%r14,%rbp,1),%r14
 	shrq	$3,%rbp
 	addq	%rbp,%r14
@@ -1333,9 +1333,9 @@
 	movq	%r14,%r10
 	leaq	2304(%r14),%r11
 	movq	%r15,%r12
-	andq	$4095,%r10
-	andq	$4095,%r11
-	andq	$4095,%r12
+	andq	$0xFFF,%r10
+	andq	$0xFFF,%r11
+	andq	$0xFFF,%r12
 
 	cmpq	%r11,%r12
 	jb	L$cbc_te_break_out
@@ -1344,7 +1344,7 @@
 	jmp	L$cbc_te_ok
 L$cbc_te_break_out:
 	subq	%r10,%r12
-	andq	$4095,%r12
+	andq	$0xFFF,%r12
 	addq	$320,%r12
 	subq	%r12,%r15
 .p2align	2
@@ -1370,7 +1370,7 @@
 
 	movq	%r15,%r10
 	subq	%r14,%r10
-	andq	$4095,%r10
+	andq	$0xfff,%r10
 	cmpq	$2304,%r10
 	jb	L$cbc_do_ecopy
 	cmpq	$4096-248,%r10
@@ -1557,7 +1557,7 @@
 	leaq	-88-63(%rcx),%r10
 	subq	%rbp,%r10
 	negq	%r10
-	andq	$960,%r10
+	andq	$0x3c0,%r10
 	subq	%r10,%rbp
 
 	xchgq	%rsp,%rbp
@@ -1586,7 +1586,7 @@
 	leaq	2048(%r14),%r14
 	leaq	768-8(%rsp),%rax
 	subq	%r14,%rax
-	andq	$768,%rax
+	andq	$0x300,%rax
 	leaq	(%r14,%rax,1),%r14
 
 	cmpq	$0,%rbx
diff --git a/third_party/boringssl/mac-x86_64/crypto/aes/aesni-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/aes/aesni-x86_64.S
index 69b22c2..3d98fa1 100644
--- a/third_party/boringssl/mac-x86_64/crypto/aes/aesni-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/aes/aesni-x86_64.S
@@ -507,7 +507,7 @@
 	testl	%r8d,%r8d
 	jz	L$ecb_decrypt
 
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	L$ecb_enc_tail
 
 	movdqu	(%rdi),%xmm2
@@ -519,7 +519,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	L$ecb_enc_loop8_enter
 .p2align	4
 L$ecb_enc_loop8:
@@ -547,7 +547,7 @@
 
 	call	_aesni_encrypt8
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	L$ecb_enc_loop8
 
 	movups	%xmm2,(%rsi)
@@ -561,22 +561,22 @@
 	movups	%xmm8,96(%rsi)
 	movups	%xmm9,112(%rsi)
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	L$ecb_ret
 
 L$ecb_enc_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$ecb_enc_one
 	movups	16(%rdi),%xmm3
 	je	L$ecb_enc_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$ecb_enc_three
 	movups	48(%rdi),%xmm5
 	je	L$ecb_enc_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	L$ecb_enc_five
 	movups	80(%rdi),%xmm7
 	je	L$ecb_enc_six
@@ -650,7 +650,7 @@
 
 .p2align	4
 L$ecb_decrypt:
-	cmpq	$128,%rdx
+	cmpq	$0x80,%rdx
 	jb	L$ecb_dec_tail
 
 	movdqu	(%rdi),%xmm2
@@ -662,7 +662,7 @@
 	movdqu	96(%rdi),%xmm8
 	movdqu	112(%rdi),%xmm9
 	leaq	128(%rdi),%rdi
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jmp	L$ecb_dec_loop8_enter
 .p2align	4
 L$ecb_dec_loop8:
@@ -691,7 +691,7 @@
 	call	_aesni_decrypt8
 
 	movups	(%r11),%xmm0
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	jnc	L$ecb_dec_loop8
 
 	movups	%xmm2,(%rsi)
@@ -713,22 +713,22 @@
 	movups	%xmm9,112(%rsi)
 	pxor	%xmm9,%xmm9
 	leaq	128(%rsi),%rsi
-	addq	$128,%rdx
+	addq	$0x80,%rdx
 	jz	L$ecb_ret
 
 L$ecb_dec_tail:
 	movups	(%rdi),%xmm2
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$ecb_dec_one
 	movups	16(%rdi),%xmm3
 	je	L$ecb_dec_two
 	movups	32(%rdi),%xmm4
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$ecb_dec_three
 	movups	48(%rdi),%xmm5
 	je	L$ecb_dec_four
 	movups	64(%rdi),%xmm6
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	jb	L$ecb_dec_five
 	movups	80(%rdi),%xmm7
 	je	L$ecb_dec_six
@@ -1606,7 +1606,7 @@
 
 	movdqa	L$xts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -1705,7 +1705,7 @@
 .byte	102,15,56,220,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	L$xts_enc_loop6
 .p2align	5
 L$xts_enc_loop6:
@@ -1844,13 +1844,13 @@
 	jz	L$xts_enc_done
 
 	pxor	%xmm0,%xmm11
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$xts_enc_one
 	pxor	%xmm0,%xmm12
 	je	L$xts_enc_two
 
 	pxor	%xmm0,%xmm13
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$xts_enc_three
 	pxor	%xmm0,%xmm14
 	je	L$xts_enc_four
@@ -2078,7 +2078,7 @@
 
 	movdqa	L$xts_magic(%rip),%xmm8
 	movdqa	%xmm2,%xmm15
-	pshufd	$95,%xmm2,%xmm9
+	pshufd	$0x5f,%xmm2,%xmm9
 	pxor	%xmm0,%xmm1
 	movdqa	%xmm9,%xmm14
 	paddd	%xmm9,%xmm9
@@ -2177,7 +2177,7 @@
 .byte	102,15,56,222,248
 	movups	64(%r11),%xmm0
 	movdqa	%xmm8,80(%rsp)
-	pshufd	$95,%xmm15,%xmm9
+	pshufd	$0x5f,%xmm15,%xmm9
 	jmp	L$xts_dec_loop6
 .p2align	5
 L$xts_dec_loop6:
@@ -2317,13 +2317,13 @@
 	jz	L$xts_dec_done
 
 	pxor	%xmm0,%xmm12
-	cmpq	$32,%rdx
+	cmpq	$0x20,%rdx
 	jb	L$xts_dec_one
 	pxor	%xmm0,%xmm13
 	je	L$xts_dec_two
 
 	pxor	%xmm0,%xmm14
-	cmpq	$64,%rdx
+	cmpq	$0x40,%rdx
 	jb	L$xts_dec_three
 	je	L$xts_dec_four
 
@@ -2354,7 +2354,7 @@
 	pcmpgtd	%xmm15,%xmm14
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	pshufd	$19,%xmm14,%xmm11
+	pshufd	$0x13,%xmm14,%xmm11
 	andq	$15,%r9
 	jz	L$xts_dec_ret
 
@@ -2644,7 +2644,7 @@
 	leaq	-8(%rax),%rbp
 	movups	(%r8),%xmm10
 	movl	%r10d,%eax
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	L$cbc_dec_tail
 
 	movups	(%rcx),%xmm0
@@ -2660,14 +2660,14 @@
 	movdqu	80(%rdi),%xmm7
 	movdqa	%xmm6,%xmm15
 	movl	_OPENSSL_ia32cap_P+4(%rip),%r9d
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	jbe	L$cbc_dec_six_or_seven
 
 	andl	$71303168,%r9d
-	subq	$80,%rdx
+	subq	$0x50,%rdx
 	cmpl	$4194304,%r9d
 	je	L$cbc_dec_loop6_enter
-	subq	$32,%rdx
+	subq	$0x20,%rdx
 	leaq	112(%rcx),%rcx
 	jmp	L$cbc_dec_loop8_enter
 .p2align	4
@@ -2682,7 +2682,7 @@
 	movups	16-112(%rcx),%xmm1
 	pxor	%xmm0,%xmm4
 	xorq	%r11,%r11
-	cmpq	$112,%rdx
+	cmpq	$0x70,%rdx
 	pxor	%xmm0,%xmm5
 	pxor	%xmm0,%xmm6
 	pxor	%xmm0,%xmm7
@@ -2867,21 +2867,21 @@
 	movups	%xmm8,96(%rsi)
 	leaq	112(%rsi),%rsi
 
-	subq	$128,%rdx
+	subq	$0x80,%rdx
 	ja	L$cbc_dec_loop8
 
 	movaps	%xmm9,%xmm2
 	leaq	-112(%rcx),%rcx
-	addq	$112,%rdx
+	addq	$0x70,%rdx
 	jle	L$cbc_dec_clear_tail_collected
 	movups	%xmm9,(%rsi)
 	leaq	16(%rsi),%rsi
-	cmpq	$80,%rdx
+	cmpq	$0x50,%rdx
 	jbe	L$cbc_dec_tail
 
 	movaps	%xmm11,%xmm2
 L$cbc_dec_six_or_seven:
-	cmpq	$96,%rdx
+	cmpq	$0x60,%rdx
 	ja	L$cbc_dec_seven
 
 	movaps	%xmm7,%xmm8
@@ -2974,33 +2974,33 @@
 	movl	%r10d,%eax
 	movdqu	%xmm6,64(%rsi)
 	leaq	80(%rsi),%rsi
-	subq	$96,%rdx
+	subq	$0x60,%rdx
 	ja	L$cbc_dec_loop6
 
 	movdqa	%xmm7,%xmm2
-	addq	$80,%rdx
+	addq	$0x50,%rdx
 	jle	L$cbc_dec_clear_tail_collected
 	movups	%xmm7,(%rsi)
 	leaq	16(%rsi),%rsi
 
 L$cbc_dec_tail:
 	movups	(%rdi),%xmm2
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_one
 
 	movups	16(%rdi),%xmm3
 	movaps	%xmm2,%xmm11
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_two
 
 	movups	32(%rdi),%xmm4
 	movaps	%xmm3,%xmm12
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_three
 
 	movups	48(%rdi),%xmm5
 	movaps	%xmm4,%xmm13
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jbe	L$cbc_dec_four
 
 	movups	64(%rdi),%xmm6
@@ -3025,7 +3025,7 @@
 	movdqa	%xmm6,%xmm2
 	pxor	%xmm6,%xmm6
 	pxor	%xmm7,%xmm7
-	subq	$16,%rdx
+	subq	$0x10,%rdx
 	jmp	L$cbc_dec_tail_collected
 
 .p2align	4
@@ -3344,7 +3344,7 @@
 	pslldq	$4,%xmm0
 	pxor	%xmm3,%xmm0
 
-	pshufd	$255,%xmm0,%xmm3
+	pshufd	$0xff,%xmm0,%xmm3
 	pxor	%xmm1,%xmm3
 	pslldq	$4,%xmm1
 	pxor	%xmm1,%xmm3
@@ -3431,7 +3431,7 @@
 	decl	%r10d
 	jz	L$done_key256
 
-	pshufd	$255,%xmm0,%xmm2
+	pshufd	$0xff,%xmm0,%xmm2
 	pxor	%xmm3,%xmm3
 .byte	102,15,56,221,211
 
diff --git a/third_party/boringssl/mac-x86_64/crypto/aes/bsaes-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/aes/bsaes-x86_64.S
index c2d0477..ad802e3 100644
--- a/third_party/boringssl/mac-x86_64/crypto/aes/bsaes-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/aes/bsaes-x86_64.S
@@ -325,45 +325,45 @@
 	pxor	%xmm2,%xmm5
 	decl	%r10d
 	jl	L$enc_done
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm3,%xmm9
+	pshufd	$0x93,%xmm3,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm5,%xmm10
+	pshufd	$0x93,%xmm5,%xmm10
 	pxor	%xmm9,%xmm3
-	pshufd	$147,%xmm2,%xmm11
+	pshufd	$0x93,%xmm2,%xmm11
 	pxor	%xmm10,%xmm5
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm2
-	pshufd	$147,%xmm1,%xmm13
+	pshufd	$0x93,%xmm1,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm1
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm2,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm5,%xmm11
-	pshufd	$78,%xmm2,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm7
 	pxor	%xmm1,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm3,%xmm10
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm1,%xmm5
+	pshufd	$0x4E,%xmm1,%xmm5
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm12,%xmm8
 	pxor	%xmm10,%xmm2
 	pxor	%xmm14,%xmm6
@@ -797,24 +797,24 @@
 	decl	%r10d
 	jl	L$dec_done
 
-	pshufd	$78,%xmm15,%xmm7
-	pshufd	$78,%xmm2,%xmm13
+	pshufd	$0x4E,%xmm15,%xmm7
+	pshufd	$0x4E,%xmm2,%xmm13
 	pxor	%xmm15,%xmm7
-	pshufd	$78,%xmm4,%xmm14
+	pshufd	$0x4E,%xmm4,%xmm14
 	pxor	%xmm2,%xmm13
-	pshufd	$78,%xmm0,%xmm8
+	pshufd	$0x4E,%xmm0,%xmm8
 	pxor	%xmm4,%xmm14
-	pshufd	$78,%xmm5,%xmm9
+	pshufd	$0x4E,%xmm5,%xmm9
 	pxor	%xmm0,%xmm8
-	pshufd	$78,%xmm3,%xmm10
+	pshufd	$0x4E,%xmm3,%xmm10
 	pxor	%xmm5,%xmm9
 	pxor	%xmm13,%xmm15
 	pxor	%xmm13,%xmm0
-	pshufd	$78,%xmm1,%xmm11
+	pshufd	$0x4E,%xmm1,%xmm11
 	pxor	%xmm3,%xmm10
 	pxor	%xmm7,%xmm5
 	pxor	%xmm8,%xmm3
-	pshufd	$78,%xmm6,%xmm12
+	pshufd	$0x4E,%xmm6,%xmm12
 	pxor	%xmm1,%xmm11
 	pxor	%xmm14,%xmm0
 	pxor	%xmm9,%xmm1
@@ -828,45 +828,45 @@
 	pxor	%xmm14,%xmm1
 	pxor	%xmm14,%xmm6
 	pxor	%xmm12,%xmm4
-	pshufd	$147,%xmm15,%xmm7
-	pshufd	$147,%xmm0,%xmm8
+	pshufd	$0x93,%xmm15,%xmm7
+	pshufd	$0x93,%xmm0,%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$147,%xmm5,%xmm9
+	pshufd	$0x93,%xmm5,%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm3,%xmm10
+	pshufd	$0x93,%xmm3,%xmm10
 	pxor	%xmm9,%xmm5
-	pshufd	$147,%xmm1,%xmm11
+	pshufd	$0x93,%xmm1,%xmm11
 	pxor	%xmm10,%xmm3
-	pshufd	$147,%xmm6,%xmm12
+	pshufd	$0x93,%xmm6,%xmm12
 	pxor	%xmm11,%xmm1
-	pshufd	$147,%xmm2,%xmm13
+	pshufd	$0x93,%xmm2,%xmm13
 	pxor	%xmm12,%xmm6
-	pshufd	$147,%xmm4,%xmm14
+	pshufd	$0x93,%xmm4,%xmm14
 	pxor	%xmm13,%xmm2
 	pxor	%xmm14,%xmm4
 
 	pxor	%xmm15,%xmm8
 	pxor	%xmm4,%xmm7
 	pxor	%xmm4,%xmm8
-	pshufd	$78,%xmm15,%xmm15
+	pshufd	$0x4E,%xmm15,%xmm15
 	pxor	%xmm0,%xmm9
-	pshufd	$78,%xmm0,%xmm0
+	pshufd	$0x4E,%xmm0,%xmm0
 	pxor	%xmm1,%xmm12
 	pxor	%xmm7,%xmm15
 	pxor	%xmm6,%xmm13
 	pxor	%xmm8,%xmm0
 	pxor	%xmm3,%xmm11
-	pshufd	$78,%xmm1,%xmm7
+	pshufd	$0x4E,%xmm1,%xmm7
 	pxor	%xmm2,%xmm14
-	pshufd	$78,%xmm6,%xmm8
+	pshufd	$0x4E,%xmm6,%xmm8
 	pxor	%xmm5,%xmm10
-	pshufd	$78,%xmm3,%xmm1
+	pshufd	$0x4E,%xmm3,%xmm1
 	pxor	%xmm4,%xmm10
-	pshufd	$78,%xmm4,%xmm6
+	pshufd	$0x4E,%xmm4,%xmm6
 	pxor	%xmm4,%xmm11
-	pshufd	$78,%xmm2,%xmm3
+	pshufd	$0x4E,%xmm2,%xmm3
 	pxor	%xmm11,%xmm7
-	pshufd	$78,%xmm5,%xmm2
+	pshufd	$0x4E,%xmm5,%xmm2
 	pxor	%xmm12,%xmm8
 	pxor	%xmm1,%xmm10
 	pxor	%xmm14,%xmm6
@@ -1556,20 +1556,20 @@
 	movdqa	%xmm7,(%rax)
 
 	andq	$-16,%r14
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	L$xts_enc_short
 	jmp	L$xts_enc_loop
 
 .p2align	4
 L$xts_enc_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1577,7 +1577,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1586,7 +1586,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1596,7 +1596,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1606,7 +1606,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1616,7 +1616,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1626,7 +1626,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -1670,20 +1670,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	L$xts_enc_loop
 
 L$xts_enc_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	L$xts_enc_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -1691,7 +1691,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -1702,7 +1702,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	L$xts_enc_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -1714,7 +1714,7 @@
 	cmpq	$32,%r14
 	je	L$xts_enc_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -1726,7 +1726,7 @@
 	cmpq	$48,%r14
 	je	L$xts_enc_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -1738,7 +1738,7 @@
 	cmpq	$64,%r14
 	je	L$xts_enc_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -1750,7 +1750,7 @@
 	cmpq	$80,%r14
 	je	L$xts_enc_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2016,20 +2016,20 @@
 	shlq	$4,%rax
 	subq	%rax,%r14
 
-	subq	$128,%rsp
+	subq	$0x80,%rsp
 	movdqa	32(%rbp),%xmm6
 
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jc	L$xts_dec_short
 	jmp	L$xts_dec_loop
 
 .p2align	4
 L$xts_dec_loop:
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2037,7 +2037,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2046,7 +2046,7 @@
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 	movdqu	0(%r12),%xmm7
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2056,7 +2056,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	16(%r12),%xmm8
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2066,7 +2066,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	32(%r12),%xmm9
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2076,7 +2076,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	48(%r12),%xmm10
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2086,7 +2086,7 @@
 	pxor	%xmm13,%xmm6
 	movdqu	64(%r12),%xmm11
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2130,20 +2130,20 @@
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
 
-	subq	$128,%r14
+	subq	$0x80,%r14
 	jnc	L$xts_dec_loop
 
 L$xts_dec_short:
-	addq	$128,%r14
+	addq	$0x80,%r14
 	jz	L$xts_dec_done
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm15
 	movdqa	%xmm6,0(%rsp)
@@ -2151,7 +2151,7 @@
 	pand	%xmm12,%xmm13
 	pcmpgtd	%xmm6,%xmm14
 	pxor	%xmm13,%xmm6
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm0
 	movdqa	%xmm6,16(%rsp)
@@ -2162,7 +2162,7 @@
 	movdqu	0(%r12),%xmm7
 	cmpq	$16,%r14
 	je	L$xts_dec_1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm1
 	movdqa	%xmm6,32(%rsp)
@@ -2174,7 +2174,7 @@
 	cmpq	$32,%r14
 	je	L$xts_dec_2
 	pxor	%xmm7,%xmm15
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm2
 	movdqa	%xmm6,48(%rsp)
@@ -2186,7 +2186,7 @@
 	cmpq	$48,%r14
 	je	L$xts_dec_3
 	pxor	%xmm8,%xmm0
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm3
 	movdqa	%xmm6,64(%rsp)
@@ -2198,7 +2198,7 @@
 	cmpq	$64,%r14
 	je	L$xts_dec_4
 	pxor	%xmm9,%xmm1
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm4
 	movdqa	%xmm6,80(%rsp)
@@ -2210,7 +2210,7 @@
 	cmpq	$80,%r14
 	je	L$xts_dec_5
 	pxor	%xmm10,%xmm2
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	pxor	%xmm14,%xmm14
 	movdqa	%xmm6,%xmm5
 	movdqa	%xmm6,96(%rsp)
@@ -2387,7 +2387,7 @@
 	pxor	%xmm14,%xmm14
 	movdqa	L$xts_magic(%rip),%xmm12
 	pcmpgtd	%xmm6,%xmm14
-	pshufd	$19,%xmm14,%xmm13
+	pshufd	$0x13,%xmm14,%xmm13
 	movdqa	%xmm6,%xmm5
 	paddq	%xmm6,%xmm6
 	pand	%xmm12,%xmm13
diff --git a/third_party/boringssl/mac-x86_64/crypto/aes/vpaes-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/aes/vpaes-x86_64.S
index 711ea43..997cde8 100644
--- a/third_party/boringssl/mac-x86_64/crypto/aes/vpaes-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/aes/vpaes-x86_64.S
@@ -61,7 +61,7 @@
 	addq	$16,%r11
 	pxor	%xmm0,%xmm3
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	subq	$1,%rax
 	pxor	%xmm3,%xmm0
 
@@ -121,10 +121,10 @@
 	pand	%xmm9,%xmm0
 .byte	102,15,56,0,208
 	movdqa	L$k_dipt+16(%rip),%xmm0
-	xorq	$48,%r11
+	xorq	$0x30,%r11
 	leaq	L$k_dsbd(%rip),%r10
 .byte	102,15,56,0,193
-	andq	$48,%r11
+	andq	$0x30,%r11
 	pxor	%xmm5,%xmm2
 	movdqa	L$k_mc_forward+48(%rip),%xmm5
 	pxor	%xmm2,%xmm0
@@ -243,7 +243,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	movdqu	%xmm3,(%rdx)
-	xorq	$48,%r8
+	xorq	$0x30,%r8
 
 L$schedule_go:
 	cmpl	$192,%esi
@@ -333,7 +333,7 @@
 	call	_vpaes_schedule_mangle
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 	movdqa	%xmm7,%xmm5
 	movdqa	%xmm6,%xmm7
 	call	_vpaes_schedule_low_round
@@ -400,8 +400,8 @@
 
 .p2align	4
 _vpaes_schedule_192_smear:
-	pshufd	$128,%xmm6,%xmm1
-	pshufd	$254,%xmm7,%xmm0
+	pshufd	$0x80,%xmm6,%xmm1
+	pshufd	$0xFE,%xmm7,%xmm0
 	pxor	%xmm1,%xmm6
 	pxor	%xmm1,%xmm1
 	pxor	%xmm0,%xmm6
@@ -438,7 +438,7 @@
 	pxor	%xmm1,%xmm7
 
 
-	pshufd	$255,%xmm0,%xmm0
+	pshufd	$0xFF,%xmm0,%xmm0
 .byte	102,15,58,15,192,1
 
 
@@ -597,7 +597,7 @@
 	movdqa	(%r8,%r10,1),%xmm1
 .byte	102,15,56,0,217
 	addq	$-16,%r8
-	andq	$48,%r8
+	andq	$0x30,%r8
 	movdqu	%xmm3,(%rdx)
 	.byte	0xf3,0xc3
 
@@ -616,7 +616,7 @@
 	movl	%eax,240(%rdx)
 
 	movl	$0,%ecx
-	movl	$48,%r8d
+	movl	$0x30,%r8d
 	call	_vpaes_schedule_core
 	xorl	%eax,%eax
 	.byte	0xf3,0xc3
diff --git a/third_party/boringssl/mac-x86_64/crypto/bn/rsaz-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/bn/rsaz-x86_64.S
index 5e9e82f..337276f 100644
--- a/third_party/boringssl/mac-x86_64/crypto/bn/rsaz-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/bn/rsaz-x86_64.S
@@ -465,48 +465,94 @@
 	pushq	%r14
 	pushq	%r15
 
-	movl	%r9d,%r9d
-	subq	$128+24,%rsp
+	subq	$152,%rsp
 L$mul_gather4_body:
-	movl	64(%rdx,%r9,4),%eax
-.byte	102,72,15,110,199
-	movl	(%rdx,%r9,4),%ebx
-.byte	102,72,15,110,201
-	movq	%r8,128(%rsp)
+	movd	%r9d,%xmm8
+	movdqa	L$inc+16(%rip),%xmm1
+	movdqa	L$inc(%rip),%xmm0
 
-	shlq	$32,%rax
-	orq	%rax,%rbx
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
+
+	movdqa	0(%rdx),%xmm8
+	movdqa	16(%rdx),%xmm9
+	movdqa	32(%rdx),%xmm10
+	movdqa	48(%rdx),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rdx),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rdx),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rdx),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rdx),%xmm15
+	leaq	128(%rdx),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
+	movq	%r8,128(%rsp)
+	movq	%rdi,128+8(%rsp)
+	movq	%rcx,128+16(%rsp)
+
 	movq	(%rsi),%rax
 	movq	8(%rsi),%rcx
-	leaq	128(%rdx,%r9,4),%rbp
 	mulq	%rbx
 	movq	%rax,(%rsp)
 	movq	%rcx,%rax
 	movq	%rdx,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r8
 	movq	16(%rsi),%rax
 	movq	%rdx,%r9
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r9
 	movq	24(%rsi),%rax
 	movq	%rdx,%r10
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r10
 	movq	32(%rsi),%rax
 	movq	%rdx,%r11
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r11
 	movq	40(%rsi),%rax
 	movq	%rdx,%r12
@@ -519,14 +565,12 @@
 	adcq	$0,%r13
 
 	mulq	%rbx
-	leaq	128(%rbp),%rbp
 	addq	%rax,%r13
 	movq	56(%rsi),%rax
 	movq	%rdx,%r14
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r14
 	movq	(%rsi),%rax
 	movq	%rdx,%r15
@@ -538,6 +582,35 @@
 
 .p2align	5
 L$oop_mul_gather:
+	movdqa	0(%rbp),%xmm8
+	movdqa	16(%rbp),%xmm9
+	movdqa	32(%rbp),%xmm10
+	movdqa	48(%rbp),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rbp),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rbp),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rbp),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rbp),%xmm15
+	leaq	128(%rbp),%rbp
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+.byte	102,76,15,126,195
+
 	mulq	%rbx
 	addq	%rax,%r8
 	movq	8(%rsi),%rax
@@ -546,7 +619,6 @@
 	adcq	$0,%r8
 
 	mulq	%rbx
-	movd	(%rbp),%xmm4
 	addq	%rax,%r9
 	movq	16(%rsi),%rax
 	adcq	$0,%rdx
@@ -555,7 +627,6 @@
 	adcq	$0,%r9
 
 	mulq	%rbx
-	movd	64(%rbp),%xmm5
 	addq	%rax,%r10
 	movq	24(%rsi),%rax
 	adcq	$0,%rdx
@@ -564,7 +635,6 @@
 	adcq	$0,%r10
 
 	mulq	%rbx
-	pslldq	$4,%xmm5
 	addq	%rax,%r11
 	movq	32(%rsi),%rax
 	adcq	$0,%rdx
@@ -573,7 +643,6 @@
 	adcq	$0,%r11
 
 	mulq	%rbx
-	por	%xmm5,%xmm4
 	addq	%rax,%r12
 	movq	40(%rsi),%rax
 	adcq	$0,%rdx
@@ -598,7 +667,6 @@
 	adcq	$0,%r14
 
 	mulq	%rbx
-.byte	102,72,15,126,227
 	addq	%rax,%r15
 	movq	(%rsi),%rax
 	adcq	$0,%rdx
@@ -606,7 +674,6 @@
 	movq	%rdx,%r15
 	adcq	$0,%r15
 
-	leaq	128(%rbp),%rbp
 	leaq	8(%rdi),%rdi
 
 	decl	%ecx
@@ -621,8 +688,8 @@
 	movq	%r14,48(%rdi)
 	movq	%r15,56(%rdi)
 
-.byte	102,72,15,126,199
-.byte	102,72,15,126,205
+	movq	128+8(%rsp),%rdi
+	movq	128+16(%rsp),%rbp
 
 	movq	(%rsp),%r8
 	movq	8(%rsp),%r9
@@ -672,7 +739,7 @@
 	movl	%r9d,%r9d
 	subq	$128+24,%rsp
 L$mul_scatter4_body:
-	leaq	(%r8,%r9,4),%r8
+	leaq	(%r8,%r9,8),%r8
 .byte	102,72,15,110,199
 .byte	102,72,15,110,202
 .byte	102,73,15,110,208
@@ -708,30 +775,14 @@
 
 	call	__rsaz_512_subtract
 
-	movl	%r8d,0(%rsi)
-	shrq	$32,%r8
-	movl	%r9d,128(%rsi)
-	shrq	$32,%r9
-	movl	%r10d,256(%rsi)
-	shrq	$32,%r10
-	movl	%r11d,384(%rsi)
-	shrq	$32,%r11
-	movl	%r12d,512(%rsi)
-	shrq	$32,%r12
-	movl	%r13d,640(%rsi)
-	shrq	$32,%r13
-	movl	%r14d,768(%rsi)
-	shrq	$32,%r14
-	movl	%r15d,896(%rsi)
-	shrq	$32,%r15
-	movl	%r8d,64(%rsi)
-	movl	%r9d,192(%rsi)
-	movl	%r10d,320(%rsi)
-	movl	%r11d,448(%rsi)
-	movl	%r12d,576(%rsi)
-	movl	%r13d,704(%rsi)
-	movl	%r14d,832(%rsi)
-	movl	%r15d,960(%rsi)
+	movq	%r8,0(%rsi)
+	movq	%r9,128(%rsi)
+	movq	%r10,256(%rsi)
+	movq	%r11,384(%rsi)
+	movq	%r12,512(%rsi)
+	movq	%r13,640(%rsi)
+	movq	%r14,768(%rsi)
+	movq	%r15,896(%rsi)
 
 	leaq	128+24+48(%rsp),%rax
 	movq	-48(%rax),%r15
@@ -1086,16 +1137,14 @@
 
 .p2align	4
 _rsaz_512_scatter4:
-	leaq	(%rdi,%rdx,4),%rdi
+	leaq	(%rdi,%rdx,8),%rdi
 	movl	$8,%r9d
 	jmp	L$oop_scatter
 .p2align	4
 L$oop_scatter:
 	movq	(%rsi),%rax
 	leaq	8(%rsi),%rsi
-	movl	%eax,(%rdi)
-	shrq	$32,%rax
-	movl	%eax,64(%rdi)
+	movq	%rax,(%rdi)
 	leaq	128(%rdi),%rdi
 	decl	%r9d
 	jnz	L$oop_scatter
@@ -1107,20 +1156,73 @@
 
 .p2align	4
 _rsaz_512_gather4:
-	leaq	(%rsi,%rdx,4),%rsi
+	movd	%edx,%xmm8
+	movdqa	L$inc+16(%rip),%xmm1
+	movdqa	L$inc(%rip),%xmm0
+
+	pshufd	$0,%xmm8,%xmm8
+	movdqa	%xmm1,%xmm7
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm8,%xmm0
+	movdqa	%xmm7,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm8,%xmm1
+	movdqa	%xmm7,%xmm4
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm8,%xmm2
+	movdqa	%xmm7,%xmm5
+	paddd	%xmm3,%xmm4
+	pcmpeqd	%xmm8,%xmm3
+	movdqa	%xmm7,%xmm6
+	paddd	%xmm4,%xmm5
+	pcmpeqd	%xmm8,%xmm4
+	paddd	%xmm5,%xmm6
+	pcmpeqd	%xmm8,%xmm5
+	paddd	%xmm6,%xmm7
+	pcmpeqd	%xmm8,%xmm6
+	pcmpeqd	%xmm8,%xmm7
 	movl	$8,%r9d
 	jmp	L$oop_gather
 .p2align	4
 L$oop_gather:
-	movl	(%rsi),%eax
-	movl	64(%rsi),%r8d
+	movdqa	0(%rsi),%xmm8
+	movdqa	16(%rsi),%xmm9
+	movdqa	32(%rsi),%xmm10
+	movdqa	48(%rsi),%xmm11
+	pand	%xmm0,%xmm8
+	movdqa	64(%rsi),%xmm12
+	pand	%xmm1,%xmm9
+	movdqa	80(%rsi),%xmm13
+	pand	%xmm2,%xmm10
+	movdqa	96(%rsi),%xmm14
+	pand	%xmm3,%xmm11
+	movdqa	112(%rsi),%xmm15
 	leaq	128(%rsi),%rsi
-	shlq	$32,%r8
-	orq	%r8,%rax
-	movq	%rax,(%rdi)
+	pand	%xmm4,%xmm12
+	pand	%xmm5,%xmm13
+	pand	%xmm6,%xmm14
+	pand	%xmm7,%xmm15
+	por	%xmm10,%xmm8
+	por	%xmm11,%xmm9
+	por	%xmm12,%xmm8
+	por	%xmm13,%xmm9
+	por	%xmm14,%xmm8
+	por	%xmm15,%xmm9
+
+	por	%xmm9,%xmm8
+	pshufd	$0x4e,%xmm8,%xmm9
+	por	%xmm9,%xmm8
+	movq	%xmm8,(%rdi)
 	leaq	8(%rdi),%rdi
 	decl	%r9d
 	jnz	L$oop_gather
 	.byte	0xf3,0xc3
+L$SEH_end_rsaz_512_gather4:
 
+
+.p2align	6
+L$inc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 #endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont.S b/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont.S
index 6b9bc05..51e5d19 100644
--- a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont.S
+++ b/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont.S
@@ -634,20 +634,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,4),%r11
+	leaq	-64(%rsp,%r9,2),%r11
 	movq	(%r8),%r8
 	subq	%rsi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$sqr8x_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	-64(%rsp,%r9,2),%rsp
 	jmp	L$sqr8x_sp_done
 
 .p2align	5
 L$sqr8x_sp_alt:
-	leaq	4096-64(,%r9,4),%r10
-	leaq	-64(%rsp,%r9,4),%rsp
+	leaq	4096-64(,%r9,2),%r10
+	leaq	-64(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -657,58 +657,80 @@
 	movq	%r9,%r10
 	negq	%r9
 
-	leaq	64(%rsp,%r9,2),%r11
 	movq	%r8,32(%rsp)
 	movq	%rax,40(%rsp)
 L$sqr8x_body:
 
-	movq	%r9,%rbp
-.byte	102,73,15,110,211
-	shrq	$3+2,%rbp
-	movl	_OPENSSL_ia32cap_P+8(%rip),%eax
-	jmp	L$sqr8x_copy_n
-
-.p2align	5
-L$sqr8x_copy_n:
-	movq	0(%rcx),%xmm0
-	movq	8(%rcx),%xmm1
-	movq	16(%rcx),%xmm3
-	movq	24(%rcx),%xmm4
-	leaq	32(%rcx),%rcx
-	movdqa	%xmm0,0(%r11)
-	movdqa	%xmm1,16(%r11)
-	movdqa	%xmm3,32(%r11)
-	movdqa	%xmm4,48(%r11)
-	leaq	64(%r11),%r11
-	decq	%rbp
-	jnz	L$sqr8x_copy_n
-
+.byte	102,72,15,110,209
 	pxor	%xmm0,%xmm0
 .byte	102,72,15,110,207
 .byte	102,73,15,110,218
 	call	_bn_sqr8x_internal
 
-	pxor	%xmm0,%xmm0
-	leaq	48(%rsp),%rax
-	leaq	64(%rsp,%r9,2),%rdx
-	shrq	$3+2,%r9
-	movq	40(%rsp),%rsi
-	jmp	L$sqr8x_zero
+
+
+
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+	movq	%r9,%rdx
+.byte	102,72,15,126,207
+	sarq	$3+2,%rcx
+	jmp	L$sqr8x_sub
 
 .p2align	5
-L$sqr8x_zero:
-	movdqa	%xmm0,0(%rax)
-	movdqa	%xmm0,16(%rax)
-	movdqa	%xmm0,32(%rax)
-	movdqa	%xmm0,48(%rax)
-	leaq	64(%rax),%rax
-	movdqa	%xmm0,0(%rdx)
-	movdqa	%xmm0,16(%rdx)
-	movdqa	%xmm0,32(%rdx)
-	movdqa	%xmm0,48(%rdx)
-	leaq	64(%rdx),%rdx
-	decq	%r9
-	jnz	L$sqr8x_zero
+L$sqr8x_sub:
+	movq	0(%rbx),%r12
+	movq	8(%rbx),%r13
+	movq	16(%rbx),%r14
+	movq	24(%rbx),%r15
+	leaq	32(%rbx),%rbx
+	sbbq	0(%rbp),%r12
+	sbbq	8(%rbp),%r13
+	sbbq	16(%rbp),%r14
+	sbbq	24(%rbp),%r15
+	leaq	32(%rbp),%rbp
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+	leaq	32(%rdi),%rdi
+	incq	%rcx
+	jnz	L$sqr8x_sub
+
+	sbbq	$0,%rax
+	leaq	(%rbx,%r9,1),%rbx
+	leaq	(%rdi,%r9,1),%rdi
+
+.byte	102,72,15,110,200
+	pxor	%xmm0,%xmm0
+	pshufd	$0,%xmm1,%xmm1
+	movq	40(%rsp),%rsi
+	jmp	L$sqr8x_cond_copy
+
+.p2align	5
+L$sqr8x_cond_copy:
+	movdqa	0(%rbx),%xmm2
+	movdqa	16(%rbx),%xmm3
+	leaq	32(%rbx),%rbx
+	movdqu	0(%rdi),%xmm4
+	movdqu	16(%rdi),%xmm5
+	leaq	32(%rdi),%rdi
+	movdqa	%xmm0,-32(%rbx)
+	movdqa	%xmm0,-16(%rbx)
+	movdqa	%xmm0,-32(%rbx,%rdx,1)
+	movdqa	%xmm0,-16(%rbx,%rdx,1)
+	pcmpeqd	%xmm1,%xmm0
+	pand	%xmm1,%xmm2
+	pand	%xmm1,%xmm3
+	pand	%xmm0,%xmm4
+	pand	%xmm0,%xmm5
+	pxor	%xmm0,%xmm0
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqu	%xmm4,-32(%rdi)
+	movdqu	%xmm5,-16(%rdi)
+	addq	$32,%r9
+	jnz	L$sqr8x_cond_copy
 
 	movq	$1,%rax
 	movq	-48(%rsi),%r15
diff --git a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S b/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S
index 2e8f469..f3ad8d7 100644
--- a/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S
+++ b/third_party/boringssl/mac-x86_64/crypto/bn/x86_64-mont5.S
@@ -16,46 +16,151 @@
 L$mul_enter:
 	movl	%r9d,%r9d
 	movq	%rsp,%rax
-	movl	8(%rsp),%r10d
+	movd	8(%rsp),%xmm5
+	leaq	L$inc(%rip),%r10
 	pushq	%rbx
 	pushq	%rbp
 	pushq	%r12
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 	leaq	2(%r9),%r11
 	negq	%r11
-	leaq	(%rsp,%r11,8),%rsp
+	leaq	-264(%rsp,%r11,8),%rsp
 	andq	$-1024,%rsp
 
 	movq	%rax,8(%rsp,%r9,8)
 L$mul_body:
-	movq	%rdx,%r12
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	L$magic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%r12,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
+	leaq	128(%rdx),%r12
+	movdqa	0(%r10),%xmm0
+	movdqa	16(%r10),%xmm1
+	leaq	24-112(%rsp,%r9,8),%r10
+	andq	$-16,%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+.byte	0x67
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
+.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
 	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 .byte	102,72,15,126,195
 
 	movq	(%r8),%r8
@@ -64,29 +169,14 @@
 	xorq	%r14,%r14
 	xorq	%r15,%r15
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	movq	%r8,%rbp
 	mulq	%rbx
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -119,14 +209,12 @@
 	cmpq	%r9,%r15
 	jne	L$1st
 
-.byte	102,72,15,126,195
 
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r13
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 	movq	%r10,%r11
 
@@ -140,33 +228,78 @@
 	jmp	L$outer
 .p2align	4
 L$outer:
+	leaq	24+128(%rsp,%r9,8),%rdx
+	andq	$-16,%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+
+	movq	(%rsi),%rax
+.byte	102,72,15,126,195
+
 	xorq	%r15,%r15
 	movq	%r8,%rbp
 	movq	(%rsp),%r10
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-
 	mulq	%rbx
 	addq	%rax,%r10
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-
 	imulq	%r10,%rbp
 	movq	%rdx,%r11
 
-	por	%xmm2,%xmm0
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi),%rax
@@ -202,15 +335,12 @@
 	cmpq	%r9,%r15
 	jne	L$inner
 
-.byte	102,72,15,126,195
-
 	addq	%rax,%r13
-	movq	(%rsi),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r13
-	movq	(%rsp,%r15,8),%r10
+	movq	(%rsp,%r9,8),%r10
 	adcq	$0,%rdx
-	movq	%r13,-16(%rsp,%r15,8)
+	movq	%r13,-16(%rsp,%r9,8)
 	movq	%rdx,%r13
 
 	xorq	%rdx,%rdx
@@ -256,6 +386,7 @@
 
 	movq	8(%rsp,%r9,8),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -278,10 +409,10 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
+
 .byte	0x67
-	movl	%r9d,%r10d
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 
 
@@ -291,19 +422,21 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$mul4xsp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	L$mul4xsp_done
 
 .p2align	5
 L$mul4xsp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -319,6 +452,7 @@
 
 	movq	40(%rsp),%rsi
 	movq	$1,%rax
+
 	movq	-48(%rsi),%r15
 	movq	-40(%rsi),%r14
 	movq	-32(%rsi),%r13
@@ -334,47 +468,141 @@
 .p2align	5
 mul4x_internal:
 	shlq	$5,%r9
-	movl	8(%rax),%r10d
-	leaq	256(%rdx,%r9,1),%r13
+	movd	8(%rax),%xmm5
+	leaq	L$inc(%rip),%rax
+	leaq	128(%rdx,%r9,1),%r13
 	shrq	$5,%r9
-	movq	%r10,%r11
-	shrq	$3,%r10
-	andq	$7,%r11
-	notq	%r10
-	leaq	L$magic_masks(%rip),%rax
-	andq	$3,%r10
-	leaq	96(%rdx,%r11,8),%r12
-	movq	0(%rax,%r10,8),%xmm4
-	movq	8(%rax,%r10,8),%xmm5
-	addq	$7,%r11
-	movq	16(%rax,%r10,8),%xmm6
-	movq	24(%rax,%r10,8),%xmm7
-	andq	$7,%r11
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	88-112(%rsp,%r9,1),%r10
+	leaq	128(%rdx),%r12
 
-	movq	-96(%r12),%xmm0
-	leaq	256(%r12),%r14
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-	pand	%xmm6,%xmm2
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+.byte	0x67,0x67
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
 .byte	0x67
-	por	%xmm1,%xmm0
-	movq	-96(%r14),%xmm1
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,112(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,128(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,144(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,160(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,176(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,192(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,208(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,224(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,240(%r10)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,256(%r10)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,272(%r10)
+	movdqa	%xmm4,%xmm2
+
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,288(%r10)
+	movdqa	%xmm4,%xmm3
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,304(%r10)
+
+	paddd	%xmm2,%xmm3
 .byte	0x67
-	pand	%xmm7,%xmm3
-.byte	0x67
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,320(%r10)
+
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,336(%r10)
+	pand	64(%r12),%xmm0
+
+	pand	80(%r12),%xmm1
+	pand	96(%r12),%xmm2
+	movdqa	%xmm3,352(%r10)
+	pand	112(%r12),%xmm3
 	por	%xmm2,%xmm0
-	movq	-32(%r14),%xmm2
-.byte	0x67
-	pand	%xmm4,%xmm1
-.byte	0x67
-	por	%xmm3,%xmm0
-	movq	32(%r14),%xmm3
-
+	por	%xmm3,%xmm1
+	movdqa	-128(%r12),%xmm4
+	movdqa	-112(%r12),%xmm5
+	movdqa	-96(%r12),%xmm2
+	pand	112(%r10),%xmm4
+	movdqa	-80(%r12),%xmm3
+	pand	128(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	144(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	160(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	-64(%r12),%xmm4
+	movdqa	-48(%r12),%xmm5
+	movdqa	-32(%r12),%xmm2
+	pand	176(%r10),%xmm4
+	movdqa	-16(%r12),%xmm3
+	pand	192(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	208(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	224(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	movdqa	0(%r12),%xmm4
+	movdqa	16(%r12),%xmm5
+	movdqa	32(%r12),%xmm2
+	pand	240(%r10),%xmm4
+	movdqa	48(%r12),%xmm3
+	pand	256(%r10),%xmm5
+	por	%xmm4,%xmm0
+	pand	272(%r10),%xmm2
+	por	%xmm5,%xmm1
+	pand	288(%r10),%xmm3
+	por	%xmm2,%xmm0
+	por	%xmm3,%xmm1
+	por	%xmm1,%xmm0
+	pshufd	$0x4e,%xmm0,%xmm1
+	por	%xmm1,%xmm0
+	leaq	256(%r12),%r12
 .byte	102,72,15,126,195
-	movq	96(%r14),%xmm0
+
 	movq	%r13,16+8(%rsp)
 	movq	%rdi,56+8(%rsp)
 
@@ -388,26 +616,10 @@
 	movq	%rax,%r10
 	movq	(%rcx),%rax
 
-	pand	%xmm5,%xmm2
-	pand	%xmm6,%xmm3
-	por	%xmm2,%xmm1
-
 	imulq	%r10,%rbp
-
-
-
-
-
-
-
-	leaq	64+8(%rsp,%r11,8),%r14
+	leaq	64+8(%rsp),%r14
 	movq	%rdx,%r11
 
-	pand	%xmm7,%xmm0
-	por	%xmm3,%xmm1
-	leaq	512(%r12),%r12
-	por	%xmm1,%xmm0
-
 	mulq	%rbp
 	addq	%rax,%r10
 	movq	8(%rsi,%r9,1),%rax
@@ -416,7 +628,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -426,7 +638,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -436,7 +648,7 @@
 L$1st4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -452,7 +664,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -482,7 +694,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -491,7 +703,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdi,(%r14)
 	movq	%rdx,%r13
@@ -501,7 +713,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	leaq	32(%r14),%r14
 	adcq	$0,%rdx
 	movq	%rdx,%r11
@@ -517,7 +729,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	movq	%rdx,%r10
 
@@ -530,8 +742,7 @@
 	movq	%rdi,-16(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -542,6 +753,63 @@
 
 .p2align	5
 L$outer4x:
+	leaq	16+128(%r14),%rdx
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r12),%xmm0
+	movdqa	-112(%r12),%xmm1
+	movdqa	-96(%r12),%xmm2
+	movdqa	-80(%r12),%xmm3
+	pand	-128(%rdx),%xmm0
+	pand	-112(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r12),%xmm0
+	movdqa	-48(%r12),%xmm1
+	movdqa	-32(%r12),%xmm2
+	movdqa	-16(%r12),%xmm3
+	pand	-64(%rdx),%xmm0
+	pand	-48(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r12),%xmm0
+	movdqa	16(%r12),%xmm1
+	movdqa	32(%r12),%xmm2
+	movdqa	48(%r12),%xmm3
+	pand	0(%rdx),%xmm0
+	pand	16(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r12),%xmm0
+	movdqa	80(%r12),%xmm1
+	movdqa	96(%r12),%xmm2
+	movdqa	112(%r12),%xmm3
+	pand	64(%rdx),%xmm0
+	pand	80(%rdx),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rdx),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rdx),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
+	leaq	256(%r12),%r12
+.byte	102,72,15,126,195
+
 	movq	(%r14,%r9,1),%r10
 	movq	%r8,%rbp
 	mulq	%rbx
@@ -549,25 +817,11 @@
 	movq	(%rcx),%rax
 	adcq	$0,%rdx
 
-	movq	-96(%r12),%xmm0
-	movq	-32(%r12),%xmm1
-	pand	%xmm4,%xmm0
-	movq	32(%r12),%xmm2
-	pand	%xmm5,%xmm1
-	movq	96(%r12),%xmm3
-
 	imulq	%r10,%rbp
-.byte	0x67
 	movq	%rdx,%r11
 	movq	%rdi,(%r14)
 
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-	por	%xmm2,%xmm0
 	leaq	(%r14,%r9,1),%r14
-	leaq	256(%r12),%r12
-	por	%xmm3,%xmm0
 
 	mulq	%rbp
 	addq	%rax,%r10
@@ -577,7 +831,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -589,7 +843,7 @@
 	adcq	$0,%rdx
 	addq	%r11,%rdi
 	leaq	32(%r9),%r15
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%rdx,%r13
 	jmp	L$inner4x
@@ -598,7 +852,7 @@
 L$inner4x:
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -616,7 +870,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	-16(%rcx),%rax
+	movq	-8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -650,7 +904,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	16(%rcx),%rax
+	movq	8(%rcx),%rax
 	adcq	$0,%rdx
 	addq	8(%r14),%r11
 	adcq	$0,%rdx
@@ -661,7 +915,7 @@
 	movq	16(%rsi,%r15,1),%rax
 	adcq	$0,%rdx
 	addq	%r11,%rdi
-	leaq	64(%rcx),%rcx
+	leaq	32(%rcx),%rcx
 	adcq	$0,%rdx
 	movq	%r13,-8(%r14)
 	movq	%rdx,%r13
@@ -671,7 +925,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	-32(%rcx),%rax
+	movq	-16(%rcx),%rax
 	adcq	$0,%rdx
 	addq	16(%r14),%r10
 	leaq	32(%r14),%r14
@@ -690,7 +944,7 @@
 	mulq	%rbx
 	addq	%rax,%r11
 	movq	%rbp,%rax
-	movq	-16(%rcx),%rbp
+	movq	-8(%rcx),%rbp
 	adcq	$0,%rdx
 	addq	-8(%r14),%r11
 	adcq	$0,%rdx
@@ -705,9 +959,8 @@
 	movq	%r13,-24(%r14)
 	movq	%rdx,%r13
 
-.byte	102,72,15,126,195
 	movq	%rdi,-16(%r14)
-	leaq	(%rcx,%r9,2),%rcx
+	leaq	(%rcx,%r9,1),%rcx
 
 	xorq	%rdi,%rdi
 	addq	%r10,%r13
@@ -718,16 +971,23 @@
 
 	cmpq	16+8(%rsp),%r12
 	jb	L$outer4x
+	xorq	%rax,%rax
 	subq	%r13,%rbp
 	adcq	%r15,%r15
 	orq	%r15,%rdi
-	xorq	$1,%rdi
+	subq	%rdi,%rax
 	leaq	(%r14,%r9,1),%rbx
-	leaq	(%rcx,%rdi,8),%rbp
+	movq	(%rcx),%r12
+	leaq	(%rcx),%rbp
 	movq	%r9,%rcx
 	sarq	$3+2,%rcx
 	movq	56+8(%rsp),%rdi
-	jmp	L$sqr4x_sub
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	L$sqr4x_sub_entry
 
 .globl	_bn_power5
 .private_extern _bn_power5
@@ -741,9 +1001,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leal	(%r9,%r9,2),%r10d
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -753,19 +1013,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$pwr_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	L$pwr_sp_done
 
 .p2align	5
 L$pwr_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -793,10 +1054,15 @@
 .byte	102,72,15,110,226
 
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 
 .byte	102,72,15,126,209
 .byte	102,72,15,126,226
@@ -1341,9 +1607,9 @@
 	movq	%rbx,-16(%rdi)
 	movq	%r8,-8(%rdi)
 .byte	102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
 	xorq	%rax,%rax
-	leaq	(%rbp,%r9,2),%rcx
+	leaq	(%r9,%rbp,1),%rcx
 	leaq	48+8(%rsp,%r9,2),%rdx
 	movq	%rcx,0+8(%rsp)
 	leaq	48+8(%rsp,%r9,1),%rdi
@@ -1376,14 +1642,14 @@
 .p2align	5
 L$8x_reduce:
 	mulq	%rbx
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	negq	%r8
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	movq	%rbx,48-8+8(%rsp,%rcx,8)
@@ -1392,7 +1658,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	32+8(%rsp),%rsi
@@ -1401,7 +1667,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	imulq	%r8,%rsi
 	addq	%r11,%r10
@@ -1410,7 +1676,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1418,7 +1684,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1426,7 +1692,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1444,7 +1710,7 @@
 	decl	%ecx
 	jnz	L$8x_reduce
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	xorq	%rax,%rax
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
@@ -1470,14 +1736,14 @@
 L$8x_tail:
 	mulq	%rbx
 	addq	%rax,%r8
-	movq	16(%rbp),%rax
+	movq	8(%rbp),%rax
 	movq	%r8,(%rdi)
 	movq	%rdx,%r8
 	adcq	$0,%r8
 
 	mulq	%rbx
 	addq	%rax,%r9
-	movq	32(%rbp),%rax
+	movq	16(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r9,%r8
 	leaq	8(%rdi),%rdi
@@ -1486,7 +1752,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r10
-	movq	48(%rbp),%rax
+	movq	24(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r10,%r9
 	movq	%rdx,%r10
@@ -1494,7 +1760,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r11
-	movq	64(%rbp),%rax
+	movq	32(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r11,%r10
 	movq	%rdx,%r11
@@ -1502,7 +1768,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r12
-	movq	80(%rbp),%rax
+	movq	40(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r12,%r11
 	movq	%rdx,%r12
@@ -1510,7 +1776,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r13
-	movq	96(%rbp),%rax
+	movq	48(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r13,%r12
 	movq	%rdx,%r13
@@ -1518,7 +1784,7 @@
 
 	mulq	%rbx
 	addq	%rax,%r14
-	movq	112(%rbp),%rax
+	movq	56(%rbp),%rax
 	adcq	$0,%rdx
 	addq	%r14,%r13
 	movq	%rdx,%r14
@@ -1536,7 +1802,7 @@
 	decl	%ecx
 	jnz	L$8x_tail
 
-	leaq	128(%rbp),%rbp
+	leaq	64(%rbp),%rbp
 	movq	8+8(%rsp),%rdx
 	cmpq	0+8(%rsp),%rbp
 	jae	L$8x_tail_done
@@ -1560,6 +1826,15 @@
 .p2align	5
 L$8x_tail_done:
 	addq	(%rdx),%r8
+	adcq	$0,%r9
+	adcq	$0,%r10
+	adcq	$0,%r11
+	adcq	$0,%r12
+	adcq	$0,%r13
+	adcq	$0,%r14
+	adcq	$0,%r15
+
+
 	xorq	%rax,%rax
 
 	negq	%rsi
@@ -1573,7 +1848,7 @@
 	adcq	48(%rdi),%r14
 	adcq	56(%rdi),%r15
 	adcq	$0,%rax
-	movq	-16(%rbp),%rcx
+	movq	-8(%rbp),%rcx
 	xorq	%rsi,%rsi
 
 .byte	102,72,15,126,213
@@ -1591,40 +1866,58 @@
 
 	cmpq	%rdx,%rdi
 	jb	L$8x_reduction_loop
+	.byte	0xf3,0xc3
 
-	subq	%r15,%rcx
-	leaq	(%rdi,%r9,1),%rbx
-	adcq	%rsi,%rsi
-	movq	%r9,%rcx
-	orq	%rsi,%rax
-.byte	102,72,15,126,207
-	xorq	$1,%rax
-.byte	102,72,15,126,206
-	leaq	(%rbp,%rax,8),%rbp
-	sarq	$3+2,%rcx
-	jmp	L$sqr4x_sub
 
 .p2align	5
+__bn_post4x_internal:
+	movq	0(%rbp),%r12
+	leaq	(%rdi,%r9,1),%rbx
+	movq	%r9,%rcx
+.byte	102,72,15,126,207
+	negq	%rax
+.byte	102,72,15,126,206
+	sarq	$3+2,%rcx
+	decq	%r12
+	xorq	%r10,%r10
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+	jmp	L$sqr4x_sub_entry
+
+.p2align	4
 L$sqr4x_sub:
-.byte	0x66
-	movq	0(%rbx),%r12
-	movq	8(%rbx),%r13
-	sbbq	0(%rbp),%r12
-	movq	16(%rbx),%r14
-	sbbq	16(%rbp),%r13
-	movq	24(%rbx),%r15
-	leaq	32(%rbx),%rbx
-	sbbq	32(%rbp),%r14
+	movq	0(%rbp),%r12
+	movq	8(%rbp),%r13
+	movq	16(%rbp),%r14
+	movq	24(%rbp),%r15
+L$sqr4x_sub_entry:
+	leaq	32(%rbp),%rbp
+	notq	%r12
+	notq	%r13
+	notq	%r14
+	notq	%r15
+	andq	%rax,%r12
+	andq	%rax,%r13
+	andq	%rax,%r14
+	andq	%rax,%r15
+
+	negq	%r10
+	adcq	0(%rbx),%r12
+	adcq	8(%rbx),%r13
+	adcq	16(%rbx),%r14
+	adcq	24(%rbx),%r15
 	movq	%r12,0(%rdi)
-	sbbq	48(%rbp),%r15
-	leaq	64(%rbp),%rbp
+	leaq	32(%rbx),%rbx
 	movq	%r13,8(%rdi)
+	sbbq	%r10,%r10
 	movq	%r14,16(%rdi)
 	movq	%r15,24(%rdi)
 	leaq	32(%rdi),%rdi
 
 	incq	%rcx
 	jnz	L$sqr4x_sub
+
 	movq	%r9,%r10
 	negq	%r9
 	.byte	0xf3,0xc3
@@ -1651,10 +1944,9 @@
 	pushq	%r13
 	pushq	%r14
 	pushq	%r15
-.byte	0x67
-	movl	%r9d,%r10d
+
 	shll	$3,%r9d
-	shll	$3+2,%r10d
+	leaq	(%r9,%r9,2),%r10
 	negq	%r9
 	movq	(%r8),%r8
 
@@ -1664,19 +1956,20 @@
 
 
 
-	leaq	-64(%rsp,%r9,2),%r11
-	subq	%rsi,%r11
+
+	leaq	-320(%rsp,%r9,2),%r11
+	subq	%rdi,%r11
 	andq	$4095,%r11
 	cmpq	%r11,%r10
 	jb	L$from_sp_alt
 	subq	%r11,%rsp
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	-320(%rsp,%r9,2),%rsp
 	jmp	L$from_sp_done
 
 .p2align	5
 L$from_sp_alt:
-	leaq	4096-64(,%r9,2),%r10
-	leaq	-64(%rsp,%r9,2),%rsp
+	leaq	4096-320(,%r9,2),%r10
+	leaq	-320(%rsp,%r9,2),%rsp
 	subq	%r10,%r11
 	movq	$0,%r10
 	cmovcq	%r10,%r11
@@ -1727,7 +2020,8 @@
 .byte	0x67
 	movq	%rcx,%rbp
 .byte	102,73,15,110,218
-	call	sqr8x_reduction
+	call	__bn_sqr8x_reduction
+	call	__bn_post4x_internal
 
 	pxor	%xmm0,%xmm0
 	leaq	48(%rsp),%rax
@@ -1777,46 +2071,170 @@
 .globl	_bn_gather5
 .private_extern _bn_gather5
 
-.p2align	4
+.p2align	5
 _bn_gather5:
-	movl	%ecx,%r11d
-	shrl	$3,%ecx
-	andq	$7,%r11
-	notl	%ecx
-	leaq	L$magic_masks(%rip),%rax
-	andl	$3,%ecx
-	leaq	128(%rdx,%r11,8),%rdx
-	movq	0(%rax,%rcx,8),%xmm4
-	movq	8(%rax,%rcx,8),%xmm5
-	movq	16(%rax,%rcx,8),%xmm6
-	movq	24(%rax,%rcx,8),%xmm7
-	jmp	L$gather
-.p2align	4
-L$gather:
-	movq	-128(%rdx),%xmm0
-	movq	-64(%rdx),%xmm1
-	pand	%xmm4,%xmm0
-	movq	0(%rdx),%xmm2
-	pand	%xmm5,%xmm1
-	movq	64(%rdx),%xmm3
-	pand	%xmm6,%xmm2
-	por	%xmm1,%xmm0
-	pand	%xmm7,%xmm3
-.byte	0x67,0x67
-	por	%xmm2,%xmm0
-	leaq	256(%rdx),%rdx
-	por	%xmm3,%xmm0
+L$SEH_begin_bn_gather5:
 
+.byte	0x4c,0x8d,0x14,0x24
+.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00
+	leaq	L$inc(%rip),%rax
+	andq	$-16,%rsp
+
+	movd	%ecx,%xmm5
+	movdqa	0(%rax),%xmm0
+	movdqa	16(%rax),%xmm1
+	leaq	128(%rdx),%r11
+	leaq	128(%rsp),%rax
+
+	pshufd	$0,%xmm5,%xmm5
+	movdqa	%xmm1,%xmm4
+	movdqa	%xmm1,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-128(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-112(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-96(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-80(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,-64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,-48(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,-32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,-16(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,0(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,16(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,32(%rax)
+	movdqa	%xmm4,%xmm2
+	paddd	%xmm0,%xmm1
+	pcmpeqd	%xmm5,%xmm0
+	movdqa	%xmm3,48(%rax)
+	movdqa	%xmm4,%xmm3
+
+	paddd	%xmm1,%xmm2
+	pcmpeqd	%xmm5,%xmm1
+	movdqa	%xmm0,64(%rax)
+	movdqa	%xmm4,%xmm0
+
+	paddd	%xmm2,%xmm3
+	pcmpeqd	%xmm5,%xmm2
+	movdqa	%xmm1,80(%rax)
+	movdqa	%xmm4,%xmm1
+
+	paddd	%xmm3,%xmm0
+	pcmpeqd	%xmm5,%xmm3
+	movdqa	%xmm2,96(%rax)
+	movdqa	%xmm4,%xmm2
+	movdqa	%xmm3,112(%rax)
+	jmp	L$gather
+
+.p2align	5
+L$gather:
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	movdqa	-128(%r11),%xmm0
+	movdqa	-112(%r11),%xmm1
+	movdqa	-96(%r11),%xmm2
+	pand	-128(%rax),%xmm0
+	movdqa	-80(%r11),%xmm3
+	pand	-112(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-80(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	-64(%r11),%xmm0
+	movdqa	-48(%r11),%xmm1
+	movdqa	-32(%r11),%xmm2
+	pand	-64(%rax),%xmm0
+	movdqa	-16(%r11),%xmm3
+	pand	-48(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	-32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	-16(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	0(%r11),%xmm0
+	movdqa	16(%r11),%xmm1
+	movdqa	32(%r11),%xmm2
+	pand	0(%rax),%xmm0
+	movdqa	48(%r11),%xmm3
+	pand	16(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	32(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	48(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	movdqa	64(%r11),%xmm0
+	movdqa	80(%r11),%xmm1
+	movdqa	96(%r11),%xmm2
+	pand	64(%rax),%xmm0
+	movdqa	112(%r11),%xmm3
+	pand	80(%rax),%xmm1
+	por	%xmm0,%xmm4
+	pand	96(%rax),%xmm2
+	por	%xmm1,%xmm5
+	pand	112(%rax),%xmm3
+	por	%xmm2,%xmm4
+	por	%xmm3,%xmm5
+	por	%xmm5,%xmm4
+	leaq	256(%r11),%r11
+	pshufd	$0x4e,%xmm4,%xmm0
+	por	%xmm4,%xmm0
 	movq	%xmm0,(%rdi)
 	leaq	8(%rdi),%rdi
 	subl	$1,%esi
 	jnz	L$gather
+
+	leaq	(%r10),%rsp
 	.byte	0xf3,0xc3
 L$SEH_end_bn_gather5:
 
 .p2align	6
-L$magic_masks:
-.long	0,0, 0,0, 0,0, -1,-1
-.long	0,0, 0,0, 0,0,  0,0
+L$inc:
+.long	0,0, 1,1
+.long	2,2, 2,2
 .byte	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115,99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
 #endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/chacha/chacha-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/chacha/chacha-x86_64.S
new file mode 100644
index 0000000..c3554c8
--- /dev/null
+++ b/third_party/boringssl/mac-x86_64/crypto/chacha/chacha-x86_64.S
@@ -0,0 +1,1584 @@
+#if defined(__x86_64__)
+.text	
+
+
+
+.p2align	6
+L$zero:
+.long	0,0,0,0
+L$one:
+.long	1,0,0,0
+L$inc:
+.long	0,1,2,3
+L$four:
+.long	4,4,4,4
+L$incy:
+.long	0,2,4,6,1,3,5,7
+L$eight:
+.long	8,8,8,8,8,8,8,8
+L$rot16:
+.byte	0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
+L$rot24:
+.byte	0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
+L$sigma:
+.byte	101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107,0
+.byte	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.globl	_ChaCha20_ctr32
+.private_extern _ChaCha20_ctr32
+
+.p2align	6
+_ChaCha20_ctr32:
+	cmpq	$0,%rdx
+	je	L$no_data
+	movq	_OPENSSL_ia32cap_P+4(%rip),%r10
+	testl	$512,%r10d
+	jnz	L$ChaCha20_ssse3
+
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$64+24,%rsp
+
+
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	L$one(%rip),%xmm4
+
+
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movq	%rdx,%rbp
+	jmp	L$oop_outer
+
+.p2align	5
+L$oop_outer:
+	movl	$0x61707865,%eax
+	movl	$0x3320646e,%ebx
+	movl	$0x79622d32,%ecx
+	movl	$0x6b206574,%edx
+	movl	16(%rsp),%r8d
+	movl	20(%rsp),%r9d
+	movl	24(%rsp),%r10d
+	movl	28(%rsp),%r11d
+	movd	%xmm3,%r12d
+	movl	52(%rsp),%r13d
+	movl	56(%rsp),%r14d
+	movl	60(%rsp),%r15d
+
+	movq	%rbp,64+0(%rsp)
+	movl	$10,%ebp
+	movq	%rsi,64+8(%rsp)
+.byte	102,72,15,126,214
+	movq	%rdi,64+16(%rsp)
+	movq	%rsi,%rdi
+	shrq	$32,%rdi
+	jmp	L$oop
+
+.p2align	5
+L$oop:
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$16,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$16,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$12,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$12,%r9d
+	addl	%r8d,%eax
+	xorl	%eax,%r12d
+	roll	$8,%r12d
+	addl	%r9d,%ebx
+	xorl	%ebx,%r13d
+	roll	$8,%r13d
+	addl	%r12d,%esi
+	xorl	%esi,%r8d
+	roll	$7,%r8d
+	addl	%r13d,%edi
+	xorl	%edi,%r9d
+	roll	$7,%r9d
+	movl	%esi,32(%rsp)
+	movl	%edi,36(%rsp)
+	movl	40(%rsp),%esi
+	movl	44(%rsp),%edi
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$16,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$16,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$12,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$12,%r11d
+	addl	%r10d,%ecx
+	xorl	%ecx,%r14d
+	roll	$8,%r14d
+	addl	%r11d,%edx
+	xorl	%edx,%r15d
+	roll	$8,%r15d
+	addl	%r14d,%esi
+	xorl	%esi,%r10d
+	roll	$7,%r10d
+	addl	%r15d,%edi
+	xorl	%edi,%r11d
+	roll	$7,%r11d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$16,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$16,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$12,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$12,%r10d
+	addl	%r9d,%eax
+	xorl	%eax,%r15d
+	roll	$8,%r15d
+	addl	%r10d,%ebx
+	xorl	%ebx,%r12d
+	roll	$8,%r12d
+	addl	%r15d,%esi
+	xorl	%esi,%r9d
+	roll	$7,%r9d
+	addl	%r12d,%edi
+	xorl	%edi,%r10d
+	roll	$7,%r10d
+	movl	%esi,40(%rsp)
+	movl	%edi,44(%rsp)
+	movl	32(%rsp),%esi
+	movl	36(%rsp),%edi
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$16,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$16,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$12,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$12,%r8d
+	addl	%r11d,%ecx
+	xorl	%ecx,%r13d
+	roll	$8,%r13d
+	addl	%r8d,%edx
+	xorl	%edx,%r14d
+	roll	$8,%r14d
+	addl	%r13d,%esi
+	xorl	%esi,%r11d
+	roll	$7,%r11d
+	addl	%r14d,%edi
+	xorl	%edi,%r8d
+	roll	$7,%r8d
+	decl	%ebp
+	jnz	L$oop
+	movl	%edi,36(%rsp)
+	movl	%esi,32(%rsp)
+	movq	64(%rsp),%rbp
+	movdqa	%xmm2,%xmm1
+	movq	64+8(%rsp),%rsi
+	paddd	%xmm4,%xmm3
+	movq	64+16(%rsp),%rdi
+
+	addl	$0x61707865,%eax
+	addl	$0x3320646e,%ebx
+	addl	$0x79622d32,%ecx
+	addl	$0x6b206574,%edx
+	addl	16(%rsp),%r8d
+	addl	20(%rsp),%r9d
+	addl	24(%rsp),%r10d
+	addl	28(%rsp),%r11d
+	addl	48(%rsp),%r12d
+	addl	52(%rsp),%r13d
+	addl	56(%rsp),%r14d
+	addl	60(%rsp),%r15d
+	paddd	32(%rsp),%xmm1
+
+	cmpq	$64,%rbp
+	jb	L$tail
+
+	xorl	0(%rsi),%eax
+	xorl	4(%rsi),%ebx
+	xorl	8(%rsi),%ecx
+	xorl	12(%rsi),%edx
+	xorl	16(%rsi),%r8d
+	xorl	20(%rsi),%r9d
+	xorl	24(%rsi),%r10d
+	xorl	28(%rsi),%r11d
+	movdqu	32(%rsi),%xmm0
+	xorl	48(%rsi),%r12d
+	xorl	52(%rsi),%r13d
+	xorl	56(%rsi),%r14d
+	xorl	60(%rsi),%r15d
+	leaq	64(%rsi),%rsi
+	pxor	%xmm1,%xmm0
+
+	movdqa	%xmm2,32(%rsp)
+	movd	%xmm3,48(%rsp)
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	movdqu	%xmm0,32(%rdi)
+	movl	%r12d,48(%rdi)
+	movl	%r13d,52(%rdi)
+	movl	%r14d,56(%rdi)
+	movl	%r15d,60(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rbp
+	jnz	L$oop_outer
+
+	jmp	L$done
+
+.p2align	4
+L$tail:
+	movl	%eax,0(%rsp)
+	movl	%ebx,4(%rsp)
+	xorq	%rbx,%rbx
+	movl	%ecx,8(%rsp)
+	movl	%edx,12(%rsp)
+	movl	%r8d,16(%rsp)
+	movl	%r9d,20(%rsp)
+	movl	%r10d,24(%rsp)
+	movl	%r11d,28(%rsp)
+	movdqa	%xmm1,32(%rsp)
+	movl	%r12d,48(%rsp)
+	movl	%r13d,52(%rsp)
+	movl	%r14d,56(%rsp)
+	movl	%r15d,60(%rsp)
+
+L$oop_tail:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%edx
+	leaq	1(%rbx),%rbx
+	xorl	%edx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rbp
+	jnz	L$oop_tail
+
+L$done:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+L$no_data:
+	.byte	0xf3,0xc3
+
+
+.p2align	5
+ChaCha20_ssse3:
+L$ChaCha20_ssse3:
+	cmpq	$128,%rdx
+	ja	L$ChaCha20_4x
+
+L$do_sse3_after_all:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+
+	subq	$64+24,%rsp
+	movdqa	L$sigma(%rip),%xmm0
+	movdqu	(%rcx),%xmm1
+	movdqu	16(%rcx),%xmm2
+	movdqu	(%r8),%xmm3
+	movdqa	L$rot16(%rip),%xmm6
+	movdqa	L$rot24(%rip),%xmm7
+
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	movl	$10,%ebp
+	jmp	L$oop_ssse3
+
+.p2align	5
+L$oop_outer_ssse3:
+	movdqa	L$one(%rip),%xmm3
+	movdqa	0(%rsp),%xmm0
+	movdqa	16(%rsp),%xmm1
+	movdqa	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+	movl	$10,%ebp
+	movdqa	%xmm3,48(%rsp)
+	jmp	L$oop_ssse3
+
+.p2align	5
+L$oop_ssse3:
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$57,%xmm1,%xmm1
+	pshufd	$147,%xmm3,%xmm3
+	nop
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,222
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$20,%xmm1
+	pslld	$12,%xmm4
+	por	%xmm4,%xmm1
+	paddd	%xmm1,%xmm0
+	pxor	%xmm0,%xmm3
+.byte	102,15,56,0,223
+	paddd	%xmm3,%xmm2
+	pxor	%xmm2,%xmm1
+	movdqa	%xmm1,%xmm4
+	psrld	$25,%xmm1
+	pslld	$7,%xmm4
+	por	%xmm4,%xmm1
+	pshufd	$78,%xmm2,%xmm2
+	pshufd	$147,%xmm1,%xmm1
+	pshufd	$57,%xmm3,%xmm3
+	decl	%ebp
+	jnz	L$oop_ssse3
+	paddd	0(%rsp),%xmm0
+	paddd	16(%rsp),%xmm1
+	paddd	32(%rsp),%xmm2
+	paddd	48(%rsp),%xmm3
+
+	cmpq	$64,%rdx
+	jb	L$tail_ssse3
+
+	movdqu	0(%rsi),%xmm4
+	movdqu	16(%rsi),%xmm5
+	pxor	%xmm4,%xmm0
+	movdqu	32(%rsi),%xmm4
+	pxor	%xmm5,%xmm1
+	movdqu	48(%rsi),%xmm5
+	leaq	64(%rsi),%rsi
+	pxor	%xmm4,%xmm2
+	pxor	%xmm5,%xmm3
+
+	movdqu	%xmm0,0(%rdi)
+	movdqu	%xmm1,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+	leaq	64(%rdi),%rdi
+
+	subq	$64,%rdx
+	jnz	L$oop_outer_ssse3
+
+	jmp	L$done_ssse3
+
+.p2align	4
+L$tail_ssse3:
+	movdqa	%xmm0,0(%rsp)
+	movdqa	%xmm1,16(%rsp)
+	movdqa	%xmm2,32(%rsp)
+	movdqa	%xmm3,48(%rsp)
+	xorq	%rbx,%rbx
+
+L$oop_tail_ssse3:
+	movzbl	(%rsi,%rbx,1),%eax
+	movzbl	(%rsp,%rbx,1),%ecx
+	leaq	1(%rbx),%rbx
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%rbx,1)
+	decq	%rdx
+	jnz	L$oop_tail_ssse3
+
+L$done_ssse3:
+	addq	$64+24,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbp
+	popq	%rbx
+	.byte	0xf3,0xc3
+
+
+.p2align	5
+ChaCha20_4x:
+L$ChaCha20_4x:
+	movq	%r10,%r11
+	shrq	$32,%r10
+	testq	$32,%r10
+	jnz	L$ChaCha20_8x
+	cmpq	$192,%rdx
+	ja	L$proceed4x
+
+	andq	$71303168,%r11
+	cmpq	$4194304,%r11
+	je	L$do_sse3_after_all
+
+L$proceed4x:
+	leaq	-120(%rsp),%r11
+	subq	$0x148+0,%rsp
+	movdqa	L$sigma(%rip),%xmm11
+	movdqu	(%rcx),%xmm15
+	movdqu	16(%rcx),%xmm7
+	movdqu	(%r8),%xmm3
+	leaq	256(%rsp),%rcx
+	leaq	L$rot16(%rip),%r10
+	leaq	L$rot24(%rip),%r11
+
+	pshufd	$0x00,%xmm11,%xmm8
+	pshufd	$0x55,%xmm11,%xmm9
+	movdqa	%xmm8,64(%rsp)
+	pshufd	$0xaa,%xmm11,%xmm10
+	movdqa	%xmm9,80(%rsp)
+	pshufd	$0xff,%xmm11,%xmm11
+	movdqa	%xmm10,96(%rsp)
+	movdqa	%xmm11,112(%rsp)
+
+	pshufd	$0x00,%xmm15,%xmm12
+	pshufd	$0x55,%xmm15,%xmm13
+	movdqa	%xmm12,128-256(%rcx)
+	pshufd	$0xaa,%xmm15,%xmm14
+	movdqa	%xmm13,144-256(%rcx)
+	pshufd	$0xff,%xmm15,%xmm15
+	movdqa	%xmm14,160-256(%rcx)
+	movdqa	%xmm15,176-256(%rcx)
+
+	pshufd	$0x00,%xmm7,%xmm4
+	pshufd	$0x55,%xmm7,%xmm5
+	movdqa	%xmm4,192-256(%rcx)
+	pshufd	$0xaa,%xmm7,%xmm6
+	movdqa	%xmm5,208-256(%rcx)
+	pshufd	$0xff,%xmm7,%xmm7
+	movdqa	%xmm6,224-256(%rcx)
+	movdqa	%xmm7,240-256(%rcx)
+
+	pshufd	$0x00,%xmm3,%xmm0
+	pshufd	$0x55,%xmm3,%xmm1
+	paddd	L$inc(%rip),%xmm0
+	pshufd	$0xaa,%xmm3,%xmm2
+	movdqa	%xmm1,272-256(%rcx)
+	pshufd	$0xff,%xmm3,%xmm3
+	movdqa	%xmm2,288-256(%rcx)
+	movdqa	%xmm3,304-256(%rcx)
+
+	jmp	L$oop_enter4x
+
+.p2align	5
+L$oop_outer4x:
+	movdqa	64(%rsp),%xmm8
+	movdqa	80(%rsp),%xmm9
+	movdqa	96(%rsp),%xmm10
+	movdqa	112(%rsp),%xmm11
+	movdqa	128-256(%rcx),%xmm12
+	movdqa	144-256(%rcx),%xmm13
+	movdqa	160-256(%rcx),%xmm14
+	movdqa	176-256(%rcx),%xmm15
+	movdqa	192-256(%rcx),%xmm4
+	movdqa	208-256(%rcx),%xmm5
+	movdqa	224-256(%rcx),%xmm6
+	movdqa	240-256(%rcx),%xmm7
+	movdqa	256-256(%rcx),%xmm0
+	movdqa	272-256(%rcx),%xmm1
+	movdqa	288-256(%rcx),%xmm2
+	movdqa	304-256(%rcx),%xmm3
+	paddd	L$four(%rip),%xmm0
+
+L$oop_enter4x:
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm7,48(%rsp)
+	movdqa	(%r10),%xmm7
+	movl	$10,%eax
+	movdqa	%xmm0,256-256(%rcx)
+	jmp	L$oop4x
+
+.p2align	5
+L$oop4x:
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,199
+.byte	102,15,56,0,207
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm6
+	pslld	$12,%xmm12
+	psrld	$20,%xmm6
+	movdqa	%xmm13,%xmm7
+	pslld	$12,%xmm13
+	por	%xmm6,%xmm12
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm13
+	paddd	%xmm12,%xmm8
+	paddd	%xmm13,%xmm9
+	pxor	%xmm8,%xmm0
+	pxor	%xmm9,%xmm1
+.byte	102,15,56,0,198
+.byte	102,15,56,0,206
+	paddd	%xmm0,%xmm4
+	paddd	%xmm1,%xmm5
+	pxor	%xmm4,%xmm12
+	pxor	%xmm5,%xmm13
+	movdqa	%xmm12,%xmm7
+	pslld	$7,%xmm12
+	psrld	$25,%xmm7
+	movdqa	%xmm13,%xmm6
+	pslld	$7,%xmm13
+	por	%xmm7,%xmm12
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm13
+	movdqa	%xmm4,0(%rsp)
+	movdqa	%xmm5,16(%rsp)
+	movdqa	32(%rsp),%xmm4
+	movdqa	48(%rsp),%xmm5
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,215
+.byte	102,15,56,0,223
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm6
+	pslld	$12,%xmm14
+	psrld	$20,%xmm6
+	movdqa	%xmm15,%xmm7
+	pslld	$12,%xmm15
+	por	%xmm6,%xmm14
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm15
+	paddd	%xmm14,%xmm10
+	paddd	%xmm15,%xmm11
+	pxor	%xmm10,%xmm2
+	pxor	%xmm11,%xmm3
+.byte	102,15,56,0,214
+.byte	102,15,56,0,222
+	paddd	%xmm2,%xmm4
+	paddd	%xmm3,%xmm5
+	pxor	%xmm4,%xmm14
+	pxor	%xmm5,%xmm15
+	movdqa	%xmm14,%xmm7
+	pslld	$7,%xmm14
+	psrld	$25,%xmm7
+	movdqa	%xmm15,%xmm6
+	pslld	$7,%xmm15
+	por	%xmm7,%xmm14
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm15
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,223
+.byte	102,15,56,0,199
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm6
+	pslld	$12,%xmm13
+	psrld	$20,%xmm6
+	movdqa	%xmm14,%xmm7
+	pslld	$12,%xmm14
+	por	%xmm6,%xmm13
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm14
+	paddd	%xmm13,%xmm8
+	paddd	%xmm14,%xmm9
+	pxor	%xmm8,%xmm3
+	pxor	%xmm9,%xmm0
+.byte	102,15,56,0,222
+.byte	102,15,56,0,198
+	paddd	%xmm3,%xmm4
+	paddd	%xmm0,%xmm5
+	pxor	%xmm4,%xmm13
+	pxor	%xmm5,%xmm14
+	movdqa	%xmm13,%xmm7
+	pslld	$7,%xmm13
+	psrld	$25,%xmm7
+	movdqa	%xmm14,%xmm6
+	pslld	$7,%xmm14
+	por	%xmm7,%xmm13
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm14
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm5,48(%rsp)
+	movdqa	0(%rsp),%xmm4
+	movdqa	16(%rsp),%xmm5
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,207
+.byte	102,15,56,0,215
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm6
+	pslld	$12,%xmm15
+	psrld	$20,%xmm6
+	movdqa	%xmm12,%xmm7
+	pslld	$12,%xmm12
+	por	%xmm6,%xmm15
+	psrld	$20,%xmm7
+	movdqa	(%r11),%xmm6
+	por	%xmm7,%xmm12
+	paddd	%xmm15,%xmm10
+	paddd	%xmm12,%xmm11
+	pxor	%xmm10,%xmm1
+	pxor	%xmm11,%xmm2
+.byte	102,15,56,0,206
+.byte	102,15,56,0,214
+	paddd	%xmm1,%xmm4
+	paddd	%xmm2,%xmm5
+	pxor	%xmm4,%xmm15
+	pxor	%xmm5,%xmm12
+	movdqa	%xmm15,%xmm7
+	pslld	$7,%xmm15
+	psrld	$25,%xmm7
+	movdqa	%xmm12,%xmm6
+	pslld	$7,%xmm12
+	por	%xmm7,%xmm15
+	psrld	$25,%xmm6
+	movdqa	(%r10),%xmm7
+	por	%xmm6,%xmm12
+	decl	%eax
+	jnz	L$oop4x
+
+	paddd	64(%rsp),%xmm8
+	paddd	80(%rsp),%xmm9
+	paddd	96(%rsp),%xmm10
+	paddd	112(%rsp),%xmm11
+
+	movdqa	%xmm8,%xmm6
+	punpckldq	%xmm9,%xmm8
+	movdqa	%xmm10,%xmm7
+	punpckldq	%xmm11,%xmm10
+	punpckhdq	%xmm9,%xmm6
+	punpckhdq	%xmm11,%xmm7
+	movdqa	%xmm8,%xmm9
+	punpcklqdq	%xmm10,%xmm8
+	movdqa	%xmm6,%xmm11
+	punpcklqdq	%xmm7,%xmm6
+	punpckhqdq	%xmm10,%xmm9
+	punpckhqdq	%xmm7,%xmm11
+	paddd	128-256(%rcx),%xmm12
+	paddd	144-256(%rcx),%xmm13
+	paddd	160-256(%rcx),%xmm14
+	paddd	176-256(%rcx),%xmm15
+
+	movdqa	%xmm8,0(%rsp)
+	movdqa	%xmm9,16(%rsp)
+	movdqa	32(%rsp),%xmm8
+	movdqa	48(%rsp),%xmm9
+
+	movdqa	%xmm12,%xmm10
+	punpckldq	%xmm13,%xmm12
+	movdqa	%xmm14,%xmm7
+	punpckldq	%xmm15,%xmm14
+	punpckhdq	%xmm13,%xmm10
+	punpckhdq	%xmm15,%xmm7
+	movdqa	%xmm12,%xmm13
+	punpcklqdq	%xmm14,%xmm12
+	movdqa	%xmm10,%xmm15
+	punpcklqdq	%xmm7,%xmm10
+	punpckhqdq	%xmm14,%xmm13
+	punpckhqdq	%xmm7,%xmm15
+	paddd	192-256(%rcx),%xmm4
+	paddd	208-256(%rcx),%xmm5
+	paddd	224-256(%rcx),%xmm8
+	paddd	240-256(%rcx),%xmm9
+
+	movdqa	%xmm6,32(%rsp)
+	movdqa	%xmm11,48(%rsp)
+
+	movdqa	%xmm4,%xmm14
+	punpckldq	%xmm5,%xmm4
+	movdqa	%xmm8,%xmm7
+	punpckldq	%xmm9,%xmm8
+	punpckhdq	%xmm5,%xmm14
+	punpckhdq	%xmm9,%xmm7
+	movdqa	%xmm4,%xmm5
+	punpcklqdq	%xmm8,%xmm4
+	movdqa	%xmm14,%xmm9
+	punpcklqdq	%xmm7,%xmm14
+	punpckhqdq	%xmm8,%xmm5
+	punpckhqdq	%xmm7,%xmm9
+	paddd	256-256(%rcx),%xmm0
+	paddd	272-256(%rcx),%xmm1
+	paddd	288-256(%rcx),%xmm2
+	paddd	304-256(%rcx),%xmm3
+
+	movdqa	%xmm0,%xmm8
+	punpckldq	%xmm1,%xmm0
+	movdqa	%xmm2,%xmm7
+	punpckldq	%xmm3,%xmm2
+	punpckhdq	%xmm1,%xmm8
+	punpckhdq	%xmm3,%xmm7
+	movdqa	%xmm0,%xmm1
+	punpcklqdq	%xmm2,%xmm0
+	movdqa	%xmm8,%xmm3
+	punpcklqdq	%xmm7,%xmm8
+	punpckhqdq	%xmm2,%xmm1
+	punpckhqdq	%xmm7,%xmm3
+	cmpq	$256,%rdx
+	jb	L$tail4x
+
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	48(%rsp),%xmm6
+	pxor	%xmm15,%xmm11
+	pxor	%xmm9,%xmm2
+	pxor	%xmm3,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$256,%rdx
+	jnz	L$oop_outer4x
+
+	jmp	L$done4x
+
+L$tail4x:
+	cmpq	$192,%rdx
+	jae	L$192_or_more4x
+	cmpq	$128,%rdx
+	jae	L$128_or_more4x
+	cmpq	$64,%rdx
+	jae	L$64_or_more4x
+
+
+	xorq	%r10,%r10
+
+	movdqa	%xmm12,16(%rsp)
+	movdqa	%xmm4,32(%rsp)
+	movdqa	%xmm0,48(%rsp)
+	jmp	L$oop_tail4x
+
+.p2align	5
+L$64_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	L$done4x
+
+	movdqa	16(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm13,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm5,32(%rsp)
+	subq	$64,%rdx
+	movdqa	%xmm1,48(%rsp)
+	jmp	L$oop_tail4x
+
+.p2align	5
+L$128_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm11,80(%rdi)
+	movdqu	%xmm2,96(%rdi)
+	movdqu	%xmm7,112(%rdi)
+	je	L$done4x
+
+	movdqa	32(%rsp),%xmm6
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm10,16(%rsp)
+	leaq	128(%rdi),%rdi
+	movdqa	%xmm14,32(%rsp)
+	subq	$128,%rdx
+	movdqa	%xmm8,48(%rsp)
+	jmp	L$oop_tail4x
+
+.p2align	5
+L$192_or_more4x:
+	movdqu	0(%rsi),%xmm6
+	movdqu	16(%rsi),%xmm11
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm7
+	pxor	0(%rsp),%xmm6
+	pxor	%xmm12,%xmm11
+	pxor	%xmm4,%xmm2
+	pxor	%xmm0,%xmm7
+
+	movdqu	%xmm6,0(%rdi)
+	movdqu	64(%rsi),%xmm6
+	movdqu	%xmm11,16(%rdi)
+	movdqu	80(%rsi),%xmm11
+	movdqu	%xmm2,32(%rdi)
+	movdqu	96(%rsi),%xmm2
+	movdqu	%xmm7,48(%rdi)
+	movdqu	112(%rsi),%xmm7
+	leaq	128(%rsi),%rsi
+	pxor	16(%rsp),%xmm6
+	pxor	%xmm13,%xmm11
+	pxor	%xmm5,%xmm2
+	pxor	%xmm1,%xmm7
+
+	movdqu	%xmm6,64(%rdi)
+	movdqu	0(%rsi),%xmm6
+	movdqu	%xmm11,80(%rdi)
+	movdqu	16(%rsi),%xmm11
+	movdqu	%xmm2,96(%rdi)
+	movdqu	32(%rsi),%xmm2
+	movdqu	%xmm7,112(%rdi)
+	leaq	128(%rdi),%rdi
+	movdqu	48(%rsi),%xmm7
+	pxor	32(%rsp),%xmm6
+	pxor	%xmm10,%xmm11
+	pxor	%xmm14,%xmm2
+	pxor	%xmm8,%xmm7
+	movdqu	%xmm6,0(%rdi)
+	movdqu	%xmm11,16(%rdi)
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm7,48(%rdi)
+	je	L$done4x
+
+	movdqa	48(%rsp),%xmm6
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	movdqa	%xmm6,0(%rsp)
+	movdqa	%xmm15,16(%rsp)
+	leaq	64(%rdi),%rdi
+	movdqa	%xmm9,32(%rsp)
+	subq	$192,%rdx
+	movdqa	%xmm3,48(%rsp)
+
+L$oop_tail4x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	L$oop_tail4x
+
+L$done4x:
+	addq	$0x148+0,%rsp
+	.byte	0xf3,0xc3
+
+
+.p2align	5
+ChaCha20_8x:
+L$ChaCha20_8x:
+	movq	%rsp,%r10
+	subq	$0x280+8,%rsp
+	andq	$-32,%rsp
+	vzeroupper
+	movq	%r10,640(%rsp)
+
+
+
+
+
+
+
+
+
+
+	vbroadcasti128	L$sigma(%rip),%ymm11
+	vbroadcasti128	(%rcx),%ymm3
+	vbroadcasti128	16(%rcx),%ymm15
+	vbroadcasti128	(%r8),%ymm7
+	leaq	256(%rsp),%rcx
+	leaq	512(%rsp),%rax
+	leaq	L$rot16(%rip),%r10
+	leaq	L$rot24(%rip),%r11
+
+	vpshufd	$0x00,%ymm11,%ymm8
+	vpshufd	$0x55,%ymm11,%ymm9
+	vmovdqa	%ymm8,128-256(%rcx)
+	vpshufd	$0xaa,%ymm11,%ymm10
+	vmovdqa	%ymm9,160-256(%rcx)
+	vpshufd	$0xff,%ymm11,%ymm11
+	vmovdqa	%ymm10,192-256(%rcx)
+	vmovdqa	%ymm11,224-256(%rcx)
+
+	vpshufd	$0x00,%ymm3,%ymm0
+	vpshufd	$0x55,%ymm3,%ymm1
+	vmovdqa	%ymm0,256-256(%rcx)
+	vpshufd	$0xaa,%ymm3,%ymm2
+	vmovdqa	%ymm1,288-256(%rcx)
+	vpshufd	$0xff,%ymm3,%ymm3
+	vmovdqa	%ymm2,320-256(%rcx)
+	vmovdqa	%ymm3,352-256(%rcx)
+
+	vpshufd	$0x00,%ymm15,%ymm12
+	vpshufd	$0x55,%ymm15,%ymm13
+	vmovdqa	%ymm12,384-512(%rax)
+	vpshufd	$0xaa,%ymm15,%ymm14
+	vmovdqa	%ymm13,416-512(%rax)
+	vpshufd	$0xff,%ymm15,%ymm15
+	vmovdqa	%ymm14,448-512(%rax)
+	vmovdqa	%ymm15,480-512(%rax)
+
+	vpshufd	$0x00,%ymm7,%ymm4
+	vpshufd	$0x55,%ymm7,%ymm5
+	vpaddd	L$incy(%rip),%ymm4,%ymm4
+	vpshufd	$0xaa,%ymm7,%ymm6
+	vmovdqa	%ymm5,544-512(%rax)
+	vpshufd	$0xff,%ymm7,%ymm7
+	vmovdqa	%ymm6,576-512(%rax)
+	vmovdqa	%ymm7,608-512(%rax)
+
+	jmp	L$oop_enter8x
+
+.p2align	5
+L$oop_outer8x:
+	vmovdqa	128-256(%rcx),%ymm8
+	vmovdqa	160-256(%rcx),%ymm9
+	vmovdqa	192-256(%rcx),%ymm10
+	vmovdqa	224-256(%rcx),%ymm11
+	vmovdqa	256-256(%rcx),%ymm0
+	vmovdqa	288-256(%rcx),%ymm1
+	vmovdqa	320-256(%rcx),%ymm2
+	vmovdqa	352-256(%rcx),%ymm3
+	vmovdqa	384-512(%rax),%ymm12
+	vmovdqa	416-512(%rax),%ymm13
+	vmovdqa	448-512(%rax),%ymm14
+	vmovdqa	480-512(%rax),%ymm15
+	vmovdqa	512-512(%rax),%ymm4
+	vmovdqa	544-512(%rax),%ymm5
+	vmovdqa	576-512(%rax),%ymm6
+	vmovdqa	608-512(%rax),%ymm7
+	vpaddd	L$eight(%rip),%ymm4,%ymm4
+
+L$oop_enter8x:
+	vmovdqa	%ymm14,64(%rsp)
+	vmovdqa	%ymm15,96(%rsp)
+	vbroadcasti128	(%r10),%ymm15
+	vmovdqa	%ymm4,512-512(%rax)
+	movl	$10,%eax
+	jmp	L$oop8x
+
+.p2align	5
+L$oop8x:
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$12,%ymm0,%ymm14
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$12,%ymm1,%ymm15
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vpaddd	%ymm0,%ymm8,%ymm8
+	vpxor	%ymm4,%ymm8,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm1,%ymm9,%ymm9
+	vpxor	%ymm5,%ymm9,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm4,%ymm12,%ymm12
+	vpxor	%ymm0,%ymm12,%ymm0
+	vpslld	$7,%ymm0,%ymm15
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm5,%ymm13,%ymm13
+	vpxor	%ymm1,%ymm13,%ymm1
+	vpslld	$7,%ymm1,%ymm14
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vmovdqa	%ymm12,0(%rsp)
+	vmovdqa	%ymm13,32(%rsp)
+	vmovdqa	64(%rsp),%ymm12
+	vmovdqa	96(%rsp),%ymm13
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$12,%ymm2,%ymm14
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$12,%ymm3,%ymm15
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vpaddd	%ymm2,%ymm10,%ymm10
+	vpxor	%ymm6,%ymm10,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm3,%ymm11,%ymm11
+	vpxor	%ymm7,%ymm11,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm6,%ymm12,%ymm12
+	vpxor	%ymm2,%ymm12,%ymm2
+	vpslld	$7,%ymm2,%ymm15
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm7,%ymm13,%ymm13
+	vpxor	%ymm3,%ymm13,%ymm3
+	vpslld	$7,%ymm3,%ymm14
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm15,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm15,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$12,%ymm1,%ymm14
+	vpsrld	$20,%ymm1,%ymm1
+	vpor	%ymm1,%ymm14,%ymm1
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$12,%ymm2,%ymm15
+	vpsrld	$20,%ymm2,%ymm2
+	vpor	%ymm2,%ymm15,%ymm2
+	vpaddd	%ymm1,%ymm8,%ymm8
+	vpxor	%ymm7,%ymm8,%ymm7
+	vpshufb	%ymm14,%ymm7,%ymm7
+	vpaddd	%ymm2,%ymm9,%ymm9
+	vpxor	%ymm4,%ymm9,%ymm4
+	vpshufb	%ymm14,%ymm4,%ymm4
+	vpaddd	%ymm7,%ymm12,%ymm12
+	vpxor	%ymm1,%ymm12,%ymm1
+	vpslld	$7,%ymm1,%ymm15
+	vpsrld	$25,%ymm1,%ymm1
+	vpor	%ymm1,%ymm15,%ymm1
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm4,%ymm13,%ymm13
+	vpxor	%ymm2,%ymm13,%ymm2
+	vpslld	$7,%ymm2,%ymm14
+	vpsrld	$25,%ymm2,%ymm2
+	vpor	%ymm2,%ymm14,%ymm2
+	vmovdqa	%ymm12,64(%rsp)
+	vmovdqa	%ymm13,96(%rsp)
+	vmovdqa	0(%rsp),%ymm12
+	vmovdqa	32(%rsp),%ymm13
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm15,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm15,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$12,%ymm3,%ymm14
+	vpsrld	$20,%ymm3,%ymm3
+	vpor	%ymm3,%ymm14,%ymm3
+	vbroadcasti128	(%r11),%ymm14
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$12,%ymm0,%ymm15
+	vpsrld	$20,%ymm0,%ymm0
+	vpor	%ymm0,%ymm15,%ymm0
+	vpaddd	%ymm3,%ymm10,%ymm10
+	vpxor	%ymm5,%ymm10,%ymm5
+	vpshufb	%ymm14,%ymm5,%ymm5
+	vpaddd	%ymm0,%ymm11,%ymm11
+	vpxor	%ymm6,%ymm11,%ymm6
+	vpshufb	%ymm14,%ymm6,%ymm6
+	vpaddd	%ymm5,%ymm12,%ymm12
+	vpxor	%ymm3,%ymm12,%ymm3
+	vpslld	$7,%ymm3,%ymm15
+	vpsrld	$25,%ymm3,%ymm3
+	vpor	%ymm3,%ymm15,%ymm3
+	vbroadcasti128	(%r10),%ymm15
+	vpaddd	%ymm6,%ymm13,%ymm13
+	vpxor	%ymm0,%ymm13,%ymm0
+	vpslld	$7,%ymm0,%ymm14
+	vpsrld	$25,%ymm0,%ymm0
+	vpor	%ymm0,%ymm14,%ymm0
+	decl	%eax
+	jnz	L$oop8x
+
+	leaq	512(%rsp),%rax
+	vpaddd	128-256(%rcx),%ymm8,%ymm8
+	vpaddd	160-256(%rcx),%ymm9,%ymm9
+	vpaddd	192-256(%rcx),%ymm10,%ymm10
+	vpaddd	224-256(%rcx),%ymm11,%ymm11
+
+	vpunpckldq	%ymm9,%ymm8,%ymm14
+	vpunpckldq	%ymm11,%ymm10,%ymm15
+	vpunpckhdq	%ymm9,%ymm8,%ymm8
+	vpunpckhdq	%ymm11,%ymm10,%ymm10
+	vpunpcklqdq	%ymm15,%ymm14,%ymm9
+	vpunpckhqdq	%ymm15,%ymm14,%ymm14
+	vpunpcklqdq	%ymm10,%ymm8,%ymm11
+	vpunpckhqdq	%ymm10,%ymm8,%ymm8
+	vpaddd	256-256(%rcx),%ymm0,%ymm0
+	vpaddd	288-256(%rcx),%ymm1,%ymm1
+	vpaddd	320-256(%rcx),%ymm2,%ymm2
+	vpaddd	352-256(%rcx),%ymm3,%ymm3
+
+	vpunpckldq	%ymm1,%ymm0,%ymm10
+	vpunpckldq	%ymm3,%ymm2,%ymm15
+	vpunpckhdq	%ymm1,%ymm0,%ymm0
+	vpunpckhdq	%ymm3,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm10,%ymm1
+	vpunpckhqdq	%ymm15,%ymm10,%ymm10
+	vpunpcklqdq	%ymm2,%ymm0,%ymm3
+	vpunpckhqdq	%ymm2,%ymm0,%ymm0
+	vperm2i128	$0x20,%ymm1,%ymm9,%ymm15
+	vperm2i128	$0x31,%ymm1,%ymm9,%ymm1
+	vperm2i128	$0x20,%ymm10,%ymm14,%ymm9
+	vperm2i128	$0x31,%ymm10,%ymm14,%ymm10
+	vperm2i128	$0x20,%ymm3,%ymm11,%ymm14
+	vperm2i128	$0x31,%ymm3,%ymm11,%ymm3
+	vperm2i128	$0x20,%ymm0,%ymm8,%ymm11
+	vperm2i128	$0x31,%ymm0,%ymm8,%ymm0
+	vmovdqa	%ymm15,0(%rsp)
+	vmovdqa	%ymm9,32(%rsp)
+	vmovdqa	64(%rsp),%ymm15
+	vmovdqa	96(%rsp),%ymm9
+
+	vpaddd	384-512(%rax),%ymm12,%ymm12
+	vpaddd	416-512(%rax),%ymm13,%ymm13
+	vpaddd	448-512(%rax),%ymm15,%ymm15
+	vpaddd	480-512(%rax),%ymm9,%ymm9
+
+	vpunpckldq	%ymm13,%ymm12,%ymm2
+	vpunpckldq	%ymm9,%ymm15,%ymm8
+	vpunpckhdq	%ymm13,%ymm12,%ymm12
+	vpunpckhdq	%ymm9,%ymm15,%ymm15
+	vpunpcklqdq	%ymm8,%ymm2,%ymm13
+	vpunpckhqdq	%ymm8,%ymm2,%ymm2
+	vpunpcklqdq	%ymm15,%ymm12,%ymm9
+	vpunpckhqdq	%ymm15,%ymm12,%ymm12
+	vpaddd	512-512(%rax),%ymm4,%ymm4
+	vpaddd	544-512(%rax),%ymm5,%ymm5
+	vpaddd	576-512(%rax),%ymm6,%ymm6
+	vpaddd	608-512(%rax),%ymm7,%ymm7
+
+	vpunpckldq	%ymm5,%ymm4,%ymm15
+	vpunpckldq	%ymm7,%ymm6,%ymm8
+	vpunpckhdq	%ymm5,%ymm4,%ymm4
+	vpunpckhdq	%ymm7,%ymm6,%ymm6
+	vpunpcklqdq	%ymm8,%ymm15,%ymm5
+	vpunpckhqdq	%ymm8,%ymm15,%ymm15
+	vpunpcklqdq	%ymm6,%ymm4,%ymm7
+	vpunpckhqdq	%ymm6,%ymm4,%ymm4
+	vperm2i128	$0x20,%ymm5,%ymm13,%ymm8
+	vperm2i128	$0x31,%ymm5,%ymm13,%ymm5
+	vperm2i128	$0x20,%ymm15,%ymm2,%ymm13
+	vperm2i128	$0x31,%ymm15,%ymm2,%ymm15
+	vperm2i128	$0x20,%ymm7,%ymm9,%ymm2
+	vperm2i128	$0x31,%ymm7,%ymm9,%ymm7
+	vperm2i128	$0x20,%ymm4,%ymm12,%ymm9
+	vperm2i128	$0x31,%ymm4,%ymm12,%ymm4
+	vmovdqa	0(%rsp),%ymm6
+	vmovdqa	32(%rsp),%ymm12
+
+	cmpq	$512,%rdx
+	jb	L$tail8x
+
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm12,%ymm12
+	vpxor	32(%rsi),%ymm13,%ymm13
+	vpxor	64(%rsi),%ymm10,%ymm10
+	vpxor	96(%rsi),%ymm15,%ymm15
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm12,0(%rdi)
+	vmovdqu	%ymm13,32(%rdi)
+	vmovdqu	%ymm10,64(%rdi)
+	vmovdqu	%ymm15,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm14,%ymm14
+	vpxor	32(%rsi),%ymm2,%ymm2
+	vpxor	64(%rsi),%ymm3,%ymm3
+	vpxor	96(%rsi),%ymm7,%ymm7
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm14,0(%rdi)
+	vmovdqu	%ymm2,32(%rdi)
+	vmovdqu	%ymm3,64(%rdi)
+	vmovdqu	%ymm7,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	vpxor	0(%rsi),%ymm11,%ymm11
+	vpxor	32(%rsi),%ymm9,%ymm9
+	vpxor	64(%rsi),%ymm0,%ymm0
+	vpxor	96(%rsi),%ymm4,%ymm4
+	leaq	128(%rsi),%rsi
+	vmovdqu	%ymm11,0(%rdi)
+	vmovdqu	%ymm9,32(%rdi)
+	vmovdqu	%ymm0,64(%rdi)
+	vmovdqu	%ymm4,96(%rdi)
+	leaq	128(%rdi),%rdi
+
+	subq	$512,%rdx
+	jnz	L$oop_outer8x
+
+	jmp	L$done8x
+
+L$tail8x:
+	cmpq	$448,%rdx
+	jae	L$448_or_more8x
+	cmpq	$384,%rdx
+	jae	L$384_or_more8x
+	cmpq	$320,%rdx
+	jae	L$320_or_more8x
+	cmpq	$256,%rdx
+	jae	L$256_or_more8x
+	cmpq	$192,%rdx
+	jae	L$192_or_more8x
+	cmpq	$128,%rdx
+	jae	L$128_or_more8x
+	cmpq	$64,%rdx
+	jae	L$64_or_more8x
+
+	xorq	%r10,%r10
+	vmovdqa	%ymm6,0(%rsp)
+	vmovdqa	%ymm8,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$64_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	je	L$done8x
+
+	leaq	64(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm1,0(%rsp)
+	leaq	64(%rdi),%rdi
+	subq	$64,%rdx
+	vmovdqa	%ymm5,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$128_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	je	L$done8x
+
+	leaq	128(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm12,0(%rsp)
+	leaq	128(%rdi),%rdi
+	subq	$128,%rdx
+	vmovdqa	%ymm13,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$192_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	je	L$done8x
+
+	leaq	192(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm10,0(%rsp)
+	leaq	192(%rdi),%rdi
+	subq	$192,%rdx
+	vmovdqa	%ymm15,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$256_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	je	L$done8x
+
+	leaq	256(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm14,0(%rsp)
+	leaq	256(%rdi),%rdi
+	subq	$256,%rdx
+	vmovdqa	%ymm2,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$320_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	je	L$done8x
+
+	leaq	320(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm3,0(%rsp)
+	leaq	320(%rdi),%rdi
+	subq	$320,%rdx
+	vmovdqa	%ymm7,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$384_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	je	L$done8x
+
+	leaq	384(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm11,0(%rsp)
+	leaq	384(%rdi),%rdi
+	subq	$384,%rdx
+	vmovdqa	%ymm9,32(%rsp)
+	jmp	L$oop_tail8x
+
+.p2align	5
+L$448_or_more8x:
+	vpxor	0(%rsi),%ymm6,%ymm6
+	vpxor	32(%rsi),%ymm8,%ymm8
+	vpxor	64(%rsi),%ymm1,%ymm1
+	vpxor	96(%rsi),%ymm5,%ymm5
+	vpxor	128(%rsi),%ymm12,%ymm12
+	vpxor	160(%rsi),%ymm13,%ymm13
+	vpxor	192(%rsi),%ymm10,%ymm10
+	vpxor	224(%rsi),%ymm15,%ymm15
+	vpxor	256(%rsi),%ymm14,%ymm14
+	vpxor	288(%rsi),%ymm2,%ymm2
+	vpxor	320(%rsi),%ymm3,%ymm3
+	vpxor	352(%rsi),%ymm7,%ymm7
+	vpxor	384(%rsi),%ymm11,%ymm11
+	vpxor	416(%rsi),%ymm9,%ymm9
+	vmovdqu	%ymm6,0(%rdi)
+	vmovdqu	%ymm8,32(%rdi)
+	vmovdqu	%ymm1,64(%rdi)
+	vmovdqu	%ymm5,96(%rdi)
+	vmovdqu	%ymm12,128(%rdi)
+	vmovdqu	%ymm13,160(%rdi)
+	vmovdqu	%ymm10,192(%rdi)
+	vmovdqu	%ymm15,224(%rdi)
+	vmovdqu	%ymm14,256(%rdi)
+	vmovdqu	%ymm2,288(%rdi)
+	vmovdqu	%ymm3,320(%rdi)
+	vmovdqu	%ymm7,352(%rdi)
+	vmovdqu	%ymm11,384(%rdi)
+	vmovdqu	%ymm9,416(%rdi)
+	je	L$done8x
+
+	leaq	448(%rsi),%rsi
+	xorq	%r10,%r10
+	vmovdqa	%ymm0,0(%rsp)
+	leaq	448(%rdi),%rdi
+	subq	$448,%rdx
+	vmovdqa	%ymm4,32(%rsp)
+
+L$oop_tail8x:
+	movzbl	(%rsi,%r10,1),%eax
+	movzbl	(%rsp,%r10,1),%ecx
+	leaq	1(%r10),%r10
+	xorl	%ecx,%eax
+	movb	%al,-1(%rdi,%r10,1)
+	decq	%rdx
+	jnz	L$oop_tail8x
+
+L$done8x:
+	vzeroall
+	movq	640(%rsp),%rsp
+	.byte	0xf3,0xc3
+
+#endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/cpu-x86_64-asm.S b/third_party/boringssl/mac-x86_64/crypto/cpu-x86_64-asm.S
deleted file mode 100644
index 0dde04d..0000000
--- a/third_party/boringssl/mac-x86_64/crypto/cpu-x86_64-asm.S
+++ /dev/null
@@ -1,143 +0,0 @@
-#if defined(__x86_64__)
-.text	
-
-.globl	_OPENSSL_ia32_cpuid
-.private_extern _OPENSSL_ia32_cpuid
-
-.p2align	4
-_OPENSSL_ia32_cpuid:
-
-
-	movq	%rdi,%rdi
-	movq	%rbx,%r8
-
-	xorl	%eax,%eax
-	movl	%eax,8(%rdi)
-	cpuid
-	movl	%eax,%r11d
-
-	xorl	%eax,%eax
-	cmpl	$1970169159,%ebx
-	setne	%al
-	movl	%eax,%r9d
-	cmpl	$1231384169,%edx
-	setne	%al
-	orl	%eax,%r9d
-	cmpl	$1818588270,%ecx
-	setne	%al
-	orl	%eax,%r9d
-	jz	L$intel
-
-	cmpl	$1752462657,%ebx
-	setne	%al
-	movl	%eax,%r10d
-	cmpl	$1769238117,%edx
-	setne	%al
-	orl	%eax,%r10d
-	cmpl	$1145913699,%ecx
-	setne	%al
-	orl	%eax,%r10d
-	jnz	L$intel
-
-
-
-
-	movl	$2147483648,%eax
-	cpuid
-
-
-	cmpl	$2147483649,%eax
-	jb	L$intel
-	movl	%eax,%r10d
-	movl	$2147483649,%eax
-	cpuid
-
-
-	orl	%ecx,%r9d
-	andl	$2049,%r9d
-
-	cmpl	$2147483656,%r10d
-	jb	L$intel
-
-	movl	$2147483656,%eax
-	cpuid
-
-	movzbq	%cl,%r10
-	incq	%r10
-
-	movl	$1,%eax
-	cpuid
-
-	btl	$28,%edx
-	jnc	L$generic
-	shrl	$16,%ebx
-	cmpb	%r10b,%bl
-	ja	L$generic
-	andl	$4026531839,%edx
-	jmp	L$generic
-
-L$intel:
-	cmpl	$4,%r11d
-	movl	$-1,%r10d
-	jb	L$nocacheinfo
-
-	movl	$4,%eax
-	movl	$0,%ecx
-	cpuid
-	movl	%eax,%r10d
-	shrl	$14,%r10d
-	andl	$4095,%r10d
-
-	cmpl	$7,%r11d
-	jb	L$nocacheinfo
-
-	movl	$7,%eax
-	xorl	%ecx,%ecx
-	cpuid
-	movl	%ebx,8(%rdi)
-
-L$nocacheinfo:
-	movl	$1,%eax
-	cpuid
-
-	andl	$3220176895,%edx
-	cmpl	$0,%r9d
-	jne	L$notintel
-	orl	$1073741824,%edx
-L$notintel:
-	btl	$28,%edx
-	jnc	L$generic
-	andl	$4026531839,%edx
-	cmpl	$0,%r10d
-	je	L$generic
-
-	orl	$268435456,%edx
-	shrl	$16,%ebx
-	cmpb	$1,%bl
-	ja	L$generic
-	andl	$4026531839,%edx
-L$generic:
-	andl	$2048,%r9d
-	andl	$4294965247,%ecx
-	orl	%ecx,%r9d
-
-	movl	%edx,%r10d
-	btl	$27,%r9d
-	jnc	L$clear_avx
-	xorl	%ecx,%ecx
-.byte	0x0f,0x01,0xd0
-	andl	$6,%eax
-	cmpl	$6,%eax
-	je	L$done
-L$clear_avx:
-	movl	$4026525695,%eax
-	andl	%eax,%r9d
-	andl	$4294967263,8(%rdi)
-L$done:
-	movl	%r9d,4(%rdi)
-	movl	%r10d,0(%rdi)
-	movq	%r8,%rbx
-	.byte	0xf3,0xc3
-
-
-#endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S b/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S
new file mode 100644
index 0000000..1cd0cc3
--- /dev/null
+++ b/third_party/boringssl/mac-x86_64/crypto/ec/p256-x86_64-asm.S
@@ -0,0 +1,1788 @@
+#if defined(__x86_64__)
+.text	
+
+
+
+.p2align	6
+L$poly:
+.quad	0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
+
+L$One:
+.long	1,1,1,1,1,1,1,1
+L$Two:
+.long	2,2,2,2,2,2,2,2
+L$Three:
+.long	3,3,3,3,3,3,3,3
+L$ONE_mont:
+.quad	0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
+
+
+.p2align	6
+ecp_nistz256_mul_by_2:
+	pushq	%r12
+	pushq	%r13
+
+	movq	0(%rsi),%r8
+	movq	8(%rsi),%r9
+	addq	%r8,%r8
+	movq	16(%rsi),%r10
+	adcq	%r9,%r9
+	movq	24(%rsi),%r11
+	leaq	L$poly(%rip),%rsi
+	movq	%r8,%rax
+	adcq	%r10,%r10
+	adcq	%r11,%r11
+	movq	%r9,%rdx
+	sbbq	%r13,%r13
+
+	subq	0(%rsi),%r8
+	movq	%r10,%rcx
+	sbbq	8(%rsi),%r9
+	sbbq	16(%rsi),%r10
+	movq	%r11,%r12
+	sbbq	24(%rsi),%r11
+	testq	%r13,%r13
+
+	cmovzq	%rax,%r8
+	cmovzq	%rdx,%r9
+	movq	%r8,0(%rdi)
+	cmovzq	%rcx,%r10
+	movq	%r9,8(%rdi)
+	cmovzq	%r12,%r11
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+
+	popq	%r13
+	popq	%r12
+	.byte	0xf3,0xc3
+
+
+
+
+.globl	_ecp_nistz256_neg
+.private_extern _ecp_nistz256_neg
+
+.p2align	5
+_ecp_nistz256_neg:
+	pushq	%r12
+	pushq	%r13
+
+	xorq	%r8,%r8
+	xorq	%r9,%r9
+	xorq	%r10,%r10
+	xorq	%r11,%r11
+	xorq	%r13,%r13
+
+	subq	0(%rsi),%r8
+	sbbq	8(%rsi),%r9
+	sbbq	16(%rsi),%r10
+	movq	%r8,%rax
+	sbbq	24(%rsi),%r11
+	leaq	L$poly(%rip),%rsi
+	movq	%r9,%rdx
+	sbbq	$0,%r13
+
+	addq	0(%rsi),%r8
+	movq	%r10,%rcx
+	adcq	8(%rsi),%r9
+	adcq	16(%rsi),%r10
+	movq	%r11,%r12
+	adcq	24(%rsi),%r11
+	testq	%r13,%r13
+
+	cmovzq	%rax,%r8
+	cmovzq	%rdx,%r9
+	movq	%r8,0(%rdi)
+	cmovzq	%rcx,%r10
+	movq	%r9,8(%rdi)
+	cmovzq	%r12,%r11
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+
+	popq	%r13
+	popq	%r12
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+.globl	_ecp_nistz256_mul_mont
+.private_extern _ecp_nistz256_mul_mont
+
+.p2align	5
+_ecp_nistz256_mul_mont:
+L$mul_mont:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rdx,%rbx
+	movq	0(%rdx),%rax
+	movq	0(%rsi),%r9
+	movq	8(%rsi),%r10
+	movq	16(%rsi),%r11
+	movq	24(%rsi),%r12
+
+	call	__ecp_nistz256_mul_montq
+L$mul_mont_done:
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+
+
+
+.p2align	5
+__ecp_nistz256_mul_montq:
+
+
+	movq	%rax,%rbp
+	mulq	%r9
+	movq	L$poly+8(%rip),%r14
+	movq	%rax,%r8
+	movq	%rbp,%rax
+	movq	%rdx,%r9
+
+	mulq	%r10
+	movq	L$poly+24(%rip),%r15
+	addq	%rax,%r9
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r10
+
+	mulq	%r11
+	addq	%rax,%r10
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%r12
+	addq	%rax,%r11
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	xorq	%r13,%r13
+	movq	%rdx,%r12
+
+
+
+
+
+
+
+
+
+
+	movq	%r8,%rbp
+	shlq	$32,%r8
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r8,%r9
+	adcq	%rbp,%r10
+	adcq	%rax,%r11
+	movq	8(%rbx),%rax
+	adcq	%rdx,%r12
+	adcq	$0,%r13
+	xorq	%r8,%r8
+
+
+
+	movq	%rax,%rbp
+	mulq	0(%rsi)
+	addq	%rax,%r9
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	8(%rsi)
+	addq	%rcx,%r10
+	adcq	$0,%rdx
+	addq	%rax,%r10
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	16(%rsi)
+	addq	%rcx,%r11
+	adcq	$0,%rdx
+	addq	%rax,%r11
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	24(%rsi)
+	addq	%rcx,%r12
+	adcq	$0,%rdx
+	addq	%rax,%r12
+	movq	%r9,%rax
+	adcq	%rdx,%r13
+	adcq	$0,%r8
+
+
+
+	movq	%r9,%rbp
+	shlq	$32,%r9
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r9,%r10
+	adcq	%rbp,%r11
+	adcq	%rax,%r12
+	movq	16(%rbx),%rax
+	adcq	%rdx,%r13
+	adcq	$0,%r8
+	xorq	%r9,%r9
+
+
+
+	movq	%rax,%rbp
+	mulq	0(%rsi)
+	addq	%rax,%r10
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	8(%rsi)
+	addq	%rcx,%r11
+	adcq	$0,%rdx
+	addq	%rax,%r11
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	16(%rsi)
+	addq	%rcx,%r12
+	adcq	$0,%rdx
+	addq	%rax,%r12
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	24(%rsi)
+	addq	%rcx,%r13
+	adcq	$0,%rdx
+	addq	%rax,%r13
+	movq	%r10,%rax
+	adcq	%rdx,%r8
+	adcq	$0,%r9
+
+
+
+	movq	%r10,%rbp
+	shlq	$32,%r10
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r10,%r11
+	adcq	%rbp,%r12
+	adcq	%rax,%r13
+	movq	24(%rbx),%rax
+	adcq	%rdx,%r8
+	adcq	$0,%r9
+	xorq	%r10,%r10
+
+
+
+	movq	%rax,%rbp
+	mulq	0(%rsi)
+	addq	%rax,%r11
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	8(%rsi)
+	addq	%rcx,%r12
+	adcq	$0,%rdx
+	addq	%rax,%r12
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	16(%rsi)
+	addq	%rcx,%r13
+	adcq	$0,%rdx
+	addq	%rax,%r13
+	movq	%rbp,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	24(%rsi)
+	addq	%rcx,%r8
+	adcq	$0,%rdx
+	addq	%rax,%r8
+	movq	%r11,%rax
+	adcq	%rdx,%r9
+	adcq	$0,%r10
+
+
+
+	movq	%r11,%rbp
+	shlq	$32,%r11
+	mulq	%r15
+	shrq	$32,%rbp
+	addq	%r11,%r12
+	adcq	%rbp,%r13
+	movq	%r12,%rcx
+	adcq	%rax,%r8
+	adcq	%rdx,%r9
+	movq	%r13,%rbp
+	adcq	$0,%r10
+
+
+
+	subq	$-1,%r12
+	movq	%r8,%rbx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%rdx
+	sbbq	%r15,%r9
+	sbbq	$0,%r10
+
+	cmovcq	%rcx,%r12
+	cmovcq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovcq	%rbx,%r8
+	movq	%r13,8(%rdi)
+	cmovcq	%rdx,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+
+
+.globl	_ecp_nistz256_sqr_mont
+.private_extern _ecp_nistz256_sqr_mont
+
+.p2align	5
+_ecp_nistz256_sqr_mont:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	0(%rsi),%rax
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r15
+	movq	24(%rsi),%r8
+
+	call	__ecp_nistz256_sqr_montq
+L$sqr_mont_done:
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+
+
+
+.p2align	5
+__ecp_nistz256_sqr_montq:
+	movq	%rax,%r13
+	mulq	%r14
+	movq	%rax,%r9
+	movq	%r15,%rax
+	movq	%rdx,%r10
+
+	mulq	%r13
+	addq	%rax,%r10
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r11
+
+	mulq	%r13
+	addq	%rax,%r11
+	movq	%r15,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%r12
+
+
+	mulq	%r14
+	addq	%rax,%r11
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rbp
+
+	mulq	%r14
+	addq	%rax,%r12
+	movq	%r8,%rax
+	adcq	$0,%rdx
+	addq	%rbp,%r12
+	movq	%rdx,%r13
+	adcq	$0,%r13
+
+
+	mulq	%r15
+	xorq	%r15,%r15
+	addq	%rax,%r13
+	movq	0(%rsi),%rax
+	movq	%rdx,%r14
+	adcq	$0,%r14
+
+	addq	%r9,%r9
+	adcq	%r10,%r10
+	adcq	%r11,%r11
+	adcq	%r12,%r12
+	adcq	%r13,%r13
+	adcq	%r14,%r14
+	adcq	$0,%r15
+
+	mulq	%rax
+	movq	%rax,%r8
+	movq	8(%rsi),%rax
+	movq	%rdx,%rcx
+
+	mulq	%rax
+	addq	%rcx,%r9
+	adcq	%rax,%r10
+	movq	16(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	%rax
+	addq	%rcx,%r11
+	adcq	%rax,%r12
+	movq	24(%rsi),%rax
+	adcq	$0,%rdx
+	movq	%rdx,%rcx
+
+	mulq	%rax
+	addq	%rcx,%r13
+	adcq	%rax,%r14
+	movq	%r8,%rax
+	adcq	%rdx,%r15
+
+	movq	L$poly+8(%rip),%rsi
+	movq	L$poly+24(%rip),%rbp
+
+
+
+
+	movq	%r8,%rcx
+	shlq	$32,%r8
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r8,%r9
+	adcq	%rcx,%r10
+	adcq	%rax,%r11
+	movq	%r9,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r9,%rcx
+	shlq	$32,%r9
+	movq	%rdx,%r8
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r9,%r10
+	adcq	%rcx,%r11
+	adcq	%rax,%r8
+	movq	%r10,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r10,%rcx
+	shlq	$32,%r10
+	movq	%rdx,%r9
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r10,%r11
+	adcq	%rcx,%r8
+	adcq	%rax,%r9
+	movq	%r11,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r11,%rcx
+	shlq	$32,%r11
+	movq	%rdx,%r10
+	mulq	%rbp
+	shrq	$32,%rcx
+	addq	%r11,%r8
+	adcq	%rcx,%r9
+	adcq	%rax,%r10
+	adcq	$0,%rdx
+	xorq	%r11,%r11
+
+
+
+	addq	%r8,%r12
+	adcq	%r9,%r13
+	movq	%r12,%r8
+	adcq	%r10,%r14
+	adcq	%rdx,%r15
+	movq	%r13,%r9
+	adcq	$0,%r11
+
+	subq	$-1,%r12
+	movq	%r14,%r10
+	sbbq	%rsi,%r13
+	sbbq	$0,%r14
+	movq	%r15,%rcx
+	sbbq	%rbp,%r15
+	sbbq	$0,%r11
+
+	cmovcq	%r8,%r12
+	cmovcq	%r9,%r13
+	movq	%r12,0(%rdi)
+	cmovcq	%r10,%r14
+	movq	%r13,8(%rdi)
+	cmovcq	%rcx,%r15
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+
+	.byte	0xf3,0xc3
+
+
+
+
+
+
+
+.globl	_ecp_nistz256_from_mont
+.private_extern _ecp_nistz256_from_mont
+
+.p2align	5
+_ecp_nistz256_from_mont:
+	pushq	%r12
+	pushq	%r13
+
+	movq	0(%rsi),%rax
+	movq	L$poly+24(%rip),%r13
+	movq	8(%rsi),%r9
+	movq	16(%rsi),%r10
+	movq	24(%rsi),%r11
+	movq	%rax,%r8
+	movq	L$poly+8(%rip),%r12
+
+
+
+	movq	%rax,%rcx
+	shlq	$32,%r8
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r8,%r9
+	adcq	%rcx,%r10
+	adcq	%rax,%r11
+	movq	%r9,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r9,%rcx
+	shlq	$32,%r9
+	movq	%rdx,%r8
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r9,%r10
+	adcq	%rcx,%r11
+	adcq	%rax,%r8
+	movq	%r10,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r10,%rcx
+	shlq	$32,%r10
+	movq	%rdx,%r9
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r10,%r11
+	adcq	%rcx,%r8
+	adcq	%rax,%r9
+	movq	%r11,%rax
+	adcq	$0,%rdx
+
+
+
+	movq	%r11,%rcx
+	shlq	$32,%r11
+	movq	%rdx,%r10
+	mulq	%r13
+	shrq	$32,%rcx
+	addq	%r11,%r8
+	adcq	%rcx,%r9
+	movq	%r8,%rcx
+	adcq	%rax,%r10
+	movq	%r9,%rsi
+	adcq	$0,%rdx
+
+	subq	$-1,%r8
+	movq	%r10,%rax
+	sbbq	%r12,%r9
+	sbbq	$0,%r10
+	movq	%rdx,%r11
+	sbbq	%r13,%rdx
+	sbbq	%r13,%r13
+
+	cmovnzq	%rcx,%r8
+	cmovnzq	%rsi,%r9
+	movq	%r8,0(%rdi)
+	cmovnzq	%rax,%r10
+	movq	%r9,8(%rdi)
+	cmovzq	%rdx,%r11
+	movq	%r10,16(%rdi)
+	movq	%r11,24(%rdi)
+
+	popq	%r13
+	popq	%r12
+	.byte	0xf3,0xc3
+
+
+
+.globl	_ecp_nistz256_select_w5
+.private_extern _ecp_nistz256_select_w5
+
+.p2align	5
+_ecp_nistz256_select_w5:
+	movdqa	L$One(%rip),%xmm0
+	movd	%edx,%xmm1
+
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+	pxor	%xmm6,%xmm6
+	pxor	%xmm7,%xmm7
+
+	movdqa	%xmm0,%xmm8
+	pshufd	$0,%xmm1,%xmm1
+
+	movq	$16,%rax
+L$select_loop_sse_w5:
+
+	movdqa	%xmm8,%xmm15
+	paddd	%xmm0,%xmm8
+	pcmpeqd	%xmm1,%xmm15
+
+	movdqa	0(%rsi),%xmm9
+	movdqa	16(%rsi),%xmm10
+	movdqa	32(%rsi),%xmm11
+	movdqa	48(%rsi),%xmm12
+	movdqa	64(%rsi),%xmm13
+	movdqa	80(%rsi),%xmm14
+	leaq	96(%rsi),%rsi
+
+	pand	%xmm15,%xmm9
+	pand	%xmm15,%xmm10
+	por	%xmm9,%xmm2
+	pand	%xmm15,%xmm11
+	por	%xmm10,%xmm3
+	pand	%xmm15,%xmm12
+	por	%xmm11,%xmm4
+	pand	%xmm15,%xmm13
+	por	%xmm12,%xmm5
+	pand	%xmm15,%xmm14
+	por	%xmm13,%xmm6
+	por	%xmm14,%xmm7
+
+	decq	%rax
+	jnz	L$select_loop_sse_w5
+
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+	movdqu	%xmm4,32(%rdi)
+	movdqu	%xmm5,48(%rdi)
+	movdqu	%xmm6,64(%rdi)
+	movdqu	%xmm7,80(%rdi)
+	.byte	0xf3,0xc3
+
+
+
+
+.globl	_ecp_nistz256_select_w7
+.private_extern _ecp_nistz256_select_w7
+
+.p2align	5
+_ecp_nistz256_select_w7:
+	movdqa	L$One(%rip),%xmm8
+	movd	%edx,%xmm1
+
+	pxor	%xmm2,%xmm2
+	pxor	%xmm3,%xmm3
+	pxor	%xmm4,%xmm4
+	pxor	%xmm5,%xmm5
+
+	movdqa	%xmm8,%xmm0
+	pshufd	$0,%xmm1,%xmm1
+	movq	$64,%rax
+
+L$select_loop_sse_w7:
+	movdqa	%xmm8,%xmm15
+	paddd	%xmm0,%xmm8
+	movdqa	0(%rsi),%xmm9
+	movdqa	16(%rsi),%xmm10
+	pcmpeqd	%xmm1,%xmm15
+	movdqa	32(%rsi),%xmm11
+	movdqa	48(%rsi),%xmm12
+	leaq	64(%rsi),%rsi
+
+	pand	%xmm15,%xmm9
+	pand	%xmm15,%xmm10
+	por	%xmm9,%xmm2
+	pand	%xmm15,%xmm11
+	por	%xmm10,%xmm3
+	pand	%xmm15,%xmm12
+	por	%xmm11,%xmm4
+	prefetcht0	255(%rsi)
+	por	%xmm12,%xmm5
+
+	decq	%rax
+	jnz	L$select_loop_sse_w7
+
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+	movdqu	%xmm4,32(%rdi)
+	movdqu	%xmm5,48(%rdi)
+	.byte	0xf3,0xc3
+
+.globl	_ecp_nistz256_avx2_select_w7
+.private_extern _ecp_nistz256_avx2_select_w7
+
+.p2align	5
+_ecp_nistz256_avx2_select_w7:
+.byte	0x0f,0x0b
+	.byte	0xf3,0xc3
+
+
+.p2align	5
+__ecp_nistz256_add_toq:
+	addq	0(%rbx),%r12
+	adcq	8(%rbx),%r13
+	movq	%r12,%rax
+	adcq	16(%rbx),%r8
+	adcq	24(%rbx),%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	cmovzq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovzq	%rcx,%r8
+	movq	%r13,8(%rdi)
+	cmovzq	%r10,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+
+
+
+.p2align	5
+__ecp_nistz256_sub_fromq:
+	subq	0(%rbx),%r12
+	sbbq	8(%rbx),%r13
+	movq	%r12,%rax
+	sbbq	16(%rbx),%r8
+	sbbq	24(%rbx),%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	addq	$-1,%r12
+	movq	%r8,%rcx
+	adcq	%r14,%r13
+	adcq	$0,%r8
+	movq	%r9,%r10
+	adcq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	cmovzq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovzq	%rcx,%r8
+	movq	%r13,8(%rdi)
+	cmovzq	%r10,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+
+
+
+.p2align	5
+__ecp_nistz256_subq:
+	subq	%r12,%rax
+	sbbq	%r13,%rbp
+	movq	%rax,%r12
+	sbbq	%r8,%rcx
+	sbbq	%r9,%r10
+	movq	%rbp,%r13
+	sbbq	%r11,%r11
+
+	addq	$-1,%rax
+	movq	%rcx,%r8
+	adcq	%r14,%rbp
+	adcq	$0,%rcx
+	movq	%r10,%r9
+	adcq	%r15,%r10
+	testq	%r11,%r11
+
+	cmovnzq	%rax,%r12
+	cmovnzq	%rbp,%r13
+	cmovnzq	%rcx,%r8
+	cmovnzq	%r10,%r9
+
+	.byte	0xf3,0xc3
+
+
+
+.p2align	5
+__ecp_nistz256_mul_by_2q:
+	addq	%r12,%r12
+	adcq	%r13,%r13
+	movq	%r12,%rax
+	adcq	%r8,%r8
+	adcq	%r9,%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	cmovzq	%rbp,%r13
+	movq	%r12,0(%rdi)
+	cmovzq	%rcx,%r8
+	movq	%r13,8(%rdi)
+	cmovzq	%r10,%r9
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+
+	.byte	0xf3,0xc3
+
+.globl	_ecp_nistz256_point_double
+.private_extern _ecp_nistz256_point_double
+
+.p2align	5
+_ecp_nistz256_point_double:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$160+8,%rsp
+
+L$point_double_shortcutq:
+	movdqu	0(%rsi),%xmm0
+	movq	%rsi,%rbx
+	movdqu	16(%rsi),%xmm1
+	movq	32+0(%rsi),%r12
+	movq	32+8(%rsi),%r13
+	movq	32+16(%rsi),%r8
+	movq	32+24(%rsi),%r9
+	movq	L$poly+8(%rip),%r14
+	movq	L$poly+24(%rip),%r15
+	movdqa	%xmm0,96(%rsp)
+	movdqa	%xmm1,96+16(%rsp)
+	leaq	32(%rdi),%r10
+	leaq	64(%rdi),%r11
+.byte	102,72,15,110,199
+.byte	102,73,15,110,202
+.byte	102,73,15,110,211
+
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_by_2q
+
+	movq	64+0(%rsi),%rax
+	movq	64+8(%rsi),%r14
+	movq	64+16(%rsi),%r15
+	movq	64+24(%rsi),%r8
+	leaq	64-0(%rsi),%rsi
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	0+0(%rsp),%rax
+	movq	8+0(%rsp),%r14
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r15
+	movq	24+0(%rsp),%r8
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	32(%rbx),%rax
+	movq	64+0(%rbx),%r9
+	movq	64+8(%rbx),%r10
+	movq	64+16(%rbx),%r11
+	movq	64+24(%rbx),%r12
+	leaq	64-0(%rbx),%rsi
+	leaq	32(%rbx),%rbx
+.byte	102,72,15,126,215
+	call	__ecp_nistz256_mul_montq
+	call	__ecp_nistz256_mul_by_2q
+
+	movq	96+0(%rsp),%r12
+	movq	96+8(%rsp),%r13
+	leaq	64(%rsp),%rbx
+	movq	96+16(%rsp),%r8
+	movq	96+24(%rsp),%r9
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_add_toq
+
+	movq	96+0(%rsp),%r12
+	movq	96+8(%rsp),%r13
+	leaq	64(%rsp),%rbx
+	movq	96+16(%rsp),%r8
+	movq	96+24(%rsp),%r9
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+0(%rsp),%rax
+	movq	8+0(%rsp),%r14
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r15
+	movq	24+0(%rsp),%r8
+.byte	102,72,15,126,207
+	call	__ecp_nistz256_sqr_montq
+	xorq	%r9,%r9
+	movq	%r12,%rax
+	addq	$-1,%r12
+	movq	%r13,%r10
+	adcq	%rsi,%r13
+	movq	%r14,%rcx
+	adcq	$0,%r14
+	movq	%r15,%r8
+	adcq	%rbp,%r15
+	adcq	$0,%r9
+	xorq	%rsi,%rsi
+	testq	$1,%rax
+
+	cmovzq	%rax,%r12
+	cmovzq	%r10,%r13
+	cmovzq	%rcx,%r14
+	cmovzq	%r8,%r15
+	cmovzq	%rsi,%r9
+
+	movq	%r13,%rax
+	shrq	$1,%r12
+	shlq	$63,%rax
+	movq	%r14,%r10
+	shrq	$1,%r13
+	orq	%rax,%r12
+	shlq	$63,%r10
+	movq	%r15,%rcx
+	shrq	$1,%r14
+	orq	%r10,%r13
+	shlq	$63,%rcx
+	movq	%r12,0(%rdi)
+	shrq	$1,%r15
+	movq	%r13,8(%rdi)
+	shlq	$63,%r9
+	orq	%rcx,%r14
+	orq	%r9,%r15
+	movq	%r14,16(%rdi)
+	movq	%r15,24(%rdi)
+	movq	64(%rsp),%rax
+	leaq	64(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_mul_by_2q
+
+	leaq	32(%rsp),%rbx
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_add_toq
+
+	movq	96(%rsp),%rax
+	leaq	96(%rsp),%rbx
+	movq	0+0(%rsp),%r9
+	movq	8+0(%rsp),%r10
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r11
+	movq	24+0(%rsp),%r12
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_mul_by_2q
+
+	movq	0+32(%rsp),%rax
+	movq	8+32(%rsp),%r14
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r15
+	movq	24+32(%rsp),%r8
+.byte	102,72,15,126,199
+	call	__ecp_nistz256_sqr_montq
+
+	leaq	128(%rsp),%rbx
+	movq	%r14,%r8
+	movq	%r15,%r9
+	movq	%rsi,%r14
+	movq	%rbp,%r15
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+0(%rsp),%rax
+	movq	0+8(%rsp),%rbp
+	movq	0+16(%rsp),%rcx
+	movq	0+24(%rsp),%r10
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_subq
+
+	movq	32(%rsp),%rax
+	leaq	32(%rsp),%rbx
+	movq	%r12,%r14
+	xorl	%ecx,%ecx
+	movq	%r12,0+0(%rsp)
+	movq	%r13,%r10
+	movq	%r13,0+8(%rsp)
+	cmovzq	%r8,%r11
+	movq	%r8,0+16(%rsp)
+	leaq	0-0(%rsp),%rsi
+	cmovzq	%r9,%r12
+	movq	%r9,0+24(%rsp)
+	movq	%r14,%r9
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+.byte	102,72,15,126,203
+.byte	102,72,15,126,207
+	call	__ecp_nistz256_sub_fromq
+
+	addq	$160+8,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+
+.globl	_ecp_nistz256_point_add
+.private_extern _ecp_nistz256_point_add
+
+.p2align	5
+_ecp_nistz256_point_add:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$576+8,%rsp
+
+	movdqu	0(%rsi),%xmm0
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm3
+	movdqu	64(%rsi),%xmm4
+	movdqu	80(%rsi),%xmm5
+	movq	%rsi,%rbx
+	movq	%rdx,%rsi
+	movdqa	%xmm0,384(%rsp)
+	movdqa	%xmm1,384+16(%rsp)
+	por	%xmm0,%xmm1
+	movdqa	%xmm2,416(%rsp)
+	movdqa	%xmm3,416+16(%rsp)
+	por	%xmm2,%xmm3
+	movdqa	%xmm4,448(%rsp)
+	movdqa	%xmm5,448+16(%rsp)
+	por	%xmm1,%xmm3
+
+	movdqu	0(%rsi),%xmm0
+	pshufd	$0xb1,%xmm3,%xmm5
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	por	%xmm3,%xmm5
+	movdqu	48(%rsi),%xmm3
+	movq	64+0(%rsi),%rax
+	movq	64+8(%rsi),%r14
+	movq	64+16(%rsi),%r15
+	movq	64+24(%rsi),%r8
+	movdqa	%xmm0,480(%rsp)
+	pshufd	$0x1e,%xmm5,%xmm4
+	movdqa	%xmm1,480+16(%rsp)
+	por	%xmm0,%xmm1
+.byte	102,72,15,110,199
+	movdqa	%xmm2,512(%rsp)
+	movdqa	%xmm3,512+16(%rsp)
+	por	%xmm2,%xmm3
+	por	%xmm4,%xmm5
+	pxor	%xmm4,%xmm4
+	por	%xmm1,%xmm3
+
+	leaq	64-0(%rsi),%rsi
+	movq	%rax,544+0(%rsp)
+	movq	%r14,544+8(%rsp)
+	movq	%r15,544+16(%rsp)
+	movq	%r8,544+24(%rsp)
+	leaq	96(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	pcmpeqd	%xmm4,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm4
+	por	%xmm3,%xmm4
+	pshufd	$0,%xmm5,%xmm5
+	pshufd	$0x1e,%xmm4,%xmm3
+	por	%xmm3,%xmm4
+	pxor	%xmm3,%xmm3
+	pcmpeqd	%xmm3,%xmm4
+	pshufd	$0,%xmm4,%xmm4
+	movq	64+0(%rbx),%rax
+	movq	64+8(%rbx),%r14
+	movq	64+16(%rbx),%r15
+	movq	64+24(%rbx),%r8
+.byte	102,72,15,110,203
+
+	leaq	64-0(%rbx),%rsi
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	544(%rsp),%rax
+	leaq	544(%rsp),%rbx
+	movq	0+96(%rsp),%r9
+	movq	8+96(%rsp),%r10
+	leaq	0+96(%rsp),%rsi
+	movq	16+96(%rsp),%r11
+	movq	24+96(%rsp),%r12
+	leaq	224(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	448(%rsp),%rax
+	leaq	448(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	416(%rsp),%rax
+	leaq	416(%rsp),%rbx
+	movq	0+224(%rsp),%r9
+	movq	8+224(%rsp),%r10
+	leaq	0+224(%rsp),%rsi
+	movq	16+224(%rsp),%r11
+	movq	24+224(%rsp),%r12
+	leaq	224(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	512(%rsp),%rax
+	leaq	512(%rsp),%rbx
+	movq	0+256(%rsp),%r9
+	movq	8+256(%rsp),%r10
+	leaq	0+256(%rsp),%rsi
+	movq	16+256(%rsp),%r11
+	movq	24+256(%rsp),%r12
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	224(%rsp),%rbx
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	orq	%r13,%r12
+	movdqa	%xmm4,%xmm2
+	orq	%r8,%r12
+	orq	%r9,%r12
+	por	%xmm5,%xmm2
+.byte	102,73,15,110,220
+
+	movq	384(%rsp),%rax
+	leaq	384(%rsp),%rbx
+	movq	0+96(%rsp),%r9
+	movq	8+96(%rsp),%r10
+	leaq	0+96(%rsp),%rsi
+	movq	16+96(%rsp),%r11
+	movq	24+96(%rsp),%r12
+	leaq	160(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	480(%rsp),%rax
+	leaq	480(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	192(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	160(%rsp),%rbx
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	orq	%r13,%r12
+	orq	%r8,%r12
+	orq	%r9,%r12
+
+.byte	0x3e
+	jnz	L$add_proceedq
+.byte	102,73,15,126,208
+.byte	102,73,15,126,217
+	testq	%r8,%r8
+	jnz	L$add_proceedq
+	testq	%r9,%r9
+	jz	L$add_doubleq
+
+.byte	102,72,15,126,199
+	pxor	%xmm0,%xmm0
+	movdqu	%xmm0,0(%rdi)
+	movdqu	%xmm0,16(%rdi)
+	movdqu	%xmm0,32(%rdi)
+	movdqu	%xmm0,48(%rdi)
+	movdqu	%xmm0,64(%rdi)
+	movdqu	%xmm0,80(%rdi)
+	jmp	L$add_doneq
+
+.p2align	5
+L$add_doubleq:
+.byte	102,72,15,126,206
+.byte	102,72,15,126,199
+	addq	$416,%rsp
+	jmp	L$point_double_shortcutq
+
+.p2align	5
+L$add_proceedq:
+	movq	0+64(%rsp),%rax
+	movq	8+64(%rsp),%r14
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r15
+	movq	24+64(%rsp),%r8
+	leaq	96(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	448(%rsp),%rax
+	leaq	448(%rsp),%rbx
+	movq	0+0(%rsp),%r9
+	movq	8+0(%rsp),%r10
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r11
+	movq	24+0(%rsp),%r12
+	leaq	352(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	0+0(%rsp),%rax
+	movq	8+0(%rsp),%r14
+	leaq	0+0(%rsp),%rsi
+	movq	16+0(%rsp),%r15
+	movq	24+0(%rsp),%r8
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	544(%rsp),%rax
+	leaq	544(%rsp),%rbx
+	movq	0+352(%rsp),%r9
+	movq	8+352(%rsp),%r10
+	leaq	0+352(%rsp),%rsi
+	movq	16+352(%rsp),%r11
+	movq	24+352(%rsp),%r12
+	leaq	352(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	0(%rsp),%rax
+	leaq	0(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	160(%rsp),%rax
+	leaq	160(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	192(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+
+
+
+	addq	%r12,%r12
+	leaq	96(%rsp),%rsi
+	adcq	%r13,%r13
+	movq	%r12,%rax
+	adcq	%r8,%r8
+	adcq	%r9,%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	movq	0(%rsi),%rax
+	cmovzq	%rbp,%r13
+	movq	8(%rsi),%rbp
+	cmovzq	%rcx,%r8
+	movq	16(%rsi),%rcx
+	cmovzq	%r10,%r9
+	movq	24(%rsi),%r10
+
+	call	__ecp_nistz256_subq
+
+	leaq	128(%rsp),%rbx
+	leaq	288(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	192+0(%rsp),%rax
+	movq	192+8(%rsp),%rbp
+	movq	192+16(%rsp),%rcx
+	movq	192+24(%rsp),%r10
+	leaq	320(%rsp),%rdi
+
+	call	__ecp_nistz256_subq
+
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+	movq	128(%rsp),%rax
+	leaq	128(%rsp),%rbx
+	movq	0+224(%rsp),%r9
+	movq	8+224(%rsp),%r10
+	leaq	0+224(%rsp),%rsi
+	movq	16+224(%rsp),%r11
+	movq	24+224(%rsp),%r12
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	320(%rsp),%rax
+	leaq	320(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	320(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	256(%rsp),%rbx
+	leaq	320(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+.byte	102,72,15,126,199
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	352(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	352+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	544(%rsp),%xmm2
+	pand	544+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	448(%rsp),%xmm2
+	pand	448+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,64(%rdi)
+	movdqu	%xmm3,80(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	288(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	288+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	480(%rsp),%xmm2
+	pand	480+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	384(%rsp),%xmm2
+	pand	384+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	320(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	320+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	512(%rsp),%xmm2
+	pand	512+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	416(%rsp),%xmm2
+	pand	416+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+
+L$add_doneq:
+	addq	$576+8,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+
+.globl	_ecp_nistz256_point_add_affine
+.private_extern _ecp_nistz256_point_add_affine
+
+.p2align	5
+_ecp_nistz256_point_add_affine:
+	pushq	%rbp
+	pushq	%rbx
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	subq	$480+8,%rsp
+
+	movdqu	0(%rsi),%xmm0
+	movq	%rdx,%rbx
+	movdqu	16(%rsi),%xmm1
+	movdqu	32(%rsi),%xmm2
+	movdqu	48(%rsi),%xmm3
+	movdqu	64(%rsi),%xmm4
+	movdqu	80(%rsi),%xmm5
+	movq	64+0(%rsi),%rax
+	movq	64+8(%rsi),%r14
+	movq	64+16(%rsi),%r15
+	movq	64+24(%rsi),%r8
+	movdqa	%xmm0,320(%rsp)
+	movdqa	%xmm1,320+16(%rsp)
+	por	%xmm0,%xmm1
+	movdqa	%xmm2,352(%rsp)
+	movdqa	%xmm3,352+16(%rsp)
+	por	%xmm2,%xmm3
+	movdqa	%xmm4,384(%rsp)
+	movdqa	%xmm5,384+16(%rsp)
+	por	%xmm1,%xmm3
+
+	movdqu	0(%rbx),%xmm0
+	pshufd	$0xb1,%xmm3,%xmm5
+	movdqu	16(%rbx),%xmm1
+	movdqu	32(%rbx),%xmm2
+	por	%xmm3,%xmm5
+	movdqu	48(%rbx),%xmm3
+	movdqa	%xmm0,416(%rsp)
+	pshufd	$0x1e,%xmm5,%xmm4
+	movdqa	%xmm1,416+16(%rsp)
+	por	%xmm0,%xmm1
+.byte	102,72,15,110,199
+	movdqa	%xmm2,448(%rsp)
+	movdqa	%xmm3,448+16(%rsp)
+	por	%xmm2,%xmm3
+	por	%xmm4,%xmm5
+	pxor	%xmm4,%xmm4
+	por	%xmm1,%xmm3
+
+	leaq	64-0(%rsi),%rsi
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	pcmpeqd	%xmm4,%xmm5
+	pshufd	$0xb1,%xmm3,%xmm4
+	movq	0(%rbx),%rax
+
+	movq	%r12,%r9
+	por	%xmm3,%xmm4
+	pshufd	$0,%xmm5,%xmm5
+	pshufd	$0x1e,%xmm4,%xmm3
+	movq	%r13,%r10
+	por	%xmm3,%xmm4
+	pxor	%xmm3,%xmm3
+	movq	%r14,%r11
+	pcmpeqd	%xmm3,%xmm4
+	pshufd	$0,%xmm4,%xmm4
+
+	leaq	32-0(%rsp),%rsi
+	movq	%r15,%r12
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	320(%rsp),%rbx
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	384(%rsp),%rax
+	leaq	384(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	384(%rsp),%rax
+	leaq	384(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	288(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	448(%rsp),%rax
+	leaq	448(%rsp),%rbx
+	movq	0+32(%rsp),%r9
+	movq	8+32(%rsp),%r10
+	leaq	0+32(%rsp),%rsi
+	movq	16+32(%rsp),%r11
+	movq	24+32(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	352(%rsp),%rbx
+	leaq	96(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+64(%rsp),%rax
+	movq	8+64(%rsp),%r14
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r15
+	movq	24+64(%rsp),%r8
+	leaq	128(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	0+96(%rsp),%rax
+	movq	8+96(%rsp),%r14
+	leaq	0+96(%rsp),%rsi
+	movq	16+96(%rsp),%r15
+	movq	24+96(%rsp),%r8
+	leaq	192(%rsp),%rdi
+	call	__ecp_nistz256_sqr_montq
+
+	movq	128(%rsp),%rax
+	leaq	128(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	160(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	320(%rsp),%rax
+	leaq	320(%rsp),%rbx
+	movq	0+128(%rsp),%r9
+	movq	8+128(%rsp),%r10
+	leaq	0+128(%rsp),%rsi
+	movq	16+128(%rsp),%r11
+	movq	24+128(%rsp),%r12
+	leaq	0(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+
+
+
+	addq	%r12,%r12
+	leaq	192(%rsp),%rsi
+	adcq	%r13,%r13
+	movq	%r12,%rax
+	adcq	%r8,%r8
+	adcq	%r9,%r9
+	movq	%r13,%rbp
+	sbbq	%r11,%r11
+
+	subq	$-1,%r12
+	movq	%r8,%rcx
+	sbbq	%r14,%r13
+	sbbq	$0,%r8
+	movq	%r9,%r10
+	sbbq	%r15,%r9
+	testq	%r11,%r11
+
+	cmovzq	%rax,%r12
+	movq	0(%rsi),%rax
+	cmovzq	%rbp,%r13
+	movq	8(%rsi),%rbp
+	cmovzq	%rcx,%r8
+	movq	16(%rsi),%rcx
+	cmovzq	%r10,%r9
+	movq	24(%rsi),%r10
+
+	call	__ecp_nistz256_subq
+
+	leaq	160(%rsp),%rbx
+	leaq	224(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+	movq	0+0(%rsp),%rax
+	movq	0+8(%rsp),%rbp
+	movq	0+16(%rsp),%rcx
+	movq	0+24(%rsp),%r10
+	leaq	64(%rsp),%rdi
+
+	call	__ecp_nistz256_subq
+
+	movq	%r12,0(%rdi)
+	movq	%r13,8(%rdi)
+	movq	%r8,16(%rdi)
+	movq	%r9,24(%rdi)
+	movq	352(%rsp),%rax
+	leaq	352(%rsp),%rbx
+	movq	0+160(%rsp),%r9
+	movq	8+160(%rsp),%r10
+	leaq	0+160(%rsp),%rsi
+	movq	16+160(%rsp),%r11
+	movq	24+160(%rsp),%r12
+	leaq	32(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	movq	96(%rsp),%rax
+	leaq	96(%rsp),%rbx
+	movq	0+64(%rsp),%r9
+	movq	8+64(%rsp),%r10
+	leaq	0+64(%rsp),%rsi
+	movq	16+64(%rsp),%r11
+	movq	24+64(%rsp),%r12
+	leaq	64(%rsp),%rdi
+	call	__ecp_nistz256_mul_montq
+
+	leaq	32(%rsp),%rbx
+	leaq	256(%rsp),%rdi
+	call	__ecp_nistz256_sub_fromq
+
+.byte	102,72,15,126,199
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	288(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	288+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	L$ONE_mont(%rip),%xmm2
+	pand	L$ONE_mont+16(%rip),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	384(%rsp),%xmm2
+	pand	384+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,64(%rdi)
+	movdqu	%xmm3,80(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	224(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	224+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	416(%rsp),%xmm2
+	pand	416+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	320(%rsp),%xmm2
+	pand	320+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,0(%rdi)
+	movdqu	%xmm3,16(%rdi)
+
+	movdqa	%xmm5,%xmm0
+	movdqa	%xmm5,%xmm1
+	pandn	256(%rsp),%xmm0
+	movdqa	%xmm5,%xmm2
+	pandn	256+16(%rsp),%xmm1
+	movdqa	%xmm5,%xmm3
+	pand	448(%rsp),%xmm2
+	pand	448+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+
+	movdqa	%xmm4,%xmm0
+	movdqa	%xmm4,%xmm1
+	pandn	%xmm2,%xmm0
+	movdqa	%xmm4,%xmm2
+	pandn	%xmm3,%xmm1
+	movdqa	%xmm4,%xmm3
+	pand	352(%rsp),%xmm2
+	pand	352+16(%rsp),%xmm3
+	por	%xmm0,%xmm2
+	por	%xmm1,%xmm3
+	movdqu	%xmm2,32(%rdi)
+	movdqu	%xmm3,48(%rdi)
+
+	addq	$480+8,%rsp
+	popq	%r15
+	popq	%r14
+	popq	%r13
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.byte	0xf3,0xc3
+
+#endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/md5/md5-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/md5/md5-x86_64.S
index 1e61479..16fd2cc 100644
--- a/third_party/boringssl/mac-x86_64/crypto/md5/md5-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/md5/md5-x86_64.S
@@ -495,14 +495,14 @@
 	movl	%ecx,%r11d
 	addl	%ecx,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	xorl	%edx,%r11d
 	leal	-198630844(%rax,%r10,1),%eax
 	orl	%ebx,%r11d
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	28(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -511,7 +511,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	56(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -520,7 +520,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	20(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -529,7 +529,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	48(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -538,7 +538,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	12(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -547,7 +547,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	40(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -556,7 +556,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	4(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -565,7 +565,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	32(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -574,7 +574,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	60(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -583,7 +583,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	24(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -592,7 +592,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	52(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -601,7 +601,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	16(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
@@ -610,7 +610,7 @@
 	xorl	%ecx,%r11d
 	addl	%r11d,%eax
 	movl	44(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$6,%eax
 	xorl	%ecx,%r11d
 	addl	%ebx,%eax
@@ -619,7 +619,7 @@
 	xorl	%ebx,%r11d
 	addl	%r11d,%edx
 	movl	8(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$10,%edx
 	xorl	%ebx,%r11d
 	addl	%eax,%edx
@@ -628,7 +628,7 @@
 	xorl	%eax,%r11d
 	addl	%r11d,%ecx
 	movl	36(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$15,%ecx
 	xorl	%eax,%r11d
 	addl	%edx,%ecx
@@ -637,7 +637,7 @@
 	xorl	%edx,%r11d
 	addl	%r11d,%ebx
 	movl	0(%rsi),%r10d
-	movl	$4294967295,%r11d
+	movl	$0xffffffff,%r11d
 	roll	$21,%ebx
 	xorl	%edx,%r11d
 	addl	%ecx,%ebx
diff --git a/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S
index 305a91c..1072c7f 100644
--- a/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/modes/ghash-x86_64.S
@@ -22,14 +22,14 @@
 	movq	$14,%rcx
 	movq	8(%rsi,%rax,1),%r8
 	movq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	movq	%r8,%rdx
 	jmp	L$oop1
 
 .p2align	4
 L$oop1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	movb	(%rdi,%rcx,1),%al
 	shrq	$4,%r9
@@ -45,13 +45,13 @@
 	js	L$break1
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
@@ -60,19 +60,19 @@
 .p2align	4
 L$break1:
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rax,1),%r8
 	shlq	$60,%r10
 	xorq	(%rsi,%rax,1),%r9
-	andb	$240,%bl
+	andb	$0xf0,%bl
 	xorq	(%r11,%rdx,8),%r9
 	movq	%r8,%rdx
 	xorq	%r10,%r8
 
 	shrq	$4,%r8
-	andq	$15,%rdx
+	andq	$0xf,%rdx
 	movq	%r9,%r10
 	shrq	$4,%r9
 	xorq	8(%rsi,%rbx,1),%r8
@@ -880,20 +880,20 @@
 	movdqu	32(%rsi),%xmm7
 .byte	102,65,15,56,0,194
 
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	L$odd_tail
 
 	movdqu	16(%rsi),%xmm6
 	movl	_OPENSSL_ia32cap_P+4(%rip),%eax
-	cmpq	$48,%rcx
+	cmpq	$0x30,%rcx
 	jb	L$skip4x
 
 	andl	$71303168,%eax
 	cmpl	$4194304,%eax
 	je	L$skip4x
 
-	subq	$48,%rcx
-	movq	$11547335547999543296,%rax
+	subq	$0x30,%rcx
+	movq	$0xA040608020C0E000,%rax
 	movdqu	48(%rsi),%xmm14
 	movdqu	64(%rsi),%xmm15
 
@@ -940,7 +940,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jc	L$tail4x
 
 	jmp	L$mod4_loop
@@ -1023,7 +1023,7 @@
 	xorps	%xmm13,%xmm5
 
 	leaq	64(%rdx),%rdx
-	subq	$64,%rcx
+	subq	$0x40,%rcx
 	jnc	L$mod4_loop
 
 L$tail4x:
@@ -1067,10 +1067,10 @@
 	pxor	%xmm4,%xmm0
 	psrlq	$1,%xmm0
 	pxor	%xmm1,%xmm0
-	addq	$64,%rcx
+	addq	$0x40,%rcx
 	jz	L$done
 	movdqu	32(%rsi),%xmm7
-	subq	$16,%rcx
+	subq	$0x10,%rcx
 	jz	L$odd_tail
 L$skip4x:
 
@@ -1093,7 +1093,7 @@
 
 	leaq	32(%rdx),%rdx
 	nop
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	jbe	L$even_tail
 	nop
 	jmp	L$mod_loop
@@ -1156,7 +1156,7 @@
 .byte	102,15,58,68,231,0
 	pxor	%xmm1,%xmm0
 
-	subq	$32,%rcx
+	subq	$0x20,%rcx
 	ja	L$mod_loop
 
 L$even_tail:
diff --git a/third_party/boringssl/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S
deleted file mode 100644
index 31ee7d2..0000000
--- a/third_party/boringssl/mac-x86_64/crypto/rc4/rc4-md5-x86_64.S
+++ /dev/null
@@ -1,1262 +0,0 @@
-#if defined(__x86_64__)
-.text	
-.p2align	4
-
-.globl	_rc4_md5_enc
-.private_extern _rc4_md5_enc
-
-_rc4_md5_enc:
-	cmpq	$0,%r9
-	je	L$abort
-	pushq	%rbx
-	pushq	%rbp
-	pushq	%r12
-	pushq	%r13
-	pushq	%r14
-	pushq	%r15
-	subq	$40,%rsp
-L$body:
-	movq	%rcx,%r11
-	movq	%r9,%r12
-	movq	%rsi,%r13
-	movq	%rdx,%r14
-	movq	%r8,%r15
-	xorq	%rbp,%rbp
-	xorq	%rcx,%rcx
-
-	leaq	8(%rdi),%rdi
-	movb	-8(%rdi),%bpl
-	movb	-4(%rdi),%cl
-
-	incb	%bpl
-	subq	%r13,%r14
-	movl	(%rdi,%rbp,4),%eax
-	addb	%al,%cl
-	leaq	(%rdi,%rbp,4),%rsi
-	shlq	$6,%r12
-	addq	%r15,%r12
-	movq	%r12,16(%rsp)
-
-	movq	%r11,24(%rsp)
-	movl	0(%r11),%r8d
-	movl	4(%r11),%r9d
-	movl	8(%r11),%r10d
-	movl	12(%r11),%r11d
-	jmp	L$oop
-
-.p2align	4
-L$oop:
-	movl	%r8d,0(%rsp)
-	movl	%r9d,4(%rsp)
-	movl	%r10d,8(%rsp)
-	movl	%r11d,%r12d
-	movl	%r11d,12(%rsp)
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	0(%r15),%r8d
-	addb	%dl,%al
-	movl	4(%rsi),%ebx
-	addl	$3614090360,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,0(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	4(%r15),%r11d
-	addb	%dl,%bl
-	movl	8(%rsi),%eax
-	addl	$3905402710,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,4(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	8(%r15),%r10d
-	addb	%dl,%al
-	movl	12(%rsi),%ebx
-	addl	$606105819,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,8(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	12(%r15),%r9d
-	addb	%dl,%bl
-	movl	16(%rsi),%eax
-	addl	$3250441966,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,12(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	16(%r15),%r8d
-	addb	%dl,%al
-	movl	20(%rsi),%ebx
-	addl	$4118548399,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,16(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	20(%r15),%r11d
-	addb	%dl,%bl
-	movl	24(%rsi),%eax
-	addl	$1200080426,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,20(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	24(%r15),%r10d
-	addb	%dl,%al
-	movl	28(%rsi),%ebx
-	addl	$2821735955,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,24(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	28(%r15),%r9d
-	addb	%dl,%bl
-	movl	32(%rsi),%eax
-	addl	$4249261313,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,28(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	32(%r15),%r8d
-	addb	%dl,%al
-	movl	36(%rsi),%ebx
-	addl	$1770035416,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,32(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	36(%r15),%r11d
-	addb	%dl,%bl
-	movl	40(%rsi),%eax
-	addl	$2336552879,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,36(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	40(%r15),%r10d
-	addb	%dl,%al
-	movl	44(%rsi),%ebx
-	addl	$4294925233,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,40(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	44(%r15),%r9d
-	addb	%dl,%bl
-	movl	48(%rsi),%eax
-	addl	$2304563134,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,44(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	48(%r15),%r8d
-	addb	%dl,%al
-	movl	52(%rsi),%ebx
-	addl	$1804603682,%r8d
-	xorl	%r11d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,48(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$7,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	52(%r15),%r11d
-	addb	%dl,%bl
-	movl	56(%rsi),%eax
-	addl	$4254626195,%r11d
-	xorl	%r10d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,52(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$12,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	56(%r15),%r10d
-	addb	%dl,%al
-	movl	60(%rsi),%ebx
-	addl	$2792965006,%r10d
-	xorl	%r9d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,56(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$17,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	(%r13),%xmm2
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	60(%r15),%r9d
-	addb	%dl,%bl
-	movl	64(%rsi),%eax
-	addl	$1236535329,%r9d
-	xorl	%r8d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,60(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$22,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm2
-	pxor	%xmm1,%xmm2
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	4(%r15),%r8d
-	addb	%dl,%al
-	movl	68(%rsi),%ebx
-	addl	$4129170786,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,64(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	24(%r15),%r11d
-	addb	%dl,%bl
-	movl	72(%rsi),%eax
-	addl	$3225465664,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,68(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	44(%r15),%r10d
-	addb	%dl,%al
-	movl	76(%rsi),%ebx
-	addl	$643717713,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,72(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	0(%r15),%r9d
-	addb	%dl,%bl
-	movl	80(%rsi),%eax
-	addl	$3921069994,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,76(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	20(%r15),%r8d
-	addb	%dl,%al
-	movl	84(%rsi),%ebx
-	addl	$3593408605,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,80(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	40(%r15),%r11d
-	addb	%dl,%bl
-	movl	88(%rsi),%eax
-	addl	$38016083,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,84(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	60(%r15),%r10d
-	addb	%dl,%al
-	movl	92(%rsi),%ebx
-	addl	$3634488961,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,88(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	16(%r15),%r9d
-	addb	%dl,%bl
-	movl	96(%rsi),%eax
-	addl	$3889429448,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,92(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	36(%r15),%r8d
-	addb	%dl,%al
-	movl	100(%rsi),%ebx
-	addl	$568446438,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,96(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	56(%r15),%r11d
-	addb	%dl,%bl
-	movl	104(%rsi),%eax
-	addl	$3275163606,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,100(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	12(%r15),%r10d
-	addb	%dl,%al
-	movl	108(%rsi),%ebx
-	addl	$4107603335,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,104(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	32(%r15),%r9d
-	addb	%dl,%bl
-	movl	112(%rsi),%eax
-	addl	$1163531501,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,108(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r10d,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r11d,%r12d
-	addl	52(%r15),%r8d
-	addb	%dl,%al
-	movl	116(%rsi),%ebx
-	addl	$2850285829,%r8d
-	xorl	%r10d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,112(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$5,%r8d
-	movl	%r9d,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r10d,%r12d
-	addl	8(%r15),%r11d
-	addb	%dl,%bl
-	movl	120(%rsi),%eax
-	addl	$4243563512,%r11d
-	xorl	%r9d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,116(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$9,%r11d
-	movl	%r8d,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	andl	%r9d,%r12d
-	addl	28(%r15),%r10d
-	addb	%dl,%al
-	movl	124(%rsi),%ebx
-	addl	$1735328473,%r10d
-	xorl	%r8d,%r12d
-	movzbl	%al,%eax
-	movl	%edx,120(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$14,%r10d
-	movl	%r11d,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	16(%r13),%xmm3
-	addb	$32,%bpl
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	andl	%r8d,%r12d
-	addl	48(%r15),%r9d
-	addb	%dl,%bl
-	movl	0(%rdi,%rbp,4),%eax
-	addl	$2368359562,%r9d
-	xorl	%r11d,%r12d
-	movzbl	%bl,%ebx
-	movl	%edx,124(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$20,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movq	%rcx,%rsi
-	xorq	%rcx,%rcx
-	movb	%sil,%cl
-	leaq	(%rdi,%rbp,4),%rsi
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm3
-	pxor	%xmm1,%xmm3
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	20(%r15),%r8d
-	addb	%dl,%al
-	movl	4(%rsi),%ebx
-	addl	$4294588738,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,0(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	32(%r15),%r11d
-	addb	%dl,%bl
-	movl	8(%rsi),%eax
-	addl	$2272392833,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,4(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	44(%r15),%r10d
-	addb	%dl,%al
-	movl	12(%rsi),%ebx
-	addl	$1839030562,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,8(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	56(%r15),%r9d
-	addb	%dl,%bl
-	movl	16(%rsi),%eax
-	addl	$4259657740,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,12(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	4(%r15),%r8d
-	addb	%dl,%al
-	movl	20(%rsi),%ebx
-	addl	$2763975236,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,16(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	16(%r15),%r11d
-	addb	%dl,%bl
-	movl	24(%rsi),%eax
-	addl	$1272893353,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,20(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	28(%r15),%r10d
-	addb	%dl,%al
-	movl	28(%rsi),%ebx
-	addl	$4139469664,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,24(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	40(%r15),%r9d
-	addb	%dl,%bl
-	movl	32(%rsi),%eax
-	addl	$3200236656,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,28(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	52(%r15),%r8d
-	addb	%dl,%al
-	movl	36(%rsi),%ebx
-	addl	$681279174,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,32(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	0(%r15),%r11d
-	addb	%dl,%bl
-	movl	40(%rsi),%eax
-	addl	$3936430074,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,36(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	12(%r15),%r10d
-	addb	%dl,%al
-	movl	44(%rsi),%ebx
-	addl	$3572445317,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,40(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	24(%r15),%r9d
-	addb	%dl,%bl
-	movl	48(%rsi),%eax
-	addl	$76029189,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,44(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	%r11d,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r9d,%r12d
-	addl	36(%r15),%r8d
-	addb	%dl,%al
-	movl	52(%rsi),%ebx
-	addl	$3654602809,%r8d
-	movzbl	%al,%eax
-	addl	%r12d,%r8d
-	movl	%edx,48(%rsi)
-	addb	%bl,%cl
-	roll	$4,%r8d
-	movl	%r10d,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r8d,%r12d
-	addl	48(%r15),%r11d
-	addb	%dl,%bl
-	movl	56(%rsi),%eax
-	addl	$3873151461,%r11d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r11d
-	movl	%edx,52(%rsi)
-	addb	%al,%cl
-	roll	$11,%r11d
-	movl	%r9d,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	xorl	%r11d,%r12d
-	addl	60(%r15),%r10d
-	addb	%dl,%al
-	movl	60(%rsi),%ebx
-	addl	$530742520,%r10d
-	movzbl	%al,%eax
-	addl	%r12d,%r10d
-	movl	%edx,56(%rsi)
-	addb	%bl,%cl
-	roll	$16,%r10d
-	movl	%r8d,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	32(%r13),%xmm4
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	xorl	%r10d,%r12d
-	addl	8(%r15),%r9d
-	addb	%dl,%bl
-	movl	64(%rsi),%eax
-	addl	$3299628645,%r9d
-	movzbl	%bl,%ebx
-	addl	%r12d,%r9d
-	movl	%edx,60(%rsi)
-	addb	%al,%cl
-	roll	$23,%r9d
-	movl	$-1,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm4
-	pxor	%xmm1,%xmm4
-	pxor	%xmm0,%xmm0
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	0(%r15),%r8d
-	addb	%dl,%al
-	movl	68(%rsi),%ebx
-	addl	$4096336452,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,64(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	movd	(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	pxor	%xmm1,%xmm1
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	28(%r15),%r11d
-	addb	%dl,%bl
-	movl	72(%rsi),%eax
-	addl	$1126891415,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,68(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	movd	(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	56(%r15),%r10d
-	addb	%dl,%al
-	movl	76(%rsi),%ebx
-	addl	$2878612391,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,72(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$1,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	20(%r15),%r9d
-	addb	%dl,%bl
-	movl	80(%rsi),%eax
-	addl	$4237533241,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,76(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$1,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	48(%r15),%r8d
-	addb	%dl,%al
-	movl	84(%rsi),%ebx
-	addl	$1700485571,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,80(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	pinsrw	$2,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	12(%r15),%r11d
-	addb	%dl,%bl
-	movl	88(%rsi),%eax
-	addl	$2399980690,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,84(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	pinsrw	$2,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	40(%r15),%r10d
-	addb	%dl,%al
-	movl	92(%rsi),%ebx
-	addl	$4293915773,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,88(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$3,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	4(%r15),%r9d
-	addb	%dl,%bl
-	movl	96(%rsi),%eax
-	addl	$2240044497,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,92(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$3,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	32(%r15),%r8d
-	addb	%dl,%al
-	movl	100(%rsi),%ebx
-	addl	$1873313359,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,96(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	pinsrw	$4,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	60(%r15),%r11d
-	addb	%dl,%bl
-	movl	104(%rsi),%eax
-	addl	$4264355552,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,100(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	pinsrw	$4,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	24(%r15),%r10d
-	addb	%dl,%al
-	movl	108(%rsi),%ebx
-	addl	$2734768916,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,104(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$5,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	52(%r15),%r9d
-	addb	%dl,%bl
-	movl	112(%rsi),%eax
-	addl	$1309151649,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,108(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$5,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r11d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r9d,%r12d
-	addl	16(%r15),%r8d
-	addb	%dl,%al
-	movl	116(%rsi),%ebx
-	addl	$4149444226,%r8d
-	movzbl	%al,%eax
-	xorl	%r10d,%r12d
-	movl	%edx,112(%rsi)
-	addl	%r12d,%r8d
-	addb	%bl,%cl
-	roll	$6,%r8d
-	movl	$-1,%r12d
-	pinsrw	$6,(%rdi,%rax,4),%xmm0
-
-	addl	%r9d,%r8d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r10d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r8d,%r12d
-	addl	44(%r15),%r11d
-	addb	%dl,%bl
-	movl	120(%rsi),%eax
-	addl	$3174756917,%r11d
-	movzbl	%bl,%ebx
-	xorl	%r9d,%r12d
-	movl	%edx,116(%rsi)
-	addl	%r12d,%r11d
-	addb	%al,%cl
-	roll	$10,%r11d
-	movl	$-1,%r12d
-	pinsrw	$6,(%rdi,%rbx,4),%xmm1
-
-	addl	%r8d,%r11d
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r9d,%r12d
-	movl	%eax,(%rdi,%rcx,4)
-	orl	%r11d,%r12d
-	addl	8(%r15),%r10d
-	addb	%dl,%al
-	movl	124(%rsi),%ebx
-	addl	$718787259,%r10d
-	movzbl	%al,%eax
-	xorl	%r8d,%r12d
-	movl	%edx,120(%rsi)
-	addl	%r12d,%r10d
-	addb	%bl,%cl
-	roll	$15,%r10d
-	movl	$-1,%r12d
-	pinsrw	$7,(%rdi,%rax,4),%xmm0
-
-	addl	%r11d,%r10d
-	movdqu	48(%r13),%xmm5
-	addb	$32,%bpl
-	movl	(%rdi,%rcx,4),%edx
-	xorl	%r8d,%r12d
-	movl	%ebx,(%rdi,%rcx,4)
-	orl	%r10d,%r12d
-	addl	36(%r15),%r9d
-	addb	%dl,%bl
-	movl	0(%rdi,%rbp,4),%eax
-	addl	$3951481745,%r9d
-	movzbl	%bl,%ebx
-	xorl	%r11d,%r12d
-	movl	%edx,124(%rsi)
-	addl	%r12d,%r9d
-	addb	%al,%cl
-	roll	$21,%r9d
-	movl	$-1,%r12d
-	pinsrw	$7,(%rdi,%rbx,4),%xmm1
-
-	addl	%r10d,%r9d
-	movq	%rbp,%rsi
-	xorq	%rbp,%rbp
-	movb	%sil,%bpl
-	movq	%rcx,%rsi
-	xorq	%rcx,%rcx
-	movb	%sil,%cl
-	leaq	(%rdi,%rbp,4),%rsi
-	psllq	$8,%xmm1
-	pxor	%xmm0,%xmm5
-	pxor	%xmm1,%xmm5
-	addl	0(%rsp),%r8d
-	addl	4(%rsp),%r9d
-	addl	8(%rsp),%r10d
-	addl	12(%rsp),%r11d
-
-	movdqu	%xmm2,(%r14,%r13,1)
-	movdqu	%xmm3,16(%r14,%r13,1)
-	movdqu	%xmm4,32(%r14,%r13,1)
-	movdqu	%xmm5,48(%r14,%r13,1)
-	leaq	64(%r15),%r15
-	leaq	64(%r13),%r13
-	cmpq	16(%rsp),%r15
-	jb	L$oop
-
-	movq	24(%rsp),%r12
-	subb	%al,%cl
-	movl	%r8d,0(%r12)
-	movl	%r9d,4(%r12)
-	movl	%r10d,8(%r12)
-	movl	%r11d,12(%r12)
-	subb	$1,%bpl
-	movl	%ebp,-8(%rdi)
-	movl	%ecx,-4(%rdi)
-
-	movq	40(%rsp),%r15
-	movq	48(%rsp),%r14
-	movq	56(%rsp),%r13
-	movq	64(%rsp),%r12
-	movq	72(%rsp),%rbp
-	movq	80(%rsp),%rbx
-	leaq	88(%rsp),%rsp
-L$epilogue:
-L$abort:
-	.byte	0xf3,0xc3
-
-#endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/sha/sha1-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/sha/sha1-x86_64.S
index 044dc5b..0509d45 100644
--- a/third_party/boringssl/mac-x86_64/crypto/sha/sha1-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/sha/sha1-x86_64.S
@@ -12,6 +12,11 @@
 	movl	_OPENSSL_ia32cap_P+8(%rip),%r10d
 	testl	$512,%r8d
 	jz	L$ialu
+	andl	$268435456,%r8d
+	andl	$1073741824,%r9d
+	orl	%r9d,%r8d
+	cmpl	$1342177280,%r8d
+	je	_avx_shortcut
 	jmp	_ssse3_shortcut
 
 .p2align	4
@@ -2407,6 +2412,1122 @@
 L$epilogue_ssse3:
 	.byte	0xf3,0xc3
 
+
+.p2align	4
+sha1_block_data_order_avx:
+_avx_shortcut:
+	movq	%rsp,%rax
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	leaq	-64(%rsp),%rsp
+	vzeroupper
+	movq	%rax,%r14
+	andq	$-64,%rsp
+	movq	%rdi,%r8
+	movq	%rsi,%r9
+	movq	%rdx,%r10
+
+	shlq	$6,%r10
+	addq	%r9,%r10
+	leaq	K_XX_XX+64(%rip),%r11
+
+	movl	0(%r8),%eax
+	movl	4(%r8),%ebx
+	movl	8(%r8),%ecx
+	movl	12(%r8),%edx
+	movl	%ebx,%esi
+	movl	16(%r8),%ebp
+	movl	%ecx,%edi
+	xorl	%edx,%edi
+	andl	%edi,%esi
+
+	vmovdqa	64(%r11),%xmm6
+	vmovdqa	-64(%r11),%xmm11
+	vmovdqu	0(%r9),%xmm0
+	vmovdqu	16(%r9),%xmm1
+	vmovdqu	32(%r9),%xmm2
+	vmovdqu	48(%r9),%xmm3
+	vpshufb	%xmm6,%xmm0,%xmm0
+	addq	$64,%r9
+	vpshufb	%xmm6,%xmm1,%xmm1
+	vpshufb	%xmm6,%xmm2,%xmm2
+	vpshufb	%xmm6,%xmm3,%xmm3
+	vpaddd	%xmm11,%xmm0,%xmm4
+	vpaddd	%xmm11,%xmm1,%xmm5
+	vpaddd	%xmm11,%xmm2,%xmm6
+	vmovdqa	%xmm4,0(%rsp)
+	vmovdqa	%xmm5,16(%rsp)
+	vmovdqa	%xmm6,32(%rsp)
+	jmp	L$oop_avx
+.p2align	4
+L$oop_avx:
+	shrdl	$2,%ebx,%ebx
+	xorl	%edx,%esi
+	vpalignr	$8,%xmm0,%xmm1,%xmm4
+	movl	%eax,%edi
+	addl	0(%rsp),%ebp
+	vpaddd	%xmm3,%xmm11,%xmm9
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrldq	$4,%xmm3,%xmm8
+	addl	%esi,%ebp
+	andl	%ebx,%edi
+	vpxor	%xmm0,%xmm4,%xmm4
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpxor	%xmm2,%xmm8,%xmm8
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	addl	4(%rsp),%edx
+	vpxor	%xmm8,%xmm4,%xmm4
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	vmovdqa	%xmm9,48(%rsp)
+	addl	%edi,%edx
+	andl	%eax,%esi
+	vpsrld	$31,%xmm4,%xmm8
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%esi
+	vpslldq	$12,%xmm4,%xmm10
+	vpaddd	%xmm4,%xmm4,%xmm4
+	movl	%edx,%edi
+	addl	8(%rsp),%ecx
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm4,%xmm4
+	addl	%esi,%ecx
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm4,%xmm4
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	addl	12(%rsp),%ebx
+	vpxor	%xmm10,%xmm4,%xmm4
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%ebp,%esi
+	vpalignr	$8,%xmm1,%xmm2,%xmm5
+	movl	%ebx,%edi
+	addl	16(%rsp),%eax
+	vpaddd	%xmm4,%xmm11,%xmm9
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrldq	$4,%xmm4,%xmm8
+	addl	%esi,%eax
+	andl	%ecx,%edi
+	vpxor	%xmm1,%xmm5,%xmm5
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm3,%xmm8,%xmm8
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	addl	20(%rsp),%ebp
+	vpxor	%xmm8,%xmm5,%xmm5
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vmovdqa	%xmm9,0(%rsp)
+	addl	%edi,%ebp
+	andl	%ebx,%esi
+	vpsrld	$31,%xmm5,%xmm8
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	vpslldq	$12,%xmm5,%xmm10
+	vpaddd	%xmm5,%xmm5,%xmm5
+	movl	%ebp,%edi
+	addl	24(%rsp),%edx
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm5,%xmm5
+	addl	%esi,%edx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm5,%xmm5
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%edi
+	movl	%edx,%esi
+	addl	28(%rsp),%ecx
+	vpxor	%xmm10,%xmm5,%xmm5
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vmovdqa	-32(%r11),%xmm11
+	addl	%edi,%ecx
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	vpalignr	$8,%xmm2,%xmm3,%xmm6
+	movl	%ecx,%edi
+	addl	32(%rsp),%ebx
+	vpaddd	%xmm5,%xmm11,%xmm9
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	vpsrldq	$4,%xmm5,%xmm8
+	addl	%esi,%ebx
+	andl	%edx,%edi
+	vpxor	%xmm2,%xmm6,%xmm6
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm4,%xmm8,%xmm8
+	shrdl	$7,%ecx,%ecx
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	addl	36(%rsp),%eax
+	vpxor	%xmm8,%xmm6,%xmm6
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vmovdqa	%xmm9,16(%rsp)
+	addl	%edi,%eax
+	andl	%ecx,%esi
+	vpsrld	$31,%xmm6,%xmm8
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%esi
+	vpslldq	$12,%xmm6,%xmm10
+	vpaddd	%xmm6,%xmm6,%xmm6
+	movl	%eax,%edi
+	addl	40(%rsp),%ebp
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm6,%xmm6
+	addl	%esi,%ebp
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm6,%xmm6
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%edi
+	movl	%ebp,%esi
+	addl	44(%rsp),%edx
+	vpxor	%xmm10,%xmm6,%xmm6
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%esi
+	vpalignr	$8,%xmm3,%xmm4,%xmm7
+	movl	%edx,%edi
+	addl	48(%rsp),%ecx
+	vpaddd	%xmm6,%xmm11,%xmm9
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vpsrldq	$4,%xmm6,%xmm8
+	addl	%esi,%ecx
+	andl	%ebp,%edi
+	vpxor	%xmm3,%xmm7,%xmm7
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	vpxor	%xmm5,%xmm8,%xmm8
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%edi
+	movl	%ecx,%esi
+	addl	52(%rsp),%ebx
+	vpxor	%xmm8,%xmm7,%xmm7
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	vmovdqa	%xmm9,32(%rsp)
+	addl	%edi,%ebx
+	andl	%edx,%esi
+	vpsrld	$31,%xmm7,%xmm8
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	shrdl	$7,%ecx,%ecx
+	xorl	%ebp,%esi
+	vpslldq	$12,%xmm7,%xmm10
+	vpaddd	%xmm7,%xmm7,%xmm7
+	movl	%ebx,%edi
+	addl	56(%rsp),%eax
+	xorl	%edx,%ecx
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm10,%xmm9
+	vpor	%xmm8,%xmm7,%xmm7
+	addl	%esi,%eax
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm10,%xmm10
+	vpxor	%xmm9,%xmm7,%xmm7
+	shrdl	$7,%ebx,%ebx
+	xorl	%edx,%edi
+	movl	%eax,%esi
+	addl	60(%rsp),%ebp
+	vpxor	%xmm10,%xmm7,%xmm7
+	xorl	%ecx,%ebx
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	vpxor	%xmm4,%xmm0,%xmm0
+	shrdl	$7,%eax,%eax
+	xorl	%ecx,%esi
+	movl	%ebp,%edi
+	addl	0(%rsp),%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	xorl	%ebx,%eax
+	shldl	$5,%ebp,%ebp
+	vpaddd	%xmm7,%xmm11,%xmm9
+	addl	%esi,%edx
+	andl	%eax,%edi
+	vpxor	%xmm8,%xmm0,%xmm0
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	shrdl	$7,%ebp,%ebp
+	xorl	%ebx,%edi
+	vpsrld	$30,%xmm0,%xmm8
+	vmovdqa	%xmm9,48(%rsp)
+	movl	%edx,%esi
+	addl	4(%rsp),%ecx
+	xorl	%eax,%ebp
+	shldl	$5,%edx,%edx
+	vpslld	$2,%xmm0,%xmm0
+	addl	%edi,%ecx
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	shrdl	$7,%edx,%edx
+	xorl	%eax,%esi
+	movl	%ecx,%edi
+	addl	8(%rsp),%ebx
+	vpor	%xmm8,%xmm0,%xmm0
+	xorl	%ebp,%edx
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	12(%rsp),%eax
+	xorl	%ebp,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	vpxor	%xmm2,%xmm1,%xmm1
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	vpaddd	%xmm0,%xmm11,%xmm9
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpxor	%xmm8,%xmm1,%xmm1
+	addl	20(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	vpsrld	$30,%xmm1,%xmm8
+	vmovdqa	%xmm9,0(%rsp)
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpslld	$2,%xmm1,%xmm1
+	addl	24(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpor	%xmm8,%xmm1,%xmm1
+	addl	28(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	vpxor	%xmm3,%xmm2,%xmm2
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	vpaddd	%xmm1,%xmm11,%xmm9
+	vmovdqa	0(%r11),%xmm11
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpxor	%xmm8,%xmm2,%xmm2
+	addl	36(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	vpsrld	$30,%xmm2,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpslld	$2,%xmm2,%xmm2
+	addl	40(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpor	%xmm8,%xmm2,%xmm2
+	addl	44(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	vpxor	%xmm4,%xmm3,%xmm3
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	vpaddd	%xmm2,%xmm11,%xmm9
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpxor	%xmm8,%xmm3,%xmm3
+	addl	52(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	vpsrld	$30,%xmm3,%xmm8
+	vmovdqa	%xmm9,32(%rsp)
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpor	%xmm8,%xmm3,%xmm3
+	addl	60(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpalignr	$8,%xmm2,%xmm3,%xmm8
+	vpxor	%xmm0,%xmm4,%xmm4
+	addl	0(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	vpxor	%xmm5,%xmm4,%xmm4
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	vpaddd	%xmm3,%xmm11,%xmm9
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpxor	%xmm8,%xmm4,%xmm4
+	addl	4(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	vpsrld	$30,%xmm4,%xmm8
+	vmovdqa	%xmm9,48(%rsp)
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpslld	$2,%xmm4,%xmm4
+	addl	8(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vpor	%xmm8,%xmm4,%xmm4
+	addl	12(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpalignr	$8,%xmm3,%xmm4,%xmm8
+	vpxor	%xmm1,%xmm5,%xmm5
+	addl	16(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	vpxor	%xmm6,%xmm5,%xmm5
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	vpaddd	%xmm4,%xmm11,%xmm9
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpxor	%xmm8,%xmm5,%xmm5
+	addl	20(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	vpsrld	$30,%xmm5,%xmm8
+	vmovdqa	%xmm9,0(%rsp)
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpslld	$2,%xmm5,%xmm5
+	addl	24(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vpor	%xmm8,%xmm5,%xmm5
+	addl	28(%rsp),%eax
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm4,%xmm5,%xmm8
+	vpxor	%xmm2,%xmm6,%xmm6
+	addl	32(%rsp),%ebp
+	andl	%ecx,%esi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%eax,%edi
+	xorl	%ecx,%esi
+	vpaddd	%xmm5,%xmm11,%xmm9
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	vpxor	%xmm8,%xmm6,%xmm6
+	xorl	%ebx,%edi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	addl	36(%rsp),%edx
+	vpsrld	$30,%xmm6,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%ebp,%esi
+	vpslld	$2,%xmm6,%xmm6
+	xorl	%ebx,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	addl	40(%rsp),%ecx
+	andl	%eax,%esi
+	vpor	%xmm8,%xmm6,%xmm6
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	movl	%edx,%edi
+	xorl	%eax,%esi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%ebp,%edi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	addl	44(%rsp),%ebx
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	xorl	%ebp,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	vpalignr	$8,%xmm5,%xmm6,%xmm8
+	vpxor	%xmm3,%xmm7,%xmm7
+	addl	48(%rsp),%eax
+	andl	%edx,%esi
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	vpxor	%xmm0,%xmm7,%xmm7
+	movl	%ebx,%edi
+	xorl	%edx,%esi
+	vpaddd	%xmm6,%xmm11,%xmm9
+	vmovdqa	32(%r11),%xmm11
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vpxor	%xmm8,%xmm7,%xmm7
+	xorl	%ecx,%edi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	52(%rsp),%ebp
+	vpsrld	$30,%xmm7,%xmm8
+	vmovdqa	%xmm9,32(%rsp)
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	vpslld	$2,%xmm7,%xmm7
+	xorl	%ecx,%edi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	addl	56(%rsp),%edx
+	andl	%ebx,%esi
+	vpor	%xmm8,%xmm7,%xmm7
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%ebp,%edi
+	xorl	%ebx,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%eax,%edi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	addl	60(%rsp),%ecx
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	movl	%edx,%esi
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	vpxor	%xmm4,%xmm0,%xmm0
+	addl	0(%rsp),%ebx
+	andl	%ebp,%esi
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	vpxor	%xmm1,%xmm0,%xmm0
+	movl	%ecx,%edi
+	xorl	%ebp,%esi
+	vpaddd	%xmm7,%xmm11,%xmm9
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	vpxor	%xmm8,%xmm0,%xmm0
+	xorl	%edx,%edi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	4(%rsp),%eax
+	vpsrld	$30,%xmm0,%xmm8
+	vmovdqa	%xmm9,48(%rsp)
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	vpslld	$2,%xmm0,%xmm0
+	xorl	%edx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%ecx,%esi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	8(%rsp),%ebp
+	andl	%ecx,%esi
+	vpor	%xmm8,%xmm0,%xmm0
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%edi
+	xorl	%ecx,%esi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ebx,%edi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	addl	12(%rsp),%edx
+	andl	%ebx,%edi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	movl	%ebp,%esi
+	xorl	%ebx,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%eax,%esi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	vpxor	%xmm5,%xmm1,%xmm1
+	addl	16(%rsp),%ecx
+	andl	%eax,%esi
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	vpxor	%xmm2,%xmm1,%xmm1
+	movl	%edx,%edi
+	xorl	%eax,%esi
+	vpaddd	%xmm0,%xmm11,%xmm9
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	vpxor	%xmm8,%xmm1,%xmm1
+	xorl	%ebp,%edi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	addl	20(%rsp),%ebx
+	vpsrld	$30,%xmm1,%xmm8
+	vmovdqa	%xmm9,0(%rsp)
+	andl	%ebp,%edi
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%esi
+	vpslld	$2,%xmm1,%xmm1
+	xorl	%ebp,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%edx,%esi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	24(%rsp),%eax
+	andl	%edx,%esi
+	vpor	%xmm8,%xmm1,%xmm1
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%edi
+	xorl	%edx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%ecx,%edi
+	xorl	%edx,%ecx
+	addl	%ebx,%eax
+	addl	28(%rsp),%ebp
+	andl	%ecx,%edi
+	xorl	%edx,%ecx
+	shrdl	$7,%ebx,%ebx
+	movl	%eax,%esi
+	xorl	%ecx,%edi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ebx,%esi
+	xorl	%ecx,%ebx
+	addl	%eax,%ebp
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	vpxor	%xmm6,%xmm2,%xmm2
+	addl	32(%rsp),%edx
+	andl	%ebx,%esi
+	xorl	%ecx,%ebx
+	shrdl	$7,%eax,%eax
+	vpxor	%xmm3,%xmm2,%xmm2
+	movl	%ebp,%edi
+	xorl	%ebx,%esi
+	vpaddd	%xmm1,%xmm11,%xmm9
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	vpxor	%xmm8,%xmm2,%xmm2
+	xorl	%eax,%edi
+	xorl	%ebx,%eax
+	addl	%ebp,%edx
+	addl	36(%rsp),%ecx
+	vpsrld	$30,%xmm2,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	andl	%eax,%edi
+	xorl	%ebx,%eax
+	shrdl	$7,%ebp,%ebp
+	movl	%edx,%esi
+	vpslld	$2,%xmm2,%xmm2
+	xorl	%eax,%edi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%ebp,%esi
+	xorl	%eax,%ebp
+	addl	%edx,%ecx
+	addl	40(%rsp),%ebx
+	andl	%ebp,%esi
+	vpor	%xmm8,%xmm2,%xmm2
+	xorl	%eax,%ebp
+	shrdl	$7,%edx,%edx
+	movl	%ecx,%edi
+	xorl	%ebp,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%edx,%edi
+	xorl	%ebp,%edx
+	addl	%ecx,%ebx
+	addl	44(%rsp),%eax
+	andl	%edx,%edi
+	xorl	%ebp,%edx
+	shrdl	$7,%ecx,%ecx
+	movl	%ebx,%esi
+	xorl	%edx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	addl	%ebx,%eax
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	vpxor	%xmm7,%xmm3,%xmm3
+	addl	48(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	vpxor	%xmm4,%xmm3,%xmm3
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	vpaddd	%xmm2,%xmm11,%xmm9
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	vpxor	%xmm8,%xmm3,%xmm3
+	addl	52(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	vpsrld	$30,%xmm3,%xmm8
+	vmovdqa	%xmm9,32(%rsp)
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vpslld	$2,%xmm3,%xmm3
+	addl	56(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vpor	%xmm8,%xmm3,%xmm3
+	addl	60(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	0(%rsp),%eax
+	vpaddd	%xmm3,%xmm11,%xmm9
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	vmovdqa	%xmm9,48(%rsp)
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	4(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	8(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	12(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	cmpq	%r10,%r9
+	je	L$done_avx
+	vmovdqa	64(%r11),%xmm6
+	vmovdqa	-64(%r11),%xmm11
+	vmovdqu	0(%r9),%xmm0
+	vmovdqu	16(%r9),%xmm1
+	vmovdqu	32(%r9),%xmm2
+	vmovdqu	48(%r9),%xmm3
+	vpshufb	%xmm6,%xmm0,%xmm0
+	addq	$64,%r9
+	addl	16(%rsp),%ebx
+	xorl	%ebp,%esi
+	vpshufb	%xmm6,%xmm1,%xmm1
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	vpaddd	%xmm11,%xmm0,%xmm4
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	vmovdqa	%xmm4,0(%rsp)
+	addl	20(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	32(%rsp),%ecx
+	xorl	%eax,%esi
+	vpshufb	%xmm6,%xmm2,%xmm2
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	vpaddd	%xmm11,%xmm1,%xmm5
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	vmovdqa	%xmm5,16(%rsp)
+	addl	36(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ebx,%esi
+	vpshufb	%xmm6,%xmm3,%xmm3
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	vpaddd	%xmm11,%xmm2,%xmm6
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	vmovdqa	%xmm6,32(%rsp)
+	addl	52(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	addl	12(%r8),%edx
+	movl	%eax,0(%r8)
+	addl	16(%r8),%ebp
+	movl	%esi,4(%r8)
+	movl	%esi,%ebx
+	movl	%ecx,8(%r8)
+	movl	%ecx,%edi
+	movl	%edx,12(%r8)
+	xorl	%edx,%edi
+	movl	%ebp,16(%r8)
+	andl	%edi,%esi
+	jmp	L$oop_avx
+
+.p2align	4
+L$done_avx:
+	addl	16(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	20(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	xorl	%edx,%esi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	24(%rsp),%ebp
+	xorl	%ecx,%esi
+	movl	%eax,%edi
+	shldl	$5,%eax,%eax
+	addl	%esi,%ebp
+	xorl	%ecx,%edi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	28(%rsp),%edx
+	xorl	%ebx,%edi
+	movl	%ebp,%esi
+	shldl	$5,%ebp,%ebp
+	addl	%edi,%edx
+	xorl	%ebx,%esi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	32(%rsp),%ecx
+	xorl	%eax,%esi
+	movl	%edx,%edi
+	shldl	$5,%edx,%edx
+	addl	%esi,%ecx
+	xorl	%eax,%edi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	addl	36(%rsp),%ebx
+	xorl	%ebp,%edi
+	movl	%ecx,%esi
+	shldl	$5,%ecx,%ecx
+	addl	%edi,%ebx
+	xorl	%ebp,%esi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	40(%rsp),%eax
+	xorl	%edx,%esi
+	movl	%ebx,%edi
+	shldl	$5,%ebx,%ebx
+	addl	%esi,%eax
+	xorl	%edx,%edi
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	addl	44(%rsp),%ebp
+	xorl	%ecx,%edi
+	movl	%eax,%esi
+	shldl	$5,%eax,%eax
+	addl	%edi,%ebp
+	xorl	%ecx,%esi
+	shrdl	$7,%ebx,%ebx
+	addl	%eax,%ebp
+	addl	48(%rsp),%edx
+	xorl	%ebx,%esi
+	movl	%ebp,%edi
+	shldl	$5,%ebp,%ebp
+	addl	%esi,%edx
+	xorl	%ebx,%edi
+	shrdl	$7,%eax,%eax
+	addl	%ebp,%edx
+	addl	52(%rsp),%ecx
+	xorl	%eax,%edi
+	movl	%edx,%esi
+	shldl	$5,%edx,%edx
+	addl	%edi,%ecx
+	xorl	%eax,%esi
+	shrdl	$7,%ebp,%ebp
+	addl	%edx,%ecx
+	addl	56(%rsp),%ebx
+	xorl	%ebp,%esi
+	movl	%ecx,%edi
+	shldl	$5,%ecx,%ecx
+	addl	%esi,%ebx
+	xorl	%ebp,%edi
+	shrdl	$7,%edx,%edx
+	addl	%ecx,%ebx
+	addl	60(%rsp),%eax
+	xorl	%edx,%edi
+	movl	%ebx,%esi
+	shldl	$5,%ebx,%ebx
+	addl	%edi,%eax
+	shrdl	$7,%ecx,%ecx
+	addl	%ebx,%eax
+	vzeroupper
+
+	addl	0(%r8),%eax
+	addl	4(%r8),%esi
+	addl	8(%r8),%ecx
+	movl	%eax,0(%r8)
+	addl	12(%r8),%edx
+	movl	%esi,4(%r8)
+	addl	16(%r8),%ebp
+	movl	%ecx,8(%r8)
+	movl	%edx,12(%r8)
+	movl	%ebp,16(%r8)
+	leaq	(%r14),%rsi
+	movq	-40(%rsi),%r14
+	movq	-32(%rsi),%r13
+	movq	-24(%rsi),%r12
+	movq	-16(%rsi),%rbp
+	movq	-8(%rsi),%rbx
+	leaq	(%rsi),%rsp
+L$epilogue_avx:
+	.byte	0xf3,0xc3
+
 .p2align	6
 K_XX_XX:
 .long	0x5a827999,0x5a827999,0x5a827999,0x5a827999
diff --git a/third_party/boringssl/mac-x86_64/crypto/sha/sha256-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/sha/sha256-x86_64.S
index da02d4c..0146ff5 100644
--- a/third_party/boringssl/mac-x86_64/crypto/sha/sha256-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/sha/sha256-x86_64.S
@@ -11,6 +11,11 @@
 	movl	0(%r11),%r9d
 	movl	4(%r11),%r10d
 	movl	8(%r11),%r11d
+	andl	$1073741824,%r9d
+	andl	$268435968,%r10d
+	orl	%r9d,%r10d
+	cmpl	$1342177792,%r10d
+	je	L$avx_shortcut
 	testl	$512,%r10d
 	jnz	L$ssse3_shortcut
 	pushq	%rbx
@@ -2840,4 +2845,1061 @@
 L$epilogue_ssse3:
 	.byte	0xf3,0xc3
 
+
+.p2align	6
+sha256_block_data_order_avx:
+L$avx_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$96,%rsp
+	leaq	(%rsi,%rdx,4),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,64+0(%rsp)
+	movq	%rsi,64+8(%rsp)
+	movq	%rdx,64+16(%rsp)
+	movq	%r11,64+24(%rsp)
+L$prologue_avx:
+
+	vzeroupper
+	movl	0(%rdi),%eax
+	movl	4(%rdi),%ebx
+	movl	8(%rdi),%ecx
+	movl	12(%rdi),%edx
+	movl	16(%rdi),%r8d
+	movl	20(%rdi),%r9d
+	movl	24(%rdi),%r10d
+	movl	28(%rdi),%r11d
+	vmovdqa	K256+512+32(%rip),%xmm8
+	vmovdqa	K256+512+64(%rip),%xmm9
+	jmp	L$loop_avx
+.p2align	4
+L$loop_avx:
+	vmovdqa	K256+512(%rip),%xmm7
+	vmovdqu	0(%rsi),%xmm0
+	vmovdqu	16(%rsi),%xmm1
+	vmovdqu	32(%rsi),%xmm2
+	vmovdqu	48(%rsi),%xmm3
+	vpshufb	%xmm7,%xmm0,%xmm0
+	leaq	K256(%rip),%rbp
+	vpshufb	%xmm7,%xmm1,%xmm1
+	vpshufb	%xmm7,%xmm2,%xmm2
+	vpaddd	0(%rbp),%xmm0,%xmm4
+	vpshufb	%xmm7,%xmm3,%xmm3
+	vpaddd	32(%rbp),%xmm1,%xmm5
+	vpaddd	64(%rbp),%xmm2,%xmm6
+	vpaddd	96(%rbp),%xmm3,%xmm7
+	vmovdqa	%xmm4,0(%rsp)
+	movl	%eax,%r14d
+	vmovdqa	%xmm5,16(%rsp)
+	movl	%ebx,%edi
+	vmovdqa	%xmm6,32(%rsp)
+	xorl	%ecx,%edi
+	vmovdqa	%xmm7,48(%rsp)
+	movl	%r8d,%r13d
+	jmp	L$avx_00_47
+
+.p2align	4
+L$avx_00_47:
+	subq	$-128,%rbp
+	vpalignr	$4,%xmm0,%xmm1,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	vpalignr	$4,%xmm2,%xmm3,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	vpaddd	%xmm7,%xmm0,%xmm0
+	xorl	%r8d,%r13d
+	addl	0(%rsp),%r11d
+	movl	%eax,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	vpshufd	$250,%xmm3,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	4(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	vpaddd	%xmm4,%xmm0,%xmm0
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	vpaddd	%xmm6,%xmm0,%xmm0
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	8(%rsp),%r9d
+	vpshufd	$80,%xmm0,%xmm7
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	vpaddd	%xmm6,%xmm0,%xmm0
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	vpaddd	0(%rbp),%xmm0,%xmm6
+	xorl	%ebx,%r13d
+	addl	12(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	vmovdqa	%xmm6,0(%rsp)
+	vpalignr	$4,%xmm1,%xmm2,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	vpalignr	$4,%xmm3,%xmm0,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	vpaddd	%xmm7,%xmm1,%xmm1
+	xorl	%eax,%r13d
+	addl	16(%rsp),%edx
+	movl	%r8d,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	vpshufd	$250,%xmm0,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	20(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	vpaddd	%xmm4,%xmm1,%xmm1
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	vpaddd	%xmm6,%xmm1,%xmm1
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	24(%rsp),%ebx
+	vpshufd	$80,%xmm1,%xmm7
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	vpaddd	%xmm6,%xmm1,%xmm1
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	vpaddd	32(%rbp),%xmm1,%xmm6
+	xorl	%r9d,%r13d
+	addl	28(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	vmovdqa	%xmm6,16(%rsp)
+	vpalignr	$4,%xmm2,%xmm3,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	vpalignr	$4,%xmm0,%xmm1,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	vpaddd	%xmm7,%xmm2,%xmm2
+	xorl	%r8d,%r13d
+	addl	32(%rsp),%r11d
+	movl	%eax,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	vpshufd	$250,%xmm1,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	36(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	vpaddd	%xmm4,%xmm2,%xmm2
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	vpaddd	%xmm6,%xmm2,%xmm2
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	40(%rsp),%r9d
+	vpshufd	$80,%xmm2,%xmm7
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	vpaddd	%xmm6,%xmm2,%xmm2
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	vpaddd	64(%rbp),%xmm2,%xmm6
+	xorl	%ebx,%r13d
+	addl	44(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	vmovdqa	%xmm6,32(%rsp)
+	vpalignr	$4,%xmm3,%xmm0,%xmm4
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	vpalignr	$4,%xmm1,%xmm2,%xmm7
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	vpsrld	$7,%xmm4,%xmm6
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	vpaddd	%xmm7,%xmm3,%xmm3
+	xorl	%eax,%r13d
+	addl	48(%rsp),%edx
+	movl	%r8d,%r15d
+	vpsrld	$3,%xmm4,%xmm7
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	vpslld	$14,%xmm4,%xmm5
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	vpxor	%xmm6,%xmm7,%xmm4
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	vpshufd	$250,%xmm2,%xmm7
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	vpsrld	$11,%xmm6,%xmm6
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	vpxor	%xmm5,%xmm4,%xmm4
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	vpslld	$11,%xmm5,%xmm5
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	vpxor	%xmm6,%xmm4,%xmm4
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	vpsrld	$10,%xmm7,%xmm6
+	addl	52(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	vpxor	%xmm5,%xmm4,%xmm4
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	vpsrlq	$17,%xmm7,%xmm7
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	vpaddd	%xmm4,%xmm3,%xmm3
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	vpxor	%xmm7,%xmm6,%xmm6
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	vpshufb	%xmm8,%xmm6,%xmm6
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	vpaddd	%xmm6,%xmm3,%xmm3
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	56(%rsp),%ebx
+	vpshufd	$80,%xmm3,%xmm7
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	vpsrld	$10,%xmm7,%xmm6
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	vpsrlq	$17,%xmm7,%xmm7
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	vpxor	%xmm7,%xmm6,%xmm6
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	vpsrlq	$2,%xmm7,%xmm7
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	vpxor	%xmm7,%xmm6,%xmm6
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	vpshufb	%xmm9,%xmm6,%xmm6
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	vpaddd	%xmm6,%xmm3,%xmm3
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	vpaddd	96(%rbp),%xmm3,%xmm6
+	xorl	%r9d,%r13d
+	addl	60(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	vmovdqa	%xmm6,48(%rsp)
+	cmpb	$0,131(%rbp)
+	jne	L$avx_00_47
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	xorl	%r8d,%r13d
+	addl	0(%rsp),%r11d
+	movl	%eax,%r15d
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	addl	4(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	8(%rsp),%r9d
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	xorl	%ebx,%r13d
+	addl	12(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	xorl	%eax,%r13d
+	addl	16(%rsp),%edx
+	movl	%r8d,%r15d
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	addl	20(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	24(%rsp),%ebx
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	xorl	%r9d,%r13d
+	addl	28(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%eax
+	movl	%r9d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r8d,%r13d
+	xorl	%r10d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%eax,%r14d
+	andl	%r8d,%r12d
+	xorl	%r8d,%r13d
+	addl	32(%rsp),%r11d
+	movl	%eax,%r15d
+	xorl	%r10d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ebx,%r15d
+	addl	%r12d,%r11d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%eax,%r14d
+	addl	%r13d,%r11d
+	xorl	%ebx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r11d,%edx
+	addl	%edi,%r11d
+	movl	%edx,%r13d
+	addl	%r11d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r11d
+	movl	%r8d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%edx,%r13d
+	xorl	%r9d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r11d,%r14d
+	andl	%edx,%r12d
+	xorl	%edx,%r13d
+	addl	36(%rsp),%r10d
+	movl	%r11d,%edi
+	xorl	%r9d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%eax,%edi
+	addl	%r12d,%r10d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r11d,%r14d
+	addl	%r13d,%r10d
+	xorl	%eax,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r10d,%ecx
+	addl	%r15d,%r10d
+	movl	%ecx,%r13d
+	addl	%r10d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r10d
+	movl	%edx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ecx,%r13d
+	xorl	%r8d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r10d,%r14d
+	andl	%ecx,%r12d
+	xorl	%ecx,%r13d
+	addl	40(%rsp),%r9d
+	movl	%r10d,%r15d
+	xorl	%r8d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r11d,%r15d
+	addl	%r12d,%r9d
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r10d,%r14d
+	addl	%r13d,%r9d
+	xorl	%r11d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%r9d,%ebx
+	addl	%edi,%r9d
+	movl	%ebx,%r13d
+	addl	%r9d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r9d
+	movl	%ecx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%ebx,%r13d
+	xorl	%edx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r9d,%r14d
+	andl	%ebx,%r12d
+	xorl	%ebx,%r13d
+	addl	44(%rsp),%r8d
+	movl	%r9d,%edi
+	xorl	%edx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r10d,%edi
+	addl	%r12d,%r8d
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%r9d,%r14d
+	addl	%r13d,%r8d
+	xorl	%r10d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%r8d,%eax
+	addl	%r15d,%r8d
+	movl	%eax,%r13d
+	addl	%r8d,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%r8d
+	movl	%ebx,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%eax,%r13d
+	xorl	%ecx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%r8d,%r14d
+	andl	%eax,%r12d
+	xorl	%eax,%r13d
+	addl	48(%rsp),%edx
+	movl	%r8d,%r15d
+	xorl	%ecx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r9d,%r15d
+	addl	%r12d,%edx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%r8d,%r14d
+	addl	%r13d,%edx
+	xorl	%r9d,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%edx,%r11d
+	addl	%edi,%edx
+	movl	%r11d,%r13d
+	addl	%edx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%edx
+	movl	%eax,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r11d,%r13d
+	xorl	%ebx,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%edx,%r14d
+	andl	%r11d,%r12d
+	xorl	%r11d,%r13d
+	addl	52(%rsp),%ecx
+	movl	%edx,%edi
+	xorl	%ebx,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%r8d,%edi
+	addl	%r12d,%ecx
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%edx,%r14d
+	addl	%r13d,%ecx
+	xorl	%r8d,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%ecx,%r10d
+	addl	%r15d,%ecx
+	movl	%r10d,%r13d
+	addl	%ecx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ecx
+	movl	%r11d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r10d,%r13d
+	xorl	%eax,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ecx,%r14d
+	andl	%r10d,%r12d
+	xorl	%r10d,%r13d
+	addl	56(%rsp),%ebx
+	movl	%ecx,%r15d
+	xorl	%eax,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%edx,%r15d
+	addl	%r12d,%ebx
+	shrdl	$6,%r13d,%r13d
+	andl	%r15d,%edi
+	xorl	%ecx,%r14d
+	addl	%r13d,%ebx
+	xorl	%edx,%edi
+	shrdl	$2,%r14d,%r14d
+	addl	%ebx,%r9d
+	addl	%edi,%ebx
+	movl	%r9d,%r13d
+	addl	%ebx,%r14d
+	shrdl	$14,%r13d,%r13d
+	movl	%r14d,%ebx
+	movl	%r10d,%r12d
+	shrdl	$9,%r14d,%r14d
+	xorl	%r9d,%r13d
+	xorl	%r11d,%r12d
+	shrdl	$5,%r13d,%r13d
+	xorl	%ebx,%r14d
+	andl	%r9d,%r12d
+	xorl	%r9d,%r13d
+	addl	60(%rsp),%eax
+	movl	%ebx,%edi
+	xorl	%r11d,%r12d
+	shrdl	$11,%r14d,%r14d
+	xorl	%ecx,%edi
+	addl	%r12d,%eax
+	shrdl	$6,%r13d,%r13d
+	andl	%edi,%r15d
+	xorl	%ebx,%r14d
+	addl	%r13d,%eax
+	xorl	%ecx,%r15d
+	shrdl	$2,%r14d,%r14d
+	addl	%eax,%r8d
+	addl	%r15d,%eax
+	movl	%r8d,%r13d
+	addl	%eax,%r14d
+	movq	64+0(%rsp),%rdi
+	movl	%r14d,%eax
+
+	addl	0(%rdi),%eax
+	leaq	64(%rsi),%rsi
+	addl	4(%rdi),%ebx
+	addl	8(%rdi),%ecx
+	addl	12(%rdi),%edx
+	addl	16(%rdi),%r8d
+	addl	20(%rdi),%r9d
+	addl	24(%rdi),%r10d
+	addl	28(%rdi),%r11d
+
+	cmpq	64+16(%rsp),%rsi
+
+	movl	%eax,0(%rdi)
+	movl	%ebx,4(%rdi)
+	movl	%ecx,8(%rdi)
+	movl	%edx,12(%rdi)
+	movl	%r8d,16(%rdi)
+	movl	%r9d,20(%rdi)
+	movl	%r10d,24(%rdi)
+	movl	%r11d,28(%rdi)
+	jb	L$loop_avx
+
+	movq	64+24(%rsp),%rsi
+	vzeroupper
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$epilogue_avx:
+	.byte	0xf3,0xc3
+
 #endif
diff --git a/third_party/boringssl/mac-x86_64/crypto/sha/sha512-x86_64.S b/third_party/boringssl/mac-x86_64/crypto/sha/sha512-x86_64.S
index 2f5d912..aeabd3f 100644
--- a/third_party/boringssl/mac-x86_64/crypto/sha/sha512-x86_64.S
+++ b/third_party/boringssl/mac-x86_64/crypto/sha/sha512-x86_64.S
@@ -7,6 +7,17 @@
 
 .p2align	4
 _sha512_block_data_order:
+	leaq	_OPENSSL_ia32cap_P(%rip),%r11
+	movl	0(%r11),%r9d
+	movl	4(%r11),%r10d
+	movl	8(%r11),%r11d
+	testl	$2048,%r10d
+	jnz	L$xop_shortcut
+	andl	$1073741824,%r9d
+	andl	$268435968,%r10d
+	orl	%r9d,%r10d
+	cmpl	$1342177792,%r10d
+	je	L$avx_shortcut
 	pushq	%rbx
 	pushq	%rbp
 	pushq	%r12
@@ -1783,4 +1794,2234 @@
 .quad	0x0001020304050607,0x08090a0b0c0d0e0f
 .quad	0x0001020304050607,0x08090a0b0c0d0e0f
 .byte	83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+
+.p2align	6
+sha512_block_data_order_xop:
+L$xop_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$160,%rsp
+	leaq	(%rsi,%rdx,8),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,128+0(%rsp)
+	movq	%rsi,128+8(%rsp)
+	movq	%rdx,128+16(%rsp)
+	movq	%r11,128+24(%rsp)
+L$prologue_xop:
+
+	vzeroupper
+	movq	0(%rdi),%rax
+	movq	8(%rdi),%rbx
+	movq	16(%rdi),%rcx
+	movq	24(%rdi),%rdx
+	movq	32(%rdi),%r8
+	movq	40(%rdi),%r9
+	movq	48(%rdi),%r10
+	movq	56(%rdi),%r11
+	jmp	L$loop_xop
+.p2align	4
+L$loop_xop:
+	vmovdqa	K512+1280(%rip),%xmm11
+	vmovdqu	0(%rsi),%xmm0
+	leaq	K512+128(%rip),%rbp
+	vmovdqu	16(%rsi),%xmm1
+	vmovdqu	32(%rsi),%xmm2
+	vpshufb	%xmm11,%xmm0,%xmm0
+	vmovdqu	48(%rsi),%xmm3
+	vpshufb	%xmm11,%xmm1,%xmm1
+	vmovdqu	64(%rsi),%xmm4
+	vpshufb	%xmm11,%xmm2,%xmm2
+	vmovdqu	80(%rsi),%xmm5
+	vpshufb	%xmm11,%xmm3,%xmm3
+	vmovdqu	96(%rsi),%xmm6
+	vpshufb	%xmm11,%xmm4,%xmm4
+	vmovdqu	112(%rsi),%xmm7
+	vpshufb	%xmm11,%xmm5,%xmm5
+	vpaddq	-128(%rbp),%xmm0,%xmm8
+	vpshufb	%xmm11,%xmm6,%xmm6
+	vpaddq	-96(%rbp),%xmm1,%xmm9
+	vpshufb	%xmm11,%xmm7,%xmm7
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	vpaddq	-32(%rbp),%xmm3,%xmm11
+	vmovdqa	%xmm8,0(%rsp)
+	vpaddq	0(%rbp),%xmm4,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	vpaddq	32(%rbp),%xmm5,%xmm9
+	vmovdqa	%xmm10,32(%rsp)
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	vmovdqa	%xmm11,48(%rsp)
+	vpaddq	96(%rbp),%xmm7,%xmm11
+	vmovdqa	%xmm8,64(%rsp)
+	movq	%rax,%r14
+	vmovdqa	%xmm9,80(%rsp)
+	movq	%rbx,%rdi
+	vmovdqa	%xmm10,96(%rsp)
+	xorq	%rcx,%rdi
+	vmovdqa	%xmm11,112(%rsp)
+	movq	%r8,%r13
+	jmp	L$xop_00_47
+
+.p2align	4
+L$xop_00_47:
+	addq	$256,%rbp
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm4,%xmm5,%xmm11
+	movq	%r9,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	vpaddq	%xmm11,%xmm0,%xmm0
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,223,3
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm7,%xmm10
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpaddq	%xmm8,%xmm0,%xmm0
+	movq	%rdx,%r13
+	addq	%r11,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r11
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpaddq	%xmm11,%xmm0,%xmm0
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	vpaddq	-128(%rbp),%xmm0,%xmm10
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,0(%rsp)
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm5,%xmm6,%xmm11
+	movq	%rdx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	vpaddq	%xmm11,%xmm1,%xmm1
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,216,3
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm0,%xmm10
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpaddq	%xmm8,%xmm1,%xmm1
+	movq	%rbx,%r13
+	addq	%r9,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r9
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpaddq	%xmm11,%xmm1,%xmm1
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	vpaddq	-96(%rbp),%xmm1,%xmm10
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,16(%rsp)
+	vpalignr	$8,%xmm2,%xmm3,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm6,%xmm7,%xmm11
+	movq	%rbx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	vpaddq	%xmm11,%xmm2,%xmm2
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,217,3
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm1,%xmm10
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpaddq	%xmm8,%xmm2,%xmm2
+	movq	%r11,%r13
+	addq	%rdx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpaddq	%xmm11,%xmm2,%xmm2
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,32(%rsp)
+	vpalignr	$8,%xmm3,%xmm4,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm7,%xmm0,%xmm11
+	movq	%r11,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	vpaddq	%xmm11,%xmm3,%xmm3
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,218,3
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm2,%xmm10
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpaddq	%xmm8,%xmm3,%xmm3
+	movq	%r9,%r13
+	addq	%rbx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpaddq	%xmm11,%xmm3,%xmm3
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	vpaddq	-32(%rbp),%xmm3,%xmm10
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,48(%rsp)
+	vpalignr	$8,%xmm4,%xmm5,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm0,%xmm1,%xmm11
+	movq	%r9,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	vpaddq	%xmm11,%xmm4,%xmm4
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,219,3
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm3,%xmm10
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpaddq	%xmm8,%xmm4,%xmm4
+	movq	%rdx,%r13
+	addq	%r11,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r11
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpaddq	%xmm11,%xmm4,%xmm4
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	vpaddq	0(%rbp),%xmm4,%xmm10
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,64(%rsp)
+	vpalignr	$8,%xmm5,%xmm6,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm1,%xmm2,%xmm11
+	movq	%rdx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	vpaddq	%xmm11,%xmm5,%xmm5
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+.byte	143,72,120,195,209,7
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,220,3
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm4,%xmm10
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpaddq	%xmm8,%xmm5,%xmm5
+	movq	%rbx,%r13
+	addq	%r9,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%r9
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpaddq	%xmm11,%xmm5,%xmm5
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	vpaddq	32(%rbp),%xmm5,%xmm10
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,80(%rsp)
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm2,%xmm3,%xmm11
+	movq	%rbx,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	vpaddq	%xmm11,%xmm6,%xmm6
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,221,3
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm5,%xmm10
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpaddq	%xmm8,%xmm6,%xmm6
+	movq	%r11,%r13
+	addq	%rdx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpaddq	%xmm11,%xmm6,%xmm6
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,96(%rsp)
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm3,%xmm4,%xmm11
+	movq	%r11,%r12
+	rorq	$5,%r14
+.byte	143,72,120,195,200,56
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpsrlq	$7,%xmm8,%xmm8
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	vpaddq	%xmm11,%xmm7,%xmm7
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+.byte	143,72,120,195,209,7
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	vpxor	%xmm9,%xmm8,%xmm8
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+.byte	143,104,120,195,222,3
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	vpsrlq	$6,%xmm6,%xmm10
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpaddq	%xmm8,%xmm7,%xmm7
+	movq	%r9,%r13
+	addq	%rbx,%r14
+.byte	143,72,120,195,203,42
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	vpxor	%xmm10,%xmm11,%xmm11
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm9,%xmm11,%xmm11
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpaddq	%xmm11,%xmm7,%xmm7
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	vpaddq	96(%rbp),%xmm7,%xmm10
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,112(%rsp)
+	cmpb	$0,135(%rbp)
+	jne	L$xop_00_47
+	rorq	$23,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	rorq	$23,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	rorq	$23,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	rorq	$23,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	rorq	$23,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	rorq	$5,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	rorq	$4,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	rorq	$6,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	rorq	$28,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	rorq	$23,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	rorq	$5,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	rorq	$4,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	rorq	$6,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	rorq	$28,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	rorq	$23,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	rorq	$5,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	rorq	$4,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	rorq	$6,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	rorq	$28,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	rorq	$23,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	rorq	$5,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	rorq	$4,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	rorq	$6,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	rorq	$28,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	rorq	$23,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	rorq	$5,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	rorq	$4,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	rorq	$6,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	rorq	$28,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	rorq	$5,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	rorq	$4,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	rorq	$6,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	rorq	$28,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	rorq	$5,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	rorq	$4,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	rorq	$6,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	rorq	$14,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	rorq	$28,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	rorq	$23,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	rorq	$5,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	rorq	$4,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	rorq	$6,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	rorq	$14,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	rorq	$28,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	movq	128+0(%rsp),%rdi
+	movq	%r14,%rax
+
+	addq	0(%rdi),%rax
+	leaq	128(%rsi),%rsi
+	addq	8(%rdi),%rbx
+	addq	16(%rdi),%rcx
+	addq	24(%rdi),%rdx
+	addq	32(%rdi),%r8
+	addq	40(%rdi),%r9
+	addq	48(%rdi),%r10
+	addq	56(%rdi),%r11
+
+	cmpq	128+16(%rsp),%rsi
+
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+	movq	%r8,32(%rdi)
+	movq	%r9,40(%rdi)
+	movq	%r10,48(%rdi)
+	movq	%r11,56(%rdi)
+	jb	L$loop_xop
+
+	movq	128+24(%rsp),%rsi
+	vzeroupper
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$epilogue_xop:
+	.byte	0xf3,0xc3
+
+
+.p2align	6
+sha512_block_data_order_avx:
+L$avx_shortcut:
+	pushq	%rbx
+	pushq	%rbp
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	pushq	%r15
+	movq	%rsp,%r11
+	shlq	$4,%rdx
+	subq	$160,%rsp
+	leaq	(%rsi,%rdx,8),%rdx
+	andq	$-64,%rsp
+	movq	%rdi,128+0(%rsp)
+	movq	%rsi,128+8(%rsp)
+	movq	%rdx,128+16(%rsp)
+	movq	%r11,128+24(%rsp)
+L$prologue_avx:
+
+	vzeroupper
+	movq	0(%rdi),%rax
+	movq	8(%rdi),%rbx
+	movq	16(%rdi),%rcx
+	movq	24(%rdi),%rdx
+	movq	32(%rdi),%r8
+	movq	40(%rdi),%r9
+	movq	48(%rdi),%r10
+	movq	56(%rdi),%r11
+	jmp	L$loop_avx
+.p2align	4
+L$loop_avx:
+	vmovdqa	K512+1280(%rip),%xmm11
+	vmovdqu	0(%rsi),%xmm0
+	leaq	K512+128(%rip),%rbp
+	vmovdqu	16(%rsi),%xmm1
+	vmovdqu	32(%rsi),%xmm2
+	vpshufb	%xmm11,%xmm0,%xmm0
+	vmovdqu	48(%rsi),%xmm3
+	vpshufb	%xmm11,%xmm1,%xmm1
+	vmovdqu	64(%rsi),%xmm4
+	vpshufb	%xmm11,%xmm2,%xmm2
+	vmovdqu	80(%rsi),%xmm5
+	vpshufb	%xmm11,%xmm3,%xmm3
+	vmovdqu	96(%rsi),%xmm6
+	vpshufb	%xmm11,%xmm4,%xmm4
+	vmovdqu	112(%rsi),%xmm7
+	vpshufb	%xmm11,%xmm5,%xmm5
+	vpaddq	-128(%rbp),%xmm0,%xmm8
+	vpshufb	%xmm11,%xmm6,%xmm6
+	vpaddq	-96(%rbp),%xmm1,%xmm9
+	vpshufb	%xmm11,%xmm7,%xmm7
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	vpaddq	-32(%rbp),%xmm3,%xmm11
+	vmovdqa	%xmm8,0(%rsp)
+	vpaddq	0(%rbp),%xmm4,%xmm8
+	vmovdqa	%xmm9,16(%rsp)
+	vpaddq	32(%rbp),%xmm5,%xmm9
+	vmovdqa	%xmm10,32(%rsp)
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	vmovdqa	%xmm11,48(%rsp)
+	vpaddq	96(%rbp),%xmm7,%xmm11
+	vmovdqa	%xmm8,64(%rsp)
+	movq	%rax,%r14
+	vmovdqa	%xmm9,80(%rsp)
+	movq	%rbx,%rdi
+	vmovdqa	%xmm10,96(%rsp)
+	xorq	%rcx,%rdi
+	vmovdqa	%xmm11,112(%rsp)
+	movq	%r8,%r13
+	jmp	L$avx_00_47
+
+.p2align	4
+L$avx_00_47:
+	addq	$256,%rbp
+	vpalignr	$8,%xmm0,%xmm1,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm4,%xmm5,%xmm11
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpaddq	%xmm11,%xmm0,%xmm0
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm7,%xmm11
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	vpsllq	$3,%xmm7,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	vpaddq	%xmm8,%xmm0,%xmm0
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm7,%xmm9
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm0,%xmm0
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	vpaddq	-128(%rbp),%xmm0,%xmm10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,0(%rsp)
+	vpalignr	$8,%xmm1,%xmm2,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm5,%xmm6,%xmm11
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpaddq	%xmm11,%xmm1,%xmm1
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm0,%xmm11
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	vpsllq	$3,%xmm0,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	vpaddq	%xmm8,%xmm1,%xmm1
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm0,%xmm9
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm1,%xmm1
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	vpaddq	-96(%rbp),%xmm1,%xmm10
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,16(%rsp)
+	vpalignr	$8,%xmm2,%xmm3,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm6,%xmm7,%xmm11
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpaddq	%xmm11,%xmm2,%xmm2
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm1,%xmm11
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	vpsllq	$3,%xmm1,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	vpaddq	%xmm8,%xmm2,%xmm2
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm1,%xmm9
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm2,%xmm2
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	vpaddq	-64(%rbp),%xmm2,%xmm10
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,32(%rsp)
+	vpalignr	$8,%xmm3,%xmm4,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm7,%xmm0,%xmm11
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpaddq	%xmm11,%xmm3,%xmm3
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm2,%xmm11
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	vpsllq	$3,%xmm2,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	vpaddq	%xmm8,%xmm3,%xmm3
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm2,%xmm9
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm3,%xmm3
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	vpaddq	-32(%rbp),%xmm3,%xmm10
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,48(%rsp)
+	vpalignr	$8,%xmm4,%xmm5,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	vpalignr	$8,%xmm0,%xmm1,%xmm11
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	vpaddq	%xmm11,%xmm4,%xmm4
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm3,%xmm11
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	vpsllq	$3,%xmm3,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	vpaddq	%xmm8,%xmm4,%xmm4
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm3,%xmm9
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm4,%xmm4
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	vpaddq	0(%rbp),%xmm4,%xmm10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	vmovdqa	%xmm10,64(%rsp)
+	vpalignr	$8,%xmm5,%xmm6,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	vpalignr	$8,%xmm1,%xmm2,%xmm11
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	vpaddq	%xmm11,%xmm5,%xmm5
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm4,%xmm11
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	vpsllq	$3,%xmm4,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	vpaddq	%xmm8,%xmm5,%xmm5
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm4,%xmm9
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm5,%xmm5
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	vpaddq	32(%rbp),%xmm5,%xmm10
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	vmovdqa	%xmm10,80(%rsp)
+	vpalignr	$8,%xmm6,%xmm7,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	vpalignr	$8,%xmm2,%xmm3,%xmm11
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	vpaddq	%xmm11,%xmm6,%xmm6
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm5,%xmm11
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	vpsllq	$3,%xmm5,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	vpaddq	%xmm8,%xmm6,%xmm6
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm5,%xmm9
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm6,%xmm6
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	vpaddq	64(%rbp),%xmm6,%xmm10
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	vmovdqa	%xmm10,96(%rsp)
+	vpalignr	$8,%xmm7,%xmm0,%xmm8
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	vpalignr	$8,%xmm3,%xmm4,%xmm11
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$1,%xmm8,%xmm10
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	vpaddq	%xmm11,%xmm7,%xmm7
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	vpsrlq	$7,%xmm8,%xmm11
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	vpsllq	$56,%xmm8,%xmm9
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+	vpxor	%xmm10,%xmm11,%xmm8
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	vpsrlq	$7,%xmm10,%xmm10
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	vpsllq	$7,%xmm9,%xmm9
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	vpxor	%xmm10,%xmm8,%xmm8
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	vpsrlq	$6,%xmm6,%xmm11
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	vpxor	%xmm9,%xmm8,%xmm8
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	vpsllq	$3,%xmm6,%xmm10
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	vpaddq	%xmm8,%xmm7,%xmm7
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	vpsrlq	$19,%xmm6,%xmm9
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	vpxor	%xmm10,%xmm11,%xmm11
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	vpsllq	$42,%xmm10,%xmm10
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	vpxor	%xmm9,%xmm11,%xmm11
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	vpsrlq	$42,%xmm9,%xmm9
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	vpxor	%xmm10,%xmm11,%xmm11
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	vpxor	%xmm9,%xmm11,%xmm11
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	vpaddq	%xmm11,%xmm7,%xmm7
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	vpaddq	96(%rbp),%xmm7,%xmm10
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	vmovdqa	%xmm10,112(%rsp)
+	cmpb	$0,135(%rbp)
+	jne	L$avx_00_47
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	0(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	8(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	16(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	24(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	32(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	40(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	48(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	56(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rax
+	movq	%r9,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r8,%r13
+	xorq	%r10,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rax,%r14
+	andq	%r8,%r12
+	xorq	%r8,%r13
+	addq	64(%rsp),%r11
+	movq	%rax,%r15
+	xorq	%r10,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rbx,%r15
+	addq	%r12,%r11
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rax,%r14
+	addq	%r13,%r11
+	xorq	%rbx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r11,%rdx
+	addq	%rdi,%r11
+	movq	%rdx,%r13
+	addq	%r11,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r11
+	movq	%r8,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rdx,%r13
+	xorq	%r9,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r11,%r14
+	andq	%rdx,%r12
+	xorq	%rdx,%r13
+	addq	72(%rsp),%r10
+	movq	%r11,%rdi
+	xorq	%r9,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rax,%rdi
+	addq	%r12,%r10
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r11,%r14
+	addq	%r13,%r10
+	xorq	%rax,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r10,%rcx
+	addq	%r15,%r10
+	movq	%rcx,%r13
+	addq	%r10,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r10
+	movq	%rdx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rcx,%r13
+	xorq	%r8,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r10,%r14
+	andq	%rcx,%r12
+	xorq	%rcx,%r13
+	addq	80(%rsp),%r9
+	movq	%r10,%r15
+	xorq	%r8,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r11,%r15
+	addq	%r12,%r9
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r10,%r14
+	addq	%r13,%r9
+	xorq	%r11,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%r9,%rbx
+	addq	%rdi,%r9
+	movq	%rbx,%r13
+	addq	%r9,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r9
+	movq	%rcx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rbx,%r13
+	xorq	%rdx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r9,%r14
+	andq	%rbx,%r12
+	xorq	%rbx,%r13
+	addq	88(%rsp),%r8
+	movq	%r9,%rdi
+	xorq	%rdx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r10,%rdi
+	addq	%r12,%r8
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%r9,%r14
+	addq	%r13,%r8
+	xorq	%r10,%r15
+	shrdq	$28,%r14,%r14
+	addq	%r8,%rax
+	addq	%r15,%r8
+	movq	%rax,%r13
+	addq	%r8,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%r8
+	movq	%rbx,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%rax,%r13
+	xorq	%rcx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%r8,%r14
+	andq	%rax,%r12
+	xorq	%rax,%r13
+	addq	96(%rsp),%rdx
+	movq	%r8,%r15
+	xorq	%rcx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r9,%r15
+	addq	%r12,%rdx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%r8,%r14
+	addq	%r13,%rdx
+	xorq	%r9,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rdx,%r11
+	addq	%rdi,%rdx
+	movq	%r11,%r13
+	addq	%rdx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rdx
+	movq	%rax,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r11,%r13
+	xorq	%rbx,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rdx,%r14
+	andq	%r11,%r12
+	xorq	%r11,%r13
+	addq	104(%rsp),%rcx
+	movq	%rdx,%rdi
+	xorq	%rbx,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%r8,%rdi
+	addq	%r12,%rcx
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rdx,%r14
+	addq	%r13,%rcx
+	xorq	%r8,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rcx,%r10
+	addq	%r15,%rcx
+	movq	%r10,%r13
+	addq	%rcx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rcx
+	movq	%r11,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r10,%r13
+	xorq	%rax,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rcx,%r14
+	andq	%r10,%r12
+	xorq	%r10,%r13
+	addq	112(%rsp),%rbx
+	movq	%rcx,%r15
+	xorq	%rax,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rdx,%r15
+	addq	%r12,%rbx
+	shrdq	$14,%r13,%r13
+	andq	%r15,%rdi
+	xorq	%rcx,%r14
+	addq	%r13,%rbx
+	xorq	%rdx,%rdi
+	shrdq	$28,%r14,%r14
+	addq	%rbx,%r9
+	addq	%rdi,%rbx
+	movq	%r9,%r13
+	addq	%rbx,%r14
+	shrdq	$23,%r13,%r13
+	movq	%r14,%rbx
+	movq	%r10,%r12
+	shrdq	$5,%r14,%r14
+	xorq	%r9,%r13
+	xorq	%r11,%r12
+	shrdq	$4,%r13,%r13
+	xorq	%rbx,%r14
+	andq	%r9,%r12
+	xorq	%r9,%r13
+	addq	120(%rsp),%rax
+	movq	%rbx,%rdi
+	xorq	%r11,%r12
+	shrdq	$6,%r14,%r14
+	xorq	%rcx,%rdi
+	addq	%r12,%rax
+	shrdq	$14,%r13,%r13
+	andq	%rdi,%r15
+	xorq	%rbx,%r14
+	addq	%r13,%rax
+	xorq	%rcx,%r15
+	shrdq	$28,%r14,%r14
+	addq	%rax,%r8
+	addq	%r15,%rax
+	movq	%r8,%r13
+	addq	%rax,%r14
+	movq	128+0(%rsp),%rdi
+	movq	%r14,%rax
+
+	addq	0(%rdi),%rax
+	leaq	128(%rsi),%rsi
+	addq	8(%rdi),%rbx
+	addq	16(%rdi),%rcx
+	addq	24(%rdi),%rdx
+	addq	32(%rdi),%r8
+	addq	40(%rdi),%r9
+	addq	48(%rdi),%r10
+	addq	56(%rdi),%r11
+
+	cmpq	128+16(%rsp),%rsi
+
+	movq	%rax,0(%rdi)
+	movq	%rbx,8(%rdi)
+	movq	%rcx,16(%rdi)
+	movq	%rdx,24(%rdi)
+	movq	%r8,32(%rdi)
+	movq	%r9,40(%rdi)
+	movq	%r10,48(%rdi)
+	movq	%r11,56(%rdi)
+	jb	L$loop_avx
+
+	movq	128+24(%rsp),%rsi
+	vzeroupper
+	movq	(%rsi),%r15
+	movq	8(%rsi),%r14
+	movq	16(%rsi),%r13
+	movq	24(%rsi),%r12
+	movq	32(%rsi),%rbp
+	movq	40(%rsi),%rbx
+	leaq	48(%rsi),%rsp
+L$epilogue_avx:
+	.byte	0xf3,0xc3
+
 #endif
diff --git a/third_party/boringssl/win-x86/crypto/chacha/chacha-x86.asm b/third_party/boringssl/win-x86/crypto/chacha/chacha-x86.asm
new file mode 100644
index 0000000..3ba31a2
--- /dev/null
+++ b/third_party/boringssl/win-x86/crypto/chacha/chacha-x86.asm
@@ -0,0 +1,977 @@
+%ifidn __OUTPUT_FORMAT__,obj
+section	code	use32 class=code align=64
+%elifidn __OUTPUT_FORMAT__,win32
+%ifdef __YASM_VERSION_ID__
+%if __YASM_VERSION_ID__ < 01010000h
+%error yasm version 1.1.0 or later needed.
+%endif
+; Yasm automatically includes .00 and complains about redefining it.
+; https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html
+%else
+$@feat.00 equ 1
+%endif
+section	.text	code align=64
+%else
+section	.text	code
+%endif
+global	_ChaCha20_ctr32
+align	16
+_ChaCha20_ctr32:
+L$_ChaCha20_ctr32_begin:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+	xor	eax,eax
+	cmp	eax,DWORD [28+esp]
+	je	NEAR L$000no_data
+	call	L$pic_point
+L$pic_point:
+	pop	eax
+	lea	ebp,[_OPENSSL_ia32cap_P]
+	test	DWORD [ebp],16777216
+	jz	NEAR L$001x86
+	test	DWORD [4+ebp],512
+	jz	NEAR L$001x86
+	jmp	NEAR L$ssse3_shortcut
+L$001x86:
+	mov	esi,DWORD [32+esp]
+	mov	edi,DWORD [36+esp]
+	sub	esp,132
+	mov	eax,DWORD [esi]
+	mov	ebx,DWORD [4+esi]
+	mov	ecx,DWORD [8+esi]
+	mov	edx,DWORD [12+esi]
+	mov	DWORD [80+esp],eax
+	mov	DWORD [84+esp],ebx
+	mov	DWORD [88+esp],ecx
+	mov	DWORD [92+esp],edx
+	mov	eax,DWORD [16+esi]
+	mov	ebx,DWORD [20+esi]
+	mov	ecx,DWORD [24+esi]
+	mov	edx,DWORD [28+esi]
+	mov	DWORD [96+esp],eax
+	mov	DWORD [100+esp],ebx
+	mov	DWORD [104+esp],ecx
+	mov	DWORD [108+esp],edx
+	mov	eax,DWORD [edi]
+	mov	ebx,DWORD [4+edi]
+	mov	ecx,DWORD [8+edi]
+	mov	edx,DWORD [12+edi]
+	sub	eax,1
+	mov	DWORD [112+esp],eax
+	mov	DWORD [116+esp],ebx
+	mov	DWORD [120+esp],ecx
+	mov	DWORD [124+esp],edx
+	jmp	NEAR L$002entry
+align	16
+L$003outer_loop:
+	mov	DWORD [156+esp],ebx
+	mov	DWORD [152+esp],eax
+	mov	DWORD [160+esp],ecx
+L$002entry:
+	mov	eax,1634760805
+	mov	DWORD [4+esp],857760878
+	mov	DWORD [8+esp],2036477234
+	mov	DWORD [12+esp],1797285236
+	mov	ebx,DWORD [84+esp]
+	mov	ebp,DWORD [88+esp]
+	mov	ecx,DWORD [104+esp]
+	mov	esi,DWORD [108+esp]
+	mov	edx,DWORD [116+esp]
+	mov	edi,DWORD [120+esp]
+	mov	DWORD [20+esp],ebx
+	mov	DWORD [24+esp],ebp
+	mov	DWORD [40+esp],ecx
+	mov	DWORD [44+esp],esi
+	mov	DWORD [52+esp],edx
+	mov	DWORD [56+esp],edi
+	mov	ebx,DWORD [92+esp]
+	mov	edi,DWORD [124+esp]
+	mov	edx,DWORD [112+esp]
+	mov	ebp,DWORD [80+esp]
+	mov	ecx,DWORD [96+esp]
+	mov	esi,DWORD [100+esp]
+	add	edx,1
+	mov	DWORD [28+esp],ebx
+	mov	DWORD [60+esp],edi
+	mov	DWORD [112+esp],edx
+	mov	ebx,10
+	jmp	NEAR L$004loop
+align	16
+L$004loop:
+	add	eax,ebp
+	mov	DWORD [128+esp],ebx
+	mov	ebx,ebp
+	xor	edx,eax
+	rol	edx,16
+	add	ecx,edx
+	xor	ebx,ecx
+	mov	edi,DWORD [52+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [20+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [esp],eax
+	rol	edx,8
+	mov	eax,DWORD [4+esp]
+	add	ecx,edx
+	mov	DWORD [48+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	mov	DWORD [32+esp],ecx
+	rol	edi,16
+	mov	DWORD [16+esp],ebx
+	add	esi,edi
+	mov	ecx,DWORD [40+esp]
+	xor	ebp,esi
+	mov	edx,DWORD [56+esp]
+	rol	ebp,12
+	mov	ebx,DWORD [24+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [4+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [8+esp]
+	add	esi,edi
+	mov	DWORD [52+esp],edi
+	xor	ebp,esi
+	add	eax,ebx
+	rol	ebp,7
+	xor	edx,eax
+	mov	DWORD [36+esp],esi
+	rol	edx,16
+	mov	DWORD [20+esp],ebp
+	add	ecx,edx
+	mov	esi,DWORD [44+esp]
+	xor	ebx,ecx
+	mov	edi,DWORD [60+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [28+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [8+esp],eax
+	rol	edx,8
+	mov	eax,DWORD [12+esp]
+	add	ecx,edx
+	mov	DWORD [56+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	rol	edi,16
+	mov	DWORD [24+esp],ebx
+	add	esi,edi
+	xor	ebp,esi
+	rol	ebp,12
+	mov	ebx,DWORD [20+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [12+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [esp]
+	add	esi,edi
+	mov	edx,edi
+	xor	ebp,esi
+	add	eax,ebx
+	rol	ebp,7
+	xor	edx,eax
+	rol	edx,16
+	mov	DWORD [28+esp],ebp
+	add	ecx,edx
+	xor	ebx,ecx
+	mov	edi,DWORD [48+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [24+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [esp],eax
+	rol	edx,8
+	mov	eax,DWORD [4+esp]
+	add	ecx,edx
+	mov	DWORD [60+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	mov	DWORD [40+esp],ecx
+	rol	edi,16
+	mov	DWORD [20+esp],ebx
+	add	esi,edi
+	mov	ecx,DWORD [32+esp]
+	xor	ebp,esi
+	mov	edx,DWORD [52+esp]
+	rol	ebp,12
+	mov	ebx,DWORD [28+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [4+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [8+esp]
+	add	esi,edi
+	mov	DWORD [48+esp],edi
+	xor	ebp,esi
+	add	eax,ebx
+	rol	ebp,7
+	xor	edx,eax
+	mov	DWORD [44+esp],esi
+	rol	edx,16
+	mov	DWORD [24+esp],ebp
+	add	ecx,edx
+	mov	esi,DWORD [36+esp]
+	xor	ebx,ecx
+	mov	edi,DWORD [56+esp]
+	rol	ebx,12
+	mov	ebp,DWORD [16+esp]
+	add	eax,ebx
+	xor	edx,eax
+	mov	DWORD [8+esp],eax
+	rol	edx,8
+	mov	eax,DWORD [12+esp]
+	add	ecx,edx
+	mov	DWORD [52+esp],edx
+	xor	ebx,ecx
+	add	eax,ebp
+	rol	ebx,7
+	xor	edi,eax
+	rol	edi,16
+	mov	DWORD [28+esp],ebx
+	add	esi,edi
+	xor	ebp,esi
+	mov	edx,DWORD [48+esp]
+	rol	ebp,12
+	mov	ebx,DWORD [128+esp]
+	add	eax,ebp
+	xor	edi,eax
+	mov	DWORD [12+esp],eax
+	rol	edi,8
+	mov	eax,DWORD [esp]
+	add	esi,edi
+	mov	DWORD [56+esp],edi
+	xor	ebp,esi
+	rol	ebp,7
+	dec	ebx
+	jnz	NEAR L$004loop
+	mov	ebx,DWORD [160+esp]
+	add	eax,1634760805
+	add	ebp,DWORD [80+esp]
+	add	ecx,DWORD [96+esp]
+	add	esi,DWORD [100+esp]
+	cmp	ebx,64
+	jb	NEAR L$005tail
+	mov	ebx,DWORD [156+esp]
+	add	edx,DWORD [112+esp]
+	add	edi,DWORD [120+esp]
+	xor	eax,DWORD [ebx]
+	xor	ebp,DWORD [16+ebx]
+	mov	DWORD [esp],eax
+	mov	eax,DWORD [152+esp]
+	xor	ecx,DWORD [32+ebx]
+	xor	esi,DWORD [36+ebx]
+	xor	edx,DWORD [48+ebx]
+	xor	edi,DWORD [56+ebx]
+	mov	DWORD [16+eax],ebp
+	mov	DWORD [32+eax],ecx
+	mov	DWORD [36+eax],esi
+	mov	DWORD [48+eax],edx
+	mov	DWORD [56+eax],edi
+	mov	ebp,DWORD [4+esp]
+	mov	ecx,DWORD [8+esp]
+	mov	esi,DWORD [12+esp]
+	mov	edx,DWORD [20+esp]
+	mov	edi,DWORD [24+esp]
+	add	ebp,857760878
+	add	ecx,2036477234
+	add	esi,1797285236
+	add	edx,DWORD [84+esp]
+	add	edi,DWORD [88+esp]
+	xor	ebp,DWORD [4+ebx]
+	xor	ecx,DWORD [8+ebx]
+	xor	esi,DWORD [12+ebx]
+	xor	edx,DWORD [20+ebx]
+	xor	edi,DWORD [24+ebx]
+	mov	DWORD [4+eax],ebp
+	mov	DWORD [8+eax],ecx
+	mov	DWORD [12+eax],esi
+	mov	DWORD [20+eax],edx
+	mov	DWORD [24+eax],edi
+	mov	ebp,DWORD [28+esp]
+	mov	ecx,DWORD [40+esp]
+	mov	esi,DWORD [44+esp]
+	mov	edx,DWORD [52+esp]
+	mov	edi,DWORD [60+esp]
+	add	ebp,DWORD [92+esp]
+	add	ecx,DWORD [104+esp]
+	add	esi,DWORD [108+esp]
+	add	edx,DWORD [116+esp]
+	add	edi,DWORD [124+esp]
+	xor	ebp,DWORD [28+ebx]
+	xor	ecx,DWORD [40+ebx]
+	xor	esi,DWORD [44+ebx]
+	xor	edx,DWORD [52+ebx]
+	xor	edi,DWORD [60+ebx]
+	lea	ebx,[64+ebx]
+	mov	DWORD [28+eax],ebp
+	mov	ebp,DWORD [esp]
+	mov	DWORD [40+eax],ecx
+	mov	ecx,DWORD [160+esp]
+	mov	DWORD [44+eax],esi
+	mov	DWORD [52+eax],edx
+	mov	DWORD [60+eax],edi
+	mov	DWORD [eax],ebp
+	lea	eax,[64+eax]
+	sub	ecx,64
+	jnz	NEAR L$003outer_loop
+	jmp	NEAR L$006done
+L$005tail:
+	add	edx,DWORD [112+esp]
+	add	edi,DWORD [120+esp]
+	mov	DWORD [esp],eax
+	mov	DWORD [16+esp],ebp
+	mov	DWORD [32+esp],ecx
+	mov	DWORD [36+esp],esi
+	mov	DWORD [48+esp],edx
+	mov	DWORD [56+esp],edi
+	mov	ebp,DWORD [4+esp]
+	mov	ecx,DWORD [8+esp]
+	mov	esi,DWORD [12+esp]
+	mov	edx,DWORD [20+esp]
+	mov	edi,DWORD [24+esp]
+	add	ebp,857760878
+	add	ecx,2036477234
+	add	esi,1797285236
+	add	edx,DWORD [84+esp]
+	add	edi,DWORD [88+esp]
+	mov	DWORD [4+esp],ebp
+	mov	DWORD [8+esp],ecx
+	mov	DWORD [12+esp],esi
+	mov	DWORD [20+esp],edx
+	mov	DWORD [24+esp],edi
+	mov	ebp,DWORD [28+esp]
+	mov	ecx,DWORD [40+esp]
+	mov	esi,DWORD [44+esp]
+	mov	edx,DWORD [52+esp]
+	mov	edi,DWORD [60+esp]
+	add	ebp,DWORD [92+esp]
+	add	ecx,DWORD [104+esp]
+	add	esi,DWORD [108+esp]
+	add	edx,DWORD [116+esp]
+	add	edi,DWORD [124+esp]
+	mov	DWORD [28+esp],ebp
+	mov	ebp,DWORD [156+esp]
+	mov	DWORD [40+esp],ecx
+	mov	ecx,DWORD [152+esp]
+	mov	DWORD [44+esp],esi
+	xor	esi,esi
+	mov	DWORD [52+esp],edx
+	mov	DWORD [60+esp],edi
+	xor	eax,eax
+	xor	edx,edx
+L$007tail_loop:
+	mov	al,BYTE [ebp*1+esi]
+	mov	dl,BYTE [esi*1+esp]
+	lea	esi,[1+esi]
+	xor	al,dl
+	mov	BYTE [esi*1+ecx-1],al
+	dec	ebx
+	jnz	NEAR L$007tail_loop
+L$006done:
+	add	esp,132
+L$000no_data:
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+global	_ChaCha20_ssse3
+align	16
+_ChaCha20_ssse3:
+L$_ChaCha20_ssse3_begin:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+L$ssse3_shortcut:
+	mov	edi,DWORD [20+esp]
+	mov	esi,DWORD [24+esp]
+	mov	ecx,DWORD [28+esp]
+	mov	edx,DWORD [32+esp]
+	mov	ebx,DWORD [36+esp]
+	mov	ebp,esp
+	sub	esp,524
+	and	esp,-64
+	mov	DWORD [512+esp],ebp
+	lea	eax,[(L$ssse3_data-L$pic_point)+eax]
+	movdqu	xmm3,[ebx]
+	cmp	ecx,256
+	jb	NEAR L$0081x
+	mov	DWORD [516+esp],edx
+	mov	DWORD [520+esp],ebx
+	sub	ecx,256
+	lea	ebp,[384+esp]
+	movdqu	xmm7,[edx]
+	pshufd	xmm0,xmm3,0
+	pshufd	xmm1,xmm3,85
+	pshufd	xmm2,xmm3,170
+	pshufd	xmm3,xmm3,255
+	paddd	xmm0,[48+eax]
+	pshufd	xmm4,xmm7,0
+	pshufd	xmm5,xmm7,85
+	psubd	xmm0,[64+eax]
+	pshufd	xmm6,xmm7,170
+	pshufd	xmm7,xmm7,255
+	movdqa	[64+ebp],xmm0
+	movdqa	[80+ebp],xmm1
+	movdqa	[96+ebp],xmm2
+	movdqa	[112+ebp],xmm3
+	movdqu	xmm3,[16+edx]
+	movdqa	[ebp-64],xmm4
+	movdqa	[ebp-48],xmm5
+	movdqa	[ebp-32],xmm6
+	movdqa	[ebp-16],xmm7
+	movdqa	xmm7,[32+eax]
+	lea	ebx,[128+esp]
+	pshufd	xmm0,xmm3,0
+	pshufd	xmm1,xmm3,85
+	pshufd	xmm2,xmm3,170
+	pshufd	xmm3,xmm3,255
+	pshufd	xmm4,xmm7,0
+	pshufd	xmm5,xmm7,85
+	pshufd	xmm6,xmm7,170
+	pshufd	xmm7,xmm7,255
+	movdqa	[ebp],xmm0
+	movdqa	[16+ebp],xmm1
+	movdqa	[32+ebp],xmm2
+	movdqa	[48+ebp],xmm3
+	movdqa	[ebp-128],xmm4
+	movdqa	[ebp-112],xmm5
+	movdqa	[ebp-96],xmm6
+	movdqa	[ebp-80],xmm7
+	lea	esi,[128+esi]
+	lea	edi,[128+edi]
+	jmp	NEAR L$009outer_loop
+align	16
+L$009outer_loop:
+	movdqa	xmm1,[ebp-112]
+	movdqa	xmm2,[ebp-96]
+	movdqa	xmm3,[ebp-80]
+	movdqa	xmm5,[ebp-48]
+	movdqa	xmm6,[ebp-32]
+	movdqa	xmm7,[ebp-16]
+	movdqa	[ebx-112],xmm1
+	movdqa	[ebx-96],xmm2
+	movdqa	[ebx-80],xmm3
+	movdqa	[ebx-48],xmm5
+	movdqa	[ebx-32],xmm6
+	movdqa	[ebx-16],xmm7
+	movdqa	xmm2,[32+ebp]
+	movdqa	xmm3,[48+ebp]
+	movdqa	xmm4,[64+ebp]
+	movdqa	xmm5,[80+ebp]
+	movdqa	xmm6,[96+ebp]
+	movdqa	xmm7,[112+ebp]
+	paddd	xmm4,[64+eax]
+	movdqa	[32+ebx],xmm2
+	movdqa	[48+ebx],xmm3
+	movdqa	[64+ebx],xmm4
+	movdqa	[80+ebx],xmm5
+	movdqa	[96+ebx],xmm6
+	movdqa	[112+ebx],xmm7
+	movdqa	[64+ebp],xmm4
+	movdqa	xmm0,[ebp-128]
+	movdqa	xmm6,xmm4
+	movdqa	xmm3,[ebp-64]
+	movdqa	xmm4,[ebp]
+	movdqa	xmm5,[16+ebp]
+	mov	edx,10
+	nop
+align	16
+L$010loop:
+	paddd	xmm0,xmm3
+	movdqa	xmm2,xmm3
+	pxor	xmm6,xmm0
+	pshufb	xmm6,[eax]
+	paddd	xmm4,xmm6
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-48]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-112]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[80+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-128],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[64+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	movdqa	[ebx],xmm4
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-64],xmm2
+	paddd	xmm5,xmm7
+	movdqa	xmm4,[32+ebx]
+	pxor	xmm3,xmm5
+	movdqa	xmm2,[ebx-32]
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-96]
+	paddd	xmm1,xmm3
+	movdqa	xmm6,[96+ebx]
+	pxor	xmm7,xmm1
+	movdqa	[ebx-112],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	[80+ebx],xmm7
+	pxor	xmm3,xmm5
+	paddd	xmm0,xmm2
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	pxor	xmm6,xmm0
+	por	xmm3,xmm1
+	movdqa	[16+ebx],xmm5
+	pshufb	xmm6,[eax]
+	movdqa	[ebx-48],xmm3
+	paddd	xmm4,xmm6
+	movdqa	xmm5,[48+ebx]
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-16]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-80]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[112+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-96],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[96+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-32],xmm2
+	paddd	xmm5,xmm7
+	pxor	xmm3,xmm5
+	movdqa	xmm2,[ebx-48]
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-128]
+	paddd	xmm1,xmm3
+	pxor	xmm7,xmm1
+	movdqa	[ebx-80],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	xmm6,xmm7
+	pxor	xmm3,xmm5
+	paddd	xmm0,xmm2
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	pxor	xmm6,xmm0
+	por	xmm3,xmm1
+	pshufb	xmm6,[eax]
+	movdqa	[ebx-16],xmm3
+	paddd	xmm4,xmm6
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-32]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-112]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[64+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-128],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[112+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	movdqa	[32+ebx],xmm4
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-48],xmm2
+	paddd	xmm5,xmm7
+	movdqa	xmm4,[ebx]
+	pxor	xmm3,xmm5
+	movdqa	xmm2,[ebx-16]
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-96]
+	paddd	xmm1,xmm3
+	movdqa	xmm6,[80+ebx]
+	pxor	xmm7,xmm1
+	movdqa	[ebx-112],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	[64+ebx],xmm7
+	pxor	xmm3,xmm5
+	paddd	xmm0,xmm2
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	pxor	xmm6,xmm0
+	por	xmm3,xmm1
+	movdqa	[48+ebx],xmm5
+	pshufb	xmm6,[eax]
+	movdqa	[ebx-32],xmm3
+	paddd	xmm4,xmm6
+	movdqa	xmm5,[16+ebx]
+	pxor	xmm2,xmm4
+	movdqa	xmm3,[ebx-64]
+	movdqa	xmm1,xmm2
+	pslld	xmm2,12
+	psrld	xmm1,20
+	por	xmm2,xmm1
+	movdqa	xmm1,[ebx-80]
+	paddd	xmm0,xmm2
+	movdqa	xmm7,[96+ebx]
+	pxor	xmm6,xmm0
+	movdqa	[ebx-96],xmm0
+	pshufb	xmm6,[16+eax]
+	paddd	xmm4,xmm6
+	movdqa	[80+ebx],xmm6
+	pxor	xmm2,xmm4
+	paddd	xmm1,xmm3
+	movdqa	xmm0,xmm2
+	pslld	xmm2,7
+	psrld	xmm0,25
+	pxor	xmm7,xmm1
+	por	xmm2,xmm0
+	pshufb	xmm7,[eax]
+	movdqa	[ebx-16],xmm2
+	paddd	xmm5,xmm7
+	pxor	xmm3,xmm5
+	movdqa	xmm0,xmm3
+	pslld	xmm3,12
+	psrld	xmm0,20
+	por	xmm3,xmm0
+	movdqa	xmm0,[ebx-128]
+	paddd	xmm1,xmm3
+	movdqa	xmm6,[64+ebx]
+	pxor	xmm7,xmm1
+	movdqa	[ebx-80],xmm1
+	pshufb	xmm7,[16+eax]
+	paddd	xmm5,xmm7
+	movdqa	[96+ebx],xmm7
+	pxor	xmm3,xmm5
+	movdqa	xmm1,xmm3
+	pslld	xmm3,7
+	psrld	xmm1,25
+	por	xmm3,xmm1
+	dec	edx
+	jnz	NEAR L$010loop
+	movdqa	[ebx-64],xmm3
+	movdqa	[ebx],xmm4
+	movdqa	[16+ebx],xmm5
+	movdqa	[64+ebx],xmm6
+	movdqa	[96+ebx],xmm7
+	movdqa	xmm1,[ebx-112]
+	movdqa	xmm2,[ebx-96]
+	movdqa	xmm3,[ebx-80]
+	paddd	xmm0,[ebp-128]
+	paddd	xmm1,[ebp-112]
+	paddd	xmm2,[ebp-96]
+	paddd	xmm3,[ebp-80]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqu	xmm4,[esi-128]
+	movdqu	xmm5,[esi-64]
+	movdqu	xmm2,[esi]
+	movdqu	xmm7,[64+esi]
+	lea	esi,[16+esi]
+	pxor	xmm4,xmm0
+	movdqa	xmm0,[ebx-64]
+	pxor	xmm5,xmm1
+	movdqa	xmm1,[ebx-48]
+	pxor	xmm6,xmm2
+	movdqa	xmm2,[ebx-32]
+	pxor	xmm7,xmm3
+	movdqa	xmm3,[ebx-16]
+	movdqu	[edi-128],xmm4
+	movdqu	[edi-64],xmm5
+	movdqu	[edi],xmm6
+	movdqu	[64+edi],xmm7
+	lea	edi,[16+edi]
+	paddd	xmm0,[ebp-64]
+	paddd	xmm1,[ebp-48]
+	paddd	xmm2,[ebp-32]
+	paddd	xmm3,[ebp-16]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqu	xmm4,[esi-128]
+	movdqu	xmm5,[esi-64]
+	movdqu	xmm2,[esi]
+	movdqu	xmm7,[64+esi]
+	lea	esi,[16+esi]
+	pxor	xmm4,xmm0
+	movdqa	xmm0,[ebx]
+	pxor	xmm5,xmm1
+	movdqa	xmm1,[16+ebx]
+	pxor	xmm6,xmm2
+	movdqa	xmm2,[32+ebx]
+	pxor	xmm7,xmm3
+	movdqa	xmm3,[48+ebx]
+	movdqu	[edi-128],xmm4
+	movdqu	[edi-64],xmm5
+	movdqu	[edi],xmm6
+	movdqu	[64+edi],xmm7
+	lea	edi,[16+edi]
+	paddd	xmm0,[ebp]
+	paddd	xmm1,[16+ebp]
+	paddd	xmm2,[32+ebp]
+	paddd	xmm3,[48+ebp]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqu	xmm4,[esi-128]
+	movdqu	xmm5,[esi-64]
+	movdqu	xmm2,[esi]
+	movdqu	xmm7,[64+esi]
+	lea	esi,[16+esi]
+	pxor	xmm4,xmm0
+	movdqa	xmm0,[64+ebx]
+	pxor	xmm5,xmm1
+	movdqa	xmm1,[80+ebx]
+	pxor	xmm6,xmm2
+	movdqa	xmm2,[96+ebx]
+	pxor	xmm7,xmm3
+	movdqa	xmm3,[112+ebx]
+	movdqu	[edi-128],xmm4
+	movdqu	[edi-64],xmm5
+	movdqu	[edi],xmm6
+	movdqu	[64+edi],xmm7
+	lea	edi,[16+edi]
+	paddd	xmm0,[64+ebp]
+	paddd	xmm1,[80+ebp]
+	paddd	xmm2,[96+ebp]
+	paddd	xmm3,[112+ebp]
+	movdqa	xmm6,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm6,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	movdqu	xmm4,[esi-128]
+	movdqu	xmm5,[esi-64]
+	movdqu	xmm2,[esi]
+	movdqu	xmm7,[64+esi]
+	lea	esi,[208+esi]
+	pxor	xmm4,xmm0
+	pxor	xmm5,xmm1
+	pxor	xmm6,xmm2
+	pxor	xmm7,xmm3
+	movdqu	[edi-128],xmm4
+	movdqu	[edi-64],xmm5
+	movdqu	[edi],xmm6
+	movdqu	[64+edi],xmm7
+	lea	edi,[208+edi]
+	sub	ecx,256
+	jnc	NEAR L$009outer_loop
+	add	ecx,256
+	jz	NEAR L$011done
+	mov	ebx,DWORD [520+esp]
+	lea	esi,[esi-128]
+	mov	edx,DWORD [516+esp]
+	lea	edi,[edi-128]
+	movd	xmm2,DWORD [64+ebp]
+	movdqu	xmm3,[ebx]
+	paddd	xmm2,[96+eax]
+	pand	xmm3,[112+eax]
+	por	xmm3,xmm2
+L$0081x:
+	movdqa	xmm0,[32+eax]
+	movdqu	xmm1,[edx]
+	movdqu	xmm2,[16+edx]
+	movdqa	xmm6,[eax]
+	movdqa	xmm7,[16+eax]
+	mov	DWORD [48+esp],ebp
+	movdqa	[esp],xmm0
+	movdqa	[16+esp],xmm1
+	movdqa	[32+esp],xmm2
+	movdqa	[48+esp],xmm3
+	mov	edx,10
+	jmp	NEAR L$012loop1x
+align	16
+L$013outer1x:
+	movdqa	xmm3,[80+eax]
+	movdqa	xmm0,[esp]
+	movdqa	xmm1,[16+esp]
+	movdqa	xmm2,[32+esp]
+	paddd	xmm3,[48+esp]
+	mov	edx,10
+	movdqa	[48+esp],xmm3
+	jmp	NEAR L$012loop1x
+align	16
+L$012loop1x:
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,57
+	pshufd	xmm3,xmm3,147
+	nop
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+db	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,147
+	pshufd	xmm3,xmm3,57
+	dec	edx
+	jnz	NEAR L$012loop1x
+	paddd	xmm0,[esp]
+	paddd	xmm1,[16+esp]
+	paddd	xmm2,[32+esp]
+	paddd	xmm3,[48+esp]
+	cmp	ecx,64
+	jb	NEAR L$014tail
+	movdqu	xmm4,[esi]
+	movdqu	xmm5,[16+esi]
+	pxor	xmm0,xmm4
+	movdqu	xmm4,[32+esi]
+	pxor	xmm1,xmm5
+	movdqu	xmm5,[48+esi]
+	pxor	xmm2,xmm4
+	pxor	xmm3,xmm5
+	lea	esi,[64+esi]
+	movdqu	[edi],xmm0
+	movdqu	[16+edi],xmm1
+	movdqu	[32+edi],xmm2
+	movdqu	[48+edi],xmm3
+	lea	edi,[64+edi]
+	sub	ecx,64
+	jnz	NEAR L$013outer1x
+	jmp	NEAR L$011done
+L$014tail:
+	movdqa	[esp],xmm0
+	movdqa	[16+esp],xmm1
+	movdqa	[32+esp],xmm2
+	movdqa	[48+esp],xmm3
+	xor	eax,eax
+	xor	edx,edx
+	xor	ebp,ebp
+L$015tail_loop:
+	mov	al,BYTE [ebp*1+esp]
+	mov	dl,BYTE [ebp*1+esi]
+	lea	ebp,[1+ebp]
+	xor	al,dl
+	mov	BYTE [ebp*1+edi-1],al
+	dec	ecx
+	jnz	NEAR L$015tail_loop
+L$011done:
+	mov	esp,DWORD [512+esp]
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+align	64
+L$ssse3_data:
+db	2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13
+db	3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14
+dd	1634760805,857760878,2036477234,1797285236
+dd	0,1,2,3
+dd	4,4,4,4
+dd	1,0,0,0
+dd	4,0,0,0
+dd	0,-1,-1,-1
+align	64
+db	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+db	44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32
+db	60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111
+db	114,103,62,0
+segment	.bss
+common	_OPENSSL_ia32cap_P 16
diff --git a/third_party/boringssl/win-x86/crypto/cpu-x86-asm.asm b/third_party/boringssl/win-x86/crypto/cpu-x86-asm.asm
deleted file mode 100644
index 4317a73..0000000
--- a/third_party/boringssl/win-x86/crypto/cpu-x86-asm.asm
+++ /dev/null
@@ -1,303 +0,0 @@
-%ifidn __OUTPUT_FORMAT__,obj
-section	code	use32 class=code align=64
-%elifidn __OUTPUT_FORMAT__,win32
-%ifdef __YASM_VERSION_ID__
-%if __YASM_VERSION_ID__ < 01010000h
-%error yasm version 1.1.0 or later needed.
-%endif
-; Yasm automatically includes .00 and complains about redefining it.
-; https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html
-%else
-$@feat.00 equ 1
-%endif
-section	.text	code align=64
-%else
-section	.text	code
-%endif
-global	_OPENSSL_ia32_cpuid
-align	16
-_OPENSSL_ia32_cpuid:
-L$_OPENSSL_ia32_cpuid_begin:
-	push	ebp
-	push	ebx
-	push	esi
-	push	edi
-	xor	edx,edx
-	pushfd
-	pop	eax
-	mov	ecx,eax
-	xor	eax,2097152
-	push	eax
-	popfd
-	pushfd
-	pop	eax
-	xor	ecx,eax
-	xor	eax,eax
-	bt	ecx,21
-	jnc	NEAR L$000nocpuid
-	mov	esi,DWORD [20+esp]
-	mov	DWORD [8+esi],eax
-	cpuid
-	mov	edi,eax
-	xor	eax,eax
-	cmp	ebx,1970169159
-	setne	al
-	mov	ebp,eax
-	cmp	edx,1231384169
-	setne	al
-	or	ebp,eax
-	cmp	ecx,1818588270
-	setne	al
-	or	ebp,eax
-	jz	NEAR L$001intel
-	cmp	ebx,1752462657
-	setne	al
-	mov	esi,eax
-	cmp	edx,1769238117
-	setne	al
-	or	esi,eax
-	cmp	ecx,1145913699
-	setne	al
-	or	esi,eax
-	jnz	NEAR L$001intel
-	mov	eax,2147483648
-	cpuid
-	cmp	eax,2147483649
-	jb	NEAR L$001intel
-	mov	esi,eax
-	mov	eax,2147483649
-	cpuid
-	or	ebp,ecx
-	and	ebp,2049
-	cmp	esi,2147483656
-	jb	NEAR L$001intel
-	mov	eax,2147483656
-	cpuid
-	movzx	esi,cl
-	inc	esi
-	mov	eax,1
-	xor	ecx,ecx
-	cpuid
-	bt	edx,28
-	jnc	NEAR L$002generic
-	shr	ebx,16
-	and	ebx,255
-	cmp	ebx,esi
-	ja	NEAR L$002generic
-	and	edx,4026531839
-	jmp	NEAR L$002generic
-L$001intel:
-	cmp	edi,7
-	jb	NEAR L$003cacheinfo
-	mov	esi,DWORD [20+esp]
-	mov	eax,7
-	xor	ecx,ecx
-	cpuid
-	mov	DWORD [8+esi],ebx
-L$003cacheinfo:
-	cmp	edi,4
-	mov	edi,-1
-	jb	NEAR L$004nocacheinfo
-	mov	eax,4
-	mov	ecx,0
-	cpuid
-	mov	edi,eax
-	shr	edi,14
-	and	edi,4095
-L$004nocacheinfo:
-	mov	eax,1
-	xor	ecx,ecx
-	cpuid
-	and	edx,3220176895
-	cmp	ebp,0
-	jne	NEAR L$005notintel
-	or	edx,1073741824
-L$005notintel:
-	bt	edx,28
-	jnc	NEAR L$002generic
-	and	edx,4026531839
-	cmp	edi,0
-	je	NEAR L$002generic
-	or	edx,268435456
-	shr	ebx,16
-	cmp	bl,1
-	ja	NEAR L$002generic
-	and	edx,4026531839
-L$002generic:
-	and	ebp,2048
-	and	ecx,4294965247
-	mov	esi,edx
-	or	ebp,ecx
-	bt	ecx,27
-	jnc	NEAR L$006clear_avx
-	xor	ecx,ecx
-db	15,1,208
-	and	eax,6
-	cmp	eax,6
-	je	NEAR L$007done
-	cmp	eax,2
-	je	NEAR L$006clear_avx
-L$008clear_xmm:
-	and	ebp,4261412861
-	and	esi,4278190079
-L$006clear_avx:
-	and	ebp,4026525695
-	mov	edi,DWORD [20+esp]
-	and	DWORD [8+edi],4294967263
-L$007done:
-	mov	eax,esi
-	mov	edx,ebp
-L$000nocpuid:
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-;extern	_OPENSSL_ia32cap_P
-global	_OPENSSL_rdtsc
-align	16
-_OPENSSL_rdtsc:
-L$_OPENSSL_rdtsc_begin:
-	xor	eax,eax
-	xor	edx,edx
-	lea	ecx,[_OPENSSL_ia32cap_P]
-	bt	DWORD [ecx],4
-	jnc	NEAR L$009notsc
-	rdtsc
-L$009notsc:
-	ret
-global	_OPENSSL_instrument_halt
-align	16
-_OPENSSL_instrument_halt:
-L$_OPENSSL_instrument_halt_begin:
-	lea	ecx,[_OPENSSL_ia32cap_P]
-	bt	DWORD [ecx],4
-	jnc	NEAR L$010nohalt
-dd	2421723150
-	and	eax,3
-	jnz	NEAR L$010nohalt
-	pushfd
-	pop	eax
-	bt	eax,9
-	jnc	NEAR L$010nohalt
-	rdtsc
-	push	edx
-	push	eax
-	hlt
-	rdtsc
-	sub	eax,DWORD [esp]
-	sbb	edx,DWORD [4+esp]
-	add	esp,8
-	ret
-L$010nohalt:
-	xor	eax,eax
-	xor	edx,edx
-	ret
-global	_OPENSSL_far_spin
-align	16
-_OPENSSL_far_spin:
-L$_OPENSSL_far_spin_begin:
-	pushfd
-	pop	eax
-	bt	eax,9
-	jnc	NEAR L$011nospin
-	mov	eax,DWORD [4+esp]
-	mov	ecx,DWORD [8+esp]
-dd	2430111262
-	xor	eax,eax
-	mov	edx,DWORD [ecx]
-	jmp	NEAR L$012spin
-align	16
-L$012spin:
-	inc	eax
-	cmp	edx,DWORD [ecx]
-	je	NEAR L$012spin
-dd	529567888
-	ret
-L$011nospin:
-	xor	eax,eax
-	xor	edx,edx
-	ret
-global	_OPENSSL_wipe_cpu
-align	16
-_OPENSSL_wipe_cpu:
-L$_OPENSSL_wipe_cpu_begin:
-	xor	eax,eax
-	xor	edx,edx
-	lea	ecx,[_OPENSSL_ia32cap_P]
-	mov	ecx,DWORD [ecx]
-	bt	DWORD [ecx],1
-	jnc	NEAR L$013no_x87
-	and	ecx,83886080
-	cmp	ecx,83886080
-	jne	NEAR L$014no_sse2
-	pxor	xmm0,xmm0
-	pxor	xmm1,xmm1
-	pxor	xmm2,xmm2
-	pxor	xmm3,xmm3
-	pxor	xmm4,xmm4
-	pxor	xmm5,xmm5
-	pxor	xmm6,xmm6
-	pxor	xmm7,xmm7
-L$014no_sse2:
-dd	4007259865,4007259865,4007259865,4007259865,2430851995
-L$013no_x87:
-	lea	eax,[4+esp]
-	ret
-global	_OPENSSL_atomic_add
-align	16
-_OPENSSL_atomic_add:
-L$_OPENSSL_atomic_add_begin:
-	mov	edx,DWORD [4+esp]
-	mov	ecx,DWORD [8+esp]
-	push	ebx
-	nop
-	mov	eax,DWORD [edx]
-L$015spin:
-	lea	ebx,[ecx*1+eax]
-	nop
-dd	447811568
-	jne	NEAR L$015spin
-	mov	eax,ebx
-	pop	ebx
-	ret
-global	_OPENSSL_indirect_call
-align	16
-_OPENSSL_indirect_call:
-L$_OPENSSL_indirect_call_begin:
-	push	ebp
-	mov	ebp,esp
-	sub	esp,28
-	mov	ecx,DWORD [12+ebp]
-	mov	DWORD [esp],ecx
-	mov	edx,DWORD [16+ebp]
-	mov	DWORD [4+esp],edx
-	mov	eax,DWORD [20+ebp]
-	mov	DWORD [8+esp],eax
-	mov	eax,DWORD [24+ebp]
-	mov	DWORD [12+esp],eax
-	mov	eax,DWORD [28+ebp]
-	mov	DWORD [16+esp],eax
-	mov	eax,DWORD [32+ebp]
-	mov	DWORD [20+esp],eax
-	mov	eax,DWORD [36+ebp]
-	mov	DWORD [24+esp],eax
-	call	DWORD [8+ebp]
-	mov	esp,ebp
-	pop	ebp
-	ret
-global	_OPENSSL_ia32_rdrand
-align	16
-_OPENSSL_ia32_rdrand:
-L$_OPENSSL_ia32_rdrand_begin:
-	mov	ecx,8
-L$016loop:
-db	15,199,240
-	jc	NEAR L$017break
-	loop	L$016loop
-L$017break:
-	cmp	eax,0
-	cmove	eax,ecx
-	ret
-segment	.bss
-common	_OPENSSL_ia32cap_P 16
diff --git a/third_party/boringssl/win-x86/crypto/rc4/rc4-586.asm b/third_party/boringssl/win-x86/crypto/rc4/rc4-586.asm
index 08cd9f6..0bab2be 100644
--- a/third_party/boringssl/win-x86/crypto/rc4/rc4-586.asm
+++ b/third_party/boringssl/win-x86/crypto/rc4/rc4-586.asm
@@ -349,34 +349,5 @@
 	pop	ebx
 	pop	ebp
 	ret
-global	_RC4_options
-align	16
-_RC4_options:
-L$_RC4_options_begin:
-	call	L$016pic_point
-L$016pic_point:
-	pop	eax
-	lea	eax,[(L$017opts-L$016pic_point)+eax]
-	lea	edx,[_OPENSSL_ia32cap_P]
-	mov	edx,DWORD [edx]
-	bt	edx,20
-	jc	NEAR L$0181xchar
-	bt	edx,26
-	jnc	NEAR L$019ret
-	add	eax,25
-	ret
-L$0181xchar:
-	add	eax,12
-L$019ret:
-	ret
-align	64
-L$017opts:
-db	114,99,52,40,52,120,44,105,110,116,41,0
-db	114,99,52,40,49,120,44,99,104,97,114,41,0
-db	114,99,52,40,56,120,44,109,109,120,41,0
-db	82,67,52,32,102,111,114,32,120,56,54,44,32,67,82,89
-db	80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114
-db	111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
-align	64
 segment	.bss
 common	_OPENSSL_ia32cap_P 16
diff --git a/third_party/boringssl/win-x86/crypto/sha/sha1-586.asm b/third_party/boringssl/win-x86/crypto/sha/sha1-586.asm
index e24449d..cee8c6262 100644
--- a/third_party/boringssl/win-x86/crypto/sha/sha1-586.asm
+++ b/third_party/boringssl/win-x86/crypto/sha/sha1-586.asm
@@ -35,8 +35,11 @@
 	mov	ecx,DWORD [8+esi]
 	test	eax,16777216
 	jz	NEAR L$001x86
-	test	ecx,536870912
-	jnz	NEAR L$shaext_shortcut
+	and	edx,268435456
+	and	eax,1073741824
+	or	eax,edx
+	cmp	eax,1342177280
+	je	NEAR L$avx_shortcut
 	jmp	NEAR L$ssse3_shortcut
 align	16
 L$001x86:
@@ -1405,7 +1408,7 @@
 	pop	ebp
 	ret
 align	16
-__sha1_block_data_order_shaext:
+__sha1_block_data_order_ssse3:
 	push	ebp
 	push	ebx
 	push	esi
@@ -1414,174 +1417,6 @@
 L$003pic_point:
 	pop	ebp
 	lea	ebp,[(L$K_XX_XX-L$003pic_point)+ebp]
-L$shaext_shortcut:
-	mov	edi,DWORD [20+esp]
-	mov	ebx,esp
-	mov	esi,DWORD [24+esp]
-	mov	ecx,DWORD [28+esp]
-	sub	esp,32
-	movdqu	xmm0,[edi]
-	movd	xmm1,DWORD [16+edi]
-	and	esp,-32
-	movdqa	xmm3,[80+ebp]
-	movdqu	xmm4,[esi]
-	pshufd	xmm0,xmm0,27
-	movdqu	xmm5,[16+esi]
-	pshufd	xmm1,xmm1,27
-	movdqu	xmm6,[32+esi]
-db	102,15,56,0,227
-	movdqu	xmm7,[48+esi]
-db	102,15,56,0,235
-db	102,15,56,0,243
-db	102,15,56,0,251
-	jmp	NEAR L$004loop_shaext
-align	16
-L$004loop_shaext:
-	dec	ecx
-	lea	eax,[64+esi]
-	movdqa	[esp],xmm1
-	paddd	xmm1,xmm4
-	cmovne	esi,eax
-	movdqa	[16+esp],xmm0
-db	15,56,201,229
-	movdqa	xmm2,xmm0
-db	15,58,204,193,0
-db	15,56,200,213
-	pxor	xmm4,xmm6
-db	15,56,201,238
-db	15,56,202,231
-	movdqa	xmm1,xmm0
-db	15,58,204,194,0
-db	15,56,200,206
-	pxor	xmm5,xmm7
-db	15,56,202,236
-db	15,56,201,247
-	movdqa	xmm2,xmm0
-db	15,58,204,193,0
-db	15,56,200,215
-	pxor	xmm6,xmm4
-db	15,56,201,252
-db	15,56,202,245
-	movdqa	xmm1,xmm0
-db	15,58,204,194,0
-db	15,56,200,204
-	pxor	xmm7,xmm5
-db	15,56,202,254
-db	15,56,201,229
-	movdqa	xmm2,xmm0
-db	15,58,204,193,0
-db	15,56,200,213
-	pxor	xmm4,xmm6
-db	15,56,201,238
-db	15,56,202,231
-	movdqa	xmm1,xmm0
-db	15,58,204,194,1
-db	15,56,200,206
-	pxor	xmm5,xmm7
-db	15,56,202,236
-db	15,56,201,247
-	movdqa	xmm2,xmm0
-db	15,58,204,193,1
-db	15,56,200,215
-	pxor	xmm6,xmm4
-db	15,56,201,252
-db	15,56,202,245
-	movdqa	xmm1,xmm0
-db	15,58,204,194,1
-db	15,56,200,204
-	pxor	xmm7,xmm5
-db	15,56,202,254
-db	15,56,201,229
-	movdqa	xmm2,xmm0
-db	15,58,204,193,1
-db	15,56,200,213
-	pxor	xmm4,xmm6
-db	15,56,201,238
-db	15,56,202,231
-	movdqa	xmm1,xmm0
-db	15,58,204,194,1
-db	15,56,200,206
-	pxor	xmm5,xmm7
-db	15,56,202,236
-db	15,56,201,247
-	movdqa	xmm2,xmm0
-db	15,58,204,193,2
-db	15,56,200,215
-	pxor	xmm6,xmm4
-db	15,56,201,252
-db	15,56,202,245
-	movdqa	xmm1,xmm0
-db	15,58,204,194,2
-db	15,56,200,204
-	pxor	xmm7,xmm5
-db	15,56,202,254
-db	15,56,201,229
-	movdqa	xmm2,xmm0
-db	15,58,204,193,2
-db	15,56,200,213
-	pxor	xmm4,xmm6
-db	15,56,201,238
-db	15,56,202,231
-	movdqa	xmm1,xmm0
-db	15,58,204,194,2
-db	15,56,200,206
-	pxor	xmm5,xmm7
-db	15,56,202,236
-db	15,56,201,247
-	movdqa	xmm2,xmm0
-db	15,58,204,193,2
-db	15,56,200,215
-	pxor	xmm6,xmm4
-db	15,56,201,252
-db	15,56,202,245
-	movdqa	xmm1,xmm0
-db	15,58,204,194,3
-db	15,56,200,204
-	pxor	xmm7,xmm5
-db	15,56,202,254
-	movdqu	xmm4,[esi]
-	movdqa	xmm2,xmm0
-db	15,58,204,193,3
-db	15,56,200,213
-	movdqu	xmm5,[16+esi]
-db	102,15,56,0,227
-	movdqa	xmm1,xmm0
-db	15,58,204,194,3
-db	15,56,200,206
-	movdqu	xmm6,[32+esi]
-db	102,15,56,0,235
-	movdqa	xmm2,xmm0
-db	15,58,204,193,3
-db	15,56,200,215
-	movdqu	xmm7,[48+esi]
-db	102,15,56,0,243
-	movdqa	xmm1,xmm0
-db	15,58,204,194,3
-	movdqa	xmm2,[esp]
-db	102,15,56,0,251
-db	15,56,200,202
-	paddd	xmm0,[16+esp]
-	jnz	NEAR L$004loop_shaext
-	pshufd	xmm0,xmm0,27
-	pshufd	xmm1,xmm1,27
-	movdqu	[edi],xmm0
-	movd	DWORD [16+edi],xmm1
-	mov	esp,ebx
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-align	16
-__sha1_block_data_order_ssse3:
-	push	ebp
-	push	ebx
-	push	esi
-	push	edi
-	call	L$005pic_point
-L$005pic_point:
-	pop	ebp
-	lea	ebp,[(L$K_XX_XX-L$005pic_point)+ebp]
 L$ssse3_shortcut:
 	movdqa	xmm7,[ebp]
 	movdqa	xmm0,[16+ebp]
@@ -1634,9 +1469,9 @@
 	xor	ebp,edx
 	pshufd	xmm4,xmm0,238
 	and	esi,ebp
-	jmp	NEAR L$006loop
+	jmp	NEAR L$004loop
 align	16
-L$006loop:
+L$004loop:
 	ror	ebx,2
 	xor	esi,edx
 	mov	ebp,eax
@@ -2539,7 +2374,7 @@
 	add	ecx,edx
 	mov	ebp,DWORD [196+esp]
 	cmp	ebp,DWORD [200+esp]
-	je	NEAR L$007done
+	je	NEAR L$005done
 	movdqa	xmm7,[160+esp]
 	movdqa	xmm6,[176+esp]
 	movdqu	xmm0,[ebp]
@@ -2674,9 +2509,9 @@
 	pshufd	xmm4,xmm0,238
 	and	esi,ebx
 	mov	ebx,ebp
-	jmp	NEAR L$006loop
+	jmp	NEAR L$004loop
 align	16
-L$007done:
+L$005done:
 	add	ebx,DWORD [16+esp]
 	xor	esi,edi
 	mov	ebp,ecx
@@ -2789,6 +2624,1174 @@
 	pop	ebx
 	pop	ebp
 	ret
+align	16
+__sha1_block_data_order_avx:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+	call	L$006pic_point
+L$006pic_point:
+	pop	ebp
+	lea	ebp,[(L$K_XX_XX-L$006pic_point)+ebp]
+L$avx_shortcut:
+	vzeroall
+	vmovdqa	xmm7,[ebp]
+	vmovdqa	xmm0,[16+ebp]
+	vmovdqa	xmm1,[32+ebp]
+	vmovdqa	xmm2,[48+ebp]
+	vmovdqa	xmm6,[64+ebp]
+	mov	edi,DWORD [20+esp]
+	mov	ebp,DWORD [24+esp]
+	mov	edx,DWORD [28+esp]
+	mov	esi,esp
+	sub	esp,208
+	and	esp,-64
+	vmovdqa	[112+esp],xmm0
+	vmovdqa	[128+esp],xmm1
+	vmovdqa	[144+esp],xmm2
+	shl	edx,6
+	vmovdqa	[160+esp],xmm7
+	add	edx,ebp
+	vmovdqa	[176+esp],xmm6
+	add	ebp,64
+	mov	DWORD [192+esp],edi
+	mov	DWORD [196+esp],ebp
+	mov	DWORD [200+esp],edx
+	mov	DWORD [204+esp],esi
+	mov	eax,DWORD [edi]
+	mov	ebx,DWORD [4+edi]
+	mov	ecx,DWORD [8+edi]
+	mov	edx,DWORD [12+edi]
+	mov	edi,DWORD [16+edi]
+	mov	esi,ebx
+	vmovdqu	xmm0,[ebp-64]
+	vmovdqu	xmm1,[ebp-48]
+	vmovdqu	xmm2,[ebp-32]
+	vmovdqu	xmm3,[ebp-16]
+	vpshufb	xmm0,xmm0,xmm6
+	vpshufb	xmm1,xmm1,xmm6
+	vpshufb	xmm2,xmm2,xmm6
+	vmovdqa	[96+esp],xmm7
+	vpshufb	xmm3,xmm3,xmm6
+	vpaddd	xmm4,xmm0,xmm7
+	vpaddd	xmm5,xmm1,xmm7
+	vpaddd	xmm6,xmm2,xmm7
+	vmovdqa	[esp],xmm4
+	mov	ebp,ecx
+	vmovdqa	[16+esp],xmm5
+	xor	ebp,edx
+	vmovdqa	[32+esp],xmm6
+	and	esi,ebp
+	jmp	NEAR L$007loop
+align	16
+L$007loop:
+	shrd	ebx,ebx,2
+	xor	esi,edx
+	vpalignr	xmm4,xmm1,xmm0,8
+	mov	ebp,eax
+	add	edi,DWORD [esp]
+	vpaddd	xmm7,xmm7,xmm3
+	vmovdqa	[64+esp],xmm0
+	xor	ebx,ecx
+	shld	eax,eax,5
+	vpsrldq	xmm6,xmm3,4
+	add	edi,esi
+	and	ebp,ebx
+	vpxor	xmm4,xmm4,xmm0
+	xor	ebx,ecx
+	add	edi,eax
+	vpxor	xmm6,xmm6,xmm2
+	shrd	eax,eax,7
+	xor	ebp,ecx
+	vmovdqa	[48+esp],xmm7
+	mov	esi,edi
+	add	edx,DWORD [4+esp]
+	vpxor	xmm4,xmm4,xmm6
+	xor	eax,ebx
+	shld	edi,edi,5
+	add	edx,ebp
+	and	esi,eax
+	vpsrld	xmm6,xmm4,31
+	xor	eax,ebx
+	add	edx,edi
+	shrd	edi,edi,7
+	xor	esi,ebx
+	vpslldq	xmm0,xmm4,12
+	vpaddd	xmm4,xmm4,xmm4
+	mov	ebp,edx
+	add	ecx,DWORD [8+esp]
+	xor	edi,eax
+	shld	edx,edx,5
+	vpsrld	xmm7,xmm0,30
+	vpor	xmm4,xmm4,xmm6
+	add	ecx,esi
+	and	ebp,edi
+	xor	edi,eax
+	add	ecx,edx
+	vpslld	xmm0,xmm0,2
+	shrd	edx,edx,7
+	xor	ebp,eax
+	vpxor	xmm4,xmm4,xmm7
+	mov	esi,ecx
+	add	ebx,DWORD [12+esp]
+	xor	edx,edi
+	shld	ecx,ecx,5
+	vpxor	xmm4,xmm4,xmm0
+	add	ebx,ebp
+	and	esi,edx
+	vmovdqa	xmm0,[96+esp]
+	xor	edx,edi
+	add	ebx,ecx
+	shrd	ecx,ecx,7
+	xor	esi,edi
+	vpalignr	xmm5,xmm2,xmm1,8
+	mov	ebp,ebx
+	add	eax,DWORD [16+esp]
+	vpaddd	xmm0,xmm0,xmm4
+	vmovdqa	[80+esp],xmm1
+	xor	ecx,edx
+	shld	ebx,ebx,5
+	vpsrldq	xmm7,xmm4,4
+	add	eax,esi
+	and	ebp,ecx
+	vpxor	xmm5,xmm5,xmm1
+	xor	ecx,edx
+	add	eax,ebx
+	vpxor	xmm7,xmm7,xmm3
+	shrd	ebx,ebx,7
+	xor	ebp,edx
+	vmovdqa	[esp],xmm0
+	mov	esi,eax
+	add	edi,DWORD [20+esp]
+	vpxor	xmm5,xmm5,xmm7
+	xor	ebx,ecx
+	shld	eax,eax,5
+	add	edi,ebp
+	and	esi,ebx
+	vpsrld	xmm7,xmm5,31
+	xor	ebx,ecx
+	add	edi,eax
+	shrd	eax,eax,7
+	xor	esi,ecx
+	vpslldq	xmm1,xmm5,12
+	vpaddd	xmm5,xmm5,xmm5
+	mov	ebp,edi
+	add	edx,DWORD [24+esp]
+	xor	eax,ebx
+	shld	edi,edi,5
+	vpsrld	xmm0,xmm1,30
+	vpor	xmm5,xmm5,xmm7
+	add	edx,esi
+	and	ebp,eax
+	xor	eax,ebx
+	add	edx,edi
+	vpslld	xmm1,xmm1,2
+	shrd	edi,edi,7
+	xor	ebp,ebx
+	vpxor	xmm5,xmm5,xmm0
+	mov	esi,edx
+	add	ecx,DWORD [28+esp]
+	xor	edi,eax
+	shld	edx,edx,5
+	vpxor	xmm5,xmm5,xmm1
+	add	ecx,ebp
+	and	esi,edi
+	vmovdqa	xmm1,[112+esp]
+	xor	edi,eax
+	add	ecx,edx
+	shrd	edx,edx,7
+	xor	esi,eax
+	vpalignr	xmm6,xmm3,xmm2,8
+	mov	ebp,ecx
+	add	ebx,DWORD [32+esp]
+	vpaddd	xmm1,xmm1,xmm5
+	vmovdqa	[96+esp],xmm2
+	xor	edx,edi
+	shld	ecx,ecx,5
+	vpsrldq	xmm0,xmm5,4
+	add	ebx,esi
+	and	ebp,edx
+	vpxor	xmm6,xmm6,xmm2
+	xor	edx,edi
+	add	ebx,ecx
+	vpxor	xmm0,xmm0,xmm4
+	shrd	ecx,ecx,7
+	xor	ebp,edi
+	vmovdqa	[16+esp],xmm1
+	mov	esi,ebx
+	add	eax,DWORD [36+esp]
+	vpxor	xmm6,xmm6,xmm0
+	xor	ecx,edx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	and	esi,ecx
+	vpsrld	xmm0,xmm6,31
+	xor	ecx,edx
+	add	eax,ebx
+	shrd	ebx,ebx,7
+	xor	esi,edx
+	vpslldq	xmm2,xmm6,12
+	vpaddd	xmm6,xmm6,xmm6
+	mov	ebp,eax
+	add	edi,DWORD [40+esp]
+	xor	ebx,ecx
+	shld	eax,eax,5
+	vpsrld	xmm1,xmm2,30
+	vpor	xmm6,xmm6,xmm0
+	add	edi,esi
+	and	ebp,ebx
+	xor	ebx,ecx
+	add	edi,eax
+	vpslld	xmm2,xmm2,2
+	vmovdqa	xmm0,[64+esp]
+	shrd	eax,eax,7
+	xor	ebp,ecx
+	vpxor	xmm6,xmm6,xmm1
+	mov	esi,edi
+	add	edx,DWORD [44+esp]
+	xor	eax,ebx
+	shld	edi,edi,5
+	vpxor	xmm6,xmm6,xmm2
+	add	edx,ebp
+	and	esi,eax
+	vmovdqa	xmm2,[112+esp]
+	xor	eax,ebx
+	add	edx,edi
+	shrd	edi,edi,7
+	xor	esi,ebx
+	vpalignr	xmm7,xmm4,xmm3,8
+	mov	ebp,edx
+	add	ecx,DWORD [48+esp]
+	vpaddd	xmm2,xmm2,xmm6
+	vmovdqa	[64+esp],xmm3
+	xor	edi,eax
+	shld	edx,edx,5
+	vpsrldq	xmm1,xmm6,4
+	add	ecx,esi
+	and	ebp,edi
+	vpxor	xmm7,xmm7,xmm3
+	xor	edi,eax
+	add	ecx,edx
+	vpxor	xmm1,xmm1,xmm5
+	shrd	edx,edx,7
+	xor	ebp,eax
+	vmovdqa	[32+esp],xmm2
+	mov	esi,ecx
+	add	ebx,DWORD [52+esp]
+	vpxor	xmm7,xmm7,xmm1
+	xor	edx,edi
+	shld	ecx,ecx,5
+	add	ebx,ebp
+	and	esi,edx
+	vpsrld	xmm1,xmm7,31
+	xor	edx,edi
+	add	ebx,ecx
+	shrd	ecx,ecx,7
+	xor	esi,edi
+	vpslldq	xmm3,xmm7,12
+	vpaddd	xmm7,xmm7,xmm7
+	mov	ebp,ebx
+	add	eax,DWORD [56+esp]
+	xor	ecx,edx
+	shld	ebx,ebx,5
+	vpsrld	xmm2,xmm3,30
+	vpor	xmm7,xmm7,xmm1
+	add	eax,esi
+	and	ebp,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	vpslld	xmm3,xmm3,2
+	vmovdqa	xmm1,[80+esp]
+	shrd	ebx,ebx,7
+	xor	ebp,edx
+	vpxor	xmm7,xmm7,xmm2
+	mov	esi,eax
+	add	edi,DWORD [60+esp]
+	xor	ebx,ecx
+	shld	eax,eax,5
+	vpxor	xmm7,xmm7,xmm3
+	add	edi,ebp
+	and	esi,ebx
+	vmovdqa	xmm3,[112+esp]
+	xor	ebx,ecx
+	add	edi,eax
+	vpalignr	xmm2,xmm7,xmm6,8
+	vpxor	xmm0,xmm0,xmm4
+	shrd	eax,eax,7
+	xor	esi,ecx
+	mov	ebp,edi
+	add	edx,DWORD [esp]
+	vpxor	xmm0,xmm0,xmm1
+	vmovdqa	[80+esp],xmm4
+	xor	eax,ebx
+	shld	edi,edi,5
+	vmovdqa	xmm4,xmm3
+	vpaddd	xmm3,xmm3,xmm7
+	add	edx,esi
+	and	ebp,eax
+	vpxor	xmm0,xmm0,xmm2
+	xor	eax,ebx
+	add	edx,edi
+	shrd	edi,edi,7
+	xor	ebp,ebx
+	vpsrld	xmm2,xmm0,30
+	vmovdqa	[48+esp],xmm3
+	mov	esi,edx
+	add	ecx,DWORD [4+esp]
+	xor	edi,eax
+	shld	edx,edx,5
+	vpslld	xmm0,xmm0,2
+	add	ecx,ebp
+	and	esi,edi
+	xor	edi,eax
+	add	ecx,edx
+	shrd	edx,edx,7
+	xor	esi,eax
+	mov	ebp,ecx
+	add	ebx,DWORD [8+esp]
+	vpor	xmm0,xmm0,xmm2
+	xor	edx,edi
+	shld	ecx,ecx,5
+	vmovdqa	xmm2,[96+esp]
+	add	ebx,esi
+	and	ebp,edx
+	xor	edx,edi
+	add	ebx,ecx
+	add	eax,DWORD [12+esp]
+	xor	ebp,edi
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpalignr	xmm3,xmm0,xmm7,8
+	vpxor	xmm1,xmm1,xmm5
+	add	edi,DWORD [16+esp]
+	xor	esi,ecx
+	mov	ebp,eax
+	shld	eax,eax,5
+	vpxor	xmm1,xmm1,xmm2
+	vmovdqa	[96+esp],xmm5
+	add	edi,esi
+	xor	ebp,ecx
+	vmovdqa	xmm5,xmm4
+	vpaddd	xmm4,xmm4,xmm0
+	shrd	ebx,ebx,7
+	add	edi,eax
+	vpxor	xmm1,xmm1,xmm3
+	add	edx,DWORD [20+esp]
+	xor	ebp,ebx
+	mov	esi,edi
+	shld	edi,edi,5
+	vpsrld	xmm3,xmm1,30
+	vmovdqa	[esp],xmm4
+	add	edx,ebp
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	vpslld	xmm1,xmm1,2
+	add	ecx,DWORD [24+esp]
+	xor	esi,eax
+	mov	ebp,edx
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	ebp,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	vpor	xmm1,xmm1,xmm3
+	add	ebx,DWORD [28+esp]
+	xor	ebp,edi
+	vmovdqa	xmm3,[64+esp]
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,ebp
+	xor	esi,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpalignr	xmm4,xmm1,xmm0,8
+	vpxor	xmm2,xmm2,xmm6
+	add	eax,DWORD [32+esp]
+	xor	esi,edx
+	mov	ebp,ebx
+	shld	ebx,ebx,5
+	vpxor	xmm2,xmm2,xmm3
+	vmovdqa	[64+esp],xmm6
+	add	eax,esi
+	xor	ebp,edx
+	vmovdqa	xmm6,[128+esp]
+	vpaddd	xmm5,xmm5,xmm1
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpxor	xmm2,xmm2,xmm4
+	add	edi,DWORD [36+esp]
+	xor	ebp,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	vpsrld	xmm4,xmm2,30
+	vmovdqa	[16+esp],xmm5
+	add	edi,ebp
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	vpslld	xmm2,xmm2,2
+	add	edx,DWORD [40+esp]
+	xor	esi,ebx
+	mov	ebp,edi
+	shld	edi,edi,5
+	add	edx,esi
+	xor	ebp,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	vpor	xmm2,xmm2,xmm4
+	add	ecx,DWORD [44+esp]
+	xor	ebp,eax
+	vmovdqa	xmm4,[80+esp]
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,ebp
+	xor	esi,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	vpalignr	xmm5,xmm2,xmm1,8
+	vpxor	xmm3,xmm3,xmm7
+	add	ebx,DWORD [48+esp]
+	xor	esi,edi
+	mov	ebp,ecx
+	shld	ecx,ecx,5
+	vpxor	xmm3,xmm3,xmm4
+	vmovdqa	[80+esp],xmm7
+	add	ebx,esi
+	xor	ebp,edi
+	vmovdqa	xmm7,xmm6
+	vpaddd	xmm6,xmm6,xmm2
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpxor	xmm3,xmm3,xmm5
+	add	eax,DWORD [52+esp]
+	xor	ebp,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	vpsrld	xmm5,xmm3,30
+	vmovdqa	[32+esp],xmm6
+	add	eax,ebp
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpslld	xmm3,xmm3,2
+	add	edi,DWORD [56+esp]
+	xor	esi,ecx
+	mov	ebp,eax
+	shld	eax,eax,5
+	add	edi,esi
+	xor	ebp,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	vpor	xmm3,xmm3,xmm5
+	add	edx,DWORD [60+esp]
+	xor	ebp,ebx
+	vmovdqa	xmm5,[96+esp]
+	mov	esi,edi
+	shld	edi,edi,5
+	add	edx,ebp
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	vpalignr	xmm6,xmm3,xmm2,8
+	vpxor	xmm4,xmm4,xmm0
+	add	ecx,DWORD [esp]
+	xor	esi,eax
+	mov	ebp,edx
+	shld	edx,edx,5
+	vpxor	xmm4,xmm4,xmm5
+	vmovdqa	[96+esp],xmm0
+	add	ecx,esi
+	xor	ebp,eax
+	vmovdqa	xmm0,xmm7
+	vpaddd	xmm7,xmm7,xmm3
+	shrd	edi,edi,7
+	add	ecx,edx
+	vpxor	xmm4,xmm4,xmm6
+	add	ebx,DWORD [4+esp]
+	xor	ebp,edi
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	vpsrld	xmm6,xmm4,30
+	vmovdqa	[48+esp],xmm7
+	add	ebx,ebp
+	xor	esi,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpslld	xmm4,xmm4,2
+	add	eax,DWORD [8+esp]
+	xor	esi,edx
+	mov	ebp,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	ebp,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpor	xmm4,xmm4,xmm6
+	add	edi,DWORD [12+esp]
+	xor	ebp,ecx
+	vmovdqa	xmm6,[64+esp]
+	mov	esi,eax
+	shld	eax,eax,5
+	add	edi,ebp
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	vpalignr	xmm7,xmm4,xmm3,8
+	vpxor	xmm5,xmm5,xmm1
+	add	edx,DWORD [16+esp]
+	xor	esi,ebx
+	mov	ebp,edi
+	shld	edi,edi,5
+	vpxor	xmm5,xmm5,xmm6
+	vmovdqa	[64+esp],xmm1
+	add	edx,esi
+	xor	ebp,ebx
+	vmovdqa	xmm1,xmm0
+	vpaddd	xmm0,xmm0,xmm4
+	shrd	eax,eax,7
+	add	edx,edi
+	vpxor	xmm5,xmm5,xmm7
+	add	ecx,DWORD [20+esp]
+	xor	ebp,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	vpsrld	xmm7,xmm5,30
+	vmovdqa	[esp],xmm0
+	add	ecx,ebp
+	xor	esi,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	vpslld	xmm5,xmm5,2
+	add	ebx,DWORD [24+esp]
+	xor	esi,edi
+	mov	ebp,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	ebp,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpor	xmm5,xmm5,xmm7
+	add	eax,DWORD [28+esp]
+	vmovdqa	xmm7,[80+esp]
+	shrd	ecx,ecx,7
+	mov	esi,ebx
+	xor	ebp,edx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	xor	esi,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	vpalignr	xmm0,xmm5,xmm4,8
+	vpxor	xmm6,xmm6,xmm2
+	add	edi,DWORD [32+esp]
+	and	esi,ecx
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	vpxor	xmm6,xmm6,xmm7
+	vmovdqa	[80+esp],xmm2
+	mov	ebp,eax
+	xor	esi,ecx
+	vmovdqa	xmm2,xmm1
+	vpaddd	xmm1,xmm1,xmm5
+	shld	eax,eax,5
+	add	edi,esi
+	vpxor	xmm6,xmm6,xmm0
+	xor	ebp,ebx
+	xor	ebx,ecx
+	add	edi,eax
+	add	edx,DWORD [36+esp]
+	vpsrld	xmm0,xmm6,30
+	vmovdqa	[16+esp],xmm1
+	and	ebp,ebx
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	mov	esi,edi
+	vpslld	xmm6,xmm6,2
+	xor	ebp,ebx
+	shld	edi,edi,5
+	add	edx,ebp
+	xor	esi,eax
+	xor	eax,ebx
+	add	edx,edi
+	add	ecx,DWORD [40+esp]
+	and	esi,eax
+	vpor	xmm6,xmm6,xmm0
+	xor	eax,ebx
+	shrd	edi,edi,7
+	vmovdqa	xmm0,[96+esp]
+	mov	ebp,edx
+	xor	esi,eax
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	ebp,edi
+	xor	edi,eax
+	add	ecx,edx
+	add	ebx,DWORD [44+esp]
+	and	ebp,edi
+	xor	edi,eax
+	shrd	edx,edx,7
+	mov	esi,ecx
+	xor	ebp,edi
+	shld	ecx,ecx,5
+	add	ebx,ebp
+	xor	esi,edx
+	xor	edx,edi
+	add	ebx,ecx
+	vpalignr	xmm1,xmm6,xmm5,8
+	vpxor	xmm7,xmm7,xmm3
+	add	eax,DWORD [48+esp]
+	and	esi,edx
+	xor	edx,edi
+	shrd	ecx,ecx,7
+	vpxor	xmm7,xmm7,xmm0
+	vmovdqa	[96+esp],xmm3
+	mov	ebp,ebx
+	xor	esi,edx
+	vmovdqa	xmm3,[144+esp]
+	vpaddd	xmm2,xmm2,xmm6
+	shld	ebx,ebx,5
+	add	eax,esi
+	vpxor	xmm7,xmm7,xmm1
+	xor	ebp,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	add	edi,DWORD [52+esp]
+	vpsrld	xmm1,xmm7,30
+	vmovdqa	[32+esp],xmm2
+	and	ebp,ecx
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	mov	esi,eax
+	vpslld	xmm7,xmm7,2
+	xor	ebp,ecx
+	shld	eax,eax,5
+	add	edi,ebp
+	xor	esi,ebx
+	xor	ebx,ecx
+	add	edi,eax
+	add	edx,DWORD [56+esp]
+	and	esi,ebx
+	vpor	xmm7,xmm7,xmm1
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	vmovdqa	xmm1,[64+esp]
+	mov	ebp,edi
+	xor	esi,ebx
+	shld	edi,edi,5
+	add	edx,esi
+	xor	ebp,eax
+	xor	eax,ebx
+	add	edx,edi
+	add	ecx,DWORD [60+esp]
+	and	ebp,eax
+	xor	eax,ebx
+	shrd	edi,edi,7
+	mov	esi,edx
+	xor	ebp,eax
+	shld	edx,edx,5
+	add	ecx,ebp
+	xor	esi,edi
+	xor	edi,eax
+	add	ecx,edx
+	vpalignr	xmm2,xmm7,xmm6,8
+	vpxor	xmm0,xmm0,xmm4
+	add	ebx,DWORD [esp]
+	and	esi,edi
+	xor	edi,eax
+	shrd	edx,edx,7
+	vpxor	xmm0,xmm0,xmm1
+	vmovdqa	[64+esp],xmm4
+	mov	ebp,ecx
+	xor	esi,edi
+	vmovdqa	xmm4,xmm3
+	vpaddd	xmm3,xmm3,xmm7
+	shld	ecx,ecx,5
+	add	ebx,esi
+	vpxor	xmm0,xmm0,xmm2
+	xor	ebp,edx
+	xor	edx,edi
+	add	ebx,ecx
+	add	eax,DWORD [4+esp]
+	vpsrld	xmm2,xmm0,30
+	vmovdqa	[48+esp],xmm3
+	and	ebp,edx
+	xor	edx,edi
+	shrd	ecx,ecx,7
+	mov	esi,ebx
+	vpslld	xmm0,xmm0,2
+	xor	ebp,edx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	xor	esi,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	add	edi,DWORD [8+esp]
+	and	esi,ecx
+	vpor	xmm0,xmm0,xmm2
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	vmovdqa	xmm2,[80+esp]
+	mov	ebp,eax
+	xor	esi,ecx
+	shld	eax,eax,5
+	add	edi,esi
+	xor	ebp,ebx
+	xor	ebx,ecx
+	add	edi,eax
+	add	edx,DWORD [12+esp]
+	and	ebp,ebx
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	mov	esi,edi
+	xor	ebp,ebx
+	shld	edi,edi,5
+	add	edx,ebp
+	xor	esi,eax
+	xor	eax,ebx
+	add	edx,edi
+	vpalignr	xmm3,xmm0,xmm7,8
+	vpxor	xmm1,xmm1,xmm5
+	add	ecx,DWORD [16+esp]
+	and	esi,eax
+	xor	eax,ebx
+	shrd	edi,edi,7
+	vpxor	xmm1,xmm1,xmm2
+	vmovdqa	[80+esp],xmm5
+	mov	ebp,edx
+	xor	esi,eax
+	vmovdqa	xmm5,xmm4
+	vpaddd	xmm4,xmm4,xmm0
+	shld	edx,edx,5
+	add	ecx,esi
+	vpxor	xmm1,xmm1,xmm3
+	xor	ebp,edi
+	xor	edi,eax
+	add	ecx,edx
+	add	ebx,DWORD [20+esp]
+	vpsrld	xmm3,xmm1,30
+	vmovdqa	[esp],xmm4
+	and	ebp,edi
+	xor	edi,eax
+	shrd	edx,edx,7
+	mov	esi,ecx
+	vpslld	xmm1,xmm1,2
+	xor	ebp,edi
+	shld	ecx,ecx,5
+	add	ebx,ebp
+	xor	esi,edx
+	xor	edx,edi
+	add	ebx,ecx
+	add	eax,DWORD [24+esp]
+	and	esi,edx
+	vpor	xmm1,xmm1,xmm3
+	xor	edx,edi
+	shrd	ecx,ecx,7
+	vmovdqa	xmm3,[96+esp]
+	mov	ebp,ebx
+	xor	esi,edx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	ebp,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	add	edi,DWORD [28+esp]
+	and	ebp,ecx
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	mov	esi,eax
+	xor	ebp,ecx
+	shld	eax,eax,5
+	add	edi,ebp
+	xor	esi,ebx
+	xor	ebx,ecx
+	add	edi,eax
+	vpalignr	xmm4,xmm1,xmm0,8
+	vpxor	xmm2,xmm2,xmm6
+	add	edx,DWORD [32+esp]
+	and	esi,ebx
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	vpxor	xmm2,xmm2,xmm3
+	vmovdqa	[96+esp],xmm6
+	mov	ebp,edi
+	xor	esi,ebx
+	vmovdqa	xmm6,xmm5
+	vpaddd	xmm5,xmm5,xmm1
+	shld	edi,edi,5
+	add	edx,esi
+	vpxor	xmm2,xmm2,xmm4
+	xor	ebp,eax
+	xor	eax,ebx
+	add	edx,edi
+	add	ecx,DWORD [36+esp]
+	vpsrld	xmm4,xmm2,30
+	vmovdqa	[16+esp],xmm5
+	and	ebp,eax
+	xor	eax,ebx
+	shrd	edi,edi,7
+	mov	esi,edx
+	vpslld	xmm2,xmm2,2
+	xor	ebp,eax
+	shld	edx,edx,5
+	add	ecx,ebp
+	xor	esi,edi
+	xor	edi,eax
+	add	ecx,edx
+	add	ebx,DWORD [40+esp]
+	and	esi,edi
+	vpor	xmm2,xmm2,xmm4
+	xor	edi,eax
+	shrd	edx,edx,7
+	vmovdqa	xmm4,[64+esp]
+	mov	ebp,ecx
+	xor	esi,edi
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	ebp,edx
+	xor	edx,edi
+	add	ebx,ecx
+	add	eax,DWORD [44+esp]
+	and	ebp,edx
+	xor	edx,edi
+	shrd	ecx,ecx,7
+	mov	esi,ebx
+	xor	ebp,edx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	xor	esi,edx
+	add	eax,ebx
+	vpalignr	xmm5,xmm2,xmm1,8
+	vpxor	xmm3,xmm3,xmm7
+	add	edi,DWORD [48+esp]
+	xor	esi,ecx
+	mov	ebp,eax
+	shld	eax,eax,5
+	vpxor	xmm3,xmm3,xmm4
+	vmovdqa	[64+esp],xmm7
+	add	edi,esi
+	xor	ebp,ecx
+	vmovdqa	xmm7,xmm6
+	vpaddd	xmm6,xmm6,xmm2
+	shrd	ebx,ebx,7
+	add	edi,eax
+	vpxor	xmm3,xmm3,xmm5
+	add	edx,DWORD [52+esp]
+	xor	ebp,ebx
+	mov	esi,edi
+	shld	edi,edi,5
+	vpsrld	xmm5,xmm3,30
+	vmovdqa	[32+esp],xmm6
+	add	edx,ebp
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	vpslld	xmm3,xmm3,2
+	add	ecx,DWORD [56+esp]
+	xor	esi,eax
+	mov	ebp,edx
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	ebp,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	vpor	xmm3,xmm3,xmm5
+	add	ebx,DWORD [60+esp]
+	xor	ebp,edi
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,ebp
+	xor	esi,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD [esp]
+	vpaddd	xmm7,xmm7,xmm3
+	xor	esi,edx
+	mov	ebp,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	vmovdqa	[48+esp],xmm7
+	xor	ebp,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	edi,DWORD [4+esp]
+	xor	ebp,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	add	edi,ebp
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	add	edx,DWORD [8+esp]
+	xor	esi,ebx
+	mov	ebp,edi
+	shld	edi,edi,5
+	add	edx,esi
+	xor	ebp,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	add	ecx,DWORD [12+esp]
+	xor	ebp,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,ebp
+	xor	esi,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	mov	ebp,DWORD [196+esp]
+	cmp	ebp,DWORD [200+esp]
+	je	NEAR L$008done
+	vmovdqa	xmm7,[160+esp]
+	vmovdqa	xmm6,[176+esp]
+	vmovdqu	xmm0,[ebp]
+	vmovdqu	xmm1,[16+ebp]
+	vmovdqu	xmm2,[32+ebp]
+	vmovdqu	xmm3,[48+ebp]
+	add	ebp,64
+	vpshufb	xmm0,xmm0,xmm6
+	mov	DWORD [196+esp],ebp
+	vmovdqa	[96+esp],xmm7
+	add	ebx,DWORD [16+esp]
+	xor	esi,edi
+	vpshufb	xmm1,xmm1,xmm6
+	mov	ebp,ecx
+	shld	ecx,ecx,5
+	vpaddd	xmm4,xmm0,xmm7
+	add	ebx,esi
+	xor	ebp,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vmovdqa	[esp],xmm4
+	add	eax,DWORD [20+esp]
+	xor	ebp,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	edi,DWORD [24+esp]
+	xor	esi,ecx
+	mov	ebp,eax
+	shld	eax,eax,5
+	add	edi,esi
+	xor	ebp,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	add	edx,DWORD [28+esp]
+	xor	ebp,ebx
+	mov	esi,edi
+	shld	edi,edi,5
+	add	edx,ebp
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	add	ecx,DWORD [32+esp]
+	xor	esi,eax
+	vpshufb	xmm2,xmm2,xmm6
+	mov	ebp,edx
+	shld	edx,edx,5
+	vpaddd	xmm5,xmm1,xmm7
+	add	ecx,esi
+	xor	ebp,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	vmovdqa	[16+esp],xmm5
+	add	ebx,DWORD [36+esp]
+	xor	ebp,edi
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,ebp
+	xor	esi,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD [40+esp]
+	xor	esi,edx
+	mov	ebp,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	ebp,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	edi,DWORD [44+esp]
+	xor	ebp,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	add	edi,ebp
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	add	edx,DWORD [48+esp]
+	xor	esi,ebx
+	vpshufb	xmm3,xmm3,xmm6
+	mov	ebp,edi
+	shld	edi,edi,5
+	vpaddd	xmm6,xmm2,xmm7
+	add	edx,esi
+	xor	ebp,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	vmovdqa	[32+esp],xmm6
+	add	ecx,DWORD [52+esp]
+	xor	ebp,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,ebp
+	xor	esi,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	add	ebx,DWORD [56+esp]
+	xor	esi,edi
+	mov	ebp,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	ebp,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD [60+esp]
+	xor	ebp,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	mov	ebp,DWORD [192+esp]
+	add	eax,DWORD [ebp]
+	add	esi,DWORD [4+ebp]
+	add	ecx,DWORD [8+ebp]
+	mov	DWORD [ebp],eax
+	add	edx,DWORD [12+ebp]
+	mov	DWORD [4+ebp],esi
+	add	edi,DWORD [16+ebp]
+	mov	ebx,ecx
+	mov	DWORD [8+ebp],ecx
+	xor	ebx,edx
+	mov	DWORD [12+ebp],edx
+	mov	DWORD [16+ebp],edi
+	mov	ebp,esi
+	and	esi,ebx
+	mov	ebx,ebp
+	jmp	NEAR L$007loop
+align	16
+L$008done:
+	add	ebx,DWORD [16+esp]
+	xor	esi,edi
+	mov	ebp,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	ebp,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD [20+esp]
+	xor	ebp,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	edi,DWORD [24+esp]
+	xor	esi,ecx
+	mov	ebp,eax
+	shld	eax,eax,5
+	add	edi,esi
+	xor	ebp,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	add	edx,DWORD [28+esp]
+	xor	ebp,ebx
+	mov	esi,edi
+	shld	edi,edi,5
+	add	edx,ebp
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	add	ecx,DWORD [32+esp]
+	xor	esi,eax
+	mov	ebp,edx
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	ebp,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	add	ebx,DWORD [36+esp]
+	xor	ebp,edi
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,ebp
+	xor	esi,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD [40+esp]
+	xor	esi,edx
+	mov	ebp,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	ebp,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	edi,DWORD [44+esp]
+	xor	ebp,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	add	edi,ebp
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	edi,eax
+	add	edx,DWORD [48+esp]
+	xor	esi,ebx
+	mov	ebp,edi
+	shld	edi,edi,5
+	add	edx,esi
+	xor	ebp,ebx
+	shrd	eax,eax,7
+	add	edx,edi
+	add	ecx,DWORD [52+esp]
+	xor	ebp,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,ebp
+	xor	esi,eax
+	shrd	edi,edi,7
+	add	ecx,edx
+	add	ebx,DWORD [56+esp]
+	xor	esi,edi
+	mov	ebp,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	ebp,edi
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD [60+esp]
+	xor	ebp,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,ebp
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vzeroall
+	mov	ebp,DWORD [192+esp]
+	add	eax,DWORD [ebp]
+	mov	esp,DWORD [204+esp]
+	add	esi,DWORD [4+ebp]
+	add	ecx,DWORD [8+ebp]
+	mov	DWORD [ebp],eax
+	add	edx,DWORD [12+ebp]
+	mov	DWORD [4+ebp],esi
+	add	edi,DWORD [16+ebp]
+	mov	DWORD [8+ebp],ecx
+	mov	DWORD [12+ebp],edx
+	mov	DWORD [16+ebp],edi
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
 align	64
 L$K_XX_XX:
 dd	1518500249,1518500249,1518500249,1518500249
diff --git a/third_party/boringssl/win-x86/crypto/sha/sha256-586.asm b/third_party/boringssl/win-x86/crypto/sha/sha256-586.asm
index fe36bc5..3e7cfcc 100644
--- a/third_party/boringssl/win-x86/crypto/sha/sha256-586.asm
+++ b/third_party/boringssl/win-x86/crypto/sha/sha256-586.asm
@@ -49,11 +49,10 @@
 	jz	NEAR L$003no_xmm
 	and	ecx,1073741824
 	and	ebx,268435968
-	test	edx,536870912
-	jnz	NEAR L$004shaext
 	or	ecx,ebx
 	and	ecx,1342177280
 	cmp	ecx,1342177280
+	je	NEAR L$004AVX
 	test	ebx,512
 	jnz	NEAR L$005SSSE3
 L$003no_xmm:
@@ -3179,204 +3178,6 @@
 	pop	ebp
 	ret
 align	32
-L$004shaext:
-	sub	esp,32
-	movdqu	xmm1,[esi]
-	lea	ebp,[128+ebp]
-	movdqu	xmm2,[16+esi]
-	movdqa	xmm7,[128+ebp]
-	pshufd	xmm0,xmm1,27
-	pshufd	xmm1,xmm1,177
-	pshufd	xmm2,xmm2,27
-db	102,15,58,15,202,8
-	punpcklqdq	xmm2,xmm0
-	jmp	NEAR L$010loop_shaext
-align	16
-L$010loop_shaext:
-	movdqu	xmm3,[edi]
-	movdqu	xmm4,[16+edi]
-	movdqu	xmm5,[32+edi]
-db	102,15,56,0,223
-	movdqu	xmm6,[48+edi]
-	movdqa	[16+esp],xmm2
-	movdqa	xmm0,[ebp-128]
-	paddd	xmm0,xmm3
-db	102,15,56,0,231
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	nop
-	movdqa	[esp],xmm1
-db	15,56,203,202
-	movdqa	xmm0,[ebp-112]
-	paddd	xmm0,xmm4
-db	102,15,56,0,239
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	lea	edi,[64+edi]
-db	15,56,204,220
-db	15,56,203,202
-	movdqa	xmm0,[ebp-96]
-	paddd	xmm0,xmm5
-db	102,15,56,0,247
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm6
-db	102,15,58,15,253,4
-	nop
-	paddd	xmm3,xmm7
-db	15,56,204,229
-db	15,56,203,202
-	movdqa	xmm0,[ebp-80]
-	paddd	xmm0,xmm6
-db	15,56,205,222
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm3
-db	102,15,58,15,254,4
-	nop
-	paddd	xmm4,xmm7
-db	15,56,204,238
-db	15,56,203,202
-	movdqa	xmm0,[ebp-64]
-	paddd	xmm0,xmm3
-db	15,56,205,227
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm4
-db	102,15,58,15,251,4
-	nop
-	paddd	xmm5,xmm7
-db	15,56,204,243
-db	15,56,203,202
-	movdqa	xmm0,[ebp-48]
-	paddd	xmm0,xmm4
-db	15,56,205,236
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm5
-db	102,15,58,15,252,4
-	nop
-	paddd	xmm6,xmm7
-db	15,56,204,220
-db	15,56,203,202
-	movdqa	xmm0,[ebp-32]
-	paddd	xmm0,xmm5
-db	15,56,205,245
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm6
-db	102,15,58,15,253,4
-	nop
-	paddd	xmm3,xmm7
-db	15,56,204,229
-db	15,56,203,202
-	movdqa	xmm0,[ebp-16]
-	paddd	xmm0,xmm6
-db	15,56,205,222
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm3
-db	102,15,58,15,254,4
-	nop
-	paddd	xmm4,xmm7
-db	15,56,204,238
-db	15,56,203,202
-	movdqa	xmm0,[ebp]
-	paddd	xmm0,xmm3
-db	15,56,205,227
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm4
-db	102,15,58,15,251,4
-	nop
-	paddd	xmm5,xmm7
-db	15,56,204,243
-db	15,56,203,202
-	movdqa	xmm0,[16+ebp]
-	paddd	xmm0,xmm4
-db	15,56,205,236
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm5
-db	102,15,58,15,252,4
-	nop
-	paddd	xmm6,xmm7
-db	15,56,204,220
-db	15,56,203,202
-	movdqa	xmm0,[32+ebp]
-	paddd	xmm0,xmm5
-db	15,56,205,245
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm6
-db	102,15,58,15,253,4
-	nop
-	paddd	xmm3,xmm7
-db	15,56,204,229
-db	15,56,203,202
-	movdqa	xmm0,[48+ebp]
-	paddd	xmm0,xmm6
-db	15,56,205,222
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm3
-db	102,15,58,15,254,4
-	nop
-	paddd	xmm4,xmm7
-db	15,56,204,238
-db	15,56,203,202
-	movdqa	xmm0,[64+ebp]
-	paddd	xmm0,xmm3
-db	15,56,205,227
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm4
-db	102,15,58,15,251,4
-	nop
-	paddd	xmm5,xmm7
-db	15,56,204,243
-db	15,56,203,202
-	movdqa	xmm0,[80+ebp]
-	paddd	xmm0,xmm4
-db	15,56,205,236
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	movdqa	xmm7,xmm5
-db	102,15,58,15,252,4
-db	15,56,203,202
-	paddd	xmm6,xmm7
-	movdqa	xmm0,[96+ebp]
-	paddd	xmm0,xmm5
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-db	15,56,205,245
-	movdqa	xmm7,[128+ebp]
-db	15,56,203,202
-	movdqa	xmm0,[112+ebp]
-	paddd	xmm0,xmm6
-	nop
-db	15,56,203,209
-	pshufd	xmm0,xmm0,14
-	cmp	eax,edi
-	nop
-db	15,56,203,202
-	paddd	xmm2,[16+esp]
-	paddd	xmm1,[esp]
-	jnz	NEAR L$010loop_shaext
-	pshufd	xmm2,xmm2,177
-	pshufd	xmm7,xmm1,27
-	pshufd	xmm1,xmm1,177
-	punpckhqdq	xmm1,xmm2
-db	102,15,58,15,215,8
-	mov	esp,DWORD [44+esp]
-	movdqu	[esi],xmm1
-	movdqu	[16+esi],xmm2
-	pop	edi
-	pop	esi
-	pop	ebx
-	pop	ebp
-	ret
-align	32
 L$005SSSE3:
 	lea	esp,[esp-96]
 	mov	eax,DWORD [esi]
@@ -3396,9 +3197,9 @@
 	mov	DWORD [24+esp],ecx
 	mov	DWORD [28+esp],esi
 	movdqa	xmm7,[256+ebp]
-	jmp	NEAR L$011grand_ssse3
+	jmp	NEAR L$010grand_ssse3
 align	16
-L$011grand_ssse3:
+L$010grand_ssse3:
 	movdqu	xmm0,[edi]
 	movdqu	xmm1,[16+edi]
 	movdqu	xmm2,[32+edi]
@@ -3421,9 +3222,9 @@
 	paddd	xmm7,xmm3
 	movdqa	[64+esp],xmm6
 	movdqa	[80+esp],xmm7
-	jmp	NEAR L$012ssse3_00_47
+	jmp	NEAR L$011ssse3_00_47
 align	16
-L$012ssse3_00_47:
+L$011ssse3_00_47:
 	add	ebp,64
 	mov	ecx,edx
 	movdqa	xmm4,xmm1
@@ -4066,7 +3867,7 @@
 	add	eax,ecx
 	movdqa	[80+esp],xmm6
 	cmp	DWORD [64+ebp],66051
-	jne	NEAR L$012ssse3_00_47
+	jne	NEAR L$011ssse3_00_47
 	mov	ecx,edx
 	ror	edx,14
 	mov	esi,DWORD [20+esp]
@@ -4580,12 +4381,1193 @@
 	movdqa	xmm7,[64+ebp]
 	sub	ebp,192
 	cmp	edi,DWORD [104+esp]
-	jb	NEAR L$011grand_ssse3
+	jb	NEAR L$010grand_ssse3
 	mov	esp,DWORD [108+esp]
 	pop	edi
 	pop	esi
 	pop	ebx
 	pop	ebp
 	ret
+align	32
+L$004AVX:
+	lea	esp,[esp-96]
+	vzeroall
+	mov	eax,DWORD [esi]
+	mov	ebx,DWORD [4+esi]
+	mov	ecx,DWORD [8+esi]
+	mov	edi,DWORD [12+esi]
+	mov	DWORD [4+esp],ebx
+	xor	ebx,ecx
+	mov	DWORD [8+esp],ecx
+	mov	DWORD [12+esp],edi
+	mov	edx,DWORD [16+esi]
+	mov	edi,DWORD [20+esi]
+	mov	ecx,DWORD [24+esi]
+	mov	esi,DWORD [28+esi]
+	mov	DWORD [20+esp],edi
+	mov	edi,DWORD [100+esp]
+	mov	DWORD [24+esp],ecx
+	mov	DWORD [28+esp],esi
+	vmovdqa	xmm7,[256+ebp]
+	jmp	NEAR L$012grand_avx
+align	32
+L$012grand_avx:
+	vmovdqu	xmm0,[edi]
+	vmovdqu	xmm1,[16+edi]
+	vmovdqu	xmm2,[32+edi]
+	vmovdqu	xmm3,[48+edi]
+	add	edi,64
+	vpshufb	xmm0,xmm0,xmm7
+	mov	DWORD [100+esp],edi
+	vpshufb	xmm1,xmm1,xmm7
+	vpshufb	xmm2,xmm2,xmm7
+	vpaddd	xmm4,xmm0,[ebp]
+	vpshufb	xmm3,xmm3,xmm7
+	vpaddd	xmm5,xmm1,[16+ebp]
+	vpaddd	xmm6,xmm2,[32+ebp]
+	vpaddd	xmm7,xmm3,[48+ebp]
+	vmovdqa	[32+esp],xmm4
+	vmovdqa	[48+esp],xmm5
+	vmovdqa	[64+esp],xmm6
+	vmovdqa	[80+esp],xmm7
+	jmp	NEAR L$013avx_00_47
+align	16
+L$013avx_00_47:
+	add	ebp,64
+	vpalignr	xmm4,xmm1,xmm0,4
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [20+esp]
+	vpalignr	xmm7,xmm3,xmm2,4
+	xor	edx,ecx
+	mov	edi,DWORD [24+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm4,7
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [16+esp],ecx
+	vpaddd	xmm0,xmm0,xmm7
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrld	xmm7,xmm4,3
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [4+esp]
+	vpslld	xmm5,xmm4,14
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [esp],eax
+	vpxor	xmm4,xmm7,xmm6
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [28+esp]
+	vpshufd	xmm7,xmm3,250
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpsrld	xmm6,xmm6,11
+	add	edx,DWORD [32+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpxor	xmm4,xmm4,xmm5
+	add	ebx,edx
+	add	edx,DWORD [12+esp]
+	add	ebx,ecx
+	vpslld	xmm5,xmm5,11
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [16+esp]
+	vpxor	xmm4,xmm4,xmm6
+	xor	edx,ecx
+	mov	edi,DWORD [20+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm7,10
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [12+esp],ecx
+	vpxor	xmm4,xmm4,xmm5
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [esp]
+	vpaddd	xmm0,xmm0,xmm4
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [28+esp],ebx
+	vpxor	xmm6,xmm6,xmm5
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [24+esp]
+	vpsrlq	xmm7,xmm7,19
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	vpxor	xmm6,xmm6,xmm7
+	add	edx,DWORD [36+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	vpshufd	xmm7,xmm6,132
+	add	eax,edx
+	add	edx,DWORD [8+esp]
+	add	eax,ecx
+	vpsrldq	xmm7,xmm7,8
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [12+esp]
+	vpaddd	xmm0,xmm0,xmm7
+	xor	edx,ecx
+	mov	edi,DWORD [16+esp]
+	xor	esi,edi
+	vpshufd	xmm7,xmm0,80
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [8+esp],ecx
+	vpsrld	xmm6,xmm7,10
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [28+esp]
+	vpxor	xmm6,xmm6,xmm5
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [24+esp],eax
+	vpsrlq	xmm7,xmm7,19
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [20+esp]
+	vpxor	xmm6,xmm6,xmm7
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpshufd	xmm7,xmm6,232
+	add	edx,DWORD [40+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpslldq	xmm7,xmm7,8
+	add	ebx,edx
+	add	edx,DWORD [4+esp]
+	add	ebx,ecx
+	vpaddd	xmm0,xmm0,xmm7
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [8+esp]
+	vpaddd	xmm6,xmm0,[ebp]
+	xor	edx,ecx
+	mov	edi,DWORD [12+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [4+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [24+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [20+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [16+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [44+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [esp]
+	add	eax,ecx
+	vmovdqa	[32+esp],xmm6
+	vpalignr	xmm4,xmm2,xmm1,4
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [4+esp]
+	vpalignr	xmm7,xmm0,xmm3,4
+	xor	edx,ecx
+	mov	edi,DWORD [8+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm4,7
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [esp],ecx
+	vpaddd	xmm1,xmm1,xmm7
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrld	xmm7,xmm4,3
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [20+esp]
+	vpslld	xmm5,xmm4,14
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [16+esp],eax
+	vpxor	xmm4,xmm7,xmm6
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [12+esp]
+	vpshufd	xmm7,xmm0,250
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpsrld	xmm6,xmm6,11
+	add	edx,DWORD [48+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpxor	xmm4,xmm4,xmm5
+	add	ebx,edx
+	add	edx,DWORD [28+esp]
+	add	ebx,ecx
+	vpslld	xmm5,xmm5,11
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [esp]
+	vpxor	xmm4,xmm4,xmm6
+	xor	edx,ecx
+	mov	edi,DWORD [4+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm7,10
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [28+esp],ecx
+	vpxor	xmm4,xmm4,xmm5
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [16+esp]
+	vpaddd	xmm1,xmm1,xmm4
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [12+esp],ebx
+	vpxor	xmm6,xmm6,xmm5
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [8+esp]
+	vpsrlq	xmm7,xmm7,19
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	vpxor	xmm6,xmm6,xmm7
+	add	edx,DWORD [52+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	vpshufd	xmm7,xmm6,132
+	add	eax,edx
+	add	edx,DWORD [24+esp]
+	add	eax,ecx
+	vpsrldq	xmm7,xmm7,8
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [28+esp]
+	vpaddd	xmm1,xmm1,xmm7
+	xor	edx,ecx
+	mov	edi,DWORD [esp]
+	xor	esi,edi
+	vpshufd	xmm7,xmm1,80
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [24+esp],ecx
+	vpsrld	xmm6,xmm7,10
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [12+esp]
+	vpxor	xmm6,xmm6,xmm5
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [8+esp],eax
+	vpsrlq	xmm7,xmm7,19
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [4+esp]
+	vpxor	xmm6,xmm6,xmm7
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpshufd	xmm7,xmm6,232
+	add	edx,DWORD [56+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpslldq	xmm7,xmm7,8
+	add	ebx,edx
+	add	edx,DWORD [20+esp]
+	add	ebx,ecx
+	vpaddd	xmm1,xmm1,xmm7
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [24+esp]
+	vpaddd	xmm6,xmm1,[16+ebp]
+	xor	edx,ecx
+	mov	edi,DWORD [28+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [20+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [8+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [4+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [60+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [16+esp]
+	add	eax,ecx
+	vmovdqa	[48+esp],xmm6
+	vpalignr	xmm4,xmm3,xmm2,4
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [20+esp]
+	vpalignr	xmm7,xmm1,xmm0,4
+	xor	edx,ecx
+	mov	edi,DWORD [24+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm4,7
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [16+esp],ecx
+	vpaddd	xmm2,xmm2,xmm7
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrld	xmm7,xmm4,3
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [4+esp]
+	vpslld	xmm5,xmm4,14
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [esp],eax
+	vpxor	xmm4,xmm7,xmm6
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [28+esp]
+	vpshufd	xmm7,xmm1,250
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpsrld	xmm6,xmm6,11
+	add	edx,DWORD [64+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpxor	xmm4,xmm4,xmm5
+	add	ebx,edx
+	add	edx,DWORD [12+esp]
+	add	ebx,ecx
+	vpslld	xmm5,xmm5,11
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [16+esp]
+	vpxor	xmm4,xmm4,xmm6
+	xor	edx,ecx
+	mov	edi,DWORD [20+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm7,10
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [12+esp],ecx
+	vpxor	xmm4,xmm4,xmm5
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [esp]
+	vpaddd	xmm2,xmm2,xmm4
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [28+esp],ebx
+	vpxor	xmm6,xmm6,xmm5
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [24+esp]
+	vpsrlq	xmm7,xmm7,19
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	vpxor	xmm6,xmm6,xmm7
+	add	edx,DWORD [68+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	vpshufd	xmm7,xmm6,132
+	add	eax,edx
+	add	edx,DWORD [8+esp]
+	add	eax,ecx
+	vpsrldq	xmm7,xmm7,8
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [12+esp]
+	vpaddd	xmm2,xmm2,xmm7
+	xor	edx,ecx
+	mov	edi,DWORD [16+esp]
+	xor	esi,edi
+	vpshufd	xmm7,xmm2,80
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [8+esp],ecx
+	vpsrld	xmm6,xmm7,10
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [28+esp]
+	vpxor	xmm6,xmm6,xmm5
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [24+esp],eax
+	vpsrlq	xmm7,xmm7,19
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [20+esp]
+	vpxor	xmm6,xmm6,xmm7
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpshufd	xmm7,xmm6,232
+	add	edx,DWORD [72+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpslldq	xmm7,xmm7,8
+	add	ebx,edx
+	add	edx,DWORD [4+esp]
+	add	ebx,ecx
+	vpaddd	xmm2,xmm2,xmm7
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [8+esp]
+	vpaddd	xmm6,xmm2,[32+ebp]
+	xor	edx,ecx
+	mov	edi,DWORD [12+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [4+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [24+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [20+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [16+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [76+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [esp]
+	add	eax,ecx
+	vmovdqa	[64+esp],xmm6
+	vpalignr	xmm4,xmm0,xmm3,4
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [4+esp]
+	vpalignr	xmm7,xmm2,xmm1,4
+	xor	edx,ecx
+	mov	edi,DWORD [8+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm4,7
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [esp],ecx
+	vpaddd	xmm3,xmm3,xmm7
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrld	xmm7,xmm4,3
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [20+esp]
+	vpslld	xmm5,xmm4,14
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [16+esp],eax
+	vpxor	xmm4,xmm7,xmm6
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [12+esp]
+	vpshufd	xmm7,xmm2,250
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpsrld	xmm6,xmm6,11
+	add	edx,DWORD [80+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpxor	xmm4,xmm4,xmm5
+	add	ebx,edx
+	add	edx,DWORD [28+esp]
+	add	ebx,ecx
+	vpslld	xmm5,xmm5,11
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [esp]
+	vpxor	xmm4,xmm4,xmm6
+	xor	edx,ecx
+	mov	edi,DWORD [4+esp]
+	xor	esi,edi
+	vpsrld	xmm6,xmm7,10
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [28+esp],ecx
+	vpxor	xmm4,xmm4,xmm5
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [16+esp]
+	vpaddd	xmm3,xmm3,xmm4
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [12+esp],ebx
+	vpxor	xmm6,xmm6,xmm5
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [8+esp]
+	vpsrlq	xmm7,xmm7,19
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	vpxor	xmm6,xmm6,xmm7
+	add	edx,DWORD [84+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	vpshufd	xmm7,xmm6,132
+	add	eax,edx
+	add	edx,DWORD [24+esp]
+	add	eax,ecx
+	vpsrldq	xmm7,xmm7,8
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [28+esp]
+	vpaddd	xmm3,xmm3,xmm7
+	xor	edx,ecx
+	mov	edi,DWORD [esp]
+	xor	esi,edi
+	vpshufd	xmm7,xmm3,80
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [24+esp],ecx
+	vpsrld	xmm6,xmm7,10
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	vpsrlq	xmm5,xmm7,17
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [12+esp]
+	vpxor	xmm6,xmm6,xmm5
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [8+esp],eax
+	vpsrlq	xmm7,xmm7,19
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [4+esp]
+	vpxor	xmm6,xmm6,xmm7
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	vpshufd	xmm7,xmm6,232
+	add	edx,DWORD [88+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	vpslldq	xmm7,xmm7,8
+	add	ebx,edx
+	add	edx,DWORD [20+esp]
+	add	ebx,ecx
+	vpaddd	xmm3,xmm3,xmm7
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [24+esp]
+	vpaddd	xmm6,xmm3,[48+ebp]
+	xor	edx,ecx
+	mov	edi,DWORD [28+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [20+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [8+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [4+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [92+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [16+esp]
+	add	eax,ecx
+	vmovdqa	[80+esp],xmm6
+	cmp	DWORD [64+ebp],66051
+	jne	NEAR L$013avx_00_47
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [20+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [24+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [16+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [4+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [28+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [32+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [12+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [16+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [20+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [12+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [28+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [24+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [36+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [8+esp]
+	add	eax,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [12+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [16+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [8+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [28+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [24+esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [20+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [40+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [4+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [8+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [12+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [4+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [24+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [20+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [16+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [44+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [esp]
+	add	eax,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [4+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [8+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [20+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [16+esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [12+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [48+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [28+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [esp]
+	xor	edx,ecx
+	mov	edi,DWORD [4+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [28+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [16+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [12+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [8+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [52+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [24+esp]
+	add	eax,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [28+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [24+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [12+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [8+esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [4+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [56+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [20+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [24+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [28+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [20+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [8+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [4+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [60+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [16+esp]
+	add	eax,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [20+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [24+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [16+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [4+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [28+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [64+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [12+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [16+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [20+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [12+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [28+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [24+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [68+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [8+esp]
+	add	eax,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [12+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [16+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [8+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [28+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [24+esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [20+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [72+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [4+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [8+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [12+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [4+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [24+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [20+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [16+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [76+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [esp]
+	add	eax,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [4+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [8+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [20+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [16+esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [12+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [80+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [28+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [esp]
+	xor	edx,ecx
+	mov	edi,DWORD [4+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [28+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [16+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [12+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [8+esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [84+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [24+esp]
+	add	eax,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [28+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [24+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,eax
+	add	edx,edi
+	mov	edi,DWORD [12+esp]
+	mov	esi,eax
+	shrd	ecx,ecx,9
+	mov	DWORD [8+esp],eax
+	xor	ecx,eax
+	xor	eax,edi
+	add	edx,DWORD [4+esp]
+	shrd	ecx,ecx,11
+	and	ebx,eax
+	xor	ecx,esi
+	add	edx,DWORD [88+esp]
+	xor	ebx,edi
+	shrd	ecx,ecx,2
+	add	ebx,edx
+	add	edx,DWORD [20+esp]
+	add	ebx,ecx
+	mov	ecx,edx
+	shrd	edx,edx,14
+	mov	esi,DWORD [24+esp]
+	xor	edx,ecx
+	mov	edi,DWORD [28+esp]
+	xor	esi,edi
+	shrd	edx,edx,5
+	and	esi,ecx
+	mov	DWORD [20+esp],ecx
+	xor	edx,ecx
+	xor	edi,esi
+	shrd	edx,edx,6
+	mov	ecx,ebx
+	add	edx,edi
+	mov	edi,DWORD [8+esp]
+	mov	esi,ebx
+	shrd	ecx,ecx,9
+	mov	DWORD [4+esp],ebx
+	xor	ecx,ebx
+	xor	ebx,edi
+	add	edx,DWORD [esp]
+	shrd	ecx,ecx,11
+	and	eax,ebx
+	xor	ecx,esi
+	add	edx,DWORD [92+esp]
+	xor	eax,edi
+	shrd	ecx,ecx,2
+	add	eax,edx
+	add	edx,DWORD [16+esp]
+	add	eax,ecx
+	mov	esi,DWORD [96+esp]
+	xor	ebx,edi
+	mov	ecx,DWORD [12+esp]
+	add	eax,DWORD [esi]
+	add	ebx,DWORD [4+esi]
+	add	edi,DWORD [8+esi]
+	add	ecx,DWORD [12+esi]
+	mov	DWORD [esi],eax
+	mov	DWORD [4+esi],ebx
+	mov	DWORD [8+esi],edi
+	mov	DWORD [12+esi],ecx
+	mov	DWORD [4+esp],ebx
+	xor	ebx,edi
+	mov	DWORD [8+esp],edi
+	mov	DWORD [12+esp],ecx
+	mov	edi,DWORD [20+esp]
+	mov	ecx,DWORD [24+esp]
+	add	edx,DWORD [16+esi]
+	add	edi,DWORD [20+esi]
+	add	ecx,DWORD [24+esi]
+	mov	DWORD [16+esi],edx
+	mov	DWORD [20+esi],edi
+	mov	DWORD [20+esp],edi
+	mov	edi,DWORD [28+esp]
+	mov	DWORD [24+esi],ecx
+	add	edi,DWORD [28+esi]
+	mov	DWORD [24+esp],ecx
+	mov	DWORD [28+esi],edi
+	mov	DWORD [28+esp],edi
+	mov	edi,DWORD [100+esp]
+	vmovdqa	xmm7,[64+ebp]
+	sub	ebp,192
+	cmp	edi,DWORD [104+esp]
+	jb	NEAR L$012grand_avx
+	mov	esp,DWORD [108+esp]
+	vzeroall
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
 segment	.bss
 common	_OPENSSL_ia32cap_P 16
diff --git a/third_party/boringssl/win-x86_64/crypto/bn/rsaz-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/bn/rsaz-x86_64.asm
index 04d5e39..72ec505 100644
--- a/third_party/boringssl/win-x86_64/crypto/bn/rsaz-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/bn/rsaz-x86_64.asm
@@ -504,48 +504,104 @@
 	push	r14
 	push	r15
 
-	mov	r9d,r9d
-	sub	rsp,128+24
+	sub	rsp,328
+	movaps	XMMWORD[160+rsp],xmm6
+	movaps	XMMWORD[176+rsp],xmm7
+	movaps	XMMWORD[192+rsp],xmm8
+	movaps	XMMWORD[208+rsp],xmm9
+	movaps	XMMWORD[224+rsp],xmm10
+	movaps	XMMWORD[240+rsp],xmm11
+	movaps	XMMWORD[256+rsp],xmm12
+	movaps	XMMWORD[272+rsp],xmm13
+	movaps	XMMWORD[288+rsp],xmm14
+	movaps	XMMWORD[304+rsp],xmm15
 $L$mul_gather4_body:
-	mov	eax,DWORD[64+r9*4+rdx]
-DB	102,72,15,110,199
-	mov	ebx,DWORD[r9*4+rdx]
-DB	102,72,15,110,201
-	mov	QWORD[128+rsp],r8
+	movd	xmm8,r9d
+	movdqa	xmm1,XMMWORD[(($L$inc+16))]
+	movdqa	xmm0,XMMWORD[$L$inc]
 
-	shl	rax,32
-	or	rbx,rax
+	pshufd	xmm8,xmm8,0
+	movdqa	xmm7,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm8
+	movdqa	xmm3,xmm7
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm8
+	movdqa	xmm4,xmm7
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm8
+	movdqa	xmm5,xmm7
+	paddd	xmm4,xmm3
+	pcmpeqd	xmm3,xmm8
+	movdqa	xmm6,xmm7
+	paddd	xmm5,xmm4
+	pcmpeqd	xmm4,xmm8
+	paddd	xmm6,xmm5
+	pcmpeqd	xmm5,xmm8
+	paddd	xmm7,xmm6
+	pcmpeqd	xmm6,xmm8
+	pcmpeqd	xmm7,xmm8
+
+	movdqa	xmm8,XMMWORD[rdx]
+	movdqa	xmm9,XMMWORD[16+rdx]
+	movdqa	xmm10,XMMWORD[32+rdx]
+	movdqa	xmm11,XMMWORD[48+rdx]
+	pand	xmm8,xmm0
+	movdqa	xmm12,XMMWORD[64+rdx]
+	pand	xmm9,xmm1
+	movdqa	xmm13,XMMWORD[80+rdx]
+	pand	xmm10,xmm2
+	movdqa	xmm14,XMMWORD[96+rdx]
+	pand	xmm11,xmm3
+	movdqa	xmm15,XMMWORD[112+rdx]
+	lea	rbp,[128+rdx]
+	pand	xmm12,xmm4
+	pand	xmm13,xmm5
+	pand	xmm14,xmm6
+	pand	xmm15,xmm7
+	por	xmm8,xmm10
+	por	xmm9,xmm11
+	por	xmm8,xmm12
+	por	xmm9,xmm13
+	por	xmm8,xmm14
+	por	xmm9,xmm15
+
+	por	xmm8,xmm9
+	pshufd	xmm9,xmm8,0x4e
+	por	xmm8,xmm9
+DB	102,76,15,126,195
+
+	mov	QWORD[128+rsp],r8
+	mov	QWORD[((128+8))+rsp],rdi
+	mov	QWORD[((128+16))+rsp],rcx
+
 	mov	rax,QWORD[rsi]
 	mov	rcx,QWORD[8+rsi]
-	lea	rbp,[128+r9*4+rdx]
 	mul	rbx
 	mov	QWORD[rsp],rax
 	mov	rax,rcx
 	mov	r8,rdx
 
 	mul	rbx
-	movd	xmm4,DWORD[rbp]
 	add	r8,rax
 	mov	rax,QWORD[16+rsi]
 	mov	r9,rdx
 	adc	r9,0
 
 	mul	rbx
-	movd	xmm5,DWORD[64+rbp]
 	add	r9,rax
 	mov	rax,QWORD[24+rsi]
 	mov	r10,rdx
 	adc	r10,0
 
 	mul	rbx
-	pslldq	xmm5,4
 	add	r10,rax
 	mov	rax,QWORD[32+rsi]
 	mov	r11,rdx
 	adc	r11,0
 
 	mul	rbx
-	por	xmm4,xmm5
 	add	r11,rax
 	mov	rax,QWORD[40+rsi]
 	mov	r12,rdx
@@ -558,14 +614,12 @@
 	adc	r13,0
 
 	mul	rbx
-	lea	rbp,[128+rbp]
 	add	r13,rax
 	mov	rax,QWORD[56+rsi]
 	mov	r14,rdx
 	adc	r14,0
 
 	mul	rbx
-DB	102,72,15,126,227
 	add	r14,rax
 	mov	rax,QWORD[rsi]
 	mov	r15,rdx
@@ -577,6 +631,35 @@
 
 ALIGN	32
 $L$oop_mul_gather:
+	movdqa	xmm8,XMMWORD[rbp]
+	movdqa	xmm9,XMMWORD[16+rbp]
+	movdqa	xmm10,XMMWORD[32+rbp]
+	movdqa	xmm11,XMMWORD[48+rbp]
+	pand	xmm8,xmm0
+	movdqa	xmm12,XMMWORD[64+rbp]
+	pand	xmm9,xmm1
+	movdqa	xmm13,XMMWORD[80+rbp]
+	pand	xmm10,xmm2
+	movdqa	xmm14,XMMWORD[96+rbp]
+	pand	xmm11,xmm3
+	movdqa	xmm15,XMMWORD[112+rbp]
+	lea	rbp,[128+rbp]
+	pand	xmm12,xmm4
+	pand	xmm13,xmm5
+	pand	xmm14,xmm6
+	pand	xmm15,xmm7
+	por	xmm8,xmm10
+	por	xmm9,xmm11
+	por	xmm8,xmm12
+	por	xmm9,xmm13
+	por	xmm8,xmm14
+	por	xmm9,xmm15
+
+	por	xmm8,xmm9
+	pshufd	xmm9,xmm8,0x4e
+	por	xmm8,xmm9
+DB	102,76,15,126,195
+
 	mul	rbx
 	add	r8,rax
 	mov	rax,QWORD[8+rsi]
@@ -585,7 +668,6 @@
 	adc	r8,0
 
 	mul	rbx
-	movd	xmm4,DWORD[rbp]
 	add	r9,rax
 	mov	rax,QWORD[16+rsi]
 	adc	rdx,0
@@ -594,7 +676,6 @@
 	adc	r9,0
 
 	mul	rbx
-	movd	xmm5,DWORD[64+rbp]
 	add	r10,rax
 	mov	rax,QWORD[24+rsi]
 	adc	rdx,0
@@ -603,7 +684,6 @@
 	adc	r10,0
 
 	mul	rbx
-	pslldq	xmm5,4
 	add	r11,rax
 	mov	rax,QWORD[32+rsi]
 	adc	rdx,0
@@ -612,7 +692,6 @@
 	adc	r11,0
 
 	mul	rbx
-	por	xmm4,xmm5
 	add	r12,rax
 	mov	rax,QWORD[40+rsi]
 	adc	rdx,0
@@ -637,7 +716,6 @@
 	adc	r14,0
 
 	mul	rbx
-DB	102,72,15,126,227
 	add	r15,rax
 	mov	rax,QWORD[rsi]
 	adc	rdx,0
@@ -645,7 +723,6 @@
 	mov	r15,rdx
 	adc	r15,0
 
-	lea	rbp,[128+rbp]
 	lea	rdi,[8+rdi]
 
 	dec	ecx
@@ -660,8 +737,8 @@
 	mov	QWORD[48+rdi],r14
 	mov	QWORD[56+rdi],r15
 
-DB	102,72,15,126,199
-DB	102,72,15,126,205
+	mov	rdi,QWORD[((128+8))+rsp]
+	mov	rbp,QWORD[((128+16))+rsp]
 
 	mov	r8,QWORD[rsp]
 	mov	r9,QWORD[8+rsp]
@@ -686,6 +763,17 @@
 	call	__rsaz_512_subtract
 
 	lea	rax,[((128+24+48))+rsp]
+	movaps	xmm6,XMMWORD[((160-200))+rax]
+	movaps	xmm7,XMMWORD[((176-200))+rax]
+	movaps	xmm8,XMMWORD[((192-200))+rax]
+	movaps	xmm9,XMMWORD[((208-200))+rax]
+	movaps	xmm10,XMMWORD[((224-200))+rax]
+	movaps	xmm11,XMMWORD[((240-200))+rax]
+	movaps	xmm12,XMMWORD[((256-200))+rax]
+	movaps	xmm13,XMMWORD[((272-200))+rax]
+	movaps	xmm14,XMMWORD[((288-200))+rax]
+	movaps	xmm15,XMMWORD[((304-200))+rax]
+	lea	rax,[176+rax]
 	mov	r15,QWORD[((-48))+rax]
 	mov	r14,QWORD[((-40))+rax]
 	mov	r13,QWORD[((-32))+rax]
@@ -724,7 +812,7 @@
 	mov	r9d,r9d
 	sub	rsp,128+24
 $L$mul_scatter4_body:
-	lea	r8,[r9*4+r8]
+	lea	r8,[r9*8+r8]
 DB	102,72,15,110,199
 DB	102,72,15,110,202
 DB	102,73,15,110,208
@@ -760,30 +848,14 @@
 
 	call	__rsaz_512_subtract
 
-	mov	DWORD[rsi],r8d
-	shr	r8,32
-	mov	DWORD[128+rsi],r9d
-	shr	r9,32
-	mov	DWORD[256+rsi],r10d
-	shr	r10,32
-	mov	DWORD[384+rsi],r11d
-	shr	r11,32
-	mov	DWORD[512+rsi],r12d
-	shr	r12,32
-	mov	DWORD[640+rsi],r13d
-	shr	r13,32
-	mov	DWORD[768+rsi],r14d
-	shr	r14,32
-	mov	DWORD[896+rsi],r15d
-	shr	r15,32
-	mov	DWORD[64+rsi],r8d
-	mov	DWORD[192+rsi],r9d
-	mov	DWORD[320+rsi],r10d
-	mov	DWORD[448+rsi],r11d
-	mov	DWORD[576+rsi],r12d
-	mov	DWORD[704+rsi],r13d
-	mov	DWORD[832+rsi],r14d
-	mov	DWORD[960+rsi],r15d
+	mov	QWORD[rsi],r8
+	mov	QWORD[128+rsi],r9
+	mov	QWORD[256+rsi],r10
+	mov	QWORD[384+rsi],r11
+	mov	QWORD[512+rsi],r12
+	mov	QWORD[640+rsi],r13
+	mov	QWORD[768+rsi],r14
+	mov	QWORD[896+rsi],r15
 
 	lea	rax,[((128+24+48))+rsp]
 	mov	r15,QWORD[((-48))+rax]
@@ -1150,16 +1222,14 @@
 
 ALIGN	16
 rsaz_512_scatter4:
-	lea	rcx,[r8*4+rcx]
+	lea	rcx,[r8*8+rcx]
 	mov	r9d,8
 	jmp	NEAR $L$oop_scatter
 ALIGN	16
 $L$oop_scatter:
 	mov	rax,QWORD[rdx]
 	lea	rdx,[8+rdx]
-	mov	DWORD[rcx],eax
-	shr	rax,32
-	mov	DWORD[64+rcx],eax
+	mov	QWORD[rcx],rax
 	lea	rcx,[128+rcx]
 	dec	r9d
 	jnz	NEAR $L$oop_scatter
@@ -1170,22 +1240,98 @@
 
 ALIGN	16
 rsaz_512_gather4:
-	lea	rdx,[r8*4+rdx]
+$L$SEH_begin_rsaz_512_gather4:
+DB	0x48,0x81,0xec,0xa8,0x00,0x00,0x00
+DB	0x0f,0x29,0x34,0x24
+DB	0x0f,0x29,0x7c,0x24,0x10
+DB	0x44,0x0f,0x29,0x44,0x24,0x20
+DB	0x44,0x0f,0x29,0x4c,0x24,0x30
+DB	0x44,0x0f,0x29,0x54,0x24,0x40
+DB	0x44,0x0f,0x29,0x5c,0x24,0x50
+DB	0x44,0x0f,0x29,0x64,0x24,0x60
+DB	0x44,0x0f,0x29,0x6c,0x24,0x70
+DB	0x44,0x0f,0x29,0xb4,0x24,0x80,0,0,0
+DB	0x44,0x0f,0x29,0xbc,0x24,0x90,0,0,0
+	movd	xmm8,r8d
+	movdqa	xmm1,XMMWORD[(($L$inc+16))]
+	movdqa	xmm0,XMMWORD[$L$inc]
+
+	pshufd	xmm8,xmm8,0
+	movdqa	xmm7,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm8
+	movdqa	xmm3,xmm7
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm8
+	movdqa	xmm4,xmm7
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm8
+	movdqa	xmm5,xmm7
+	paddd	xmm4,xmm3
+	pcmpeqd	xmm3,xmm8
+	movdqa	xmm6,xmm7
+	paddd	xmm5,xmm4
+	pcmpeqd	xmm4,xmm8
+	paddd	xmm6,xmm5
+	pcmpeqd	xmm5,xmm8
+	paddd	xmm7,xmm6
+	pcmpeqd	xmm6,xmm8
+	pcmpeqd	xmm7,xmm8
 	mov	r9d,8
 	jmp	NEAR $L$oop_gather
 ALIGN	16
 $L$oop_gather:
-	mov	eax,DWORD[rdx]
-	mov	r8d,DWORD[64+rdx]
+	movdqa	xmm8,XMMWORD[rdx]
+	movdqa	xmm9,XMMWORD[16+rdx]
+	movdqa	xmm10,XMMWORD[32+rdx]
+	movdqa	xmm11,XMMWORD[48+rdx]
+	pand	xmm8,xmm0
+	movdqa	xmm12,XMMWORD[64+rdx]
+	pand	xmm9,xmm1
+	movdqa	xmm13,XMMWORD[80+rdx]
+	pand	xmm10,xmm2
+	movdqa	xmm14,XMMWORD[96+rdx]
+	pand	xmm11,xmm3
+	movdqa	xmm15,XMMWORD[112+rdx]
 	lea	rdx,[128+rdx]
-	shl	r8,32
-	or	rax,r8
-	mov	QWORD[rcx],rax
+	pand	xmm12,xmm4
+	pand	xmm13,xmm5
+	pand	xmm14,xmm6
+	pand	xmm15,xmm7
+	por	xmm8,xmm10
+	por	xmm9,xmm11
+	por	xmm8,xmm12
+	por	xmm9,xmm13
+	por	xmm8,xmm14
+	por	xmm9,xmm15
+
+	por	xmm8,xmm9
+	pshufd	xmm9,xmm8,0x4e
+	por	xmm8,xmm9
+	movq	QWORD[rcx],xmm8
 	lea	rcx,[8+rcx]
 	dec	r9d
 	jnz	NEAR $L$oop_gather
+	movaps	xmm6,XMMWORD[rsp]
+	movaps	xmm7,XMMWORD[16+rsp]
+	movaps	xmm8,XMMWORD[32+rsp]
+	movaps	xmm9,XMMWORD[48+rsp]
+	movaps	xmm10,XMMWORD[64+rsp]
+	movaps	xmm11,XMMWORD[80+rsp]
+	movaps	xmm12,XMMWORD[96+rsp]
+	movaps	xmm13,XMMWORD[112+rsp]
+	movaps	xmm14,XMMWORD[128+rsp]
+	movaps	xmm15,XMMWORD[144+rsp]
+	add	rsp,0xa8
 	DB	0F3h,0C3h		;repret
+$L$SEH_end_rsaz_512_gather4:
 
+
+ALIGN	64
+$L$inc:
+	DD	0,0,1,1
+	DD	2,2,2,2
 EXTERN	__imp_RtlVirtualUnwind
 
 ALIGN	16
@@ -1221,6 +1367,18 @@
 
 	lea	rax,[((128+24+48))+rax]
 
+	lea	rbx,[$L$mul_gather4_epilogue]
+	cmp	rbx,r10
+	jne	NEAR $L$se_not_in_mul_gather4
+
+	lea	rax,[176+rax]
+
+	lea	rsi,[((-48-168))+rax]
+	lea	rdi,[512+r8]
+	mov	ecx,20
+	DD	0xa548f3fc
+
+$L$se_not_in_mul_gather4:
 	mov	rbx,QWORD[((-8))+rax]
 	mov	rbp,QWORD[((-16))+rax]
 	mov	r12,QWORD[((-24))+rax]
@@ -1296,6 +1454,10 @@
 	DD	$L$SEH_end_rsaz_512_mul_by_one wrt ..imagebase
 	DD	$L$SEH_info_rsaz_512_mul_by_one wrt ..imagebase
 
+	DD	$L$SEH_begin_rsaz_512_gather4 wrt ..imagebase
+	DD	$L$SEH_end_rsaz_512_gather4 wrt ..imagebase
+	DD	$L$SEH_info_rsaz_512_gather4 wrt ..imagebase
+
 section	.xdata rdata align=8
 ALIGN	8
 $L$SEH_info_rsaz_512_sqr:
@@ -1318,3 +1480,16 @@
 DB	9,0,0,0
 	DD	se_handler wrt ..imagebase
 	DD	$L$mul_by_one_body wrt ..imagebase,$L$mul_by_one_epilogue wrt ..imagebase
+$L$SEH_info_rsaz_512_gather4:
+DB	0x01,0x46,0x16,0x00
+DB	0x46,0xf8,0x09,0x00
+DB	0x3d,0xe8,0x08,0x00
+DB	0x34,0xd8,0x07,0x00
+DB	0x2e,0xc8,0x06,0x00
+DB	0x28,0xb8,0x05,0x00
+DB	0x22,0xa8,0x04,0x00
+DB	0x1c,0x98,0x03,0x00
+DB	0x16,0x88,0x02,0x00
+DB	0x10,0x78,0x01,0x00
+DB	0x0b,0x68,0x00,0x00
+DB	0x07,0x01,0x15,0x00
diff --git a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont.asm b/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont.asm
index db0d1b9..4d8e1cb 100644
--- a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont.asm
+++ b/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont.asm
@@ -677,20 +677,20 @@
 
 
 
-	lea	r11,[((-64))+r9*4+rsp]
+	lea	r11,[((-64))+r9*2+rsp]
 	mov	r8,QWORD[r8]
 	sub	r11,rsi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$sqr8x_sp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*4+rsp]
+	lea	rsp,[((-64))+r9*2+rsp]
 	jmp	NEAR $L$sqr8x_sp_done
 
 ALIGN	32
 $L$sqr8x_sp_alt:
-	lea	r10,[((4096-64))+r9*4]
-	lea	rsp,[((-64))+r9*4+rsp]
+	lea	r10,[((4096-64))+r9*2]
+	lea	rsp,[((-64))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -700,58 +700,80 @@
 	mov	r10,r9
 	neg	r9
 
-	lea	r11,[64+r9*2+rsp]
 	mov	QWORD[32+rsp],r8
 	mov	QWORD[40+rsp],rax
 $L$sqr8x_body:
 
-	mov	rbp,r9
-DB	102,73,15,110,211
-	shr	rbp,3+2
-	mov	eax,DWORD[((OPENSSL_ia32cap_P+8))]
-	jmp	NEAR $L$sqr8x_copy_n
-
-ALIGN	32
-$L$sqr8x_copy_n:
-	movq	xmm0,QWORD[rcx]
-	movq	xmm1,QWORD[8+rcx]
-	movq	xmm3,QWORD[16+rcx]
-	movq	xmm4,QWORD[24+rcx]
-	lea	rcx,[32+rcx]
-	movdqa	XMMWORD[r11],xmm0
-	movdqa	XMMWORD[16+r11],xmm1
-	movdqa	XMMWORD[32+r11],xmm3
-	movdqa	XMMWORD[48+r11],xmm4
-	lea	r11,[64+r11]
-	dec	rbp
-	jnz	NEAR $L$sqr8x_copy_n
-
+DB	102,72,15,110,209
 	pxor	xmm0,xmm0
 DB	102,72,15,110,207
 DB	102,73,15,110,218
 	call	bn_sqr8x_internal
 
-	pxor	xmm0,xmm0
-	lea	rax,[48+rsp]
-	lea	rdx,[64+r9*2+rsp]
-	shr	r9,3+2
-	mov	rsi,QWORD[40+rsp]
-	jmp	NEAR $L$sqr8x_zero
+
+
+
+	lea	rbx,[r9*1+rdi]
+	mov	rcx,r9
+	mov	rdx,r9
+DB	102,72,15,126,207
+	sar	rcx,3+2
+	jmp	NEAR $L$sqr8x_sub
 
 ALIGN	32
-$L$sqr8x_zero:
-	movdqa	XMMWORD[rax],xmm0
-	movdqa	XMMWORD[16+rax],xmm0
-	movdqa	XMMWORD[32+rax],xmm0
-	movdqa	XMMWORD[48+rax],xmm0
-	lea	rax,[64+rax]
-	movdqa	XMMWORD[rdx],xmm0
-	movdqa	XMMWORD[16+rdx],xmm0
-	movdqa	XMMWORD[32+rdx],xmm0
-	movdqa	XMMWORD[48+rdx],xmm0
-	lea	rdx,[64+rdx]
-	dec	r9
-	jnz	NEAR $L$sqr8x_zero
+$L$sqr8x_sub:
+	mov	r12,QWORD[rbx]
+	mov	r13,QWORD[8+rbx]
+	mov	r14,QWORD[16+rbx]
+	mov	r15,QWORD[24+rbx]
+	lea	rbx,[32+rbx]
+	sbb	r12,QWORD[rbp]
+	sbb	r13,QWORD[8+rbp]
+	sbb	r14,QWORD[16+rbp]
+	sbb	r15,QWORD[24+rbp]
+	lea	rbp,[32+rbp]
+	mov	QWORD[rdi],r12
+	mov	QWORD[8+rdi],r13
+	mov	QWORD[16+rdi],r14
+	mov	QWORD[24+rdi],r15
+	lea	rdi,[32+rdi]
+	inc	rcx
+	jnz	NEAR $L$sqr8x_sub
+
+	sbb	rax,0
+	lea	rbx,[r9*1+rbx]
+	lea	rdi,[r9*1+rdi]
+
+DB	102,72,15,110,200
+	pxor	xmm0,xmm0
+	pshufd	xmm1,xmm1,0
+	mov	rsi,QWORD[40+rsp]
+	jmp	NEAR $L$sqr8x_cond_copy
+
+ALIGN	32
+$L$sqr8x_cond_copy:
+	movdqa	xmm2,XMMWORD[rbx]
+	movdqa	xmm3,XMMWORD[16+rbx]
+	lea	rbx,[32+rbx]
+	movdqu	xmm4,XMMWORD[rdi]
+	movdqu	xmm5,XMMWORD[16+rdi]
+	lea	rdi,[32+rdi]
+	movdqa	XMMWORD[(-32)+rbx],xmm0
+	movdqa	XMMWORD[(-16)+rbx],xmm0
+	movdqa	XMMWORD[(-32)+rdx*1+rbx],xmm0
+	movdqa	XMMWORD[(-16)+rdx*1+rbx],xmm0
+	pcmpeqd	xmm0,xmm1
+	pand	xmm2,xmm1
+	pand	xmm3,xmm1
+	pand	xmm4,xmm0
+	pand	xmm5,xmm0
+	pxor	xmm0,xmm0
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqu	XMMWORD[(-32)+rdi],xmm4
+	movdqu	XMMWORD[(-16)+rdi],xmm5
+	add	r9,32
+	jnz	NEAR $L$sqr8x_cond_copy
 
 	mov	rax,1
 	mov	r15,QWORD[((-48))+rsi]
diff --git a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm b/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm
index 284318a..cd9a6e5 100644
--- a/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm
+++ b/third_party/boringssl/win-x86_64/crypto/bn/x86_64-mont5.asm
@@ -31,49 +31,151 @@
 $L$mul_enter:
 	mov	r9d,r9d
 	mov	rax,rsp
-	mov	r10d,DWORD[56+rsp]
+	movd	xmm5,DWORD[56+rsp]
+	lea	r10,[$L$inc]
 	push	rbx
 	push	rbp
 	push	r12
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
+
 	lea	r11,[2+r9]
 	neg	r11
-	lea	rsp,[r11*8+rsp]
+	lea	rsp,[((-264))+r11*8+rsp]
 	and	rsp,-1024
 
 	mov	QWORD[8+r9*8+rsp],rax
 $L$mul_body:
-	mov	r12,rdx
-	mov	r11,r10
-	shr	r10,3
-	and	r11,7
-	not	r10
-	lea	rax,[$L$magic_masks]
-	and	r10,3
-	lea	r12,[96+r11*8+r12]
-	movq	xmm4,QWORD[r10*8+rax]
-	movq	xmm5,QWORD[8+r10*8+rax]
-	movq	xmm6,QWORD[16+r10*8+rax]
-	movq	xmm7,QWORD[24+r10*8+rax]
+	lea	r12,[128+rdx]
+	movdqa	xmm0,XMMWORD[r10]
+	movdqa	xmm1,XMMWORD[16+r10]
+	lea	r10,[((24-112))+r9*8+rsp]
+	and	r10,-16
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
+	pshufd	xmm5,xmm5,0
+	movdqa	xmm4,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+DB	0x67
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[112+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[128+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[144+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[160+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[176+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[192+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[208+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[224+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[240+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[256+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[272+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[288+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[304+r10],xmm0
+
+	paddd	xmm3,xmm2
+DB	0x67
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[320+r10],xmm1
+
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[336+r10],xmm2
+	pand	xmm0,XMMWORD[64+r12]
+
+	pand	xmm1,XMMWORD[80+r12]
+	pand	xmm2,XMMWORD[96+r12]
+	movdqa	XMMWORD[352+r10],xmm3
+	pand	xmm3,XMMWORD[112+r12]
 	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-128))+r12]
+	movdqa	xmm5,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	pand	xmm4,XMMWORD[112+r10]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm5,XMMWORD[128+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[144+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[160+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-64))+r12]
+	movdqa	xmm5,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	pand	xmm4,XMMWORD[176+r10]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm5,XMMWORD[192+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[208+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[224+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[r12]
+	movdqa	xmm5,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	pand	xmm4,XMMWORD[240+r10]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm5,XMMWORD[256+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[272+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[288+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	por	xmm0,xmm1
+	pshufd	xmm1,xmm0,0x4e
+	por	xmm0,xmm1
 	lea	r12,[256+r12]
-	por	xmm0,xmm3
-
 DB	102,72,15,126,195
 
 	mov	r8,QWORD[r8]
@@ -82,29 +184,14 @@
 	xor	r14,r14
 	xor	r15,r15
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-
 	mov	rbp,r8
 	mul	rbx
 	mov	r10,rax
 	mov	rax,QWORD[rcx]
 
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-
 	imul	rbp,r10
 	mov	r11,rdx
 
-	por	xmm0,xmm2
-	lea	r12,[256+r12]
-	por	xmm0,xmm3
-
 	mul	rbp
 	add	r10,rax
 	mov	rax,QWORD[8+rsi]
@@ -137,14 +224,12 @@
 	cmp	r15,r9
 	jne	NEAR $L$1st
 
-DB	102,72,15,126,195
 
 	add	r13,rax
-	mov	rax,QWORD[rsi]
 	adc	rdx,0
 	add	r13,r11
 	adc	rdx,0
-	mov	QWORD[((-16))+r15*8+rsp],r13
+	mov	QWORD[((-16))+r9*8+rsp],r13
 	mov	r13,rdx
 	mov	r11,r10
 
@@ -158,33 +243,78 @@
 	jmp	NEAR $L$outer
 ALIGN	16
 $L$outer:
+	lea	rdx,[((24+128))+r9*8+rsp]
+	and	rdx,-16
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+	movdqa	xmm0,XMMWORD[((-128))+r12]
+	movdqa	xmm1,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm0,XMMWORD[((-128))+rdx]
+	pand	xmm1,XMMWORD[((-112))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-96))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-80))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[((-64))+r12]
+	movdqa	xmm1,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm0,XMMWORD[((-64))+rdx]
+	pand	xmm1,XMMWORD[((-48))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-32))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-16))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[r12]
+	movdqa	xmm1,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm0,XMMWORD[rdx]
+	pand	xmm1,XMMWORD[16+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[32+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[48+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[64+r12]
+	movdqa	xmm1,XMMWORD[80+r12]
+	movdqa	xmm2,XMMWORD[96+r12]
+	movdqa	xmm3,XMMWORD[112+r12]
+	pand	xmm0,XMMWORD[64+rdx]
+	pand	xmm1,XMMWORD[80+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[96+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[112+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	por	xmm4,xmm5
+	pshufd	xmm0,xmm4,0x4e
+	por	xmm0,xmm4
+	lea	r12,[256+r12]
+
+	mov	rax,QWORD[rsi]
+DB	102,72,15,126,195
+
 	xor	r15,r15
 	mov	rbp,r8
 	mov	r10,QWORD[rsp]
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-
 	mul	rbx
 	add	r10,rax
 	mov	rax,QWORD[rcx]
 	adc	rdx,0
 
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-
 	imul	rbp,r10
 	mov	r11,rdx
 
-	por	xmm0,xmm2
-	lea	r12,[256+r12]
-	por	xmm0,xmm3
-
 	mul	rbp
 	add	r10,rax
 	mov	rax,QWORD[8+rsi]
@@ -220,15 +350,12 @@
 	cmp	r15,r9
 	jne	NEAR $L$inner
 
-DB	102,72,15,126,195
-
 	add	r13,rax
-	mov	rax,QWORD[rsi]
 	adc	rdx,0
 	add	r13,r10
-	mov	r10,QWORD[r15*8+rsp]
+	mov	r10,QWORD[r9*8+rsp]
 	adc	rdx,0
-	mov	QWORD[((-16))+r15*8+rsp],r13
+	mov	QWORD[((-16))+r9*8+rsp],r13
 	mov	r13,rdx
 
 	xor	rdx,rdx
@@ -274,8 +401,7 @@
 
 	mov	rsi,QWORD[8+r9*8+rsp]
 	mov	rax,1
-	movaps	xmm6,XMMWORD[((-88))+rsi]
-	movaps	xmm7,XMMWORD[((-72))+rsi]
+
 	mov	r15,QWORD[((-48))+rsi]
 	mov	r14,QWORD[((-40))+rsi]
 	mov	r13,QWORD[((-32))+rsi]
@@ -312,13 +438,10 @@
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
+
 DB	0x67
-	mov	r10d,r9d
 	shl	r9d,3
-	shl	r10d,3+2
+	lea	r10,[r9*2+r9]
 	neg	r9
 
 
@@ -328,19 +451,21 @@
 
 
 
-	lea	r11,[((-64))+r9*2+rsp]
-	sub	r11,rsi
+
+
+	lea	r11,[((-320))+r9*2+rsp]
+	sub	r11,rdi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$mul4xsp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	rsp,[((-320))+r9*2+rsp]
 	jmp	NEAR $L$mul4xsp_done
 
 ALIGN	32
 $L$mul4xsp_alt:
-	lea	r10,[((4096-64))+r9*2]
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	r10,[((4096-320))+r9*2]
+	lea	rsp,[((-320))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -356,8 +481,7 @@
 
 	mov	rsi,QWORD[40+rsp]
 	mov	rax,1
-	movaps	xmm6,XMMWORD[((-88))+rsi]
-	movaps	xmm7,XMMWORD[((-72))+rsi]
+
 	mov	r15,QWORD[((-48))+rsi]
 	mov	r14,QWORD[((-40))+rsi]
 	mov	r13,QWORD[((-32))+rsi]
@@ -375,47 +499,141 @@
 ALIGN	32
 mul4x_internal:
 	shl	r9,5
-	mov	r10d,DWORD[56+rax]
-	lea	r13,[256+r9*1+rdx]
+	movd	xmm5,DWORD[56+rax]
+	lea	rax,[$L$inc]
+	lea	r13,[128+r9*1+rdx]
 	shr	r9,5
-	mov	r11,r10
-	shr	r10,3
-	and	r11,7
-	not	r10
-	lea	rax,[$L$magic_masks]
-	and	r10,3
-	lea	r12,[96+r11*8+rdx]
-	movq	xmm4,QWORD[r10*8+rax]
-	movq	xmm5,QWORD[8+r10*8+rax]
-	add	r11,7
-	movq	xmm6,QWORD[16+r10*8+rax]
-	movq	xmm7,QWORD[24+r10*8+rax]
-	and	r11,7
+	movdqa	xmm0,XMMWORD[rax]
+	movdqa	xmm1,XMMWORD[16+rax]
+	lea	r10,[((88-112))+r9*1+rsp]
+	lea	r12,[128+rdx]
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	lea	r14,[256+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[96+r12]
-	pand	xmm2,xmm6
+	pshufd	xmm5,xmm5,0
+	movdqa	xmm4,xmm1
+DB	0x67,0x67
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
 DB	0x67
-	por	xmm0,xmm1
-	movq	xmm1,QWORD[((-96))+r14]
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[112+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[128+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[144+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[160+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[176+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[192+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[208+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[224+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[240+r10],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[256+r10],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[272+r10],xmm2
+	movdqa	xmm2,xmm4
+
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[288+r10],xmm3
+	movdqa	xmm3,xmm4
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[304+r10],xmm0
+
+	paddd	xmm3,xmm2
 DB	0x67
-	pand	xmm3,xmm7
-DB	0x67
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[320+r10],xmm1
+
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[336+r10],xmm2
+	pand	xmm0,XMMWORD[64+r12]
+
+	pand	xmm1,XMMWORD[80+r12]
+	pand	xmm2,XMMWORD[96+r12]
+	movdqa	XMMWORD[352+r10],xmm3
+	pand	xmm3,XMMWORD[112+r12]
 	por	xmm0,xmm2
-	movq	xmm2,QWORD[((-32))+r14]
-DB	0x67
-	pand	xmm1,xmm4
-DB	0x67
-	por	xmm0,xmm3
-	movq	xmm3,QWORD[32+r14]
-
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-128))+r12]
+	movdqa	xmm5,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	pand	xmm4,XMMWORD[112+r10]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm5,XMMWORD[128+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[144+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[160+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[((-64))+r12]
+	movdqa	xmm5,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	pand	xmm4,XMMWORD[176+r10]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm5,XMMWORD[192+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[208+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[224+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	movdqa	xmm4,XMMWORD[r12]
+	movdqa	xmm5,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	pand	xmm4,XMMWORD[240+r10]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm5,XMMWORD[256+r10]
+	por	xmm0,xmm4
+	pand	xmm2,XMMWORD[272+r10]
+	por	xmm1,xmm5
+	pand	xmm3,XMMWORD[288+r10]
+	por	xmm0,xmm2
+	por	xmm1,xmm3
+	por	xmm0,xmm1
+	pshufd	xmm1,xmm0,0x4e
+	por	xmm0,xmm1
+	lea	r12,[256+r12]
 DB	102,72,15,126,195
-	movq	xmm0,QWORD[96+r14]
+
 	mov	QWORD[((16+8))+rsp],r13
 	mov	QWORD[((56+8))+rsp],rdi
 
@@ -429,26 +647,10 @@
 	mov	r10,rax
 	mov	rax,QWORD[rcx]
 
-	pand	xmm2,xmm5
-	pand	xmm3,xmm6
-	por	xmm1,xmm2
-
 	imul	rbp,r10
-
-
-
-
-
-
-
-	lea	r14,[((64+8))+r11*8+rsp]
+	lea	r14,[((64+8))+rsp]
 	mov	r11,rdx
 
-	pand	xmm0,xmm7
-	por	xmm1,xmm3
-	lea	r12,[512+r12]
-	por	xmm0,xmm1
-
 	mul	rbp
 	add	r10,rax
 	mov	rax,QWORD[8+r9*1+rsi]
@@ -457,7 +659,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -467,7 +669,7 @@
 	adc	rdx,0
 	add	rdi,r11
 	lea	r15,[32+r9]
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	QWORD[r14],rdi
 	mov	r13,rdx
@@ -477,7 +679,7 @@
 $L$1st4x:
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	lea	r14,[32+r14]
 	adc	rdx,0
 	mov	r11,rdx
@@ -493,7 +695,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[((-16))+rcx]
+	mov	rax,QWORD[((-8))+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -523,7 +725,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -532,7 +734,7 @@
 	mov	rax,QWORD[16+r15*1+rsi]
 	adc	rdx,0
 	add	rdi,r11
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	QWORD[r14],rdi
 	mov	r13,rdx
@@ -542,7 +744,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	lea	r14,[32+r14]
 	adc	rdx,0
 	mov	r11,rdx
@@ -558,7 +760,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[((-16))+rcx]
+	mov	rax,QWORD[((-8))+rcx]
 	adc	rdx,0
 	mov	r10,rdx
 
@@ -571,8 +773,7 @@
 	mov	QWORD[((-16))+r14],rdi
 	mov	r13,rdx
 
-DB	102,72,15,126,195
-	lea	rcx,[r9*2+rcx]
+	lea	rcx,[r9*1+rcx]
 
 	xor	rdi,rdi
 	add	r13,r10
@@ -583,6 +784,63 @@
 
 ALIGN	32
 $L$outer4x:
+	lea	rdx,[((16+128))+r14]
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+	movdqa	xmm0,XMMWORD[((-128))+r12]
+	movdqa	xmm1,XMMWORD[((-112))+r12]
+	movdqa	xmm2,XMMWORD[((-96))+r12]
+	movdqa	xmm3,XMMWORD[((-80))+r12]
+	pand	xmm0,XMMWORD[((-128))+rdx]
+	pand	xmm1,XMMWORD[((-112))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-96))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-80))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[((-64))+r12]
+	movdqa	xmm1,XMMWORD[((-48))+r12]
+	movdqa	xmm2,XMMWORD[((-32))+r12]
+	movdqa	xmm3,XMMWORD[((-16))+r12]
+	pand	xmm0,XMMWORD[((-64))+rdx]
+	pand	xmm1,XMMWORD[((-48))+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-32))+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-16))+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[r12]
+	movdqa	xmm1,XMMWORD[16+r12]
+	movdqa	xmm2,XMMWORD[32+r12]
+	movdqa	xmm3,XMMWORD[48+r12]
+	pand	xmm0,XMMWORD[rdx]
+	pand	xmm1,XMMWORD[16+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[32+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[48+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[64+r12]
+	movdqa	xmm1,XMMWORD[80+r12]
+	movdqa	xmm2,XMMWORD[96+r12]
+	movdqa	xmm3,XMMWORD[112+r12]
+	pand	xmm0,XMMWORD[64+rdx]
+	pand	xmm1,XMMWORD[80+rdx]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[96+rdx]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[112+rdx]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	por	xmm4,xmm5
+	pshufd	xmm0,xmm4,0x4e
+	por	xmm0,xmm4
+	lea	r12,[256+r12]
+DB	102,72,15,126,195
+
 	mov	r10,QWORD[r9*1+r14]
 	mov	rbp,r8
 	mul	rbx
@@ -590,25 +848,11 @@
 	mov	rax,QWORD[rcx]
 	adc	rdx,0
 
-	movq	xmm0,QWORD[(((-96)))+r12]
-	movq	xmm1,QWORD[((-32))+r12]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[32+r12]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[96+r12]
-
 	imul	rbp,r10
-DB	0x67
 	mov	r11,rdx
 	mov	QWORD[r14],rdi
 
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-	por	xmm0,xmm2
 	lea	r14,[r9*1+r14]
-	lea	r12,[256+r12]
-	por	xmm0,xmm3
 
 	mul	rbp
 	add	r10,rax
@@ -618,7 +862,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	add	r11,QWORD[8+r14]
 	adc	rdx,0
@@ -630,7 +874,7 @@
 	adc	rdx,0
 	add	rdi,r11
 	lea	r15,[32+r9]
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	r13,rdx
 	jmp	NEAR $L$inner4x
@@ -639,7 +883,7 @@
 $L$inner4x:
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	adc	rdx,0
 	add	r10,QWORD[16+r14]
 	lea	r14,[32+r14]
@@ -657,7 +901,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[((-16))+rcx]
+	mov	rax,QWORD[((-8))+rcx]
 	adc	rdx,0
 	add	r11,QWORD[((-8))+r14]
 	adc	rdx,0
@@ -691,7 +935,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[16+rcx]
+	mov	rax,QWORD[8+rcx]
 	adc	rdx,0
 	add	r11,QWORD[8+r14]
 	adc	rdx,0
@@ -702,7 +946,7 @@
 	mov	rax,QWORD[16+r15*1+rsi]
 	adc	rdx,0
 	add	rdi,r11
-	lea	rcx,[64+rcx]
+	lea	rcx,[32+rcx]
 	adc	rdx,0
 	mov	QWORD[((-8))+r14],r13
 	mov	r13,rdx
@@ -712,7 +956,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[((-32))+rcx]
+	mov	rax,QWORD[((-16))+rcx]
 	adc	rdx,0
 	add	r10,QWORD[16+r14]
 	lea	r14,[32+r14]
@@ -731,7 +975,7 @@
 	mul	rbx
 	add	r11,rax
 	mov	rax,rbp
-	mov	rbp,QWORD[((-16))+rcx]
+	mov	rbp,QWORD[((-8))+rcx]
 	adc	rdx,0
 	add	r11,QWORD[((-8))+r14]
 	adc	rdx,0
@@ -746,9 +990,8 @@
 	mov	QWORD[((-24))+r14],r13
 	mov	r13,rdx
 
-DB	102,72,15,126,195
 	mov	QWORD[((-16))+r14],rdi
-	lea	rcx,[r9*2+rcx]
+	lea	rcx,[r9*1+rcx]
 
 	xor	rdi,rdi
 	add	r13,r10
@@ -759,16 +1002,23 @@
 
 	cmp	r12,QWORD[((16+8))+rsp]
 	jb	NEAR $L$outer4x
+	xor	rax,rax
 	sub	rbp,r13
 	adc	r15,r15
 	or	rdi,r15
-	xor	rdi,1
+	sub	rax,rdi
 	lea	rbx,[r9*1+r14]
-	lea	rbp,[rdi*8+rcx]
+	mov	r12,QWORD[rcx]
+	lea	rbp,[rcx]
 	mov	rcx,r9
 	sar	rcx,3+2
 	mov	rdi,QWORD[((56+8))+rsp]
-	jmp	NEAR $L$sqr4x_sub
+	dec	r12
+	xor	r10,r10
+	mov	r13,QWORD[8+rbp]
+	mov	r14,QWORD[16+rbp]
+	mov	r15,QWORD[24+rbp]
+	jmp	NEAR $L$sqr4x_sub_entry
 
 global	bn_power5
 
@@ -793,12 +1043,9 @@
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-	mov	r10d,r9d
+
 	shl	r9d,3
-	shl	r10d,3+2
+	lea	r10d,[r9*2+r9]
 	neg	r9
 	mov	r8,QWORD[r8]
 
@@ -808,19 +1055,20 @@
 
 
 
-	lea	r11,[((-64))+r9*2+rsp]
-	sub	r11,rsi
+
+	lea	r11,[((-320))+r9*2+rsp]
+	sub	r11,rdi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$pwr_sp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	rsp,[((-320))+r9*2+rsp]
 	jmp	NEAR $L$pwr_sp_done
 
 ALIGN	32
 $L$pwr_sp_alt:
-	lea	r10,[((4096-64))+r9*2]
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	r10,[((4096-320))+r9*2]
+	lea	rsp,[((-320))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -848,10 +1096,15 @@
 DB	102,72,15,110,226
 
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 	call	__bn_sqr8x_internal
+	call	__bn_post4x_internal
 
 DB	102,72,15,126,209
 DB	102,72,15,126,226
@@ -1397,9 +1650,9 @@
 	mov	QWORD[((-16))+rdi],rbx
 	mov	QWORD[((-8))+rdi],r8
 DB	102,72,15,126,213
-sqr8x_reduction:
+__bn_sqr8x_reduction:
 	xor	rax,rax
-	lea	rcx,[r9*2+rbp]
+	lea	rcx,[rbp*1+r9]
 	lea	rdx,[((48+8))+r9*2+rsp]
 	mov	QWORD[((0+8))+rsp],rcx
 	lea	rdi,[((48+8))+r9*1+rsp]
@@ -1432,14 +1685,14 @@
 ALIGN	32
 $L$8x_reduce:
 	mul	rbx
-	mov	rax,QWORD[16+rbp]
+	mov	rax,QWORD[8+rbp]
 	neg	r8
 	mov	r8,rdx
 	adc	r8,0
 
 	mul	rbx
 	add	r9,rax
-	mov	rax,QWORD[32+rbp]
+	mov	rax,QWORD[16+rbp]
 	adc	rdx,0
 	add	r8,r9
 	mov	QWORD[((48-8+8))+rcx*8+rsp],rbx
@@ -1448,7 +1701,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[48+rbp]
+	mov	rax,QWORD[24+rbp]
 	adc	rdx,0
 	add	r9,r10
 	mov	rsi,QWORD[((32+8))+rsp]
@@ -1457,7 +1710,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[64+rbp]
+	mov	rax,QWORD[32+rbp]
 	adc	rdx,0
 	imul	rsi,r8
 	add	r10,r11
@@ -1466,7 +1719,7 @@
 
 	mul	rbx
 	add	r12,rax
-	mov	rax,QWORD[80+rbp]
+	mov	rax,QWORD[40+rbp]
 	adc	rdx,0
 	add	r11,r12
 	mov	r12,rdx
@@ -1474,7 +1727,7 @@
 
 	mul	rbx
 	add	r13,rax
-	mov	rax,QWORD[96+rbp]
+	mov	rax,QWORD[48+rbp]
 	adc	rdx,0
 	add	r12,r13
 	mov	r13,rdx
@@ -1482,7 +1735,7 @@
 
 	mul	rbx
 	add	r14,rax
-	mov	rax,QWORD[112+rbp]
+	mov	rax,QWORD[56+rbp]
 	adc	rdx,0
 	add	r13,r14
 	mov	r14,rdx
@@ -1500,7 +1753,7 @@
 	dec	ecx
 	jnz	NEAR $L$8x_reduce
 
-	lea	rbp,[128+rbp]
+	lea	rbp,[64+rbp]
 	xor	rax,rax
 	mov	rdx,QWORD[((8+8))+rsp]
 	cmp	rbp,QWORD[((0+8))+rsp]
@@ -1526,14 +1779,14 @@
 $L$8x_tail:
 	mul	rbx
 	add	r8,rax
-	mov	rax,QWORD[16+rbp]
+	mov	rax,QWORD[8+rbp]
 	mov	QWORD[rdi],r8
 	mov	r8,rdx
 	adc	r8,0
 
 	mul	rbx
 	add	r9,rax
-	mov	rax,QWORD[32+rbp]
+	mov	rax,QWORD[16+rbp]
 	adc	rdx,0
 	add	r8,r9
 	lea	rdi,[8+rdi]
@@ -1542,7 +1795,7 @@
 
 	mul	rbx
 	add	r10,rax
-	mov	rax,QWORD[48+rbp]
+	mov	rax,QWORD[24+rbp]
 	adc	rdx,0
 	add	r9,r10
 	mov	r10,rdx
@@ -1550,7 +1803,7 @@
 
 	mul	rbx
 	add	r11,rax
-	mov	rax,QWORD[64+rbp]
+	mov	rax,QWORD[32+rbp]
 	adc	rdx,0
 	add	r10,r11
 	mov	r11,rdx
@@ -1558,7 +1811,7 @@
 
 	mul	rbx
 	add	r12,rax
-	mov	rax,QWORD[80+rbp]
+	mov	rax,QWORD[40+rbp]
 	adc	rdx,0
 	add	r11,r12
 	mov	r12,rdx
@@ -1566,7 +1819,7 @@
 
 	mul	rbx
 	add	r13,rax
-	mov	rax,QWORD[96+rbp]
+	mov	rax,QWORD[48+rbp]
 	adc	rdx,0
 	add	r12,r13
 	mov	r13,rdx
@@ -1574,7 +1827,7 @@
 
 	mul	rbx
 	add	r14,rax
-	mov	rax,QWORD[112+rbp]
+	mov	rax,QWORD[56+rbp]
 	adc	rdx,0
 	add	r13,r14
 	mov	r14,rdx
@@ -1592,7 +1845,7 @@
 	dec	ecx
 	jnz	NEAR $L$8x_tail
 
-	lea	rbp,[128+rbp]
+	lea	rbp,[64+rbp]
 	mov	rdx,QWORD[((8+8))+rsp]
 	cmp	rbp,QWORD[((0+8))+rsp]
 	jae	NEAR $L$8x_tail_done
@@ -1616,6 +1869,15 @@
 ALIGN	32
 $L$8x_tail_done:
 	add	r8,QWORD[rdx]
+	adc	r9,0
+	adc	r10,0
+	adc	r11,0
+	adc	r12,0
+	adc	r13,0
+	adc	r14,0
+	adc	r15,0
+
+
 	xor	rax,rax
 
 	neg	rsi
@@ -1629,7 +1891,7 @@
 	adc	r14,QWORD[48+rdi]
 	adc	r15,QWORD[56+rdi]
 	adc	rax,0
-	mov	rcx,QWORD[((-16))+rbp]
+	mov	rcx,QWORD[((-8))+rbp]
 	xor	rsi,rsi
 
 DB	102,72,15,126,213
@@ -1647,40 +1909,58 @@
 
 	cmp	rdi,rdx
 	jb	NEAR $L$8x_reduction_loop
+	DB	0F3h,0C3h		;repret
 
-	sub	rcx,r15
-	lea	rbx,[r9*1+rdi]
-	adc	rsi,rsi
-	mov	rcx,r9
-	or	rax,rsi
-DB	102,72,15,126,207
-	xor	rax,1
-DB	102,72,15,126,206
-	lea	rbp,[rax*8+rbp]
-	sar	rcx,3+2
-	jmp	NEAR $L$sqr4x_sub
 
 ALIGN	32
+__bn_post4x_internal:
+	mov	r12,QWORD[rbp]
+	lea	rbx,[r9*1+rdi]
+	mov	rcx,r9
+DB	102,72,15,126,207
+	neg	rax
+DB	102,72,15,126,206
+	sar	rcx,3+2
+	dec	r12
+	xor	r10,r10
+	mov	r13,QWORD[8+rbp]
+	mov	r14,QWORD[16+rbp]
+	mov	r15,QWORD[24+rbp]
+	jmp	NEAR $L$sqr4x_sub_entry
+
+ALIGN	16
 $L$sqr4x_sub:
-DB	0x66
-	mov	r12,QWORD[rbx]
-	mov	r13,QWORD[8+rbx]
-	sbb	r12,QWORD[rbp]
-	mov	r14,QWORD[16+rbx]
-	sbb	r13,QWORD[16+rbp]
-	mov	r15,QWORD[24+rbx]
-	lea	rbx,[32+rbx]
-	sbb	r14,QWORD[32+rbp]
+	mov	r12,QWORD[rbp]
+	mov	r13,QWORD[8+rbp]
+	mov	r14,QWORD[16+rbp]
+	mov	r15,QWORD[24+rbp]
+$L$sqr4x_sub_entry:
+	lea	rbp,[32+rbp]
+	not	r12
+	not	r13
+	not	r14
+	not	r15
+	and	r12,rax
+	and	r13,rax
+	and	r14,rax
+	and	r15,rax
+
+	neg	r10
+	adc	r12,QWORD[rbx]
+	adc	r13,QWORD[8+rbx]
+	adc	r14,QWORD[16+rbx]
+	adc	r15,QWORD[24+rbx]
 	mov	QWORD[rdi],r12
-	sbb	r15,QWORD[48+rbp]
-	lea	rbp,[64+rbp]
+	lea	rbx,[32+rbx]
 	mov	QWORD[8+rdi],r13
+	sbb	r10,r10
 	mov	QWORD[16+rdi],r14
 	mov	QWORD[24+rdi],r15
 	lea	rdi,[32+rdi]
 
 	inc	rcx
 	jnz	NEAR $L$sqr4x_sub
+
 	mov	r10,r9
 	neg	r9
 	DB	0F3h,0C3h		;repret
@@ -1718,13 +1998,9 @@
 	push	r13
 	push	r14
 	push	r15
-	lea	rsp,[((-40))+rsp]
-	movaps	XMMWORD[rsp],xmm6
-	movaps	XMMWORD[16+rsp],xmm7
-DB	0x67
-	mov	r10d,r9d
+
 	shl	r9d,3
-	shl	r10d,3+2
+	lea	r10,[r9*2+r9]
 	neg	r9
 	mov	r8,QWORD[r8]
 
@@ -1734,19 +2010,20 @@
 
 
 
-	lea	r11,[((-64))+r9*2+rsp]
-	sub	r11,rsi
+
+	lea	r11,[((-320))+r9*2+rsp]
+	sub	r11,rdi
 	and	r11,4095
 	cmp	r10,r11
 	jb	NEAR $L$from_sp_alt
 	sub	rsp,r11
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	rsp,[((-320))+r9*2+rsp]
 	jmp	NEAR $L$from_sp_done
 
 ALIGN	32
 $L$from_sp_alt:
-	lea	r10,[((4096-64))+r9*2]
-	lea	rsp,[((-64))+r9*2+rsp]
+	lea	r10,[((4096-320))+r9*2]
+	lea	rsp,[((-320))+r9*2+rsp]
 	sub	r11,r10
 	mov	r10,0
 	cmovc	r11,r10
@@ -1797,7 +2074,8 @@
 DB	0x67
 	mov	rbp,rcx
 DB	102,73,15,110,218
-	call	sqr8x_reduction
+	call	__bn_sqr8x_reduction
+	call	__bn_post4x_internal
 
 	pxor	xmm0,xmm0
 	lea	rax,[48+rsp]
@@ -1847,55 +2125,171 @@
 
 global	bn_gather5
 
-ALIGN	16
+ALIGN	32
 bn_gather5:
 $L$SEH_begin_bn_gather5:
 
-DB	0x48,0x83,0xec,0x28
-DB	0x0f,0x29,0x34,0x24
-DB	0x0f,0x29,0x7c,0x24,0x10
-	mov	r11d,r9d
-	shr	r9d,3
-	and	r11,7
-	not	r9d
-	lea	rax,[$L$magic_masks]
-	and	r9d,3
-	lea	r8,[128+r11*8+r8]
-	movq	xmm4,QWORD[r9*8+rax]
-	movq	xmm5,QWORD[8+r9*8+rax]
-	movq	xmm6,QWORD[16+r9*8+rax]
-	movq	xmm7,QWORD[24+r9*8+rax]
-	jmp	NEAR $L$gather
-ALIGN	16
-$L$gather:
-	movq	xmm0,QWORD[(((-128)))+r8]
-	movq	xmm1,QWORD[((-64))+r8]
-	pand	xmm0,xmm4
-	movq	xmm2,QWORD[r8]
-	pand	xmm1,xmm5
-	movq	xmm3,QWORD[64+r8]
-	pand	xmm2,xmm6
-	por	xmm0,xmm1
-	pand	xmm3,xmm7
-DB	0x67,0x67
-	por	xmm0,xmm2
-	lea	r8,[256+r8]
-	por	xmm0,xmm3
+DB	0x4c,0x8d,0x14,0x24
+DB	0x48,0x81,0xec,0x08,0x01,0x00,0x00
+	lea	rax,[$L$inc]
+	and	rsp,-16
 
+	movd	xmm5,r9d
+	movdqa	xmm0,XMMWORD[rax]
+	movdqa	xmm1,XMMWORD[16+rax]
+	lea	r11,[128+r8]
+	lea	rax,[128+rsp]
+
+	pshufd	xmm5,xmm5,0
+	movdqa	xmm4,xmm1
+	movdqa	xmm2,xmm1
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[(-128)+rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[(-112)+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[(-96)+rax],xmm2
+	movdqa	xmm2,xmm4
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[(-80)+rax],xmm3
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[(-64)+rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[(-48)+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[(-32)+rax],xmm2
+	movdqa	xmm2,xmm4
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[(-16)+rax],xmm3
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[16+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[32+rax],xmm2
+	movdqa	xmm2,xmm4
+	paddd	xmm1,xmm0
+	pcmpeqd	xmm0,xmm5
+	movdqa	XMMWORD[48+rax],xmm3
+	movdqa	xmm3,xmm4
+
+	paddd	xmm2,xmm1
+	pcmpeqd	xmm1,xmm5
+	movdqa	XMMWORD[64+rax],xmm0
+	movdqa	xmm0,xmm4
+
+	paddd	xmm3,xmm2
+	pcmpeqd	xmm2,xmm5
+	movdqa	XMMWORD[80+rax],xmm1
+	movdqa	xmm1,xmm4
+
+	paddd	xmm0,xmm3
+	pcmpeqd	xmm3,xmm5
+	movdqa	XMMWORD[96+rax],xmm2
+	movdqa	xmm2,xmm4
+	movdqa	XMMWORD[112+rax],xmm3
+	jmp	NEAR $L$gather
+
+ALIGN	32
+$L$gather:
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+	movdqa	xmm0,XMMWORD[((-128))+r11]
+	movdqa	xmm1,XMMWORD[((-112))+r11]
+	movdqa	xmm2,XMMWORD[((-96))+r11]
+	pand	xmm0,XMMWORD[((-128))+rax]
+	movdqa	xmm3,XMMWORD[((-80))+r11]
+	pand	xmm1,XMMWORD[((-112))+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-96))+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-80))+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[((-64))+r11]
+	movdqa	xmm1,XMMWORD[((-48))+r11]
+	movdqa	xmm2,XMMWORD[((-32))+r11]
+	pand	xmm0,XMMWORD[((-64))+rax]
+	movdqa	xmm3,XMMWORD[((-16))+r11]
+	pand	xmm1,XMMWORD[((-48))+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[((-32))+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[((-16))+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[r11]
+	movdqa	xmm1,XMMWORD[16+r11]
+	movdqa	xmm2,XMMWORD[32+r11]
+	pand	xmm0,XMMWORD[rax]
+	movdqa	xmm3,XMMWORD[48+r11]
+	pand	xmm1,XMMWORD[16+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[32+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[48+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	movdqa	xmm0,XMMWORD[64+r11]
+	movdqa	xmm1,XMMWORD[80+r11]
+	movdqa	xmm2,XMMWORD[96+r11]
+	pand	xmm0,XMMWORD[64+rax]
+	movdqa	xmm3,XMMWORD[112+r11]
+	pand	xmm1,XMMWORD[80+rax]
+	por	xmm4,xmm0
+	pand	xmm2,XMMWORD[96+rax]
+	por	xmm5,xmm1
+	pand	xmm3,XMMWORD[112+rax]
+	por	xmm4,xmm2
+	por	xmm5,xmm3
+	por	xmm4,xmm5
+	lea	r11,[256+r11]
+	pshufd	xmm0,xmm4,0x4e
+	por	xmm0,xmm4
 	movq	QWORD[rcx],xmm0
 	lea	rcx,[8+rcx]
 	sub	edx,1
 	jnz	NEAR $L$gather
-	movaps	xmm6,XMMWORD[rsp]
-	movaps	xmm7,XMMWORD[16+rsp]
-	lea	rsp,[40+rsp]
+
+	lea	rsp,[r10]
 	DB	0F3h,0C3h		;repret
 $L$SEH_end_bn_gather5:
 
 ALIGN	64
-$L$magic_masks:
-	DD	0,0,0,0,0,0,-1,-1
-	DD	0,0,0,0,0,0,0,0
+$L$inc:
+	DD	0,0,1,1
+	DD	2,2,2,2
 DB	77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105
 DB	112,108,105,99,97,116,105,111,110,32,119,105,116,104,32,115
 DB	99,97,116,116,101,114,47,103,97,116,104,101,114,32,102,111
@@ -1937,19 +2331,16 @@
 
 	lea	r10,[$L$mul_epilogue]
 	cmp	rbx,r10
-	jb	NEAR $L$body_40
+	ja	NEAR $L$body_40
 
 	mov	r10,QWORD[192+r8]
 	mov	rax,QWORD[8+r10*8+rax]
+
 	jmp	NEAR $L$body_proceed
 
 $L$body_40:
 	mov	rax,QWORD[40+rax]
 $L$body_proceed:
-
-	movaps	xmm0,XMMWORD[((-88))+rax]
-	movaps	xmm1,XMMWORD[((-72))+rax]
-
 	mov	rbx,QWORD[((-8))+rax]
 	mov	rbp,QWORD[((-16))+rax]
 	mov	r12,QWORD[((-24))+rax]
@@ -1962,8 +2353,6 @@
 	mov	QWORD[224+r8],r13
 	mov	QWORD[232+r8],r14
 	mov	QWORD[240+r8],r15
-	movups	XMMWORD[512+r8],xmm0
-	movups	XMMWORD[528+r8],xmm1
 
 $L$common_seh_tail:
 	mov	rdi,QWORD[8+rax]
@@ -2049,8 +2438,7 @@
 	DD	$L$from_body wrt ..imagebase,$L$from_epilogue wrt ..imagebase
 ALIGN	8
 $L$SEH_info_bn_gather5:
-DB	0x01,0x0d,0x05,0x00
-DB	0x0d,0x78,0x01,0x00
-DB	0x08,0x68,0x00,0x00
-DB	0x04,0x42,0x00,0x00
+DB	0x01,0x0b,0x03,0x0a
+DB	0x0b,0x01,0x21,0x00
+DB	0x04,0xa3,0x00,0x00
 ALIGN	8
diff --git a/third_party/boringssl/win-x86_64/crypto/chacha/chacha-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/chacha/chacha-x86_64.asm
new file mode 100644
index 0000000..afebd2e
--- /dev/null
+++ b/third_party/boringssl/win-x86_64/crypto/chacha/chacha-x86_64.asm
@@ -0,0 +1,1689 @@
+default	rel
+%define XMMWORD
+%define YMMWORD
+%define ZMMWORD
+section	.text code align=64
+
+
+EXTERN	OPENSSL_ia32cap_P
+
+ALIGN	64
+$L$zero:
+	DD	0,0,0,0
+$L$one:
+	DD	1,0,0,0
+$L$inc:
+	DD	0,1,2,3
+$L$four:
+	DD	4,4,4,4
+$L$incy:
+	DD	0,2,4,6,1,3,5,7
+$L$eight:
+	DD	8,8,8,8,8,8,8,8
+$L$rot16:
+DB	0x2,0x3,0x0,0x1,0x6,0x7,0x4,0x5,0xa,0xb,0x8,0x9,0xe,0xf,0xc,0xd
+$L$rot24:
+DB	0x3,0x0,0x1,0x2,0x7,0x4,0x5,0x6,0xb,0x8,0x9,0xa,0xf,0xc,0xd,0xe
+$L$sigma:
+DB	101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107
+DB	0
+DB	67,104,97,67,104,97,50,48,32,102,111,114,32,120,56,54
+DB	95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32
+DB	98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115
+DB	108,46,111,114,103,62,0
+global	ChaCha20_ctr32
+
+ALIGN	64
+ChaCha20_ctr32:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_ctr32:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+	cmp	rdx,0
+	je	NEAR $L$no_data
+	mov	r10,QWORD[((OPENSSL_ia32cap_P+4))]
+	test	r10d,512
+	jnz	NEAR $L$ChaCha20_ssse3
+
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	sub	rsp,64+24
+
+
+	movdqu	xmm1,XMMWORD[rcx]
+	movdqu	xmm2,XMMWORD[16+rcx]
+	movdqu	xmm3,XMMWORD[r8]
+	movdqa	xmm4,XMMWORD[$L$one]
+
+
+	movdqa	XMMWORD[16+rsp],xmm1
+	movdqa	XMMWORD[32+rsp],xmm2
+	movdqa	XMMWORD[48+rsp],xmm3
+	mov	rbp,rdx
+	jmp	NEAR $L$oop_outer
+
+ALIGN	32
+$L$oop_outer:
+	mov	eax,0x61707865
+	mov	ebx,0x3320646e
+	mov	ecx,0x79622d32
+	mov	edx,0x6b206574
+	mov	r8d,DWORD[16+rsp]
+	mov	r9d,DWORD[20+rsp]
+	mov	r10d,DWORD[24+rsp]
+	mov	r11d,DWORD[28+rsp]
+	movd	r12d,xmm3
+	mov	r13d,DWORD[52+rsp]
+	mov	r14d,DWORD[56+rsp]
+	mov	r15d,DWORD[60+rsp]
+
+	mov	QWORD[((64+0))+rsp],rbp
+	mov	ebp,10
+	mov	QWORD[((64+8))+rsp],rsi
+DB	102,72,15,126,214
+	mov	QWORD[((64+16))+rsp],rdi
+	mov	rdi,rsi
+	shr	rdi,32
+	jmp	NEAR $L$oop
+
+ALIGN	32
+$L$oop:
+	add	eax,r8d
+	xor	r12d,eax
+	rol	r12d,16
+	add	ebx,r9d
+	xor	r13d,ebx
+	rol	r13d,16
+	add	esi,r12d
+	xor	r8d,esi
+	rol	r8d,12
+	add	edi,r13d
+	xor	r9d,edi
+	rol	r9d,12
+	add	eax,r8d
+	xor	r12d,eax
+	rol	r12d,8
+	add	ebx,r9d
+	xor	r13d,ebx
+	rol	r13d,8
+	add	esi,r12d
+	xor	r8d,esi
+	rol	r8d,7
+	add	edi,r13d
+	xor	r9d,edi
+	rol	r9d,7
+	mov	DWORD[32+rsp],esi
+	mov	DWORD[36+rsp],edi
+	mov	esi,DWORD[40+rsp]
+	mov	edi,DWORD[44+rsp]
+	add	ecx,r10d
+	xor	r14d,ecx
+	rol	r14d,16
+	add	edx,r11d
+	xor	r15d,edx
+	rol	r15d,16
+	add	esi,r14d
+	xor	r10d,esi
+	rol	r10d,12
+	add	edi,r15d
+	xor	r11d,edi
+	rol	r11d,12
+	add	ecx,r10d
+	xor	r14d,ecx
+	rol	r14d,8
+	add	edx,r11d
+	xor	r15d,edx
+	rol	r15d,8
+	add	esi,r14d
+	xor	r10d,esi
+	rol	r10d,7
+	add	edi,r15d
+	xor	r11d,edi
+	rol	r11d,7
+	add	eax,r9d
+	xor	r15d,eax
+	rol	r15d,16
+	add	ebx,r10d
+	xor	r12d,ebx
+	rol	r12d,16
+	add	esi,r15d
+	xor	r9d,esi
+	rol	r9d,12
+	add	edi,r12d
+	xor	r10d,edi
+	rol	r10d,12
+	add	eax,r9d
+	xor	r15d,eax
+	rol	r15d,8
+	add	ebx,r10d
+	xor	r12d,ebx
+	rol	r12d,8
+	add	esi,r15d
+	xor	r9d,esi
+	rol	r9d,7
+	add	edi,r12d
+	xor	r10d,edi
+	rol	r10d,7
+	mov	DWORD[40+rsp],esi
+	mov	DWORD[44+rsp],edi
+	mov	esi,DWORD[32+rsp]
+	mov	edi,DWORD[36+rsp]
+	add	ecx,r11d
+	xor	r13d,ecx
+	rol	r13d,16
+	add	edx,r8d
+	xor	r14d,edx
+	rol	r14d,16
+	add	esi,r13d
+	xor	r11d,esi
+	rol	r11d,12
+	add	edi,r14d
+	xor	r8d,edi
+	rol	r8d,12
+	add	ecx,r11d
+	xor	r13d,ecx
+	rol	r13d,8
+	add	edx,r8d
+	xor	r14d,edx
+	rol	r14d,8
+	add	esi,r13d
+	xor	r11d,esi
+	rol	r11d,7
+	add	edi,r14d
+	xor	r8d,edi
+	rol	r8d,7
+	dec	ebp
+	jnz	NEAR $L$oop
+	mov	DWORD[36+rsp],edi
+	mov	DWORD[32+rsp],esi
+	mov	rbp,QWORD[64+rsp]
+	movdqa	xmm1,xmm2
+	mov	rsi,QWORD[((64+8))+rsp]
+	paddd	xmm3,xmm4
+	mov	rdi,QWORD[((64+16))+rsp]
+
+	add	eax,0x61707865
+	add	ebx,0x3320646e
+	add	ecx,0x79622d32
+	add	edx,0x6b206574
+	add	r8d,DWORD[16+rsp]
+	add	r9d,DWORD[20+rsp]
+	add	r10d,DWORD[24+rsp]
+	add	r11d,DWORD[28+rsp]
+	add	r12d,DWORD[48+rsp]
+	add	r13d,DWORD[52+rsp]
+	add	r14d,DWORD[56+rsp]
+	add	r15d,DWORD[60+rsp]
+	paddd	xmm1,XMMWORD[32+rsp]
+
+	cmp	rbp,64
+	jb	NEAR $L$tail
+
+	xor	eax,DWORD[rsi]
+	xor	ebx,DWORD[4+rsi]
+	xor	ecx,DWORD[8+rsi]
+	xor	edx,DWORD[12+rsi]
+	xor	r8d,DWORD[16+rsi]
+	xor	r9d,DWORD[20+rsi]
+	xor	r10d,DWORD[24+rsi]
+	xor	r11d,DWORD[28+rsi]
+	movdqu	xmm0,XMMWORD[32+rsi]
+	xor	r12d,DWORD[48+rsi]
+	xor	r13d,DWORD[52+rsi]
+	xor	r14d,DWORD[56+rsi]
+	xor	r15d,DWORD[60+rsi]
+	lea	rsi,[64+rsi]
+	pxor	xmm0,xmm1
+
+	movdqa	XMMWORD[32+rsp],xmm2
+	movd	DWORD[48+rsp],xmm3
+
+	mov	DWORD[rdi],eax
+	mov	DWORD[4+rdi],ebx
+	mov	DWORD[8+rdi],ecx
+	mov	DWORD[12+rdi],edx
+	mov	DWORD[16+rdi],r8d
+	mov	DWORD[20+rdi],r9d
+	mov	DWORD[24+rdi],r10d
+	mov	DWORD[28+rdi],r11d
+	movdqu	XMMWORD[32+rdi],xmm0
+	mov	DWORD[48+rdi],r12d
+	mov	DWORD[52+rdi],r13d
+	mov	DWORD[56+rdi],r14d
+	mov	DWORD[60+rdi],r15d
+	lea	rdi,[64+rdi]
+
+	sub	rbp,64
+	jnz	NEAR $L$oop_outer
+
+	jmp	NEAR $L$done
+
+ALIGN	16
+$L$tail:
+	mov	DWORD[rsp],eax
+	mov	DWORD[4+rsp],ebx
+	xor	rbx,rbx
+	mov	DWORD[8+rsp],ecx
+	mov	DWORD[12+rsp],edx
+	mov	DWORD[16+rsp],r8d
+	mov	DWORD[20+rsp],r9d
+	mov	DWORD[24+rsp],r10d
+	mov	DWORD[28+rsp],r11d
+	movdqa	XMMWORD[32+rsp],xmm1
+	mov	DWORD[48+rsp],r12d
+	mov	DWORD[52+rsp],r13d
+	mov	DWORD[56+rsp],r14d
+	mov	DWORD[60+rsp],r15d
+
+$L$oop_tail:
+	movzx	eax,BYTE[rbx*1+rsi]
+	movzx	edx,BYTE[rbx*1+rsp]
+	lea	rbx,[1+rbx]
+	xor	eax,edx
+	mov	BYTE[((-1))+rbx*1+rdi],al
+	dec	rbp
+	jnz	NEAR $L$oop_tail
+
+$L$done:
+	add	rsp,64+24
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbp
+	pop	rbx
+$L$no_data:
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_ctr32:
+
+ALIGN	32
+ChaCha20_ssse3:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_ssse3:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_ssse3:
+	cmp	rdx,128
+	ja	NEAR $L$ChaCha20_4x
+
+$L$do_sse3_after_all:
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+
+	sub	rsp,64+72
+	movaps	XMMWORD[(64+32)+rsp],xmm6
+	movaps	XMMWORD[(64+48)+rsp],xmm7
+	movdqa	xmm0,XMMWORD[$L$sigma]
+	movdqu	xmm1,XMMWORD[rcx]
+	movdqu	xmm2,XMMWORD[16+rcx]
+	movdqu	xmm3,XMMWORD[r8]
+	movdqa	xmm6,XMMWORD[$L$rot16]
+	movdqa	xmm7,XMMWORD[$L$rot24]
+
+	movdqa	XMMWORD[rsp],xmm0
+	movdqa	XMMWORD[16+rsp],xmm1
+	movdqa	XMMWORD[32+rsp],xmm2
+	movdqa	XMMWORD[48+rsp],xmm3
+	mov	ebp,10
+	jmp	NEAR $L$oop_ssse3
+
+ALIGN	32
+$L$oop_outer_ssse3:
+	movdqa	xmm3,XMMWORD[$L$one]
+	movdqa	xmm0,XMMWORD[rsp]
+	movdqa	xmm1,XMMWORD[16+rsp]
+	movdqa	xmm2,XMMWORD[32+rsp]
+	paddd	xmm3,XMMWORD[48+rsp]
+	mov	ebp,10
+	movdqa	XMMWORD[48+rsp],xmm3
+	jmp	NEAR $L$oop_ssse3
+
+ALIGN	32
+$L$oop_ssse3:
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,57
+	pshufd	xmm3,xmm3,147
+	nop
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,222
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,20
+	pslld	xmm4,12
+	por	xmm1,xmm4
+	paddd	xmm0,xmm1
+	pxor	xmm3,xmm0
+DB	102,15,56,0,223
+	paddd	xmm2,xmm3
+	pxor	xmm1,xmm2
+	movdqa	xmm4,xmm1
+	psrld	xmm1,25
+	pslld	xmm4,7
+	por	xmm1,xmm4
+	pshufd	xmm2,xmm2,78
+	pshufd	xmm1,xmm1,147
+	pshufd	xmm3,xmm3,57
+	dec	ebp
+	jnz	NEAR $L$oop_ssse3
+	paddd	xmm0,XMMWORD[rsp]
+	paddd	xmm1,XMMWORD[16+rsp]
+	paddd	xmm2,XMMWORD[32+rsp]
+	paddd	xmm3,XMMWORD[48+rsp]
+
+	cmp	rdx,64
+	jb	NEAR $L$tail_ssse3
+
+	movdqu	xmm4,XMMWORD[rsi]
+	movdqu	xmm5,XMMWORD[16+rsi]
+	pxor	xmm0,xmm4
+	movdqu	xmm4,XMMWORD[32+rsi]
+	pxor	xmm1,xmm5
+	movdqu	xmm5,XMMWORD[48+rsi]
+	lea	rsi,[64+rsi]
+	pxor	xmm2,xmm4
+	pxor	xmm3,xmm5
+
+	movdqu	XMMWORD[rdi],xmm0
+	movdqu	XMMWORD[16+rdi],xmm1
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm3
+	lea	rdi,[64+rdi]
+
+	sub	rdx,64
+	jnz	NEAR $L$oop_outer_ssse3
+
+	jmp	NEAR $L$done_ssse3
+
+ALIGN	16
+$L$tail_ssse3:
+	movdqa	XMMWORD[rsp],xmm0
+	movdqa	XMMWORD[16+rsp],xmm1
+	movdqa	XMMWORD[32+rsp],xmm2
+	movdqa	XMMWORD[48+rsp],xmm3
+	xor	rbx,rbx
+
+$L$oop_tail_ssse3:
+	movzx	eax,BYTE[rbx*1+rsi]
+	movzx	ecx,BYTE[rbx*1+rsp]
+	lea	rbx,[1+rbx]
+	xor	eax,ecx
+	mov	BYTE[((-1))+rbx*1+rdi],al
+	dec	rdx
+	jnz	NEAR $L$oop_tail_ssse3
+
+$L$done_ssse3:
+	movaps	xmm6,XMMWORD[((64+32))+rsp]
+	movaps	xmm7,XMMWORD[((64+48))+rsp]
+	add	rsp,64+72
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbp
+	pop	rbx
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_ssse3:
+
+ALIGN	32
+ChaCha20_4x:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_4x:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_4x:
+	mov	r11,r10
+	shr	r10,32
+	test	r10,32
+	jnz	NEAR $L$ChaCha20_8x
+	cmp	rdx,192
+	ja	NEAR $L$proceed4x
+
+	and	r11,71303168
+	cmp	r11,4194304
+	je	NEAR $L$do_sse3_after_all
+
+$L$proceed4x:
+	lea	r11,[((-120))+rsp]
+	sub	rsp,0x148+160
+	movaps	XMMWORD[(-48)+r11],xmm6
+	movaps	XMMWORD[(-32)+r11],xmm7
+	movaps	XMMWORD[(-16)+r11],xmm8
+	movaps	XMMWORD[r11],xmm9
+	movaps	XMMWORD[16+r11],xmm10
+	movaps	XMMWORD[32+r11],xmm11
+	movaps	XMMWORD[48+r11],xmm12
+	movaps	XMMWORD[64+r11],xmm13
+	movaps	XMMWORD[80+r11],xmm14
+	movaps	XMMWORD[96+r11],xmm15
+	movdqa	xmm11,XMMWORD[$L$sigma]
+	movdqu	xmm15,XMMWORD[rcx]
+	movdqu	xmm7,XMMWORD[16+rcx]
+	movdqu	xmm3,XMMWORD[r8]
+	lea	rcx,[256+rsp]
+	lea	r10,[$L$rot16]
+	lea	r11,[$L$rot24]
+
+	pshufd	xmm8,xmm11,0x00
+	pshufd	xmm9,xmm11,0x55
+	movdqa	XMMWORD[64+rsp],xmm8
+	pshufd	xmm10,xmm11,0xaa
+	movdqa	XMMWORD[80+rsp],xmm9
+	pshufd	xmm11,xmm11,0xff
+	movdqa	XMMWORD[96+rsp],xmm10
+	movdqa	XMMWORD[112+rsp],xmm11
+
+	pshufd	xmm12,xmm15,0x00
+	pshufd	xmm13,xmm15,0x55
+	movdqa	XMMWORD[(128-256)+rcx],xmm12
+	pshufd	xmm14,xmm15,0xaa
+	movdqa	XMMWORD[(144-256)+rcx],xmm13
+	pshufd	xmm15,xmm15,0xff
+	movdqa	XMMWORD[(160-256)+rcx],xmm14
+	movdqa	XMMWORD[(176-256)+rcx],xmm15
+
+	pshufd	xmm4,xmm7,0x00
+	pshufd	xmm5,xmm7,0x55
+	movdqa	XMMWORD[(192-256)+rcx],xmm4
+	pshufd	xmm6,xmm7,0xaa
+	movdqa	XMMWORD[(208-256)+rcx],xmm5
+	pshufd	xmm7,xmm7,0xff
+	movdqa	XMMWORD[(224-256)+rcx],xmm6
+	movdqa	XMMWORD[(240-256)+rcx],xmm7
+
+	pshufd	xmm0,xmm3,0x00
+	pshufd	xmm1,xmm3,0x55
+	paddd	xmm0,XMMWORD[$L$inc]
+	pshufd	xmm2,xmm3,0xaa
+	movdqa	XMMWORD[(272-256)+rcx],xmm1
+	pshufd	xmm3,xmm3,0xff
+	movdqa	XMMWORD[(288-256)+rcx],xmm2
+	movdqa	XMMWORD[(304-256)+rcx],xmm3
+
+	jmp	NEAR $L$oop_enter4x
+
+ALIGN	32
+$L$oop_outer4x:
+	movdqa	xmm8,XMMWORD[64+rsp]
+	movdqa	xmm9,XMMWORD[80+rsp]
+	movdqa	xmm10,XMMWORD[96+rsp]
+	movdqa	xmm11,XMMWORD[112+rsp]
+	movdqa	xmm12,XMMWORD[((128-256))+rcx]
+	movdqa	xmm13,XMMWORD[((144-256))+rcx]
+	movdqa	xmm14,XMMWORD[((160-256))+rcx]
+	movdqa	xmm15,XMMWORD[((176-256))+rcx]
+	movdqa	xmm4,XMMWORD[((192-256))+rcx]
+	movdqa	xmm5,XMMWORD[((208-256))+rcx]
+	movdqa	xmm6,XMMWORD[((224-256))+rcx]
+	movdqa	xmm7,XMMWORD[((240-256))+rcx]
+	movdqa	xmm0,XMMWORD[((256-256))+rcx]
+	movdqa	xmm1,XMMWORD[((272-256))+rcx]
+	movdqa	xmm2,XMMWORD[((288-256))+rcx]
+	movdqa	xmm3,XMMWORD[((304-256))+rcx]
+	paddd	xmm0,XMMWORD[$L$four]
+
+$L$oop_enter4x:
+	movdqa	XMMWORD[32+rsp],xmm6
+	movdqa	XMMWORD[48+rsp],xmm7
+	movdqa	xmm7,XMMWORD[r10]
+	mov	eax,10
+	movdqa	XMMWORD[(256-256)+rcx],xmm0
+	jmp	NEAR $L$oop4x
+
+ALIGN	32
+$L$oop4x:
+	paddd	xmm8,xmm12
+	paddd	xmm9,xmm13
+	pxor	xmm0,xmm8
+	pxor	xmm1,xmm9
+DB	102,15,56,0,199
+DB	102,15,56,0,207
+	paddd	xmm4,xmm0
+	paddd	xmm5,xmm1
+	pxor	xmm12,xmm4
+	pxor	xmm13,xmm5
+	movdqa	xmm6,xmm12
+	pslld	xmm12,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm13
+	pslld	xmm13,12
+	por	xmm12,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm13,xmm7
+	paddd	xmm8,xmm12
+	paddd	xmm9,xmm13
+	pxor	xmm0,xmm8
+	pxor	xmm1,xmm9
+DB	102,15,56,0,198
+DB	102,15,56,0,206
+	paddd	xmm4,xmm0
+	paddd	xmm5,xmm1
+	pxor	xmm12,xmm4
+	pxor	xmm13,xmm5
+	movdqa	xmm7,xmm12
+	pslld	xmm12,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm13
+	pslld	xmm13,7
+	por	xmm12,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm13,xmm6
+	movdqa	XMMWORD[rsp],xmm4
+	movdqa	XMMWORD[16+rsp],xmm5
+	movdqa	xmm4,XMMWORD[32+rsp]
+	movdqa	xmm5,XMMWORD[48+rsp]
+	paddd	xmm10,xmm14
+	paddd	xmm11,xmm15
+	pxor	xmm2,xmm10
+	pxor	xmm3,xmm11
+DB	102,15,56,0,215
+DB	102,15,56,0,223
+	paddd	xmm4,xmm2
+	paddd	xmm5,xmm3
+	pxor	xmm14,xmm4
+	pxor	xmm15,xmm5
+	movdqa	xmm6,xmm14
+	pslld	xmm14,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm15
+	pslld	xmm15,12
+	por	xmm14,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm15,xmm7
+	paddd	xmm10,xmm14
+	paddd	xmm11,xmm15
+	pxor	xmm2,xmm10
+	pxor	xmm3,xmm11
+DB	102,15,56,0,214
+DB	102,15,56,0,222
+	paddd	xmm4,xmm2
+	paddd	xmm5,xmm3
+	pxor	xmm14,xmm4
+	pxor	xmm15,xmm5
+	movdqa	xmm7,xmm14
+	pslld	xmm14,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm15
+	pslld	xmm15,7
+	por	xmm14,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm15,xmm6
+	paddd	xmm8,xmm13
+	paddd	xmm9,xmm14
+	pxor	xmm3,xmm8
+	pxor	xmm0,xmm9
+DB	102,15,56,0,223
+DB	102,15,56,0,199
+	paddd	xmm4,xmm3
+	paddd	xmm5,xmm0
+	pxor	xmm13,xmm4
+	pxor	xmm14,xmm5
+	movdqa	xmm6,xmm13
+	pslld	xmm13,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm14
+	pslld	xmm14,12
+	por	xmm13,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm14,xmm7
+	paddd	xmm8,xmm13
+	paddd	xmm9,xmm14
+	pxor	xmm3,xmm8
+	pxor	xmm0,xmm9
+DB	102,15,56,0,222
+DB	102,15,56,0,198
+	paddd	xmm4,xmm3
+	paddd	xmm5,xmm0
+	pxor	xmm13,xmm4
+	pxor	xmm14,xmm5
+	movdqa	xmm7,xmm13
+	pslld	xmm13,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm14
+	pslld	xmm14,7
+	por	xmm13,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm14,xmm6
+	movdqa	XMMWORD[32+rsp],xmm4
+	movdqa	XMMWORD[48+rsp],xmm5
+	movdqa	xmm4,XMMWORD[rsp]
+	movdqa	xmm5,XMMWORD[16+rsp]
+	paddd	xmm10,xmm15
+	paddd	xmm11,xmm12
+	pxor	xmm1,xmm10
+	pxor	xmm2,xmm11
+DB	102,15,56,0,207
+DB	102,15,56,0,215
+	paddd	xmm4,xmm1
+	paddd	xmm5,xmm2
+	pxor	xmm15,xmm4
+	pxor	xmm12,xmm5
+	movdqa	xmm6,xmm15
+	pslld	xmm15,12
+	psrld	xmm6,20
+	movdqa	xmm7,xmm12
+	pslld	xmm12,12
+	por	xmm15,xmm6
+	psrld	xmm7,20
+	movdqa	xmm6,XMMWORD[r11]
+	por	xmm12,xmm7
+	paddd	xmm10,xmm15
+	paddd	xmm11,xmm12
+	pxor	xmm1,xmm10
+	pxor	xmm2,xmm11
+DB	102,15,56,0,206
+DB	102,15,56,0,214
+	paddd	xmm4,xmm1
+	paddd	xmm5,xmm2
+	pxor	xmm15,xmm4
+	pxor	xmm12,xmm5
+	movdqa	xmm7,xmm15
+	pslld	xmm15,7
+	psrld	xmm7,25
+	movdqa	xmm6,xmm12
+	pslld	xmm12,7
+	por	xmm15,xmm7
+	psrld	xmm6,25
+	movdqa	xmm7,XMMWORD[r10]
+	por	xmm12,xmm6
+	dec	eax
+	jnz	NEAR $L$oop4x
+
+	paddd	xmm8,XMMWORD[64+rsp]
+	paddd	xmm9,XMMWORD[80+rsp]
+	paddd	xmm10,XMMWORD[96+rsp]
+	paddd	xmm11,XMMWORD[112+rsp]
+
+	movdqa	xmm6,xmm8
+	punpckldq	xmm8,xmm9
+	movdqa	xmm7,xmm10
+	punpckldq	xmm10,xmm11
+	punpckhdq	xmm6,xmm9
+	punpckhdq	xmm7,xmm11
+	movdqa	xmm9,xmm8
+	punpcklqdq	xmm8,xmm10
+	movdqa	xmm11,xmm6
+	punpcklqdq	xmm6,xmm7
+	punpckhqdq	xmm9,xmm10
+	punpckhqdq	xmm11,xmm7
+	paddd	xmm12,XMMWORD[((128-256))+rcx]
+	paddd	xmm13,XMMWORD[((144-256))+rcx]
+	paddd	xmm14,XMMWORD[((160-256))+rcx]
+	paddd	xmm15,XMMWORD[((176-256))+rcx]
+
+	movdqa	XMMWORD[rsp],xmm8
+	movdqa	XMMWORD[16+rsp],xmm9
+	movdqa	xmm8,XMMWORD[32+rsp]
+	movdqa	xmm9,XMMWORD[48+rsp]
+
+	movdqa	xmm10,xmm12
+	punpckldq	xmm12,xmm13
+	movdqa	xmm7,xmm14
+	punpckldq	xmm14,xmm15
+	punpckhdq	xmm10,xmm13
+	punpckhdq	xmm7,xmm15
+	movdqa	xmm13,xmm12
+	punpcklqdq	xmm12,xmm14
+	movdqa	xmm15,xmm10
+	punpcklqdq	xmm10,xmm7
+	punpckhqdq	xmm13,xmm14
+	punpckhqdq	xmm15,xmm7
+	paddd	xmm4,XMMWORD[((192-256))+rcx]
+	paddd	xmm5,XMMWORD[((208-256))+rcx]
+	paddd	xmm8,XMMWORD[((224-256))+rcx]
+	paddd	xmm9,XMMWORD[((240-256))+rcx]
+
+	movdqa	XMMWORD[32+rsp],xmm6
+	movdqa	XMMWORD[48+rsp],xmm11
+
+	movdqa	xmm14,xmm4
+	punpckldq	xmm4,xmm5
+	movdqa	xmm7,xmm8
+	punpckldq	xmm8,xmm9
+	punpckhdq	xmm14,xmm5
+	punpckhdq	xmm7,xmm9
+	movdqa	xmm5,xmm4
+	punpcklqdq	xmm4,xmm8
+	movdqa	xmm9,xmm14
+	punpcklqdq	xmm14,xmm7
+	punpckhqdq	xmm5,xmm8
+	punpckhqdq	xmm9,xmm7
+	paddd	xmm0,XMMWORD[((256-256))+rcx]
+	paddd	xmm1,XMMWORD[((272-256))+rcx]
+	paddd	xmm2,XMMWORD[((288-256))+rcx]
+	paddd	xmm3,XMMWORD[((304-256))+rcx]
+
+	movdqa	xmm8,xmm0
+	punpckldq	xmm0,xmm1
+	movdqa	xmm7,xmm2
+	punpckldq	xmm2,xmm3
+	punpckhdq	xmm8,xmm1
+	punpckhdq	xmm7,xmm3
+	movdqa	xmm1,xmm0
+	punpcklqdq	xmm0,xmm2
+	movdqa	xmm3,xmm8
+	punpcklqdq	xmm8,xmm7
+	punpckhqdq	xmm1,xmm2
+	punpckhqdq	xmm3,xmm7
+	cmp	rdx,64*4
+	jb	NEAR $L$tail4x
+
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	lea	rsi,[128+rsi]
+	pxor	xmm6,XMMWORD[16+rsp]
+	pxor	xmm11,xmm13
+	pxor	xmm2,xmm5
+	pxor	xmm7,xmm1
+
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	XMMWORD[112+rdi],xmm7
+	lea	rdi,[128+rdi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[32+rsp]
+	pxor	xmm11,xmm10
+	pxor	xmm2,xmm14
+	pxor	xmm7,xmm8
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	lea	rsi,[128+rsi]
+	pxor	xmm6,XMMWORD[48+rsp]
+	pxor	xmm11,xmm15
+	pxor	xmm2,xmm9
+	pxor	xmm7,xmm3
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	XMMWORD[112+rdi],xmm7
+	lea	rdi,[128+rdi]
+
+	sub	rdx,64*4
+	jnz	NEAR $L$oop_outer4x
+
+	jmp	NEAR $L$done4x
+
+$L$tail4x:
+	cmp	rdx,192
+	jae	NEAR $L$192_or_more4x
+	cmp	rdx,128
+	jae	NEAR $L$128_or_more4x
+	cmp	rdx,64
+	jae	NEAR $L$64_or_more4x
+
+
+	xor	r10,r10
+
+	movdqa	XMMWORD[16+rsp],xmm12
+	movdqa	XMMWORD[32+rsp],xmm4
+	movdqa	XMMWORD[48+rsp],xmm0
+	jmp	NEAR $L$oop_tail4x
+
+ALIGN	32
+$L$64_or_more4x:
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm7
+	je	NEAR $L$done4x
+
+	movdqa	xmm6,XMMWORD[16+rsp]
+	lea	rsi,[64+rsi]
+	xor	r10,r10
+	movdqa	XMMWORD[rsp],xmm6
+	movdqa	XMMWORD[16+rsp],xmm13
+	lea	rdi,[64+rdi]
+	movdqa	XMMWORD[32+rsp],xmm5
+	sub	rdx,64
+	movdqa	XMMWORD[48+rsp],xmm1
+	jmp	NEAR $L$oop_tail4x
+
+ALIGN	32
+$L$128_or_more4x:
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	pxor	xmm6,XMMWORD[16+rsp]
+	pxor	xmm11,xmm13
+	pxor	xmm2,xmm5
+	pxor	xmm7,xmm1
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	XMMWORD[112+rdi],xmm7
+	je	NEAR $L$done4x
+
+	movdqa	xmm6,XMMWORD[32+rsp]
+	lea	rsi,[128+rsi]
+	xor	r10,r10
+	movdqa	XMMWORD[rsp],xmm6
+	movdqa	XMMWORD[16+rsp],xmm10
+	lea	rdi,[128+rdi]
+	movdqa	XMMWORD[32+rsp],xmm14
+	sub	rdx,128
+	movdqa	XMMWORD[48+rsp],xmm8
+	jmp	NEAR $L$oop_tail4x
+
+ALIGN	32
+$L$192_or_more4x:
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[rsp]
+	pxor	xmm11,xmm12
+	pxor	xmm2,xmm4
+	pxor	xmm7,xmm0
+
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	xmm6,XMMWORD[64+rsi]
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	xmm11,XMMWORD[80+rsi]
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	xmm2,XMMWORD[96+rsi]
+	movdqu	XMMWORD[48+rdi],xmm7
+	movdqu	xmm7,XMMWORD[112+rsi]
+	lea	rsi,[128+rsi]
+	pxor	xmm6,XMMWORD[16+rsp]
+	pxor	xmm11,xmm13
+	pxor	xmm2,xmm5
+	pxor	xmm7,xmm1
+
+	movdqu	XMMWORD[64+rdi],xmm6
+	movdqu	xmm6,XMMWORD[rsi]
+	movdqu	XMMWORD[80+rdi],xmm11
+	movdqu	xmm11,XMMWORD[16+rsi]
+	movdqu	XMMWORD[96+rdi],xmm2
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	XMMWORD[112+rdi],xmm7
+	lea	rdi,[128+rdi]
+	movdqu	xmm7,XMMWORD[48+rsi]
+	pxor	xmm6,XMMWORD[32+rsp]
+	pxor	xmm11,xmm10
+	pxor	xmm2,xmm14
+	pxor	xmm7,xmm8
+	movdqu	XMMWORD[rdi],xmm6
+	movdqu	XMMWORD[16+rdi],xmm11
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm7
+	je	NEAR $L$done4x
+
+	movdqa	xmm6,XMMWORD[48+rsp]
+	lea	rsi,[64+rsi]
+	xor	r10,r10
+	movdqa	XMMWORD[rsp],xmm6
+	movdqa	XMMWORD[16+rsp],xmm15
+	lea	rdi,[64+rdi]
+	movdqa	XMMWORD[32+rsp],xmm9
+	sub	rdx,192
+	movdqa	XMMWORD[48+rsp],xmm3
+
+$L$oop_tail4x:
+	movzx	eax,BYTE[r10*1+rsi]
+	movzx	ecx,BYTE[r10*1+rsp]
+	lea	r10,[1+r10]
+	xor	eax,ecx
+	mov	BYTE[((-1))+r10*1+rdi],al
+	dec	rdx
+	jnz	NEAR $L$oop_tail4x
+
+$L$done4x:
+	lea	r11,[((320+48))+rsp]
+	movaps	xmm6,XMMWORD[((-48))+r11]
+	movaps	xmm7,XMMWORD[((-32))+r11]
+	movaps	xmm8,XMMWORD[((-16))+r11]
+	movaps	xmm9,XMMWORD[r11]
+	movaps	xmm10,XMMWORD[16+r11]
+	movaps	xmm11,XMMWORD[32+r11]
+	movaps	xmm12,XMMWORD[48+r11]
+	movaps	xmm13,XMMWORD[64+r11]
+	movaps	xmm14,XMMWORD[80+r11]
+	movaps	xmm15,XMMWORD[96+r11]
+	add	rsp,0x148+160
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_4x:
+
+ALIGN	32
+ChaCha20_8x:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ChaCha20_8x:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+	mov	rcx,r9
+	mov	r8,QWORD[40+rsp]
+
+
+$L$ChaCha20_8x:
+	mov	r10,rsp
+	sub	rsp,0x280+176
+	and	rsp,-32
+	lea	r11,[((656+48))+rsp]
+	movaps	XMMWORD[(-48)+r11],xmm6
+	movaps	XMMWORD[(-32)+r11],xmm7
+	movaps	XMMWORD[(-16)+r11],xmm8
+	movaps	XMMWORD[r11],xmm9
+	movaps	XMMWORD[16+r11],xmm10
+	movaps	XMMWORD[32+r11],xmm11
+	movaps	XMMWORD[48+r11],xmm12
+	movaps	XMMWORD[64+r11],xmm13
+	movaps	XMMWORD[80+r11],xmm14
+	movaps	XMMWORD[96+r11],xmm15
+	vzeroupper
+	mov	QWORD[640+rsp],r10
+
+
+
+
+
+
+
+
+
+
+	vbroadcasti128	ymm11,XMMWORD[$L$sigma]
+	vbroadcasti128	ymm3,XMMWORD[rcx]
+	vbroadcasti128	ymm15,XMMWORD[16+rcx]
+	vbroadcasti128	ymm7,XMMWORD[r8]
+	lea	rcx,[256+rsp]
+	lea	rax,[512+rsp]
+	lea	r10,[$L$rot16]
+	lea	r11,[$L$rot24]
+
+	vpshufd	ymm8,ymm11,0x00
+	vpshufd	ymm9,ymm11,0x55
+	vmovdqa	YMMWORD[(128-256)+rcx],ymm8
+	vpshufd	ymm10,ymm11,0xaa
+	vmovdqa	YMMWORD[(160-256)+rcx],ymm9
+	vpshufd	ymm11,ymm11,0xff
+	vmovdqa	YMMWORD[(192-256)+rcx],ymm10
+	vmovdqa	YMMWORD[(224-256)+rcx],ymm11
+
+	vpshufd	ymm0,ymm3,0x00
+	vpshufd	ymm1,ymm3,0x55
+	vmovdqa	YMMWORD[(256-256)+rcx],ymm0
+	vpshufd	ymm2,ymm3,0xaa
+	vmovdqa	YMMWORD[(288-256)+rcx],ymm1
+	vpshufd	ymm3,ymm3,0xff
+	vmovdqa	YMMWORD[(320-256)+rcx],ymm2
+	vmovdqa	YMMWORD[(352-256)+rcx],ymm3
+
+	vpshufd	ymm12,ymm15,0x00
+	vpshufd	ymm13,ymm15,0x55
+	vmovdqa	YMMWORD[(384-512)+rax],ymm12
+	vpshufd	ymm14,ymm15,0xaa
+	vmovdqa	YMMWORD[(416-512)+rax],ymm13
+	vpshufd	ymm15,ymm15,0xff
+	vmovdqa	YMMWORD[(448-512)+rax],ymm14
+	vmovdqa	YMMWORD[(480-512)+rax],ymm15
+
+	vpshufd	ymm4,ymm7,0x00
+	vpshufd	ymm5,ymm7,0x55
+	vpaddd	ymm4,ymm4,YMMWORD[$L$incy]
+	vpshufd	ymm6,ymm7,0xaa
+	vmovdqa	YMMWORD[(544-512)+rax],ymm5
+	vpshufd	ymm7,ymm7,0xff
+	vmovdqa	YMMWORD[(576-512)+rax],ymm6
+	vmovdqa	YMMWORD[(608-512)+rax],ymm7
+
+	jmp	NEAR $L$oop_enter8x
+
+ALIGN	32
+$L$oop_outer8x:
+	vmovdqa	ymm8,YMMWORD[((128-256))+rcx]
+	vmovdqa	ymm9,YMMWORD[((160-256))+rcx]
+	vmovdqa	ymm10,YMMWORD[((192-256))+rcx]
+	vmovdqa	ymm11,YMMWORD[((224-256))+rcx]
+	vmovdqa	ymm0,YMMWORD[((256-256))+rcx]
+	vmovdqa	ymm1,YMMWORD[((288-256))+rcx]
+	vmovdqa	ymm2,YMMWORD[((320-256))+rcx]
+	vmovdqa	ymm3,YMMWORD[((352-256))+rcx]
+	vmovdqa	ymm12,YMMWORD[((384-512))+rax]
+	vmovdqa	ymm13,YMMWORD[((416-512))+rax]
+	vmovdqa	ymm14,YMMWORD[((448-512))+rax]
+	vmovdqa	ymm15,YMMWORD[((480-512))+rax]
+	vmovdqa	ymm4,YMMWORD[((512-512))+rax]
+	vmovdqa	ymm5,YMMWORD[((544-512))+rax]
+	vmovdqa	ymm6,YMMWORD[((576-512))+rax]
+	vmovdqa	ymm7,YMMWORD[((608-512))+rax]
+	vpaddd	ymm4,ymm4,YMMWORD[$L$eight]
+
+$L$oop_enter8x:
+	vmovdqa	YMMWORD[64+rsp],ymm14
+	vmovdqa	YMMWORD[96+rsp],ymm15
+	vbroadcasti128	ymm15,XMMWORD[r10]
+	vmovdqa	YMMWORD[(512-512)+rax],ymm4
+	mov	eax,10
+	jmp	NEAR $L$oop8x
+
+ALIGN	32
+$L$oop8x:
+	vpaddd	ymm8,ymm8,ymm0
+	vpxor	ymm4,ymm8,ymm4
+	vpshufb	ymm4,ymm4,ymm15
+	vpaddd	ymm9,ymm9,ymm1
+	vpxor	ymm5,ymm9,ymm5
+	vpshufb	ymm5,ymm5,ymm15
+	vpaddd	ymm12,ymm12,ymm4
+	vpxor	ymm0,ymm12,ymm0
+	vpslld	ymm14,ymm0,12
+	vpsrld	ymm0,ymm0,20
+	vpor	ymm0,ymm14,ymm0
+	vbroadcasti128	ymm14,XMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm5
+	vpxor	ymm1,ymm13,ymm1
+	vpslld	ymm15,ymm1,12
+	vpsrld	ymm1,ymm1,20
+	vpor	ymm1,ymm15,ymm1
+	vpaddd	ymm8,ymm8,ymm0
+	vpxor	ymm4,ymm8,ymm4
+	vpshufb	ymm4,ymm4,ymm14
+	vpaddd	ymm9,ymm9,ymm1
+	vpxor	ymm5,ymm9,ymm5
+	vpshufb	ymm5,ymm5,ymm14
+	vpaddd	ymm12,ymm12,ymm4
+	vpxor	ymm0,ymm12,ymm0
+	vpslld	ymm15,ymm0,7
+	vpsrld	ymm0,ymm0,25
+	vpor	ymm0,ymm15,ymm0
+	vbroadcasti128	ymm15,XMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm5
+	vpxor	ymm1,ymm13,ymm1
+	vpslld	ymm14,ymm1,7
+	vpsrld	ymm1,ymm1,25
+	vpor	ymm1,ymm14,ymm1
+	vmovdqa	YMMWORD[rsp],ymm12
+	vmovdqa	YMMWORD[32+rsp],ymm13
+	vmovdqa	ymm12,YMMWORD[64+rsp]
+	vmovdqa	ymm13,YMMWORD[96+rsp]
+	vpaddd	ymm10,ymm10,ymm2
+	vpxor	ymm6,ymm10,ymm6
+	vpshufb	ymm6,ymm6,ymm15
+	vpaddd	ymm11,ymm11,ymm3
+	vpxor	ymm7,ymm11,ymm7
+	vpshufb	ymm7,ymm7,ymm15
+	vpaddd	ymm12,ymm12,ymm6
+	vpxor	ymm2,ymm12,ymm2
+	vpslld	ymm14,ymm2,12
+	vpsrld	ymm2,ymm2,20
+	vpor	ymm2,ymm14,ymm2
+	vbroadcasti128	ymm14,XMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm7
+	vpxor	ymm3,ymm13,ymm3
+	vpslld	ymm15,ymm3,12
+	vpsrld	ymm3,ymm3,20
+	vpor	ymm3,ymm15,ymm3
+	vpaddd	ymm10,ymm10,ymm2
+	vpxor	ymm6,ymm10,ymm6
+	vpshufb	ymm6,ymm6,ymm14
+	vpaddd	ymm11,ymm11,ymm3
+	vpxor	ymm7,ymm11,ymm7
+	vpshufb	ymm7,ymm7,ymm14
+	vpaddd	ymm12,ymm12,ymm6
+	vpxor	ymm2,ymm12,ymm2
+	vpslld	ymm15,ymm2,7
+	vpsrld	ymm2,ymm2,25
+	vpor	ymm2,ymm15,ymm2
+	vbroadcasti128	ymm15,XMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm7
+	vpxor	ymm3,ymm13,ymm3
+	vpslld	ymm14,ymm3,7
+	vpsrld	ymm3,ymm3,25
+	vpor	ymm3,ymm14,ymm3
+	vpaddd	ymm8,ymm8,ymm1
+	vpxor	ymm7,ymm8,ymm7
+	vpshufb	ymm7,ymm7,ymm15
+	vpaddd	ymm9,ymm9,ymm2
+	vpxor	ymm4,ymm9,ymm4
+	vpshufb	ymm4,ymm4,ymm15
+	vpaddd	ymm12,ymm12,ymm7
+	vpxor	ymm1,ymm12,ymm1
+	vpslld	ymm14,ymm1,12
+	vpsrld	ymm1,ymm1,20
+	vpor	ymm1,ymm14,ymm1
+	vbroadcasti128	ymm14,XMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm4
+	vpxor	ymm2,ymm13,ymm2
+	vpslld	ymm15,ymm2,12
+	vpsrld	ymm2,ymm2,20
+	vpor	ymm2,ymm15,ymm2
+	vpaddd	ymm8,ymm8,ymm1
+	vpxor	ymm7,ymm8,ymm7
+	vpshufb	ymm7,ymm7,ymm14
+	vpaddd	ymm9,ymm9,ymm2
+	vpxor	ymm4,ymm9,ymm4
+	vpshufb	ymm4,ymm4,ymm14
+	vpaddd	ymm12,ymm12,ymm7
+	vpxor	ymm1,ymm12,ymm1
+	vpslld	ymm15,ymm1,7
+	vpsrld	ymm1,ymm1,25
+	vpor	ymm1,ymm15,ymm1
+	vbroadcasti128	ymm15,XMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm4
+	vpxor	ymm2,ymm13,ymm2
+	vpslld	ymm14,ymm2,7
+	vpsrld	ymm2,ymm2,25
+	vpor	ymm2,ymm14,ymm2
+	vmovdqa	YMMWORD[64+rsp],ymm12
+	vmovdqa	YMMWORD[96+rsp],ymm13
+	vmovdqa	ymm12,YMMWORD[rsp]
+	vmovdqa	ymm13,YMMWORD[32+rsp]
+	vpaddd	ymm10,ymm10,ymm3
+	vpxor	ymm5,ymm10,ymm5
+	vpshufb	ymm5,ymm5,ymm15
+	vpaddd	ymm11,ymm11,ymm0
+	vpxor	ymm6,ymm11,ymm6
+	vpshufb	ymm6,ymm6,ymm15
+	vpaddd	ymm12,ymm12,ymm5
+	vpxor	ymm3,ymm12,ymm3
+	vpslld	ymm14,ymm3,12
+	vpsrld	ymm3,ymm3,20
+	vpor	ymm3,ymm14,ymm3
+	vbroadcasti128	ymm14,XMMWORD[r11]
+	vpaddd	ymm13,ymm13,ymm6
+	vpxor	ymm0,ymm13,ymm0
+	vpslld	ymm15,ymm0,12
+	vpsrld	ymm0,ymm0,20
+	vpor	ymm0,ymm15,ymm0
+	vpaddd	ymm10,ymm10,ymm3
+	vpxor	ymm5,ymm10,ymm5
+	vpshufb	ymm5,ymm5,ymm14
+	vpaddd	ymm11,ymm11,ymm0
+	vpxor	ymm6,ymm11,ymm6
+	vpshufb	ymm6,ymm6,ymm14
+	vpaddd	ymm12,ymm12,ymm5
+	vpxor	ymm3,ymm12,ymm3
+	vpslld	ymm15,ymm3,7
+	vpsrld	ymm3,ymm3,25
+	vpor	ymm3,ymm15,ymm3
+	vbroadcasti128	ymm15,XMMWORD[r10]
+	vpaddd	ymm13,ymm13,ymm6
+	vpxor	ymm0,ymm13,ymm0
+	vpslld	ymm14,ymm0,7
+	vpsrld	ymm0,ymm0,25
+	vpor	ymm0,ymm14,ymm0
+	dec	eax
+	jnz	NEAR $L$oop8x
+
+	lea	rax,[512+rsp]
+	vpaddd	ymm8,ymm8,YMMWORD[((128-256))+rcx]
+	vpaddd	ymm9,ymm9,YMMWORD[((160-256))+rcx]
+	vpaddd	ymm10,ymm10,YMMWORD[((192-256))+rcx]
+	vpaddd	ymm11,ymm11,YMMWORD[((224-256))+rcx]
+
+	vpunpckldq	ymm14,ymm8,ymm9
+	vpunpckldq	ymm15,ymm10,ymm11
+	vpunpckhdq	ymm8,ymm8,ymm9
+	vpunpckhdq	ymm10,ymm10,ymm11
+	vpunpcklqdq	ymm9,ymm14,ymm15
+	vpunpckhqdq	ymm14,ymm14,ymm15
+	vpunpcklqdq	ymm11,ymm8,ymm10
+	vpunpckhqdq	ymm8,ymm8,ymm10
+	vpaddd	ymm0,ymm0,YMMWORD[((256-256))+rcx]
+	vpaddd	ymm1,ymm1,YMMWORD[((288-256))+rcx]
+	vpaddd	ymm2,ymm2,YMMWORD[((320-256))+rcx]
+	vpaddd	ymm3,ymm3,YMMWORD[((352-256))+rcx]
+
+	vpunpckldq	ymm10,ymm0,ymm1
+	vpunpckldq	ymm15,ymm2,ymm3
+	vpunpckhdq	ymm0,ymm0,ymm1
+	vpunpckhdq	ymm2,ymm2,ymm3
+	vpunpcklqdq	ymm1,ymm10,ymm15
+	vpunpckhqdq	ymm10,ymm10,ymm15
+	vpunpcklqdq	ymm3,ymm0,ymm2
+	vpunpckhqdq	ymm0,ymm0,ymm2
+	vperm2i128	ymm15,ymm9,ymm1,0x20
+	vperm2i128	ymm1,ymm9,ymm1,0x31
+	vperm2i128	ymm9,ymm14,ymm10,0x20
+	vperm2i128	ymm10,ymm14,ymm10,0x31
+	vperm2i128	ymm14,ymm11,ymm3,0x20
+	vperm2i128	ymm3,ymm11,ymm3,0x31
+	vperm2i128	ymm11,ymm8,ymm0,0x20
+	vperm2i128	ymm0,ymm8,ymm0,0x31
+	vmovdqa	YMMWORD[rsp],ymm15
+	vmovdqa	YMMWORD[32+rsp],ymm9
+	vmovdqa	ymm15,YMMWORD[64+rsp]
+	vmovdqa	ymm9,YMMWORD[96+rsp]
+
+	vpaddd	ymm12,ymm12,YMMWORD[((384-512))+rax]
+	vpaddd	ymm13,ymm13,YMMWORD[((416-512))+rax]
+	vpaddd	ymm15,ymm15,YMMWORD[((448-512))+rax]
+	vpaddd	ymm9,ymm9,YMMWORD[((480-512))+rax]
+
+	vpunpckldq	ymm2,ymm12,ymm13
+	vpunpckldq	ymm8,ymm15,ymm9
+	vpunpckhdq	ymm12,ymm12,ymm13
+	vpunpckhdq	ymm15,ymm15,ymm9
+	vpunpcklqdq	ymm13,ymm2,ymm8
+	vpunpckhqdq	ymm2,ymm2,ymm8
+	vpunpcklqdq	ymm9,ymm12,ymm15
+	vpunpckhqdq	ymm12,ymm12,ymm15
+	vpaddd	ymm4,ymm4,YMMWORD[((512-512))+rax]
+	vpaddd	ymm5,ymm5,YMMWORD[((544-512))+rax]
+	vpaddd	ymm6,ymm6,YMMWORD[((576-512))+rax]
+	vpaddd	ymm7,ymm7,YMMWORD[((608-512))+rax]
+
+	vpunpckldq	ymm15,ymm4,ymm5
+	vpunpckldq	ymm8,ymm6,ymm7
+	vpunpckhdq	ymm4,ymm4,ymm5
+	vpunpckhdq	ymm6,ymm6,ymm7
+	vpunpcklqdq	ymm5,ymm15,ymm8
+	vpunpckhqdq	ymm15,ymm15,ymm8
+	vpunpcklqdq	ymm7,ymm4,ymm6
+	vpunpckhqdq	ymm4,ymm4,ymm6
+	vperm2i128	ymm8,ymm13,ymm5,0x20
+	vperm2i128	ymm5,ymm13,ymm5,0x31
+	vperm2i128	ymm13,ymm2,ymm15,0x20
+	vperm2i128	ymm15,ymm2,ymm15,0x31
+	vperm2i128	ymm2,ymm9,ymm7,0x20
+	vperm2i128	ymm7,ymm9,ymm7,0x31
+	vperm2i128	ymm9,ymm12,ymm4,0x20
+	vperm2i128	ymm4,ymm12,ymm4,0x31
+	vmovdqa	ymm6,YMMWORD[rsp]
+	vmovdqa	ymm12,YMMWORD[32+rsp]
+
+	cmp	rdx,64*8
+	jb	NEAR $L$tail8x
+
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	lea	rdi,[128+rdi]
+
+	vpxor	ymm12,ymm12,YMMWORD[rsi]
+	vpxor	ymm13,ymm13,YMMWORD[32+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[64+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm12
+	vmovdqu	YMMWORD[32+rdi],ymm13
+	vmovdqu	YMMWORD[64+rdi],ymm10
+	vmovdqu	YMMWORD[96+rdi],ymm15
+	lea	rdi,[128+rdi]
+
+	vpxor	ymm14,ymm14,YMMWORD[rsi]
+	vpxor	ymm2,ymm2,YMMWORD[32+rsi]
+	vpxor	ymm3,ymm3,YMMWORD[64+rsi]
+	vpxor	ymm7,ymm7,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm14
+	vmovdqu	YMMWORD[32+rdi],ymm2
+	vmovdqu	YMMWORD[64+rdi],ymm3
+	vmovdqu	YMMWORD[96+rdi],ymm7
+	lea	rdi,[128+rdi]
+
+	vpxor	ymm11,ymm11,YMMWORD[rsi]
+	vpxor	ymm9,ymm9,YMMWORD[32+rsi]
+	vpxor	ymm0,ymm0,YMMWORD[64+rsi]
+	vpxor	ymm4,ymm4,YMMWORD[96+rsi]
+	lea	rsi,[128+rsi]
+	vmovdqu	YMMWORD[rdi],ymm11
+	vmovdqu	YMMWORD[32+rdi],ymm9
+	vmovdqu	YMMWORD[64+rdi],ymm0
+	vmovdqu	YMMWORD[96+rdi],ymm4
+	lea	rdi,[128+rdi]
+
+	sub	rdx,64*8
+	jnz	NEAR $L$oop_outer8x
+
+	jmp	NEAR $L$done8x
+
+$L$tail8x:
+	cmp	rdx,448
+	jae	NEAR $L$448_or_more8x
+	cmp	rdx,384
+	jae	NEAR $L$384_or_more8x
+	cmp	rdx,320
+	jae	NEAR $L$320_or_more8x
+	cmp	rdx,256
+	jae	NEAR $L$256_or_more8x
+	cmp	rdx,192
+	jae	NEAR $L$192_or_more8x
+	cmp	rdx,128
+	jae	NEAR $L$128_or_more8x
+	cmp	rdx,64
+	jae	NEAR $L$64_or_more8x
+
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm6
+	vmovdqa	YMMWORD[32+rsp],ymm8
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$64_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	je	NEAR $L$done8x
+
+	lea	rsi,[64+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm1
+	lea	rdi,[64+rdi]
+	sub	rdx,64
+	vmovdqa	YMMWORD[32+rsp],ymm5
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$128_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	je	NEAR $L$done8x
+
+	lea	rsi,[128+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm12
+	lea	rdi,[128+rdi]
+	sub	rdx,128
+	vmovdqa	YMMWORD[32+rsp],ymm13
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$192_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	je	NEAR $L$done8x
+
+	lea	rsi,[192+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm10
+	lea	rdi,[192+rdi]
+	sub	rdx,192
+	vmovdqa	YMMWORD[32+rsp],ymm15
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$256_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	je	NEAR $L$done8x
+
+	lea	rsi,[256+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm14
+	lea	rdi,[256+rdi]
+	sub	rdx,256
+	vmovdqa	YMMWORD[32+rsp],ymm2
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$320_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vpxor	ymm14,ymm14,YMMWORD[256+rsi]
+	vpxor	ymm2,ymm2,YMMWORD[288+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	vmovdqu	YMMWORD[256+rdi],ymm14
+	vmovdqu	YMMWORD[288+rdi],ymm2
+	je	NEAR $L$done8x
+
+	lea	rsi,[320+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm3
+	lea	rdi,[320+rdi]
+	sub	rdx,320
+	vmovdqa	YMMWORD[32+rsp],ymm7
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$384_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vpxor	ymm14,ymm14,YMMWORD[256+rsi]
+	vpxor	ymm2,ymm2,YMMWORD[288+rsi]
+	vpxor	ymm3,ymm3,YMMWORD[320+rsi]
+	vpxor	ymm7,ymm7,YMMWORD[352+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	vmovdqu	YMMWORD[256+rdi],ymm14
+	vmovdqu	YMMWORD[288+rdi],ymm2
+	vmovdqu	YMMWORD[320+rdi],ymm3
+	vmovdqu	YMMWORD[352+rdi],ymm7
+	je	NEAR $L$done8x
+
+	lea	rsi,[384+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm11
+	lea	rdi,[384+rdi]
+	sub	rdx,384
+	vmovdqa	YMMWORD[32+rsp],ymm9
+	jmp	NEAR $L$oop_tail8x
+
+ALIGN	32
+$L$448_or_more8x:
+	vpxor	ymm6,ymm6,YMMWORD[rsi]
+	vpxor	ymm8,ymm8,YMMWORD[32+rsi]
+	vpxor	ymm1,ymm1,YMMWORD[64+rsi]
+	vpxor	ymm5,ymm5,YMMWORD[96+rsi]
+	vpxor	ymm12,ymm12,YMMWORD[128+rsi]
+	vpxor	ymm13,ymm13,YMMWORD[160+rsi]
+	vpxor	ymm10,ymm10,YMMWORD[192+rsi]
+	vpxor	ymm15,ymm15,YMMWORD[224+rsi]
+	vpxor	ymm14,ymm14,YMMWORD[256+rsi]
+	vpxor	ymm2,ymm2,YMMWORD[288+rsi]
+	vpxor	ymm3,ymm3,YMMWORD[320+rsi]
+	vpxor	ymm7,ymm7,YMMWORD[352+rsi]
+	vpxor	ymm11,ymm11,YMMWORD[384+rsi]
+	vpxor	ymm9,ymm9,YMMWORD[416+rsi]
+	vmovdqu	YMMWORD[rdi],ymm6
+	vmovdqu	YMMWORD[32+rdi],ymm8
+	vmovdqu	YMMWORD[64+rdi],ymm1
+	vmovdqu	YMMWORD[96+rdi],ymm5
+	vmovdqu	YMMWORD[128+rdi],ymm12
+	vmovdqu	YMMWORD[160+rdi],ymm13
+	vmovdqu	YMMWORD[192+rdi],ymm10
+	vmovdqu	YMMWORD[224+rdi],ymm15
+	vmovdqu	YMMWORD[256+rdi],ymm14
+	vmovdqu	YMMWORD[288+rdi],ymm2
+	vmovdqu	YMMWORD[320+rdi],ymm3
+	vmovdqu	YMMWORD[352+rdi],ymm7
+	vmovdqu	YMMWORD[384+rdi],ymm11
+	vmovdqu	YMMWORD[416+rdi],ymm9
+	je	NEAR $L$done8x
+
+	lea	rsi,[448+rsi]
+	xor	r10,r10
+	vmovdqa	YMMWORD[rsp],ymm0
+	lea	rdi,[448+rdi]
+	sub	rdx,448
+	vmovdqa	YMMWORD[32+rsp],ymm4
+
+$L$oop_tail8x:
+	movzx	eax,BYTE[r10*1+rsi]
+	movzx	ecx,BYTE[r10*1+rsp]
+	lea	r10,[1+r10]
+	xor	eax,ecx
+	mov	BYTE[((-1))+r10*1+rdi],al
+	dec	rdx
+	jnz	NEAR $L$oop_tail8x
+
+$L$done8x:
+	vzeroall
+	lea	r11,[((656+48))+rsp]
+	movaps	xmm6,XMMWORD[((-48))+r11]
+	movaps	xmm7,XMMWORD[((-32))+r11]
+	movaps	xmm8,XMMWORD[((-16))+r11]
+	movaps	xmm9,XMMWORD[r11]
+	movaps	xmm10,XMMWORD[16+r11]
+	movaps	xmm11,XMMWORD[32+r11]
+	movaps	xmm12,XMMWORD[48+r11]
+	movaps	xmm13,XMMWORD[64+r11]
+	movaps	xmm14,XMMWORD[80+r11]
+	movaps	xmm15,XMMWORD[96+r11]
+	mov	rsp,QWORD[640+rsp]
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ChaCha20_8x:
diff --git a/third_party/boringssl/win-x86_64/crypto/cpu-x86_64-asm.asm b/third_party/boringssl/win-x86_64/crypto/cpu-x86_64-asm.asm
deleted file mode 100644
index c92d7bb..0000000
--- a/third_party/boringssl/win-x86_64/crypto/cpu-x86_64-asm.asm
+++ /dev/null
@@ -1,154 +0,0 @@
-default	rel
-%define XMMWORD
-%define YMMWORD
-%define ZMMWORD
-section	.text code align=64
-
-
-global	OPENSSL_ia32_cpuid
-
-ALIGN	16
-OPENSSL_ia32_cpuid:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_OPENSSL_ia32_cpuid:
-	mov	rdi,rcx
-
-
-
-
-	mov	rdi,rcx
-	mov	r8,rbx
-
-	xor	eax,eax
-	mov	DWORD[8+rdi],eax
-	cpuid
-	mov	r11d,eax
-
-	xor	eax,eax
-	cmp	ebx,0x756e6547
-	setne	al
-	mov	r9d,eax
-	cmp	edx,0x49656e69
-	setne	al
-	or	r9d,eax
-	cmp	ecx,0x6c65746e
-	setne	al
-	or	r9d,eax
-	jz	NEAR $L$intel
-
-	cmp	ebx,0x68747541
-	setne	al
-	mov	r10d,eax
-	cmp	edx,0x69746E65
-	setne	al
-	or	r10d,eax
-	cmp	ecx,0x444D4163
-	setne	al
-	or	r10d,eax
-	jnz	NEAR $L$intel
-
-
-
-
-	mov	eax,0x80000000
-	cpuid
-
-
-	cmp	eax,0x80000001
-	jb	NEAR $L$intel
-	mov	r10d,eax
-	mov	eax,0x80000001
-	cpuid
-
-
-	or	r9d,ecx
-	and	r9d,0x00000801
-
-	cmp	r10d,0x80000008
-	jb	NEAR $L$intel
-
-	mov	eax,0x80000008
-	cpuid
-
-	movzx	r10,cl
-	inc	r10
-
-	mov	eax,1
-	cpuid
-
-	bt	edx,28
-	jnc	NEAR $L$generic
-	shr	ebx,16
-	cmp	bl,r10b
-	ja	NEAR $L$generic
-	and	edx,0xefffffff
-	jmp	NEAR $L$generic
-
-$L$intel:
-	cmp	r11d,4
-	mov	r10d,-1
-	jb	NEAR $L$nocacheinfo
-
-	mov	eax,4
-	mov	ecx,0
-	cpuid
-	mov	r10d,eax
-	shr	r10d,14
-	and	r10d,0xfff
-
-	cmp	r11d,7
-	jb	NEAR $L$nocacheinfo
-
-	mov	eax,7
-	xor	ecx,ecx
-	cpuid
-	mov	DWORD[8+rdi],ebx
-
-$L$nocacheinfo:
-	mov	eax,1
-	cpuid
-
-	and	edx,0xbfefffff
-	cmp	r9d,0
-	jne	NEAR $L$notintel
-	or	edx,0x40000000
-$L$notintel:
-	bt	edx,28
-	jnc	NEAR $L$generic
-	and	edx,0xefffffff
-	cmp	r10d,0
-	je	NEAR $L$generic
-
-	or	edx,0x10000000
-	shr	ebx,16
-	cmp	bl,1
-	ja	NEAR $L$generic
-	and	edx,0xefffffff
-$L$generic:
-	and	r9d,0x00000800
-	and	ecx,0xfffff7ff
-	or	r9d,ecx
-
-	mov	r10d,edx
-	bt	r9d,27
-	jnc	NEAR $L$clear_avx
-	xor	ecx,ecx
-DB	0x0f,0x01,0xd0
-	and	eax,6
-	cmp	eax,6
-	je	NEAR $L$done
-$L$clear_avx:
-	mov	eax,0xefffe7ff
-	and	r9d,eax
-	and	DWORD[8+rdi],0xffffffdf
-$L$done:
-	mov	DWORD[4+rdi],r9d
-	mov	DWORD[rdi],r10d
-	mov	rbx,r8
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-$L$SEH_end_OPENSSL_ia32_cpuid:
-
diff --git a/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm b/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm
new file mode 100644
index 0000000..a2e4075
--- /dev/null
+++ b/third_party/boringssl/win-x86_64/crypto/ec/p256-x86_64-asm.asm
@@ -0,0 +1,1925 @@
+default	rel
+%define XMMWORD
+%define YMMWORD
+%define ZMMWORD
+section	.text code align=64
+
+EXTERN	OPENSSL_ia32cap_P
+
+
+ALIGN	64
+$L$poly:
+	DQ	0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001
+
+$L$One:
+	DD	1,1,1,1,1,1,1,1
+$L$Two:
+	DD	2,2,2,2,2,2,2,2
+$L$Three:
+	DD	3,3,3,3,3,3,3,3
+$L$ONE_mont:
+	DQ	0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe
+
+
+ALIGN	64
+ecp_nistz256_mul_by_2:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_mul_by_2:
+	mov	rdi,rcx
+	mov	rsi,rdx
+
+
+	push	r12
+	push	r13
+
+	mov	r8,QWORD[rsi]
+	mov	r9,QWORD[8+rsi]
+	add	r8,r8
+	mov	r10,QWORD[16+rsi]
+	adc	r9,r9
+	mov	r11,QWORD[24+rsi]
+	lea	rsi,[$L$poly]
+	mov	rax,r8
+	adc	r10,r10
+	adc	r11,r11
+	mov	rdx,r9
+	sbb	r13,r13
+
+	sub	r8,QWORD[rsi]
+	mov	rcx,r10
+	sbb	r9,QWORD[8+rsi]
+	sbb	r10,QWORD[16+rsi]
+	mov	r12,r11
+	sbb	r11,QWORD[24+rsi]
+	test	r13,r13
+
+	cmovz	r8,rax
+	cmovz	r9,rdx
+	mov	QWORD[rdi],r8
+	cmovz	r10,rcx
+	mov	QWORD[8+rdi],r9
+	cmovz	r11,r12
+	mov	QWORD[16+rdi],r10
+	mov	QWORD[24+rdi],r11
+
+	pop	r13
+	pop	r12
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_mul_by_2:
+
+
+
+global	ecp_nistz256_neg
+
+ALIGN	32
+ecp_nistz256_neg:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_neg:
+	mov	rdi,rcx
+	mov	rsi,rdx
+
+
+	push	r12
+	push	r13
+
+	xor	r8,r8
+	xor	r9,r9
+	xor	r10,r10
+	xor	r11,r11
+	xor	r13,r13
+
+	sub	r8,QWORD[rsi]
+	sbb	r9,QWORD[8+rsi]
+	sbb	r10,QWORD[16+rsi]
+	mov	rax,r8
+	sbb	r11,QWORD[24+rsi]
+	lea	rsi,[$L$poly]
+	mov	rdx,r9
+	sbb	r13,0
+
+	add	r8,QWORD[rsi]
+	mov	rcx,r10
+	adc	r9,QWORD[8+rsi]
+	adc	r10,QWORD[16+rsi]
+	mov	r12,r11
+	adc	r11,QWORD[24+rsi]
+	test	r13,r13
+
+	cmovz	r8,rax
+	cmovz	r9,rdx
+	mov	QWORD[rdi],r8
+	cmovz	r10,rcx
+	mov	QWORD[8+rdi],r9
+	cmovz	r11,r12
+	mov	QWORD[16+rdi],r10
+	mov	QWORD[24+rdi],r11
+
+	pop	r13
+	pop	r12
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_neg:
+
+
+
+
+
+
+global	ecp_nistz256_mul_mont
+
+ALIGN	32
+ecp_nistz256_mul_mont:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_mul_mont:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+$L$mul_mont:
+	push	rbp
+	push	rbx
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	mov	rbx,rdx
+	mov	rax,QWORD[rdx]
+	mov	r9,QWORD[rsi]
+	mov	r10,QWORD[8+rsi]
+	mov	r11,QWORD[16+rsi]
+	mov	r12,QWORD[24+rsi]
+
+	call	__ecp_nistz256_mul_montq
+$L$mul_mont_done:
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbx
+	pop	rbp
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_mul_mont:
+
+
+ALIGN	32
+__ecp_nistz256_mul_montq:
+
+
+	mov	rbp,rax
+	mul	r9
+	mov	r14,QWORD[(($L$poly+8))]
+	mov	r8,rax
+	mov	rax,rbp
+	mov	r9,rdx
+
+	mul	r10
+	mov	r15,QWORD[(($L$poly+24))]
+	add	r9,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	r10,rdx
+
+	mul	r11
+	add	r10,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	r11,rdx
+
+	mul	r12
+	add	r11,rax
+	mov	rax,r8
+	adc	rdx,0
+	xor	r13,r13
+	mov	r12,rdx
+
+
+
+
+
+
+
+
+
+
+	mov	rbp,r8
+	shl	r8,32
+	mul	r15
+	shr	rbp,32
+	add	r9,r8
+	adc	r10,rbp
+	adc	r11,rax
+	mov	rax,QWORD[8+rbx]
+	adc	r12,rdx
+	adc	r13,0
+	xor	r8,r8
+
+
+
+	mov	rbp,rax
+	mul	QWORD[rsi]
+	add	r9,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[8+rsi]
+	add	r10,rcx
+	adc	rdx,0
+	add	r10,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[16+rsi]
+	add	r11,rcx
+	adc	rdx,0
+	add	r11,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[24+rsi]
+	add	r12,rcx
+	adc	rdx,0
+	add	r12,rax
+	mov	rax,r9
+	adc	r13,rdx
+	adc	r8,0
+
+
+
+	mov	rbp,r9
+	shl	r9,32
+	mul	r15
+	shr	rbp,32
+	add	r10,r9
+	adc	r11,rbp
+	adc	r12,rax
+	mov	rax,QWORD[16+rbx]
+	adc	r13,rdx
+	adc	r8,0
+	xor	r9,r9
+
+
+
+	mov	rbp,rax
+	mul	QWORD[rsi]
+	add	r10,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[8+rsi]
+	add	r11,rcx
+	adc	rdx,0
+	add	r11,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[16+rsi]
+	add	r12,rcx
+	adc	rdx,0
+	add	r12,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[24+rsi]
+	add	r13,rcx
+	adc	rdx,0
+	add	r13,rax
+	mov	rax,r10
+	adc	r8,rdx
+	adc	r9,0
+
+
+
+	mov	rbp,r10
+	shl	r10,32
+	mul	r15
+	shr	rbp,32
+	add	r11,r10
+	adc	r12,rbp
+	adc	r13,rax
+	mov	rax,QWORD[24+rbx]
+	adc	r8,rdx
+	adc	r9,0
+	xor	r10,r10
+
+
+
+	mov	rbp,rax
+	mul	QWORD[rsi]
+	add	r11,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[8+rsi]
+	add	r12,rcx
+	adc	rdx,0
+	add	r12,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[16+rsi]
+	add	r13,rcx
+	adc	rdx,0
+	add	r13,rax
+	mov	rax,rbp
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	QWORD[24+rsi]
+	add	r8,rcx
+	adc	rdx,0
+	add	r8,rax
+	mov	rax,r11
+	adc	r9,rdx
+	adc	r10,0
+
+
+
+	mov	rbp,r11
+	shl	r11,32
+	mul	r15
+	shr	rbp,32
+	add	r12,r11
+	adc	r13,rbp
+	mov	rcx,r12
+	adc	r8,rax
+	adc	r9,rdx
+	mov	rbp,r13
+	adc	r10,0
+
+
+
+	sub	r12,-1
+	mov	rbx,r8
+	sbb	r13,r14
+	sbb	r8,0
+	mov	rdx,r9
+	sbb	r9,r15
+	sbb	r10,0
+
+	cmovc	r12,rcx
+	cmovc	r13,rbp
+	mov	QWORD[rdi],r12
+	cmovc	r8,rbx
+	mov	QWORD[8+rdi],r13
+	cmovc	r9,rdx
+	mov	QWORD[16+rdi],r8
+	mov	QWORD[24+rdi],r9
+
+	DB	0F3h,0C3h		;repret
+
+
+
+
+
+
+
+
+
+global	ecp_nistz256_sqr_mont
+
+ALIGN	32
+ecp_nistz256_sqr_mont:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_sqr_mont:
+	mov	rdi,rcx
+	mov	rsi,rdx
+
+
+	push	rbp
+	push	rbx
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	mov	rax,QWORD[rsi]
+	mov	r14,QWORD[8+rsi]
+	mov	r15,QWORD[16+rsi]
+	mov	r8,QWORD[24+rsi]
+
+	call	__ecp_nistz256_sqr_montq
+$L$sqr_mont_done:
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbx
+	pop	rbp
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_sqr_mont:
+
+
+ALIGN	32
+__ecp_nistz256_sqr_montq:
+	mov	r13,rax
+	mul	r14
+	mov	r9,rax
+	mov	rax,r15
+	mov	r10,rdx
+
+	mul	r13
+	add	r10,rax
+	mov	rax,r8
+	adc	rdx,0
+	mov	r11,rdx
+
+	mul	r13
+	add	r11,rax
+	mov	rax,r15
+	adc	rdx,0
+	mov	r12,rdx
+
+
+	mul	r14
+	add	r11,rax
+	mov	rax,r8
+	adc	rdx,0
+	mov	rbp,rdx
+
+	mul	r14
+	add	r12,rax
+	mov	rax,r8
+	adc	rdx,0
+	add	r12,rbp
+	mov	r13,rdx
+	adc	r13,0
+
+
+	mul	r15
+	xor	r15,r15
+	add	r13,rax
+	mov	rax,QWORD[rsi]
+	mov	r14,rdx
+	adc	r14,0
+
+	add	r9,r9
+	adc	r10,r10
+	adc	r11,r11
+	adc	r12,r12
+	adc	r13,r13
+	adc	r14,r14
+	adc	r15,0
+
+	mul	rax
+	mov	r8,rax
+	mov	rax,QWORD[8+rsi]
+	mov	rcx,rdx
+
+	mul	rax
+	add	r9,rcx
+	adc	r10,rax
+	mov	rax,QWORD[16+rsi]
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	rax
+	add	r11,rcx
+	adc	r12,rax
+	mov	rax,QWORD[24+rsi]
+	adc	rdx,0
+	mov	rcx,rdx
+
+	mul	rax
+	add	r13,rcx
+	adc	r14,rax
+	mov	rax,r8
+	adc	r15,rdx
+
+	mov	rsi,QWORD[(($L$poly+8))]
+	mov	rbp,QWORD[(($L$poly+24))]
+
+
+
+
+	mov	rcx,r8
+	shl	r8,32
+	mul	rbp
+	shr	rcx,32
+	add	r9,r8
+	adc	r10,rcx
+	adc	r11,rax
+	mov	rax,r9
+	adc	rdx,0
+
+
+
+	mov	rcx,r9
+	shl	r9,32
+	mov	r8,rdx
+	mul	rbp
+	shr	rcx,32
+	add	r10,r9
+	adc	r11,rcx
+	adc	r8,rax
+	mov	rax,r10
+	adc	rdx,0
+
+
+
+	mov	rcx,r10
+	shl	r10,32
+	mov	r9,rdx
+	mul	rbp
+	shr	rcx,32
+	add	r11,r10
+	adc	r8,rcx
+	adc	r9,rax
+	mov	rax,r11
+	adc	rdx,0
+
+
+
+	mov	rcx,r11
+	shl	r11,32
+	mov	r10,rdx
+	mul	rbp
+	shr	rcx,32
+	add	r8,r11
+	adc	r9,rcx
+	adc	r10,rax
+	adc	rdx,0
+	xor	r11,r11
+
+
+
+	add	r12,r8
+	adc	r13,r9
+	mov	r8,r12
+	adc	r14,r10
+	adc	r15,rdx
+	mov	r9,r13
+	adc	r11,0
+
+	sub	r12,-1
+	mov	r10,r14
+	sbb	r13,rsi
+	sbb	r14,0
+	mov	rcx,r15
+	sbb	r15,rbp
+	sbb	r11,0
+
+	cmovc	r12,r8
+	cmovc	r13,r9
+	mov	QWORD[rdi],r12
+	cmovc	r14,r10
+	mov	QWORD[8+rdi],r13
+	cmovc	r15,rcx
+	mov	QWORD[16+rdi],r14
+	mov	QWORD[24+rdi],r15
+
+	DB	0F3h,0C3h		;repret
+
+
+
+
+
+
+
+global	ecp_nistz256_from_mont
+
+ALIGN	32
+ecp_nistz256_from_mont:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_from_mont:
+	mov	rdi,rcx
+	mov	rsi,rdx
+
+
+	push	r12
+	push	r13
+
+	mov	rax,QWORD[rsi]
+	mov	r13,QWORD[(($L$poly+24))]
+	mov	r9,QWORD[8+rsi]
+	mov	r10,QWORD[16+rsi]
+	mov	r11,QWORD[24+rsi]
+	mov	r8,rax
+	mov	r12,QWORD[(($L$poly+8))]
+
+
+
+	mov	rcx,rax
+	shl	r8,32
+	mul	r13
+	shr	rcx,32
+	add	r9,r8
+	adc	r10,rcx
+	adc	r11,rax
+	mov	rax,r9
+	adc	rdx,0
+
+
+
+	mov	rcx,r9
+	shl	r9,32
+	mov	r8,rdx
+	mul	r13
+	shr	rcx,32
+	add	r10,r9
+	adc	r11,rcx
+	adc	r8,rax
+	mov	rax,r10
+	adc	rdx,0
+
+
+
+	mov	rcx,r10
+	shl	r10,32
+	mov	r9,rdx
+	mul	r13
+	shr	rcx,32
+	add	r11,r10
+	adc	r8,rcx
+	adc	r9,rax
+	mov	rax,r11
+	adc	rdx,0
+
+
+
+	mov	rcx,r11
+	shl	r11,32
+	mov	r10,rdx
+	mul	r13
+	shr	rcx,32
+	add	r8,r11
+	adc	r9,rcx
+	mov	rcx,r8
+	adc	r10,rax
+	mov	rsi,r9
+	adc	rdx,0
+
+	sub	r8,-1
+	mov	rax,r10
+	sbb	r9,r12
+	sbb	r10,0
+	mov	r11,rdx
+	sbb	rdx,r13
+	sbb	r13,r13
+
+	cmovnz	r8,rcx
+	cmovnz	r9,rsi
+	mov	QWORD[rdi],r8
+	cmovnz	r10,rax
+	mov	QWORD[8+rdi],r9
+	cmovz	r11,rdx
+	mov	QWORD[16+rdi],r10
+	mov	QWORD[24+rdi],r11
+
+	pop	r13
+	pop	r12
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_from_mont:
+
+
+global	ecp_nistz256_select_w5
+
+ALIGN	32
+ecp_nistz256_select_w5:
+	lea	rax,[((-136))+rsp]
+$L$SEH_begin_ecp_nistz256_select_w5:
+DB	0x48,0x8d,0x60,0xe0
+DB	0x0f,0x29,0x70,0xe0
+DB	0x0f,0x29,0x78,0xf0
+DB	0x44,0x0f,0x29,0x00
+DB	0x44,0x0f,0x29,0x48,0x10
+DB	0x44,0x0f,0x29,0x50,0x20
+DB	0x44,0x0f,0x29,0x58,0x30
+DB	0x44,0x0f,0x29,0x60,0x40
+DB	0x44,0x0f,0x29,0x68,0x50
+DB	0x44,0x0f,0x29,0x70,0x60
+DB	0x44,0x0f,0x29,0x78,0x70
+	movdqa	xmm0,XMMWORD[$L$One]
+	movd	xmm1,r8d
+
+	pxor	xmm2,xmm2
+	pxor	xmm3,xmm3
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+	pxor	xmm6,xmm6
+	pxor	xmm7,xmm7
+
+	movdqa	xmm8,xmm0
+	pshufd	xmm1,xmm1,0
+
+	mov	rax,16
+$L$select_loop_sse_w5:
+
+	movdqa	xmm15,xmm8
+	paddd	xmm8,xmm0
+	pcmpeqd	xmm15,xmm1
+
+	movdqa	xmm9,XMMWORD[rdx]
+	movdqa	xmm10,XMMWORD[16+rdx]
+	movdqa	xmm11,XMMWORD[32+rdx]
+	movdqa	xmm12,XMMWORD[48+rdx]
+	movdqa	xmm13,XMMWORD[64+rdx]
+	movdqa	xmm14,XMMWORD[80+rdx]
+	lea	rdx,[96+rdx]
+
+	pand	xmm9,xmm15
+	pand	xmm10,xmm15
+	por	xmm2,xmm9
+	pand	xmm11,xmm15
+	por	xmm3,xmm10
+	pand	xmm12,xmm15
+	por	xmm4,xmm11
+	pand	xmm13,xmm15
+	por	xmm5,xmm12
+	pand	xmm14,xmm15
+	por	xmm6,xmm13
+	por	xmm7,xmm14
+
+	dec	rax
+	jnz	NEAR $L$select_loop_sse_w5
+
+	movdqu	XMMWORD[rcx],xmm2
+	movdqu	XMMWORD[16+rcx],xmm3
+	movdqu	XMMWORD[32+rcx],xmm4
+	movdqu	XMMWORD[48+rcx],xmm5
+	movdqu	XMMWORD[64+rcx],xmm6
+	movdqu	XMMWORD[80+rcx],xmm7
+	movaps	xmm6,XMMWORD[rsp]
+	movaps	xmm7,XMMWORD[16+rsp]
+	movaps	xmm8,XMMWORD[32+rsp]
+	movaps	xmm9,XMMWORD[48+rsp]
+	movaps	xmm10,XMMWORD[64+rsp]
+	movaps	xmm11,XMMWORD[80+rsp]
+	movaps	xmm12,XMMWORD[96+rsp]
+	movaps	xmm13,XMMWORD[112+rsp]
+	movaps	xmm14,XMMWORD[128+rsp]
+	movaps	xmm15,XMMWORD[144+rsp]
+	lea	rsp,[168+rsp]
+$L$SEH_end_ecp_nistz256_select_w5:
+	DB	0F3h,0C3h		;repret
+
+
+
+
+global	ecp_nistz256_select_w7
+
+ALIGN	32
+ecp_nistz256_select_w7:
+	lea	rax,[((-136))+rsp]
+$L$SEH_begin_ecp_nistz256_select_w7:
+DB	0x48,0x8d,0x60,0xe0
+DB	0x0f,0x29,0x70,0xe0
+DB	0x0f,0x29,0x78,0xf0
+DB	0x44,0x0f,0x29,0x00
+DB	0x44,0x0f,0x29,0x48,0x10
+DB	0x44,0x0f,0x29,0x50,0x20
+DB	0x44,0x0f,0x29,0x58,0x30
+DB	0x44,0x0f,0x29,0x60,0x40
+DB	0x44,0x0f,0x29,0x68,0x50
+DB	0x44,0x0f,0x29,0x70,0x60
+DB	0x44,0x0f,0x29,0x78,0x70
+	movdqa	xmm8,XMMWORD[$L$One]
+	movd	xmm1,r8d
+
+	pxor	xmm2,xmm2
+	pxor	xmm3,xmm3
+	pxor	xmm4,xmm4
+	pxor	xmm5,xmm5
+
+	movdqa	xmm0,xmm8
+	pshufd	xmm1,xmm1,0
+	mov	rax,64
+
+$L$select_loop_sse_w7:
+	movdqa	xmm15,xmm8
+	paddd	xmm8,xmm0
+	movdqa	xmm9,XMMWORD[rdx]
+	movdqa	xmm10,XMMWORD[16+rdx]
+	pcmpeqd	xmm15,xmm1
+	movdqa	xmm11,XMMWORD[32+rdx]
+	movdqa	xmm12,XMMWORD[48+rdx]
+	lea	rdx,[64+rdx]
+
+	pand	xmm9,xmm15
+	pand	xmm10,xmm15
+	por	xmm2,xmm9
+	pand	xmm11,xmm15
+	por	xmm3,xmm10
+	pand	xmm12,xmm15
+	por	xmm4,xmm11
+	prefetcht0	[255+rdx]
+	por	xmm5,xmm12
+
+	dec	rax
+	jnz	NEAR $L$select_loop_sse_w7
+
+	movdqu	XMMWORD[rcx],xmm2
+	movdqu	XMMWORD[16+rcx],xmm3
+	movdqu	XMMWORD[32+rcx],xmm4
+	movdqu	XMMWORD[48+rcx],xmm5
+	movaps	xmm6,XMMWORD[rsp]
+	movaps	xmm7,XMMWORD[16+rsp]
+	movaps	xmm8,XMMWORD[32+rsp]
+	movaps	xmm9,XMMWORD[48+rsp]
+	movaps	xmm10,XMMWORD[64+rsp]
+	movaps	xmm11,XMMWORD[80+rsp]
+	movaps	xmm12,XMMWORD[96+rsp]
+	movaps	xmm13,XMMWORD[112+rsp]
+	movaps	xmm14,XMMWORD[128+rsp]
+	movaps	xmm15,XMMWORD[144+rsp]
+	lea	rsp,[168+rsp]
+$L$SEH_end_ecp_nistz256_select_w7:
+	DB	0F3h,0C3h		;repret
+
+global	ecp_nistz256_avx2_select_w7
+
+ALIGN	32
+ecp_nistz256_avx2_select_w7:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_avx2_select_w7:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+DB	0x0f,0x0b
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_avx2_select_w7:
+
+ALIGN	32
+__ecp_nistz256_add_toq:
+	add	r12,QWORD[rbx]
+	adc	r13,QWORD[8+rbx]
+	mov	rax,r12
+	adc	r8,QWORD[16+rbx]
+	adc	r9,QWORD[24+rbx]
+	mov	rbp,r13
+	sbb	r11,r11
+
+	sub	r12,-1
+	mov	rcx,r8
+	sbb	r13,r14
+	sbb	r8,0
+	mov	r10,r9
+	sbb	r9,r15
+	test	r11,r11
+
+	cmovz	r12,rax
+	cmovz	r13,rbp
+	mov	QWORD[rdi],r12
+	cmovz	r8,rcx
+	mov	QWORD[8+rdi],r13
+	cmovz	r9,r10
+	mov	QWORD[16+rdi],r8
+	mov	QWORD[24+rdi],r9
+
+	DB	0F3h,0C3h		;repret
+
+
+
+ALIGN	32
+__ecp_nistz256_sub_fromq:
+	sub	r12,QWORD[rbx]
+	sbb	r13,QWORD[8+rbx]
+	mov	rax,r12
+	sbb	r8,QWORD[16+rbx]
+	sbb	r9,QWORD[24+rbx]
+	mov	rbp,r13
+	sbb	r11,r11
+
+	add	r12,-1
+	mov	rcx,r8
+	adc	r13,r14
+	adc	r8,0
+	mov	r10,r9
+	adc	r9,r15
+	test	r11,r11
+
+	cmovz	r12,rax
+	cmovz	r13,rbp
+	mov	QWORD[rdi],r12
+	cmovz	r8,rcx
+	mov	QWORD[8+rdi],r13
+	cmovz	r9,r10
+	mov	QWORD[16+rdi],r8
+	mov	QWORD[24+rdi],r9
+
+	DB	0F3h,0C3h		;repret
+
+
+
+ALIGN	32
+__ecp_nistz256_subq:
+	sub	rax,r12
+	sbb	rbp,r13
+	mov	r12,rax
+	sbb	rcx,r8
+	sbb	r10,r9
+	mov	r13,rbp
+	sbb	r11,r11
+
+	add	rax,-1
+	mov	r8,rcx
+	adc	rbp,r14
+	adc	rcx,0
+	mov	r9,r10
+	adc	r10,r15
+	test	r11,r11
+
+	cmovnz	r12,rax
+	cmovnz	r13,rbp
+	cmovnz	r8,rcx
+	cmovnz	r9,r10
+
+	DB	0F3h,0C3h		;repret
+
+
+
+ALIGN	32
+__ecp_nistz256_mul_by_2q:
+	add	r12,r12
+	adc	r13,r13
+	mov	rax,r12
+	adc	r8,r8
+	adc	r9,r9
+	mov	rbp,r13
+	sbb	r11,r11
+
+	sub	r12,-1
+	mov	rcx,r8
+	sbb	r13,r14
+	sbb	r8,0
+	mov	r10,r9
+	sbb	r9,r15
+	test	r11,r11
+
+	cmovz	r12,rax
+	cmovz	r13,rbp
+	mov	QWORD[rdi],r12
+	cmovz	r8,rcx
+	mov	QWORD[8+rdi],r13
+	cmovz	r9,r10
+	mov	QWORD[16+rdi],r8
+	mov	QWORD[24+rdi],r9
+
+	DB	0F3h,0C3h		;repret
+
+global	ecp_nistz256_point_double
+
+ALIGN	32
+ecp_nistz256_point_double:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_point_double:
+	mov	rdi,rcx
+	mov	rsi,rdx
+
+
+	push	rbp
+	push	rbx
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	sub	rsp,32*5+8
+
+$L$point_double_shortcutq:
+	movdqu	xmm0,XMMWORD[rsi]
+	mov	rbx,rsi
+	movdqu	xmm1,XMMWORD[16+rsi]
+	mov	r12,QWORD[((32+0))+rsi]
+	mov	r13,QWORD[((32+8))+rsi]
+	mov	r8,QWORD[((32+16))+rsi]
+	mov	r9,QWORD[((32+24))+rsi]
+	mov	r14,QWORD[(($L$poly+8))]
+	mov	r15,QWORD[(($L$poly+24))]
+	movdqa	XMMWORD[96+rsp],xmm0
+	movdqa	XMMWORD[(96+16)+rsp],xmm1
+	lea	r10,[32+rdi]
+	lea	r11,[64+rdi]
+DB	102,72,15,110,199
+DB	102,73,15,110,202
+DB	102,73,15,110,211
+
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_mul_by_2q
+
+	mov	rax,QWORD[((64+0))+rsi]
+	mov	r14,QWORD[((64+8))+rsi]
+	mov	r15,QWORD[((64+16))+rsi]
+	mov	r8,QWORD[((64+24))+rsi]
+	lea	rsi,[((64-0))+rsi]
+	lea	rdi,[64+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	mov	rax,QWORD[((0+0))+rsp]
+	mov	r14,QWORD[((8+0))+rsp]
+	lea	rsi,[((0+0))+rsp]
+	mov	r15,QWORD[((16+0))+rsp]
+	mov	r8,QWORD[((24+0))+rsp]
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	mov	rax,QWORD[32+rbx]
+	mov	r9,QWORD[((64+0))+rbx]
+	mov	r10,QWORD[((64+8))+rbx]
+	mov	r11,QWORD[((64+16))+rbx]
+	mov	r12,QWORD[((64+24))+rbx]
+	lea	rsi,[((64-0))+rbx]
+	lea	rbx,[32+rbx]
+DB	102,72,15,126,215
+	call	__ecp_nistz256_mul_montq
+	call	__ecp_nistz256_mul_by_2q
+
+	mov	r12,QWORD[((96+0))+rsp]
+	mov	r13,QWORD[((96+8))+rsp]
+	lea	rbx,[64+rsp]
+	mov	r8,QWORD[((96+16))+rsp]
+	mov	r9,QWORD[((96+24))+rsp]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_add_toq
+
+	mov	r12,QWORD[((96+0))+rsp]
+	mov	r13,QWORD[((96+8))+rsp]
+	lea	rbx,[64+rsp]
+	mov	r8,QWORD[((96+16))+rsp]
+	mov	r9,QWORD[((96+24))+rsp]
+	lea	rdi,[64+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+	mov	rax,QWORD[((0+0))+rsp]
+	mov	r14,QWORD[((8+0))+rsp]
+	lea	rsi,[((0+0))+rsp]
+	mov	r15,QWORD[((16+0))+rsp]
+	mov	r8,QWORD[((24+0))+rsp]
+DB	102,72,15,126,207
+	call	__ecp_nistz256_sqr_montq
+	xor	r9,r9
+	mov	rax,r12
+	add	r12,-1
+	mov	r10,r13
+	adc	r13,rsi
+	mov	rcx,r14
+	adc	r14,0
+	mov	r8,r15
+	adc	r15,rbp
+	adc	r9,0
+	xor	rsi,rsi
+	test	rax,1
+
+	cmovz	r12,rax
+	cmovz	r13,r10
+	cmovz	r14,rcx
+	cmovz	r15,r8
+	cmovz	r9,rsi
+
+	mov	rax,r13
+	shr	r12,1
+	shl	rax,63
+	mov	r10,r14
+	shr	r13,1
+	or	r12,rax
+	shl	r10,63
+	mov	rcx,r15
+	shr	r14,1
+	or	r13,r10
+	shl	rcx,63
+	mov	QWORD[rdi],r12
+	shr	r15,1
+	mov	QWORD[8+rdi],r13
+	shl	r9,63
+	or	r14,rcx
+	or	r15,r9
+	mov	QWORD[16+rdi],r14
+	mov	QWORD[24+rdi],r15
+	mov	rax,QWORD[64+rsp]
+	lea	rbx,[64+rsp]
+	mov	r9,QWORD[((0+32))+rsp]
+	mov	r10,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r11,QWORD[((16+32))+rsp]
+	mov	r12,QWORD[((24+32))+rsp]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rdi,[128+rsp]
+	call	__ecp_nistz256_mul_by_2q
+
+	lea	rbx,[32+rsp]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_add_toq
+
+	mov	rax,QWORD[96+rsp]
+	lea	rbx,[96+rsp]
+	mov	r9,QWORD[((0+0))+rsp]
+	mov	r10,QWORD[((8+0))+rsp]
+	lea	rsi,[((0+0))+rsp]
+	mov	r11,QWORD[((16+0))+rsp]
+	mov	r12,QWORD[((24+0))+rsp]
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rdi,[128+rsp]
+	call	__ecp_nistz256_mul_by_2q
+
+	mov	rax,QWORD[((0+32))+rsp]
+	mov	r14,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r15,QWORD[((16+32))+rsp]
+	mov	r8,QWORD[((24+32))+rsp]
+DB	102,72,15,126,199
+	call	__ecp_nistz256_sqr_montq
+
+	lea	rbx,[128+rsp]
+	mov	r8,r14
+	mov	r9,r15
+	mov	r14,rsi
+	mov	r15,rbp
+	call	__ecp_nistz256_sub_fromq
+
+	mov	rax,QWORD[((0+0))+rsp]
+	mov	rbp,QWORD[((0+8))+rsp]
+	mov	rcx,QWORD[((0+16))+rsp]
+	mov	r10,QWORD[((0+24))+rsp]
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_subq
+
+	mov	rax,QWORD[32+rsp]
+	lea	rbx,[32+rsp]
+	mov	r14,r12
+	xor	ecx,ecx
+	mov	QWORD[((0+0))+rsp],r12
+	mov	r10,r13
+	mov	QWORD[((0+8))+rsp],r13
+	cmovz	r11,r8
+	mov	QWORD[((0+16))+rsp],r8
+	lea	rsi,[((0-0))+rsp]
+	cmovz	r12,r9
+	mov	QWORD[((0+24))+rsp],r9
+	mov	r9,r14
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_mul_montq
+
+DB	102,72,15,126,203
+DB	102,72,15,126,207
+	call	__ecp_nistz256_sub_fromq
+
+	add	rsp,32*5+8
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbx
+	pop	rbp
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_point_double:
+global	ecp_nistz256_point_add
+
+ALIGN	32
+ecp_nistz256_point_add:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_point_add:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+	push	rbp
+	push	rbx
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	sub	rsp,32*18+8
+
+	movdqu	xmm0,XMMWORD[rsi]
+	movdqu	xmm1,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm3,XMMWORD[48+rsi]
+	movdqu	xmm4,XMMWORD[64+rsi]
+	movdqu	xmm5,XMMWORD[80+rsi]
+	mov	rbx,rsi
+	mov	rsi,rdx
+	movdqa	XMMWORD[384+rsp],xmm0
+	movdqa	XMMWORD[(384+16)+rsp],xmm1
+	por	xmm1,xmm0
+	movdqa	XMMWORD[416+rsp],xmm2
+	movdqa	XMMWORD[(416+16)+rsp],xmm3
+	por	xmm3,xmm2
+	movdqa	XMMWORD[448+rsp],xmm4
+	movdqa	XMMWORD[(448+16)+rsp],xmm5
+	por	xmm3,xmm1
+
+	movdqu	xmm0,XMMWORD[rsi]
+	pshufd	xmm5,xmm3,0xb1
+	movdqu	xmm1,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	por	xmm5,xmm3
+	movdqu	xmm3,XMMWORD[48+rsi]
+	mov	rax,QWORD[((64+0))+rsi]
+	mov	r14,QWORD[((64+8))+rsi]
+	mov	r15,QWORD[((64+16))+rsi]
+	mov	r8,QWORD[((64+24))+rsi]
+	movdqa	XMMWORD[480+rsp],xmm0
+	pshufd	xmm4,xmm5,0x1e
+	movdqa	XMMWORD[(480+16)+rsp],xmm1
+	por	xmm1,xmm0
+DB	102,72,15,110,199
+	movdqa	XMMWORD[512+rsp],xmm2
+	movdqa	XMMWORD[(512+16)+rsp],xmm3
+	por	xmm3,xmm2
+	por	xmm5,xmm4
+	pxor	xmm4,xmm4
+	por	xmm3,xmm1
+
+	lea	rsi,[((64-0))+rsi]
+	mov	QWORD[((544+0))+rsp],rax
+	mov	QWORD[((544+8))+rsp],r14
+	mov	QWORD[((544+16))+rsp],r15
+	mov	QWORD[((544+24))+rsp],r8
+	lea	rdi,[96+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	pcmpeqd	xmm5,xmm4
+	pshufd	xmm4,xmm3,0xb1
+	por	xmm4,xmm3
+	pshufd	xmm5,xmm5,0
+	pshufd	xmm3,xmm4,0x1e
+	por	xmm4,xmm3
+	pxor	xmm3,xmm3
+	pcmpeqd	xmm4,xmm3
+	pshufd	xmm4,xmm4,0
+	mov	rax,QWORD[((64+0))+rbx]
+	mov	r14,QWORD[((64+8))+rbx]
+	mov	r15,QWORD[((64+16))+rbx]
+	mov	r8,QWORD[((64+24))+rbx]
+DB	102,72,15,110,203
+
+	lea	rsi,[((64-0))+rbx]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	mov	rax,QWORD[544+rsp]
+	lea	rbx,[544+rsp]
+	mov	r9,QWORD[((0+96))+rsp]
+	mov	r10,QWORD[((8+96))+rsp]
+	lea	rsi,[((0+96))+rsp]
+	mov	r11,QWORD[((16+96))+rsp]
+	mov	r12,QWORD[((24+96))+rsp]
+	lea	rdi,[224+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[448+rsp]
+	lea	rbx,[448+rsp]
+	mov	r9,QWORD[((0+32))+rsp]
+	mov	r10,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r11,QWORD[((16+32))+rsp]
+	mov	r12,QWORD[((24+32))+rsp]
+	lea	rdi,[256+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[416+rsp]
+	lea	rbx,[416+rsp]
+	mov	r9,QWORD[((0+224))+rsp]
+	mov	r10,QWORD[((8+224))+rsp]
+	lea	rsi,[((0+224))+rsp]
+	mov	r11,QWORD[((16+224))+rsp]
+	mov	r12,QWORD[((24+224))+rsp]
+	lea	rdi,[224+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[512+rsp]
+	lea	rbx,[512+rsp]
+	mov	r9,QWORD[((0+256))+rsp]
+	mov	r10,QWORD[((8+256))+rsp]
+	lea	rsi,[((0+256))+rsp]
+	mov	r11,QWORD[((16+256))+rsp]
+	mov	r12,QWORD[((24+256))+rsp]
+	lea	rdi,[256+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rbx,[224+rsp]
+	lea	rdi,[64+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+	or	r12,r13
+	movdqa	xmm2,xmm4
+	or	r12,r8
+	or	r12,r9
+	por	xmm2,xmm5
+DB	102,73,15,110,220
+
+	mov	rax,QWORD[384+rsp]
+	lea	rbx,[384+rsp]
+	mov	r9,QWORD[((0+96))+rsp]
+	mov	r10,QWORD[((8+96))+rsp]
+	lea	rsi,[((0+96))+rsp]
+	mov	r11,QWORD[((16+96))+rsp]
+	mov	r12,QWORD[((24+96))+rsp]
+	lea	rdi,[160+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[480+rsp]
+	lea	rbx,[480+rsp]
+	mov	r9,QWORD[((0+32))+rsp]
+	mov	r10,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r11,QWORD[((16+32))+rsp]
+	mov	r12,QWORD[((24+32))+rsp]
+	lea	rdi,[192+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rbx,[160+rsp]
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_sub_fromq
+
+	or	r12,r13
+	or	r12,r8
+	or	r12,r9
+
+DB	0x3e
+	jnz	NEAR $L$add_proceedq
+DB	102,73,15,126,208
+DB	102,73,15,126,217
+	test	r8,r8
+	jnz	NEAR $L$add_proceedq
+	test	r9,r9
+	jz	NEAR $L$add_doubleq
+
+DB	102,72,15,126,199
+	pxor	xmm0,xmm0
+	movdqu	XMMWORD[rdi],xmm0
+	movdqu	XMMWORD[16+rdi],xmm0
+	movdqu	XMMWORD[32+rdi],xmm0
+	movdqu	XMMWORD[48+rdi],xmm0
+	movdqu	XMMWORD[64+rdi],xmm0
+	movdqu	XMMWORD[80+rdi],xmm0
+	jmp	NEAR $L$add_doneq
+
+ALIGN	32
+$L$add_doubleq:
+DB	102,72,15,126,206
+DB	102,72,15,126,199
+	add	rsp,416
+	jmp	NEAR $L$point_double_shortcutq
+
+ALIGN	32
+$L$add_proceedq:
+	mov	rax,QWORD[((0+64))+rsp]
+	mov	r14,QWORD[((8+64))+rsp]
+	lea	rsi,[((0+64))+rsp]
+	mov	r15,QWORD[((16+64))+rsp]
+	mov	r8,QWORD[((24+64))+rsp]
+	lea	rdi,[96+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	mov	rax,QWORD[448+rsp]
+	lea	rbx,[448+rsp]
+	mov	r9,QWORD[((0+0))+rsp]
+	mov	r10,QWORD[((8+0))+rsp]
+	lea	rsi,[((0+0))+rsp]
+	mov	r11,QWORD[((16+0))+rsp]
+	mov	r12,QWORD[((24+0))+rsp]
+	lea	rdi,[352+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[((0+0))+rsp]
+	mov	r14,QWORD[((8+0))+rsp]
+	lea	rsi,[((0+0))+rsp]
+	mov	r15,QWORD[((16+0))+rsp]
+	mov	r8,QWORD[((24+0))+rsp]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	mov	rax,QWORD[544+rsp]
+	lea	rbx,[544+rsp]
+	mov	r9,QWORD[((0+352))+rsp]
+	mov	r10,QWORD[((8+352))+rsp]
+	lea	rsi,[((0+352))+rsp]
+	mov	r11,QWORD[((16+352))+rsp]
+	mov	r12,QWORD[((24+352))+rsp]
+	lea	rdi,[352+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[rsp]
+	lea	rbx,[rsp]
+	mov	r9,QWORD[((0+32))+rsp]
+	mov	r10,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r11,QWORD[((16+32))+rsp]
+	mov	r12,QWORD[((24+32))+rsp]
+	lea	rdi,[128+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[160+rsp]
+	lea	rbx,[160+rsp]
+	mov	r9,QWORD[((0+32))+rsp]
+	mov	r10,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r11,QWORD[((16+32))+rsp]
+	mov	r12,QWORD[((24+32))+rsp]
+	lea	rdi,[192+rsp]
+	call	__ecp_nistz256_mul_montq
+
+
+
+
+	add	r12,r12
+	lea	rsi,[96+rsp]
+	adc	r13,r13
+	mov	rax,r12
+	adc	r8,r8
+	adc	r9,r9
+	mov	rbp,r13
+	sbb	r11,r11
+
+	sub	r12,-1
+	mov	rcx,r8
+	sbb	r13,r14
+	sbb	r8,0
+	mov	r10,r9
+	sbb	r9,r15
+	test	r11,r11
+
+	cmovz	r12,rax
+	mov	rax,QWORD[rsi]
+	cmovz	r13,rbp
+	mov	rbp,QWORD[8+rsi]
+	cmovz	r8,rcx
+	mov	rcx,QWORD[16+rsi]
+	cmovz	r9,r10
+	mov	r10,QWORD[24+rsi]
+
+	call	__ecp_nistz256_subq
+
+	lea	rbx,[128+rsp]
+	lea	rdi,[288+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+	mov	rax,QWORD[((192+0))+rsp]
+	mov	rbp,QWORD[((192+8))+rsp]
+	mov	rcx,QWORD[((192+16))+rsp]
+	mov	r10,QWORD[((192+24))+rsp]
+	lea	rdi,[320+rsp]
+
+	call	__ecp_nistz256_subq
+
+	mov	QWORD[rdi],r12
+	mov	QWORD[8+rdi],r13
+	mov	QWORD[16+rdi],r8
+	mov	QWORD[24+rdi],r9
+	mov	rax,QWORD[128+rsp]
+	lea	rbx,[128+rsp]
+	mov	r9,QWORD[((0+224))+rsp]
+	mov	r10,QWORD[((8+224))+rsp]
+	lea	rsi,[((0+224))+rsp]
+	mov	r11,QWORD[((16+224))+rsp]
+	mov	r12,QWORD[((24+224))+rsp]
+	lea	rdi,[256+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[320+rsp]
+	lea	rbx,[320+rsp]
+	mov	r9,QWORD[((0+64))+rsp]
+	mov	r10,QWORD[((8+64))+rsp]
+	lea	rsi,[((0+64))+rsp]
+	mov	r11,QWORD[((16+64))+rsp]
+	mov	r12,QWORD[((24+64))+rsp]
+	lea	rdi,[320+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rbx,[256+rsp]
+	lea	rdi,[320+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+DB	102,72,15,126,199
+
+	movdqa	xmm0,xmm5
+	movdqa	xmm1,xmm5
+	pandn	xmm0,XMMWORD[352+rsp]
+	movdqa	xmm2,xmm5
+	pandn	xmm1,XMMWORD[((352+16))+rsp]
+	movdqa	xmm3,xmm5
+	pand	xmm2,XMMWORD[544+rsp]
+	pand	xmm3,XMMWORD[((544+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+
+	movdqa	xmm0,xmm4
+	movdqa	xmm1,xmm4
+	pandn	xmm0,xmm2
+	movdqa	xmm2,xmm4
+	pandn	xmm1,xmm3
+	movdqa	xmm3,xmm4
+	pand	xmm2,XMMWORD[448+rsp]
+	pand	xmm3,XMMWORD[((448+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+	movdqu	XMMWORD[64+rdi],xmm2
+	movdqu	XMMWORD[80+rdi],xmm3
+
+	movdqa	xmm0,xmm5
+	movdqa	xmm1,xmm5
+	pandn	xmm0,XMMWORD[288+rsp]
+	movdqa	xmm2,xmm5
+	pandn	xmm1,XMMWORD[((288+16))+rsp]
+	movdqa	xmm3,xmm5
+	pand	xmm2,XMMWORD[480+rsp]
+	pand	xmm3,XMMWORD[((480+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+
+	movdqa	xmm0,xmm4
+	movdqa	xmm1,xmm4
+	pandn	xmm0,xmm2
+	movdqa	xmm2,xmm4
+	pandn	xmm1,xmm3
+	movdqa	xmm3,xmm4
+	pand	xmm2,XMMWORD[384+rsp]
+	pand	xmm3,XMMWORD[((384+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+	movdqu	XMMWORD[rdi],xmm2
+	movdqu	XMMWORD[16+rdi],xmm3
+
+	movdqa	xmm0,xmm5
+	movdqa	xmm1,xmm5
+	pandn	xmm0,XMMWORD[320+rsp]
+	movdqa	xmm2,xmm5
+	pandn	xmm1,XMMWORD[((320+16))+rsp]
+	movdqa	xmm3,xmm5
+	pand	xmm2,XMMWORD[512+rsp]
+	pand	xmm3,XMMWORD[((512+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+
+	movdqa	xmm0,xmm4
+	movdqa	xmm1,xmm4
+	pandn	xmm0,xmm2
+	movdqa	xmm2,xmm4
+	pandn	xmm1,xmm3
+	movdqa	xmm3,xmm4
+	pand	xmm2,XMMWORD[416+rsp]
+	pand	xmm3,XMMWORD[((416+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm3
+
+$L$add_doneq:
+	add	rsp,32*18+8
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbx
+	pop	rbp
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_point_add:
+global	ecp_nistz256_point_add_affine
+
+ALIGN	32
+ecp_nistz256_point_add_affine:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_ecp_nistz256_point_add_affine:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+	push	rbp
+	push	rbx
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	sub	rsp,32*15+8
+
+	movdqu	xmm0,XMMWORD[rsi]
+	mov	rbx,rdx
+	movdqu	xmm1,XMMWORD[16+rsi]
+	movdqu	xmm2,XMMWORD[32+rsi]
+	movdqu	xmm3,XMMWORD[48+rsi]
+	movdqu	xmm4,XMMWORD[64+rsi]
+	movdqu	xmm5,XMMWORD[80+rsi]
+	mov	rax,QWORD[((64+0))+rsi]
+	mov	r14,QWORD[((64+8))+rsi]
+	mov	r15,QWORD[((64+16))+rsi]
+	mov	r8,QWORD[((64+24))+rsi]
+	movdqa	XMMWORD[320+rsp],xmm0
+	movdqa	XMMWORD[(320+16)+rsp],xmm1
+	por	xmm1,xmm0
+	movdqa	XMMWORD[352+rsp],xmm2
+	movdqa	XMMWORD[(352+16)+rsp],xmm3
+	por	xmm3,xmm2
+	movdqa	XMMWORD[384+rsp],xmm4
+	movdqa	XMMWORD[(384+16)+rsp],xmm5
+	por	xmm3,xmm1
+
+	movdqu	xmm0,XMMWORD[rbx]
+	pshufd	xmm5,xmm3,0xb1
+	movdqu	xmm1,XMMWORD[16+rbx]
+	movdqu	xmm2,XMMWORD[32+rbx]
+	por	xmm5,xmm3
+	movdqu	xmm3,XMMWORD[48+rbx]
+	movdqa	XMMWORD[416+rsp],xmm0
+	pshufd	xmm4,xmm5,0x1e
+	movdqa	XMMWORD[(416+16)+rsp],xmm1
+	por	xmm1,xmm0
+DB	102,72,15,110,199
+	movdqa	XMMWORD[448+rsp],xmm2
+	movdqa	XMMWORD[(448+16)+rsp],xmm3
+	por	xmm3,xmm2
+	por	xmm5,xmm4
+	pxor	xmm4,xmm4
+	por	xmm3,xmm1
+
+	lea	rsi,[((64-0))+rsi]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	pcmpeqd	xmm5,xmm4
+	pshufd	xmm4,xmm3,0xb1
+	mov	rax,QWORD[rbx]
+
+	mov	r9,r12
+	por	xmm4,xmm3
+	pshufd	xmm5,xmm5,0
+	pshufd	xmm3,xmm4,0x1e
+	mov	r10,r13
+	por	xmm4,xmm3
+	pxor	xmm3,xmm3
+	mov	r11,r14
+	pcmpeqd	xmm4,xmm3
+	pshufd	xmm4,xmm4,0
+
+	lea	rsi,[((32-0))+rsp]
+	mov	r12,r15
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rbx,[320+rsp]
+	lea	rdi,[64+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+	mov	rax,QWORD[384+rsp]
+	lea	rbx,[384+rsp]
+	mov	r9,QWORD[((0+32))+rsp]
+	mov	r10,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r11,QWORD[((16+32))+rsp]
+	mov	r12,QWORD[((24+32))+rsp]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[384+rsp]
+	lea	rbx,[384+rsp]
+	mov	r9,QWORD[((0+64))+rsp]
+	mov	r10,QWORD[((8+64))+rsp]
+	lea	rsi,[((0+64))+rsp]
+	mov	r11,QWORD[((16+64))+rsp]
+	mov	r12,QWORD[((24+64))+rsp]
+	lea	rdi,[288+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[448+rsp]
+	lea	rbx,[448+rsp]
+	mov	r9,QWORD[((0+32))+rsp]
+	mov	r10,QWORD[((8+32))+rsp]
+	lea	rsi,[((0+32))+rsp]
+	mov	r11,QWORD[((16+32))+rsp]
+	mov	r12,QWORD[((24+32))+rsp]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rbx,[352+rsp]
+	lea	rdi,[96+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+	mov	rax,QWORD[((0+64))+rsp]
+	mov	r14,QWORD[((8+64))+rsp]
+	lea	rsi,[((0+64))+rsp]
+	mov	r15,QWORD[((16+64))+rsp]
+	mov	r8,QWORD[((24+64))+rsp]
+	lea	rdi,[128+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	mov	rax,QWORD[((0+96))+rsp]
+	mov	r14,QWORD[((8+96))+rsp]
+	lea	rsi,[((0+96))+rsp]
+	mov	r15,QWORD[((16+96))+rsp]
+	mov	r8,QWORD[((24+96))+rsp]
+	lea	rdi,[192+rsp]
+	call	__ecp_nistz256_sqr_montq
+
+	mov	rax,QWORD[128+rsp]
+	lea	rbx,[128+rsp]
+	mov	r9,QWORD[((0+64))+rsp]
+	mov	r10,QWORD[((8+64))+rsp]
+	lea	rsi,[((0+64))+rsp]
+	mov	r11,QWORD[((16+64))+rsp]
+	mov	r12,QWORD[((24+64))+rsp]
+	lea	rdi,[160+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[320+rsp]
+	lea	rbx,[320+rsp]
+	mov	r9,QWORD[((0+128))+rsp]
+	mov	r10,QWORD[((8+128))+rsp]
+	lea	rsi,[((0+128))+rsp]
+	mov	r11,QWORD[((16+128))+rsp]
+	mov	r12,QWORD[((24+128))+rsp]
+	lea	rdi,[rsp]
+	call	__ecp_nistz256_mul_montq
+
+
+
+
+	add	r12,r12
+	lea	rsi,[192+rsp]
+	adc	r13,r13
+	mov	rax,r12
+	adc	r8,r8
+	adc	r9,r9
+	mov	rbp,r13
+	sbb	r11,r11
+
+	sub	r12,-1
+	mov	rcx,r8
+	sbb	r13,r14
+	sbb	r8,0
+	mov	r10,r9
+	sbb	r9,r15
+	test	r11,r11
+
+	cmovz	r12,rax
+	mov	rax,QWORD[rsi]
+	cmovz	r13,rbp
+	mov	rbp,QWORD[8+rsi]
+	cmovz	r8,rcx
+	mov	rcx,QWORD[16+rsi]
+	cmovz	r9,r10
+	mov	r10,QWORD[24+rsi]
+
+	call	__ecp_nistz256_subq
+
+	lea	rbx,[160+rsp]
+	lea	rdi,[224+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+	mov	rax,QWORD[((0+0))+rsp]
+	mov	rbp,QWORD[((0+8))+rsp]
+	mov	rcx,QWORD[((0+16))+rsp]
+	mov	r10,QWORD[((0+24))+rsp]
+	lea	rdi,[64+rsp]
+
+	call	__ecp_nistz256_subq
+
+	mov	QWORD[rdi],r12
+	mov	QWORD[8+rdi],r13
+	mov	QWORD[16+rdi],r8
+	mov	QWORD[24+rdi],r9
+	mov	rax,QWORD[352+rsp]
+	lea	rbx,[352+rsp]
+	mov	r9,QWORD[((0+160))+rsp]
+	mov	r10,QWORD[((8+160))+rsp]
+	lea	rsi,[((0+160))+rsp]
+	mov	r11,QWORD[((16+160))+rsp]
+	mov	r12,QWORD[((24+160))+rsp]
+	lea	rdi,[32+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	mov	rax,QWORD[96+rsp]
+	lea	rbx,[96+rsp]
+	mov	r9,QWORD[((0+64))+rsp]
+	mov	r10,QWORD[((8+64))+rsp]
+	lea	rsi,[((0+64))+rsp]
+	mov	r11,QWORD[((16+64))+rsp]
+	mov	r12,QWORD[((24+64))+rsp]
+	lea	rdi,[64+rsp]
+	call	__ecp_nistz256_mul_montq
+
+	lea	rbx,[32+rsp]
+	lea	rdi,[256+rsp]
+	call	__ecp_nistz256_sub_fromq
+
+DB	102,72,15,126,199
+
+	movdqa	xmm0,xmm5
+	movdqa	xmm1,xmm5
+	pandn	xmm0,XMMWORD[288+rsp]
+	movdqa	xmm2,xmm5
+	pandn	xmm1,XMMWORD[((288+16))+rsp]
+	movdqa	xmm3,xmm5
+	pand	xmm2,XMMWORD[$L$ONE_mont]
+	pand	xmm3,XMMWORD[(($L$ONE_mont+16))]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+
+	movdqa	xmm0,xmm4
+	movdqa	xmm1,xmm4
+	pandn	xmm0,xmm2
+	movdqa	xmm2,xmm4
+	pandn	xmm1,xmm3
+	movdqa	xmm3,xmm4
+	pand	xmm2,XMMWORD[384+rsp]
+	pand	xmm3,XMMWORD[((384+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+	movdqu	XMMWORD[64+rdi],xmm2
+	movdqu	XMMWORD[80+rdi],xmm3
+
+	movdqa	xmm0,xmm5
+	movdqa	xmm1,xmm5
+	pandn	xmm0,XMMWORD[224+rsp]
+	movdqa	xmm2,xmm5
+	pandn	xmm1,XMMWORD[((224+16))+rsp]
+	movdqa	xmm3,xmm5
+	pand	xmm2,XMMWORD[416+rsp]
+	pand	xmm3,XMMWORD[((416+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+
+	movdqa	xmm0,xmm4
+	movdqa	xmm1,xmm4
+	pandn	xmm0,xmm2
+	movdqa	xmm2,xmm4
+	pandn	xmm1,xmm3
+	movdqa	xmm3,xmm4
+	pand	xmm2,XMMWORD[320+rsp]
+	pand	xmm3,XMMWORD[((320+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+	movdqu	XMMWORD[rdi],xmm2
+	movdqu	XMMWORD[16+rdi],xmm3
+
+	movdqa	xmm0,xmm5
+	movdqa	xmm1,xmm5
+	pandn	xmm0,XMMWORD[256+rsp]
+	movdqa	xmm2,xmm5
+	pandn	xmm1,XMMWORD[((256+16))+rsp]
+	movdqa	xmm3,xmm5
+	pand	xmm2,XMMWORD[448+rsp]
+	pand	xmm3,XMMWORD[((448+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+
+	movdqa	xmm0,xmm4
+	movdqa	xmm1,xmm4
+	pandn	xmm0,xmm2
+	movdqa	xmm2,xmm4
+	pandn	xmm1,xmm3
+	movdqa	xmm3,xmm4
+	pand	xmm2,XMMWORD[352+rsp]
+	pand	xmm3,XMMWORD[((352+16))+rsp]
+	por	xmm2,xmm0
+	por	xmm3,xmm1
+	movdqu	XMMWORD[32+rdi],xmm2
+	movdqu	XMMWORD[48+rdi],xmm3
+
+	add	rsp,32*15+8
+	pop	r15
+	pop	r14
+	pop	r13
+	pop	r12
+	pop	rbx
+	pop	rbp
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_ecp_nistz256_point_add_affine:
diff --git a/third_party/boringssl/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm
deleted file mode 100644
index f1ea965..0000000
--- a/third_party/boringssl/win-x86_64/crypto/rc4/rc4-md5-x86_64.asm
+++ /dev/null
@@ -1,1372 +0,0 @@
-default	rel
-%define XMMWORD
-%define YMMWORD
-%define ZMMWORD
-section	.text code align=64
-
-ALIGN	16
-
-global	rc4_md5_enc
-
-rc4_md5_enc:
-	mov	QWORD[8+rsp],rdi	;WIN64 prologue
-	mov	QWORD[16+rsp],rsi
-	mov	rax,rsp
-$L$SEH_begin_rc4_md5_enc:
-	mov	rdi,rcx
-	mov	rsi,rdx
-	mov	rdx,r8
-	mov	rcx,r9
-	mov	r8,QWORD[40+rsp]
-	mov	r9,QWORD[48+rsp]
-
-
-	cmp	r9,0
-	je	NEAR $L$abort
-	push	rbx
-	push	rbp
-	push	r12
-	push	r13
-	push	r14
-	push	r15
-	sub	rsp,40
-$L$body:
-	mov	r11,rcx
-	mov	r12,r9
-	mov	r13,rsi
-	mov	r14,rdx
-	mov	r15,r8
-	xor	rbp,rbp
-	xor	rcx,rcx
-
-	lea	rdi,[8+rdi]
-	mov	bpl,BYTE[((-8))+rdi]
-	mov	cl,BYTE[((-4))+rdi]
-
-	inc	bpl
-	sub	r14,r13
-	mov	eax,DWORD[rbp*4+rdi]
-	add	cl,al
-	lea	rsi,[rbp*4+rdi]
-	shl	r12,6
-	add	r12,r15
-	mov	QWORD[16+rsp],r12
-
-	mov	QWORD[24+rsp],r11
-	mov	r8d,DWORD[r11]
-	mov	r9d,DWORD[4+r11]
-	mov	r10d,DWORD[8+r11]
-	mov	r11d,DWORD[12+r11]
-	jmp	NEAR $L$oop
-
-ALIGN	16
-$L$oop:
-	mov	DWORD[rsp],r8d
-	mov	DWORD[4+rsp],r9d
-	mov	DWORD[8+rsp],r10d
-	mov	r12d,r11d
-	mov	DWORD[12+rsp],r11d
-	pxor	xmm0,xmm0
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r8d,DWORD[r15]
-	add	al,dl
-	mov	ebx,DWORD[4+rsi]
-	add	r8d,3614090360
-	xor	r12d,r11d
-	movzx	eax,al
-	mov	DWORD[rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,7
-	mov	r12d,r10d
-	movd	xmm0,DWORD[rax*4+rdi]
-
-	add	r8d,r9d
-	pxor	xmm1,xmm1
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r11d,DWORD[4+r15]
-	add	bl,dl
-	mov	eax,DWORD[8+rsi]
-	add	r11d,3905402710
-	xor	r12d,r10d
-	movzx	ebx,bl
-	mov	DWORD[4+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,12
-	mov	r12d,r9d
-	movd	xmm1,DWORD[rbx*4+rdi]
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r10d,DWORD[8+r15]
-	add	al,dl
-	mov	ebx,DWORD[12+rsi]
-	add	r10d,606105819
-	xor	r12d,r9d
-	movzx	eax,al
-	mov	DWORD[8+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,17
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],1
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r9d,DWORD[12+r15]
-	add	bl,dl
-	mov	eax,DWORD[16+rsi]
-	add	r9d,3250441966
-	xor	r12d,r8d
-	movzx	ebx,bl
-	mov	DWORD[12+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,22
-	mov	r12d,r11d
-	pinsrw	xmm1,WORD[rbx*4+rdi],1
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r8d,DWORD[16+r15]
-	add	al,dl
-	mov	ebx,DWORD[20+rsi]
-	add	r8d,4118548399
-	xor	r12d,r11d
-	movzx	eax,al
-	mov	DWORD[16+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,7
-	mov	r12d,r10d
-	pinsrw	xmm0,WORD[rax*4+rdi],2
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r11d,DWORD[20+r15]
-	add	bl,dl
-	mov	eax,DWORD[24+rsi]
-	add	r11d,1200080426
-	xor	r12d,r10d
-	movzx	ebx,bl
-	mov	DWORD[20+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,12
-	mov	r12d,r9d
-	pinsrw	xmm1,WORD[rbx*4+rdi],2
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r10d,DWORD[24+r15]
-	add	al,dl
-	mov	ebx,DWORD[28+rsi]
-	add	r10d,2821735955
-	xor	r12d,r9d
-	movzx	eax,al
-	mov	DWORD[24+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,17
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],3
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r9d,DWORD[28+r15]
-	add	bl,dl
-	mov	eax,DWORD[32+rsi]
-	add	r9d,4249261313
-	xor	r12d,r8d
-	movzx	ebx,bl
-	mov	DWORD[28+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,22
-	mov	r12d,r11d
-	pinsrw	xmm1,WORD[rbx*4+rdi],3
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r8d,DWORD[32+r15]
-	add	al,dl
-	mov	ebx,DWORD[36+rsi]
-	add	r8d,1770035416
-	xor	r12d,r11d
-	movzx	eax,al
-	mov	DWORD[32+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,7
-	mov	r12d,r10d
-	pinsrw	xmm0,WORD[rax*4+rdi],4
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r11d,DWORD[36+r15]
-	add	bl,dl
-	mov	eax,DWORD[40+rsi]
-	add	r11d,2336552879
-	xor	r12d,r10d
-	movzx	ebx,bl
-	mov	DWORD[36+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,12
-	mov	r12d,r9d
-	pinsrw	xmm1,WORD[rbx*4+rdi],4
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r10d,DWORD[40+r15]
-	add	al,dl
-	mov	ebx,DWORD[44+rsi]
-	add	r10d,4294925233
-	xor	r12d,r9d
-	movzx	eax,al
-	mov	DWORD[40+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,17
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],5
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r9d,DWORD[44+r15]
-	add	bl,dl
-	mov	eax,DWORD[48+rsi]
-	add	r9d,2304563134
-	xor	r12d,r8d
-	movzx	ebx,bl
-	mov	DWORD[44+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,22
-	mov	r12d,r11d
-	pinsrw	xmm1,WORD[rbx*4+rdi],5
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r8d,DWORD[48+r15]
-	add	al,dl
-	mov	ebx,DWORD[52+rsi]
-	add	r8d,1804603682
-	xor	r12d,r11d
-	movzx	eax,al
-	mov	DWORD[48+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,7
-	mov	r12d,r10d
-	pinsrw	xmm0,WORD[rax*4+rdi],6
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r11d,DWORD[52+r15]
-	add	bl,dl
-	mov	eax,DWORD[56+rsi]
-	add	r11d,4254626195
-	xor	r12d,r10d
-	movzx	ebx,bl
-	mov	DWORD[52+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,12
-	mov	r12d,r9d
-	pinsrw	xmm1,WORD[rbx*4+rdi],6
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r10d,DWORD[56+r15]
-	add	al,dl
-	mov	ebx,DWORD[60+rsi]
-	add	r10d,2792965006
-	xor	r12d,r9d
-	movzx	eax,al
-	mov	DWORD[56+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,17
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],7
-
-	add	r10d,r11d
-	movdqu	xmm2,XMMWORD[r13]
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r9d,DWORD[60+r15]
-	add	bl,dl
-	mov	eax,DWORD[64+rsi]
-	add	r9d,1236535329
-	xor	r12d,r8d
-	movzx	ebx,bl
-	mov	DWORD[60+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,22
-	mov	r12d,r10d
-	pinsrw	xmm1,WORD[rbx*4+rdi],7
-
-	add	r9d,r10d
-	psllq	xmm1,8
-	pxor	xmm2,xmm0
-	pxor	xmm2,xmm1
-	pxor	xmm0,xmm0
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r8d,DWORD[4+r15]
-	add	al,dl
-	mov	ebx,DWORD[68+rsi]
-	add	r8d,4129170786
-	xor	r12d,r10d
-	movzx	eax,al
-	mov	DWORD[64+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,5
-	mov	r12d,r9d
-	movd	xmm0,DWORD[rax*4+rdi]
-
-	add	r8d,r9d
-	pxor	xmm1,xmm1
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r11d,DWORD[24+r15]
-	add	bl,dl
-	mov	eax,DWORD[72+rsi]
-	add	r11d,3225465664
-	xor	r12d,r9d
-	movzx	ebx,bl
-	mov	DWORD[68+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,9
-	mov	r12d,r8d
-	movd	xmm1,DWORD[rbx*4+rdi]
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r10d,DWORD[44+r15]
-	add	al,dl
-	mov	ebx,DWORD[76+rsi]
-	add	r10d,643717713
-	xor	r12d,r8d
-	movzx	eax,al
-	mov	DWORD[72+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,14
-	mov	r12d,r11d
-	pinsrw	xmm0,WORD[rax*4+rdi],1
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r9d,DWORD[r15]
-	add	bl,dl
-	mov	eax,DWORD[80+rsi]
-	add	r9d,3921069994
-	xor	r12d,r11d
-	movzx	ebx,bl
-	mov	DWORD[76+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,20
-	mov	r12d,r10d
-	pinsrw	xmm1,WORD[rbx*4+rdi],1
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r8d,DWORD[20+r15]
-	add	al,dl
-	mov	ebx,DWORD[84+rsi]
-	add	r8d,3593408605
-	xor	r12d,r10d
-	movzx	eax,al
-	mov	DWORD[80+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,5
-	mov	r12d,r9d
-	pinsrw	xmm0,WORD[rax*4+rdi],2
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r11d,DWORD[40+r15]
-	add	bl,dl
-	mov	eax,DWORD[88+rsi]
-	add	r11d,38016083
-	xor	r12d,r9d
-	movzx	ebx,bl
-	mov	DWORD[84+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,9
-	mov	r12d,r8d
-	pinsrw	xmm1,WORD[rbx*4+rdi],2
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r10d,DWORD[60+r15]
-	add	al,dl
-	mov	ebx,DWORD[92+rsi]
-	add	r10d,3634488961
-	xor	r12d,r8d
-	movzx	eax,al
-	mov	DWORD[88+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,14
-	mov	r12d,r11d
-	pinsrw	xmm0,WORD[rax*4+rdi],3
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r9d,DWORD[16+r15]
-	add	bl,dl
-	mov	eax,DWORD[96+rsi]
-	add	r9d,3889429448
-	xor	r12d,r11d
-	movzx	ebx,bl
-	mov	DWORD[92+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,20
-	mov	r12d,r10d
-	pinsrw	xmm1,WORD[rbx*4+rdi],3
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r8d,DWORD[36+r15]
-	add	al,dl
-	mov	ebx,DWORD[100+rsi]
-	add	r8d,568446438
-	xor	r12d,r10d
-	movzx	eax,al
-	mov	DWORD[96+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,5
-	mov	r12d,r9d
-	pinsrw	xmm0,WORD[rax*4+rdi],4
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r11d,DWORD[56+r15]
-	add	bl,dl
-	mov	eax,DWORD[104+rsi]
-	add	r11d,3275163606
-	xor	r12d,r9d
-	movzx	ebx,bl
-	mov	DWORD[100+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,9
-	mov	r12d,r8d
-	pinsrw	xmm1,WORD[rbx*4+rdi],4
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r10d,DWORD[12+r15]
-	add	al,dl
-	mov	ebx,DWORD[108+rsi]
-	add	r10d,4107603335
-	xor	r12d,r8d
-	movzx	eax,al
-	mov	DWORD[104+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,14
-	mov	r12d,r11d
-	pinsrw	xmm0,WORD[rax*4+rdi],5
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r9d,DWORD[32+r15]
-	add	bl,dl
-	mov	eax,DWORD[112+rsi]
-	add	r9d,1163531501
-	xor	r12d,r11d
-	movzx	ebx,bl
-	mov	DWORD[108+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,20
-	mov	r12d,r10d
-	pinsrw	xmm1,WORD[rbx*4+rdi],5
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r11d
-	add	r8d,DWORD[52+r15]
-	add	al,dl
-	mov	ebx,DWORD[116+rsi]
-	add	r8d,2850285829
-	xor	r12d,r10d
-	movzx	eax,al
-	mov	DWORD[112+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,5
-	mov	r12d,r9d
-	pinsrw	xmm0,WORD[rax*4+rdi],6
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r10d
-	add	r11d,DWORD[8+r15]
-	add	bl,dl
-	mov	eax,DWORD[120+rsi]
-	add	r11d,4243563512
-	xor	r12d,r9d
-	movzx	ebx,bl
-	mov	DWORD[116+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,9
-	mov	r12d,r8d
-	pinsrw	xmm1,WORD[rbx*4+rdi],6
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	and	r12d,r9d
-	add	r10d,DWORD[28+r15]
-	add	al,dl
-	mov	ebx,DWORD[124+rsi]
-	add	r10d,1735328473
-	xor	r12d,r8d
-	movzx	eax,al
-	mov	DWORD[120+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,14
-	mov	r12d,r11d
-	pinsrw	xmm0,WORD[rax*4+rdi],7
-
-	add	r10d,r11d
-	movdqu	xmm3,XMMWORD[16+r13]
-	add	bpl,32
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	and	r12d,r8d
-	add	r9d,DWORD[48+r15]
-	add	bl,dl
-	mov	eax,DWORD[rbp*4+rdi]
-	add	r9d,2368359562
-	xor	r12d,r11d
-	movzx	ebx,bl
-	mov	DWORD[124+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,20
-	mov	r12d,r11d
-	pinsrw	xmm1,WORD[rbx*4+rdi],7
-
-	add	r9d,r10d
-	mov	rsi,rcx
-	xor	rcx,rcx
-	mov	cl,sil
-	lea	rsi,[rbp*4+rdi]
-	psllq	xmm1,8
-	pxor	xmm3,xmm0
-	pxor	xmm3,xmm1
-	pxor	xmm0,xmm0
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r9d
-	add	r8d,DWORD[20+r15]
-	add	al,dl
-	mov	ebx,DWORD[4+rsi]
-	add	r8d,4294588738
-	movzx	eax,al
-	add	r8d,r12d
-	mov	DWORD[rsi],edx
-	add	cl,bl
-	rol	r8d,4
-	mov	r12d,r10d
-	movd	xmm0,DWORD[rax*4+rdi]
-
-	add	r8d,r9d
-	pxor	xmm1,xmm1
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r8d
-	add	r11d,DWORD[32+r15]
-	add	bl,dl
-	mov	eax,DWORD[8+rsi]
-	add	r11d,2272392833
-	movzx	ebx,bl
-	add	r11d,r12d
-	mov	DWORD[4+rsi],edx
-	add	cl,al
-	rol	r11d,11
-	mov	r12d,r9d
-	movd	xmm1,DWORD[rbx*4+rdi]
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r11d
-	add	r10d,DWORD[44+r15]
-	add	al,dl
-	mov	ebx,DWORD[12+rsi]
-	add	r10d,1839030562
-	movzx	eax,al
-	add	r10d,r12d
-	mov	DWORD[8+rsi],edx
-	add	cl,bl
-	rol	r10d,16
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],1
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r10d
-	add	r9d,DWORD[56+r15]
-	add	bl,dl
-	mov	eax,DWORD[16+rsi]
-	add	r9d,4259657740
-	movzx	ebx,bl
-	add	r9d,r12d
-	mov	DWORD[12+rsi],edx
-	add	cl,al
-	rol	r9d,23
-	mov	r12d,r11d
-	pinsrw	xmm1,WORD[rbx*4+rdi],1
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r9d
-	add	r8d,DWORD[4+r15]
-	add	al,dl
-	mov	ebx,DWORD[20+rsi]
-	add	r8d,2763975236
-	movzx	eax,al
-	add	r8d,r12d
-	mov	DWORD[16+rsi],edx
-	add	cl,bl
-	rol	r8d,4
-	mov	r12d,r10d
-	pinsrw	xmm0,WORD[rax*4+rdi],2
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r8d
-	add	r11d,DWORD[16+r15]
-	add	bl,dl
-	mov	eax,DWORD[24+rsi]
-	add	r11d,1272893353
-	movzx	ebx,bl
-	add	r11d,r12d
-	mov	DWORD[20+rsi],edx
-	add	cl,al
-	rol	r11d,11
-	mov	r12d,r9d
-	pinsrw	xmm1,WORD[rbx*4+rdi],2
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r11d
-	add	r10d,DWORD[28+r15]
-	add	al,dl
-	mov	ebx,DWORD[28+rsi]
-	add	r10d,4139469664
-	movzx	eax,al
-	add	r10d,r12d
-	mov	DWORD[24+rsi],edx
-	add	cl,bl
-	rol	r10d,16
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],3
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r10d
-	add	r9d,DWORD[40+r15]
-	add	bl,dl
-	mov	eax,DWORD[32+rsi]
-	add	r9d,3200236656
-	movzx	ebx,bl
-	add	r9d,r12d
-	mov	DWORD[28+rsi],edx
-	add	cl,al
-	rol	r9d,23
-	mov	r12d,r11d
-	pinsrw	xmm1,WORD[rbx*4+rdi],3
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r9d
-	add	r8d,DWORD[52+r15]
-	add	al,dl
-	mov	ebx,DWORD[36+rsi]
-	add	r8d,681279174
-	movzx	eax,al
-	add	r8d,r12d
-	mov	DWORD[32+rsi],edx
-	add	cl,bl
-	rol	r8d,4
-	mov	r12d,r10d
-	pinsrw	xmm0,WORD[rax*4+rdi],4
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r8d
-	add	r11d,DWORD[r15]
-	add	bl,dl
-	mov	eax,DWORD[40+rsi]
-	add	r11d,3936430074
-	movzx	ebx,bl
-	add	r11d,r12d
-	mov	DWORD[36+rsi],edx
-	add	cl,al
-	rol	r11d,11
-	mov	r12d,r9d
-	pinsrw	xmm1,WORD[rbx*4+rdi],4
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r11d
-	add	r10d,DWORD[12+r15]
-	add	al,dl
-	mov	ebx,DWORD[44+rsi]
-	add	r10d,3572445317
-	movzx	eax,al
-	add	r10d,r12d
-	mov	DWORD[40+rsi],edx
-	add	cl,bl
-	rol	r10d,16
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],5
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r10d
-	add	r9d,DWORD[24+r15]
-	add	bl,dl
-	mov	eax,DWORD[48+rsi]
-	add	r9d,76029189
-	movzx	ebx,bl
-	add	r9d,r12d
-	mov	DWORD[44+rsi],edx
-	add	cl,al
-	rol	r9d,23
-	mov	r12d,r11d
-	pinsrw	xmm1,WORD[rbx*4+rdi],5
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r9d
-	add	r8d,DWORD[36+r15]
-	add	al,dl
-	mov	ebx,DWORD[52+rsi]
-	add	r8d,3654602809
-	movzx	eax,al
-	add	r8d,r12d
-	mov	DWORD[48+rsi],edx
-	add	cl,bl
-	rol	r8d,4
-	mov	r12d,r10d
-	pinsrw	xmm0,WORD[rax*4+rdi],6
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r8d
-	add	r11d,DWORD[48+r15]
-	add	bl,dl
-	mov	eax,DWORD[56+rsi]
-	add	r11d,3873151461
-	movzx	ebx,bl
-	add	r11d,r12d
-	mov	DWORD[52+rsi],edx
-	add	cl,al
-	rol	r11d,11
-	mov	r12d,r9d
-	pinsrw	xmm1,WORD[rbx*4+rdi],6
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],eax
-	xor	r12d,r11d
-	add	r10d,DWORD[60+r15]
-	add	al,dl
-	mov	ebx,DWORD[60+rsi]
-	add	r10d,530742520
-	movzx	eax,al
-	add	r10d,r12d
-	mov	DWORD[56+rsi],edx
-	add	cl,bl
-	rol	r10d,16
-	mov	r12d,r8d
-	pinsrw	xmm0,WORD[rax*4+rdi],7
-
-	add	r10d,r11d
-	movdqu	xmm4,XMMWORD[32+r13]
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],ebx
-	xor	r12d,r10d
-	add	r9d,DWORD[8+r15]
-	add	bl,dl
-	mov	eax,DWORD[64+rsi]
-	add	r9d,3299628645
-	movzx	ebx,bl
-	add	r9d,r12d
-	mov	DWORD[60+rsi],edx
-	add	cl,al
-	rol	r9d,23
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],7
-
-	add	r9d,r10d
-	psllq	xmm1,8
-	pxor	xmm4,xmm0
-	pxor	xmm4,xmm1
-	pxor	xmm0,xmm0
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r9d
-	add	r8d,DWORD[r15]
-	add	al,dl
-	mov	ebx,DWORD[68+rsi]
-	add	r8d,4096336452
-	movzx	eax,al
-	xor	r12d,r10d
-	mov	DWORD[64+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,6
-	mov	r12d,-1
-	movd	xmm0,DWORD[rax*4+rdi]
-
-	add	r8d,r9d
-	pxor	xmm1,xmm1
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r8d
-	add	r11d,DWORD[28+r15]
-	add	bl,dl
-	mov	eax,DWORD[72+rsi]
-	add	r11d,1126891415
-	movzx	ebx,bl
-	xor	r12d,r9d
-	mov	DWORD[68+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,10
-	mov	r12d,-1
-	movd	xmm1,DWORD[rbx*4+rdi]
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r11d
-	add	r10d,DWORD[56+r15]
-	add	al,dl
-	mov	ebx,DWORD[76+rsi]
-	add	r10d,2878612391
-	movzx	eax,al
-	xor	r12d,r8d
-	mov	DWORD[72+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,15
-	mov	r12d,-1
-	pinsrw	xmm0,WORD[rax*4+rdi],1
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r10d
-	add	r9d,DWORD[20+r15]
-	add	bl,dl
-	mov	eax,DWORD[80+rsi]
-	add	r9d,4237533241
-	movzx	ebx,bl
-	xor	r12d,r11d
-	mov	DWORD[76+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,21
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],1
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r9d
-	add	r8d,DWORD[48+r15]
-	add	al,dl
-	mov	ebx,DWORD[84+rsi]
-	add	r8d,1700485571
-	movzx	eax,al
-	xor	r12d,r10d
-	mov	DWORD[80+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,6
-	mov	r12d,-1
-	pinsrw	xmm0,WORD[rax*4+rdi],2
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r8d
-	add	r11d,DWORD[12+r15]
-	add	bl,dl
-	mov	eax,DWORD[88+rsi]
-	add	r11d,2399980690
-	movzx	ebx,bl
-	xor	r12d,r9d
-	mov	DWORD[84+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,10
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],2
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r11d
-	add	r10d,DWORD[40+r15]
-	add	al,dl
-	mov	ebx,DWORD[92+rsi]
-	add	r10d,4293915773
-	movzx	eax,al
-	xor	r12d,r8d
-	mov	DWORD[88+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,15
-	mov	r12d,-1
-	pinsrw	xmm0,WORD[rax*4+rdi],3
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r10d
-	add	r9d,DWORD[4+r15]
-	add	bl,dl
-	mov	eax,DWORD[96+rsi]
-	add	r9d,2240044497
-	movzx	ebx,bl
-	xor	r12d,r11d
-	mov	DWORD[92+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,21
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],3
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r9d
-	add	r8d,DWORD[32+r15]
-	add	al,dl
-	mov	ebx,DWORD[100+rsi]
-	add	r8d,1873313359
-	movzx	eax,al
-	xor	r12d,r10d
-	mov	DWORD[96+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,6
-	mov	r12d,-1
-	pinsrw	xmm0,WORD[rax*4+rdi],4
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r8d
-	add	r11d,DWORD[60+r15]
-	add	bl,dl
-	mov	eax,DWORD[104+rsi]
-	add	r11d,4264355552
-	movzx	ebx,bl
-	xor	r12d,r9d
-	mov	DWORD[100+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,10
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],4
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r11d
-	add	r10d,DWORD[24+r15]
-	add	al,dl
-	mov	ebx,DWORD[108+rsi]
-	add	r10d,2734768916
-	movzx	eax,al
-	xor	r12d,r8d
-	mov	DWORD[104+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,15
-	mov	r12d,-1
-	pinsrw	xmm0,WORD[rax*4+rdi],5
-
-	add	r10d,r11d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r10d
-	add	r9d,DWORD[52+r15]
-	add	bl,dl
-	mov	eax,DWORD[112+rsi]
-	add	r9d,1309151649
-	movzx	ebx,bl
-	xor	r12d,r11d
-	mov	DWORD[108+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,21
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],5
-
-	add	r9d,r10d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r11d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r9d
-	add	r8d,DWORD[16+r15]
-	add	al,dl
-	mov	ebx,DWORD[116+rsi]
-	add	r8d,4149444226
-	movzx	eax,al
-	xor	r12d,r10d
-	mov	DWORD[112+rsi],edx
-	add	r8d,r12d
-	add	cl,bl
-	rol	r8d,6
-	mov	r12d,-1
-	pinsrw	xmm0,WORD[rax*4+rdi],6
-
-	add	r8d,r9d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r10d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r8d
-	add	r11d,DWORD[44+r15]
-	add	bl,dl
-	mov	eax,DWORD[120+rsi]
-	add	r11d,3174756917
-	movzx	ebx,bl
-	xor	r12d,r9d
-	mov	DWORD[116+rsi],edx
-	add	r11d,r12d
-	add	cl,al
-	rol	r11d,10
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],6
-
-	add	r11d,r8d
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r9d
-	mov	DWORD[rcx*4+rdi],eax
-	or	r12d,r11d
-	add	r10d,DWORD[8+r15]
-	add	al,dl
-	mov	ebx,DWORD[124+rsi]
-	add	r10d,718787259
-	movzx	eax,al
-	xor	r12d,r8d
-	mov	DWORD[120+rsi],edx
-	add	r10d,r12d
-	add	cl,bl
-	rol	r10d,15
-	mov	r12d,-1
-	pinsrw	xmm0,WORD[rax*4+rdi],7
-
-	add	r10d,r11d
-	movdqu	xmm5,XMMWORD[48+r13]
-	add	bpl,32
-	mov	edx,DWORD[rcx*4+rdi]
-	xor	r12d,r8d
-	mov	DWORD[rcx*4+rdi],ebx
-	or	r12d,r10d
-	add	r9d,DWORD[36+r15]
-	add	bl,dl
-	mov	eax,DWORD[rbp*4+rdi]
-	add	r9d,3951481745
-	movzx	ebx,bl
-	xor	r12d,r11d
-	mov	DWORD[124+rsi],edx
-	add	r9d,r12d
-	add	cl,al
-	rol	r9d,21
-	mov	r12d,-1
-	pinsrw	xmm1,WORD[rbx*4+rdi],7
-
-	add	r9d,r10d
-	mov	rsi,rbp
-	xor	rbp,rbp
-	mov	bpl,sil
-	mov	rsi,rcx
-	xor	rcx,rcx
-	mov	cl,sil
-	lea	rsi,[rbp*4+rdi]
-	psllq	xmm1,8
-	pxor	xmm5,xmm0
-	pxor	xmm5,xmm1
-	add	r8d,DWORD[rsp]
-	add	r9d,DWORD[4+rsp]
-	add	r10d,DWORD[8+rsp]
-	add	r11d,DWORD[12+rsp]
-
-	movdqu	XMMWORD[r13*1+r14],xmm2
-	movdqu	XMMWORD[16+r13*1+r14],xmm3
-	movdqu	XMMWORD[32+r13*1+r14],xmm4
-	movdqu	XMMWORD[48+r13*1+r14],xmm5
-	lea	r15,[64+r15]
-	lea	r13,[64+r13]
-	cmp	r15,QWORD[16+rsp]
-	jb	NEAR $L$oop
-
-	mov	r12,QWORD[24+rsp]
-	sub	cl,al
-	mov	DWORD[r12],r8d
-	mov	DWORD[4+r12],r9d
-	mov	DWORD[8+r12],r10d
-	mov	DWORD[12+r12],r11d
-	sub	bpl,1
-	mov	DWORD[((-8))+rdi],ebp
-	mov	DWORD[((-4))+rdi],ecx
-
-	mov	r15,QWORD[40+rsp]
-	mov	r14,QWORD[48+rsp]
-	mov	r13,QWORD[56+rsp]
-	mov	r12,QWORD[64+rsp]
-	mov	rbp,QWORD[72+rsp]
-	mov	rbx,QWORD[80+rsp]
-	lea	rsp,[88+rsp]
-$L$epilogue:
-$L$abort:
-	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
-	mov	rsi,QWORD[16+rsp]
-	DB	0F3h,0C3h		;repret
-$L$SEH_end_rc4_md5_enc:
-EXTERN	__imp_RtlVirtualUnwind
-
-ALIGN	16
-se_handler:
-	push	rsi
-	push	rdi
-	push	rbx
-	push	rbp
-	push	r12
-	push	r13
-	push	r14
-	push	r15
-	pushfq
-	sub	rsp,64
-
-	mov	rax,QWORD[120+r8]
-	mov	rbx,QWORD[248+r8]
-
-	lea	r10,[$L$body]
-	cmp	rbx,r10
-	jb	NEAR $L$in_prologue
-
-	mov	rax,QWORD[152+r8]
-
-	lea	r10,[$L$epilogue]
-	cmp	rbx,r10
-	jae	NEAR $L$in_prologue
-
-	mov	r15,QWORD[40+rax]
-	mov	r14,QWORD[48+rax]
-	mov	r13,QWORD[56+rax]
-	mov	r12,QWORD[64+rax]
-	mov	rbp,QWORD[72+rax]
-	mov	rbx,QWORD[80+rax]
-	lea	rax,[88+rax]
-
-	mov	QWORD[144+r8],rbx
-	mov	QWORD[160+r8],rbp
-	mov	QWORD[216+r8],r12
-	mov	QWORD[224+r8],r13
-	mov	QWORD[232+r8],r14
-	mov	QWORD[240+r8],r15
-
-$L$in_prologue:
-	mov	rdi,QWORD[8+rax]
-	mov	rsi,QWORD[16+rax]
-	mov	QWORD[152+r8],rax
-	mov	QWORD[168+r8],rsi
-	mov	QWORD[176+r8],rdi
-
-	mov	rdi,QWORD[40+r9]
-	mov	rsi,r8
-	mov	ecx,154
-	DD	0xa548f3fc
-
-	mov	rsi,r9
-	xor	rcx,rcx
-	mov	rdx,QWORD[8+rsi]
-	mov	r8,QWORD[rsi]
-	mov	r9,QWORD[16+rsi]
-	mov	r10,QWORD[40+rsi]
-	lea	r11,[56+rsi]
-	lea	r12,[24+rsi]
-	mov	QWORD[32+rsp],r10
-	mov	QWORD[40+rsp],r11
-	mov	QWORD[48+rsp],r12
-	mov	QWORD[56+rsp],rcx
-	call	QWORD[__imp_RtlVirtualUnwind]
-
-	mov	eax,1
-	add	rsp,64
-	popfq
-	pop	r15
-	pop	r14
-	pop	r13
-	pop	r12
-	pop	rbp
-	pop	rbx
-	pop	rdi
-	pop	rsi
-	DB	0F3h,0C3h		;repret
-
-
-section	.pdata rdata align=4
-ALIGN	4
-	DD	$L$SEH_begin_rc4_md5_enc wrt ..imagebase
-	DD	$L$SEH_end_rc4_md5_enc wrt ..imagebase
-	DD	$L$SEH_info_rc4_md5_enc wrt ..imagebase
-
-section	.xdata rdata align=8
-ALIGN	8
-$L$SEH_info_rc4_md5_enc:
-DB	9,0,0,0
-	DD	se_handler wrt ..imagebase
diff --git a/third_party/boringssl/win-x86_64/crypto/sha/sha1-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/sha/sha1-x86_64.asm
index 0f5361a..168f78d 100644
--- a/third_party/boringssl/win-x86_64/crypto/sha/sha1-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/sha/sha1-x86_64.asm
@@ -24,6 +24,11 @@
 	mov	r10d,DWORD[((OPENSSL_ia32cap_P+8))]
 	test	r8d,512
 	jz	NEAR $L$ialu
+	and	r8d,268435456
+	and	r9d,1073741824
+	or	r8d,r9d
+	cmp	r8d,1342177280
+	je	NEAR _avx_shortcut
 	jmp	NEAR _ssse3_shortcut
 
 ALIGN	16
@@ -2445,6 +2450,1146 @@
 	mov	rsi,QWORD[16+rsp]
 	DB	0F3h,0C3h		;repret
 $L$SEH_end_sha1_block_data_order_ssse3:
+
+ALIGN	16
+sha1_block_data_order_avx:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_sha1_block_data_order_avx:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+_avx_shortcut:
+	mov	rax,rsp
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	lea	rsp,[((-160))+rsp]
+	vzeroupper
+	vmovaps	XMMWORD[(-40-96)+rax],xmm6
+	vmovaps	XMMWORD[(-40-80)+rax],xmm7
+	vmovaps	XMMWORD[(-40-64)+rax],xmm8
+	vmovaps	XMMWORD[(-40-48)+rax],xmm9
+	vmovaps	XMMWORD[(-40-32)+rax],xmm10
+	vmovaps	XMMWORD[(-40-16)+rax],xmm11
+$L$prologue_avx:
+	mov	r14,rax
+	and	rsp,-64
+	mov	r8,rdi
+	mov	r9,rsi
+	mov	r10,rdx
+
+	shl	r10,6
+	add	r10,r9
+	lea	r11,[((K_XX_XX+64))]
+
+	mov	eax,DWORD[r8]
+	mov	ebx,DWORD[4+r8]
+	mov	ecx,DWORD[8+r8]
+	mov	edx,DWORD[12+r8]
+	mov	esi,ebx
+	mov	ebp,DWORD[16+r8]
+	mov	edi,ecx
+	xor	edi,edx
+	and	esi,edi
+
+	vmovdqa	xmm6,XMMWORD[64+r11]
+	vmovdqa	xmm11,XMMWORD[((-64))+r11]
+	vmovdqu	xmm0,XMMWORD[r9]
+	vmovdqu	xmm1,XMMWORD[16+r9]
+	vmovdqu	xmm2,XMMWORD[32+r9]
+	vmovdqu	xmm3,XMMWORD[48+r9]
+	vpshufb	xmm0,xmm0,xmm6
+	add	r9,64
+	vpshufb	xmm1,xmm1,xmm6
+	vpshufb	xmm2,xmm2,xmm6
+	vpshufb	xmm3,xmm3,xmm6
+	vpaddd	xmm4,xmm0,xmm11
+	vpaddd	xmm5,xmm1,xmm11
+	vpaddd	xmm6,xmm2,xmm11
+	vmovdqa	XMMWORD[rsp],xmm4
+	vmovdqa	XMMWORD[16+rsp],xmm5
+	vmovdqa	XMMWORD[32+rsp],xmm6
+	jmp	NEAR $L$oop_avx
+ALIGN	16
+$L$oop_avx:
+	shrd	ebx,ebx,2
+	xor	esi,edx
+	vpalignr	xmm4,xmm1,xmm0,8
+	mov	edi,eax
+	add	ebp,DWORD[rsp]
+	vpaddd	xmm9,xmm11,xmm3
+	xor	ebx,ecx
+	shld	eax,eax,5
+	vpsrldq	xmm8,xmm3,4
+	add	ebp,esi
+	and	edi,ebx
+	vpxor	xmm4,xmm4,xmm0
+	xor	ebx,ecx
+	add	ebp,eax
+	vpxor	xmm8,xmm8,xmm2
+	shrd	eax,eax,7
+	xor	edi,ecx
+	mov	esi,ebp
+	add	edx,DWORD[4+rsp]
+	vpxor	xmm4,xmm4,xmm8
+	xor	eax,ebx
+	shld	ebp,ebp,5
+	vmovdqa	XMMWORD[48+rsp],xmm9
+	add	edx,edi
+	and	esi,eax
+	vpsrld	xmm8,xmm4,31
+	xor	eax,ebx
+	add	edx,ebp
+	shrd	ebp,ebp,7
+	xor	esi,ebx
+	vpslldq	xmm10,xmm4,12
+	vpaddd	xmm4,xmm4,xmm4
+	mov	edi,edx
+	add	ecx,DWORD[8+rsp]
+	xor	ebp,eax
+	shld	edx,edx,5
+	vpsrld	xmm9,xmm10,30
+	vpor	xmm4,xmm4,xmm8
+	add	ecx,esi
+	and	edi,ebp
+	xor	ebp,eax
+	add	ecx,edx
+	vpslld	xmm10,xmm10,2
+	vpxor	xmm4,xmm4,xmm9
+	shrd	edx,edx,7
+	xor	edi,eax
+	mov	esi,ecx
+	add	ebx,DWORD[12+rsp]
+	vpxor	xmm4,xmm4,xmm10
+	xor	edx,ebp
+	shld	ecx,ecx,5
+	add	ebx,edi
+	and	esi,edx
+	xor	edx,ebp
+	add	ebx,ecx
+	shrd	ecx,ecx,7
+	xor	esi,ebp
+	vpalignr	xmm5,xmm2,xmm1,8
+	mov	edi,ebx
+	add	eax,DWORD[16+rsp]
+	vpaddd	xmm9,xmm11,xmm4
+	xor	ecx,edx
+	shld	ebx,ebx,5
+	vpsrldq	xmm8,xmm4,4
+	add	eax,esi
+	and	edi,ecx
+	vpxor	xmm5,xmm5,xmm1
+	xor	ecx,edx
+	add	eax,ebx
+	vpxor	xmm8,xmm8,xmm3
+	shrd	ebx,ebx,7
+	xor	edi,edx
+	mov	esi,eax
+	add	ebp,DWORD[20+rsp]
+	vpxor	xmm5,xmm5,xmm8
+	xor	ebx,ecx
+	shld	eax,eax,5
+	vmovdqa	XMMWORD[rsp],xmm9
+	add	ebp,edi
+	and	esi,ebx
+	vpsrld	xmm8,xmm5,31
+	xor	ebx,ecx
+	add	ebp,eax
+	shrd	eax,eax,7
+	xor	esi,ecx
+	vpslldq	xmm10,xmm5,12
+	vpaddd	xmm5,xmm5,xmm5
+	mov	edi,ebp
+	add	edx,DWORD[24+rsp]
+	xor	eax,ebx
+	shld	ebp,ebp,5
+	vpsrld	xmm9,xmm10,30
+	vpor	xmm5,xmm5,xmm8
+	add	edx,esi
+	and	edi,eax
+	xor	eax,ebx
+	add	edx,ebp
+	vpslld	xmm10,xmm10,2
+	vpxor	xmm5,xmm5,xmm9
+	shrd	ebp,ebp,7
+	xor	edi,ebx
+	mov	esi,edx
+	add	ecx,DWORD[28+rsp]
+	vpxor	xmm5,xmm5,xmm10
+	xor	ebp,eax
+	shld	edx,edx,5
+	vmovdqa	xmm11,XMMWORD[((-32))+r11]
+	add	ecx,edi
+	and	esi,ebp
+	xor	ebp,eax
+	add	ecx,edx
+	shrd	edx,edx,7
+	xor	esi,eax
+	vpalignr	xmm6,xmm3,xmm2,8
+	mov	edi,ecx
+	add	ebx,DWORD[32+rsp]
+	vpaddd	xmm9,xmm11,xmm5
+	xor	edx,ebp
+	shld	ecx,ecx,5
+	vpsrldq	xmm8,xmm5,4
+	add	ebx,esi
+	and	edi,edx
+	vpxor	xmm6,xmm6,xmm2
+	xor	edx,ebp
+	add	ebx,ecx
+	vpxor	xmm8,xmm8,xmm4
+	shrd	ecx,ecx,7
+	xor	edi,ebp
+	mov	esi,ebx
+	add	eax,DWORD[36+rsp]
+	vpxor	xmm6,xmm6,xmm8
+	xor	ecx,edx
+	shld	ebx,ebx,5
+	vmovdqa	XMMWORD[16+rsp],xmm9
+	add	eax,edi
+	and	esi,ecx
+	vpsrld	xmm8,xmm6,31
+	xor	ecx,edx
+	add	eax,ebx
+	shrd	ebx,ebx,7
+	xor	esi,edx
+	vpslldq	xmm10,xmm6,12
+	vpaddd	xmm6,xmm6,xmm6
+	mov	edi,eax
+	add	ebp,DWORD[40+rsp]
+	xor	ebx,ecx
+	shld	eax,eax,5
+	vpsrld	xmm9,xmm10,30
+	vpor	xmm6,xmm6,xmm8
+	add	ebp,esi
+	and	edi,ebx
+	xor	ebx,ecx
+	add	ebp,eax
+	vpslld	xmm10,xmm10,2
+	vpxor	xmm6,xmm6,xmm9
+	shrd	eax,eax,7
+	xor	edi,ecx
+	mov	esi,ebp
+	add	edx,DWORD[44+rsp]
+	vpxor	xmm6,xmm6,xmm10
+	xor	eax,ebx
+	shld	ebp,ebp,5
+	add	edx,edi
+	and	esi,eax
+	xor	eax,ebx
+	add	edx,ebp
+	shrd	ebp,ebp,7
+	xor	esi,ebx
+	vpalignr	xmm7,xmm4,xmm3,8
+	mov	edi,edx
+	add	ecx,DWORD[48+rsp]
+	vpaddd	xmm9,xmm11,xmm6
+	xor	ebp,eax
+	shld	edx,edx,5
+	vpsrldq	xmm8,xmm6,4
+	add	ecx,esi
+	and	edi,ebp
+	vpxor	xmm7,xmm7,xmm3
+	xor	ebp,eax
+	add	ecx,edx
+	vpxor	xmm8,xmm8,xmm5
+	shrd	edx,edx,7
+	xor	edi,eax
+	mov	esi,ecx
+	add	ebx,DWORD[52+rsp]
+	vpxor	xmm7,xmm7,xmm8
+	xor	edx,ebp
+	shld	ecx,ecx,5
+	vmovdqa	XMMWORD[32+rsp],xmm9
+	add	ebx,edi
+	and	esi,edx
+	vpsrld	xmm8,xmm7,31
+	xor	edx,ebp
+	add	ebx,ecx
+	shrd	ecx,ecx,7
+	xor	esi,ebp
+	vpslldq	xmm10,xmm7,12
+	vpaddd	xmm7,xmm7,xmm7
+	mov	edi,ebx
+	add	eax,DWORD[56+rsp]
+	xor	ecx,edx
+	shld	ebx,ebx,5
+	vpsrld	xmm9,xmm10,30
+	vpor	xmm7,xmm7,xmm8
+	add	eax,esi
+	and	edi,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	vpslld	xmm10,xmm10,2
+	vpxor	xmm7,xmm7,xmm9
+	shrd	ebx,ebx,7
+	xor	edi,edx
+	mov	esi,eax
+	add	ebp,DWORD[60+rsp]
+	vpxor	xmm7,xmm7,xmm10
+	xor	ebx,ecx
+	shld	eax,eax,5
+	add	ebp,edi
+	and	esi,ebx
+	xor	ebx,ecx
+	add	ebp,eax
+	vpalignr	xmm8,xmm7,xmm6,8
+	vpxor	xmm0,xmm0,xmm4
+	shrd	eax,eax,7
+	xor	esi,ecx
+	mov	edi,ebp
+	add	edx,DWORD[rsp]
+	vpxor	xmm0,xmm0,xmm1
+	xor	eax,ebx
+	shld	ebp,ebp,5
+	vpaddd	xmm9,xmm11,xmm7
+	add	edx,esi
+	and	edi,eax
+	vpxor	xmm0,xmm0,xmm8
+	xor	eax,ebx
+	add	edx,ebp
+	shrd	ebp,ebp,7
+	xor	edi,ebx
+	vpsrld	xmm8,xmm0,30
+	vmovdqa	XMMWORD[48+rsp],xmm9
+	mov	esi,edx
+	add	ecx,DWORD[4+rsp]
+	xor	ebp,eax
+	shld	edx,edx,5
+	vpslld	xmm0,xmm0,2
+	add	ecx,edi
+	and	esi,ebp
+	xor	ebp,eax
+	add	ecx,edx
+	shrd	edx,edx,7
+	xor	esi,eax
+	mov	edi,ecx
+	add	ebx,DWORD[8+rsp]
+	vpor	xmm0,xmm0,xmm8
+	xor	edx,ebp
+	shld	ecx,ecx,5
+	add	ebx,esi
+	and	edi,edx
+	xor	edx,ebp
+	add	ebx,ecx
+	add	eax,DWORD[12+rsp]
+	xor	edi,ebp
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,edi
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpalignr	xmm8,xmm0,xmm7,8
+	vpxor	xmm1,xmm1,xmm5
+	add	ebp,DWORD[16+rsp]
+	xor	esi,ecx
+	mov	edi,eax
+	shld	eax,eax,5
+	vpxor	xmm1,xmm1,xmm2
+	add	ebp,esi
+	xor	edi,ecx
+	vpaddd	xmm9,xmm11,xmm0
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	vpxor	xmm1,xmm1,xmm8
+	add	edx,DWORD[20+rsp]
+	xor	edi,ebx
+	mov	esi,ebp
+	shld	ebp,ebp,5
+	vpsrld	xmm8,xmm1,30
+	vmovdqa	XMMWORD[rsp],xmm9
+	add	edx,edi
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	vpslld	xmm1,xmm1,2
+	add	ecx,DWORD[24+rsp]
+	xor	esi,eax
+	mov	edi,edx
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	edi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	vpor	xmm1,xmm1,xmm8
+	add	ebx,DWORD[28+rsp]
+	xor	edi,ebp
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,edi
+	xor	esi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpalignr	xmm8,xmm1,xmm0,8
+	vpxor	xmm2,xmm2,xmm6
+	add	eax,DWORD[32+rsp]
+	xor	esi,edx
+	mov	edi,ebx
+	shld	ebx,ebx,5
+	vpxor	xmm2,xmm2,xmm3
+	add	eax,esi
+	xor	edi,edx
+	vpaddd	xmm9,xmm11,xmm1
+	vmovdqa	xmm11,XMMWORD[r11]
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpxor	xmm2,xmm2,xmm8
+	add	ebp,DWORD[36+rsp]
+	xor	edi,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	vpsrld	xmm8,xmm2,30
+	vmovdqa	XMMWORD[16+rsp],xmm9
+	add	ebp,edi
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	vpslld	xmm2,xmm2,2
+	add	edx,DWORD[40+rsp]
+	xor	esi,ebx
+	mov	edi,ebp
+	shld	ebp,ebp,5
+	add	edx,esi
+	xor	edi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	vpor	xmm2,xmm2,xmm8
+	add	ecx,DWORD[44+rsp]
+	xor	edi,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,edi
+	xor	esi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	vpalignr	xmm8,xmm2,xmm1,8
+	vpxor	xmm3,xmm3,xmm7
+	add	ebx,DWORD[48+rsp]
+	xor	esi,ebp
+	mov	edi,ecx
+	shld	ecx,ecx,5
+	vpxor	xmm3,xmm3,xmm4
+	add	ebx,esi
+	xor	edi,ebp
+	vpaddd	xmm9,xmm11,xmm2
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpxor	xmm3,xmm3,xmm8
+	add	eax,DWORD[52+rsp]
+	xor	edi,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	vpsrld	xmm8,xmm3,30
+	vmovdqa	XMMWORD[32+rsp],xmm9
+	add	eax,edi
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpslld	xmm3,xmm3,2
+	add	ebp,DWORD[56+rsp]
+	xor	esi,ecx
+	mov	edi,eax
+	shld	eax,eax,5
+	add	ebp,esi
+	xor	edi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	vpor	xmm3,xmm3,xmm8
+	add	edx,DWORD[60+rsp]
+	xor	edi,ebx
+	mov	esi,ebp
+	shld	ebp,ebp,5
+	add	edx,edi
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	vpalignr	xmm8,xmm3,xmm2,8
+	vpxor	xmm4,xmm4,xmm0
+	add	ecx,DWORD[rsp]
+	xor	esi,eax
+	mov	edi,edx
+	shld	edx,edx,5
+	vpxor	xmm4,xmm4,xmm5
+	add	ecx,esi
+	xor	edi,eax
+	vpaddd	xmm9,xmm11,xmm3
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	vpxor	xmm4,xmm4,xmm8
+	add	ebx,DWORD[4+rsp]
+	xor	edi,ebp
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	vpsrld	xmm8,xmm4,30
+	vmovdqa	XMMWORD[48+rsp],xmm9
+	add	ebx,edi
+	xor	esi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpslld	xmm4,xmm4,2
+	add	eax,DWORD[8+rsp]
+	xor	esi,edx
+	mov	edi,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	edi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vpor	xmm4,xmm4,xmm8
+	add	ebp,DWORD[12+rsp]
+	xor	edi,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	add	ebp,edi
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	vpalignr	xmm8,xmm4,xmm3,8
+	vpxor	xmm5,xmm5,xmm1
+	add	edx,DWORD[16+rsp]
+	xor	esi,ebx
+	mov	edi,ebp
+	shld	ebp,ebp,5
+	vpxor	xmm5,xmm5,xmm6
+	add	edx,esi
+	xor	edi,ebx
+	vpaddd	xmm9,xmm11,xmm4
+	shrd	eax,eax,7
+	add	edx,ebp
+	vpxor	xmm5,xmm5,xmm8
+	add	ecx,DWORD[20+rsp]
+	xor	edi,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	vpsrld	xmm8,xmm5,30
+	vmovdqa	XMMWORD[rsp],xmm9
+	add	ecx,edi
+	xor	esi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	vpslld	xmm5,xmm5,2
+	add	ebx,DWORD[24+rsp]
+	xor	esi,ebp
+	mov	edi,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	edi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vpor	xmm5,xmm5,xmm8
+	add	eax,DWORD[28+rsp]
+	shrd	ecx,ecx,7
+	mov	esi,ebx
+	xor	edi,edx
+	shld	ebx,ebx,5
+	add	eax,edi
+	xor	esi,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	vpalignr	xmm8,xmm5,xmm4,8
+	vpxor	xmm6,xmm6,xmm2
+	add	ebp,DWORD[32+rsp]
+	and	esi,ecx
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	vpxor	xmm6,xmm6,xmm7
+	mov	edi,eax
+	xor	esi,ecx
+	vpaddd	xmm9,xmm11,xmm5
+	shld	eax,eax,5
+	add	ebp,esi
+	vpxor	xmm6,xmm6,xmm8
+	xor	edi,ebx
+	xor	ebx,ecx
+	add	ebp,eax
+	add	edx,DWORD[36+rsp]
+	vpsrld	xmm8,xmm6,30
+	vmovdqa	XMMWORD[16+rsp],xmm9
+	and	edi,ebx
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	mov	esi,ebp
+	vpslld	xmm6,xmm6,2
+	xor	edi,ebx
+	shld	ebp,ebp,5
+	add	edx,edi
+	xor	esi,eax
+	xor	eax,ebx
+	add	edx,ebp
+	add	ecx,DWORD[40+rsp]
+	and	esi,eax
+	vpor	xmm6,xmm6,xmm8
+	xor	eax,ebx
+	shrd	ebp,ebp,7
+	mov	edi,edx
+	xor	esi,eax
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	edi,ebp
+	xor	ebp,eax
+	add	ecx,edx
+	add	ebx,DWORD[44+rsp]
+	and	edi,ebp
+	xor	ebp,eax
+	shrd	edx,edx,7
+	mov	esi,ecx
+	xor	edi,ebp
+	shld	ecx,ecx,5
+	add	ebx,edi
+	xor	esi,edx
+	xor	edx,ebp
+	add	ebx,ecx
+	vpalignr	xmm8,xmm6,xmm5,8
+	vpxor	xmm7,xmm7,xmm3
+	add	eax,DWORD[48+rsp]
+	and	esi,edx
+	xor	edx,ebp
+	shrd	ecx,ecx,7
+	vpxor	xmm7,xmm7,xmm0
+	mov	edi,ebx
+	xor	esi,edx
+	vpaddd	xmm9,xmm11,xmm6
+	vmovdqa	xmm11,XMMWORD[32+r11]
+	shld	ebx,ebx,5
+	add	eax,esi
+	vpxor	xmm7,xmm7,xmm8
+	xor	edi,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	add	ebp,DWORD[52+rsp]
+	vpsrld	xmm8,xmm7,30
+	vmovdqa	XMMWORD[32+rsp],xmm9
+	and	edi,ecx
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	mov	esi,eax
+	vpslld	xmm7,xmm7,2
+	xor	edi,ecx
+	shld	eax,eax,5
+	add	ebp,edi
+	xor	esi,ebx
+	xor	ebx,ecx
+	add	ebp,eax
+	add	edx,DWORD[56+rsp]
+	and	esi,ebx
+	vpor	xmm7,xmm7,xmm8
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	mov	edi,ebp
+	xor	esi,ebx
+	shld	ebp,ebp,5
+	add	edx,esi
+	xor	edi,eax
+	xor	eax,ebx
+	add	edx,ebp
+	add	ecx,DWORD[60+rsp]
+	and	edi,eax
+	xor	eax,ebx
+	shrd	ebp,ebp,7
+	mov	esi,edx
+	xor	edi,eax
+	shld	edx,edx,5
+	add	ecx,edi
+	xor	esi,ebp
+	xor	ebp,eax
+	add	ecx,edx
+	vpalignr	xmm8,xmm7,xmm6,8
+	vpxor	xmm0,xmm0,xmm4
+	add	ebx,DWORD[rsp]
+	and	esi,ebp
+	xor	ebp,eax
+	shrd	edx,edx,7
+	vpxor	xmm0,xmm0,xmm1
+	mov	edi,ecx
+	xor	esi,ebp
+	vpaddd	xmm9,xmm11,xmm7
+	shld	ecx,ecx,5
+	add	ebx,esi
+	vpxor	xmm0,xmm0,xmm8
+	xor	edi,edx
+	xor	edx,ebp
+	add	ebx,ecx
+	add	eax,DWORD[4+rsp]
+	vpsrld	xmm8,xmm0,30
+	vmovdqa	XMMWORD[48+rsp],xmm9
+	and	edi,edx
+	xor	edx,ebp
+	shrd	ecx,ecx,7
+	mov	esi,ebx
+	vpslld	xmm0,xmm0,2
+	xor	edi,edx
+	shld	ebx,ebx,5
+	add	eax,edi
+	xor	esi,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	add	ebp,DWORD[8+rsp]
+	and	esi,ecx
+	vpor	xmm0,xmm0,xmm8
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	mov	edi,eax
+	xor	esi,ecx
+	shld	eax,eax,5
+	add	ebp,esi
+	xor	edi,ebx
+	xor	ebx,ecx
+	add	ebp,eax
+	add	edx,DWORD[12+rsp]
+	and	edi,ebx
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	mov	esi,ebp
+	xor	edi,ebx
+	shld	ebp,ebp,5
+	add	edx,edi
+	xor	esi,eax
+	xor	eax,ebx
+	add	edx,ebp
+	vpalignr	xmm8,xmm0,xmm7,8
+	vpxor	xmm1,xmm1,xmm5
+	add	ecx,DWORD[16+rsp]
+	and	esi,eax
+	xor	eax,ebx
+	shrd	ebp,ebp,7
+	vpxor	xmm1,xmm1,xmm2
+	mov	edi,edx
+	xor	esi,eax
+	vpaddd	xmm9,xmm11,xmm0
+	shld	edx,edx,5
+	add	ecx,esi
+	vpxor	xmm1,xmm1,xmm8
+	xor	edi,ebp
+	xor	ebp,eax
+	add	ecx,edx
+	add	ebx,DWORD[20+rsp]
+	vpsrld	xmm8,xmm1,30
+	vmovdqa	XMMWORD[rsp],xmm9
+	and	edi,ebp
+	xor	ebp,eax
+	shrd	edx,edx,7
+	mov	esi,ecx
+	vpslld	xmm1,xmm1,2
+	xor	edi,ebp
+	shld	ecx,ecx,5
+	add	ebx,edi
+	xor	esi,edx
+	xor	edx,ebp
+	add	ebx,ecx
+	add	eax,DWORD[24+rsp]
+	and	esi,edx
+	vpor	xmm1,xmm1,xmm8
+	xor	edx,ebp
+	shrd	ecx,ecx,7
+	mov	edi,ebx
+	xor	esi,edx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	edi,ecx
+	xor	ecx,edx
+	add	eax,ebx
+	add	ebp,DWORD[28+rsp]
+	and	edi,ecx
+	xor	ecx,edx
+	shrd	ebx,ebx,7
+	mov	esi,eax
+	xor	edi,ecx
+	shld	eax,eax,5
+	add	ebp,edi
+	xor	esi,ebx
+	xor	ebx,ecx
+	add	ebp,eax
+	vpalignr	xmm8,xmm1,xmm0,8
+	vpxor	xmm2,xmm2,xmm6
+	add	edx,DWORD[32+rsp]
+	and	esi,ebx
+	xor	ebx,ecx
+	shrd	eax,eax,7
+	vpxor	xmm2,xmm2,xmm3
+	mov	edi,ebp
+	xor	esi,ebx
+	vpaddd	xmm9,xmm11,xmm1
+	shld	ebp,ebp,5
+	add	edx,esi
+	vpxor	xmm2,xmm2,xmm8
+	xor	edi,eax
+	xor	eax,ebx
+	add	edx,ebp
+	add	ecx,DWORD[36+rsp]
+	vpsrld	xmm8,xmm2,30
+	vmovdqa	XMMWORD[16+rsp],xmm9
+	and	edi,eax
+	xor	eax,ebx
+	shrd	ebp,ebp,7
+	mov	esi,edx
+	vpslld	xmm2,xmm2,2
+	xor	edi,eax
+	shld	edx,edx,5
+	add	ecx,edi
+	xor	esi,ebp
+	xor	ebp,eax
+	add	ecx,edx
+	add	ebx,DWORD[40+rsp]
+	and	esi,ebp
+	vpor	xmm2,xmm2,xmm8
+	xor	ebp,eax
+	shrd	edx,edx,7
+	mov	edi,ecx
+	xor	esi,ebp
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	edi,edx
+	xor	edx,ebp
+	add	ebx,ecx
+	add	eax,DWORD[44+rsp]
+	and	edi,edx
+	xor	edx,ebp
+	shrd	ecx,ecx,7
+	mov	esi,ebx
+	xor	edi,edx
+	shld	ebx,ebx,5
+	add	eax,edi
+	xor	esi,edx
+	add	eax,ebx
+	vpalignr	xmm8,xmm2,xmm1,8
+	vpxor	xmm3,xmm3,xmm7
+	add	ebp,DWORD[48+rsp]
+	xor	esi,ecx
+	mov	edi,eax
+	shld	eax,eax,5
+	vpxor	xmm3,xmm3,xmm4
+	add	ebp,esi
+	xor	edi,ecx
+	vpaddd	xmm9,xmm11,xmm2
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	vpxor	xmm3,xmm3,xmm8
+	add	edx,DWORD[52+rsp]
+	xor	edi,ebx
+	mov	esi,ebp
+	shld	ebp,ebp,5
+	vpsrld	xmm8,xmm3,30
+	vmovdqa	XMMWORD[32+rsp],xmm9
+	add	edx,edi
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	vpslld	xmm3,xmm3,2
+	add	ecx,DWORD[56+rsp]
+	xor	esi,eax
+	mov	edi,edx
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	edi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	vpor	xmm3,xmm3,xmm8
+	add	ebx,DWORD[60+rsp]
+	xor	edi,ebp
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,edi
+	xor	esi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD[rsp]
+	vpaddd	xmm9,xmm11,xmm3
+	xor	esi,edx
+	mov	edi,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	vmovdqa	XMMWORD[48+rsp],xmm9
+	xor	edi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	ebp,DWORD[4+rsp]
+	xor	edi,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	add	ebp,edi
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	add	edx,DWORD[8+rsp]
+	xor	esi,ebx
+	mov	edi,ebp
+	shld	ebp,ebp,5
+	add	edx,esi
+	xor	edi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	add	ecx,DWORD[12+rsp]
+	xor	edi,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,edi
+	xor	esi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	cmp	r9,r10
+	je	NEAR $L$done_avx
+	vmovdqa	xmm6,XMMWORD[64+r11]
+	vmovdqa	xmm11,XMMWORD[((-64))+r11]
+	vmovdqu	xmm0,XMMWORD[r9]
+	vmovdqu	xmm1,XMMWORD[16+r9]
+	vmovdqu	xmm2,XMMWORD[32+r9]
+	vmovdqu	xmm3,XMMWORD[48+r9]
+	vpshufb	xmm0,xmm0,xmm6
+	add	r9,64
+	add	ebx,DWORD[16+rsp]
+	xor	esi,ebp
+	vpshufb	xmm1,xmm1,xmm6
+	mov	edi,ecx
+	shld	ecx,ecx,5
+	vpaddd	xmm4,xmm0,xmm11
+	add	ebx,esi
+	xor	edi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	vmovdqa	XMMWORD[rsp],xmm4
+	add	eax,DWORD[20+rsp]
+	xor	edi,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,edi
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	ebp,DWORD[24+rsp]
+	xor	esi,ecx
+	mov	edi,eax
+	shld	eax,eax,5
+	add	ebp,esi
+	xor	edi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	add	edx,DWORD[28+rsp]
+	xor	edi,ebx
+	mov	esi,ebp
+	shld	ebp,ebp,5
+	add	edx,edi
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	add	ecx,DWORD[32+rsp]
+	xor	esi,eax
+	vpshufb	xmm2,xmm2,xmm6
+	mov	edi,edx
+	shld	edx,edx,5
+	vpaddd	xmm5,xmm1,xmm11
+	add	ecx,esi
+	xor	edi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	vmovdqa	XMMWORD[16+rsp],xmm5
+	add	ebx,DWORD[36+rsp]
+	xor	edi,ebp
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,edi
+	xor	esi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD[40+rsp]
+	xor	esi,edx
+	mov	edi,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	edi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	ebp,DWORD[44+rsp]
+	xor	edi,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	add	ebp,edi
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	add	edx,DWORD[48+rsp]
+	xor	esi,ebx
+	vpshufb	xmm3,xmm3,xmm6
+	mov	edi,ebp
+	shld	ebp,ebp,5
+	vpaddd	xmm6,xmm2,xmm11
+	add	edx,esi
+	xor	edi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	vmovdqa	XMMWORD[32+rsp],xmm6
+	add	ecx,DWORD[52+rsp]
+	xor	edi,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,edi
+	xor	esi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	add	ebx,DWORD[56+rsp]
+	xor	esi,ebp
+	mov	edi,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	edi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD[60+rsp]
+	xor	edi,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,edi
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	eax,DWORD[r8]
+	add	esi,DWORD[4+r8]
+	add	ecx,DWORD[8+r8]
+	add	edx,DWORD[12+r8]
+	mov	DWORD[r8],eax
+	add	ebp,DWORD[16+r8]
+	mov	DWORD[4+r8],esi
+	mov	ebx,esi
+	mov	DWORD[8+r8],ecx
+	mov	edi,ecx
+	mov	DWORD[12+r8],edx
+	xor	edi,edx
+	mov	DWORD[16+r8],ebp
+	and	esi,edi
+	jmp	NEAR $L$oop_avx
+
+ALIGN	16
+$L$done_avx:
+	add	ebx,DWORD[16+rsp]
+	xor	esi,ebp
+	mov	edi,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	edi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD[20+rsp]
+	xor	edi,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,edi
+	xor	esi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	ebp,DWORD[24+rsp]
+	xor	esi,ecx
+	mov	edi,eax
+	shld	eax,eax,5
+	add	ebp,esi
+	xor	edi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	add	edx,DWORD[28+rsp]
+	xor	edi,ebx
+	mov	esi,ebp
+	shld	ebp,ebp,5
+	add	edx,edi
+	xor	esi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	add	ecx,DWORD[32+rsp]
+	xor	esi,eax
+	mov	edi,edx
+	shld	edx,edx,5
+	add	ecx,esi
+	xor	edi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	add	ebx,DWORD[36+rsp]
+	xor	edi,ebp
+	mov	esi,ecx
+	shld	ecx,ecx,5
+	add	ebx,edi
+	xor	esi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD[40+rsp]
+	xor	esi,edx
+	mov	edi,ebx
+	shld	ebx,ebx,5
+	add	eax,esi
+	xor	edi,edx
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	add	ebp,DWORD[44+rsp]
+	xor	edi,ecx
+	mov	esi,eax
+	shld	eax,eax,5
+	add	ebp,edi
+	xor	esi,ecx
+	shrd	ebx,ebx,7
+	add	ebp,eax
+	add	edx,DWORD[48+rsp]
+	xor	esi,ebx
+	mov	edi,ebp
+	shld	ebp,ebp,5
+	add	edx,esi
+	xor	edi,ebx
+	shrd	eax,eax,7
+	add	edx,ebp
+	add	ecx,DWORD[52+rsp]
+	xor	edi,eax
+	mov	esi,edx
+	shld	edx,edx,5
+	add	ecx,edi
+	xor	esi,eax
+	shrd	ebp,ebp,7
+	add	ecx,edx
+	add	ebx,DWORD[56+rsp]
+	xor	esi,ebp
+	mov	edi,ecx
+	shld	ecx,ecx,5
+	add	ebx,esi
+	xor	edi,ebp
+	shrd	edx,edx,7
+	add	ebx,ecx
+	add	eax,DWORD[60+rsp]
+	xor	edi,edx
+	mov	esi,ebx
+	shld	ebx,ebx,5
+	add	eax,edi
+	shrd	ecx,ecx,7
+	add	eax,ebx
+	vzeroupper
+
+	add	eax,DWORD[r8]
+	add	esi,DWORD[4+r8]
+	add	ecx,DWORD[8+r8]
+	mov	DWORD[r8],eax
+	add	edx,DWORD[12+r8]
+	mov	DWORD[4+r8],esi
+	add	ebp,DWORD[16+r8]
+	mov	DWORD[8+r8],ecx
+	mov	DWORD[12+r8],edx
+	mov	DWORD[16+r8],ebp
+	movaps	xmm6,XMMWORD[((-40-96))+r14]
+	movaps	xmm7,XMMWORD[((-40-80))+r14]
+	movaps	xmm8,XMMWORD[((-40-64))+r14]
+	movaps	xmm9,XMMWORD[((-40-48))+r14]
+	movaps	xmm10,XMMWORD[((-40-32))+r14]
+	movaps	xmm11,XMMWORD[((-40-16))+r14]
+	lea	rsi,[r14]
+	mov	r14,QWORD[((-40))+rsi]
+	mov	r13,QWORD[((-32))+rsi]
+	mov	r12,QWORD[((-24))+rsi]
+	mov	rbp,QWORD[((-16))+rsi]
+	mov	rbx,QWORD[((-8))+rsi]
+	lea	rsp,[rsi]
+$L$epilogue_avx:
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_sha1_block_data_order_avx:
 ALIGN	64
 K_XX_XX:
 	DD	0x5a827999,0x5a827999,0x5a827999,0x5a827999
@@ -2605,6 +3750,9 @@
 	DD	$L$SEH_begin_sha1_block_data_order_ssse3 wrt ..imagebase
 	DD	$L$SEH_end_sha1_block_data_order_ssse3 wrt ..imagebase
 	DD	$L$SEH_info_sha1_block_data_order_ssse3 wrt ..imagebase
+	DD	$L$SEH_begin_sha1_block_data_order_avx wrt ..imagebase
+	DD	$L$SEH_end_sha1_block_data_order_avx wrt ..imagebase
+	DD	$L$SEH_info_sha1_block_data_order_avx wrt ..imagebase
 section	.xdata rdata align=8
 ALIGN	8
 $L$SEH_info_sha1_block_data_order:
@@ -2614,3 +3762,7 @@
 DB	9,0,0,0
 	DD	ssse3_handler wrt ..imagebase
 	DD	$L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase
+$L$SEH_info_sha1_block_data_order_avx:
+DB	9,0,0,0
+	DD	ssse3_handler wrt ..imagebase
+	DD	$L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase
diff --git a/third_party/boringssl/win-x86_64/crypto/sha/sha256-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/sha/sha256-x86_64.asm
index e6193c5..efaf9b5 100644
--- a/third_party/boringssl/win-x86_64/crypto/sha/sha256-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/sha/sha256-x86_64.asm
@@ -23,6 +23,11 @@
 	mov	r9d,DWORD[r11]
 	mov	r10d,DWORD[4+r11]
 	mov	r11d,DWORD[8+r11]
+	and	r9d,1073741824
+	and	r10d,268435968
+	or	r10d,r9d
+	cmp	r10d,1342177792
+	je	NEAR $L$avx_shortcut
 	test	r10d,512
 	jnz	NEAR $L$ssse3_shortcut
 	push	rbx
@@ -2877,6 +2882,1082 @@
 	mov	rsi,QWORD[16+rsp]
 	DB	0F3h,0C3h		;repret
 $L$SEH_end_sha256_block_data_order_ssse3:
+
+ALIGN	64
+sha256_block_data_order_avx:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_sha256_block_data_order_avx:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+$L$avx_shortcut:
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	mov	r11,rsp
+	shl	rdx,4
+	sub	rsp,160
+	lea	rdx,[rdx*4+rsi]
+	and	rsp,-64
+	mov	QWORD[((64+0))+rsp],rdi
+	mov	QWORD[((64+8))+rsp],rsi
+	mov	QWORD[((64+16))+rsp],rdx
+	mov	QWORD[((64+24))+rsp],r11
+	movaps	XMMWORD[(64+32)+rsp],xmm6
+	movaps	XMMWORD[(64+48)+rsp],xmm7
+	movaps	XMMWORD[(64+64)+rsp],xmm8
+	movaps	XMMWORD[(64+80)+rsp],xmm9
+$L$prologue_avx:
+
+	vzeroupper
+	mov	eax,DWORD[rdi]
+	mov	ebx,DWORD[4+rdi]
+	mov	ecx,DWORD[8+rdi]
+	mov	edx,DWORD[12+rdi]
+	mov	r8d,DWORD[16+rdi]
+	mov	r9d,DWORD[20+rdi]
+	mov	r10d,DWORD[24+rdi]
+	mov	r11d,DWORD[28+rdi]
+	vmovdqa	xmm8,XMMWORD[((K256+512+32))]
+	vmovdqa	xmm9,XMMWORD[((K256+512+64))]
+	jmp	NEAR $L$loop_avx
+ALIGN	16
+$L$loop_avx:
+	vmovdqa	xmm7,XMMWORD[((K256+512))]
+	vmovdqu	xmm0,XMMWORD[rsi]
+	vmovdqu	xmm1,XMMWORD[16+rsi]
+	vmovdqu	xmm2,XMMWORD[32+rsi]
+	vmovdqu	xmm3,XMMWORD[48+rsi]
+	vpshufb	xmm0,xmm0,xmm7
+	lea	rbp,[K256]
+	vpshufb	xmm1,xmm1,xmm7
+	vpshufb	xmm2,xmm2,xmm7
+	vpaddd	xmm4,xmm0,XMMWORD[rbp]
+	vpshufb	xmm3,xmm3,xmm7
+	vpaddd	xmm5,xmm1,XMMWORD[32+rbp]
+	vpaddd	xmm6,xmm2,XMMWORD[64+rbp]
+	vpaddd	xmm7,xmm3,XMMWORD[96+rbp]
+	vmovdqa	XMMWORD[rsp],xmm4
+	mov	r14d,eax
+	vmovdqa	XMMWORD[16+rsp],xmm5
+	mov	edi,ebx
+	vmovdqa	XMMWORD[32+rsp],xmm6
+	xor	edi,ecx
+	vmovdqa	XMMWORD[48+rsp],xmm7
+	mov	r13d,r8d
+	jmp	NEAR $L$avx_00_47
+
+ALIGN	16
+$L$avx_00_47:
+	sub	rbp,-128
+	vpalignr	xmm4,xmm1,xmm0,4
+	shrd	r13d,r13d,14
+	mov	eax,r14d
+	mov	r12d,r9d
+	vpalignr	xmm7,xmm3,xmm2,4
+	shrd	r14d,r14d,9
+	xor	r13d,r8d
+	xor	r12d,r10d
+	vpsrld	xmm6,xmm4,7
+	shrd	r13d,r13d,5
+	xor	r14d,eax
+	and	r12d,r8d
+	vpaddd	xmm0,xmm0,xmm7
+	xor	r13d,r8d
+	add	r11d,DWORD[rsp]
+	mov	r15d,eax
+	vpsrld	xmm7,xmm4,3
+	xor	r12d,r10d
+	shrd	r14d,r14d,11
+	xor	r15d,ebx
+	vpslld	xmm5,xmm4,14
+	add	r11d,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	vpxor	xmm4,xmm7,xmm6
+	xor	r14d,eax
+	add	r11d,r13d
+	xor	edi,ebx
+	vpshufd	xmm7,xmm3,250
+	shrd	r14d,r14d,2
+	add	edx,r11d
+	add	r11d,edi
+	vpsrld	xmm6,xmm6,11
+	mov	r13d,edx
+	add	r14d,r11d
+	shrd	r13d,r13d,14
+	vpxor	xmm4,xmm4,xmm5
+	mov	r11d,r14d
+	mov	r12d,r8d
+	shrd	r14d,r14d,9
+	vpslld	xmm5,xmm5,11
+	xor	r13d,edx
+	xor	r12d,r9d
+	shrd	r13d,r13d,5
+	vpxor	xmm4,xmm4,xmm6
+	xor	r14d,r11d
+	and	r12d,edx
+	xor	r13d,edx
+	vpsrld	xmm6,xmm7,10
+	add	r10d,DWORD[4+rsp]
+	mov	edi,r11d
+	xor	r12d,r9d
+	vpxor	xmm4,xmm4,xmm5
+	shrd	r14d,r14d,11
+	xor	edi,eax
+	add	r10d,r12d
+	vpsrlq	xmm7,xmm7,17
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r11d
+	vpaddd	xmm0,xmm0,xmm4
+	add	r10d,r13d
+	xor	r15d,eax
+	shrd	r14d,r14d,2
+	vpxor	xmm6,xmm6,xmm7
+	add	ecx,r10d
+	add	r10d,r15d
+	mov	r13d,ecx
+	vpsrlq	xmm7,xmm7,2
+	add	r14d,r10d
+	shrd	r13d,r13d,14
+	mov	r10d,r14d
+	vpxor	xmm6,xmm6,xmm7
+	mov	r12d,edx
+	shrd	r14d,r14d,9
+	xor	r13d,ecx
+	vpshufb	xmm6,xmm6,xmm8
+	xor	r12d,r8d
+	shrd	r13d,r13d,5
+	xor	r14d,r10d
+	vpaddd	xmm0,xmm0,xmm6
+	and	r12d,ecx
+	xor	r13d,ecx
+	add	r9d,DWORD[8+rsp]
+	vpshufd	xmm7,xmm0,80
+	mov	r15d,r10d
+	xor	r12d,r8d
+	shrd	r14d,r14d,11
+	vpsrld	xmm6,xmm7,10
+	xor	r15d,r11d
+	add	r9d,r12d
+	shrd	r13d,r13d,6
+	vpsrlq	xmm7,xmm7,17
+	and	edi,r15d
+	xor	r14d,r10d
+	add	r9d,r13d
+	vpxor	xmm6,xmm6,xmm7
+	xor	edi,r11d
+	shrd	r14d,r14d,2
+	add	ebx,r9d
+	vpsrlq	xmm7,xmm7,2
+	add	r9d,edi
+	mov	r13d,ebx
+	add	r14d,r9d
+	vpxor	xmm6,xmm6,xmm7
+	shrd	r13d,r13d,14
+	mov	r9d,r14d
+	mov	r12d,ecx
+	vpshufb	xmm6,xmm6,xmm9
+	shrd	r14d,r14d,9
+	xor	r13d,ebx
+	xor	r12d,edx
+	vpaddd	xmm0,xmm0,xmm6
+	shrd	r13d,r13d,5
+	xor	r14d,r9d
+	and	r12d,ebx
+	vpaddd	xmm6,xmm0,XMMWORD[rbp]
+	xor	r13d,ebx
+	add	r8d,DWORD[12+rsp]
+	mov	edi,r9d
+	xor	r12d,edx
+	shrd	r14d,r14d,11
+	xor	edi,r10d
+	add	r8d,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r9d
+	add	r8d,r13d
+	xor	r15d,r10d
+	shrd	r14d,r14d,2
+	add	eax,r8d
+	add	r8d,r15d
+	mov	r13d,eax
+	add	r14d,r8d
+	vmovdqa	XMMWORD[rsp],xmm6
+	vpalignr	xmm4,xmm2,xmm1,4
+	shrd	r13d,r13d,14
+	mov	r8d,r14d
+	mov	r12d,ebx
+	vpalignr	xmm7,xmm0,xmm3,4
+	shrd	r14d,r14d,9
+	xor	r13d,eax
+	xor	r12d,ecx
+	vpsrld	xmm6,xmm4,7
+	shrd	r13d,r13d,5
+	xor	r14d,r8d
+	and	r12d,eax
+	vpaddd	xmm1,xmm1,xmm7
+	xor	r13d,eax
+	add	edx,DWORD[16+rsp]
+	mov	r15d,r8d
+	vpsrld	xmm7,xmm4,3
+	xor	r12d,ecx
+	shrd	r14d,r14d,11
+	xor	r15d,r9d
+	vpslld	xmm5,xmm4,14
+	add	edx,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	vpxor	xmm4,xmm7,xmm6
+	xor	r14d,r8d
+	add	edx,r13d
+	xor	edi,r9d
+	vpshufd	xmm7,xmm0,250
+	shrd	r14d,r14d,2
+	add	r11d,edx
+	add	edx,edi
+	vpsrld	xmm6,xmm6,11
+	mov	r13d,r11d
+	add	r14d,edx
+	shrd	r13d,r13d,14
+	vpxor	xmm4,xmm4,xmm5
+	mov	edx,r14d
+	mov	r12d,eax
+	shrd	r14d,r14d,9
+	vpslld	xmm5,xmm5,11
+	xor	r13d,r11d
+	xor	r12d,ebx
+	shrd	r13d,r13d,5
+	vpxor	xmm4,xmm4,xmm6
+	xor	r14d,edx
+	and	r12d,r11d
+	xor	r13d,r11d
+	vpsrld	xmm6,xmm7,10
+	add	ecx,DWORD[20+rsp]
+	mov	edi,edx
+	xor	r12d,ebx
+	vpxor	xmm4,xmm4,xmm5
+	shrd	r14d,r14d,11
+	xor	edi,r8d
+	add	ecx,r12d
+	vpsrlq	xmm7,xmm7,17
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,edx
+	vpaddd	xmm1,xmm1,xmm4
+	add	ecx,r13d
+	xor	r15d,r8d
+	shrd	r14d,r14d,2
+	vpxor	xmm6,xmm6,xmm7
+	add	r10d,ecx
+	add	ecx,r15d
+	mov	r13d,r10d
+	vpsrlq	xmm7,xmm7,2
+	add	r14d,ecx
+	shrd	r13d,r13d,14
+	mov	ecx,r14d
+	vpxor	xmm6,xmm6,xmm7
+	mov	r12d,r11d
+	shrd	r14d,r14d,9
+	xor	r13d,r10d
+	vpshufb	xmm6,xmm6,xmm8
+	xor	r12d,eax
+	shrd	r13d,r13d,5
+	xor	r14d,ecx
+	vpaddd	xmm1,xmm1,xmm6
+	and	r12d,r10d
+	xor	r13d,r10d
+	add	ebx,DWORD[24+rsp]
+	vpshufd	xmm7,xmm1,80
+	mov	r15d,ecx
+	xor	r12d,eax
+	shrd	r14d,r14d,11
+	vpsrld	xmm6,xmm7,10
+	xor	r15d,edx
+	add	ebx,r12d
+	shrd	r13d,r13d,6
+	vpsrlq	xmm7,xmm7,17
+	and	edi,r15d
+	xor	r14d,ecx
+	add	ebx,r13d
+	vpxor	xmm6,xmm6,xmm7
+	xor	edi,edx
+	shrd	r14d,r14d,2
+	add	r9d,ebx
+	vpsrlq	xmm7,xmm7,2
+	add	ebx,edi
+	mov	r13d,r9d
+	add	r14d,ebx
+	vpxor	xmm6,xmm6,xmm7
+	shrd	r13d,r13d,14
+	mov	ebx,r14d
+	mov	r12d,r10d
+	vpshufb	xmm6,xmm6,xmm9
+	shrd	r14d,r14d,9
+	xor	r13d,r9d
+	xor	r12d,r11d
+	vpaddd	xmm1,xmm1,xmm6
+	shrd	r13d,r13d,5
+	xor	r14d,ebx
+	and	r12d,r9d
+	vpaddd	xmm6,xmm1,XMMWORD[32+rbp]
+	xor	r13d,r9d
+	add	eax,DWORD[28+rsp]
+	mov	edi,ebx
+	xor	r12d,r11d
+	shrd	r14d,r14d,11
+	xor	edi,ecx
+	add	eax,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,ebx
+	add	eax,r13d
+	xor	r15d,ecx
+	shrd	r14d,r14d,2
+	add	r8d,eax
+	add	eax,r15d
+	mov	r13d,r8d
+	add	r14d,eax
+	vmovdqa	XMMWORD[16+rsp],xmm6
+	vpalignr	xmm4,xmm3,xmm2,4
+	shrd	r13d,r13d,14
+	mov	eax,r14d
+	mov	r12d,r9d
+	vpalignr	xmm7,xmm1,xmm0,4
+	shrd	r14d,r14d,9
+	xor	r13d,r8d
+	xor	r12d,r10d
+	vpsrld	xmm6,xmm4,7
+	shrd	r13d,r13d,5
+	xor	r14d,eax
+	and	r12d,r8d
+	vpaddd	xmm2,xmm2,xmm7
+	xor	r13d,r8d
+	add	r11d,DWORD[32+rsp]
+	mov	r15d,eax
+	vpsrld	xmm7,xmm4,3
+	xor	r12d,r10d
+	shrd	r14d,r14d,11
+	xor	r15d,ebx
+	vpslld	xmm5,xmm4,14
+	add	r11d,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	vpxor	xmm4,xmm7,xmm6
+	xor	r14d,eax
+	add	r11d,r13d
+	xor	edi,ebx
+	vpshufd	xmm7,xmm1,250
+	shrd	r14d,r14d,2
+	add	edx,r11d
+	add	r11d,edi
+	vpsrld	xmm6,xmm6,11
+	mov	r13d,edx
+	add	r14d,r11d
+	shrd	r13d,r13d,14
+	vpxor	xmm4,xmm4,xmm5
+	mov	r11d,r14d
+	mov	r12d,r8d
+	shrd	r14d,r14d,9
+	vpslld	xmm5,xmm5,11
+	xor	r13d,edx
+	xor	r12d,r9d
+	shrd	r13d,r13d,5
+	vpxor	xmm4,xmm4,xmm6
+	xor	r14d,r11d
+	and	r12d,edx
+	xor	r13d,edx
+	vpsrld	xmm6,xmm7,10
+	add	r10d,DWORD[36+rsp]
+	mov	edi,r11d
+	xor	r12d,r9d
+	vpxor	xmm4,xmm4,xmm5
+	shrd	r14d,r14d,11
+	xor	edi,eax
+	add	r10d,r12d
+	vpsrlq	xmm7,xmm7,17
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r11d
+	vpaddd	xmm2,xmm2,xmm4
+	add	r10d,r13d
+	xor	r15d,eax
+	shrd	r14d,r14d,2
+	vpxor	xmm6,xmm6,xmm7
+	add	ecx,r10d
+	add	r10d,r15d
+	mov	r13d,ecx
+	vpsrlq	xmm7,xmm7,2
+	add	r14d,r10d
+	shrd	r13d,r13d,14
+	mov	r10d,r14d
+	vpxor	xmm6,xmm6,xmm7
+	mov	r12d,edx
+	shrd	r14d,r14d,9
+	xor	r13d,ecx
+	vpshufb	xmm6,xmm6,xmm8
+	xor	r12d,r8d
+	shrd	r13d,r13d,5
+	xor	r14d,r10d
+	vpaddd	xmm2,xmm2,xmm6
+	and	r12d,ecx
+	xor	r13d,ecx
+	add	r9d,DWORD[40+rsp]
+	vpshufd	xmm7,xmm2,80
+	mov	r15d,r10d
+	xor	r12d,r8d
+	shrd	r14d,r14d,11
+	vpsrld	xmm6,xmm7,10
+	xor	r15d,r11d
+	add	r9d,r12d
+	shrd	r13d,r13d,6
+	vpsrlq	xmm7,xmm7,17
+	and	edi,r15d
+	xor	r14d,r10d
+	add	r9d,r13d
+	vpxor	xmm6,xmm6,xmm7
+	xor	edi,r11d
+	shrd	r14d,r14d,2
+	add	ebx,r9d
+	vpsrlq	xmm7,xmm7,2
+	add	r9d,edi
+	mov	r13d,ebx
+	add	r14d,r9d
+	vpxor	xmm6,xmm6,xmm7
+	shrd	r13d,r13d,14
+	mov	r9d,r14d
+	mov	r12d,ecx
+	vpshufb	xmm6,xmm6,xmm9
+	shrd	r14d,r14d,9
+	xor	r13d,ebx
+	xor	r12d,edx
+	vpaddd	xmm2,xmm2,xmm6
+	shrd	r13d,r13d,5
+	xor	r14d,r9d
+	and	r12d,ebx
+	vpaddd	xmm6,xmm2,XMMWORD[64+rbp]
+	xor	r13d,ebx
+	add	r8d,DWORD[44+rsp]
+	mov	edi,r9d
+	xor	r12d,edx
+	shrd	r14d,r14d,11
+	xor	edi,r10d
+	add	r8d,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r9d
+	add	r8d,r13d
+	xor	r15d,r10d
+	shrd	r14d,r14d,2
+	add	eax,r8d
+	add	r8d,r15d
+	mov	r13d,eax
+	add	r14d,r8d
+	vmovdqa	XMMWORD[32+rsp],xmm6
+	vpalignr	xmm4,xmm0,xmm3,4
+	shrd	r13d,r13d,14
+	mov	r8d,r14d
+	mov	r12d,ebx
+	vpalignr	xmm7,xmm2,xmm1,4
+	shrd	r14d,r14d,9
+	xor	r13d,eax
+	xor	r12d,ecx
+	vpsrld	xmm6,xmm4,7
+	shrd	r13d,r13d,5
+	xor	r14d,r8d
+	and	r12d,eax
+	vpaddd	xmm3,xmm3,xmm7
+	xor	r13d,eax
+	add	edx,DWORD[48+rsp]
+	mov	r15d,r8d
+	vpsrld	xmm7,xmm4,3
+	xor	r12d,ecx
+	shrd	r14d,r14d,11
+	xor	r15d,r9d
+	vpslld	xmm5,xmm4,14
+	add	edx,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	vpxor	xmm4,xmm7,xmm6
+	xor	r14d,r8d
+	add	edx,r13d
+	xor	edi,r9d
+	vpshufd	xmm7,xmm2,250
+	shrd	r14d,r14d,2
+	add	r11d,edx
+	add	edx,edi
+	vpsrld	xmm6,xmm6,11
+	mov	r13d,r11d
+	add	r14d,edx
+	shrd	r13d,r13d,14
+	vpxor	xmm4,xmm4,xmm5
+	mov	edx,r14d
+	mov	r12d,eax
+	shrd	r14d,r14d,9
+	vpslld	xmm5,xmm5,11
+	xor	r13d,r11d
+	xor	r12d,ebx
+	shrd	r13d,r13d,5
+	vpxor	xmm4,xmm4,xmm6
+	xor	r14d,edx
+	and	r12d,r11d
+	xor	r13d,r11d
+	vpsrld	xmm6,xmm7,10
+	add	ecx,DWORD[52+rsp]
+	mov	edi,edx
+	xor	r12d,ebx
+	vpxor	xmm4,xmm4,xmm5
+	shrd	r14d,r14d,11
+	xor	edi,r8d
+	add	ecx,r12d
+	vpsrlq	xmm7,xmm7,17
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,edx
+	vpaddd	xmm3,xmm3,xmm4
+	add	ecx,r13d
+	xor	r15d,r8d
+	shrd	r14d,r14d,2
+	vpxor	xmm6,xmm6,xmm7
+	add	r10d,ecx
+	add	ecx,r15d
+	mov	r13d,r10d
+	vpsrlq	xmm7,xmm7,2
+	add	r14d,ecx
+	shrd	r13d,r13d,14
+	mov	ecx,r14d
+	vpxor	xmm6,xmm6,xmm7
+	mov	r12d,r11d
+	shrd	r14d,r14d,9
+	xor	r13d,r10d
+	vpshufb	xmm6,xmm6,xmm8
+	xor	r12d,eax
+	shrd	r13d,r13d,5
+	xor	r14d,ecx
+	vpaddd	xmm3,xmm3,xmm6
+	and	r12d,r10d
+	xor	r13d,r10d
+	add	ebx,DWORD[56+rsp]
+	vpshufd	xmm7,xmm3,80
+	mov	r15d,ecx
+	xor	r12d,eax
+	shrd	r14d,r14d,11
+	vpsrld	xmm6,xmm7,10
+	xor	r15d,edx
+	add	ebx,r12d
+	shrd	r13d,r13d,6
+	vpsrlq	xmm7,xmm7,17
+	and	edi,r15d
+	xor	r14d,ecx
+	add	ebx,r13d
+	vpxor	xmm6,xmm6,xmm7
+	xor	edi,edx
+	shrd	r14d,r14d,2
+	add	r9d,ebx
+	vpsrlq	xmm7,xmm7,2
+	add	ebx,edi
+	mov	r13d,r9d
+	add	r14d,ebx
+	vpxor	xmm6,xmm6,xmm7
+	shrd	r13d,r13d,14
+	mov	ebx,r14d
+	mov	r12d,r10d
+	vpshufb	xmm6,xmm6,xmm9
+	shrd	r14d,r14d,9
+	xor	r13d,r9d
+	xor	r12d,r11d
+	vpaddd	xmm3,xmm3,xmm6
+	shrd	r13d,r13d,5
+	xor	r14d,ebx
+	and	r12d,r9d
+	vpaddd	xmm6,xmm3,XMMWORD[96+rbp]
+	xor	r13d,r9d
+	add	eax,DWORD[60+rsp]
+	mov	edi,ebx
+	xor	r12d,r11d
+	shrd	r14d,r14d,11
+	xor	edi,ecx
+	add	eax,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,ebx
+	add	eax,r13d
+	xor	r15d,ecx
+	shrd	r14d,r14d,2
+	add	r8d,eax
+	add	eax,r15d
+	mov	r13d,r8d
+	add	r14d,eax
+	vmovdqa	XMMWORD[48+rsp],xmm6
+	cmp	BYTE[131+rbp],0
+	jne	NEAR $L$avx_00_47
+	shrd	r13d,r13d,14
+	mov	eax,r14d
+	mov	r12d,r9d
+	shrd	r14d,r14d,9
+	xor	r13d,r8d
+	xor	r12d,r10d
+	shrd	r13d,r13d,5
+	xor	r14d,eax
+	and	r12d,r8d
+	xor	r13d,r8d
+	add	r11d,DWORD[rsp]
+	mov	r15d,eax
+	xor	r12d,r10d
+	shrd	r14d,r14d,11
+	xor	r15d,ebx
+	add	r11d,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,eax
+	add	r11d,r13d
+	xor	edi,ebx
+	shrd	r14d,r14d,2
+	add	edx,r11d
+	add	r11d,edi
+	mov	r13d,edx
+	add	r14d,r11d
+	shrd	r13d,r13d,14
+	mov	r11d,r14d
+	mov	r12d,r8d
+	shrd	r14d,r14d,9
+	xor	r13d,edx
+	xor	r12d,r9d
+	shrd	r13d,r13d,5
+	xor	r14d,r11d
+	and	r12d,edx
+	xor	r13d,edx
+	add	r10d,DWORD[4+rsp]
+	mov	edi,r11d
+	xor	r12d,r9d
+	shrd	r14d,r14d,11
+	xor	edi,eax
+	add	r10d,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r11d
+	add	r10d,r13d
+	xor	r15d,eax
+	shrd	r14d,r14d,2
+	add	ecx,r10d
+	add	r10d,r15d
+	mov	r13d,ecx
+	add	r14d,r10d
+	shrd	r13d,r13d,14
+	mov	r10d,r14d
+	mov	r12d,edx
+	shrd	r14d,r14d,9
+	xor	r13d,ecx
+	xor	r12d,r8d
+	shrd	r13d,r13d,5
+	xor	r14d,r10d
+	and	r12d,ecx
+	xor	r13d,ecx
+	add	r9d,DWORD[8+rsp]
+	mov	r15d,r10d
+	xor	r12d,r8d
+	shrd	r14d,r14d,11
+	xor	r15d,r11d
+	add	r9d,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,r10d
+	add	r9d,r13d
+	xor	edi,r11d
+	shrd	r14d,r14d,2
+	add	ebx,r9d
+	add	r9d,edi
+	mov	r13d,ebx
+	add	r14d,r9d
+	shrd	r13d,r13d,14
+	mov	r9d,r14d
+	mov	r12d,ecx
+	shrd	r14d,r14d,9
+	xor	r13d,ebx
+	xor	r12d,edx
+	shrd	r13d,r13d,5
+	xor	r14d,r9d
+	and	r12d,ebx
+	xor	r13d,ebx
+	add	r8d,DWORD[12+rsp]
+	mov	edi,r9d
+	xor	r12d,edx
+	shrd	r14d,r14d,11
+	xor	edi,r10d
+	add	r8d,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r9d
+	add	r8d,r13d
+	xor	r15d,r10d
+	shrd	r14d,r14d,2
+	add	eax,r8d
+	add	r8d,r15d
+	mov	r13d,eax
+	add	r14d,r8d
+	shrd	r13d,r13d,14
+	mov	r8d,r14d
+	mov	r12d,ebx
+	shrd	r14d,r14d,9
+	xor	r13d,eax
+	xor	r12d,ecx
+	shrd	r13d,r13d,5
+	xor	r14d,r8d
+	and	r12d,eax
+	xor	r13d,eax
+	add	edx,DWORD[16+rsp]
+	mov	r15d,r8d
+	xor	r12d,ecx
+	shrd	r14d,r14d,11
+	xor	r15d,r9d
+	add	edx,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,r8d
+	add	edx,r13d
+	xor	edi,r9d
+	shrd	r14d,r14d,2
+	add	r11d,edx
+	add	edx,edi
+	mov	r13d,r11d
+	add	r14d,edx
+	shrd	r13d,r13d,14
+	mov	edx,r14d
+	mov	r12d,eax
+	shrd	r14d,r14d,9
+	xor	r13d,r11d
+	xor	r12d,ebx
+	shrd	r13d,r13d,5
+	xor	r14d,edx
+	and	r12d,r11d
+	xor	r13d,r11d
+	add	ecx,DWORD[20+rsp]
+	mov	edi,edx
+	xor	r12d,ebx
+	shrd	r14d,r14d,11
+	xor	edi,r8d
+	add	ecx,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,edx
+	add	ecx,r13d
+	xor	r15d,r8d
+	shrd	r14d,r14d,2
+	add	r10d,ecx
+	add	ecx,r15d
+	mov	r13d,r10d
+	add	r14d,ecx
+	shrd	r13d,r13d,14
+	mov	ecx,r14d
+	mov	r12d,r11d
+	shrd	r14d,r14d,9
+	xor	r13d,r10d
+	xor	r12d,eax
+	shrd	r13d,r13d,5
+	xor	r14d,ecx
+	and	r12d,r10d
+	xor	r13d,r10d
+	add	ebx,DWORD[24+rsp]
+	mov	r15d,ecx
+	xor	r12d,eax
+	shrd	r14d,r14d,11
+	xor	r15d,edx
+	add	ebx,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,ecx
+	add	ebx,r13d
+	xor	edi,edx
+	shrd	r14d,r14d,2
+	add	r9d,ebx
+	add	ebx,edi
+	mov	r13d,r9d
+	add	r14d,ebx
+	shrd	r13d,r13d,14
+	mov	ebx,r14d
+	mov	r12d,r10d
+	shrd	r14d,r14d,9
+	xor	r13d,r9d
+	xor	r12d,r11d
+	shrd	r13d,r13d,5
+	xor	r14d,ebx
+	and	r12d,r9d
+	xor	r13d,r9d
+	add	eax,DWORD[28+rsp]
+	mov	edi,ebx
+	xor	r12d,r11d
+	shrd	r14d,r14d,11
+	xor	edi,ecx
+	add	eax,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,ebx
+	add	eax,r13d
+	xor	r15d,ecx
+	shrd	r14d,r14d,2
+	add	r8d,eax
+	add	eax,r15d
+	mov	r13d,r8d
+	add	r14d,eax
+	shrd	r13d,r13d,14
+	mov	eax,r14d
+	mov	r12d,r9d
+	shrd	r14d,r14d,9
+	xor	r13d,r8d
+	xor	r12d,r10d
+	shrd	r13d,r13d,5
+	xor	r14d,eax
+	and	r12d,r8d
+	xor	r13d,r8d
+	add	r11d,DWORD[32+rsp]
+	mov	r15d,eax
+	xor	r12d,r10d
+	shrd	r14d,r14d,11
+	xor	r15d,ebx
+	add	r11d,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,eax
+	add	r11d,r13d
+	xor	edi,ebx
+	shrd	r14d,r14d,2
+	add	edx,r11d
+	add	r11d,edi
+	mov	r13d,edx
+	add	r14d,r11d
+	shrd	r13d,r13d,14
+	mov	r11d,r14d
+	mov	r12d,r8d
+	shrd	r14d,r14d,9
+	xor	r13d,edx
+	xor	r12d,r9d
+	shrd	r13d,r13d,5
+	xor	r14d,r11d
+	and	r12d,edx
+	xor	r13d,edx
+	add	r10d,DWORD[36+rsp]
+	mov	edi,r11d
+	xor	r12d,r9d
+	shrd	r14d,r14d,11
+	xor	edi,eax
+	add	r10d,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r11d
+	add	r10d,r13d
+	xor	r15d,eax
+	shrd	r14d,r14d,2
+	add	ecx,r10d
+	add	r10d,r15d
+	mov	r13d,ecx
+	add	r14d,r10d
+	shrd	r13d,r13d,14
+	mov	r10d,r14d
+	mov	r12d,edx
+	shrd	r14d,r14d,9
+	xor	r13d,ecx
+	xor	r12d,r8d
+	shrd	r13d,r13d,5
+	xor	r14d,r10d
+	and	r12d,ecx
+	xor	r13d,ecx
+	add	r9d,DWORD[40+rsp]
+	mov	r15d,r10d
+	xor	r12d,r8d
+	shrd	r14d,r14d,11
+	xor	r15d,r11d
+	add	r9d,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,r10d
+	add	r9d,r13d
+	xor	edi,r11d
+	shrd	r14d,r14d,2
+	add	ebx,r9d
+	add	r9d,edi
+	mov	r13d,ebx
+	add	r14d,r9d
+	shrd	r13d,r13d,14
+	mov	r9d,r14d
+	mov	r12d,ecx
+	shrd	r14d,r14d,9
+	xor	r13d,ebx
+	xor	r12d,edx
+	shrd	r13d,r13d,5
+	xor	r14d,r9d
+	and	r12d,ebx
+	xor	r13d,ebx
+	add	r8d,DWORD[44+rsp]
+	mov	edi,r9d
+	xor	r12d,edx
+	shrd	r14d,r14d,11
+	xor	edi,r10d
+	add	r8d,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,r9d
+	add	r8d,r13d
+	xor	r15d,r10d
+	shrd	r14d,r14d,2
+	add	eax,r8d
+	add	r8d,r15d
+	mov	r13d,eax
+	add	r14d,r8d
+	shrd	r13d,r13d,14
+	mov	r8d,r14d
+	mov	r12d,ebx
+	shrd	r14d,r14d,9
+	xor	r13d,eax
+	xor	r12d,ecx
+	shrd	r13d,r13d,5
+	xor	r14d,r8d
+	and	r12d,eax
+	xor	r13d,eax
+	add	edx,DWORD[48+rsp]
+	mov	r15d,r8d
+	xor	r12d,ecx
+	shrd	r14d,r14d,11
+	xor	r15d,r9d
+	add	edx,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,r8d
+	add	edx,r13d
+	xor	edi,r9d
+	shrd	r14d,r14d,2
+	add	r11d,edx
+	add	edx,edi
+	mov	r13d,r11d
+	add	r14d,edx
+	shrd	r13d,r13d,14
+	mov	edx,r14d
+	mov	r12d,eax
+	shrd	r14d,r14d,9
+	xor	r13d,r11d
+	xor	r12d,ebx
+	shrd	r13d,r13d,5
+	xor	r14d,edx
+	and	r12d,r11d
+	xor	r13d,r11d
+	add	ecx,DWORD[52+rsp]
+	mov	edi,edx
+	xor	r12d,ebx
+	shrd	r14d,r14d,11
+	xor	edi,r8d
+	add	ecx,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,edx
+	add	ecx,r13d
+	xor	r15d,r8d
+	shrd	r14d,r14d,2
+	add	r10d,ecx
+	add	ecx,r15d
+	mov	r13d,r10d
+	add	r14d,ecx
+	shrd	r13d,r13d,14
+	mov	ecx,r14d
+	mov	r12d,r11d
+	shrd	r14d,r14d,9
+	xor	r13d,r10d
+	xor	r12d,eax
+	shrd	r13d,r13d,5
+	xor	r14d,ecx
+	and	r12d,r10d
+	xor	r13d,r10d
+	add	ebx,DWORD[56+rsp]
+	mov	r15d,ecx
+	xor	r12d,eax
+	shrd	r14d,r14d,11
+	xor	r15d,edx
+	add	ebx,r12d
+	shrd	r13d,r13d,6
+	and	edi,r15d
+	xor	r14d,ecx
+	add	ebx,r13d
+	xor	edi,edx
+	shrd	r14d,r14d,2
+	add	r9d,ebx
+	add	ebx,edi
+	mov	r13d,r9d
+	add	r14d,ebx
+	shrd	r13d,r13d,14
+	mov	ebx,r14d
+	mov	r12d,r10d
+	shrd	r14d,r14d,9
+	xor	r13d,r9d
+	xor	r12d,r11d
+	shrd	r13d,r13d,5
+	xor	r14d,ebx
+	and	r12d,r9d
+	xor	r13d,r9d
+	add	eax,DWORD[60+rsp]
+	mov	edi,ebx
+	xor	r12d,r11d
+	shrd	r14d,r14d,11
+	xor	edi,ecx
+	add	eax,r12d
+	shrd	r13d,r13d,6
+	and	r15d,edi
+	xor	r14d,ebx
+	add	eax,r13d
+	xor	r15d,ecx
+	shrd	r14d,r14d,2
+	add	r8d,eax
+	add	eax,r15d
+	mov	r13d,r8d
+	add	r14d,eax
+	mov	rdi,QWORD[((64+0))+rsp]
+	mov	eax,r14d
+
+	add	eax,DWORD[rdi]
+	lea	rsi,[64+rsi]
+	add	ebx,DWORD[4+rdi]
+	add	ecx,DWORD[8+rdi]
+	add	edx,DWORD[12+rdi]
+	add	r8d,DWORD[16+rdi]
+	add	r9d,DWORD[20+rdi]
+	add	r10d,DWORD[24+rdi]
+	add	r11d,DWORD[28+rdi]
+
+	cmp	rsi,QWORD[((64+16))+rsp]
+
+	mov	DWORD[rdi],eax
+	mov	DWORD[4+rdi],ebx
+	mov	DWORD[8+rdi],ecx
+	mov	DWORD[12+rdi],edx
+	mov	DWORD[16+rdi],r8d
+	mov	DWORD[20+rdi],r9d
+	mov	DWORD[24+rdi],r10d
+	mov	DWORD[28+rdi],r11d
+	jb	NEAR $L$loop_avx
+
+	mov	rsi,QWORD[((64+24))+rsp]
+	vzeroupper
+	movaps	xmm6,XMMWORD[((64+32))+rsp]
+	movaps	xmm7,XMMWORD[((64+48))+rsp]
+	movaps	xmm8,XMMWORD[((64+64))+rsp]
+	movaps	xmm9,XMMWORD[((64+80))+rsp]
+	mov	r15,QWORD[rsi]
+	mov	r14,QWORD[8+rsi]
+	mov	r13,QWORD[16+rsi]
+	mov	r12,QWORD[24+rsi]
+	mov	rbp,QWORD[32+rsi]
+	mov	rbx,QWORD[40+rsi]
+	lea	rsp,[48+rsi]
+$L$epilogue_avx:
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_sha256_block_data_order_avx:
 EXTERN	__imp_RtlVirtualUnwind
 
 ALIGN	16
@@ -2982,6 +4063,9 @@
 	DD	$L$SEH_begin_sha256_block_data_order_ssse3 wrt ..imagebase
 	DD	$L$SEH_end_sha256_block_data_order_ssse3 wrt ..imagebase
 	DD	$L$SEH_info_sha256_block_data_order_ssse3 wrt ..imagebase
+	DD	$L$SEH_begin_sha256_block_data_order_avx wrt ..imagebase
+	DD	$L$SEH_end_sha256_block_data_order_avx wrt ..imagebase
+	DD	$L$SEH_info_sha256_block_data_order_avx wrt ..imagebase
 section	.xdata rdata align=8
 ALIGN	8
 $L$SEH_info_sha256_block_data_order:
@@ -2992,3 +4076,7 @@
 DB	9,0,0,0
 	DD	se_handler wrt ..imagebase
 	DD	$L$prologue_ssse3 wrt ..imagebase,$L$epilogue_ssse3 wrt ..imagebase
+$L$SEH_info_sha256_block_data_order_avx:
+DB	9,0,0,0
+	DD	se_handler wrt ..imagebase
+	DD	$L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase
diff --git a/third_party/boringssl/win-x86_64/crypto/sha/sha512-x86_64.asm b/third_party/boringssl/win-x86_64/crypto/sha/sha512-x86_64.asm
index b76cc0e..71449cd 100644
--- a/third_party/boringssl/win-x86_64/crypto/sha/sha512-x86_64.asm
+++ b/third_party/boringssl/win-x86_64/crypto/sha/sha512-x86_64.asm
@@ -19,6 +19,17 @@
 	mov	rdx,r8
 
 
+	lea	r11,[OPENSSL_ia32cap_P]
+	mov	r9d,DWORD[r11]
+	mov	r10d,DWORD[4+r11]
+	mov	r11d,DWORD[8+r11]
+	test	r10d,2048
+	jnz	NEAR $L$xop_shortcut
+	and	r9d,1073741824
+	and	r10d,268435968
+	or	r10d,r9d
+	cmp	r10d,1342177792
+	je	NEAR $L$avx_shortcut
 	push	rbx
 	push	rbp
 	push	r12
@@ -1801,6 +1812,2282 @@
 DB	52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121
 DB	32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46
 DB	111,114,103,62,0
+
+ALIGN	64
+sha512_block_data_order_xop:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_sha512_block_data_order_xop:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+$L$xop_shortcut:
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	mov	r11,rsp
+	shl	rdx,4
+	sub	rsp,256
+	lea	rdx,[rdx*8+rsi]
+	and	rsp,-64
+	mov	QWORD[((128+0))+rsp],rdi
+	mov	QWORD[((128+8))+rsp],rsi
+	mov	QWORD[((128+16))+rsp],rdx
+	mov	QWORD[((128+24))+rsp],r11
+	movaps	XMMWORD[(128+32)+rsp],xmm6
+	movaps	XMMWORD[(128+48)+rsp],xmm7
+	movaps	XMMWORD[(128+64)+rsp],xmm8
+	movaps	XMMWORD[(128+80)+rsp],xmm9
+	movaps	XMMWORD[(128+96)+rsp],xmm10
+	movaps	XMMWORD[(128+112)+rsp],xmm11
+$L$prologue_xop:
+
+	vzeroupper
+	mov	rax,QWORD[rdi]
+	mov	rbx,QWORD[8+rdi]
+	mov	rcx,QWORD[16+rdi]
+	mov	rdx,QWORD[24+rdi]
+	mov	r8,QWORD[32+rdi]
+	mov	r9,QWORD[40+rdi]
+	mov	r10,QWORD[48+rdi]
+	mov	r11,QWORD[56+rdi]
+	jmp	NEAR $L$loop_xop
+ALIGN	16
+$L$loop_xop:
+	vmovdqa	xmm11,XMMWORD[((K512+1280))]
+	vmovdqu	xmm0,XMMWORD[rsi]
+	lea	rbp,[((K512+128))]
+	vmovdqu	xmm1,XMMWORD[16+rsi]
+	vmovdqu	xmm2,XMMWORD[32+rsi]
+	vpshufb	xmm0,xmm0,xmm11
+	vmovdqu	xmm3,XMMWORD[48+rsi]
+	vpshufb	xmm1,xmm1,xmm11
+	vmovdqu	xmm4,XMMWORD[64+rsi]
+	vpshufb	xmm2,xmm2,xmm11
+	vmovdqu	xmm5,XMMWORD[80+rsi]
+	vpshufb	xmm3,xmm3,xmm11
+	vmovdqu	xmm6,XMMWORD[96+rsi]
+	vpshufb	xmm4,xmm4,xmm11
+	vmovdqu	xmm7,XMMWORD[112+rsi]
+	vpshufb	xmm5,xmm5,xmm11
+	vpaddq	xmm8,xmm0,XMMWORD[((-128))+rbp]
+	vpshufb	xmm6,xmm6,xmm11
+	vpaddq	xmm9,xmm1,XMMWORD[((-96))+rbp]
+	vpshufb	xmm7,xmm7,xmm11
+	vpaddq	xmm10,xmm2,XMMWORD[((-64))+rbp]
+	vpaddq	xmm11,xmm3,XMMWORD[((-32))+rbp]
+	vmovdqa	XMMWORD[rsp],xmm8
+	vpaddq	xmm8,xmm4,XMMWORD[rbp]
+	vmovdqa	XMMWORD[16+rsp],xmm9
+	vpaddq	xmm9,xmm5,XMMWORD[32+rbp]
+	vmovdqa	XMMWORD[32+rsp],xmm10
+	vpaddq	xmm10,xmm6,XMMWORD[64+rbp]
+	vmovdqa	XMMWORD[48+rsp],xmm11
+	vpaddq	xmm11,xmm7,XMMWORD[96+rbp]
+	vmovdqa	XMMWORD[64+rsp],xmm8
+	mov	r14,rax
+	vmovdqa	XMMWORD[80+rsp],xmm9
+	mov	rdi,rbx
+	vmovdqa	XMMWORD[96+rsp],xmm10
+	xor	rdi,rcx
+	vmovdqa	XMMWORD[112+rsp],xmm11
+	mov	r13,r8
+	jmp	NEAR $L$xop_00_47
+
+ALIGN	16
+$L$xop_00_47:
+	add	rbp,256
+	vpalignr	xmm8,xmm1,xmm0,8
+	ror	r13,23
+	mov	rax,r14
+	vpalignr	xmm11,xmm5,xmm4,8
+	mov	r12,r9
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,r8
+	xor	r12,r10
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,rax
+	vpaddq	xmm0,xmm0,xmm11
+	and	r12,r8
+	xor	r13,r8
+	add	r11,QWORD[rsp]
+	mov	r15,rax
+DB	143,72,120,195,209,7
+	xor	r12,r10
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,rbx
+	add	r11,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,223,3
+	xor	r14,rax
+	add	r11,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rbx
+	ror	r14,28
+	vpsrlq	xmm10,xmm7,6
+	add	rdx,r11
+	add	r11,rdi
+	vpaddq	xmm0,xmm0,xmm8
+	mov	r13,rdx
+	add	r14,r11
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	r11,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,r8
+	ror	r14,5
+	xor	r13,rdx
+	xor	r12,r9
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,r11
+	and	r12,rdx
+	xor	r13,rdx
+	vpaddq	xmm0,xmm0,xmm11
+	add	r10,QWORD[8+rsp]
+	mov	rdi,r11
+	xor	r12,r9
+	ror	r14,6
+	vpaddq	xmm10,xmm0,XMMWORD[((-128))+rbp]
+	xor	rdi,rax
+	add	r10,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r11
+	add	r10,r13
+	xor	r15,rax
+	ror	r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	vmovdqa	XMMWORD[rsp],xmm10
+	vpalignr	xmm8,xmm2,xmm1,8
+	ror	r13,23
+	mov	r10,r14
+	vpalignr	xmm11,xmm6,xmm5,8
+	mov	r12,rdx
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,rcx
+	xor	r12,r8
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,r10
+	vpaddq	xmm1,xmm1,xmm11
+	and	r12,rcx
+	xor	r13,rcx
+	add	r9,QWORD[16+rsp]
+	mov	r15,r10
+DB	143,72,120,195,209,7
+	xor	r12,r8
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,r11
+	add	r9,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,216,3
+	xor	r14,r10
+	add	r9,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r11
+	ror	r14,28
+	vpsrlq	xmm10,xmm0,6
+	add	rbx,r9
+	add	r9,rdi
+	vpaddq	xmm1,xmm1,xmm8
+	mov	r13,rbx
+	add	r14,r9
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	r9,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,rcx
+	ror	r14,5
+	xor	r13,rbx
+	xor	r12,rdx
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,r9
+	and	r12,rbx
+	xor	r13,rbx
+	vpaddq	xmm1,xmm1,xmm11
+	add	r8,QWORD[24+rsp]
+	mov	rdi,r9
+	xor	r12,rdx
+	ror	r14,6
+	vpaddq	xmm10,xmm1,XMMWORD[((-96))+rbp]
+	xor	rdi,r10
+	add	r8,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r9
+	add	r8,r13
+	xor	r15,r10
+	ror	r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	vmovdqa	XMMWORD[16+rsp],xmm10
+	vpalignr	xmm8,xmm3,xmm2,8
+	ror	r13,23
+	mov	r8,r14
+	vpalignr	xmm11,xmm7,xmm6,8
+	mov	r12,rbx
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,rax
+	xor	r12,rcx
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,r8
+	vpaddq	xmm2,xmm2,xmm11
+	and	r12,rax
+	xor	r13,rax
+	add	rdx,QWORD[32+rsp]
+	mov	r15,r8
+DB	143,72,120,195,209,7
+	xor	r12,rcx
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,r9
+	add	rdx,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,217,3
+	xor	r14,r8
+	add	rdx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r9
+	ror	r14,28
+	vpsrlq	xmm10,xmm1,6
+	add	r11,rdx
+	add	rdx,rdi
+	vpaddq	xmm2,xmm2,xmm8
+	mov	r13,r11
+	add	r14,rdx
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	rdx,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,rax
+	ror	r14,5
+	xor	r13,r11
+	xor	r12,rbx
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,rdx
+	and	r12,r11
+	xor	r13,r11
+	vpaddq	xmm2,xmm2,xmm11
+	add	rcx,QWORD[40+rsp]
+	mov	rdi,rdx
+	xor	r12,rbx
+	ror	r14,6
+	vpaddq	xmm10,xmm2,XMMWORD[((-64))+rbp]
+	xor	rdi,r8
+	add	rcx,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rdx
+	add	rcx,r13
+	xor	r15,r8
+	ror	r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	vmovdqa	XMMWORD[32+rsp],xmm10
+	vpalignr	xmm8,xmm4,xmm3,8
+	ror	r13,23
+	mov	rcx,r14
+	vpalignr	xmm11,xmm0,xmm7,8
+	mov	r12,r11
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,r10
+	xor	r12,rax
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,rcx
+	vpaddq	xmm3,xmm3,xmm11
+	and	r12,r10
+	xor	r13,r10
+	add	rbx,QWORD[48+rsp]
+	mov	r15,rcx
+DB	143,72,120,195,209,7
+	xor	r12,rax
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,rdx
+	add	rbx,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,218,3
+	xor	r14,rcx
+	add	rbx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rdx
+	ror	r14,28
+	vpsrlq	xmm10,xmm2,6
+	add	r9,rbx
+	add	rbx,rdi
+	vpaddq	xmm3,xmm3,xmm8
+	mov	r13,r9
+	add	r14,rbx
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	rbx,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,r10
+	ror	r14,5
+	xor	r13,r9
+	xor	r12,r11
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,rbx
+	and	r12,r9
+	xor	r13,r9
+	vpaddq	xmm3,xmm3,xmm11
+	add	rax,QWORD[56+rsp]
+	mov	rdi,rbx
+	xor	r12,r11
+	ror	r14,6
+	vpaddq	xmm10,xmm3,XMMWORD[((-32))+rbp]
+	xor	rdi,rcx
+	add	rax,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rbx
+	add	rax,r13
+	xor	r15,rcx
+	ror	r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	vmovdqa	XMMWORD[48+rsp],xmm10
+	vpalignr	xmm8,xmm5,xmm4,8
+	ror	r13,23
+	mov	rax,r14
+	vpalignr	xmm11,xmm1,xmm0,8
+	mov	r12,r9
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,r8
+	xor	r12,r10
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,rax
+	vpaddq	xmm4,xmm4,xmm11
+	and	r12,r8
+	xor	r13,r8
+	add	r11,QWORD[64+rsp]
+	mov	r15,rax
+DB	143,72,120,195,209,7
+	xor	r12,r10
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,rbx
+	add	r11,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,219,3
+	xor	r14,rax
+	add	r11,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rbx
+	ror	r14,28
+	vpsrlq	xmm10,xmm3,6
+	add	rdx,r11
+	add	r11,rdi
+	vpaddq	xmm4,xmm4,xmm8
+	mov	r13,rdx
+	add	r14,r11
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	r11,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,r8
+	ror	r14,5
+	xor	r13,rdx
+	xor	r12,r9
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,r11
+	and	r12,rdx
+	xor	r13,rdx
+	vpaddq	xmm4,xmm4,xmm11
+	add	r10,QWORD[72+rsp]
+	mov	rdi,r11
+	xor	r12,r9
+	ror	r14,6
+	vpaddq	xmm10,xmm4,XMMWORD[rbp]
+	xor	rdi,rax
+	add	r10,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r11
+	add	r10,r13
+	xor	r15,rax
+	ror	r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	vmovdqa	XMMWORD[64+rsp],xmm10
+	vpalignr	xmm8,xmm6,xmm5,8
+	ror	r13,23
+	mov	r10,r14
+	vpalignr	xmm11,xmm2,xmm1,8
+	mov	r12,rdx
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,rcx
+	xor	r12,r8
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,r10
+	vpaddq	xmm5,xmm5,xmm11
+	and	r12,rcx
+	xor	r13,rcx
+	add	r9,QWORD[80+rsp]
+	mov	r15,r10
+DB	143,72,120,195,209,7
+	xor	r12,r8
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,r11
+	add	r9,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,220,3
+	xor	r14,r10
+	add	r9,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r11
+	ror	r14,28
+	vpsrlq	xmm10,xmm4,6
+	add	rbx,r9
+	add	r9,rdi
+	vpaddq	xmm5,xmm5,xmm8
+	mov	r13,rbx
+	add	r14,r9
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	r9,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,rcx
+	ror	r14,5
+	xor	r13,rbx
+	xor	r12,rdx
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,r9
+	and	r12,rbx
+	xor	r13,rbx
+	vpaddq	xmm5,xmm5,xmm11
+	add	r8,QWORD[88+rsp]
+	mov	rdi,r9
+	xor	r12,rdx
+	ror	r14,6
+	vpaddq	xmm10,xmm5,XMMWORD[32+rbp]
+	xor	rdi,r10
+	add	r8,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r9
+	add	r8,r13
+	xor	r15,r10
+	ror	r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	vmovdqa	XMMWORD[80+rsp],xmm10
+	vpalignr	xmm8,xmm7,xmm6,8
+	ror	r13,23
+	mov	r8,r14
+	vpalignr	xmm11,xmm3,xmm2,8
+	mov	r12,rbx
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,rax
+	xor	r12,rcx
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,r8
+	vpaddq	xmm6,xmm6,xmm11
+	and	r12,rax
+	xor	r13,rax
+	add	rdx,QWORD[96+rsp]
+	mov	r15,r8
+DB	143,72,120,195,209,7
+	xor	r12,rcx
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,r9
+	add	rdx,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,221,3
+	xor	r14,r8
+	add	rdx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r9
+	ror	r14,28
+	vpsrlq	xmm10,xmm5,6
+	add	r11,rdx
+	add	rdx,rdi
+	vpaddq	xmm6,xmm6,xmm8
+	mov	r13,r11
+	add	r14,rdx
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	rdx,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,rax
+	ror	r14,5
+	xor	r13,r11
+	xor	r12,rbx
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,rdx
+	and	r12,r11
+	xor	r13,r11
+	vpaddq	xmm6,xmm6,xmm11
+	add	rcx,QWORD[104+rsp]
+	mov	rdi,rdx
+	xor	r12,rbx
+	ror	r14,6
+	vpaddq	xmm10,xmm6,XMMWORD[64+rbp]
+	xor	rdi,r8
+	add	rcx,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rdx
+	add	rcx,r13
+	xor	r15,r8
+	ror	r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	vmovdqa	XMMWORD[96+rsp],xmm10
+	vpalignr	xmm8,xmm0,xmm7,8
+	ror	r13,23
+	mov	rcx,r14
+	vpalignr	xmm11,xmm4,xmm3,8
+	mov	r12,r11
+	ror	r14,5
+DB	143,72,120,195,200,56
+	xor	r13,r10
+	xor	r12,rax
+	vpsrlq	xmm8,xmm8,7
+	ror	r13,4
+	xor	r14,rcx
+	vpaddq	xmm7,xmm7,xmm11
+	and	r12,r10
+	xor	r13,r10
+	add	rbx,QWORD[112+rsp]
+	mov	r15,rcx
+DB	143,72,120,195,209,7
+	xor	r12,rax
+	ror	r14,6
+	vpxor	xmm8,xmm8,xmm9
+	xor	r15,rdx
+	add	rbx,r12
+	ror	r13,14
+	and	rdi,r15
+DB	143,104,120,195,222,3
+	xor	r14,rcx
+	add	rbx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rdx
+	ror	r14,28
+	vpsrlq	xmm10,xmm6,6
+	add	r9,rbx
+	add	rbx,rdi
+	vpaddq	xmm7,xmm7,xmm8
+	mov	r13,r9
+	add	r14,rbx
+DB	143,72,120,195,203,42
+	ror	r13,23
+	mov	rbx,r14
+	vpxor	xmm11,xmm11,xmm10
+	mov	r12,r10
+	ror	r14,5
+	xor	r13,r9
+	xor	r12,r11
+	vpxor	xmm11,xmm11,xmm9
+	ror	r13,4
+	xor	r14,rbx
+	and	r12,r9
+	xor	r13,r9
+	vpaddq	xmm7,xmm7,xmm11
+	add	rax,QWORD[120+rsp]
+	mov	rdi,rbx
+	xor	r12,r11
+	ror	r14,6
+	vpaddq	xmm10,xmm7,XMMWORD[96+rbp]
+	xor	rdi,rcx
+	add	rax,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rbx
+	add	rax,r13
+	xor	r15,rcx
+	ror	r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	vmovdqa	XMMWORD[112+rsp],xmm10
+	cmp	BYTE[135+rbp],0
+	jne	NEAR $L$xop_00_47
+	ror	r13,23
+	mov	rax,r14
+	mov	r12,r9
+	ror	r14,5
+	xor	r13,r8
+	xor	r12,r10
+	ror	r13,4
+	xor	r14,rax
+	and	r12,r8
+	xor	r13,r8
+	add	r11,QWORD[rsp]
+	mov	r15,rax
+	xor	r12,r10
+	ror	r14,6
+	xor	r15,rbx
+	add	r11,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,rax
+	add	r11,r13
+	xor	rdi,rbx
+	ror	r14,28
+	add	rdx,r11
+	add	r11,rdi
+	mov	r13,rdx
+	add	r14,r11
+	ror	r13,23
+	mov	r11,r14
+	mov	r12,r8
+	ror	r14,5
+	xor	r13,rdx
+	xor	r12,r9
+	ror	r13,4
+	xor	r14,r11
+	and	r12,rdx
+	xor	r13,rdx
+	add	r10,QWORD[8+rsp]
+	mov	rdi,r11
+	xor	r12,r9
+	ror	r14,6
+	xor	rdi,rax
+	add	r10,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r11
+	add	r10,r13
+	xor	r15,rax
+	ror	r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	ror	r13,23
+	mov	r10,r14
+	mov	r12,rdx
+	ror	r14,5
+	xor	r13,rcx
+	xor	r12,r8
+	ror	r13,4
+	xor	r14,r10
+	and	r12,rcx
+	xor	r13,rcx
+	add	r9,QWORD[16+rsp]
+	mov	r15,r10
+	xor	r12,r8
+	ror	r14,6
+	xor	r15,r11
+	add	r9,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,r10
+	add	r9,r13
+	xor	rdi,r11
+	ror	r14,28
+	add	rbx,r9
+	add	r9,rdi
+	mov	r13,rbx
+	add	r14,r9
+	ror	r13,23
+	mov	r9,r14
+	mov	r12,rcx
+	ror	r14,5
+	xor	r13,rbx
+	xor	r12,rdx
+	ror	r13,4
+	xor	r14,r9
+	and	r12,rbx
+	xor	r13,rbx
+	add	r8,QWORD[24+rsp]
+	mov	rdi,r9
+	xor	r12,rdx
+	ror	r14,6
+	xor	rdi,r10
+	add	r8,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r9
+	add	r8,r13
+	xor	r15,r10
+	ror	r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	ror	r13,23
+	mov	r8,r14
+	mov	r12,rbx
+	ror	r14,5
+	xor	r13,rax
+	xor	r12,rcx
+	ror	r13,4
+	xor	r14,r8
+	and	r12,rax
+	xor	r13,rax
+	add	rdx,QWORD[32+rsp]
+	mov	r15,r8
+	xor	r12,rcx
+	ror	r14,6
+	xor	r15,r9
+	add	rdx,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,r8
+	add	rdx,r13
+	xor	rdi,r9
+	ror	r14,28
+	add	r11,rdx
+	add	rdx,rdi
+	mov	r13,r11
+	add	r14,rdx
+	ror	r13,23
+	mov	rdx,r14
+	mov	r12,rax
+	ror	r14,5
+	xor	r13,r11
+	xor	r12,rbx
+	ror	r13,4
+	xor	r14,rdx
+	and	r12,r11
+	xor	r13,r11
+	add	rcx,QWORD[40+rsp]
+	mov	rdi,rdx
+	xor	r12,rbx
+	ror	r14,6
+	xor	rdi,r8
+	add	rcx,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rdx
+	add	rcx,r13
+	xor	r15,r8
+	ror	r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	ror	r13,23
+	mov	rcx,r14
+	mov	r12,r11
+	ror	r14,5
+	xor	r13,r10
+	xor	r12,rax
+	ror	r13,4
+	xor	r14,rcx
+	and	r12,r10
+	xor	r13,r10
+	add	rbx,QWORD[48+rsp]
+	mov	r15,rcx
+	xor	r12,rax
+	ror	r14,6
+	xor	r15,rdx
+	add	rbx,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,rcx
+	add	rbx,r13
+	xor	rdi,rdx
+	ror	r14,28
+	add	r9,rbx
+	add	rbx,rdi
+	mov	r13,r9
+	add	r14,rbx
+	ror	r13,23
+	mov	rbx,r14
+	mov	r12,r10
+	ror	r14,5
+	xor	r13,r9
+	xor	r12,r11
+	ror	r13,4
+	xor	r14,rbx
+	and	r12,r9
+	xor	r13,r9
+	add	rax,QWORD[56+rsp]
+	mov	rdi,rbx
+	xor	r12,r11
+	ror	r14,6
+	xor	rdi,rcx
+	add	rax,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rbx
+	add	rax,r13
+	xor	r15,rcx
+	ror	r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	ror	r13,23
+	mov	rax,r14
+	mov	r12,r9
+	ror	r14,5
+	xor	r13,r8
+	xor	r12,r10
+	ror	r13,4
+	xor	r14,rax
+	and	r12,r8
+	xor	r13,r8
+	add	r11,QWORD[64+rsp]
+	mov	r15,rax
+	xor	r12,r10
+	ror	r14,6
+	xor	r15,rbx
+	add	r11,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,rax
+	add	r11,r13
+	xor	rdi,rbx
+	ror	r14,28
+	add	rdx,r11
+	add	r11,rdi
+	mov	r13,rdx
+	add	r14,r11
+	ror	r13,23
+	mov	r11,r14
+	mov	r12,r8
+	ror	r14,5
+	xor	r13,rdx
+	xor	r12,r9
+	ror	r13,4
+	xor	r14,r11
+	and	r12,rdx
+	xor	r13,rdx
+	add	r10,QWORD[72+rsp]
+	mov	rdi,r11
+	xor	r12,r9
+	ror	r14,6
+	xor	rdi,rax
+	add	r10,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r11
+	add	r10,r13
+	xor	r15,rax
+	ror	r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	ror	r13,23
+	mov	r10,r14
+	mov	r12,rdx
+	ror	r14,5
+	xor	r13,rcx
+	xor	r12,r8
+	ror	r13,4
+	xor	r14,r10
+	and	r12,rcx
+	xor	r13,rcx
+	add	r9,QWORD[80+rsp]
+	mov	r15,r10
+	xor	r12,r8
+	ror	r14,6
+	xor	r15,r11
+	add	r9,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,r10
+	add	r9,r13
+	xor	rdi,r11
+	ror	r14,28
+	add	rbx,r9
+	add	r9,rdi
+	mov	r13,rbx
+	add	r14,r9
+	ror	r13,23
+	mov	r9,r14
+	mov	r12,rcx
+	ror	r14,5
+	xor	r13,rbx
+	xor	r12,rdx
+	ror	r13,4
+	xor	r14,r9
+	and	r12,rbx
+	xor	r13,rbx
+	add	r8,QWORD[88+rsp]
+	mov	rdi,r9
+	xor	r12,rdx
+	ror	r14,6
+	xor	rdi,r10
+	add	r8,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,r9
+	add	r8,r13
+	xor	r15,r10
+	ror	r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	ror	r13,23
+	mov	r8,r14
+	mov	r12,rbx
+	ror	r14,5
+	xor	r13,rax
+	xor	r12,rcx
+	ror	r13,4
+	xor	r14,r8
+	and	r12,rax
+	xor	r13,rax
+	add	rdx,QWORD[96+rsp]
+	mov	r15,r8
+	xor	r12,rcx
+	ror	r14,6
+	xor	r15,r9
+	add	rdx,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,r8
+	add	rdx,r13
+	xor	rdi,r9
+	ror	r14,28
+	add	r11,rdx
+	add	rdx,rdi
+	mov	r13,r11
+	add	r14,rdx
+	ror	r13,23
+	mov	rdx,r14
+	mov	r12,rax
+	ror	r14,5
+	xor	r13,r11
+	xor	r12,rbx
+	ror	r13,4
+	xor	r14,rdx
+	and	r12,r11
+	xor	r13,r11
+	add	rcx,QWORD[104+rsp]
+	mov	rdi,rdx
+	xor	r12,rbx
+	ror	r14,6
+	xor	rdi,r8
+	add	rcx,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rdx
+	add	rcx,r13
+	xor	r15,r8
+	ror	r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	ror	r13,23
+	mov	rcx,r14
+	mov	r12,r11
+	ror	r14,5
+	xor	r13,r10
+	xor	r12,rax
+	ror	r13,4
+	xor	r14,rcx
+	and	r12,r10
+	xor	r13,r10
+	add	rbx,QWORD[112+rsp]
+	mov	r15,rcx
+	xor	r12,rax
+	ror	r14,6
+	xor	r15,rdx
+	add	rbx,r12
+	ror	r13,14
+	and	rdi,r15
+	xor	r14,rcx
+	add	rbx,r13
+	xor	rdi,rdx
+	ror	r14,28
+	add	r9,rbx
+	add	rbx,rdi
+	mov	r13,r9
+	add	r14,rbx
+	ror	r13,23
+	mov	rbx,r14
+	mov	r12,r10
+	ror	r14,5
+	xor	r13,r9
+	xor	r12,r11
+	ror	r13,4
+	xor	r14,rbx
+	and	r12,r9
+	xor	r13,r9
+	add	rax,QWORD[120+rsp]
+	mov	rdi,rbx
+	xor	r12,r11
+	ror	r14,6
+	xor	rdi,rcx
+	add	rax,r12
+	ror	r13,14
+	and	r15,rdi
+	xor	r14,rbx
+	add	rax,r13
+	xor	r15,rcx
+	ror	r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	mov	rdi,QWORD[((128+0))+rsp]
+	mov	rax,r14
+
+	add	rax,QWORD[rdi]
+	lea	rsi,[128+rsi]
+	add	rbx,QWORD[8+rdi]
+	add	rcx,QWORD[16+rdi]
+	add	rdx,QWORD[24+rdi]
+	add	r8,QWORD[32+rdi]
+	add	r9,QWORD[40+rdi]
+	add	r10,QWORD[48+rdi]
+	add	r11,QWORD[56+rdi]
+
+	cmp	rsi,QWORD[((128+16))+rsp]
+
+	mov	QWORD[rdi],rax
+	mov	QWORD[8+rdi],rbx
+	mov	QWORD[16+rdi],rcx
+	mov	QWORD[24+rdi],rdx
+	mov	QWORD[32+rdi],r8
+	mov	QWORD[40+rdi],r9
+	mov	QWORD[48+rdi],r10
+	mov	QWORD[56+rdi],r11
+	jb	NEAR $L$loop_xop
+
+	mov	rsi,QWORD[((128+24))+rsp]
+	vzeroupper
+	movaps	xmm6,XMMWORD[((128+32))+rsp]
+	movaps	xmm7,XMMWORD[((128+48))+rsp]
+	movaps	xmm8,XMMWORD[((128+64))+rsp]
+	movaps	xmm9,XMMWORD[((128+80))+rsp]
+	movaps	xmm10,XMMWORD[((128+96))+rsp]
+	movaps	xmm11,XMMWORD[((128+112))+rsp]
+	mov	r15,QWORD[rsi]
+	mov	r14,QWORD[8+rsi]
+	mov	r13,QWORD[16+rsi]
+	mov	r12,QWORD[24+rsi]
+	mov	rbp,QWORD[32+rsi]
+	mov	rbx,QWORD[40+rsi]
+	lea	rsp,[48+rsi]
+$L$epilogue_xop:
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_sha512_block_data_order_xop:
+
+ALIGN	64
+sha512_block_data_order_avx:
+	mov	QWORD[8+rsp],rdi	;WIN64 prologue
+	mov	QWORD[16+rsp],rsi
+	mov	rax,rsp
+$L$SEH_begin_sha512_block_data_order_avx:
+	mov	rdi,rcx
+	mov	rsi,rdx
+	mov	rdx,r8
+
+
+$L$avx_shortcut:
+	push	rbx
+	push	rbp
+	push	r12
+	push	r13
+	push	r14
+	push	r15
+	mov	r11,rsp
+	shl	rdx,4
+	sub	rsp,256
+	lea	rdx,[rdx*8+rsi]
+	and	rsp,-64
+	mov	QWORD[((128+0))+rsp],rdi
+	mov	QWORD[((128+8))+rsp],rsi
+	mov	QWORD[((128+16))+rsp],rdx
+	mov	QWORD[((128+24))+rsp],r11
+	movaps	XMMWORD[(128+32)+rsp],xmm6
+	movaps	XMMWORD[(128+48)+rsp],xmm7
+	movaps	XMMWORD[(128+64)+rsp],xmm8
+	movaps	XMMWORD[(128+80)+rsp],xmm9
+	movaps	XMMWORD[(128+96)+rsp],xmm10
+	movaps	XMMWORD[(128+112)+rsp],xmm11
+$L$prologue_avx:
+
+	vzeroupper
+	mov	rax,QWORD[rdi]
+	mov	rbx,QWORD[8+rdi]
+	mov	rcx,QWORD[16+rdi]
+	mov	rdx,QWORD[24+rdi]
+	mov	r8,QWORD[32+rdi]
+	mov	r9,QWORD[40+rdi]
+	mov	r10,QWORD[48+rdi]
+	mov	r11,QWORD[56+rdi]
+	jmp	NEAR $L$loop_avx
+ALIGN	16
+$L$loop_avx:
+	vmovdqa	xmm11,XMMWORD[((K512+1280))]
+	vmovdqu	xmm0,XMMWORD[rsi]
+	lea	rbp,[((K512+128))]
+	vmovdqu	xmm1,XMMWORD[16+rsi]
+	vmovdqu	xmm2,XMMWORD[32+rsi]
+	vpshufb	xmm0,xmm0,xmm11
+	vmovdqu	xmm3,XMMWORD[48+rsi]
+	vpshufb	xmm1,xmm1,xmm11
+	vmovdqu	xmm4,XMMWORD[64+rsi]
+	vpshufb	xmm2,xmm2,xmm11
+	vmovdqu	xmm5,XMMWORD[80+rsi]
+	vpshufb	xmm3,xmm3,xmm11
+	vmovdqu	xmm6,XMMWORD[96+rsi]
+	vpshufb	xmm4,xmm4,xmm11
+	vmovdqu	xmm7,XMMWORD[112+rsi]
+	vpshufb	xmm5,xmm5,xmm11
+	vpaddq	xmm8,xmm0,XMMWORD[((-128))+rbp]
+	vpshufb	xmm6,xmm6,xmm11
+	vpaddq	xmm9,xmm1,XMMWORD[((-96))+rbp]
+	vpshufb	xmm7,xmm7,xmm11
+	vpaddq	xmm10,xmm2,XMMWORD[((-64))+rbp]
+	vpaddq	xmm11,xmm3,XMMWORD[((-32))+rbp]
+	vmovdqa	XMMWORD[rsp],xmm8
+	vpaddq	xmm8,xmm4,XMMWORD[rbp]
+	vmovdqa	XMMWORD[16+rsp],xmm9
+	vpaddq	xmm9,xmm5,XMMWORD[32+rbp]
+	vmovdqa	XMMWORD[32+rsp],xmm10
+	vpaddq	xmm10,xmm6,XMMWORD[64+rbp]
+	vmovdqa	XMMWORD[48+rsp],xmm11
+	vpaddq	xmm11,xmm7,XMMWORD[96+rbp]
+	vmovdqa	XMMWORD[64+rsp],xmm8
+	mov	r14,rax
+	vmovdqa	XMMWORD[80+rsp],xmm9
+	mov	rdi,rbx
+	vmovdqa	XMMWORD[96+rsp],xmm10
+	xor	rdi,rcx
+	vmovdqa	XMMWORD[112+rsp],xmm11
+	mov	r13,r8
+	jmp	NEAR $L$avx_00_47
+
+ALIGN	16
+$L$avx_00_47:
+	add	rbp,256
+	vpalignr	xmm8,xmm1,xmm0,8
+	shrd	r13,r13,23
+	mov	rax,r14
+	vpalignr	xmm11,xmm5,xmm4,8
+	mov	r12,r9
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,r8
+	xor	r12,r10
+	vpaddq	xmm0,xmm0,xmm11
+	shrd	r13,r13,4
+	xor	r14,rax
+	vpsrlq	xmm11,xmm8,7
+	and	r12,r8
+	xor	r13,r8
+	vpsllq	xmm9,xmm8,56
+	add	r11,QWORD[rsp]
+	mov	r15,rax
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,r10
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,rbx
+	add	r11,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,rax
+	add	r11,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rbx
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm7,6
+	add	rdx,r11
+	add	r11,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,rdx
+	add	r14,r11
+	vpsllq	xmm10,xmm7,3
+	shrd	r13,r13,23
+	mov	r11,r14
+	vpaddq	xmm0,xmm0,xmm8
+	mov	r12,r8
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm7,19
+	xor	r13,rdx
+	xor	r12,r9
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,r11
+	vpsllq	xmm10,xmm10,42
+	and	r12,rdx
+	xor	r13,rdx
+	vpxor	xmm11,xmm11,xmm9
+	add	r10,QWORD[8+rsp]
+	mov	rdi,r11
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,r9
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,rax
+	add	r10,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm0,xmm0,xmm11
+	xor	r14,r11
+	add	r10,r13
+	vpaddq	xmm10,xmm0,XMMWORD[((-128))+rbp]
+	xor	r15,rax
+	shrd	r14,r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	vmovdqa	XMMWORD[rsp],xmm10
+	vpalignr	xmm8,xmm2,xmm1,8
+	shrd	r13,r13,23
+	mov	r10,r14
+	vpalignr	xmm11,xmm6,xmm5,8
+	mov	r12,rdx
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,rcx
+	xor	r12,r8
+	vpaddq	xmm1,xmm1,xmm11
+	shrd	r13,r13,4
+	xor	r14,r10
+	vpsrlq	xmm11,xmm8,7
+	and	r12,rcx
+	xor	r13,rcx
+	vpsllq	xmm9,xmm8,56
+	add	r9,QWORD[16+rsp]
+	mov	r15,r10
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,r8
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,r11
+	add	r9,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,r10
+	add	r9,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r11
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm0,6
+	add	rbx,r9
+	add	r9,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,rbx
+	add	r14,r9
+	vpsllq	xmm10,xmm0,3
+	shrd	r13,r13,23
+	mov	r9,r14
+	vpaddq	xmm1,xmm1,xmm8
+	mov	r12,rcx
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm0,19
+	xor	r13,rbx
+	xor	r12,rdx
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,r9
+	vpsllq	xmm10,xmm10,42
+	and	r12,rbx
+	xor	r13,rbx
+	vpxor	xmm11,xmm11,xmm9
+	add	r8,QWORD[24+rsp]
+	mov	rdi,r9
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,rdx
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,r10
+	add	r8,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm1,xmm1,xmm11
+	xor	r14,r9
+	add	r8,r13
+	vpaddq	xmm10,xmm1,XMMWORD[((-96))+rbp]
+	xor	r15,r10
+	shrd	r14,r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	vmovdqa	XMMWORD[16+rsp],xmm10
+	vpalignr	xmm8,xmm3,xmm2,8
+	shrd	r13,r13,23
+	mov	r8,r14
+	vpalignr	xmm11,xmm7,xmm6,8
+	mov	r12,rbx
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,rax
+	xor	r12,rcx
+	vpaddq	xmm2,xmm2,xmm11
+	shrd	r13,r13,4
+	xor	r14,r8
+	vpsrlq	xmm11,xmm8,7
+	and	r12,rax
+	xor	r13,rax
+	vpsllq	xmm9,xmm8,56
+	add	rdx,QWORD[32+rsp]
+	mov	r15,r8
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,rcx
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,r9
+	add	rdx,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,r8
+	add	rdx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r9
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm1,6
+	add	r11,rdx
+	add	rdx,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,r11
+	add	r14,rdx
+	vpsllq	xmm10,xmm1,3
+	shrd	r13,r13,23
+	mov	rdx,r14
+	vpaddq	xmm2,xmm2,xmm8
+	mov	r12,rax
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm1,19
+	xor	r13,r11
+	xor	r12,rbx
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,rdx
+	vpsllq	xmm10,xmm10,42
+	and	r12,r11
+	xor	r13,r11
+	vpxor	xmm11,xmm11,xmm9
+	add	rcx,QWORD[40+rsp]
+	mov	rdi,rdx
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,rbx
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,r8
+	add	rcx,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm2,xmm2,xmm11
+	xor	r14,rdx
+	add	rcx,r13
+	vpaddq	xmm10,xmm2,XMMWORD[((-64))+rbp]
+	xor	r15,r8
+	shrd	r14,r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	vmovdqa	XMMWORD[32+rsp],xmm10
+	vpalignr	xmm8,xmm4,xmm3,8
+	shrd	r13,r13,23
+	mov	rcx,r14
+	vpalignr	xmm11,xmm0,xmm7,8
+	mov	r12,r11
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,r10
+	xor	r12,rax
+	vpaddq	xmm3,xmm3,xmm11
+	shrd	r13,r13,4
+	xor	r14,rcx
+	vpsrlq	xmm11,xmm8,7
+	and	r12,r10
+	xor	r13,r10
+	vpsllq	xmm9,xmm8,56
+	add	rbx,QWORD[48+rsp]
+	mov	r15,rcx
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,rax
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,rdx
+	add	rbx,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,rcx
+	add	rbx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rdx
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm2,6
+	add	r9,rbx
+	add	rbx,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,r9
+	add	r14,rbx
+	vpsllq	xmm10,xmm2,3
+	shrd	r13,r13,23
+	mov	rbx,r14
+	vpaddq	xmm3,xmm3,xmm8
+	mov	r12,r10
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm2,19
+	xor	r13,r9
+	xor	r12,r11
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,rbx
+	vpsllq	xmm10,xmm10,42
+	and	r12,r9
+	xor	r13,r9
+	vpxor	xmm11,xmm11,xmm9
+	add	rax,QWORD[56+rsp]
+	mov	rdi,rbx
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,r11
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,rcx
+	add	rax,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm3,xmm3,xmm11
+	xor	r14,rbx
+	add	rax,r13
+	vpaddq	xmm10,xmm3,XMMWORD[((-32))+rbp]
+	xor	r15,rcx
+	shrd	r14,r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	vmovdqa	XMMWORD[48+rsp],xmm10
+	vpalignr	xmm8,xmm5,xmm4,8
+	shrd	r13,r13,23
+	mov	rax,r14
+	vpalignr	xmm11,xmm1,xmm0,8
+	mov	r12,r9
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,r8
+	xor	r12,r10
+	vpaddq	xmm4,xmm4,xmm11
+	shrd	r13,r13,4
+	xor	r14,rax
+	vpsrlq	xmm11,xmm8,7
+	and	r12,r8
+	xor	r13,r8
+	vpsllq	xmm9,xmm8,56
+	add	r11,QWORD[64+rsp]
+	mov	r15,rax
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,r10
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,rbx
+	add	r11,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,rax
+	add	r11,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rbx
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm3,6
+	add	rdx,r11
+	add	r11,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,rdx
+	add	r14,r11
+	vpsllq	xmm10,xmm3,3
+	shrd	r13,r13,23
+	mov	r11,r14
+	vpaddq	xmm4,xmm4,xmm8
+	mov	r12,r8
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm3,19
+	xor	r13,rdx
+	xor	r12,r9
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,r11
+	vpsllq	xmm10,xmm10,42
+	and	r12,rdx
+	xor	r13,rdx
+	vpxor	xmm11,xmm11,xmm9
+	add	r10,QWORD[72+rsp]
+	mov	rdi,r11
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,r9
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,rax
+	add	r10,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm4,xmm4,xmm11
+	xor	r14,r11
+	add	r10,r13
+	vpaddq	xmm10,xmm4,XMMWORD[rbp]
+	xor	r15,rax
+	shrd	r14,r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	vmovdqa	XMMWORD[64+rsp],xmm10
+	vpalignr	xmm8,xmm6,xmm5,8
+	shrd	r13,r13,23
+	mov	r10,r14
+	vpalignr	xmm11,xmm2,xmm1,8
+	mov	r12,rdx
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,rcx
+	xor	r12,r8
+	vpaddq	xmm5,xmm5,xmm11
+	shrd	r13,r13,4
+	xor	r14,r10
+	vpsrlq	xmm11,xmm8,7
+	and	r12,rcx
+	xor	r13,rcx
+	vpsllq	xmm9,xmm8,56
+	add	r9,QWORD[80+rsp]
+	mov	r15,r10
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,r8
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,r11
+	add	r9,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,r10
+	add	r9,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r11
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm4,6
+	add	rbx,r9
+	add	r9,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,rbx
+	add	r14,r9
+	vpsllq	xmm10,xmm4,3
+	shrd	r13,r13,23
+	mov	r9,r14
+	vpaddq	xmm5,xmm5,xmm8
+	mov	r12,rcx
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm4,19
+	xor	r13,rbx
+	xor	r12,rdx
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,r9
+	vpsllq	xmm10,xmm10,42
+	and	r12,rbx
+	xor	r13,rbx
+	vpxor	xmm11,xmm11,xmm9
+	add	r8,QWORD[88+rsp]
+	mov	rdi,r9
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,rdx
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,r10
+	add	r8,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm5,xmm5,xmm11
+	xor	r14,r9
+	add	r8,r13
+	vpaddq	xmm10,xmm5,XMMWORD[32+rbp]
+	xor	r15,r10
+	shrd	r14,r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	vmovdqa	XMMWORD[80+rsp],xmm10
+	vpalignr	xmm8,xmm7,xmm6,8
+	shrd	r13,r13,23
+	mov	r8,r14
+	vpalignr	xmm11,xmm3,xmm2,8
+	mov	r12,rbx
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,rax
+	xor	r12,rcx
+	vpaddq	xmm6,xmm6,xmm11
+	shrd	r13,r13,4
+	xor	r14,r8
+	vpsrlq	xmm11,xmm8,7
+	and	r12,rax
+	xor	r13,rax
+	vpsllq	xmm9,xmm8,56
+	add	rdx,QWORD[96+rsp]
+	mov	r15,r8
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,rcx
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,r9
+	add	rdx,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,r8
+	add	rdx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,r9
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm5,6
+	add	r11,rdx
+	add	rdx,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,r11
+	add	r14,rdx
+	vpsllq	xmm10,xmm5,3
+	shrd	r13,r13,23
+	mov	rdx,r14
+	vpaddq	xmm6,xmm6,xmm8
+	mov	r12,rax
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm5,19
+	xor	r13,r11
+	xor	r12,rbx
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,rdx
+	vpsllq	xmm10,xmm10,42
+	and	r12,r11
+	xor	r13,r11
+	vpxor	xmm11,xmm11,xmm9
+	add	rcx,QWORD[104+rsp]
+	mov	rdi,rdx
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,rbx
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,r8
+	add	rcx,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm6,xmm6,xmm11
+	xor	r14,rdx
+	add	rcx,r13
+	vpaddq	xmm10,xmm6,XMMWORD[64+rbp]
+	xor	r15,r8
+	shrd	r14,r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	vmovdqa	XMMWORD[96+rsp],xmm10
+	vpalignr	xmm8,xmm0,xmm7,8
+	shrd	r13,r13,23
+	mov	rcx,r14
+	vpalignr	xmm11,xmm4,xmm3,8
+	mov	r12,r11
+	shrd	r14,r14,5
+	vpsrlq	xmm10,xmm8,1
+	xor	r13,r10
+	xor	r12,rax
+	vpaddq	xmm7,xmm7,xmm11
+	shrd	r13,r13,4
+	xor	r14,rcx
+	vpsrlq	xmm11,xmm8,7
+	and	r12,r10
+	xor	r13,r10
+	vpsllq	xmm9,xmm8,56
+	add	rbx,QWORD[112+rsp]
+	mov	r15,rcx
+	vpxor	xmm8,xmm11,xmm10
+	xor	r12,rax
+	shrd	r14,r14,6
+	vpsrlq	xmm10,xmm10,7
+	xor	r15,rdx
+	add	rbx,r12
+	vpxor	xmm8,xmm8,xmm9
+	shrd	r13,r13,14
+	and	rdi,r15
+	vpsllq	xmm9,xmm9,7
+	xor	r14,rcx
+	add	rbx,r13
+	vpxor	xmm8,xmm8,xmm10
+	xor	rdi,rdx
+	shrd	r14,r14,28
+	vpsrlq	xmm11,xmm6,6
+	add	r9,rbx
+	add	rbx,rdi
+	vpxor	xmm8,xmm8,xmm9
+	mov	r13,r9
+	add	r14,rbx
+	vpsllq	xmm10,xmm6,3
+	shrd	r13,r13,23
+	mov	rbx,r14
+	vpaddq	xmm7,xmm7,xmm8
+	mov	r12,r10
+	shrd	r14,r14,5
+	vpsrlq	xmm9,xmm6,19
+	xor	r13,r9
+	xor	r12,r11
+	vpxor	xmm11,xmm11,xmm10
+	shrd	r13,r13,4
+	xor	r14,rbx
+	vpsllq	xmm10,xmm10,42
+	and	r12,r9
+	xor	r13,r9
+	vpxor	xmm11,xmm11,xmm9
+	add	rax,QWORD[120+rsp]
+	mov	rdi,rbx
+	vpsrlq	xmm9,xmm9,42
+	xor	r12,r11
+	shrd	r14,r14,6
+	vpxor	xmm11,xmm11,xmm10
+	xor	rdi,rcx
+	add	rax,r12
+	vpxor	xmm11,xmm11,xmm9
+	shrd	r13,r13,14
+	and	r15,rdi
+	vpaddq	xmm7,xmm7,xmm11
+	xor	r14,rbx
+	add	rax,r13
+	vpaddq	xmm10,xmm7,XMMWORD[96+rbp]
+	xor	r15,rcx
+	shrd	r14,r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	vmovdqa	XMMWORD[112+rsp],xmm10
+	cmp	BYTE[135+rbp],0
+	jne	NEAR $L$avx_00_47
+	shrd	r13,r13,23
+	mov	rax,r14
+	mov	r12,r9
+	shrd	r14,r14,5
+	xor	r13,r8
+	xor	r12,r10
+	shrd	r13,r13,4
+	xor	r14,rax
+	and	r12,r8
+	xor	r13,r8
+	add	r11,QWORD[rsp]
+	mov	r15,rax
+	xor	r12,r10
+	shrd	r14,r14,6
+	xor	r15,rbx
+	add	r11,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,rax
+	add	r11,r13
+	xor	rdi,rbx
+	shrd	r14,r14,28
+	add	rdx,r11
+	add	r11,rdi
+	mov	r13,rdx
+	add	r14,r11
+	shrd	r13,r13,23
+	mov	r11,r14
+	mov	r12,r8
+	shrd	r14,r14,5
+	xor	r13,rdx
+	xor	r12,r9
+	shrd	r13,r13,4
+	xor	r14,r11
+	and	r12,rdx
+	xor	r13,rdx
+	add	r10,QWORD[8+rsp]
+	mov	rdi,r11
+	xor	r12,r9
+	shrd	r14,r14,6
+	xor	rdi,rax
+	add	r10,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,r11
+	add	r10,r13
+	xor	r15,rax
+	shrd	r14,r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	shrd	r13,r13,23
+	mov	r10,r14
+	mov	r12,rdx
+	shrd	r14,r14,5
+	xor	r13,rcx
+	xor	r12,r8
+	shrd	r13,r13,4
+	xor	r14,r10
+	and	r12,rcx
+	xor	r13,rcx
+	add	r9,QWORD[16+rsp]
+	mov	r15,r10
+	xor	r12,r8
+	shrd	r14,r14,6
+	xor	r15,r11
+	add	r9,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,r10
+	add	r9,r13
+	xor	rdi,r11
+	shrd	r14,r14,28
+	add	rbx,r9
+	add	r9,rdi
+	mov	r13,rbx
+	add	r14,r9
+	shrd	r13,r13,23
+	mov	r9,r14
+	mov	r12,rcx
+	shrd	r14,r14,5
+	xor	r13,rbx
+	xor	r12,rdx
+	shrd	r13,r13,4
+	xor	r14,r9
+	and	r12,rbx
+	xor	r13,rbx
+	add	r8,QWORD[24+rsp]
+	mov	rdi,r9
+	xor	r12,rdx
+	shrd	r14,r14,6
+	xor	rdi,r10
+	add	r8,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,r9
+	add	r8,r13
+	xor	r15,r10
+	shrd	r14,r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	shrd	r13,r13,23
+	mov	r8,r14
+	mov	r12,rbx
+	shrd	r14,r14,5
+	xor	r13,rax
+	xor	r12,rcx
+	shrd	r13,r13,4
+	xor	r14,r8
+	and	r12,rax
+	xor	r13,rax
+	add	rdx,QWORD[32+rsp]
+	mov	r15,r8
+	xor	r12,rcx
+	shrd	r14,r14,6
+	xor	r15,r9
+	add	rdx,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,r8
+	add	rdx,r13
+	xor	rdi,r9
+	shrd	r14,r14,28
+	add	r11,rdx
+	add	rdx,rdi
+	mov	r13,r11
+	add	r14,rdx
+	shrd	r13,r13,23
+	mov	rdx,r14
+	mov	r12,rax
+	shrd	r14,r14,5
+	xor	r13,r11
+	xor	r12,rbx
+	shrd	r13,r13,4
+	xor	r14,rdx
+	and	r12,r11
+	xor	r13,r11
+	add	rcx,QWORD[40+rsp]
+	mov	rdi,rdx
+	xor	r12,rbx
+	shrd	r14,r14,6
+	xor	rdi,r8
+	add	rcx,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,rdx
+	add	rcx,r13
+	xor	r15,r8
+	shrd	r14,r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	shrd	r13,r13,23
+	mov	rcx,r14
+	mov	r12,r11
+	shrd	r14,r14,5
+	xor	r13,r10
+	xor	r12,rax
+	shrd	r13,r13,4
+	xor	r14,rcx
+	and	r12,r10
+	xor	r13,r10
+	add	rbx,QWORD[48+rsp]
+	mov	r15,rcx
+	xor	r12,rax
+	shrd	r14,r14,6
+	xor	r15,rdx
+	add	rbx,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,rcx
+	add	rbx,r13
+	xor	rdi,rdx
+	shrd	r14,r14,28
+	add	r9,rbx
+	add	rbx,rdi
+	mov	r13,r9
+	add	r14,rbx
+	shrd	r13,r13,23
+	mov	rbx,r14
+	mov	r12,r10
+	shrd	r14,r14,5
+	xor	r13,r9
+	xor	r12,r11
+	shrd	r13,r13,4
+	xor	r14,rbx
+	and	r12,r9
+	xor	r13,r9
+	add	rax,QWORD[56+rsp]
+	mov	rdi,rbx
+	xor	r12,r11
+	shrd	r14,r14,6
+	xor	rdi,rcx
+	add	rax,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,rbx
+	add	rax,r13
+	xor	r15,rcx
+	shrd	r14,r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	shrd	r13,r13,23
+	mov	rax,r14
+	mov	r12,r9
+	shrd	r14,r14,5
+	xor	r13,r8
+	xor	r12,r10
+	shrd	r13,r13,4
+	xor	r14,rax
+	and	r12,r8
+	xor	r13,r8
+	add	r11,QWORD[64+rsp]
+	mov	r15,rax
+	xor	r12,r10
+	shrd	r14,r14,6
+	xor	r15,rbx
+	add	r11,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,rax
+	add	r11,r13
+	xor	rdi,rbx
+	shrd	r14,r14,28
+	add	rdx,r11
+	add	r11,rdi
+	mov	r13,rdx
+	add	r14,r11
+	shrd	r13,r13,23
+	mov	r11,r14
+	mov	r12,r8
+	shrd	r14,r14,5
+	xor	r13,rdx
+	xor	r12,r9
+	shrd	r13,r13,4
+	xor	r14,r11
+	and	r12,rdx
+	xor	r13,rdx
+	add	r10,QWORD[72+rsp]
+	mov	rdi,r11
+	xor	r12,r9
+	shrd	r14,r14,6
+	xor	rdi,rax
+	add	r10,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,r11
+	add	r10,r13
+	xor	r15,rax
+	shrd	r14,r14,28
+	add	rcx,r10
+	add	r10,r15
+	mov	r13,rcx
+	add	r14,r10
+	shrd	r13,r13,23
+	mov	r10,r14
+	mov	r12,rdx
+	shrd	r14,r14,5
+	xor	r13,rcx
+	xor	r12,r8
+	shrd	r13,r13,4
+	xor	r14,r10
+	and	r12,rcx
+	xor	r13,rcx
+	add	r9,QWORD[80+rsp]
+	mov	r15,r10
+	xor	r12,r8
+	shrd	r14,r14,6
+	xor	r15,r11
+	add	r9,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,r10
+	add	r9,r13
+	xor	rdi,r11
+	shrd	r14,r14,28
+	add	rbx,r9
+	add	r9,rdi
+	mov	r13,rbx
+	add	r14,r9
+	shrd	r13,r13,23
+	mov	r9,r14
+	mov	r12,rcx
+	shrd	r14,r14,5
+	xor	r13,rbx
+	xor	r12,rdx
+	shrd	r13,r13,4
+	xor	r14,r9
+	and	r12,rbx
+	xor	r13,rbx
+	add	r8,QWORD[88+rsp]
+	mov	rdi,r9
+	xor	r12,rdx
+	shrd	r14,r14,6
+	xor	rdi,r10
+	add	r8,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,r9
+	add	r8,r13
+	xor	r15,r10
+	shrd	r14,r14,28
+	add	rax,r8
+	add	r8,r15
+	mov	r13,rax
+	add	r14,r8
+	shrd	r13,r13,23
+	mov	r8,r14
+	mov	r12,rbx
+	shrd	r14,r14,5
+	xor	r13,rax
+	xor	r12,rcx
+	shrd	r13,r13,4
+	xor	r14,r8
+	and	r12,rax
+	xor	r13,rax
+	add	rdx,QWORD[96+rsp]
+	mov	r15,r8
+	xor	r12,rcx
+	shrd	r14,r14,6
+	xor	r15,r9
+	add	rdx,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,r8
+	add	rdx,r13
+	xor	rdi,r9
+	shrd	r14,r14,28
+	add	r11,rdx
+	add	rdx,rdi
+	mov	r13,r11
+	add	r14,rdx
+	shrd	r13,r13,23
+	mov	rdx,r14
+	mov	r12,rax
+	shrd	r14,r14,5
+	xor	r13,r11
+	xor	r12,rbx
+	shrd	r13,r13,4
+	xor	r14,rdx
+	and	r12,r11
+	xor	r13,r11
+	add	rcx,QWORD[104+rsp]
+	mov	rdi,rdx
+	xor	r12,rbx
+	shrd	r14,r14,6
+	xor	rdi,r8
+	add	rcx,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,rdx
+	add	rcx,r13
+	xor	r15,r8
+	shrd	r14,r14,28
+	add	r10,rcx
+	add	rcx,r15
+	mov	r13,r10
+	add	r14,rcx
+	shrd	r13,r13,23
+	mov	rcx,r14
+	mov	r12,r11
+	shrd	r14,r14,5
+	xor	r13,r10
+	xor	r12,rax
+	shrd	r13,r13,4
+	xor	r14,rcx
+	and	r12,r10
+	xor	r13,r10
+	add	rbx,QWORD[112+rsp]
+	mov	r15,rcx
+	xor	r12,rax
+	shrd	r14,r14,6
+	xor	r15,rdx
+	add	rbx,r12
+	shrd	r13,r13,14
+	and	rdi,r15
+	xor	r14,rcx
+	add	rbx,r13
+	xor	rdi,rdx
+	shrd	r14,r14,28
+	add	r9,rbx
+	add	rbx,rdi
+	mov	r13,r9
+	add	r14,rbx
+	shrd	r13,r13,23
+	mov	rbx,r14
+	mov	r12,r10
+	shrd	r14,r14,5
+	xor	r13,r9
+	xor	r12,r11
+	shrd	r13,r13,4
+	xor	r14,rbx
+	and	r12,r9
+	xor	r13,r9
+	add	rax,QWORD[120+rsp]
+	mov	rdi,rbx
+	xor	r12,r11
+	shrd	r14,r14,6
+	xor	rdi,rcx
+	add	rax,r12
+	shrd	r13,r13,14
+	and	r15,rdi
+	xor	r14,rbx
+	add	rax,r13
+	xor	r15,rcx
+	shrd	r14,r14,28
+	add	r8,rax
+	add	rax,r15
+	mov	r13,r8
+	add	r14,rax
+	mov	rdi,QWORD[((128+0))+rsp]
+	mov	rax,r14
+
+	add	rax,QWORD[rdi]
+	lea	rsi,[128+rsi]
+	add	rbx,QWORD[8+rdi]
+	add	rcx,QWORD[16+rdi]
+	add	rdx,QWORD[24+rdi]
+	add	r8,QWORD[32+rdi]
+	add	r9,QWORD[40+rdi]
+	add	r10,QWORD[48+rdi]
+	add	r11,QWORD[56+rdi]
+
+	cmp	rsi,QWORD[((128+16))+rsp]
+
+	mov	QWORD[rdi],rax
+	mov	QWORD[8+rdi],rbx
+	mov	QWORD[16+rdi],rcx
+	mov	QWORD[24+rdi],rdx
+	mov	QWORD[32+rdi],r8
+	mov	QWORD[40+rdi],r9
+	mov	QWORD[48+rdi],r10
+	mov	QWORD[56+rdi],r11
+	jb	NEAR $L$loop_avx
+
+	mov	rsi,QWORD[((128+24))+rsp]
+	vzeroupper
+	movaps	xmm6,XMMWORD[((128+32))+rsp]
+	movaps	xmm7,XMMWORD[((128+48))+rsp]
+	movaps	xmm8,XMMWORD[((128+64))+rsp]
+	movaps	xmm9,XMMWORD[((128+80))+rsp]
+	movaps	xmm10,XMMWORD[((128+96))+rsp]
+	movaps	xmm11,XMMWORD[((128+112))+rsp]
+	mov	r15,QWORD[rsi]
+	mov	r14,QWORD[8+rsi]
+	mov	r13,QWORD[16+rsi]
+	mov	r12,QWORD[24+rsi]
+	mov	rbp,QWORD[32+rsi]
+	mov	rbx,QWORD[40+rsi]
+	lea	rsp,[48+rsi]
+$L$epilogue_avx:
+	mov	rdi,QWORD[8+rsp]	;WIN64 epilogue
+	mov	rsi,QWORD[16+rsp]
+	DB	0F3h,0C3h		;repret
+$L$SEH_end_sha512_block_data_order_avx:
 EXTERN	__imp_RtlVirtualUnwind
 
 ALIGN	16
@@ -1903,9 +4190,23 @@
 	DD	$L$SEH_begin_sha512_block_data_order wrt ..imagebase
 	DD	$L$SEH_end_sha512_block_data_order wrt ..imagebase
 	DD	$L$SEH_info_sha512_block_data_order wrt ..imagebase
+	DD	$L$SEH_begin_sha512_block_data_order_xop wrt ..imagebase
+	DD	$L$SEH_end_sha512_block_data_order_xop wrt ..imagebase
+	DD	$L$SEH_info_sha512_block_data_order_xop wrt ..imagebase
+	DD	$L$SEH_begin_sha512_block_data_order_avx wrt ..imagebase
+	DD	$L$SEH_end_sha512_block_data_order_avx wrt ..imagebase
+	DD	$L$SEH_info_sha512_block_data_order_avx wrt ..imagebase
 section	.xdata rdata align=8
 ALIGN	8
 $L$SEH_info_sha512_block_data_order:
 DB	9,0,0,0
 	DD	se_handler wrt ..imagebase
 	DD	$L$prologue wrt ..imagebase,$L$epilogue wrt ..imagebase
+$L$SEH_info_sha512_block_data_order_xop:
+DB	9,0,0,0
+	DD	se_handler wrt ..imagebase
+	DD	$L$prologue_xop wrt ..imagebase,$L$epilogue_xop wrt ..imagebase
+$L$SEH_info_sha512_block_data_order_avx:
+DB	9,0,0,0
+	DD	se_handler wrt ..imagebase
+	DD	$L$prologue_avx wrt ..imagebase,$L$epilogue_avx wrt ..imagebase
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index 63b6b4b..cc5aa2f 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -17,3 +17,5 @@
 googlecode back up
 CIT outage - all slaves rebooted
 Authentication failure flake - rerun all bots
+Trigger bots after master restart - switch dart2js bots to use downloaded sdk.
+Trigger bots after master restart.
\ No newline at end of file
diff --git a/tools/VERSION b/tools/VERSION
index 8c51c08..c35c369 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL stable
 MAJOR 1
-MINOR 18
-PATCH 1
+MINOR 19
+PATCH 0
 PRERELEASE 0
 PRERELEASE_PATCH 0
diff --git a/tools/bots/bot.py b/tools/bots/bot.py
index cfd9076..b24fe74 100644
--- a/tools/bots/bot.py
+++ b/tools/bots/bot.py
@@ -271,14 +271,17 @@
     RunProcess(args)
 
 
-def RunProcess(command):
+def RunProcess(command, env=None):
   """
   Runs command.
 
   If a non-zero exit code is returned, raises an OSError with errno as the exit
   code.
   """
-  no_color_env = dict(os.environ)
+  if env is None:
+    no_color_env = dict(os.environ)
+  else:
+    no_color_env = env
   no_color_env['TERM'] = 'nocolor'
 
   exit_code = subprocess.call(command, env=no_color_env)
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index 00e7d35..ce8b5c9 100644
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -4,6 +4,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 os
 import os.path
 import shutil
 import sys
@@ -21,8 +22,26 @@
 
 def BuildSDK():
   with bot.BuildStep('Build SDK'):
+    sysroot_env =  dict(os.environ)
+    if BUILD_OS == 'linux':
+      ia32root = os.path.join(bot_utils.DART_DIR, '..', 'sysroots',
+                              'build', 'linux', 'debian_wheezy_i386-sysroot')
+      sysroot_env['CXXFLAGS'] = ("--sysroot=%s -I=/usr/include/c++/4.6 "
+               "-I=/usr/include/c++/4.6/i486-linux-gnu") % ia32root
+      sysroot_env['LDFLAGS'] = '--sysroot=%s' % ia32root
+      sysroot_env['CFLAGS'] = '--sysroot=%s' % ia32root
     Run([sys.executable, './tools/build.py', '--mode=release',
-         '--arch=ia32,x64', 'create_sdk'])
+         '--arch=ia32', 'create_sdk'], env=sysroot_env)
+
+    x64root = os.path.join(bot_utils.DART_DIR, '..', 'sysroots', 'build',
+                           'linux', 'debian_wheezy_amd64-sysroot')
+    if BUILD_OS == 'linux':
+      sysroot_env['CXXFLAGS'] = ("--sysroot=%s -I=/usr/include/c++/4.6 "
+              "-I=/usr/include/c++/4.6/x86_64-linux-gnu") % x64root
+      sysroot_env['LDFLAGS'] = '--sysroot=%s' % x64root
+      sysroot_env['CFLAGS'] = '--sysroot=%s' % x64root
+    Run([sys.executable, './tools/build.py', '--mode=release',
+         '--arch=x64', 'create_sdk'], env=sysroot_env)
 
 def BuildDartdocAPIDocs(dirname):
   dart_sdk = os.path.join(bot_utils.DART_DIR,
@@ -81,8 +100,9 @@
 
 def DartArchiveUploadSDKs(system, sdk32_zip, sdk64_zip):
   namer = bot_utils.GCSNamer(CHANNEL, bot_utils.ReleaseType.RAW)
-  revision = utils.GetArchiveVersion()
-  for revision in [revision, 'latest']:
+  git_number = utils.GetArchiveVersion()
+  git_hash = 'hash/%s' % utils.GetGitRevision()
+  for revision in [git_number, git_hash, 'latest']:
     path32 = namer.sdk_zipfilepath(revision, system, 'ia32', 'release')
     path64 = namer.sdk_zipfilepath(revision, system, 'x64', 'release')
     DartArchiveFile(sdk32_zip, path32, checksum_files=True)
@@ -213,9 +233,10 @@
                                                       mangled_filename)
     gsutil.upload(local_sha256, remote_path + '.sha256sum', public=True)
 
-def Run(command):
+def Run(command, env=None):
   print "Running %s" % ' '.join(command)
-  return bot.RunProcess(command)
+  print "Environment %s" % env
+  return bot.RunProcess(command, env=env)
 
 if __name__ == '__main__':
   # We always clobber the bot, to make sure releases are build from scratch
diff --git a/tools/bots/linux_distribution_support.py b/tools/bots/linux_distribution_support.py
index 6b8b2e8..5e859e4 100644
--- a/tools/bots/linux_distribution_support.py
+++ b/tools/bots/linux_distribution_support.py
@@ -116,7 +116,7 @@
       sys.exit(1)
 
     if build_info.builder_tag == "debian_wheezy":
-      if not "wheezy" in stdout:
+      if not "jessie" in stdout:
         print "Trying to build debian bits on a non debian system"
         print "You can't fix this, please contact ricow@ or whesse@"
         sys.exit(1)
diff --git a/tools/build.py b/tools/build.py
index 1f9eb8b..a27dd41 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -60,7 +60,7 @@
       default=utils.GuessArchitecture())
   result.add_option("--os",
     help='Target OSs (comma-separated).',
-    metavar='[all,host,android,fuchsia]',
+    metavar='[all,host,android]',
     default='host')
   result.add_option("-t", "--toolchain",
     help='Cross-compiler toolchain path',
@@ -88,7 +88,7 @@
 
 def ProcessOptions(options, args):
   if options.arch == 'all':
-    options.arch = 'ia32,x64,simarm,simarm64,simmips,simdbc'
+    options.arch = 'ia32,x64,simarm,simarm64,simmips,simdbc64'
   if options.mode == 'all':
     options.mode = 'debug,release,product'
   if options.os == 'all':
@@ -109,11 +109,11 @@
       return False
   options.os = [ProcessOsOption(os_name) for os_name in options.os]
   for os_name in options.os:
-    if not os_name in ['android', 'freebsd', 'fuchsia', 'linux', 'macos', 'win32']:
+    if not os_name in ['android', 'freebsd', 'linux', 'macos', 'win32']:
       print "Unknown os %s" % os_name
       return False
     if os_name != HOST_OS:
-      if os_name != 'android' and os_name != 'fuchsia':
+      if os_name != 'android':
         print "Unsupported target os %s" % os_name
         return False
       if not HOST_OS in ['linux']:
@@ -148,13 +148,6 @@
     if arch == 'x64':
       return os.path.join(android_toolchain, 'x86_64-linux-android')
 
-  if target_os == 'fuchsia':
-    fuchsia_toolchain = GetFuchsiaToolchainDir(HOST_OS, arch)
-    if arch == 'arm64':
-      return os.path.join(fuchsia_toolchain, 'aarch64-elf')
-    if arch == 'x64':
-      return os.path.join(fuchsia_toolchain, 'x86_64-elf')
-
   # If no cross compiler is specified, only try to figure one out on Linux.
   if not HOST_OS in ['linux']:
     raise Exception('Unless --toolchain is used cross-building is only '
@@ -182,8 +175,6 @@
   linker = ""
   if target_os == 'android':
     linker = os.path.join(DART_ROOT, 'tools', 'android_link.py')
-  elif target_os == 'fuchsia':
-    linker = os.path.join(DART_ROOT, 'tools', 'fuchsia_link.py')
   elif toolchainprefix:
     linker = toolchainprefix + "-g++"
 
@@ -235,28 +226,6 @@
   return android_toolchain
 
 
-def GetFuchsiaToolchainDir(host_os, target_arch):
-  global THIRD_PARTY_ROOT
-  if host_os not in ['linux']:
-    raise Exception('Unsupported host os %s' % host_os)
-  if target_arch not in ['x64', 'arm64',]:
-    raise Exception('Unsupported target architecture %s' % target_arch)
-
-  # Set up path to the Android NDK.
-  CheckDirExists(THIRD_PARTY_ROOT, 'third party tools')
-  fuchsia_tools = os.path.join(THIRD_PARTY_ROOT, 'fuchsia_tools')
-  CheckDirExists(fuchsia_tools, 'Fuchsia tools')
-
-  toolchain_arch = 'x86_64-elf-5.3.0-Linux-x86_64'
-  if target_arch == 'arm64':
-    toolchain_arch = 'aarch64-elf-5.3.0-Linux-x86_64'
-  fuchsia_toolchain = os.path.join(
-      fuchsia_tools, 'toolchains', toolchain_arch, 'bin')
-  CheckDirExists(fuchsia_toolchain, 'Fuchsia toolchain')
-
-  return fuchsia_toolchain
-
-
 def Execute(args):
   process = subprocess.Popen(args)
   process.wait()
diff --git a/tools/create_debian_chroot.sh b/tools/create_debian_chroot.sh
index 0f42c3e3..1cfcf1e 100755
--- a/tools/create_debian_chroot.sh
+++ b/tools/create_debian_chroot.sh
@@ -72,13 +72,13 @@
     wheezy $CHROOT http://http.us.debian.org/debian/
 chroot $CHROOT apt-get update
 chroot $CHROOT apt-get -y install \
-    debhelper python g++-4.6 git subversion
+    debhelper python git gcc sudo make
 
 # Add chrome-bot user.
-chroot $CHROOT groupadd --gid 1000 chrome-bot
-chroot $CHROOT useradd --gid 1000 --uid 1000 --create-home chrome-bot
+chroot $CHROOT groupadd --gid 1001 chrome-bot
+chroot $CHROOT useradd --gid 1001 --uid 1001 --create-home chrome-bot
 mkdir $CHROOT/b
-chown 1000:1000 $CHROOT/b
+chown 1001:1001 $CHROOT/b
 
 # Create trampoline script for running the initialization as chrome-bot.
 cat << EOF > $CHROOT/b/init_chroot_trampoline.sh
@@ -111,6 +111,6 @@
 
 chmod 755 $CHROOT/b/init_chroot_trampoline.sh
 
-chown 1000:1000 $CHROOT/b/init_chroot.sh
+chown 1001:1001 $CHROOT/b/init_chroot.sh
 chmod 755 $CHROOT/b/init_chroot.sh
 chroot $CHROOT /bin/sh /b/init_chroot_trampoline.sh
diff --git a/tools/create_debian_packages.py b/tools/create_debian_packages.py
index 4a6dddb..d267e80 100755
--- a/tools/create_debian_packages.py
+++ b/tools/create_debian_packages.py
@@ -101,7 +101,7 @@
     source_package = [
       '%s-1.dsc' % debbase,
       '%s.orig.tar.gz' % debbase,
-      '%s-1.debian.tar.gz' % debbase
+      '%s-1.debian.tar.xz' % debbase
     ]
     i386_package = [
       '%s-1_i386.deb' % debbase
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 65f585e..85ba811 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -44,7 +44,6 @@
 # ......dart_client.platform
 # ......dart_server.platform
 # ......dart_shared.platform
-# ......dart2dart.platform
 # ......_internal/
 #.........spec.sum
 #.........strong.sum
@@ -59,6 +58,7 @@
 # ......io/
 # ......isolate/
 # ......js/
+# ......js_util/
 # ......math/
 # ......mirrors/
 # ......typed_data/
@@ -254,7 +254,7 @@
                   join('html', 'dart2js'), join('html', 'dartium'),
                   join('html', 'html_common'),
                   join('indexed_db', 'dart2js'), join('indexed_db', 'dartium'),
-                  'js', 'math', 'mirrors', 'profiler', 'typed_data',
+                  'js', 'js_util', 'math', 'mirrors', 'profiler', 'typed_data',
                   join('svg', 'dart2js'), join('svg', 'dartium'),
                   join('web_audio', 'dart2js'), join('web_audio', 'dartium'),
                   join('web_gl', 'dart2js'), join('web_gl', 'dartium'),
@@ -266,8 +266,7 @@
   # Copy the platform descriptors.
   for file_name in ["dart_client.platform",
                     "dart_server.platform",
-                    "dart_shared.platform",
-                    "dart2dart.platform"]:
+                    "dart_shared.platform"]:
     copyfile(join(HOME, 'sdk', 'lib', file_name), join(LIB, file_name));
 
   # Copy libraries.dart to lib/_internal/libraries.dart for backwards
diff --git a/tools/dartium/generate_patches.sh b/tools/dartium/generate_patches.sh
index 40dc895..11c73b8 100755
--- a/tools/dartium/generate_patches.sh
+++ b/tools/dartium/generate_patches.sh
@@ -26,17 +26,17 @@
 #       build Dartium, run this script and build Dartium again with the newly
 #       generated patches. 
 
-LOCATION_DARTIUM="../../../out/Release"
-DARTIUM="$LOCATION_DARTIUM"
+if [[ "$1" != "" ]] ; then
+  DARTIUM="$1"
+else
+  LOCATION_DARTIUM="../../../out/Release"
+  DARTIUM="$LOCATION_DARTIUM"
+fi
 
 DART_APP_LOCATION="file://"$PWD"/generate_app/generate_cached_patches.html"
 DARTIUM_ARGS=" --user-data-dir=out --disable-web-security --no-sandbox --enable-blink-features=dartGenCachedPatches"
 CACHED_PATCHES_FILE=""$PWD"/../../sdk/lib/js/dartium/cached_patches.dart"
 
-if [[ "$1" != "" ]] ; then
-  DARTIM="$1"
-fi
-
 cmd=""$DARTIUM"/chrome "$DARTIUM_ARGS" "$DART_APP_LOCATION" |
   (sed -n '/START_OF_CACHED_PATCHES/,/END_OF_CACHED_PATCHES/p') > "$CACHED_PATCHES_FILE""
 
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index a12cdc3..00ba641 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -9,7 +9,7 @@
 
 vars.update({
   "dartium_chromium_commit": "67a7ba9669f7bb0300ef35085d4e6bb98b1966cc",
-  "dartium_webkit_commit": "d3db7d1b53979ca91cbf8f3117971f49d0fddf13",
+  "dartium_webkit_commit": "522da5fa29843cb44afdc20328be356f693685d6",
   "chromium_base_revision": "338390",
 
   # We use mirrors of all github repos to guarantee reproducibility and
diff --git a/tools/dom/scripts/dartdomgenerator.py b/tools/dom/scripts/dartdomgenerator.py
index c0315df2..6459e45 100755
--- a/tools/dom/scripts/dartdomgenerator.py
+++ b/tools/dom/scripts/dartdomgenerator.py
@@ -287,6 +287,9 @@
   parser.add_option('--gen-interop', dest='dart_js_interop',
                     action='store_true', default=False,
                     help='Use Javascript objects (dart:js) accessing the DOM in _blink')
+  parser.add_option('--no-cached-patches', dest='no_cached_patches',
+                    action='store_true', default=False,
+                    help='Do not generate the sdk/lib/js/cached_patches.dart file')
 
   (options, args) = parser.parse_args()
 
@@ -346,13 +349,14 @@
           os.path.join(dartium_output_dir, '%s_dartium.dart' % library_name),
           os.path.join('..', '..', '..', 'sdk', 'lib', library_name, 'dartium'))
 
-    # Blow away the cached_patches.dart needs to be re-generated for Dartium
-    # see tools/dartium/generate_patches.sh
-    cached_patches_filename = os.path.join('..', '..', '..', 'sdk', 'lib', 'js', 'dartium',
-                                           'cached_patches.dart')
-    cached_patches = open(cached_patches_filename, 'w')
-    cached_patches.write(CACHED_PATCHES);
-    cached_patches.close()
+    if (not(options.no_cached_patches)):
+      # Blow away the cached_patches.dart needs to be re-generated for Dartium
+      # see tools/dartium/generate_patches.sh
+      cached_patches_filename = os.path.join('..', '..', '..', 'sdk', 'lib', 'js', 'dartium',
+                                             'cached_patches.dart')
+      cached_patches = open(cached_patches_filename, 'w')
+      cached_patches.write(CACHED_PATCHES);
+      cached_patches.close()
 
   if '_blink' in systems:
     _logger.info('Generating dartium _blink file.')
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 2b2d594..339a33c 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -152,6 +152,11 @@
       "@Creates('Null')",
     ],
 
+    'Gamepad.buttons': [
+        "@Creates('JSExtendableArray|GamepadButton')",
+        "@Returns('JSExtendableArray')",
+    ],
+
     'HTMLCanvasElement.getContext': [
       "@Creates('CanvasRenderingContext2D|RenderingContext')",
       "@Returns('CanvasRenderingContext2D|RenderingContext|Null')",
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index db47521..8c5b416 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -321,14 +321,47 @@
 
     'TransitionEvent': 'TransitionEvent,WebKitTransitionEvent',
 
-    'WebGLLoseContext': 'WebGLLoseContext,WebGLExtensionLoseContext',
-
     'CSSKeyframeRule':
         'CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule',
 
     'CSSKeyframesRule':
         'CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule',
 
+    # webgl extensions are sometimes named directly after the getExtension
+    # parameter (e.g on Firefox).
+
+    'ANGLEInstancedArrays': 'ANGLEInstancedArrays,ANGLE_instanced_arrays',
+    'EXTsRGB': 'EXTsRGB,EXT_sRGB',
+    'EXTBlendMinMax': 'EXTBlendMinMax,EXT_blend_minmax',
+    'EXTFragDepth': 'EXTFragDepth,EXT_frag_depth',
+    'EXTShaderTextureLOD': 'EXTShaderTextureLOD,EXT_shader_texture_lod',
+    'EXTTextureFilterAnisotropic':
+        'EXTTextureFilterAnisotropic,EXT_texture_filter_anisotropic',
+    'OESElementIndexUint': 'OESElementIndexUint,OES_element_index_uint',
+    'OESStandardDerivatives': 'OESStandardDerivatives,OES_standard_derivatives',
+    'OESTextureFloat': 'OESTextureFloat,OES_texture_float',
+    'OESTextureFloatLinear': 'OESTextureFloatLinear,OES_texture_float_linear',
+    'OESTextureHalfFloat': 'OESTextureHalfFloat,OES_texture_half_float',
+    'OESTextureHalfFloatLinear':
+        'OESTextureHalfFloatLinear,OES_texture_half_float_linear',
+    'OESVertexArrayObject':
+        'OESVertexArrayObject,OES_vertex_array_object',
+    'WebGLCompressedTextureATC':
+        'WebGLCompressedTextureATC,WEBGL_compressed_texture_atc',
+    'WebGLCompressedTextureETC1':
+        'WebGLCompressedTextureETC1,WEBGL_compressed_texture_etc1',
+    'WebGLCompressedTexturePVRTC':
+        'WebGLCompressedTexturePVRTC,WEBGL_compressed_texture_pvrtc',
+    'WebGLCompressedTextureS3TC':
+        'WebGLCompressedTextureS3TC,WEBGL_compressed_texture_s3tc',
+    'WebGLDebugRendererInfo': 'WebGLDebugRendererInfo,WEBGL_debug_renderer_info',
+    'WebGLDebugShaders': 'WebGLDebugShaders,WEBGL_debug_shaders',
+    'WebGLDepthTexture': 'WebGLDepthTexture,WEBGL_depth_texture',
+    'WebGLDrawBuffers': 'WebGLDrawBuffers,WEBGL_draw_buffers',
+    'WebGLLoseContext':
+        'WebGLLoseContext,WebGLExtensionLoseContext,WEBGL_lose_context',
+
+
 }, dart2jsOnly=True)
 
 def IsRegisteredType(type_name):
@@ -698,7 +731,7 @@
               # Events fired need use a JSFunction not a anonymous closure to
               # insure the event can really be removed.
               parameters.append('js.allowInterop(%s)' % p.name)
-# These commented out cases don't actually generate any code.              
+# These commented out cases don't actually generate any code.
 #          elif dart_js_interop and type_id == 'FontFaceSetForEachCallback':
               # forEach is supported in the DOM for FontFaceSet as it iterates
               # over the Javascript Object the callback parameters are also
@@ -1103,6 +1136,9 @@
   def list_item_type(self):
     return self._data.item_type
 
+  def list_item_type_nullable(self):
+    return self._data.item_type_nullable
+
   def merged_interface(self):
     # All constants, attributes, and operations of merged interface should be
     # added to this interface. Merged idl interface does not have corresponding
@@ -1357,7 +1393,8 @@
                conversion_includes=None,
                webcore_getter_name='getAttribute',
                webcore_setter_name='setAttribute',
-               item_type=None, suppress_interface=False):
+               item_type=None, item_type_nullable=False,
+               suppress_interface=False):
     self.clazz = clazz
     self.dart_type = dart_type
     self.native_type = native_type
@@ -1369,6 +1406,7 @@
     self.webcore_getter_name = webcore_getter_name
     self.webcore_setter_name = webcore_setter_name
     self.item_type = item_type
+    self.item_type_nullable = item_type_nullable
     self.suppress_interface = suppress_interface
 
 
@@ -1455,7 +1493,7 @@
         dart_type='List<File>'),
     'Future': TypeData(clazz='Interface', dart_type='Future'),
     'GamepadList': TypeData(clazz='Interface', item_type='Gamepad',
-        suppress_interface=True),
+        item_type_nullable=True, suppress_interface=True),
     'GLenum': TypeData(clazz='Primitive', dart_type='int',
         native_type='unsigned'),
     'GLboolean': TypeData(clazz='Primitive', dart_type='bool',
diff --git a/tools/dom/scripts/go.sh b/tools/dom/scripts/go.sh
index a830a9b..99c4e72 100755
--- a/tools/dom/scripts/go.sh
+++ b/tools/dom/scripts/go.sh
@@ -20,6 +20,12 @@
 #
 #   ./go.sh dart2js,htmldartium
 #
+# To re-gen all sdk/lib files (outside of a Dartium enlistment the file
+# 'sdk/lib/js/cached_patches.dart' might not need to be generated).  To run
+# go.sh w/o the patches files used --no-cached-patches switch e.g.,
+#
+#  ./go.sh --no-cached-patches
+#
 # The following gives a picture of the changes due to 'work'
 #
 #   git checkout master               # select client without changes
@@ -33,8 +39,20 @@
 SYSTEMS="$ALLSYSTEMS"
 
 if [[ "$1" != "" ]] ; then
-  SYSTEMS="$1"
+  if [[ "$1" =~ ^-- ]]; then
+      ARG_OPTION="$1"
+  else
+      SYSTEMS="$1"
+  fi
+fi
+
+if [[ "$2" != "" ]] ; then
+  if [[ "$2" =~ ^-- ]]; then
+      ARG_OPTION="$2"
+  else
+      SYSTEMS="$2"
+  fi
 fi
 
 reset && \
-./dartdomgenerator.py --systems="$SYSTEMS" --logging=40 --update-dom-metadata --gen-interop
+./dartdomgenerator.py --systems="$SYSTEMS" --logging=40 --update-dom-metadata --gen-interop "$ARG_OPTION"
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 8397b8f..2d5e52d 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -83,7 +83,8 @@
     element_type = None
     requires_indexer = False
     if self._interface_type_info.list_item_type():
-      self.AddIndexer(self._interface_type_info.list_item_type())
+      self.AddIndexer(self._interface_type_info.list_item_type(),
+                      self._interface_type_info.list_item_type_nullable())
     else:
       for parent in self._database.Hierarchy(self._interface):
         if parent == self._interface:
@@ -759,7 +760,7 @@
              NAME=method_name,
              PARAMS=operation.ParametersAsDeclaration(self._DartType))
 
-  def EmitListMixin(self, element_name):
+  def EmitListMixin(self, element_name, nullable):
     # TODO(sra): Use separate mixins for mutable implementations of List<T>.
     # TODO(sra): Use separate mixins for typed array implementations of List<T>.
     template_file = 'immutable_list_mixin.darttemplate'
@@ -795,7 +796,12 @@
           'DEFINE_LENGTH_SETTER': not has_length_setter,
           'USE_NATIVE_INDEXED_GETTER': _HasNativeIndexedGetter(self) or _HasExplicitIndexedGetter(self),
         })
-    self._members_emitter.Emit(template, E=element_name, GETTER=getter_name)
+    if nullable:
+        element_js = element_name + "|Null"
+    else:
+        element_js = element_name
+    self._members_emitter.Emit(template, E=element_name, EJS=element_js,
+                               GETTER=getter_name)
 
   def SecureOutputType(self, type_name, is_dart_type=False,
       can_narrow_type=False):
@@ -870,7 +876,7 @@
         else:
           param_type = self._NarrowInputType(arg.type.id)
           # Verified by argument checking on entry to the dispatcher.
-  
+
           verified_type = self._InputType(
               info.param_infos[position].type_id, info)
           # The native method does not need an argument type if we know the type.
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 2208f22..4fc7e6e 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -838,7 +838,7 @@
         break
     return has_indexed_getter
 
-  def AddIndexer(self, element_type):
+  def AddIndexer(self, element_type, nullable):
     """Adds all the methods required to complete implementation of List."""
     # We would like to simply inherit the implementation of everything except
     # length, [], and maybe []=.  It is possible to extend from a base
@@ -861,8 +861,8 @@
     has_indexed_getter = self.HasIndexedGetter()
 
     if has_indexed_getter:
-      indexed_getter = ('JS("%s", "#[#]", this, index)' %
-          self.SecureOutputType(element_type));
+      indexed_getter = ('JS("%s%s", "#[#]", this, index)' %
+          (self.SecureOutputType(element_type), "|Null" if nullable else ""));
     elif any(op.id == 'getItem' for op in self._interface.operations):
       indexed_getter = 'this.getItem(index)'
     elif any(op.id == 'item' for op in self._interface.operations):
@@ -894,7 +894,7 @@
           '  }\n',
           TYPE=self._NarrowInputType(element_type))
 
-    self.EmitListMixin(self._DartType(element_type))
+    self.EmitListMixin(self._DartType(element_type), nullable)
 
   def EmitAttribute(self, attribute, html_name, read_only):
     if self._HasCustomImplementation(attribute.id):
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index f6284ab..659d24c 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -548,7 +548,7 @@
         # JsObject maybe stored in the Dart class.
         return_wrap_jso = wrap_return_type_blink(return_type, attr.type.id, self._type_registry)
     wrap_unwrap_list.append(return_wrap_jso)       # wrap_jso the returned object
-    wrap_unwrap_list.append(self._dart_use_blink) 
+    wrap_unwrap_list.append(self._dart_use_blink)
 
     # This seems to have been replaced with Custom=Getter (see above), but
     # check to be sure we don't see the old syntax
@@ -638,7 +638,7 @@
     raises = ('RaisesException' in attr.ext_attrs and
               attr.ext_attrs['RaisesException'] != 'Getter')
 
-  def AddIndexer(self, element_type):
+  def AddIndexer(self, element_type, nullable):
     """Adds all the methods required to complete implementation of List."""
     # We would like to simply inherit the implementation of everything except
     # length, [], and maybe []=.  It is possible to extend from a base
@@ -709,7 +709,7 @@
           '  }\n',
           TYPE=dart_element_type)
 
-    self.EmitListMixin(dart_element_type)
+    self.EmitListMixin(dart_element_type, nullable)
 
   def AmendIndexer(self, element_type):
     # If interface is marked as having native indexed
diff --git a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
index 8077fb0..f5b7e1b 100644
--- a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
@@ -24,14 +24,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point(_clientX, _clientY);
+  Point get client => new Point/*<num>*/(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @Experimental()
-  Point get movement => new Point(_movementX, _movementY);
+  Point get movement => new Point/*<num>*/(_movementX, _movementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -44,7 +44,7 @@
     if (JS('bool', '!!#.offsetX', this)) {
       var x = JS('int', '#.offsetX', this);
       var y = JS('int', '#.offsetY', this);
-      return new Point(x, y);
+      return new Point/*<num>*/(x, y);
     } else {
       // Firefox does not support offsetX.
       if (!(this.target is Element)) {
@@ -53,19 +53,19 @@
       }
       Element target = this.target;
       var point = (this.client - target.getBoundingClientRect().topLeft);
-      return new Point(point.x.toInt(), point.y.toInt());
+      return new Point/*<num>*/(point.x.toInt(), point.y.toInt());
     }
   }
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point(_screenX, _screenY);
+  Point get screen => new Point/*<num>*/(_screenX, _screenY);
 
   @DomName('MouseEvent.layerX')
   @DomName('MouseEvent.layerY')
-  Point get layer => new Point(_layerX, _layerY);
+  Point get layer => new Point/*<num>*/(_layerX, _layerY);
 
   @DomName('MouseEvent.pageX')
   @DomName('MouseEvent.pageY')
-  Point get page => new Point(_pageX, _pageY);
+  Point get page => new Point/*<num>*/(_pageX, _pageY);
 }
diff --git a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
index 1b2bbc8..229afe6 100644
--- a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
@@ -43,14 +43,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point(_clientX, _clientY);
+  Point get client => new Point/*<num>*/(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.FIREFOX)
   @Experimental()
-  Point get movement => new Point(_movementX, _movementY);
+  Point get movement => new Point/*<num>*/(_movementX, _movementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -59,17 +59,17 @@
    * after the event has fired or if the element has CSS transforms affecting
    * it.
    */
-  Point get offset => new Point(_offsetX, _offsetY);
+  Point get offset => new Point/*<num>*/(_offsetX, _offsetY);
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point(_screenX, _screenY);
+  Point get screen => new Point/*<num>*/(_screenX, _screenY);
 
   @DomName('MouseEvent.layerX')
   @DomName('MouseEvent.layerY')
-  Point get layer => new Point(_layerX, _layerY);
+  Point get layer => new Point/*<num>*/(_layerX, _layerY);
 
   @DomName('MouseEvent.pageX')
   @DomName('MouseEvent.pageY')
-  Point get page => new Point(_pageX, _pageY);
+  Point get page => new Point/*<num>*/(_pageX, _pageY);
 }
diff --git a/tools/dom/templates/html/impl/impl_ClientRect.darttemplate b/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
index 22f115e..f52240a 100644
--- a/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
+++ b/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
@@ -89,11 +89,11 @@
            another.y <= top + height;
   }
 
-  Point get topLeft => new Point(this.left, this.top);
-  Point get topRight => new Point(this.left + this.width, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
+  Point get topLeft => new Point/*<num>*/(this.left, this.top);
+  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
+  Point get bottomRight => new Point/*<num>*/(this.left + this.width,
       this.top + this.height);
-  Point get bottomLeft => new Point(this.left,
+  Point get bottomLeft => new Point/*<num>*/(this.left,
       this.top + this.height);
 
   $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_DOMRectReadOnly.darttemplate b/tools/dom/templates/html/impl/impl_DOMRectReadOnly.darttemplate
index b17b5bc..e9bf8a6 100644
--- a/tools/dom/templates/html/impl/impl_DOMRectReadOnly.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DOMRectReadOnly.darttemplate
@@ -89,11 +89,11 @@
            another.y <= top + height;
   }
 
-  Point get topLeft => new Point(this.left, this.top);
-  Point get topRight => new Point(this.left + this.width, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
+  Point get topLeft => new Point/*<num>*/(this.left, this.top);
+  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
+  Point get bottomRight => new Point/*<num>*/(this.left + this.width,
       this.top + this.height);
-  Point get bottomLeft => new Point(this.left,
+  Point get bottomLeft => new Point/*<num>*/(this.left,
       this.top + this.height);
 
   $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index c9ef54a..e89c912 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -1272,13 +1272,13 @@
 $endif
     bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
     if (current == null || sameAsParent) {
-      if (foundAsParent) return new Point(0, 0);
+      if (foundAsParent) return new Point/*<num>*/(0, 0);
       throw new ArgumentError("Specified element is not a transitive offset "
           "parent of this element.");
     }
     Element parentOffset = current.offsetParent;
     Point p = Element._offsetToHelper(parentOffset, parent);
-    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
+    return new Point/*<num>*/(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
 
   static HtmlDocument _parseDocument;
diff --git a/tools/dom/templates/html/impl/impl_Touch.darttemplate b/tools/dom/templates/html/impl/impl_Touch.darttemplate
index 889485d..a23e2f5 100644
--- a/tools/dom/templates/html/impl/impl_Touch.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Touch.darttemplate
@@ -32,15 +32,15 @@
 
   @DomName('Touch.clientX')
   @DomName('Touch.clientY')
-  Point get client => new Point(__clientX, __clientY);
+  Point get client => new Point/*<num>*/(__clientX, __clientY);
 
   @DomName('Touch.pageX')
   @DomName('Touch.pageY')
-  Point get page => new Point(__pageX, __pageY);
+  Point get page => new Point/*<num>*/(__pageX, __pageY);
 
   @DomName('Touch.screenX')
   @DomName('Touch.screenY')
-  Point get screen => new Point(__screenX, __screenY);
+  Point get screen => new Point/*<num>*/(__screenX, __screenY);
 
   @DomName('Touch.radiusX')
   @DocsEditable()
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index b9820dc..02b0b4e 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -15,7 +15,7 @@
   $E get first {
     if (this.length > 0) {
 $if DART2JS
-      return JS('$E', '#[0]', this);
+      return JS('$EJS', '#[0]', this);
 $else
 $if USE_NATIVE_INDEXED_GETTER
       return $GETTER(0);
@@ -31,7 +31,7 @@
     int len = this.length;
     if (len > 0) {
 $if DART2JS
-      return JS('$E', '#[#]', this, len - 1);
+      return JS('$EJS', '#[#]', this, len - 1);
 $else
 $if USE_NATIVE_INDEXED_GETTER
       return $GETTER(len - 1);
@@ -47,7 +47,7 @@
     int len = this.length;
     if (len == 1) {
 $if DART2JS
-      return JS('$E', '#[0]', this);
+      return JS('$EJS', '#[0]', this);
 $else
 $if USE_NATIVE_INDEXED_GETTER
       return $GETTER(0);
diff --git a/tools/download_chromium_sysroot.sh b/tools/download_chromium_sysroot.sh
new file mode 100755
index 0000000..75b3744
--- /dev/null
+++ b/tools/download_chromium_sysroot.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Downloads the ia32 and x64 Debian wheezy sysroot that chromium uses,
+# Only tested and used on Ubuntu trusty linux. Used to keep glibc version low.
+# Creates directories called "build" and "tools" in the current directory.
+# After running this, source set_ia32_sysroot.sh or set_x64_sysroot.sh, in 
+# the same working directory, to set the compilation environment variables.
+# Sourcing a script means running the script with a '.', so that it runs
+# in the current shell, not a subshell, as in:
+#   . sdk/tools/set_ia32_sysroot.sh
+
+git clone https://chromium.googlesource.com/chromium/src/build
+mkdir tools
+cd tools
+git clone https://chromium.googlesource.com/external/gyp
+cd ..
+
+build/linux/sysroot_scripts/install-sysroot.py --arch i386
+build/linux/sysroot_scripts/install-sysroot.py --arch amd64
diff --git a/tools/fuchsia_link.py b/tools/fuchsia_link.py
deleted file mode 100755
index c3c537b..0000000
--- a/tools/fuchsia_link.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2016 The Dart Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-This script performs the final link step for Fuchsia NDK executables.
-Usage:
-./fuchsia_link {arm,arm64,ia32} {executable,library,shared_library}
-               {host,target} [linker args]
-"""
-
-import os
-import subprocess
-import sys
-
-# Figure out where we are.
-SCRIPT_DIR = os.path.dirname(sys.argv[0])
-DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
-THIRD_PARTY_ROOT = os.path.join(DART_ROOT, 'third_party')
-
-
-def CheckDirExists(path, docstring):
-  if not os.path.isdir(path):
-    raise Exception('Could not find %s directory %s'
-          % (docstring, path))
-
-
-def execute(args):
-  process = subprocess.Popen(args)
-  process.wait()
-  return process.returncode
-
-
-def main():
-  if len(sys.argv) < 5:
-    raise Exception(sys.argv[0] + " failed: not enough arguments")
-
-  # gyp puts -shared first in a shared_library link. Remove it.
-  if sys.argv[1] == '-shared':
-    sys.argv.remove('-shared')
-
-  # Grab the command line arguments.
-  target_arch = sys.argv[1]
-  link_type = sys.argv[2]
-  link_target = sys.argv[3]
-  link_args = sys.argv[4:]
-
-  # Check arguments.
-  if target_arch not in ['arm64', 'x64',]:
-    raise Exception(sys.argv[0] +
-        " first argument must be 'arm64', or 'x64'")
-  if link_type not in ['executable', 'library', 'shared_library']:
-    raise Exception(sys.argv[0] +
-      " second argument must be 'executable' or 'library' or 'shared_library'")
-  if link_target not in ['host', 'target']:
-    raise Exception(sys.argv[0] + " third argument must be 'host' or 'target'")
-
-  # TODO(zra): Figure out how to link a shared library with the
-  # cross-compilers. For now, we disable it by generating empty files
-  # for the results. We disable it here to avoid inspecting the OS type in
-  # the gyp files.
-  if link_type == 'shared_library':
-    print "NOT linking shared library for Fuchsia."
-    o_index = link_args.index('-o')
-    output = os.path.join(DART_ROOT, link_args[o_index + 1])
-    open(output, 'a').close()
-    sys.exit(0)
-
-  # Set up path to the Fuchsia NDK.
-  CheckDirExists(THIRD_PARTY_ROOT, 'third party tools')
-  fuchsia_tools = os.path.join(THIRD_PARTY_ROOT, 'fuchsia_tools')
-  CheckDirExists(fuchsia_tools, 'Fuchsia tools')
-
-  # Set up the directory of the Fuchsia NDK cross-compiler toolchain.
-  toolchain_arch = 'x86_64-elf-5.3.0-Linux-x86_64'
-  if target_arch == 'arm64':
-    toolchain_arch = 'aarch64-elf-5.3.0-Linux-x86_64'
-  fuchsia_toolchain = os.path.join(
-      fuchsia_tools, 'toolchains', toolchain_arch, 'bin')
-  CheckDirExists(fuchsia_toolchain, 'Fuchsia toolchain')
-
-  # Set up the path to the linker executable.
-  fuchsia_linker = os.path.join(fuchsia_toolchain, 'x86_64-elf-g++')
-  if target_arch == 'arm64':
-    fuchsia_linker = os.path.join(fuchsia_toolchain, 'aarch64-elf-c++')
-
-  # Grab the path to libgcc.a, which we must explicitly add to the link,
-  # by invoking the cross-compiler with the -print-libgcc-file-name flag.
-  fuchsia_gcc = os.path.join(fuchsia_toolchain, 'x86_64-elf-gcc')
-  if target_arch == 'arm64':
-    fuchsia_gcc = os.path.join(fuchsia_toolchain, 'aarch64-elf-gcc')
-  fuchsia_libgcc = subprocess.check_output(
-      [fuchsia_gcc, '-print-libgcc-file-name']).strip()
-
-  # Set up the path to the system root directory, which is where we'll find the
-  # Fuchsia specific system includes and libraries.
-  fuchsia_sysroot = os.path.join(fuchsia_tools, 'sysroot', 'x86_64')
-  if target_arch == 'arm64':
-    fuchsia_sysroot = os.path.join(fuchsia_tools, 'sysroot', 'arm64')
-  CheckDirExists(fuchsia_sysroot, 'Fuchsia sysroot')
-  fuchsia_lib = os.path.join(fuchsia_sysroot, 'usr', 'lib')
-  crtn_fuchsia = os.path.join(fuchsia_lib, 'crtn.o')
-
-  if link_target == 'target':
-    # Add and remove libraries as listed in configurations_fuchsia.gypi
-    libs_to_rm = ['-lrt', '-lpthread', '-ldl']
-    libs_to_add = [fuchsia_libgcc, '-lc',]
-
-    # Add crtn_fuchsia to end if we are linking an executable.
-    if link_type == 'executable':
-      libs_to_add.extend([crtn_fuchsia])
-
-    link_args = [i for i in link_args if i not in libs_to_rm]
-    link_args.extend(libs_to_add)
-
-    link_args.insert(0, fuchsia_linker)
-  else:
-    link_args.extend(['-ldl', '-lrt'])
-    link_args.insert(0, 'g++')
-
-  print ' '.join(link_args)
-  sys.exit(execute(link_args))
-
-if __name__ == '__main__':
-  main()
diff --git a/tools/gyp/configurations.gypi b/tools/gyp/configurations.gypi
index 267be04..29f457e 100644
--- a/tools/gyp/configurations.gypi
+++ b/tools/gyp/configurations.gypi
@@ -41,7 +41,6 @@
   },
   'includes': [
     'configurations_android.gypi',
-    'configurations_fuchsia.gypi',
     'configurations_make.gypi',
     'configurations_xcode.gypi',
     'configurations_msvs.gypi',
@@ -730,21 +729,6 @@
         ],
       },
 
-      # Fuchsia configurations. The configuration names explicitly include
-      # 'Fuchsia' because we are cross-building from Linux, and, when building
-      # the standalone VM, we cannot inspect the gyp built-in 'OS' variable to
-      # figure out that we are building for Fuchsia. Since we have not re-run
-      # gyp, it will still be 'linux'.
-      'ProductFuchsiaX64': {
-        'inherit_from': [
-          'Dart_Base', 'Dart_x64_Base', 'Dart_Product',
-          'Dart_Fuchsia_Base',
-          'Dart_Fuchsia_x64_Base',
-          'Dart_Fuchsia_Product',
-        ],
-      },
-
-
       # Android configurations. The configuration names explicitly include
       # 'Android' because we are cross-building from Linux, and, when building
       # the standalone VM, we cannot inspect the gyp built-in 'OS' variable to
diff --git a/tools/gyp/configurations_fuchsia.gypi b/tools/gyp/configurations_fuchsia.gypi
deleted file mode 100644
index 5b291d3..0000000
--- a/tools/gyp/configurations_fuchsia.gypi
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# Definitions for building standalone Dart binaries to run on Fuchsia.
-
-{
-  'variables': {
-    'fuchsia_tools': '<(PRODUCT_DIR)/../../third_party/fuchsia_tools/',
-  },  # variables
-  'target_defaults': {
-    'configurations': {
-      'Dart_Fuchsia_Base': {
-        'abstract': 1,
-        'cflags': [
-          '-Werror',
-          '<@(common_gcc_warning_flags)',
-          '-Wnon-virtual-dtor',
-          '-Wvla',
-          '-Woverloaded-virtual',
-          '-g3',
-          '-ggdb3',
-          '-fno-rtti',
-          '-fno-exceptions',
-          '-fstack-protector',
-          '-Wa,--noexecstack',
-        ],
-        'target_conditions': [
-          ['_toolset=="target"', {
-            'cflags!': [
-              '-pthread',  # Not supported by Android toolchain.
-            ],
-          }],
-        ],
-      },
-      'Dart_Fuchsia_Debug': {
-        'abstract': 1,
-        'defines': [
-          'DEBUG',
-        ],
-        'cflags': [
-          '-fno-omit-frame-pointer',
-        ],
-      },
-      'Dart_Fuchsia_Release': {
-        'abstract': 1,
-        'defines': [
-          'NDEBUG',
-        ],
-        'cflags!': [
-          '-O2',
-          '-Os',
-        ],
-        'cflags': [
-          '-fno-omit-frame-pointer',
-          '-fdata-sections',
-          '-ffunction-sections',
-          '-O3',
-        ],
-      },
-      'Dart_Fuchsia_Product': {
-        'abstract': 1,
-        'defines': [
-          'NDEBUG',
-          'PRODUCT',
-        ],
-        'cflags!': [
-          '-O2',
-          '-Os',
-        ],
-        'cflags': [
-          '-fdata-sections',
-          '-ffunction-sections',
-          '-O3',
-        ],
-      },
-      'Dart_Fuchsia_x64_Base': {
-        'abstract': 1,
-        'variables': {
-          'fuchsia_sysroot': '<(fuchsia_tools)/sysroot/x86_64',
-          'fuchsia_include': '<(fuchsia_sysroot)/usr/include',
-          'fuchsia_lib': '<(fuchsia_sysroot)/usr/lib',
-        },
-        'target_conditions': [
-          ['_toolset=="target"', {
-            'defines': [
-              'TARGET_OS_FUCHSIA',
-            ],
-            'cflags': [
-              '--sysroot=<(fuchsia_sysroot)',
-              '-I<(fuchsia_include)',
-              '-fno-threadsafe-statics',
-            ],
-            'ldflags': [
-              'x64', '>(_type)', 'target',
-              '-nostdlib',
-              '-T<(fuchsia_sysroot)/usr/user.ld',
-              '-L<(fuchsia_lib)',
-              '-Wl,-z,noexecstack',
-              '-Wl,-z,now',
-              '-Wl,-z,relro',
-              '<(fuchsia_lib)/crt1.o',
-              '<(fuchsia_lib)/crti.o',
-            ],
-            'ldflags!': [
-              '-pthread',
-            ],
-          }],
-          ['_toolset=="host"', {
-            'cflags': [ '-pthread' ],
-            'ldflags': [ '-pthread' ],
-          }],
-        ],
-      },
-      'Dart_Fuchsia_arm64_Base': {
-        'abstract': 1,
-        'variables': {
-          'fuchsia_sysroot': '<(fuchsia_tools)/sysroot/arm64',
-          'fuchsia_include': '<(fuchsia_sysroot)/usr/include',
-          'fuchsia_lib': '<(fuchsia_sysroot)/usr/lib',
-        },
-        'target_conditions': [
-          ['_toolset=="target"', {
-            'defines': [
-              'TARGET_OS_FUCHSIA',
-            ],
-            'cflags': [
-              '--sysroot=<(fuchsia_sysroot)',
-              '-I<(fuchsia_include)',
-              '-fno-threadsafe-statics',
-            ],
-            'ldflags': [
-              'arm64', '>(_type)', 'target',
-              '-nostdlib',
-              '-L<(fuchsia_lib)',
-              '-Wl,-z,noexecstack',
-              '-Wl,-z,now',
-              '-Wl,-z,relro',
-            ],
-            'ldflags!': [
-              '-pthread',
-            ],
-          }],
-          ['_toolset=="host"', {
-            'cflags': [ '-pthread' ],
-            'ldflags': [ '-pthread' ],
-          }],
-        ],
-      },  # Dart_Fuchsia_arm64_Base
-    },  # configurations
-  },  # target_defaults
-}
diff --git a/tools/gyp/configurations_msvs.gypi b/tools/gyp/configurations_msvs.gypi
index 68a08c5..10e3c47 100644
--- a/tools/gyp/configurations_msvs.gypi
+++ b/tools/gyp/configurations_msvs.gypi
@@ -116,6 +116,7 @@
             'Optimization': '2',
             'InlineFunctionExpansion': '2',
             'EnableIntrinsicFunctions': 'true',
+            'EnableFunctionLevelLinking': 'true',
             'FavorSizeOrSpeed': '0',
             'ExceptionHandling': '0',
             'RuntimeTypeInfo': 'false',
diff --git a/tools/gypi_to_gn.py b/tools/gypi_to_gn.py
old mode 100644
new mode 100755
index a107f94..ca62a12
--- a/tools/gypi_to_gn.py
+++ b/tools/gypi_to_gn.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # Copyright 2014 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.
@@ -128,10 +129,28 @@
   # Assume everything else is unchanged.
   return values
 
+def KeepOnly(values, filters):
+  """Recursively filters out strings not ending in "f" from "values"""
+
+  if isinstance(values, list):
+    return [v for v in values if v.endswith(tuple(filters))]
+
+  if isinstance(values, dict):
+    result = {}
+    for key, value in values.items():
+      new_key = KeepOnly(key, filters)
+      new_value = KeepOnly(value, filters)
+      result[new_key] = new_value
+    return result
+
+  return values
+
 def main():
   parser = OptionParser()
   parser.add_option("-r", "--replace", action="append",
     help="Replaces substrings. If passed a=b, replaces all substrs a with b.")
+  parser.add_option("-k", "--keep_only", default = [], action="append",
+    help="Keeps only files ending with the listed strings.")
   (options, args) = parser.parse_args()
 
   if len(args) != 1:
@@ -148,6 +167,9 @@
       assert len(split) == 2, "Replacement must be of the form 'key=value'."
       data = ReplaceSubstrings(data, split[0], split[1])
 
+  if options.keep_only != []:
+    data = KeepOnly(data, options.keep_only)
+
   # Sometimes .gypi files use the GYP syntax with percents at the end of the
   # variable name (to indicate not to overwrite a previously-defined value):
   #   'foo%': 'bar',
diff --git a/tools/make_version.py b/tools/make_version.py
old mode 100644
new mode 100755
index cf96fe2..157c955
--- a/tools/make_version.py
+++ b/tools/make_version.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env 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.
diff --git a/tools/set_ia32_sysroot.sh b/tools/set_ia32_sysroot.sh
new file mode 100755
index 0000000..c7156ce
--- /dev/null
+++ b/tools/set_ia32_sysroot.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Sets the compiler environment variables to use a downloaded wheezy sysroot
+# when building Dart with architecture ia32.
+# Run this in the same working directory that you have run 
+# sdk/tools/download_chromium_sysroot.sh in.
+# Must be sourced, not run in a subshell, to modify the environment.
+# Run with the command ". sdk/tools/set_ia32_sysroot.sh"
+# Only tested and used on Ubuntu trusty linux. Used to build dart with
+# no requirement for glibc greater than version 2.14.
+
+export CXXFLAGS="--sysroot=$PWD/build/linux/debian_wheezy_i386-sysroot -I=/usr/include/c++/4.6 -I=/usr/include/c++/4.6/i486-linux-gnu"
+
+export LDFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_i386-sysroot
+export CFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_i386-sysroot
diff --git a/tools/set_x64_sysroot.sh b/tools/set_x64_sysroot.sh
new file mode 100755
index 0000000..bc28961
--- /dev/null
+++ b/tools/set_x64_sysroot.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Sets the compiler environment variables to use a downloaded wheezy sysroot
+# when building Dart with architecture x64.
+# Run this in the same working directory that you have run 
+# sdk/tools/download_chromium_sysroot.sh in.
+# Must be sourced, not run in a subshell, to modify the environment.
+# Run with the command ". sdk/tools/set_x64_sysroot.sh"
+# Only tested and used on Ubuntu trusty linux. Used to build dart with
+# no requirement for glibc greater than version 2.14.
+
+export CXXFLAGS="--sysroot=$PWD/build/linux/debian_wheezy_amd64-sysroot -I=/usr/include/c++/4.6 -I=/usr/include/c++/4.6/x86_64-linux-gnu"
+
+export LDFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_amd64-sysroot
+export CFLAGS=--sysroot=$PWD/build/linux/debian_wheezy_amd64-sysroot
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 76a0e55..f6ac871 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -34,6 +34,7 @@
 abstract class CompilerConfiguration {
   final bool isDebug;
   final bool isChecked;
+  final bool isStrong;
   final bool isHostChecked;
   final bool useSdk;
 
@@ -48,18 +49,21 @@
     // object.
     bool isDebug = configuration['mode'] == 'debug';
     bool isChecked = configuration['checked'];
+    bool isStrong = configuration['strong'];
     bool isHostChecked = configuration['host_checked'];
     bool useSdk = configuration['use_sdk'];
     bool isCsp = configuration['csp'];
     bool useCps = configuration['cps_ir'];
     bool useBlobs = configuration['use_blobs'];
     bool hotReload = configuration['hot_reload'];
+    bool hotReloadRollback = configuration['hot_reload_rollback'];
 
     switch (compiler) {
       case 'dart2analyzer':
         return new AnalyzerCompilerConfiguration(
             isDebug: isDebug,
             isChecked: isChecked,
+            isStrong: isStrong,
             isHostChecked: isHostChecked,
             useSdk: useSdk);
       case 'dart2js':
@@ -91,7 +95,8 @@
             isChecked: isChecked,
             isHostChecked: isHostChecked,
             useSdk: useSdk,
-            hotReload: hotReload);
+            hotReload: hotReload,
+            hotReloadRollback: hotReloadRollback);
       default:
         throw "Unknown compiler '$compiler'";
     }
@@ -100,6 +105,7 @@
   CompilerConfiguration._subclass(
       {this.isDebug: false,
       this.isChecked: false,
+      this.isStrong: false,
       this.isHostChecked: false,
       this.useSdk: false});
 
@@ -152,16 +158,19 @@
 /// The "none" compiler.
 class NoneCompilerConfiguration extends CompilerConfiguration {
   final bool hotReload;
+  final bool hotReloadRollback;
 
   NoneCompilerConfiguration(
       {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk,
-       bool hotReload})
+       bool hotReload,
+       bool hotReloadRollback})
       : super._subclass(
             isDebug: isDebug,
             isChecked: isChecked,
             isHostChecked: isHostChecked,
             useSdk: useSdk),
-        this.hotReload = hotReload;
+        this.hotReload = hotReload,
+        this.hotReloadRollback = hotReloadRollback;
 
   bool get hasCompiler => false;
 
@@ -180,10 +189,8 @@
     }
     if (hotReload) {
       args.add('--hot-reload-test-mode');
-      // Remove the following once known bugs with background compilation
-      // and OSR are fixed.
-      args.add('--no-background-compilation');
-      args.add('--no-osr');
+    } else if (hotReloadRollback) {
+      args.add('--hot-reload-rollback-test-mode');
     }
     return args
       ..addAll(vmOptions)
@@ -601,10 +608,12 @@
 
 class AnalyzerCompilerConfiguration extends CompilerConfiguration {
   AnalyzerCompilerConfiguration(
-      {bool isDebug, bool isChecked, bool isHostChecked, bool useSdk})
+      {bool isDebug, bool isChecked, bool isStrong, bool isHostChecked, bool
+      useSdk})
       : super._subclass(
             isDebug: isDebug,
             isChecked: isChecked,
+            isStrong: isStrong,
             isHostChecked: isHostChecked,
             useSdk: useSdk);
 
@@ -637,9 +646,12 @@
       List arguments,
       Map<String, String> environmentOverrides) {
     arguments = new List.from(arguments);
-    if (isChecked) {
+    if (isChecked || isStrong) {
       arguments.add('--enable_type_checks');
     }
+    if (isStrong){
+      arguments.add('--strong');
+    }
     return new CommandArtifact(<Command>[
       commandBuilder.getAnalysisCommand('dart2analyzer',
           computeCompilerPath(buildDir), arguments, environmentOverrides,
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 429ddeac..82f45cc 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -85,6 +85,7 @@
       abbr: 'h', negatable: false, help: 'Print this usage information.');
   parser.addOption('build-directory', help: 'The build directory to use.');
   parser.addOption('package-root', help: 'The package root to use.');
+  parser.addOption('packages', help: 'The package spec file to use.');
   parser.addOption('network',
       help: 'The network interface to use.', defaultsTo: '0.0.0.0');
   parser.addFlag('csp',
@@ -97,7 +98,8 @@
     print(parser.getUsage());
   } else {
     var servers = new TestingServers(new Path(args['build-directory']),
-        args['csp'], args['runtime'], null, args['package-root']);
+        args['csp'], args['runtime'], null, args['package-root'],
+        args['packages']);
     var port = int.parse(args['port']);
     var crossOriginPort = int.parse(args['crossOriginPort']);
     servers
@@ -130,6 +132,7 @@
   Path _buildDirectory = null;
   Path _dartDirectory = null;
   Path _packageRoot;
+  Path _packages;
   final bool useContentSecurityPolicy;
   final String runtime;
   DispatchingServer _server;
@@ -137,13 +140,15 @@
   TestingServers(Path buildDirectory, this.useContentSecurityPolicy,
       [String this.runtime = 'none',
       String dartDirectory,
-      String packageRoot]) {
+      String packageRoot,
+      String packages]) {
     _buildDirectory = TestUtils.absolutePath(buildDirectory);
     _dartDirectory =
         dartDirectory == null ? TestUtils.dartDir : new Path(dartDirectory);
     _packageRoot = packageRoot == null
-        ? _buildDirectory.append('packages')
-        : new Path(packageRoot);
+      ? (packages == null ? _buildDirectory.append('packages') : null)
+      : new Path(packageRoot);
+    _packages = packages == null ? null : new Path(packages);
   }
 
   int get port => _serverList[0].port;
@@ -288,6 +293,10 @@
       }
       var packagesIndex = pathSegments.indexOf('packages');
       if (packagesIndex != -1) {
+        if (_packages != null) {
+          // TODO(27065): Package spec file not supported by http server yet
+          return null;
+        }
         var start = packagesIndex + 1;
         basePath = _packageRoot;
         relativePath = new Path(pathSegments.skip(start).join('/'));
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index d39bc9a..eb85c1a 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -221,7 +221,11 @@
 }
 
 Future doMultitest(
-    Path filePath, String outputDir, Path suiteDir, CreateTest doTest) {
+    Path filePath,
+    String outputDir,
+    Path suiteDir,
+    CreateTest doTest,
+    bool hotReload) {
   void writeFile(String filepath, String content) {
     final File file = new File(filepath);
 
@@ -273,6 +277,13 @@
       bool isNegativeIfChecked = outcome.contains('dynamic type error');
       bool hasCompileErrorIfChecked =
           outcome.contains('checked mode compile-time error');
+      if (hotReload) {
+        if (hasCompileError || hasCompileErrorIfChecked) {
+          // Running a test that expects a compilation error with hot reloading
+          // is redundant with a regular run of the test.
+          continue;
+        }
+      }
       doTest(multitestFilename, filePath, hasCompileError, hasRuntimeErrors,
           isNegativeIfChecked: isNegativeIfChecked,
           hasCompileErrorIfChecked: hasCompileErrorIfChecked,
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 8c10e10..8983cc5 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -70,7 +70,7 @@
   RuntimeConfiguration._subclass();
 
   int computeTimeoutMultiplier(
-      {String mode, bool isChecked: false, String arch}) {
+      {String mode, bool isChecked: false, bool isReload: false, String arch}) {
     return 1;
   }
 
@@ -164,7 +164,7 @@
   DartVmRuntimeConfiguration() : super._subclass();
 
   int computeTimeoutMultiplier(
-      {String mode, bool isChecked: false, String arch}) {
+      {String mode, bool isChecked: false, bool isReload: false, String arch}) {
     int multiplier = 1;
     switch (arch) {
       case 'simarm':
@@ -183,6 +183,9 @@
     }
     if (mode == 'debug') {
       multiplier *= 2;
+      if (isReload) {
+        multiplier *= 2;
+      }
     }
     return multiplier;
   }
@@ -192,13 +195,14 @@
 /// program named Dump Render Tree, hence the name.
 class DrtRuntimeConfiguration extends DartVmRuntimeConfiguration {
   int computeTimeoutMultiplier(
-      {String mode, bool isChecked: false, String arch}) {
+      {String mode, bool isChecked: false, bool isReload: false, String arch}) {
     return 4 // Allow additional time for browser testing to run.
         // TODO(ahe): We might need to distinquish between DRT for running
         // JavaScript and Dart code.  I'm not convinced the inherited timeout
         // multiplier is relevant for JavaScript.
         *
-        super.computeTimeoutMultiplier(mode: mode, isChecked: isChecked);
+        super.computeTimeoutMultiplier(
+            mode: mode, isChecked: isChecked, isReload: isReload);
   }
 }
 
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index ca3bfbe..47e233b 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -45,7 +45,6 @@
   new Path('tests/language'),
   new Path('tests/lib'),
   new Path('tests/standalone'),
-  new Path('tests/try'),
   new Path('tests/utils'),
   new Path('utils/tests/css'),
   new Path('utils/tests/peg'),
@@ -103,6 +102,7 @@
           .map((name) => conf[name])
           .toList();
       if (conf['checked']) settings.add('checked');
+      if (conf['strong']) settings.add('strong');
       if (conf['noopt']) settings.add('noopt');
       output_words.add(settings.join('_'));
     }
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index da2c5d0..922e386 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -163,6 +163,9 @@
       new _TestOptionSpecification(
           'checked', 'Run tests in checked mode', ['--checked'], [], false,
           type: 'bool'),
+      new _TestOptionSpecification(
+          'strong', 'Run tests in strong mode', ['--strong'], [], false,
+          type: 'bool'),
       new _TestOptionSpecification('host_checked',
           'Run compiler in checked mode', ['--host-checked'], [], false,
           type: 'bool'),
@@ -190,6 +193,11 @@
           'hot_reload', 'Run hot reload stress tests', ['--hot-reload'], [],
           false, type: 'bool'),
       new _TestOptionSpecification(
+          'hot_reload_rollback',
+          'Run hot reload rollback stress tests', ['--hot-reload-rollback'],
+          [],
+          false, type: 'bool'),
+      new _TestOptionSpecification(
           'use_blobs',
           'Use mmap instead of shared libraries for precompilation',
           ['--use-blobs'], [], false, type: 'bool'),
@@ -429,6 +437,12 @@
       new _TestOptionSpecification('package_root',
           'The package root to use for testing.', ['--package-root'], [], null),
       new _TestOptionSpecification(
+          'packages',
+          'The package spec file to use for testing.',
+          ['--packages'],
+          [],
+          null),
+      new _TestOptionSpecification(
           'exclude_suite',
           'Exclude suites from default selector, only works when no'
           ' selector has been specified on the command line',
@@ -703,7 +717,7 @@
   List<Map> _expandConfigurations(Map configuration) {
     // Expand the pseudo-values such as 'all'.
     if (configuration['arch'] == 'all') {
-      configuration['arch'] = 'ia32,x64,simarm,simarm64,simmips,simdbc';
+      configuration['arch'] = 'ia32,x64,simarm,simarm64,simmips,simdbc64';
     }
     if (configuration['mode'] == 'all') {
       configuration['mode'] = 'debug,release,product';
@@ -819,12 +833,15 @@
 
     // Adjust default timeout based on mode, compiler, and sometimes runtime.
     if (configuration['timeout'] == -1) {
+      var isReload = configuration['hot_reload'] ||
+                     configuration['hot_reload_rollback'];
       int compilerMulitiplier =
           new CompilerConfiguration(configuration).computeTimeoutMultiplier();
       int runtimeMultiplier = new RuntimeConfiguration(configuration)
           .computeTimeoutMultiplier(
               mode: configuration['mode'],
               isChecked: configuration['checked'],
+              isReload: isReload,
               arch: configuration['arch']);
       configuration['timeout'] = 60 * compilerMulitiplier * runtimeMultiplier;
     }
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index b93294b..14910fa 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -255,6 +255,7 @@
     'compiler',
     'runtime',
     'checked',
+    'strong',
     'host_checked',
     'minified',
     'csp',
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index c73dc7c..fd8270d 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -300,6 +300,15 @@
       return;
     }
 
+    if (configuration['hot_reload'] || configuration['hot_reload_rollback']) {
+      // Handle reload special cases.
+      if (expectations.contains(Expectation.COMPILETIME_ERROR)) {
+        // Running a test that expects a compilation error with hot reloading
+        // is redundant with a regular run of the test.
+        return;
+      }
+    }
+
     // Update Summary report
     if (configuration['report']) {
       if (testCase.expectCompileError &&
@@ -368,25 +377,27 @@
 
   String createOutputDirectory(Path testPath, String optionsName) {
     var checked = configuration['checked'] ? '-checked' : '';
+    var strong =  configuration['strong'] ? '-strong' : '';
     var minified = configuration['minified'] ? '-minified' : '';
     var sdk = configuration['use_sdk'] ? '-sdk' : '';
     var packages =
         configuration['use_public_packages'] ? '-public_packages' : '';
     var dirName = "${configuration['compiler']}-${configuration['runtime']}"
-        "$checked$minified$packages$sdk";
+        "$checked$strong$minified$packages$sdk";
     return createGeneratedTestDirectoryHelper(
         "tests", dirName, testPath, optionsName);
   }
 
   String createCompilationOutputDirectory(Path testPath) {
     var checked = configuration['checked'] ? '-checked' : '';
+    var strong =  configuration['strong'] ? '-strong' : '';
     var minified = configuration['minified'] ? '-minified' : '';
     var csp = configuration['csp'] ? '-csp' : '';
     var sdk = configuration['use_sdk'] ? '-sdk' : '';
     var packages =
         configuration['use_public_packages'] ? '-public_packages' : '';
     var dirName = "${configuration['compiler']}"
-        "$checked$minified$csp$packages$sdk";
+        "$checked$strong$minified$csp$packages$sdk";
     return createGeneratedTestDirectoryHelper(
         "compilations", dirName, testPath, "");
   }
@@ -837,7 +848,12 @@
     CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
 
     if (optionsFromFile['isMultitest']) {
-      group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase));
+      group.add(doMultitest(filePath,
+                            buildDir,
+                            suiteDir,
+                            createTestCase,
+                            (configuration['hot_reload'] ||
+                             configuration['hot_reload_rollback'])));
     } else {
       createTestCase(filePath, filePath, optionsFromFile['hasCompileError'],
           optionsFromFile['hasRuntimeError'],
@@ -957,6 +973,10 @@
       packageRoot = new Path(configuration['package_root']);
       optionsFromFile['packageRoot'] = packageRoot.toNativePath();
     }
+    if (configuration['packages'] != null) {
+      Path packages = new Path(configuration['packages']);
+      optionsFromFile['packages'] = packages.toNativePath();
+    }
 
     if (new CompilerConfiguration(configuration).hasCompiler &&
         expectCompileError(info)) {
@@ -1455,9 +1475,8 @@
       args = [];
     }
     args.addAll(TestUtils.standardOptions(configuration));
-    String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
-    if (packageRoot != null) args.add(packageRoot);
-    String packages = packagesArgument(optionsFromFile['packages']);
+    String packages = packagesArgument(optionsFromFile['packageRoot'],
+                                       optionsFromFile['packages']);
     if (packages != null) args.add(packages);
     args.add('--out=$outputFile');
     args.add(inputFile);
@@ -1477,9 +1496,8 @@
   Command _polymerDeployCommand(
       String inputFile, String outputDir, optionsFromFile) {
     List<String> args = [];
-    String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
-    if (packageRoot != null) args.add(packageRoot);
-    String packages = packagesArgument(optionsFromFile['packages']);
+    String packages = packagesArgument(optionsFromFile['packageRoot'],
+                                       optionsFromFile['packages']);
     if (packages != null) args.add(packages);
     args
       ..add('package:polymer/deploy.dart')
@@ -1534,11 +1552,8 @@
   List<String> commonArgumentsFromFile(Path filePath, Map optionsFromFile) {
     List args = TestUtils.standardOptions(configuration);
 
-    String packageRoot = packageRootArgument(optionsFromFile['packageRoot']);
-    if (packageRoot != null) {
-      args.add(packageRoot);
-    }
-    String packages = packagesArgument(optionsFromFile['packages']);
+    String packages = packagesArgument(optionsFromFile['packageRoot'],
+                                       optionsFromFile['packages']);
     if (packages != null) {
       args.add(packages);
     }
@@ -1566,30 +1581,16 @@
     return args;
   }
 
-  String packageRoot(String packageRootFromFile) {
+  String packagesArgument(String packageRootFromFile,
+                             String packagesFromFile) {
+    if (packagesFromFile != null) {
+      return "--packages=$packagesFromFile";
+    }
     if (packageRootFromFile == "none") {
       return null;
     }
-    String packageRoot = packageRootFromFile;
-    if (packageRootFromFile == null) {
-      packageRoot = "$buildDir/packages/";
-    }
-    return packageRoot;
-  }
-
-  String packageRootArgument(String packageRootFromFile) {
-    var packageRootPath = packageRoot(packageRootFromFile);
-    if (packageRootPath == null) {
-      return null;
-    }
-    return "--package-root=$packageRootPath";
-  }
-
-  String packagesArgument(String packagesFromFile) {
-    if (packagesFromFile == null || packagesFromFile == "none") {
-      return null;
-    }
-    return "--packages=$packagesFromFile";
+    packageRootFromFile ??= "$buildDir/packages/";
+    return "--package-root=$packageRootFromFile";
   }
 
   /**
@@ -2197,13 +2198,14 @@
         configuration['compiler'] == 'dart2appjit' ||
         configuration['compiler'] == 'precompiler') {
       var checked = configuration['checked'] ? '-checked' : '';
+      var strong =  configuration['strong'] ? '-strong' : '';
       var minified = configuration['minified'] ? '-minified' : '';
       var csp = configuration['csp'] ? '-csp' : '';
       var sdk = configuration['use_sdk'] ? '-sdk' : '';
       var packages =
           configuration['use_public_packages'] ? '-public_packages' : '';
       var dirName = "${configuration['compiler']}"
-          "$checked$minified$csp$packages$sdk";
+          "$checked$strong$minified$csp$packages$sdk";
       String generatedPath = "${TestUtils.buildDir(configuration)}"
           "/generated_compilations/$dirName";
       TestUtils.deleteDirectory(generatedPath);
diff --git a/tools/update_ddc_dep.py b/tools/update_ddc_dep.py
new file mode 100755
index 0000000..d3a3979
--- /dev/null
+++ b/tools/update_ddc_dep.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+
+# Update ddc dep automatically.
+
+import optparse
+import os
+import re
+from subprocess import Popen, PIPE
+import sys
+
+# Instructions:
+#
+# To run locally:
+#  (a) Create and change to a directory to run the updater in:
+#  mkdir /usr/local/google/home/$USER/ddc_deps_updater
+#
+#  (b) Test by running (Ctrl-C to quit):
+#      > ./update_ddc_deps.py
+#
+#  (c) Run periodical update:
+#      > while true; do ./update_ddc_deps.py --force ; sleep 300 ; done
+
+########################################################################
+# Actions
+########################################################################
+
+def write_file(filename, content):
+  f = open(filename, "w")
+  f.write(content)
+  f.close()
+
+def run_cmd(cmd):
+  print "\n[%s]\n$ %s" % (os.getcwd(), " ".join(cmd))
+  pipe = Popen(cmd, stdout=PIPE, stderr=PIPE)
+  output = pipe.communicate()
+  if pipe.returncode == 0:
+    return output[0]
+  else:
+    print output[1]
+    print "FAILED. RET_CODE=%d" % pipe.returncode
+    sys.exit(pipe.returncode)
+
+def main():
+  option_parser = optparse.OptionParser()
+  option_parser.add_option(
+      '',
+      '--force',
+      help="Push DEPS update to server without prompting",
+      action="store_true",
+      dest="force")
+  options, args = option_parser.parse_args()
+
+  target = 'ddc'
+  repo = 'dev_compiler'
+  repo_name = 'git@github.com:dart-lang/sdk.git'
+  ddc_repo_name = 'git@github.com:dart-lang/%s.git' % (repo)
+  repo_branch = 'origin/master'
+  repo_branch_parts = repo_branch.split('/')
+
+  root_dir = "/usr/local/google/home/%s/ddc_deps_updater" % (os.environ["USER"])
+  src_dir = "%s/sdk" % (root_dir)
+  ddc_dir = "%s/%s" % (root_dir, repo)
+  deps_file = src_dir + '/DEPS'
+
+  os.putenv("GIT_PAGER", "")
+
+  if not os.path.exists(src_dir):
+    print run_cmd(['git', 'clone', repo_name])
+
+  if not os.path.exists(ddc_dir):
+    print run_cmd(['git', 'clone', ddc_repo_name])
+
+  os.chdir(ddc_dir)
+  run_cmd(['git', 'fetch'])
+
+  os.chdir(src_dir)
+  run_cmd(['git', 'fetch'])
+  run_cmd(['git', 'stash'])
+  run_cmd(['git', 'checkout', '-B', repo_branch_parts[1], repo_branch])
+
+  # parse DEPS
+  deps = run_cmd(['cat', deps_file])
+  rev_num = {}
+  revision = '%s_rev":\s*"@(.+)"' % (repo)
+  rev_num = re.search(revision, deps).group(1)
+
+  # update repos
+  all_revs = []
+  os.chdir(ddc_dir)
+
+  output = run_cmd(["git", "log",  "--pretty=%H", "%s..HEAD" % (rev_num),
+      "origin/master"])
+  commits = output.split('\n')
+  if not commits or len(commits[0]) < 10:
+    print "DEPS is up-to-date."
+    sys.exit(0)
+
+  revision = commits[0]
+
+  history = run_cmd(["git", "log",  "--format=short", "%s..HEAD" % (rev_num),
+      "origin/master"])
+
+  print "Pending DEPS update: %s" % (revision)
+
+  # make the next DEPS update
+  os.chdir(src_dir)
+  run_cmd(['rm', deps_file])
+
+  pattern = re.compile('%s_rev":\s*"@(.+)"' % (repo))
+  new_deps = pattern.sub('%s_rev": "@%s"' % (repo, revision), deps)
+  write_file(deps_file, new_deps)
+
+  commit_log = 'DEPS AutoUpdate: %s\n\n' % (repo)
+  commit_log += history
+
+  write_file('commit_log.txt', commit_log)
+  run_cmd(['git', 'add', deps_file])
+
+  print run_cmd(['git', 'diff', 'HEAD'])
+  print
+  print "Commit log:"
+  print "---------------------------------------------"
+  print commit_log
+  print "---------------------------------------------"
+
+  if not options.force:
+    print "Ready to push; press Enter to continue or Control-C to abort..."
+    sys.stdin.readline()
+  print run_cmd(['git', 'commit', '-F', 'commit_log.txt'])
+  print run_cmd(['git', 'push', repo_branch_parts[0], repo_branch_parts[1]])
+  print "Done."
+
+
+if '__main__' == __name__:
+  main()
diff --git a/tools/utils.py b/tools/utils.py
index 496b499..51a3a03 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -103,7 +103,7 @@
 
 # Try to guess Visual Studio location when buiding on Windows.
 def GuessVisualStudioPath():
-  defaultPath = r"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7" \
+  defaultPath = r"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7" \
                 r"\IDE"
   defaultExecutable = "devenv.com"
 
@@ -148,8 +148,8 @@
               # Can't find value under the key - continue to the next key.
               continue
             isExpress = executable != 'devenv.com'
-            if not isExpress and subkeyName == '12.0':
-              # Stop search since if we found non-Express VS2013 version
+            if not isExpress and subkeyName == '14.0':
+              # Stop search since if we found non-Express VS2015 version
               # installed, which is preferred version.
               return installDir, executable
             else:
@@ -268,7 +268,7 @@
           (target_os != GuessOS()))
 
 def GetBuildConf(mode, arch, conf_os=None):
-  if conf_os == 'android' or conf_os == 'fuchsia':
+  if conf_os == 'android':
     return '%s%s%s' % (GetBuildMode(mode), conf_os.title(), arch.upper())
   else:
     # Ask for a cross build if the host and target architectures don't match.